Passed
Push — master ( 8c9545...f42925 )
by Jaspar
01:33 queued 10s
created

gvm.protocols.gmpv208.entities.port_lists   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 297
Duplicated Lines 11.78 %

Importance

Changes 0
Metric Value
eloc 135
dl 35
loc 297
rs 10
c 0
b 0
f 0
wmc 30

8 Methods

Rating   Name   Duplication   Size   Complexity  
A PortListMixin.delete_port_list() 0 19 2
A PortListMixin.clone_port_list() 0 17 2
A PortListMixin.create_port_list() 0 32 4
A PortListMixin.modify_port_list() 0 31 4
A PortListMixin.delete_port_range() 0 16 2
A PortListMixin.get_port_lists() 35 35 4
A PortListMixin.get_port_list() 0 22 2
B PortListMixin.create_port_range() 0 60 7

1 Function

Rating   Name   Duplication   Size   Complexity  
A get_port_range_type_from_string() 0 18 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2021 Greenbone Networks GmbH
3
#
4
# SPDX-License-Identifier: GPL-3.0-or-later
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
# pylint:  disable=redefined-builtin
20
# MAYBE we should change filter to filter_string (everywhere)
21
22
from enum import Enum
23
from typing import Any, Optional
24
25
from gvm.errors import RequiredArgument, InvalidArgument, InvalidArgumentType
26
from gvm.utils import add_filter, to_bool
27
from gvm.xml import XmlCommand
28
29
30
class PortRangeType(Enum):
31
    """Enum for port range type"""
32
33
    TCP = 'TCP'
34
    UDP = 'UDP'
35
36
37
def get_port_range_type_from_string(
38
    port_range_type: Optional[str],
39
) -> Optional[PortRangeType]:
40
    """Convert a port range type string to an actual PortRangeType instance
41
42
    Arguments:
43
        port_range_type: Port range type string to convert to a PortRangeType
44
    """
45
    if not port_range_type:
46
        return None
47
48
    try:
49
        return PortRangeType[port_range_type.upper()]
50
    except KeyError:
51
        raise InvalidArgument(
52
            argument='port_range_type',
53
            function=get_port_range_type_from_string.__name__,
54
        ) from None
55
56
57
class PortListMixin:
58
    def clone_port_list(self, port_list_id: str) -> Any:
59
        """Clone an existing port list
60
61
        Arguments:
62
            port_list_id: UUID of an existing port list to clone from
63
64
        Returns:
65
            The response. See :py:meth:`send_command` for details.
66
        """
67
        if not port_list_id:
68
            raise RequiredArgument(
69
                function=self.clone_port_list.__name__, argument='port_list_id'
70
            )
71
72
        cmd = XmlCommand("create_port_list")
73
        cmd.add_element("copy", port_list_id)
74
        return self._send_xml_command(cmd)
75
76
    def create_port_list(
77
        self, name: str, port_range: str, *, comment: Optional[str] = None
78
    ) -> Any:
79
        """Create a new port list
80
81
        Arguments:
82
            name: Name of the new port list
83
            port_range: Port list ranges e.g. `"T: 1-1234"` for tcp port
84
                1 - 1234
85
            comment: Comment for the port list
86
87
        Returns:
88
            The response. See :py:meth:`send_command` for details.
89
        """
90
        if not name:
91
            raise RequiredArgument(
92
                function=self.create_port_list.__name__, argument='name'
93
            )
94
95
        if not port_range:
96
            raise RequiredArgument(
97
                function=self.create_port_list.__name__, argument='port_range'
98
            )
99
100
        cmd = XmlCommand("create_port_list")
101
        cmd.add_element("name", name)
102
        cmd.add_element("port_range", port_range)
103
104
        if comment:
105
            cmd.add_element("comment", comment)
106
107
        return self._send_xml_command(cmd)
108
109
    def create_port_range(
110
        self,
111
        port_list_id: str,
112
        start: int,
113
        end: int,
114
        port_range_type: PortRangeType,
115
        *,
116
        comment: Optional[str] = None,
117
    ) -> Any:
118
        """Create new port range
119
120
        Arguments:
121
            port_list_id: UUID of the port list to which to add the range
122
            start: The first port in the range
123
            end: The last port in the range
124
            port_range_type: The type of the ports: TCP, UDP, ...
125
            comment: Comment for the port range
126
127
        Returns:
128
            The response. See :py:meth:`send_command` for details.
129
        """
130
        if not port_list_id:
131
            raise RequiredArgument(
132
                function=self.create_port_range.__name__,
133
                argument='port_list_id',
134
            )
135
136
        if not port_range_type:
137
            raise RequiredArgument(
138
                function=self.create_port_range.__name__,
139
                argument='port_range_type',
140
            )
141
142
        if not start:
143
            raise RequiredArgument(
144
                function=self.create_port_range.__name__, argument='start'
145
            )
146
147
        if not end:
148
            raise RequiredArgument(
149
                function=self.create_port_range.__name__, argument='end'
150
            )
151
152
        if not isinstance(port_range_type, PortRangeType):
153
            raise InvalidArgumentType(
154
                function=self.create_port_range.__name__,
155
                argument='port_range_type',
156
                arg_type=PortRangeType.__name__,
157
            )
158
159
        cmd = XmlCommand("create_port_range")
160
        cmd.add_element("port_list", attrs={"id": port_list_id})
161
        cmd.add_element("start", str(start))
162
        cmd.add_element("end", str(end))
163
        cmd.add_element("type", port_range_type.value)
164
165
        if comment:
166
            cmd.add_element("comment", comment)
167
168
        return self._send_xml_command(cmd)
169
170
    def delete_port_list(
171
        self, port_list_id: str, *, ultimate: Optional[bool] = False
172
    ) -> Any:
173
        """Deletes an existing port list
174
175
        Arguments:
176
            port_list_id: UUID of the port list to be deleted.
177
            ultimate: Whether to remove entirely, or to the trashcan.
178
        """
179
        if not port_list_id:
180
            raise RequiredArgument(
181
                function=self.delete_port_list.__name__, argument='port_list_id'
182
            )
183
184
        cmd = XmlCommand("delete_port_list")
185
        cmd.set_attribute("port_list_id", port_list_id)
186
        cmd.set_attribute("ultimate", to_bool(ultimate))
187
188
        return self._send_xml_command(cmd)
189
190
    def delete_port_range(self, port_range_id: str) -> Any:
191
        """Deletes an existing port range
192
193
        Arguments:
194
            port_range_id: UUID of the port range to be deleted.
195
        """
196
        if not port_range_id:
197
            raise RequiredArgument(
198
                function=self.delete_port_range.__name__,
199
                argument='port_range_id',
200
            )
201
202
        cmd = XmlCommand("delete_port_range")
203
        cmd.set_attribute("port_range_id", port_range_id)
204
205
        return self._send_xml_command(cmd)
206
207 View Code Duplication
    def get_port_lists(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
208
        self,
209
        *,
210
        filter: Optional[str] = None,
211
        filter_id: Optional[str] = None,
212
        details: Optional[bool] = None,
213
        targets: Optional[bool] = None,
214
        trash: Optional[bool] = None,
215
    ) -> Any:
216
        """Request a list of port lists
217
218
        Arguments:
219
            filter: Filter term to use for the query
220
            filter_id: UUID of an existing filter to use for the query
221
            details: Whether to include full port list details
222
            targets: Whether to include targets using this port list
223
            trash: Whether to get port lists in the trashcan instead
224
225
        Returns:
226
            The response. See :py:meth:`send_command` for details.
227
        """
228
        cmd = XmlCommand("get_port_lists")
229
230
        add_filter(cmd, filter, filter_id)
231
232
        if details is not None:
233
            cmd.set_attribute("details", to_bool(details))
234
235
        if targets is not None:
236
            cmd.set_attribute("targets", to_bool(targets))
237
238
        if trash is not None:
239
            cmd.set_attribute("trash", to_bool(trash))
240
241
        return self._send_xml_command(cmd)
242
243
    def get_port_list(self, port_list_id: str):
244
        """Request a single port list
245
246
        Arguments:
247
            port_list_id: UUID of an existing port list
248
249
        Returns:
250
            The response. See :py:meth:`send_command` for details.
251
        """
252
        cmd = XmlCommand("get_port_lists")
253
254
        if not port_list_id:
255
            raise RequiredArgument(
256
                function=self.get_port_list.__name__, argument='port_list_id'
257
            )
258
259
        cmd.set_attribute("port_list_id", port_list_id)
260
261
        # for single entity always request all details
262
263
        cmd.set_attribute("details", "1")
264
        return self._send_xml_command(cmd)
265
266
    def modify_port_list(
267
        self,
268
        port_list_id: str,
269
        *,
270
        comment: Optional[str] = None,
271
        name: Optional[str] = None,
272
    ) -> Any:
273
        """Modifies an existing port list.
274
275
        Arguments:
276
            port_list_id: UUID of port list to modify.
277
            name: Name of port list.
278
            comment: Comment on port list.
279
280
        Returns:
281
            The response. See :py:meth:`send_command` for details.
282
        """
283
        if not port_list_id:
284
            raise RequiredArgument(
285
                function=self.modify_port_list.__name__, argument='port_list_id'
286
            )
287
        cmd = XmlCommand("modify_port_list")
288
        cmd.set_attribute("port_list_id", port_list_id)
289
290
        if comment:
291
            cmd.add_element("comment", comment)
292
293
        if name:
294
            cmd.add_element("name", name)
295
296
        return self._send_xml_command(cmd)
297