Completed
Push — master ( e81db1...a7ad2f )
by Björn
17s queued 13s
created

GmpV214Mixin.modify_note()   C

Complexity

Conditions 10

Size

Total Lines 72
Code Lines 40

Duplication

Lines 72
Ratio 100 %

Importance

Changes 0
Metric Value
cc 10
eloc 40
nop 11
dl 72
loc 72
rs 5.9999
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like gvm.protocols.gmpv214.gmpv214.GmpV214Mixin.modify_note() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2020 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=arguments-differ, redefined-builtin, too-many-lines
20
21
"""
22
Module for communication with gvmd in
23
`Greenbone Management Protocol version 21.04`_
24
25
.. _Greenbone Management Protocol version 21.04:
26
    https://docs.greenbone.net/API/GMP/gmp-21.04.html
27
"""
28
29
from typing import Any, List, Optional, Callable
30
import numbers
31
32
from gvm.utils import deprecation
33
from gvm.xml import XmlCommand
34
from gvm.protocols.gmpv7.gmpv7 import _to_comma_list
35
36
from gvm.connections import GvmConnection
37
from gvm.errors import RequiredArgument
38
39
from gvm.protocols.base import GvmProtocol
40
41
from . import types
42
from .types import *  # pylint: disable=unused-wildcard-import, wildcard-import
43
44
_EMPTY_POLICY_ID = '085569ce-73ed-11df-83c3-002264764cea'
45
46
PROTOCOL_VERSION = (21, 4)
47
48
Severity = numbers.Real
49
50
51
class GmpV214Mixin(GvmProtocol):
52
    types = types
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable types does not seem to be defined.
Loading history...
53
54
    def __init__(
55
        self,
56
        connection: GvmConnection,
57
        *,
58
        transform: Optional[Callable[[str], Any]] = None
59
    ):
60
        super().__init__(connection, transform=transform)
61
62
        # Is authenticated on gvmd
63
        self._authenticated = False
64
65 View Code Duplication
    def create_note(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
66
        self,
67
        text: str,
68
        nvt_oid: str,
69
        *,
70
        days_active: Optional[int] = None,
71
        hosts: Optional[List[str]] = None,
72
        port: Optional[int] = None,
73
        result_id: Optional[str] = None,
74
        severity: Optional[Severity] = None,
75
        task_id: Optional[str] = None,
76
        threat: Optional[SeverityLevel] = None
77
    ) -> Any:
78
        """Create a new note
79
80
        Arguments:
81
            text: Text of the new note
82
            nvt_id: OID of the nvt to which note applies
83
            days_active: Days note will be active. -1 on
84
                always, 0 off
85
            hosts: A list of hosts addresses
86
            port: Port to which the note applies
87
            result_id: UUID of a result to which note applies
88
            severity: Severity to which note applies
89
            task_id: UUID of task to which note applies
90
            threat: Severity level to which note applies. Will be converted to
91
                severity.
92
93
        Returns:
94
            The response. See :py:meth:`send_command` for details.
95
        """
96
        if not text:
97
            raise RequiredArgument(
98
                function=self.create_note.__name__, argument='text'
99
            )
100
101
        if not nvt_oid:
102
            raise RequiredArgument(
103
                function=self.create_note.__name__, argument='nvt_oid'
104
            )
105
106
        cmd = XmlCommand("create_note")
107
        cmd.add_element("text", text)
108
        cmd.add_element("nvt", attrs={"oid": nvt_oid})
109
110
        if days_active is not None:
111
            cmd.add_element("active", str(days_active))
112
113
        if hosts:
114
            cmd.add_element("hosts", _to_comma_list(hosts))
115
116
        if port:
117
            cmd.add_element("port", str(port))
118
119
        if result_id:
120
            cmd.add_element("result", attrs={"id": result_id})
121
122
        if severity:
123
            cmd.add_element("severity", str(severity))
124
125
        if task_id:
126
            cmd.add_element("task", attrs={"id": task_id})
127
128
        if threat is not None:
129
            deprecation(
130
                "The threat parameter has been removed in GMP"
131
                " version {}{}".format(
132
                    self.get_protocol_version()[0],
133
                    self.get_protocol_version()[1],
134
                )
135
            )
136
137
        return self._send_xml_command(cmd)
138
139 View Code Duplication
    def create_override(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
140
        self,
141
        text: str,
142
        nvt_oid: str,
143
        *,
144
        days_active: Optional[int] = None,
145
        hosts: Optional[List[str]] = None,
146
        port: Optional[int] = None,
147
        result_id: Optional[str] = None,
148
        severity: Optional[Severity] = None,
149
        new_severity: Optional[Severity] = None,
150
        task_id: Optional[str] = None,
151
        threat: Optional[SeverityLevel] = None,
152
        new_threat: Optional[SeverityLevel] = None
153
    ) -> Any:
154
        """Create a new override
155
156
        Arguments:
157
            text: Text of the new override
158
            nvt_id: OID of the nvt to which override applies
159
            days_active: Days override will be active. -1 on always, 0 off
160
            hosts: A list of host addresses
161
            port: Port to which the override applies
162
            result_id: UUID of a result to which override applies
163
            severity: Severity to which override applies
164
            new_severity: New severity for result
165
            task_id: UUID of task to which override applies
166
            threat: Severity level to which override applies. Will be converted
167
                to severity.
168
            new_threat: New severity level for results. Will be converted to
169
                new_severity.
170
171
        Returns:
172
            The response. See :py:meth:`send_command` for details.
173
        """
174
        if not text:
175
            raise RequiredArgument(
176
                function=self.create_override.__name__, argument='text'
177
            )
178
179
        if not nvt_oid:
180
            raise RequiredArgument(
181
                function=self.create_override.__name__, argument='nvt_oid'
182
            )
183
184
        cmd = XmlCommand("create_override")
185
        cmd.add_element("text", text)
186
        cmd.add_element("nvt", attrs={"oid": nvt_oid})
187
188
        if days_active is not None:
189
            cmd.add_element("active", str(days_active))
190
191
        if hosts:
192
            cmd.add_element("hosts", _to_comma_list(hosts))
193
194
        if port:
195
            cmd.add_element("port", str(port))
196
197
        if result_id:
198
            cmd.add_element("result", attrs={"id": result_id})
199
200
        if severity:
201
            cmd.add_element("severity", str(severity))
202
203
        if new_severity:
204
            cmd.add_element("new_severity", str(new_severity))
205
206
        if task_id:
207
            cmd.add_element("task", attrs={"id": task_id})
208
209
        if threat is not None:
210
            deprecation(
211
                "The threat parameter has been removed in GMP"
212
                " version {}{}".format(
213
                    self.get_protocol_version()[0],
214
                    self.get_protocol_version()[1],
215
                )
216
            )
217
218
        if new_threat is not None:
219
            deprecation(
220
                "The new_threat parameter has been removed in GMP"
221
                " version {}{}".format(
222
                    self.get_protocol_version()[0],
223
                    self.get_protocol_version()[1],
224
                )
225
            )
226
227
        return self._send_xml_command(cmd)
228
229 View Code Duplication
    def modify_note(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
230
        self,
231
        note_id: str,
232
        text: str,
233
        *,
234
        days_active: Optional[int] = None,
235
        hosts: Optional[List[str]] = None,
236
        port: Optional[int] = None,
237
        result_id: Optional[str] = None,
238
        severity: Optional[Severity] = None,
239
        task_id: Optional[str] = None,
240
        threat: Optional[SeverityLevel] = None
241
    ) -> Any:
242
        """Modifies an existing note.
243
244
        Arguments:
245
            note_id: UUID of note to modify.
246
            text: The text of the note.
247
            days_active: Days note will be active. -1 on always, 0 off.
248
            hosts: A list of hosts addresses
249
            port: Port to which note applies.
250
            result_id: Result to which note applies.
251
            severity: Severity to which note applies.
252
            task_id: Task to which note applies.
253
            threat: Threat level to which note applies. Will be converted to
254
                severity.
255
256
        Returns:
257
            The response. See :py:meth:`send_command` for details.
258
        """
259
        if not note_id:
260
            raise RequiredArgument(
261
                function=self.modify_note.__name__, argument='note_id'
262
            )
263
264
        if not text:
265
            raise RequiredArgument(
266
                function=self.modify_note.__name__, argument='text'
267
            )
268
269
        cmd = XmlCommand("modify_note")
270
        cmd.set_attribute("note_id", note_id)
271
        cmd.add_element("text", text)
272
273
        if days_active is not None:
274
            cmd.add_element("active", str(days_active))
275
276
        if hosts:
277
            cmd.add_element("hosts", _to_comma_list(hosts))
278
279
        if port:
280
            cmd.add_element("port", str(port))
281
282
        if result_id:
283
            cmd.add_element("result", attrs={"id": result_id})
284
285
        if severity:
286
            cmd.add_element("severity", str(severity))
287
288
        if task_id:
289
            cmd.add_element("task", attrs={"id": task_id})
290
291
        if threat is not None:
292
            deprecation(
293
                "The threat parameter has been removed in GMP"
294
                " version {}{}".format(
295
                    self.get_protocol_version()[0],
296
                    self.get_protocol_version()[1],
297
                )
298
            )
299
300
        return self._send_xml_command(cmd)
301
302 View Code Duplication
    def modify_override(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
303
        self,
304
        override_id: str,
305
        text: str,
306
        *,
307
        days_active: Optional[int] = None,
308
        hosts: Optional[List[str]] = None,
309
        port: Optional[int] = None,
310
        result_id: Optional[str] = None,
311
        severity: Optional[Severity] = None,
312
        new_severity: Optional[Severity] = None,
313
        task_id: Optional[str] = None,
314
        threat: Optional[SeverityLevel] = None,
315
        new_threat: Optional[SeverityLevel] = None
316
    ) -> Any:
317
        """Modifies an existing override.
318
319
        Arguments:
320
            override_id: UUID of override to modify.
321
            text: The text of the override.
322
            days_active: Days override will be active. -1 on always,
323
                0 off.
324
            hosts: A list of host addresses
325
            port: Port to which override applies.
326
            result_id: Result to which override applies.
327
            severity: Severity to which override applies.
328
            new_severity: New severity score for result.
329
            task_id: Task to which override applies.
330
            threat: Threat level to which override applies.
331
                Will be converted to severity.
332
            new_threat: New threat level for results. Will be converted to
333
                new_severity.
334
335
        Returns:
336
            The response. See :py:meth:`send_command` for details.
337
        """
338
        if not override_id:
339
            raise RequiredArgument(
340
                function=self.modify_override.__name__, argument='override_id'
341
            )
342
        if not text:
343
            raise RequiredArgument(
344
                function=self.modify_override.__name__, argument='text'
345
            )
346
347
        cmd = XmlCommand("modify_override")
348
        cmd.set_attribute("override_id", override_id)
349
        cmd.add_element("text", text)
350
351
        if days_active is not None:
352
            cmd.add_element("active", str(days_active))
353
354
        if hosts:
355
            cmd.add_element("hosts", _to_comma_list(hosts))
356
357
        if port:
358
            cmd.add_element("port", str(port))
359
360
        if result_id:
361
            cmd.add_element("result", attrs={"id": result_id})
362
363
        if severity:
364
            cmd.add_element("severity", str(severity))
365
366
        if new_severity:
367
            cmd.add_element("new_severity", str(new_severity))
368
369
        if task_id:
370
            cmd.add_element("task", attrs={"id": task_id})
371
372
        if threat is not None:
373
            deprecation(
374
                "The threat parameter has been removed in GMP"
375
                " version {}{}".format(
376
                    self.get_protocol_version()[0],
377
                    self.get_protocol_version()[1],
378
                )
379
            )
380
381
        if new_threat is not None:
382
            deprecation(
383
                "The new_threat parameter has been removed in GMP"
384
                " version {}{}".format(
385
                    self.get_protocol_version()[0],
386
                    self.get_protocol_version()[1],
387
                )
388
            )
389
390
        return self._send_xml_command(cmd)
391