Passed
Push — master ( 1e243f...b519bb )
by Björn
197:44 queued 153:47
created

ScanConfigsMixin.modify_scan_config()   B

Complexity

Conditions 7

Size

Total Lines 84
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 36
nop 4
dl 0
loc 84
rs 7.616
c 0
b 0
f 0

How to fix   Long Method   

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:

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
23
from typing import Any, List, Optional, Tuple
24
from lxml.etree import XMLSyntaxError
25
26
from gvm.errors import RequiredArgument, InvalidArgument, InvalidArgumentType
27
from gvm.utils import add_filter, deprecation, is_list_like, to_base64, to_bool
28
from gvm.xml import XmlCommand
29
30
31
class ScanConfigsMixin:
32
    def clone_scan_config(self, config_id: str) -> Any:
33
        """Clone a scan config from an existing one
34
35
        Arguments:
36
            config_id: UUID of the existing scan config
37
38
        Returns:
39
            The response. See :py:meth:`send_command` for details.
40
        """
41
        if not config_id:
42
            raise RequiredArgument(
43
                function=self.clone_scan_config.__name__, argument='config_id'
44
            )
45
46
        cmd = XmlCommand("create_config")
47
        cmd.add_element("copy", config_id)
48
        return self._send_xml_command(cmd)
49
50
    def create_scan_config(
51
        self, config_id: str, name: str, *, comment: Optional[str] = None
52
    ) -> Any:
53
        """Create a new scan config
54
55
        Arguments:
56
            config_id: UUID of the existing scan config
57
            name: Name of the new scan config
58
            comment: A comment on the config
59
60
        Returns:
61
            The response. See :py:meth:`send_command` for details.
62
        """
63
        if not name:
64
            raise RequiredArgument(
65
                function=self.create_scan_config.__name__, argument='name'
66
            )
67
68
        if not config_id:
69
            raise RequiredArgument(
70
                function=self.create_scan_config.__name__, argument='config_id'
71
            )
72
73
        cmd = XmlCommand("create_config")
74
        if comment is not None:
75
            cmd.add_element("comment", comment)
76
        cmd.add_element("copy", config_id)
77
        cmd.add_element("name", name)
78
        cmd.add_element("usage_type", "scan")
79
        return self._send_xml_command(cmd)
80
81
    def create_scan_config_from_osp_scanner(
82
        self, scanner_id: str, name: str, *, comment: Optional[str] = None
83
    ) -> Any:
84
        """Create a new scan config from an ospd scanner.
85
86
        Create config by retrieving the expected preferences from the given
87
        scanner via OSP.
88
89
        Arguments:
90
            scanner_id: UUID of an OSP scanner to get config data from
91
            name: Name of the new scan config
92
            comment: A comment on the config
93
94
        Returns:
95
            The response. See :py:meth:`send_command` for details.
96
        """
97
        if not name:
98
            raise RequiredArgument(
99
                function=self.create_scan_config_from_osp_scanner.__name__,
100
                argument='name',
101
            )
102
103
        if not scanner_id:
104
            raise RequiredArgument(
105
                function=self.create_scan_config_from_osp_scanner.__name__,
106
                argument='scanner_id',
107
            )
108
109
        cmd = XmlCommand("create_config")
110
        if comment is not None:
111
            cmd.add_element("comment", comment)
112
        cmd.add_element("scanner", scanner_id)
113
        cmd.add_element("name", name)
114
        cmd.add_element("usage_type", "scan")
115
        return self._send_xml_command(cmd)
116
117
    def delete_scan_config(
118
        self, config_id: str, *, ultimate: Optional[bool] = False
119
    ) -> Any:
120
        """Deletes an existing config
121
122
        Arguments:
123
            config_id: UUID of the config to be deleted.
124
            ultimate: Whether to remove entirely, or to the trashcan.
125
        """
126
        if not config_id:
127
            raise RequiredArgument(
128
                function=self.delete_scan_config.__name__, argument='config_id'
129
            )
130
131
        cmd = XmlCommand("delete_config")
132
        cmd.set_attribute("config_id", config_id)
133
        cmd.set_attribute("ultimate", to_bool(ultimate))
134
135
        return self._send_xml_command(cmd)
136
137 View Code Duplication
    def get_scan_configs(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
138
        self,
139
        *,
140
        filter: Optional[str] = None,
141
        filter_id: Optional[str] = None,
142
        trash: Optional[bool] = None,
143
        details: Optional[bool] = None,
144
        families: Optional[bool] = None,
145
        preferences: Optional[bool] = None,
146
        tasks: Optional[bool] = None,
147
    ) -> Any:
148
        """Request a list of scan configs
149
150
        Arguments:
151
            filter: Filter term to use for the query
152
            filter_id: UUID of an existing filter to use for the query
153
            trash: Whether to get the trashcan scan configs instead
154
            details: Whether to get config families, preferences, nvt selectors
155
                and tasks.
156
            families: Whether to include the families if no details are
157
                requested
158
            preferences: Whether to include the preferences if no details are
159
                requested
160
            tasks: Whether to get tasks using this config
161
162
        Returns:
163
            The response. See :py:meth:`send_command` for details.
164
        """
165
        cmd = XmlCommand("get_configs")
166
        cmd.set_attribute("usage_type", "scan")
167
168
        add_filter(cmd, filter, filter_id)
169
170
        if trash is not None:
171
            cmd.set_attribute("trash", to_bool(trash))
172
173
        if details is not None:
174
            cmd.set_attribute("details", to_bool(details))
175
176
        if families is not None:
177
            cmd.set_attribute("families", to_bool(families))
178
179
        if preferences is not None:
180
            cmd.set_attribute("preferences", to_bool(preferences))
181
182
        if tasks is not None:
183
            cmd.set_attribute("tasks", to_bool(tasks))
184
185
        return self._send_xml_command(cmd)
186
187
    def get_scan_config(
188
        self, config_id: str, *, tasks: Optional[bool] = None
189
    ) -> Any:
190
        """Request a single scan config
191
192
        Arguments:
193
            config_id: UUID of an existing scan config
194
            tasks: Whether to get tasks using this config
195
196
        Returns:
197
            The response. See :py:meth:`send_command` for details.
198
        """
199
        if not config_id:
200
            raise RequiredArgument(
201
                function=self.get_scan_config.__name__, argument='config_id'
202
            )
203
204
        cmd = XmlCommand("get_configs")
205
        cmd.set_attribute("config_id", config_id)
206
207
        cmd.set_attribute("usage_type", "scan")
208
209
        if tasks is not None:
210
            cmd.set_attribute("tasks", to_bool(tasks))
211
212
        # for single entity always request all details
213
        cmd.set_attribute("details", "1")
214
215
        return self._send_xml_command(cmd)
216
217
    def import_scan_config(self, config: str) -> Any:
218
        """Import a scan config from XML
219
220
        Arguments:
221
            config: Scan Config XML as string to import. This XML must
222
                contain a :code:`<get_configs_response>` root element.
223
224
        Returns:
225
            The response. See :py:meth:`send_command` for details.
226
        """
227
        if not config:
228
            raise RequiredArgument(
229
                function=self.import_scan_config.__name__, argument='config'
230
            )
231
232
        cmd = XmlCommand("create_config")
233
234
        try:
235
            cmd.append_xml_str(config)
236
        except XMLSyntaxError as e:
237
            raise InvalidArgument(
238
                function=self.import_scan_config.__name__, argument='config'
239
            ) from e
240
241
        return self._send_xml_command(cmd)
242
243 View Code Duplication
    def modify_scan_config_set_nvt_preference(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
244
        self,
245
        config_id: str,
246
        name: str,
247
        nvt_oid: str,
248
        *,
249
        value: Optional[str] = None,
250
    ) -> Any:
251
        """Modifies the nvt preferences of an existing scan config.
252
253
        Arguments:
254
            config_id: UUID of scan config to modify.
255
            name: Name for nvt preference to change.
256
            nvt_oid: OID of the NVT associated with preference to modify
257
            value: New value for the preference. None to delete the preference
258
                and to use the default instead.
259
        """
260
        if not config_id:
261
            raise RequiredArgument(
262
                function=self.modify_scan_config_set_nvt_preference.__name__,
263
                argument='config_id',
264
            )
265
266
        if not nvt_oid:
267
            raise RequiredArgument(
268
                function=self.modify_scan_config_set_nvt_preference.__name__,
269
                argument='nvt_oid',
270
            )
271
272
        if not name:
273
            raise RequiredArgument(
274
                function=self.modify_scan_config_set_nvt_preference.__name__,
275
                argument='name',
276
            )
277
278
        cmd = XmlCommand("modify_config")
279
        cmd.set_attribute("config_id", str(config_id))
280
281
        _xmlpref = cmd.add_element("preference")
282
283
        _xmlpref.add_element("nvt", attrs={"oid": nvt_oid})
284
        _xmlpref.add_element("name", name)
285
286
        if value:
287
            _xmlpref.add_element("value", to_base64(value))
288
289
        return self._send_xml_command(cmd)
290
291
    def modify_scan_config_set_name(self, config_id: str, name: str) -> Any:
292
        """Modifies the name of an existing scan config
293
294
        Arguments:
295
            config_id: UUID of scan config to modify.
296
            name: New name for the config.
297
        """
298
        if not config_id:
299
            raise RequiredArgument(
300
                function=self.modify_scan_config_set_name.__name__,
301
                argument='config_id',
302
            )
303
304
        if not name:
305
            raise RequiredArgument(
306
                function=self.modify_scan_config_set_name.__name__,
307
                argument='name',
308
            )
309
310
        cmd = XmlCommand("modify_config")
311
        cmd.set_attribute("config_id", str(config_id))
312
313
        cmd.add_element("name", name)
314
315
        return self._send_xml_command(cmd)
316
317
    def modify_scan_config_set_comment(
318
        self, config_id: str, *, comment: Optional[str] = None
319
    ) -> Any:
320
        """Modifies the comment of an existing scan config
321
322
        Arguments:
323
            config_id: UUID of scan config to modify.
324
            comment: Comment to set on a config. Default is an
325
                empty comment and the previous comment will be
326
                removed.
327
        """
328
        if not config_id:
329
            raise RequiredArgument(
330
                function=self.modify_scan_config_set_comment.__name__,
331
                argument='config_id argument',
332
            )
333
334
        cmd = XmlCommand("modify_config")
335
        cmd.set_attribute("config_id", str(config_id))
336
        if not comment:
337
            comment = ""
338
        cmd.add_element("comment", comment)
339
340
        return self._send_xml_command(cmd)
341
342
    def modify_scan_config_set_scanner_preference(
343
        self, config_id: str, name: str, *, value: Optional[str] = None
344
    ) -> Any:
345
        """Modifies the scanner preferences of an existing scan config
346
347
        Arguments:
348
            config_id: UUID of scan config to modify.
349
            name: Name of the scanner preference to change
350
            value: New value for the preference. None to delete the preference
351
                and to use the default instead.
352
353
        """
354
        if not config_id:
355
            raise RequiredArgument(
356
                function=(
357
                    self.modify_scan_config_set_scanner_preference.__name__
358
                ),
359
                argument='config_id',
360
            )
361
362
        if not name:
363
            raise RequiredArgument(
364
                function=(
365
                    self.modify_scan_config_set_scanner_preference.__name__
366
                ),
367
                argument='name argument',
368
            )
369
370
        cmd = XmlCommand("modify_config")
371
        cmd.set_attribute("config_id", str(config_id))
372
373
        _xmlpref = cmd.add_element("preference")
374
375
        _xmlpref.add_element("name", name)
376
377
        if value:
378
            _xmlpref.add_element("value", to_base64(value))
379
380
        return self._send_xml_command(cmd)
381
382 View Code Duplication
    def modify_scan_config_set_nvt_selection(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
383
        self, config_id: str, family: str, nvt_oids: List[str]
384
    ) -> Any:
385
        """Modifies the selected nvts of an existing scan config
386
387
        The manager updates the given family in the config to include only the
388
        given NVTs.
389
390
        Arguments:
391
            config_id: UUID of scan config to modify.
392
            family: Name of the NVT family to include NVTs from
393
            nvt_oids: List of NVTs to select for the family.
394
        """
395
        if not config_id:
396
            raise RequiredArgument(
397
                function=self.modify_scan_config_set_nvt_selection.__name__,
398
                argument='config_id',
399
            )
400
401
        if not family:
402
            raise RequiredArgument(
403
                function=self.modify_scan_config_set_nvt_selection.__name__,
404
                argument='family argument',
405
            )
406
407
        if not is_list_like(nvt_oids):
408
            raise InvalidArgumentType(
409
                function=self.modify_scan_config_set_nvt_selection.__name__,
410
                argument='nvt_oids',
411
                arg_type='list',
412
            )
413
414
        cmd = XmlCommand("modify_config")
415
        cmd.set_attribute("config_id", str(config_id))
416
417
        _xmlnvtsel = cmd.add_element("nvt_selection")
418
        _xmlnvtsel.add_element("family", family)
419
420
        for nvt in nvt_oids:
421
            _xmlnvtsel.add_element("nvt", attrs={"oid": nvt})
422
423
        return self._send_xml_command(cmd)
424
425 View Code Duplication
    def modify_scan_config_set_family_selection(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
426
        self,
427
        config_id: str,
428
        families: List[Tuple[str, bool, bool]],
429
        *,
430
        auto_add_new_families: Optional[bool] = True,
431
    ) -> Any:
432
        """
433
        Selected the NVTs of a scan config at a family level.
434
435
        Arguments:
436
            config_id: UUID of scan config to modify.
437
            families: A list of tuples (str, bool, bool):
438
                str: the name of the NVT family selected,
439
                bool: add new NVTs  to the family automatically,
440
                bool: include all NVTs from the family
441
            auto_add_new_families: Whether new families should be added to the
442
                scan config automatically. Default: True.
443
        """
444
        if not config_id:
445
            raise RequiredArgument(
446
                function=self.modify_scan_config_set_family_selection.__name__,
447
                argument='config_id',
448
            )
449
450
        if not is_list_like(families):
451
            raise InvalidArgumentType(
452
                function=self.modify_scan_config_set_family_selection.__name__,
453
                argument='families',
454
                arg_type='list',
455
            )
456
457
        cmd = XmlCommand("modify_config")
458
        cmd.set_attribute("config_id", str(config_id))
459
460
        _xmlfamsel = cmd.add_element("family_selection")
461
        _xmlfamsel.add_element("growing", to_bool(auto_add_new_families))
462
463
        for family in families:
464
            _xmlfamily = _xmlfamsel.add_element("family")
465
            _xmlfamily.add_element("name", family[0])
466
467
            if len(family) != 3:
468
                raise InvalidArgument(
469
                    "Family must be a tuple of 3. (str, bool, bool)"
470
                )
471
472
            if not isinstance(family[1], bool) or not isinstance(
473
                family[2], bool
474
            ):
475
                raise InvalidArgumentType(
476
                    function=(
477
                        self.modify_scan_config_set_family_selection.__name__
478
                    ),
479
                    argument='families',
480
                    arg_type='[tuple(str, bool, bool)]',
481
                )
482
483
            _xmlfamily.add_element("all", to_bool(family[2]))
484
            _xmlfamily.add_element("growing", to_bool(family[1]))
485
486
        return self._send_xml_command(cmd)
487
488
    def modify_scan_config(
489
        self, config_id: str, selection: Optional[str] = None, **kwargs
490
    ) -> Any:
491
        """Modifies an existing scan config.
492
493
        DEPRECATED. Please use *modify_config_set_* methods instead.
494
495
        modify_config has four modes to operate depending on the selection.
496
497
        Arguments:
498
            config_id: UUID of scan config to modify.
499
            selection: one of 'scan_pref', 'nvt_pref', 'nvt_selection' or
500
                'family_selection'
501
            name: New name for preference.
502
            value: New value for preference.
503
            nvt_oids: List of NVTs associated with preference to modify.
504
            family: Name of family to modify.
505
506
        Returns:
507
            The response. See :py:meth:`send_command` for details.
508
        """
509
        if not config_id:
510
            raise RequiredArgument(
511
                function=self.modify_scan_config.__name__,
512
                argument='config_id argument',
513
            )
514
515
        if selection is None:
516
            deprecation(
517
                "Using modify_config to update the comment of a scan config is"
518
                "deprecated. Please use modify_scan_config_set_comment instead."
519
            )
520
            return self.modify_scan_config_set_comment(
521
                config_id, comment=kwargs.get("comment")
522
            )
523
524
        if selection not in (
525
            "nvt_pref",
526
            "scan_pref",
527
            "family_selection",
528
            "nvt_selection",
529
        ):
530
            raise InvalidArgument(
531
                "selection must be one of nvt_pref, "
532
                "scan_pref, family_selection or "
533
                "nvt_selection"
534
            )
535
536
        if selection == "nvt_pref":
537
            deprecation(
538
                "Using modify_scan_config to update a nvt preference of a scan "
539
                "config is deprecated. Please use "
540
                "modify_scan_config_set_nvt_preference instead."
541
            )
542
            return self.modify_scan_config_set_nvt_preference(
543
                config_id, **kwargs
544
            )
545
546
        if selection == "scan_pref":
547
            deprecation(
548
                "Using modify_scan_config to update a scanner preference of a "
549
                "scan config is deprecated. Please use "
550
                "modify_scan_config_set_scanner_preference instead."
551
            )
552
            return self.modify_scan_config_set_scanner_preference(
553
                config_id, **kwargs
554
            )
555
556
        if selection == "nvt_selection":
557
            deprecation(
558
                "Using modify_scan_config to update a nvt selection of a "
559
                "scan config is deprecated. Please use "
560
                "modify_scan_config_set_nvt_selection instead."
561
            )
562
            return self.modify_scan_config_set_nvt_selection(
563
                config_id, **kwargs
564
            )
565
566
        deprecation(
567
            "Using modify_scan_config to update a family selection of a "
568
            "scan config is deprecated. Please use "
569
            "modify_scan_config_set_family_selection instead."
570
        )
571
        return self.modify_scan_config_set_family_selection(config_id, **kwargs)
572
573
    def sync_scan_config(self) -> Any:
574
        """Request an OSP config synchronization with scanner
575
576
        Returns:
577
            The response. See :py:meth:`send_command` for details.
578
        """
579
        return self._send_xml_command(XmlCommand("sync_config"))
580