Passed
Push — master ( 5ec2d4...3118bd )
by Jaspar
61:24 queued 59:51
created

)   A

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2018-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=arguments-differ, redefined-builtin, too-many-lines
20
21
"""
22
Module for communication with gvmd in
23
`Greenbone Management Protocol version 20.08`_
24
25
.. _Greenbone Management Protocol version 20.08:
26
    https://docs.greenbone.net/API/GMP/gmp-20.08.html
27
"""
28
import base64
29
import collections
30
import logging
31
import numbers
32
import warnings
33
34
from typing import Any, List, Optional, Callable, Union, Tuple
35
from lxml import etree
36
37
from gvm.connections import GvmConnection
38
from gvm.errors import InvalidArgument, InvalidArgumentType, RequiredArgument
39
from gvm.protocols.base import GvmProtocol
40
from gvm.utils import deprecation
41
from gvm.xml import create_parser, XmlCommand
42
43
from . import types
44
from .types import *  # pylint: disable=unused-wildcard-import, wildcard-import
45
from .types import _UsageType as UsageType
46
47
_EMPTY_POLICY_ID = '085569ce-73ed-11df-83c3-002264764cea'
48
49
PROTOCOL_VERSION = (20, 8)
50
51
52
logger = logging.getLogger(__name__)
53
54
Severity = numbers.Real
55
56
57
def _check_command_status(xml: str) -> bool:
58
    """Check gmp response
59
60
    Look into the gmp response and check for the status in the root element
61
62
    Arguments:
63
        xml: XML-Source
64
65
    Returns:
66
        True if valid, otherwise False
67
    """
68
69
    if xml == 0 or xml is None:
70
        logger.error("XML Command is empty")
71
        return False
72
73
    try:
74
        root = etree.XML(xml, parser=create_parser())
75
        status = root.attrib["status"]
76
        return status is not None and status[0] == "2"
77
78
    except etree.Error as e:
79
        logger.error("etree.XML(xml): %s", e)
80
        return False
81
82
83
def _to_bool(value: bool) -> str:
84
    return "1" if value else "0"
85
86
87
def _to_base64(value: str) -> bytes:
88
    return base64.b64encode(value.encode("utf-8"))
89
90
91
def _to_comma_list(value: List) -> str:
92
    return ",".join(value)
93
94
95
def _add_filter(cmd, filter, filter_id):
96
    if filter:
97
        cmd.set_attribute("filter", filter)
98
99
    if filter_id:
100
        cmd.set_attribute("filt_id", filter_id)
101
102
103
def _is_list_like(value: Any) -> bool:
104
    return isinstance(value, (list, tuple))
105
106
107
def _check_event(
108
    event: AlertEvent, condition: AlertCondition, method: AlertMethod
109
):
110
    if event == AlertEvent.TASK_RUN_STATUS_CHANGED:
111
        if not condition:
112
            raise RequiredArgument(
113
                "condition is required for event {}".format(event.name)
114
            )
115
116
        if not method:
117
            raise RequiredArgument(
118
                "method is required for event {}".format(event.name)
119
            )
120
121
        if condition not in (
122
            AlertCondition.ALWAYS,
123
            AlertCondition.FILTER_COUNT_CHANGED,
124
            AlertCondition.FILTER_COUNT_AT_LEAST,
125
            AlertCondition.SEVERITY_AT_LEAST,
126
            AlertCondition.SEVERITY_CHANGED,
127
        ):
128
            raise InvalidArgument(
129
                "Invalid condition {} for event {}".format(
130
                    condition.name, event.name
131
                )
132
            )
133
    elif event in (
134
        AlertEvent.NEW_SECINFO_ARRIVED,
135
        AlertEvent.UPDATED_SECINFO_ARRIVED,
136
    ):
137
        if not condition:
138
            raise RequiredArgument(
139
                "condition is required for event {}".format(event.name)
140
            )
141
142
        if not method:
143
            raise RequiredArgument(
144
                "method is required for event {}".format(event.name)
145
            )
146
147
        if condition != AlertCondition.ALWAYS:
148
            raise InvalidArgument(
149
                "Invalid condition {} for event {}".format(
150
                    condition.name, event.name
151
                )
152
            )
153
        if method not in (
154
            AlertMethod.SCP,
155
            AlertMethod.SEND,
156
            AlertMethod.SMB,
157
            AlertMethod.SNMP,
158
            AlertMethod.SYSLOG,
159
            AlertMethod.EMAIL,
160
        ):
161
            raise InvalidArgument(
162
                "Invalid method {} for event {}".format(method.name, event.name)
163
            )
164
    elif event in (
165
        AlertEvent.TICKET_RECEIVED,
166
        AlertEvent.OWNED_TICKET_CHANGED,
167
        AlertEvent.ASSIGNED_TICKET_CHANGED,
168
    ):
169
        if not condition:
170
            raise RequiredArgument(
171
                "condition is required for event {}".format(event.name)
172
            )
173
174
        if not method:
175
            raise RequiredArgument(
176
                "method is required for event {}".format(event.name)
177
            )
178
        if condition != AlertCondition.ALWAYS:
179
            raise InvalidArgument(
180
                "Invalid condition {} for event {}".format(
181
                    condition.name, event.name
182
                )
183
            )
184
        if method not in (
185
            AlertMethod.EMAIL,
186
            AlertMethod.START_TASK,
187
            AlertMethod.SYSLOG,
188
        ):
189
            raise InvalidArgument(
190
                "Invalid method {} for event {}".format(method.name, event.name)
191
            )
192
    elif event is not None:
193
        raise InvalidArgument('Invalid event "{}"'.format(event.name))
194
195
196
class GmpV208Mixin(GvmProtocol):
197
    """Python interface for Greenbone Management Protocol
198
199
    This class implements the `Greenbone Management Protocol version 20.08`_
200
201
    Arguments:
202
        connection: Connection to use to talk with the gvmd daemon. See
203
            :mod:`gvm.connections` for possible connection types.
204
        transform: Optional transform `callable`_ to convert response data.
205
            After each request the callable gets passed the plain response data
206
            which can be used to check the data and/or conversion into different
207
            representations like a xml dom.
208
209
            See :mod:`gvm.transforms` for existing transforms.
210
211
    .. _Greenbone Management Protocol version 20.08:
212
        https://docs.greenbone.net/API/GMP/gmp-20.08.html
213
    .. _callable:
214
        https://docs.python.org/3/library/functions.html#callable
215
    """
216
217
    types = types
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable types does not seem to be defined.
Loading history...
218
219
    def __init__(
220
        self,
221
        connection: GvmConnection,
222
        *,
223
        transform: Optional[Callable[[str], Any]] = None,
224
    ):
225
        super().__init__(connection, transform=transform)
226
227
        # Is authenticated on gvmd
228
        self._authenticated = False
229
230
    def is_authenticated(self) -> bool:
231
        """Checks if the user is authenticated
232
233
        If the user is authenticated privileged GMP commands like get_tasks
234
        may be send to gvmd.
235
236
        Returns:
237
            bool: True if an authenticated connection to gvmd has been
238
            established.
239
        """
240
        return self._authenticated
241
242
    def authenticate(self, username: str, password: str) -> Any:
243
        """Authenticate to gvmd.
244
245
        The generated authenticate command will be send to server.
246
        Afterwards the response is read, transformed and returned.
247
248
        Arguments:
249
            username: Username
250
            password: Password
251
252
        Returns:
253
            Transformed response from server.
254
        """
255
        cmd = XmlCommand("authenticate")
256
257
        if not username:
258
            raise RequiredArgument(
259
                function=self.authenticate.__name__, argument='username'
260
            )
261
262
        if not password:
263
            raise RequiredArgument(
264
                function=self.authenticate.__name__, argument='password'
265
            )
266
267
        credentials = cmd.add_element("credentials")
268
        credentials.add_element("username", username)
269
        credentials.add_element("password", password)
270
271
        self._send(cmd.to_string())
272
        response = self._read()
273
274
        if _check_command_status(response):
275
            self._authenticated = True
276
277
        return self._transform(response)
278
279
    def create_alert(
280
        self,
281
        name: str,
282
        condition: AlertCondition,
283
        event: AlertEvent,
284
        method: AlertMethod,
285
        *,
286
        method_data: Optional[dict] = None,
287
        event_data: Optional[dict] = None,
288
        condition_data: Optional[dict] = None,
289
        filter_id: Optional[int] = None,
290
        comment: Optional[str] = None,
291
    ) -> Any:
292
        """Create a new alert
293
294
        Arguments:
295
            name: Name of the new Alert
296
            condition: The condition that must be satisfied for the alert
297
                to occur; if the event is either 'Updated SecInfo arrived' or
298
                'New SecInfo arrived', condition must be 'Always'. Otherwise,
299
                condition can also be on of 'Severity at least', 'Filter count
300
                changed' or 'Filter count at least'.
301
            event: The event that must happen for the alert to occur, one
302
                of 'Task run status changed', 'Updated SecInfo arrived' or 'New
303
                SecInfo arrived'
304
            method: The method by which the user is alerted, one of 'SCP',
305
                'Send', 'SMB', 'SNMP', 'Syslog' or 'Email'; if the event is
306
                neither 'Updated SecInfo arrived' nor 'New SecInfo arrived',
307
                method can also be one of 'Start Task', 'HTTP Get', 'Sourcefire
308
                Connector' or 'verinice Connector'.
309
            condition_data: Data that defines the condition
310
            event_data: Data that defines the event
311
            method_data: Data that defines the method
312
            filter_id: Filter to apply when executing alert
313
            comment: Comment for the alert
314
315
        Returns:
316
            The response. See :py:meth:`send_command` for details.
317
        """
318
        if not name:
319
            raise RequiredArgument(
320
                function=self.create_alert.__name__, argument='name'
321
            )
322
323
        if not condition:
324
            raise RequiredArgument(
325
                function=self.create_alert.__name__, argument='condition'
326
            )
327
328
        if not event:
329
            raise RequiredArgument(
330
                function=self.create_alert.__name__, argument='event'
331
            )
332
333
        if not method:
334
            raise RequiredArgument(
335
                function=self.create_alert.__name__, argument='method'
336
            )
337
338
        if not isinstance(condition, AlertCondition):
339
            raise InvalidArgumentType(
340
                function=self.create_alert.__name__,
341
                argument='condition',
342
                arg_type=AlertCondition.__name__,
343
            )
344
345
        if not isinstance(event, AlertEvent):
346
            raise InvalidArgumentType(
347
                function=self.create_alert.__name__,
348
                argument='even',
349
                arg_type=AlertEvent.__name__,
350
            )
351
352
        if not isinstance(method, AlertMethod):
353
            raise InvalidArgumentType(
354
                function=self.create_alert.__name__,
355
                argument='method',
356
                arg_type=AlertMethod.__name__,
357
            )
358
359
        _check_event(event, condition, method)
360
361
        cmd = XmlCommand("create_alert")
362
        cmd.add_element("name", name)
363
364
        conditions = cmd.add_element("condition", condition.value)
365
366
        if condition_data is not None:
367
            for key, value in condition_data.items():
368
                _data = conditions.add_element("data", value)
369
                _data.add_element("name", key)
370
371
        events = cmd.add_element("event", event.value)
372
373
        if event_data is not None:
374
            for key, value in event_data.items():
375
                _data = events.add_element("data", value)
376
                _data.add_element("name", key)
377
378
        methods = cmd.add_element("method", method.value)
379
380
        if method_data is not None:
381
            for key, value in method_data.items():
382
                _data = methods.add_element("data", value)
383
                _data.add_element("name", key)
384
385
        if filter_id:
386
            cmd.add_element("filter", attrs={"id": filter_id})
387
388
        if comment:
389
            cmd.add_element("comment", comment)
390
391
        return self._send_xml_command(cmd)
392
393 View Code Duplication
    def create_audit(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
394
        self,
395
        name: str,
396
        policy_id: str,
397
        target_id: str,
398
        scanner_id: str,
399
        *,
400
        alterable: Optional[bool] = None,
401
        hosts_ordering: Optional[HostsOrdering] = None,
402
        schedule_id: Optional[str] = None,
403
        alert_ids: Optional[List[str]] = None,
404
        comment: Optional[str] = None,
405
        schedule_periods: Optional[int] = None,
406
        observers: Optional[List[str]] = None,
407
        preferences: Optional[dict] = None,
408
    ) -> Any:
409
        """Create a new audit task
410
411
        Arguments:
412
            name: Name of the new audit
413
            policy_id: UUID of policy to use by the audit
414
            target_id: UUID of target to be scanned
415
            scanner_id: UUID of scanner to use for scanning the target
416
            comment: Comment for the audit
417
            alterable: Whether the task should be alterable
418
            alert_ids: List of UUIDs for alerts to be applied to the audit
419
            hosts_ordering: The order hosts are scanned in
420
            schedule_id: UUID of a schedule when the audit should be run.
421
            schedule_periods: A limit to the number of times the audit will be
422
                scheduled, or 0 for no limit
423
            observers: List of names or ids of users which should be allowed to
424
                observe this audit
425
            preferences: Name/Value pairs of scanner preferences.
426
427
        Returns:
428
            The response. See :py:meth:`send_command` for details.
429
        """
430
431
        return self.__create_task(
432
            name=name,
433
            config_id=policy_id,
434
            target_id=target_id,
435
            scanner_id=scanner_id,
436
            usage_type=UsageType.AUDIT,
437
            function=self.create_audit.__name__,
438
            alterable=alterable,
439
            hosts_ordering=hosts_ordering,
440
            schedule_id=schedule_id,
441
            alert_ids=alert_ids,
442
            comment=comment,
443
            schedule_periods=schedule_periods,
444
            observers=observers,
445
            preferences=preferences,
446
        )
447
448
    def create_config(
449
        self, config_id: str, name: str, *, comment: Optional[str] = None
450
    ) -> Any:
451
        """Create a new scan config
452
453
        Arguments:
454
            config_id: UUID of the existing scan config
455
            name: Name of the new scan config
456
            comment: A comment on the config
457
458
        Returns:
459
            The response. See :py:meth:`send_command` for details.
460
        """
461
        return self.__create_config(
462
            config_id=config_id,
463
            name=name,
464
            comment=comment,
465
            usage_type=UsageType.SCAN,
466
            function=self.create_config.__name__,
467
        )
468
469
    def create_config_from_osp_scanner(
470
        self, scanner_id: str, name: str, *, comment: Optional[str] = None
471
    ) -> Any:
472
        """Create a new scan config from an ospd scanner.
473
474
        Create config by retrieving the expected preferences from the given
475
        scanner via OSP.
476
477
        Arguments:
478
            scanner_id: UUID of an OSP scanner to get config data from
479
            name: Name of the new scan config
480
            comment: A comment on the config
481
482
        Returns:
483
            The response. See :py:meth:`send_command` for details.
484
        """
485
        return self.__create_config_from_osp_scanner(
486
            scanner_id=scanner_id,
487
            name=name,
488
            comment=comment,
489
            usage_type=UsageType.SCAN,
490
            function=self.create_config.__name__,
491
        )
492
493
    def create_permission(
494
        self,
495
        name: str,
496
        subject_id: str,
497
        subject_type: PermissionSubjectType,
498
        *,
499
        resource_id: Optional[str] = None,
500
        resource_type: Optional[EntityType] = None,
501
        comment: Optional[str] = None,
502
    ) -> Any:
503
        """Create a new permission
504
505
        Arguments:
506
            name: Name of the new permission
507
            subject_id: UUID of subject to whom the permission is granted
508
            subject_type: Type of the subject user, group or role
509
            comment: Comment for the permission
510
            resource_id: UUID of entity to which the permission applies
511
            resource_type: Type of the resource. For Super permissions user,
512
                group or role
513
514
        Returns:
515
            The response. See :py:meth:`send_command` for details.
516
        """
517
        if not name:
518
            raise RequiredArgument(
519
                function=self.create_permission.__name__, argument='name'
520
            )
521
522
        if not subject_id:
523
            raise RequiredArgument(
524
                function=self.create_permission.__name__, argument='subject_id'
525
            )
526
527
        if not isinstance(subject_type, PermissionSubjectType):
528
            raise InvalidArgumentType(
529
                function=self.create_permission.__name__,
530
                argument='subject_type',
531
                arg_type=PermissionSubjectType.__name__,
532
            )
533
534
        cmd = XmlCommand("create_permission")
535
        cmd.add_element("name", name)
536
537
        _xmlsubject = cmd.add_element("subject", attrs={"id": subject_id})
538
        _xmlsubject.add_element("type", subject_type.value)
539
540
        if comment:
541
            cmd.add_element("comment", comment)
542
543 View Code Duplication
        if resource_id or resource_type:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
544
            if not resource_id:
545
                raise RequiredArgument(
546
                    function=self.create_permission.__name__,
547
                    argument='resource_id',
548
                )
549
550
            if not resource_type:
551
                raise RequiredArgument(
552
                    function=self.create_permission.__name__,
553
                    argument='resource_type',
554
                )
555
556
            if not isinstance(resource_type, self.types.EntityType):
557
                raise InvalidArgumentType(
558
                    function=self.create_permission.__name__,
559
                    argument='resource_type',
560
                    arg_type=self.types.EntityType.__name__,
561
                )
562
563
            _xmlresource = cmd.add_element(
564
                "resource", attrs={"id": resource_id}
565
            )
566
567
            _actual_resource_type = resource_type
568
            if resource_type.value == EntityType.AUDIT.value:
569
                _actual_resource_type = EntityType.TASK
570
            elif resource_type.value == EntityType.POLICY.value:
571
                _actual_resource_type = EntityType.SCAN_CONFIG
572
573
            _xmlresource.add_element("type", _actual_resource_type.value)
574
575
        return self._send_xml_command(cmd)
576
577
    def create_policy(
578
        self, name: str, *, policy_id: str = None, comment: Optional[str] = None
579
    ) -> Any:
580
        """Create a new policy config
581
582
        Arguments:
583
            name: Name of the new policy
584
            policy_id: UUID of an existing policy as base. By default the empty
585
                policy is used.
586
            comment: A comment on the policy
587
588
        Returns:
589
            The response. See :py:meth:`send_command` for details.
590
        """
591
        if policy_id is None:
592
            policy_id = _EMPTY_POLICY_ID
593
        return self.__create_config(
594
            config_id=policy_id,
595
            name=name,
596
            comment=comment,
597
            usage_type=UsageType.POLICY,
598
            function=self.create_policy.__name__,
599
        )
600
601
    def create_tag(
602
        self,
603
        name: str,
604
        resource_type: EntityType,
605
        *,
606
        resource_filter: Optional[str] = None,
607
        resource_ids: Optional[List[str]] = None,
608
        value: Optional[str] = None,
609
        comment: Optional[str] = None,
610
        active: Optional[bool] = None,
611
    ) -> Any:
612
        """Create a tag.
613
614
        Arguments:
615
            name: Name of the tag. A full tag name consisting of namespace and
616
                predicate e.g. `foo:bar`.
617
            resource_type: Entity type the tag is to be attached to.
618
            resource_filter: Filter term to select resources the tag is to be
619
                attached to. Only one of resource_filter or resource_ids can be
620
                provided.
621
            resource_ids: IDs of the resources the tag is to be attached to.
622
                Only one of resource_filter or resource_ids can be provided.
623
            value: Value associated with the tag.
624
            comment: Comment for the tag.
625
            active: Whether the tag should be active.
626
627
        Returns:
628
            The response. See :py:meth:`send_command` for details.
629
        """
630
        if not name:
631
            raise RequiredArgument(
632
                function=self.create_tag.__name__, argument='name'
633
            )
634
635
        if resource_filter and resource_ids:
636
            raise InvalidArgument(
637
                "create_tag accepts either resource_filter or resource_ids "
638
                "argument",
639
                function=self.create_tag.__name__,
640
            )
641
642
        if not resource_type:
643
            raise RequiredArgument(
644
                function=self.create_tag.__name__, argument='resource_type'
645
            )
646
647
        if not isinstance(resource_type, self.types.EntityType):
648
            raise InvalidArgumentType(
649
                function=self.create_tag.__name__,
650
                argument='resource_type',
651
                arg_type=EntityType.__name__,
652
            )
653
654
        cmd = XmlCommand('create_tag')
655
        cmd.add_element('name', name)
656
657
        _xmlresources = cmd.add_element("resources")
658
        if resource_filter is not None:
659
            _xmlresources.set_attribute("filter", resource_filter)
660
661
        for resource_id in resource_ids or []:
662
            _xmlresources.add_element(
663
                "resource", attrs={"id": str(resource_id)}
664
            )
665
666
        _actual_resource_type = resource_type
667
        if resource_type.value == EntityType.AUDIT.value:
668
            _actual_resource_type = EntityType.TASK
669
        elif resource_type.value == EntityType.POLICY.value:
670
            _actual_resource_type = EntityType.SCAN_CONFIG
671
        _xmlresources.add_element("type", _actual_resource_type.value)
672
673
        if comment:
674
            cmd.add_element("comment", comment)
675
676
        if value:
677
            cmd.add_element("value", value)
678
679
        if active is not None:
680
            if active:
681
                cmd.add_element("active", "1")
682
            else:
683
                cmd.add_element("active", "0")
684
685
        return self._send_xml_command(cmd)
686
687 View Code Duplication
    def create_task(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
688
        self,
689
        name: str,
690
        config_id: str,
691
        target_id: str,
692
        scanner_id: str,
693
        *,
694
        alterable: Optional[bool] = None,
695
        hosts_ordering: Optional[HostsOrdering] = None,
696
        schedule_id: Optional[str] = None,
697
        alert_ids: Optional[List[str]] = None,
698
        comment: Optional[str] = None,
699
        schedule_periods: Optional[int] = None,
700
        observers: Optional[List[str]] = None,
701
        preferences: Optional[dict] = None,
702
    ) -> Any:
703
        """Create a new scan task
704
705
        Arguments:
706
            name: Name of the task
707
            config_id: UUID of scan config to use by the task
708
            target_id: UUID of target to be scanned
709
            scanner_id: UUID of scanner to use for scanning the target
710
            comment: Comment for the task
711
            alterable: Whether the task should be alterable
712
            alert_ids: List of UUIDs for alerts to be applied to the task
713
            hosts_ordering: The order hosts are scanned in
714
            schedule_id: UUID of a schedule when the task should be run.
715
            schedule_periods: A limit to the number of times the task will be
716
                scheduled, or 0 for no limit
717
            observers: List of names or ids of users which should be allowed to
718
                observe this task
719
            preferences: Name/Value pairs of scanner preferences.
720
721
        Returns:
722
            The response. See :py:meth:`send_command` for details.
723
        """
724
        return self.__create_task(
725
            name=name,
726
            config_id=config_id,
727
            target_id=target_id,
728
            scanner_id=scanner_id,
729
            usage_type=UsageType.SCAN,
730
            function=self.create_task.__name__,
731
            alterable=alterable,
732
            hosts_ordering=hosts_ordering,
733
            schedule_id=schedule_id,
734
            alert_ids=alert_ids,
735
            comment=comment,
736
            schedule_periods=schedule_periods,
737
            observers=observers,
738
            preferences=preferences,
739
        )
740
741 View Code Duplication
    def create_tls_certificate(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
742
        self,
743
        name: str,
744
        certificate: str,
745
        *,
746
        comment: Optional[str] = None,
747
        trust: Optional[bool] = None,
748
    ) -> Any:
749
        """Create a new TLS certificate
750
751
        Arguments:
752
            name: Name of the TLS certificate, defaulting to the MD5
753
                fingerprint.
754
            certificate: The Base64 encoded certificate data (x.509 DER or PEM).
755
            comment: Comment for the TLS certificate.
756
            trust: Whether the certificate is trusted.
757
758
        Returns:
759
            The response. See :py:meth:`send_command` for details.
760
        """
761
        if not name:
762
            raise RequiredArgument(
763
                function=self.create_tls_certificate.__name__, argument='name'
764
            )
765
        if not certificate:
766
            raise RequiredArgument(
767
                function=self.create_tls_certificate.__name__,
768
                argument='certificate',
769
            )
770
771
        cmd = XmlCommand("create_tls_certificate")
772
773
        if comment:
774
            cmd.add_element("comment", comment)
775
776
        cmd.add_element("name", name)
777
        cmd.add_element("certificate", certificate)
778
779
        if trust:
780
            cmd.add_element("trust", _to_bool(trust))
781
782
        return self._send_xml_command(cmd)
783
784
    def get_aggregates(
785
        self,
786
        resource_type: EntityType,
787
        *,
788
        filter: Optional[str] = None,
789
        filter_id: Optional[str] = None,
790
        sort_criteria: Optional[list] = None,
791
        data_columns: Optional[list] = None,
792
        group_column: Optional[str] = None,
793
        subgroup_column: Optional[str] = None,
794
        text_columns: Optional[list] = None,
795
        first_group: Optional[int] = None,
796
        max_groups: Optional[int] = None,
797
        mode: Optional[int] = None,
798
        **kwargs,
799
    ) -> Any:
800
        """Request aggregated information on a resource / entity type
801
802
        Additional arguments can be set via the kwargs parameter for backward
803
        compatibility with older versions of python-gvm, but are not validated.
804
805
        Arguments:
806
            resource_type: The entity type to gather data from
807
            filter: Filter term to use for the query
808
            filter_id: UUID of an existing filter to use for the query
809
            sort_criteria: List of sort criteria (dicts that can contain
810
                a field, stat and order)
811
            data_columns: List of fields to aggregate data from
812
            group_column: The field to group the entities by
813
            subgroup_column: The field to further group the entities
814
                inside groups by
815
            text_columns: List of simple text columns which no statistics
816
                are calculated for
817
            first_group: The index of the first aggregate group to return
818
            max_groups: The maximum number of aggregate groups to return,
819
                -1 for all
820
            mode: Special mode for aggregation
821
822
        Returns:
823
            The response. See :py:meth:`send_command` for details.
824
        """
825
        if not resource_type:
826
            raise RequiredArgument(
827
                function=self.get_aggregates.__name__, argument='resource_type'
828
            )
829
830
        if not isinstance(resource_type, self.types.EntityType):
831
            raise InvalidArgumentType(
832
                function=self.get_aggregates.__name__,
833
                argument='resource_type',
834
                arg_type=self.types.EntityType.__name__,
835
            )
836
837
        cmd = XmlCommand('get_aggregates')
838
839
        _actual_resource_type = resource_type
840
        if resource_type.value == EntityType.AUDIT.value:
841
            _actual_resource_type = EntityType.TASK
842
            cmd.set_attribute('usage_type', 'audit')
843
        elif resource_type.value == EntityType.POLICY.value:
844
            _actual_resource_type = EntityType.SCAN_CONFIG
845
            cmd.set_attribute('usage_type', 'policy')
846
        elif resource_type.value == EntityType.SCAN_CONFIG.value:
847
            cmd.set_attribute('usage_type', 'scan')
848
        elif resource_type.value == EntityType.TASK.value:
849
            cmd.set_attribute('usage_type', 'scan')
850
        cmd.set_attribute('type', _actual_resource_type.value)
851
852
        _add_filter(cmd, filter, filter_id)
853
854
        if first_group is not None:
855
            if not isinstance(first_group, int):
856
                raise InvalidArgumentType(
857
                    function=self.get_aggregates.__name__,
858
                    argument='first_group',
859
                    arg_type=int.__name__,
860
                )
861
            cmd.set_attribute('first_group', str(first_group))
862
863
        if max_groups is not None:
864
            if not isinstance(max_groups, int):
865
                raise InvalidArgumentType(
866
                    function=self.get_aggregates.__name__,
867
                    argument='max_groups',
868
                    arg_type=int.__name__,
869
                )
870
            cmd.set_attribute('max_groups', str(max_groups))
871
872
        if sort_criteria is not None:
873
            if not isinstance(sort_criteria, list):
874
                raise InvalidArgumentType(
875
                    function=self.get_aggregates.__name__,
876
                    argument='sort_criteria',
877
                    arg_type=list.__name__,
878
                )
879
            for sort in sort_criteria:
880
                if not isinstance(sort, dict):
881
                    raise InvalidArgumentType(
882
                        function=self.get_aggregates.__name__,
883
                        argument='sort_criteria',
884
                    )
885
886
                sort_elem = cmd.add_element('sort')
887
                if sort.get('field'):
888
                    sort_elem.set_attribute('field', sort.get('field'))
889
890
                if sort.get('stat'):
891
                    if isinstance(sort['stat'], AggregateStatistic):
892
                        sort_elem.set_attribute('stat', sort['stat'].value)
893
                    else:
894
                        stat = get_aggregate_statistic_from_string(sort['stat'])
895
                        sort_elem.set_attribute('stat', stat.value)
896
897
                if sort.get('order'):
898
                    if isinstance(sort['order'], SortOrder):
899
                        sort_elem.set_attribute('order', sort['order'].value)
900
                    else:
901
                        so = get_sort_order_from_string(sort['order'])
902
                        sort_elem.set_attribute('order', so.value)
903
904
        if data_columns is not None:
905
            if not isinstance(data_columns, list):
906
                raise InvalidArgumentType(
907
                    function=self.get_aggregates.__name__,
908
                    argument='data_columns',
909
                    arg_type=list.__name__,
910
                )
911
            for column in data_columns:
912
                cmd.add_element('data_column', column)
913
914
        if group_column is not None:
915
            cmd.set_attribute('group_column', group_column)
916
917
        if subgroup_column is not None:
918
            if not group_column:
919
                raise RequiredArgument(
920
                    '{} requires a group_column argument'
921
                    ' if subgroup_column is given'.format(
922
                        self.get_aggregates.__name__
923
                    ),
924
                    function=self.get_aggregates.__name__,
925
                    argument='subgroup_column',
926
                )
927
            cmd.set_attribute('subgroup_column', subgroup_column)
928
929
        if text_columns is not None:
930
            if not isinstance(text_columns, list):
931
                raise InvalidArgumentType(
932
                    function=self.get_aggregates.__name__,
933
                    argument='text_columns',
934
                    arg_type=list.__name__,
935
                )
936
            for column in text_columns:
937
                cmd.add_element('text_column', column)
938
939
        if mode is not None:
940
            cmd.set_attribute('mode', mode)
941
942
        # Add additional keyword args as attributes for backward compatibility.
943
        cmd.set_attributes(kwargs)
944
945
        return self._send_xml_command(cmd)
946
947
    def get_tls_certificates(
948
        self,
949
        *,
950
        filter: Optional[str] = None,
951
        filter_id: Optional[str] = None,
952
        include_certificate_data: Optional[bool] = None,
953
        details: Optional[bool] = None,
954
    ) -> Any:
955
        """Request a list of TLS certificates
956
957
        Arguments:
958
            filter: Filter term to use for the query
959
            filter_id: UUID of an existing filter to use for the query
960
            include_certificate_data: Whether to include the certificate data in
961
                the response
962
963
        Returns:
964
            The response. See :py:meth:`send_command` for details.
965
        """
966
967
        cmd = XmlCommand("get_tls_certificates")
968
969
        _add_filter(cmd, filter, filter_id)
970
971
        if details is not None:
972
            cmd.set_attribute("details", _to_bool(details))
973
974
        if include_certificate_data is not None:
975
            cmd.set_attribute(
976
                "include_certificate_data", _to_bool(include_certificate_data)
977
            )
978
979
        return self._send_xml_command(cmd)
980
981
    def get_tls_certificate(self, tls_certificate_id: str) -> Any:
982
        """Request a single TLS certificate
983
984
        Arguments:
985
            tls_certificate_id: UUID of an existing TLS certificate
986
987
        Returns:
988
            The response. See :py:meth:`send_command` for details.
989
        """
990
        cmd = XmlCommand("get_tls_certificates")
991
992
        if not tls_certificate_id:
993
            raise RequiredArgument(
994
                function=self.get_tls_certificate.__name__,
995
                argument='tls_certificate_id',
996
            )
997
998
        cmd.set_attribute("tls_certificate_id", tls_certificate_id)
999
1000
        # for single tls certificate always request cert data
1001
        cmd.set_attribute("include_certificate_data", "1")
1002
1003
        # for single entity always request all details
1004
        cmd.set_attribute("details", "1")
1005
1006
        return self._send_xml_command(cmd)
1007
1008
    def modify_alert(
1009
        self,
1010
        alert_id: str,
1011
        *,
1012
        name: Optional[str] = None,
1013
        comment: Optional[str] = None,
1014
        filter_id: Optional[str] = None,
1015
        event: Optional[AlertEvent] = None,
1016
        event_data: Optional[dict] = None,
1017
        condition: Optional[AlertCondition] = None,
1018
        condition_data: Optional[dict] = None,
1019
        method: Optional[AlertMethod] = None,
1020
        method_data: Optional[dict] = None,
1021
    ) -> Any:
1022
        """Modifies an existing alert.
1023
1024
        Arguments:
1025
            alert_id: UUID of the alert to be modified.
1026
            name: Name of the Alert.
1027
            condition: The condition that must be satisfied for the alert to
1028
                occur. If the event is either 'Updated SecInfo
1029
                arrived' or 'New SecInfo arrived', condition must be 'Always'.
1030
                Otherwise, condition can also be on of 'Severity at least',
1031
                'Filter count changed' or 'Filter count at least'.
1032
            condition_data: Data that defines the condition
1033
            event: The event that must happen for the alert to occur, one of
1034
                'Task run status changed', 'Updated SecInfo arrived' or
1035
                'New SecInfo arrived'
1036
            event_data: Data that defines the event
1037
            method: The method by which the user is alerted, one of 'SCP',
1038
                'Send', 'SMB', 'SNMP', 'Syslog' or 'Email';
1039
                if the event is neither 'Updated SecInfo arrived' nor
1040
                'New SecInfo arrived', method can also be one of 'Start Task',
1041
                'HTTP Get', 'Sourcefire Connector' or 'verinice Connector'.
1042
            method_data: Data that defines the method
1043
            filter_id: Filter to apply when executing alert
1044
            comment: Comment for the alert
1045
1046
        Returns:
1047
            The response. See :py:meth:`send_command` for details.
1048
        """
1049
1050
        if not alert_id:
1051
            raise RequiredArgument(
1052
                function=self.modify_alert.__name__, argument='alert_id'
1053
            )
1054
1055
        cmd = XmlCommand("modify_alert")
1056
        cmd.set_attribute("alert_id", str(alert_id))
1057
1058
        if name:
1059
            cmd.add_element("name", name)
1060
1061
        if comment:
1062
            cmd.add_element("comment", comment)
1063
1064
        if filter_id:
1065
            cmd.add_element("filter", attrs={"id": filter_id})
1066
1067
        if condition:
1068
            if not isinstance(condition, AlertCondition):
1069
                raise InvalidArgumentType(
1070
                    function=self.modify_alert.__name__,
1071
                    argument='condition',
1072
                    arg_type=AlertCondition.__name__,
1073
                )
1074
1075
            conditions = cmd.add_element("condition", condition.value)
1076
1077
            if condition_data is not None:
1078
                for key, value in condition_data.items():
1079
                    _data = conditions.add_element("data", value)
1080
                    _data.add_element("name", key)
1081
1082
        if method:
1083
            if not isinstance(method, AlertMethod):
1084
                raise InvalidArgumentType(
1085
                    function=self.modify_alert.__name__,
1086
                    argument='method',
1087
                    arg_type=AlertMethod.__name__,
1088
                )
1089
1090
            methods = cmd.add_element("method", method.value)
1091
1092
            if method_data is not None:
1093
                for key, value in method_data.items():
1094
                    _data = methods.add_element("data", value)
1095
                    _data.add_element("name", key)
1096
1097
        if event:
1098
            if not isinstance(event, AlertEvent):
1099
                raise InvalidArgumentType(
1100
                    function=self.modify_alert.__name__,
1101
                    argument='event',
1102
                    arg_type=AlertEvent.__name__,
1103
                )
1104
1105
            _check_event(event, condition, method)
1106
1107
            events = cmd.add_element("event", event.value)
1108
1109
            if event_data is not None:
1110
                for key, value in event_data.items():
1111
                    _data = events.add_element("data", value)
1112
                    _data.add_element("name", key)
1113
1114
        return self._send_xml_command(cmd)
1115
1116
    def modify_audit(
1117
        self,
1118
        audit_id: str,
1119
        *,
1120
        name: Optional[str] = None,
1121
        policy_id: Optional[str] = None,
1122
        target_id: Optional[str] = None,
1123
        scanner_id: Optional[str] = None,
1124
        alterable: Optional[bool] = None,
1125
        hosts_ordering: Optional[HostsOrdering] = None,
1126
        schedule_id: Optional[str] = None,
1127
        schedule_periods: Optional[int] = None,
1128
        comment: Optional[str] = None,
1129
        alert_ids: Optional[List[str]] = None,
1130
        observers: Optional[List[str]] = None,
1131
        preferences: Optional[dict] = None,
1132
    ) -> Any:
1133
        """Modifies an existing task.
1134
1135
        Arguments:
1136
            audit_id: UUID of audit to modify.
1137
            name: The name of the audit.
1138
            policy_id: UUID of policy to use by the audit
1139
            target_id: UUID of target to be scanned
1140
            scanner_id: UUID of scanner to use for scanning the target
1141
            comment: The comment on the audit.
1142
            alert_ids: List of UUIDs for alerts to be applied to the audit
1143
            hosts_ordering: The order hosts are scanned in
1144
            schedule_id: UUID of a schedule when the audit should be run.
1145
            schedule_periods: A limit to the number of times the audit will be
1146
                scheduled, or 0 for no limit.
1147
            observers: List of names or ids of users which should be allowed to
1148
                observe this audit
1149
            preferences: Name/Value pairs of scanner preferences.
1150
1151
        Returns:
1152
            The response. See :py:meth:`send_command` for details.
1153
        """
1154
        self.modify_task(
1155
            task_id=audit_id,
1156
            name=name,
1157
            config_id=policy_id,
1158
            target_id=target_id,
1159
            scanner_id=scanner_id,
1160
            alterable=alterable,
1161
            hosts_ordering=hosts_ordering,
1162
            schedule_id=schedule_id,
1163
            schedule_periods=schedule_periods,
1164
            comment=comment,
1165
            alert_ids=alert_ids,
1166
            observers=observers,
1167
            preferences=preferences,
1168
        )
1169
1170
    def modify_permission(
1171
        self,
1172
        permission_id: str,
1173
        *,
1174
        comment: Optional[str] = None,
1175
        name: Optional[str] = None,
1176
        resource_id: Optional[str] = None,
1177
        resource_type: Optional[EntityType] = None,
1178
        subject_id: Optional[str] = None,
1179
        subject_type: Optional[PermissionSubjectType] = None,
1180
    ) -> Any:
1181
        """Modifies an existing permission.
1182
1183
        Arguments:
1184
            permission_id: UUID of permission to be modified.
1185
            comment: The comment on the permission.
1186
            name: Permission name, currently the name of a command.
1187
            subject_id: UUID of subject to whom the permission is granted
1188
            subject_type: Type of the subject user, group or role
1189
            resource_id: UUID of entity to which the permission applies
1190
            resource_type: Type of the resource. For Super permissions user,
1191
                group or role
1192
1193
        Returns:
1194
            The response. See :py:meth:`send_command` for details.
1195
        """
1196
        if not permission_id:
1197
            raise RequiredArgument(
1198
                function=self.modify_permission.__name__,
1199
                argument='permission_id',
1200
            )
1201
1202
        cmd = XmlCommand("modify_permission")
1203
        cmd.set_attribute("permission_id", permission_id)
1204
1205
        if comment:
1206
            cmd.add_element("comment", comment)
1207
1208
        if name:
1209
            cmd.add_element("name", name)
1210
1211 View Code Duplication
        if resource_id or resource_type:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1212
            if not resource_id:
1213
                raise RequiredArgument(
1214
                    function=self.modify_permission.__name__,
1215
                    argument='resource_id',
1216
                )
1217
1218
            if not resource_type:
1219
                raise RequiredArgument(
1220
                    function=self.modify_permission.__name__,
1221
                    argument='resource_type',
1222
                )
1223
1224
            if not isinstance(resource_type, self.types.EntityType):
1225
                raise InvalidArgumentType(
1226
                    function=self.modify_permission.__name__,
1227
                    argument='resource_type',
1228
                    arg_type=self.types.EntityType.__name__,
1229
                )
1230
1231
            _xmlresource = cmd.add_element(
1232
                "resource", attrs={"id": resource_id}
1233
            )
1234
            _actual_resource_type = resource_type
1235
            if resource_type.value == EntityType.AUDIT.value:
1236
                _actual_resource_type = EntityType.TASK
1237
            elif resource_type.value == EntityType.POLICY.value:
1238
                _actual_resource_type = EntityType.SCAN_CONFIG
1239
            _xmlresource.add_element("type", _actual_resource_type.value)
1240
1241
        if subject_id or subject_type:
1242
            if not subject_id:
1243
                raise RequiredArgument(
1244
                    function=self.modify_permission.__name__,
1245
                    argument='subject_id',
1246
                )
1247
1248
            if not isinstance(subject_type, PermissionSubjectType):
1249
                raise InvalidArgumentType(
1250
                    function=self.modify_permission.__name__,
1251
                    argument='subject_type',
1252
                    arg_type=PermissionSubjectType.__name__,
1253
                )
1254
1255
            _xmlsubject = cmd.add_element("subject", attrs={"id": subject_id})
1256
            _xmlsubject.add_element("type", subject_type.value)
1257
1258
        return self._send_xml_command(cmd)
1259
1260
    def modify_policy_set_nvt_preference(
1261
        self,
1262
        policy_id: str,
1263
        name: str,
1264
        nvt_oid: str,
1265
        *,
1266
        value: Optional[str] = None,
1267
    ) -> Any:
1268
        """Modifies the nvt preferences of an existing policy.
1269
1270
        Arguments:
1271
            policy_id: UUID of policy to modify.
1272
            name: Name for preference to change.
1273
            nvt_oid: OID of the NVT associated with preference to modify
1274
            value: New value for the preference. None to delete the preference
1275
                and to use the default instead.
1276
        """
1277
        self.modify_config_set_nvt_preference(
1278
            config_id=policy_id, name=name, nvt_oid=nvt_oid, value=value
1279
        )
1280
1281
    def modify_policy_set_name(self, policy_id: str, name: str) -> Any:
1282
        """Modifies the name of an existing policy
1283
1284
        Arguments:
1285
            config_id: UUID of policy to modify.
1286
            name: New name for the config.
1287
        """
1288
        self.modify_config_set_name(config_id=policy_id, name=name)
1289
1290
    def modify_policy_set_comment(
1291
        self, policy_id: str, comment: Optional[str] = ""
1292
    ) -> Any:
1293
        """Modifies the comment of an existing policy
1294
1295
        Arguments:
1296
            policy_id: UUID of policy to modify.
1297
            comment: Comment to set on a config. Default: ''
1298
        """
1299
        self.modify_config_set_comment(config_id=policy_id, comment=comment)
1300
1301
    def modify_policy_set_scanner_preference(
1302
        self, policy_id: str, name: str, *, value: Optional[str] = None
1303
    ) -> Any:
1304
        """Modifies the scanner preferences of an existing policy
1305
1306
        Arguments:
1307
            policy_id: UUID of policy to modify.
1308
            name: Name of the scanner preference to change
1309
            value: New value for the preference. None to delete the preference
1310
                and to use the default instead.
1311
1312
        """
1313
        self.modify_config_set_scanner_preference(
1314
            config_id=policy_id, name=name, value=value
1315
        )
1316
1317
    def modify_policy_set_nvt_selection(
1318
        self, policy_id: str, family: str, nvt_oids: List[str]
1319
    ) -> Any:
1320
        """Modifies the selected nvts of an existing policy
1321
1322
        The manager updates the given family in the config to include only the
1323
        given NVTs.
1324
1325
        Arguments:
1326
            policy_id: UUID of policy to modify.
1327
            family: Name of the NVT family to include NVTs from
1328
            nvt_oids: List of NVTs to select for the family.
1329
        """
1330
        self.modify_config_set_nvt_selection(
1331
            config_id=policy_id, family=family, nvt_oids=nvt_oids
1332
        )
1333
1334
    def modify_policy_set_family_selection(
1335
        self,
1336
        policy_id: str,
1337
        families: List[Tuple[str, bool, bool]],
1338
        *,
1339
        auto_add_new_families: Optional[bool] = True,
1340
    ) -> Any:
1341
        """
1342
        Selected the NVTs of a policy at a family level.
1343
1344
        Arguments:
1345
            policy_id: UUID of policy to modify.
1346
            families: A list of tuples with the first entry being the name
1347
                of the NVT family selected, second entry a boolean indicating
1348
                whether new NVTs should be added to the family automatically,
1349
                and third entry a boolean indicating whether all nvts from
1350
                the family should be included.
1351
            auto_add_new_families: Whether new families should be added to the
1352
                policy automatically. Default: True.
1353
        """
1354
        self.modify_config_set_family_selection(
1355
            config_id=policy_id,
1356
            families=families,
1357
            auto_add_new_families=auto_add_new_families,
1358
        )
1359
1360
    def modify_tag(
1361
        self,
1362
        tag_id: str,
1363
        *,
1364
        comment: Optional[str] = None,
1365
        name: Optional[str] = None,
1366
        value=None,
1367
        active=None,
1368
        resource_action: Optional[str] = None,
1369
        resource_type: Optional[EntityType] = None,
1370
        resource_filter: Optional[str] = None,
1371
        resource_ids: Optional[List[str]] = None,
1372
    ) -> Any:
1373
        """Modifies an existing tag.
1374
1375
        Arguments:
1376
            tag_id: UUID of the tag.
1377
            comment: Comment to add to the tag.
1378
            name: Name of the tag.
1379
            value: Value of the tag.
1380
            active: Whether the tag is active.
1381
            resource_action: Whether to add or remove resources instead of
1382
                overwriting. One of '', 'add', 'set' or 'remove'.
1383
            resource_type: Type of the resources to which to attach the tag.
1384
                Required if resource_filter is set.
1385
            resource_filter: Filter term to select resources the tag is to be
1386
                attached to.
1387
            resource_ids: IDs of the resources to which to attach the tag.
1388
1389
        Returns:
1390
            The response. See :py:meth:`send_command` for details.
1391
        """
1392
        if not tag_id:
1393
            raise RequiredArgument(
1394
                function=self.modify_tag.__name__, argument='tag_id'
1395
            )
1396
1397
        cmd = XmlCommand("modify_tag")
1398
        cmd.set_attribute("tag_id", str(tag_id))
1399
1400
        if comment:
1401
            cmd.add_element("comment", comment)
1402
1403
        if name:
1404
            cmd.add_element("name", name)
1405
1406
        if value:
1407
            cmd.add_element("value", value)
1408
1409
        if active is not None:
1410
            cmd.add_element("active", _to_bool(active))
1411
1412
        if resource_action or resource_filter or resource_ids or resource_type:
1413
            if resource_filter and not resource_type:
1414
                raise RequiredArgument(
1415
                    function=self.modify_tag.__name__, argument='resource_type'
1416
                )
1417
1418
            _xmlresources = cmd.add_element("resources")
1419
            if resource_action is not None:
1420
                _xmlresources.set_attribute("action", resource_action)
1421
1422
            if resource_filter is not None:
1423
                _xmlresources.set_attribute("filter", resource_filter)
1424
1425
            for resource_id in resource_ids or []:
1426
                _xmlresources.add_element(
1427
                    "resource", attrs={"id": str(resource_id)}
1428
                )
1429
1430
            if resource_type is not None:
1431
                if not isinstance(resource_type, self.types.EntityType):
1432
                    raise InvalidArgumentType(
1433
                        function=self.modify_tag.__name__,
1434
                        argument="resource_type",
1435
                        arg_type=EntityType.__name__,
1436
                    )
1437
                _actual_resource_type = resource_type
1438
                if resource_type.value == EntityType.AUDIT.value:
1439
                    _actual_resource_type = EntityType.TASK
1440
                elif resource_type.value == EntityType.POLICY.value:
1441
                    _actual_resource_type = EntityType.SCAN_CONFIG
1442
                _xmlresources.add_element("type", _actual_resource_type.value)
1443
1444
        return self._send_xml_command(cmd)
1445
1446 View Code Duplication
    def modify_tls_certificate(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1447
        self,
1448
        tls_certificate_id: str,
1449
        *,
1450
        name: Optional[str] = None,
1451
        comment: Optional[str] = None,
1452
        trust: Optional[bool] = None,
1453
    ) -> Any:
1454
        """Modifies an existing TLS certificate.
1455
1456
        Arguments:
1457
            tls_certificate_id: UUID of the TLS certificate to be modified.
1458
            name: Name of the TLS certificate, defaulting to the MD5 fingerprint
1459
            comment: Comment for the TLS certificate.
1460
            trust: Whether the certificate is trusted.
1461
1462
        Returns:
1463
            The response. See :py:meth:`send_command` for details.
1464
        """
1465
        if not tls_certificate_id:
1466
            raise RequiredArgument(
1467
                function=self.modify_tls_certificate.__name__,
1468
                argument='tls_certificate_id',
1469
            )
1470
1471
        cmd = XmlCommand("modify_tls_certificate")
1472
        cmd.set_attribute("tls_certificate_id", str(tls_certificate_id))
1473
1474
        if comment:
1475
            cmd.add_element("comment", comment)
1476
1477
        if name:
1478
            cmd.add_element("name", name)
1479
1480
        if trust:
1481
            cmd.add_element("trust", _to_bool(trust))
1482
1483
        return self._send_xml_command(cmd)
1484
1485
    def clone_alert(self, alert_id: str) -> Any:
1486
        """Clone an existing alert
1487
1488
        Arguments:
1489
            alert_id: UUID of an existing alert to clone from
1490
1491
        Returns:
1492
            The response. See :py:meth:`send_command` for details.
1493
        """
1494
        if not alert_id:
1495
            raise RequiredArgument(
1496
                function=self.clone_alert.__name__, argument='alert_id'
1497
            )
1498
1499
        cmd = XmlCommand("create_alert")
1500
        cmd.add_element("copy", alert_id)
1501
        return self._send_xml_command(cmd)
1502
1503
    def clone_ticket(self, ticket_id: str) -> Any:
1504
        """Clone an existing ticket
1505
1506
        Arguments:
1507
            ticket_id: UUID of an existing ticket to clone from
1508
1509
        Returns:
1510
            The response. See :py:meth:`send_command` for details.
1511
        """
1512
        if not ticket_id:
1513
            raise RequiredArgument(
1514
                function=self.clone_ticket.__name__, argument='ticket_id'
1515
            )
1516
1517
        cmd = XmlCommand("create_ticket")
1518
1519
        _copy = cmd.add_element("copy", ticket_id)
1520
1521
        return self._send_xml_command(cmd)
1522
1523
    def clone_tls_certificate(self, tls_certificate_id: str) -> Any:
1524
        """Modifies an existing TLS certificate.
1525
1526
        Arguments:
1527
            tls_certificate_id: The UUID of an existing TLS certificate
1528
1529
        Returns:
1530
            The response. See :py:meth:`send_command` for details.
1531
        """
1532
        if not tls_certificate_id:
1533
            raise RequiredArgument(
1534
                function=self.clone_tls_certificate.__name__,
1535
                argument='tls_certificate_id',
1536
            )
1537
1538
        cmd = XmlCommand("create_tls_certificate")
1539
1540
        cmd.add_element("copy", tls_certificate_id)
1541
1542
        return self._send_xml_command(cmd)
1543
1544
    def get_configs(
1545
        self,
1546
        *,
1547
        filter: Optional[str] = None,
1548
        filter_id: Optional[str] = None,
1549
        trash: Optional[bool] = None,
1550
        details: Optional[bool] = None,
1551
        families: Optional[bool] = None,
1552
        preferences: Optional[bool] = None,
1553
        tasks: Optional[bool] = None,
1554
    ) -> Any:
1555
        """Request a list of scan configs
1556
1557
        Arguments:
1558
            filter: Filter term to use for the query
1559
            filter_id: UUID of an existing filter to use for the query
1560
            trash: Whether to get the trashcan scan configs instead
1561
            details: Whether to get config families, preferences, nvt selectors
1562
                and tasks.
1563
            families: Whether to include the families if no details are
1564
                requested
1565
            preferences: Whether to include the preferences if no details are
1566
                requested
1567
            tasks: Whether to get tasks using this config
1568
1569
        Returns:
1570
            The response. See :py:meth:`send_command` for details.
1571
        """
1572
        return self.__get_configs(
1573
            UsageType.SCAN,
1574
            filter=filter,
1575
            filter_id=filter_id,
1576
            trash=trash,
1577
            details=details,
1578
            families=families,
1579
            preferences=preferences,
1580
            tasks=tasks,
1581
        )
1582
1583
    def get_policies(
1584
        self,
1585
        *,
1586
        audits: Optional[bool] = None,
1587
        filter: Optional[str] = None,
1588
        filter_id: Optional[str] = None,
1589
        details: Optional[bool] = None,
1590
        families: Optional[bool] = None,
1591
        preferences: Optional[bool] = None,
1592
        trash: Optional[bool] = None,
1593
    ) -> Any:
1594
        """Request a list of policies
1595
1596
        Arguments:
1597
            audits: Whether to get audits using the policy
1598
            filter: Filter term to use for the query
1599
            filter_id: UUID of an existing filter to use for the query
1600
            details: Whether to get  families, preferences, nvt selectors
1601
                and tasks.
1602
            families: Whether to include the families if no details are
1603
                requested
1604
            preferences: Whether to include the preferences if no details are
1605
                requested
1606
            trash: Whether to get the trashcan audits instead
1607
1608
        Returns:
1609
            The response. See :py:meth:`send_command` for details.
1610
        """
1611
        return self.__get_configs(
1612
            UsageType.POLICY,
1613
            filter=filter,
1614
            filter_id=filter_id,
1615
            details=details,
1616
            families=families,
1617
            preferences=preferences,
1618
            tasks=audits,
1619
            trash=trash,
1620
        )
1621
1622
    def get_config(
1623
        self, config_id: str, *, tasks: Optional[bool] = None
1624
    ) -> Any:
1625
        """Request a single scan config
1626
1627
        Arguments:
1628
            config_id: UUID of an existing scan config
1629
            tasks: Whether to get tasks using this config
1630
1631
        Returns:
1632
            The response. See :py:meth:`send_command` for details.
1633
        """
1634
        return self.__get_config(
1635
            config_id=config_id, usage_type=UsageType.SCAN, tasks=tasks
1636
        )
1637
1638
    def get_policy(
1639
        self, policy_id: str, *, audits: Optional[bool] = None
1640
    ) -> Any:
1641
        """Request a single policy
1642
1643
        Arguments:
1644
            policy_id: UUID of an existing policy
1645
            audits: Whether to get audits using this config
1646
1647
        Returns:
1648
            The response. See :py:meth:`send_command` for details.
1649
        """
1650
        return self.__get_config(policy_id, UsageType.POLICY, tasks=audits)
1651
1652
    def get_tasks(
1653
        self,
1654
        *,
1655
        filter: Optional[str] = None,
1656
        filter_id: Optional[str] = None,
1657
        trash: Optional[bool] = None,
1658
        details: Optional[bool] = None,
1659
        schedules_only: Optional[bool] = None,
1660
    ) -> Any:
1661
        """Request a list of tasks
1662
1663
        Arguments:
1664
            filter: Filter term to use for the query
1665
            filter_id: UUID of an existing filter to use for the query
1666
            trash: Whether to get the trashcan tasks instead
1667
            details: Whether to include full task details
1668
            schedules_only: Whether to only include id, name and schedule
1669
                details
1670
1671
        Returns:
1672
            The response. See :py:meth:`send_command` for details.
1673
        """
1674
        return self.__get_tasks(
1675
            UsageType.SCAN,
1676
            filter=filter,
1677
            filter_id=filter_id,
1678
            trash=trash,
1679
            details=details,
1680
            schedules_only=schedules_only,
1681
        )
1682
1683
    def get_audits(
1684
        self,
1685
        *,
1686
        filter: Optional[str] = None,
1687
        filter_id: Optional[str] = None,
1688
        trash: Optional[bool] = None,
1689
        details: Optional[bool] = None,
1690
        schedules_only: Optional[bool] = None,
1691
    ) -> Any:
1692
        """Request a list of audits
1693
1694
        Arguments:
1695
            filter: Filter term to use for the query
1696
            filter_id: UUID of an existing filter to use for the query
1697
            trash: Whether to get the trashcan audits instead
1698
            details: Whether to include full audit details
1699
            schedules_only: Whether to only include id, name and schedule
1700
                details
1701
1702
        Returns:
1703
            The response. See :py:meth:`send_command` for details.
1704
        """
1705
        return self.__get_tasks(
1706
            UsageType.AUDIT,
1707
            filter=filter,
1708
            filter_id=filter_id,
1709
            trash=trash,
1710
            details=details,
1711
            schedules_only=schedules_only,
1712
        )
1713
1714
    def get_task(self, task_id: str) -> Any:
1715
        """Request a single task
1716
1717
        Arguments:
1718
            task_id: UUID of an existing task
1719
1720
        Returns:
1721
            The response. See :py:meth:`send_command` for details.
1722
        """
1723
        return self.__get_task(task_id, UsageType.SCAN)
1724
1725
    def get_audit(self, audit_id: str) -> Any:
1726
        """Request a single audit
1727
1728
        Arguments:
1729
            audit_id: UUID of an existing audit
1730
1731
        Returns:
1732
            The response. See :py:meth:`send_command` for details.
1733
        """
1734
        return self.__get_task(audit_id, UsageType.AUDIT)
1735
1736
    def clone_audit(self, audit_id: str) -> Any:
1737
        """Clone an existing audit
1738
1739
        Arguments:
1740
            audit_id: UUID of existing audit to clone from
1741
1742
        Returns:
1743
            The response. See :py:meth:`send_command` for details.
1744
        """
1745
        if not audit_id:
1746
            raise RequiredArgument(
1747
                function=self.clone_audit.__name__, argument='audit_id'
1748
            )
1749
1750
        cmd = XmlCommand("create_task")
1751
        cmd.add_element("copy", audit_id)
1752
        return self._send_xml_command(cmd)
1753
1754
    def clone_policy(self, policy_id: str) -> Any:
1755
        """Clone a policy from an existing one
1756
1757
        Arguments:
1758
            policy_id: UUID of the existing policy
1759
1760
        Returns:
1761
            The response. See :py:meth:`send_command` for details.
1762
        """
1763
        if not policy_id:
1764
            raise RequiredArgument(
1765
                function=self.clone_policy.__name__, argument='policy_id'
1766
            )
1767
1768
        cmd = XmlCommand("create_config")
1769
        cmd.add_element("copy", policy_id)
1770
        return self._send_xml_command(cmd)
1771
1772
    def delete_audit(
1773
        self, audit_id: str, *, ultimate: Optional[bool] = False
1774
    ) -> Any:
1775
        """Deletes an existing audit
1776
1777
        Arguments:
1778
            audit_id: UUID of the audit to be deleted.
1779
            ultimate: Whether to remove entirely, or to the trashcan.
1780
        """
1781
        if not audit_id:
1782
            raise RequiredArgument(
1783
                function=self.delete_audit.__name__, argument='audit_id'
1784
            )
1785
1786
        cmd = XmlCommand("delete_task")
1787
        cmd.set_attribute("task_id", audit_id)
1788
        cmd.set_attribute("ultimate", _to_bool(ultimate))
1789
1790
        return self._send_xml_command(cmd)
1791
1792
    def delete_policy(
1793
        self, policy_id: str, *, ultimate: Optional[bool] = False
1794
    ) -> Any:
1795
        """Deletes an existing policy
1796
1797
        Arguments:
1798
            policy_id: UUID of the policy to be deleted.
1799
            ultimate: Whether to remove entirely, or to the trashcan.
1800
        """
1801
        if not policy_id:
1802
            raise RequiredArgument(
1803
                function=self.delete_policy.__name__, argument='policy_id'
1804
            )
1805
1806
        cmd = XmlCommand("delete_config")
1807
        cmd.set_attribute("config_id", policy_id)
1808
        cmd.set_attribute("ultimate", _to_bool(ultimate))
1809
1810
        return self._send_xml_command(cmd)
1811
1812
    def delete_tls_certificate(self, tls_certificate_id: str) -> Any:
1813
        """Deletes an existing tls certificate
1814
1815
        Arguments:
1816
            tls_certificate_id: UUID of the tls certificate to be deleted.
1817
        """
1818
        if not tls_certificate_id:
1819
            raise RequiredArgument(
1820
                function=self.delete_tls_certificate.__name__,
1821
                argument='tls_certificate_id',
1822
            )
1823
1824
        cmd = XmlCommand("delete_tls_certificate")
1825
        cmd.set_attribute("tls_certificate_id", tls_certificate_id)
1826
1827
        return self._send_xml_command(cmd)
1828
1829
    def __create_task(
1830
        self,
1831
        name: str,
1832
        config_id: str,
1833
        target_id: str,
1834
        scanner_id: str,
1835
        usage_type: UsageType,
1836
        function: str,
1837
        *,
1838
        alterable: Optional[bool] = None,
1839
        hosts_ordering: Optional[HostsOrdering] = None,
1840
        schedule_id: Optional[str] = None,
1841
        alert_ids: Optional[List[str]] = None,
1842
        comment: Optional[str] = None,
1843
        schedule_periods: Optional[int] = None,
1844
        observers: Optional[List[str]] = None,
1845
        preferences: Optional[dict] = None,
1846
    ) -> Any:
1847
        if not name:
1848
            raise RequiredArgument(function=function, argument='name')
1849
1850
        if not config_id:
1851
            raise RequiredArgument(function=function, argument='config_id')
1852
1853
        if not target_id:
1854
            raise RequiredArgument(function=function, argument='target_id')
1855
1856
        if not scanner_id:
1857
            raise RequiredArgument(function=function, argument='scanner_id')
1858
1859
        # don't allow to create a container task with create_task
1860
        if target_id == '0':
1861
            raise InvalidArgument(function=function, argument='target_id')
1862
1863
        cmd = XmlCommand("create_task")
1864
        cmd.add_element("name", name)
1865
        cmd.add_element("usage_type", usage_type.value)
1866
        cmd.add_element("config", attrs={"id": config_id})
1867
        cmd.add_element("target", attrs={"id": target_id})
1868
        cmd.add_element("scanner", attrs={"id": scanner_id})
1869
1870
        if comment:
1871
            cmd.add_element("comment", comment)
1872
1873
        if alterable is not None:
1874
            cmd.add_element("alterable", _to_bool(alterable))
1875
1876
        if hosts_ordering:
1877
            if not isinstance(hosts_ordering, self.types.HostsOrdering):
1878
                raise InvalidArgumentType(
1879
                    function=function,
1880
                    argument='hosts_ordering',
1881
                    arg_type=HostsOrdering.__name__,
1882
                )
1883
            cmd.add_element("hosts_ordering", hosts_ordering.value)
1884
1885
        if alert_ids:
1886
            if isinstance(alert_ids, str):
1887
                deprecation(
1888
                    "Please pass a list as alert_ids parameter to {}. "
1889
                    "Passing a string is deprecated and will be removed in "
1890
                    "future.".format(function)
1891
                )
1892
1893
                # if a single id is given as a string wrap it into a list
1894
                alert_ids = [alert_ids]
1895
            if _is_list_like(alert_ids):
1896
                # parse all given alert id's
1897
                for alert in alert_ids:
1898
                    cmd.add_element("alert", attrs={"id": str(alert)})
1899
1900
        if schedule_id:
1901
            cmd.add_element("schedule", attrs={"id": schedule_id})
1902
1903 View Code Duplication
            if schedule_periods is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1904
                if (
1905
                    not isinstance(schedule_periods, numbers.Integral)
1906
                    or schedule_periods < 0
1907
                ):
1908
                    raise InvalidArgument(
1909
                        "schedule_periods must be an integer greater or equal "
1910
                        "than 0"
1911
                    )
1912
                cmd.add_element("schedule_periods", str(schedule_periods))
1913
1914
        if observers is not None:
1915
            if not _is_list_like(observers):
1916
                raise InvalidArgumentType(
1917
                    function=function, argument='observers', arg_type='list'
1918
                )
1919
1920
            # gvmd splits by comma and space
1921
            # gvmd tries to lookup each value as user name and afterwards as
1922
            # user id. So both user name and user id are possible
1923
            cmd.add_element("observers", _to_comma_list(observers))
1924
1925 View Code Duplication
        if preferences is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1926
            if not isinstance(preferences, collections.abc.Mapping):
1927
                raise InvalidArgumentType(
1928
                    function=function,
1929
                    argument='preferences',
1930
                    arg_type=collections.abc.Mapping.__name__,
1931
                )
1932
1933
            _xmlprefs = cmd.add_element("preferences")
1934
            for pref_name, pref_value in preferences.items():
1935
                _xmlpref = _xmlprefs.add_element("preference")
1936
                _xmlpref.add_element("scanner_name", pref_name)
1937
                _xmlpref.add_element("value", str(pref_value))
1938
1939
        return self._send_xml_command(cmd)
1940
1941
    def __create_config(
1942
        self,
1943
        config_id: str,
1944
        name: str,
1945
        usage_type: UsageType,
1946
        function: str,
1947
        *,
1948
        comment: Optional[str] = None,
1949
    ) -> Any:
1950
        if not name:
1951
            raise RequiredArgument(function=function, argument='name')
1952
1953
        if not config_id:
1954
            raise RequiredArgument(function=function, argument='config_id')
1955
1956
        cmd = XmlCommand("create_config")
1957
        if comment is not None:
1958
            cmd.add_element("comment", comment)
1959
        cmd.add_element("copy", config_id)
1960
        cmd.add_element("name", name)
1961
        cmd.add_element("usage_type", usage_type.value)
1962
        return self._send_xml_command(cmd)
1963
1964
    def __create_config_from_osp_scanner(
1965
        self,
1966
        scanner_id: str,
1967
        name: str,
1968
        usage_type: UsageType,
1969
        function: str,
1970
        *,
1971
        comment: Optional[str] = None,
1972
    ) -> Any:
1973
        if not name:
1974
            raise RequiredArgument(function=function, argument='name')
1975
1976
        if not scanner_id:
1977
            raise RequiredArgument(function=function, argument='scanner_id')
1978
1979
        cmd = XmlCommand("create_config")
1980
        if comment is not None:
1981
            cmd.add_element("comment", comment)
1982
        cmd.add_element("scanner", scanner_id)
1983
        cmd.add_element("name", name)
1984
        cmd.add_element("usage_type", usage_type.value)
1985
        return self._send_xml_command(cmd)
1986
1987
    def __get_configs(
1988
        self,
1989
        usage_type: UsageType,
1990
        *,
1991
        filter: Optional[str] = None,
1992
        filter_id: Optional[str] = None,
1993
        trash: Optional[bool] = None,
1994
        details: Optional[bool] = None,
1995
        families: Optional[bool] = None,
1996
        preferences: Optional[bool] = None,
1997
        tasks: Optional[bool] = None,
1998
    ) -> Any:
1999
        cmd = XmlCommand("get_configs")
2000
        cmd.set_attribute("usage_type", usage_type.value)
2001
2002
        _add_filter(cmd, filter, filter_id)
2003
2004
        if trash is not None:
2005
            cmd.set_attribute("trash", _to_bool(trash))
2006
2007
        if details is not None:
2008
            cmd.set_attribute("details", _to_bool(details))
2009
2010
        if families is not None:
2011
            cmd.set_attribute("families", _to_bool(families))
2012
2013
        if preferences is not None:
2014
            cmd.set_attribute("preferences", _to_bool(preferences))
2015
2016
        if tasks is not None:
2017
            cmd.set_attribute("tasks", _to_bool(tasks))
2018
2019
        return self._send_xml_command(cmd)
2020
2021
    def __get_config(
2022
        self,
2023
        config_id: str,
2024
        usage_type: UsageType,
2025
        *,
2026
        tasks: Optional[bool] = None,
2027
    ) -> Any:
2028
        if not config_id:
2029
            raise RequiredArgument(
2030
                function=self.get_config.__name__, argument='config_id'
2031
            )
2032
2033
        cmd = XmlCommand("get_configs")
2034
        cmd.set_attribute("config_id", config_id)
2035
2036
        cmd.set_attribute("usage_type", usage_type.value)
2037
2038
        if tasks is not None:
2039
            cmd.set_attribute("tasks", _to_bool(tasks))
2040
2041
        # for single entity always request all details
2042
        cmd.set_attribute("details", "1")
2043
2044
        return self._send_xml_command(cmd)
2045
2046
    def __get_tasks(
2047
        self,
2048
        usage_type: UsageType,
2049
        *,
2050
        filter: Optional[str] = None,
2051
        filter_id: Optional[str] = None,
2052
        trash: Optional[bool] = None,
2053
        details: Optional[bool] = None,
2054
        schedules_only: Optional[bool] = None,
2055
    ) -> Any:
2056
        cmd = XmlCommand("get_tasks")
2057
        cmd.set_attribute("usage_type", usage_type.value)
2058
2059
        _add_filter(cmd, filter, filter_id)
2060
2061
        if trash is not None:
2062
            cmd.set_attribute("trash", _to_bool(trash))
2063
2064
        if details is not None:
2065
            cmd.set_attribute("details", _to_bool(details))
2066
2067
        if schedules_only is not None:
2068
            cmd.set_attribute("schedules_only", _to_bool(schedules_only))
2069
2070
        return self._send_xml_command(cmd)
2071
2072
    def __get_task(self, task_id: str, usage_type: UsageType) -> Any:
2073
        if not task_id:
2074
            raise RequiredArgument(
2075
                function=self.get_task.__name__, argument='task_id'
2076
            )
2077
2078
        cmd = XmlCommand("get_tasks")
2079
        cmd.set_attribute("task_id", task_id)
2080
        cmd.set_attribute("usage_type", usage_type.value)
2081
2082
        # for single entity always request all details
2083
        cmd.set_attribute("details", "1")
2084
        return self._send_xml_command(cmd)
2085
2086
    def resume_audit(self, audit_id: str) -> Any:
2087
        """Resume an existing stopped audit
2088
2089
        Arguments:
2090
            audit_id: UUID of the audit to be resumed
2091
2092
        Returns:
2093
            The response. See :py:meth:`send_command` for details.
2094
        """
2095
        if not audit_id:
2096
            raise RequiredArgument(
2097
                function=self.resume_audit.__name__, argument='audit_id'
2098
            )
2099
2100
        cmd = XmlCommand("resume_task")
2101
        cmd.set_attribute("task_id", audit_id)
2102
2103
        return self._send_xml_command(cmd)
2104
2105
    def start_audit(self, audit_id: str) -> Any:
2106
        """Start an existing audit
2107
2108
        Arguments:
2109
            audit_id: UUID of the audit to be started
2110
2111
        Returns:
2112
            The response. See :py:meth:`send_command` for details.
2113
        """
2114
        if not audit_id:
2115
            raise RequiredArgument(
2116
                function=self.start_audit.__name__, argument='audit_id'
2117
            )
2118
2119
        cmd = XmlCommand("start_task")
2120
        cmd.set_attribute("task_id", audit_id)
2121
2122
        return self._send_xml_command(cmd)
2123
2124
    def stop_audit(self, audit_id: str) -> Any:
2125
        """Stop an existing running audit
2126
2127
        Arguments:
2128
            audit_id: UUID of the audit to be stopped
2129
2130
        Returns:
2131
            The response. See :py:meth:`send_command` for details.
2132
        """
2133
        if not audit_id:
2134
            raise RequiredArgument(
2135
                function=self.stop_audit.__name__, argument='audit_id'
2136
            )
2137
2138
        cmd = XmlCommand("stop_task")
2139
        cmd.set_attribute("task_id", audit_id)
2140
2141
        return self._send_xml_command(cmd)
2142
2143
    def import_report(
2144
        self,
2145
        report: str,
2146
        *,
2147
        task_id: Optional[str] = None,
2148
        in_assets: Optional[bool] = None,
2149
    ) -> Any:
2150
        """Import a Report from XML
2151
2152
        Arguments:
2153
            report: Report XML as string to import. This XML must contain
2154
                a :code:`<report>` root element.
2155
            task_id: UUID of task to import report to
2156
            in_asset: Whether to create or update assets using the report
2157
2158
        Returns:
2159
            The response. See :py:meth:`send_command` for details.
2160
        """
2161
        if not report:
2162
            raise RequiredArgument(
2163
                function=self.import_report.__name__, argument='report'
2164
            )
2165
2166
        cmd = XmlCommand("create_report")
2167
2168
        if task_id:
2169
            cmd.add_element("task", attrs={"id": task_id})
2170
        else:
2171
            raise RequiredArgument(
2172
                function=self.import_report.__name__, argument='task_id'
2173
            )
2174
2175
        if in_assets is not None:
2176
            cmd.add_element("in_assets", _to_bool(in_assets))
2177
2178
        try:
2179
            cmd.append_xml_str(report)
2180
        except etree.XMLSyntaxError as e:
2181
            raise InvalidArgument(
2182
                "Invalid xml passed as report to import_report {}".format(e)
2183
            ) from None
2184
2185
        return self._send_xml_command(cmd)
2186
2187
    def get_info_list(
2188
        self,
2189
        info_type: InfoType,
2190
        *,
2191
        filter: Optional[str] = None,
2192
        filter_id: Optional[str] = None,
2193
        name: Optional[str] = None,
2194
        details: Optional[bool] = None,
2195
    ) -> Any:
2196
        """Request a list of security information
2197
2198
        Arguments:
2199
            info_type: Type must be either CERT_BUND_ADV, CPE, CVE,
2200
                DFN_CERT_ADV, OVALDEF, NVT or ALLINFO
2201
            filter: Filter term to use for the query
2202
            filter_id: UUID of an existing filter to use for the query
2203
            name: Name or identifier of the requested information
2204
            details: Whether to include information about references to this
2205
                information
2206
2207
        Returns:
2208
            The response. See :py:meth:`send_command` for details.
2209
        """
2210
        if not info_type:
2211
            raise RequiredArgument(
2212
                function=self.get_info_list.__name__, argument='info_type'
2213
            )
2214
2215
        if not isinstance(info_type, InfoType):
2216
            raise InvalidArgumentType(
2217
                function=self.get_info_list.__name__,
2218
                argument='info_type',
2219
                arg_type=InfoType.__name__,
2220
            )
2221
2222
        cmd = XmlCommand("get_info")
2223
2224
        cmd.set_attribute("type", info_type.value)
2225
2226
        _add_filter(cmd, filter, filter_id)
2227
2228
        if name:
2229
            cmd.set_attribute("name", name)
2230
2231
        if details is not None:
2232
            cmd.set_attribute("details", _to_bool(details))
2233
2234
        return self._send_xml_command(cmd)
2235
2236
    def get_info(self, info_id: str, info_type: InfoType) -> Any:
2237
        """Request a single secinfo
2238
2239
        Arguments:
2240
            info_id: UUID of an existing secinfo
2241
            info_type: Type must be either CERT_BUND_ADV, CPE, CVE,
2242
                DFN_CERT_ADV, OVALDEF, NVT
2243
2244
        Returns:
2245
            The response. See :py:meth:`send_command` for details.
2246
        """
2247
        if not info_type:
2248
            raise RequiredArgument(
2249
                function=self.get_info.__name__, argument='info_type'
2250
            )
2251
2252
        if not isinstance(info_type, InfoType):
2253
            raise InvalidArgumentType(
2254
                function=self.get_info.__name__,
2255
                argument='info_type',
2256
                arg_type=InfoType.__name__,
2257
            )
2258
2259
        if not info_id:
2260
            raise RequiredArgument(
2261
                function=self.get_info.__name__, argument='info_id'
2262
            )
2263
2264
        cmd = XmlCommand("get_info")
2265
        cmd.set_attribute("info_id", info_id)
2266
2267
        cmd.set_attribute("type", info_type.value)
2268
2269
        # for single entity always request all details
2270
        cmd.set_attribute("details", "1")
2271
        return self._send_xml_command(cmd)
2272
2273
    def create_target(
2274
        self,
2275
        name: str,
2276
        *,
2277
        make_unique: Optional[bool] = None,
2278
        asset_hosts_filter: Optional[str] = None,
2279
        hosts: Optional[List[str]] = None,
2280
        comment: Optional[str] = None,
2281
        exclude_hosts: Optional[List[str]] = None,
2282
        ssh_credential_id: Optional[str] = None,
2283
        ssh_credential_port: Optional[int] = None,
2284
        smb_credential_id: Optional[str] = None,
2285
        esxi_credential_id: Optional[str] = None,
2286
        snmp_credential_id: Optional[str] = None,
2287
        alive_test: Optional[AliveTest] = None,
2288
        reverse_lookup_only: Optional[bool] = None,
2289
        reverse_lookup_unify: Optional[bool] = None,
2290
        port_range: Optional[str] = None,
2291
        port_list_id: Optional[str] = None,
2292
    ) -> Any:
2293
        """Create a new target
2294
2295
        Arguments:
2296
            name: Name of the target
2297
            make_unique: Deprecated. Will be ignored.
2298
            asset_hosts_filter: Filter to select target host from assets hosts
2299
            hosts: List of hosts addresses to scan
2300
            exclude_hosts: List of hosts addresses to exclude from scan
2301
            comment: Comment for the target
2302
            ssh_credential_id: UUID of a ssh credential to use on target
2303
            ssh_credential_port: The port to use for ssh credential
2304
            smb_credential_id: UUID of a smb credential to use on target
2305
            snmp_credential_id: UUID of a snmp credential to use on target
2306
            esxi_credential_id: UUID of a esxi credential to use on target
2307
            alive_test: Which alive test to use
2308
            reverse_lookup_only: Whether to scan only hosts that have names
2309
            reverse_lookup_unify: Whether to scan only one IP when multiple IPs
2310
                have the same name.
2311
            port_range: Port range for the target
2312
            port_list_id: UUID of the port list to use on target
2313
2314
        Returns:
2315
            The response. See :py:meth:`send_command` for details.
2316
        """
2317
2318
        cmd = XmlCommand("create_target")
2319
        _xmlname = cmd.add_element("name", name)
2320
2321
        if make_unique is not None:
2322
            warnings.warn(
2323
                'create_target make_unique argument is deprecated '
2324
                'and will be ignored.',
2325
                DeprecationWarning,
2326
            )
2327
2328
        if not name:
2329
            raise RequiredArgument(
2330
                function=self.create_target.__name__, argument='name'
2331
            )
2332
2333
        if asset_hosts_filter:
2334
            cmd.add_element(
2335
                "asset_hosts", attrs={"filter": str(asset_hosts_filter)}
2336
            )
2337
        elif hosts:
2338
            cmd.add_element("hosts", _to_comma_list(hosts))
2339
        else:
2340
            raise RequiredArgument(
2341
                function=self.create_target.__name__,
2342
                argument='hosts or asset_hosts_filter',
2343
            )
2344
2345
        if comment:
2346
            cmd.add_element("comment", comment)
2347
2348
        if exclude_hosts:
2349
            cmd.add_element("exclude_hosts", _to_comma_list(exclude_hosts))
2350
2351
        if ssh_credential_id:
2352
            _xmlssh = cmd.add_element(
2353
                "ssh_credential", attrs={"id": ssh_credential_id}
2354
            )
2355
            if ssh_credential_port:
2356
                _xmlssh.add_element("port", str(ssh_credential_port))
2357
2358
        if smb_credential_id:
2359
            cmd.add_element("smb_credential", attrs={"id": smb_credential_id})
2360
2361
        if esxi_credential_id:
2362
            cmd.add_element("esxi_credential", attrs={"id": esxi_credential_id})
2363
2364
        if snmp_credential_id:
2365
            cmd.add_element("snmp_credential", attrs={"id": snmp_credential_id})
2366
2367
        if alive_test:
2368
            if not isinstance(alive_test, AliveTest):
2369
                raise InvalidArgumentType(
2370
                    function=self.create_target.__name__,
2371
                    argument='alive_test',
2372
                    arg_type=AliveTest.__name__,
2373
                )
2374
2375
            cmd.add_element("alive_tests", alive_test.value)
2376
2377
        if reverse_lookup_only is not None:
2378
            cmd.add_element(
2379
                "reverse_lookup_only", _to_bool(reverse_lookup_only)
2380
            )
2381
2382
        if reverse_lookup_unify is not None:
2383
            cmd.add_element(
2384
                "reverse_lookup_unify", _to_bool(reverse_lookup_unify)
2385
            )
2386
2387
        # since 20.08 one of port_range or port_list_id is required!
2388
        if not port_range and not port_list_id:
2389
            raise RequiredArgument(
2390
                function=self.create_target.__name__,
2391
                argument='port_range or port_list_id',
2392
            )
2393
2394
        if port_range:
2395
            cmd.add_element("port_range", port_range)
2396
2397
        if port_list_id:
2398
            cmd.add_element("port_list", attrs={"id": port_list_id})
2399
2400
        return self._send_xml_command(cmd)
2401
2402
    def get_feed(self, feed_type: Optional[FeedType]) -> Any:
2403
        """Request a single feed
2404
2405
        Arguments:
2406
            feed_type: Type of single feed to get: NVT, CERT or SCAP
2407
2408
        Returns:
2409
            The response. See :py:meth:`send_command` for details.
2410
        """
2411
        if not feed_type:
2412
            raise RequiredArgument(
2413
                function=self.get_feed.__name__, argument='feed_type'
2414
            )
2415
2416
        if not isinstance(feed_type, FeedType):
2417
            raise InvalidArgumentType(
2418
                function=self.get_feed.__name__,
2419
                argument='feed_type',
2420
                arg_type=FeedType.__name__,
2421
            )
2422
2423
        cmd = XmlCommand("get_feeds")
2424
        cmd.set_attribute("type", feed_type.value)
2425
2426
        return self._send_xml_command(cmd)
2427
2428
    def create_credential(
2429
        self,
2430
        name: str,
2431
        credential_type: CredentialType,
2432
        *,
2433
        comment: Optional[str] = None,
2434
        allow_insecure: Optional[bool] = None,
2435
        certificate: Optional[str] = None,
2436
        key_phrase: Optional[str] = None,
2437
        private_key: Optional[str] = None,
2438
        login: Optional[str] = None,
2439
        password: Optional[str] = None,
2440
        auth_algorithm: Optional[SnmpAuthAlgorithm] = None,
2441
        community: Optional[str] = None,
2442
        privacy_algorithm: Optional[SnmpPrivacyAlgorithm] = None,
2443
        privacy_password: Optional[str] = None,
2444
        public_key: Optional[str] = None,
2445
    ) -> Any:
2446
        """Create a new credential
2447
2448
        Create a new credential e.g. to be used in the method of an alert.
2449
2450
        Currently the following credential types are supported:
2451
2452
            - Username + Password
2453
            - Username + SSH-Key
2454
            - Client Certificates
2455
            - SNMPv1 or SNMPv2c protocol
2456
            - S/MIME Certificate
2457
            - OpenPGP Key
2458
            - Password only
2459
2460
        Arguments:
2461
            name: Name of the new credential
2462
            credential_type: The credential type.
2463
            comment: Comment for the credential
2464
            allow_insecure: Whether to allow insecure use of the credential
2465
            certificate: Certificate for the credential.
2466
                Required for client-certificate and smime credential types.
2467
            key_phrase: Key passphrase for the private key.
2468
                Used for the username+ssh-key credential type.
2469
            private_key: Private key to use for login. Required
2470
                for usk credential type. Also used for the cc credential type.
2471
                The supported key types (dsa, rsa, ecdsa, ...) and formats (PEM,
2472
                PKC#12, OpenSSL, ...) depend on your installed GnuTLS version.
2473
            login: Username for the credential. Required for username+password,
2474
                username+ssh-key and snmp credential type.
2475
            password: Password for the credential. Used for username+password
2476
                and snmp credential types.
2477
            community: The SNMP community
2478
            auth_algorithm: The SNMP authentication algorithm. Required for snmp
2479
                credential type.
2480
            privacy_algorithm: The SNMP privacy algorithm
2481
            privacy_password: The SNMP privacy password
2482
            public_key: PGP public key in *armor* plain text format. Required
2483
                for pgp credential type.
2484
2485
        Examples:
2486
            Creating a Username + Password credential
2487
2488
            .. code-block:: python
2489
2490
                gmp.create_credential(
2491
                    name='UP Credential',
2492
                    credential_type=CredentialType.USERNAME_PASSWORD,
2493
                    login='foo',
2494
                    password='bar',
2495
                )
2496
2497
            Creating a Username + SSH Key credential
2498
2499
            .. code-block:: python
2500
2501
                with open('path/to/private-ssh-key') as f:
2502
                    key = f.read()
2503
2504
                gmp.create_credential(
2505
                    name='USK Credential',
2506
                    credential_type=CredentialType.USERNAME_SSH_KEY,
2507
                    login='foo',
2508
                    key_phrase='foobar',
2509
                    private_key=key,
2510
                )
2511
2512
            Creating a PGP credential
2513
2514
            .. note::
2515
2516
                A compatible public pgp key file can be exported with GnuPG via
2517
                ::
2518
2519
                    $ gpg --armor --export [email protected] > alice.asc
2520
2521
            .. code-block:: python
2522
2523
                with open('path/to/pgp.key.asc') as f:
2524
                    key = f.read()
2525
2526
                gmp.create_credential(
2527
                    name='PGP Credential',
2528
                    credential_type=CredentialType.PGP_ENCRYPTION_KEY,
2529
                    public_key=key,
2530
                )
2531
2532
            Creating a S/MIME credential
2533
2534
            .. code-block:: python
2535
2536
                with open('path/to/smime-cert') as f:
2537
                    cert = f.read()
2538
2539
                gmp.create_credential(
2540
                    name='SMIME Credential',
2541
                    credential_type=CredentialType.SMIME_CERTIFICATE,
2542
                    certificate=cert,
2543
                )
2544
2545
            Creating a Password-Only credential
2546
2547
            .. code-block:: python
2548
2549
                gmp.create_credential(
2550
                    name='Password-Only Credential',
2551
                    credential_type=CredentialType.PASSWORD_ONLY,
2552
                    password='foo',
2553
                )
2554
        Returns:
2555
            The response. See :py:meth:`send_command` for details.
2556
        """
2557
        if not name:
2558
            raise RequiredArgument(
2559
                function=self.create_credential.__name__, argument='name'
2560
            )
2561
2562
        if not isinstance(credential_type, self.types.CredentialType):
2563
            raise InvalidArgumentType(
2564
                function=self.create_credential.__name__,
2565
                argument='credential_type',
2566
                arg_type=CredentialType.__name__,
2567
            )
2568
2569
        cmd = XmlCommand("create_credential")
2570
        cmd.add_element("name", name)
2571
2572
        cmd.add_element("type", credential_type.value)
2573
2574
        if comment:
2575
            cmd.add_element("comment", comment)
2576
2577
        if allow_insecure is not None:
2578
            cmd.add_element("allow_insecure", _to_bool(allow_insecure))
2579
2580
        if (
2581
            credential_type == CredentialType.CLIENT_CERTIFICATE
2582
            or credential_type == CredentialType.SMIME_CERTIFICATE
2583
        ):
2584
            if not certificate:
2585
                raise RequiredArgument(
2586
                    function=self.create_credential.__name__,
2587
                    argument='certificate',
2588
                )
2589
2590
            cmd.add_element("certificate", certificate)
2591
2592
        if (
2593
            credential_type == CredentialType.USERNAME_PASSWORD
2594
            or credential_type == CredentialType.USERNAME_SSH_KEY
2595
            or credential_type == CredentialType.SNMP
2596
        ):
2597
            if not login:
2598
                raise RequiredArgument(
2599
                    function=self.create_credential.__name__, argument='login'
2600
                )
2601
2602
            cmd.add_element("login", login)
2603
2604
        if credential_type == CredentialType.PASSWORD_ONLY and not password:
2605
            raise RequiredArgument(
2606
                function=self.create_credential.__name__, argument='password'
2607
            )
2608
2609
        if (
2610
            credential_type == CredentialType.USERNAME_PASSWORD
2611
            or credential_type == CredentialType.SNMP
2612
            or credential_type == CredentialType.PASSWORD_ONLY
2613
        ) and password:
2614
            cmd.add_element("password", password)
2615
2616
        if credential_type == CredentialType.USERNAME_SSH_KEY:
2617
            if not private_key:
2618
                raise RequiredArgument(
2619
                    function=self.create_credential.__name__,
2620
                    argument='private_key',
2621
                )
2622
2623
            _xmlkey = cmd.add_element("key")
2624
            _xmlkey.add_element("private", private_key)
2625
2626
            if key_phrase:
2627
                _xmlkey.add_element("phrase", key_phrase)
2628
2629
        if credential_type == CredentialType.CLIENT_CERTIFICATE and private_key:
2630
            _xmlkey = cmd.add_element("key")
2631
            _xmlkey.add_element("private", private_key)
2632
2633
        if credential_type == CredentialType.SNMP:
2634
            if not isinstance(auth_algorithm, self.types.SnmpAuthAlgorithm):
2635
                raise InvalidArgumentType(
2636
                    function=self.create_credential.__name__,
2637
                    argument='auth_algorithm',
2638
                    arg_type=SnmpAuthAlgorithm.__name__,
2639
                )
2640
2641
            cmd.add_element("auth_algorithm", auth_algorithm.value)
2642
2643
            if community:
2644
                cmd.add_element("community", community)
2645
2646 View Code Duplication
            if privacy_algorithm is not None or privacy_password:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2647
                _xmlprivacy = cmd.add_element("privacy")
2648
2649
                if privacy_algorithm is not None:
2650
                    if not isinstance(
2651
                        privacy_algorithm, self.types.SnmpPrivacyAlgorithm
2652
                    ):
2653
                        raise InvalidArgumentType(
2654
                            function=self.create_credential.__name__,
2655
                            argument='privacy_algorithm',
2656
                            arg_type=SnmpPrivacyAlgorithm.__name__,
2657
                        )
2658
2659
                    _xmlprivacy.add_element(
2660
                        "algorithm", privacy_algorithm.value
2661
                    )
2662
2663
                if privacy_password:
2664
                    _xmlprivacy.add_element("password", privacy_password)
2665
2666
        if credential_type == CredentialType.PGP_ENCRYPTION_KEY:
2667
            if not public_key:
2668
                raise RequiredArgument(
2669
                    function=self.create_credential.__name__,
2670
                    argument='public_key',
2671
                )
2672
2673
            _xmlkey = cmd.add_element("key")
2674
            _xmlkey.add_element("public", public_key)
2675
2676
        return self._send_xml_command(cmd)
2677
2678
    def modify_credential(
2679
        self,
2680
        credential_id: str,
2681
        *,
2682
        name: Optional[str] = None,
2683
        comment: Optional[str] = None,
2684
        allow_insecure: Optional[bool] = None,
2685
        certificate: Optional[str] = None,
2686
        key_phrase: Optional[str] = None,
2687
        private_key: Optional[str] = None,
2688
        login: Optional[str] = None,
2689
        password: Optional[str] = None,
2690
        auth_algorithm: Optional[SnmpAuthAlgorithm] = None,
2691
        community: Optional[str] = None,
2692
        privacy_algorithm: Optional[SnmpPrivacyAlgorithm] = None,
2693
        privacy_password: Optional[str] = None,
2694
        public_key: Optional[str] = None,
2695
    ) -> Any:
2696
        """Modifies an existing credential.
2697
2698
        Arguments:
2699
            credential_id: UUID of the credential
2700
            name: Name of the credential
2701
            comment: Comment for the credential
2702
            allow_insecure: Whether to allow insecure use of the credential
2703
            certificate: Certificate for the credential
2704
            key_phrase: Key passphrase for the private key
2705
            private_key: Private key to use for login
2706
            login: Username for the credential
2707
            password: Password for the credential
2708
            auth_algorithm: The authentication algorithm for SNMP
2709
            community: The SNMP community
2710
            privacy_algorithm: The privacy algorithm for SNMP
2711
            privacy_password: The SNMP privacy password
2712
            public_key: PGP public key in *armor* plain text format
2713
2714
        Returns:
2715
            The response. See :py:meth:`send_command` for details.
2716
        """
2717
        if not credential_id:
2718
            raise RequiredArgument(
2719
                function=self.modify_credential.__name__,
2720
                argument='credential_id',
2721
            )
2722
2723
        cmd = XmlCommand("modify_credential")
2724
        cmd.set_attribute("credential_id", credential_id)
2725
2726
        if comment:
2727
            cmd.add_element("comment", comment)
2728
2729
        if name:
2730
            cmd.add_element("name", name)
2731
2732
        if allow_insecure is not None:
2733
            cmd.add_element("allow_insecure", _to_bool(allow_insecure))
2734
2735
        if certificate:
2736
            cmd.add_element("certificate", certificate)
2737
2738
        if key_phrase and private_key:
2739
            _xmlkey = cmd.add_element("key")
2740
            _xmlkey.add_element("phrase", key_phrase)
2741
            _xmlkey.add_element("private", private_key)
2742
        elif (not key_phrase and private_key) or (
2743
            key_phrase and not private_key
2744
        ):
2745
            raise RequiredArgument(
2746
                function=self.modify_credential.__name__,
2747
                argument='key_phrase and private_key',
2748
            )
2749
2750
        if login:
2751
            cmd.add_element("login", login)
2752
2753
        if password:
2754
            cmd.add_element("password", password)
2755
2756
        if auth_algorithm:
2757
            if not isinstance(auth_algorithm, self.types.SnmpAuthAlgorithm):
2758
                raise InvalidArgumentType(
2759
                    function=self.modify_credential.__name__,
2760
                    argument='auth_algorithm',
2761
                    arg_type=SnmpAuthAlgorithm.__name__,
2762
                )
2763
            cmd.add_element("auth_algorithm", auth_algorithm.value)
2764
2765
        if community:
2766
            cmd.add_element("community", community)
2767
2768 View Code Duplication
        if privacy_algorithm is not None or privacy_password is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2769
            _xmlprivacy = cmd.add_element("privacy")
2770
2771
            if privacy_algorithm is not None:
2772
                if not isinstance(
2773
                    privacy_algorithm, self.types.SnmpPrivacyAlgorithm
2774
                ):
2775
                    raise InvalidArgumentType(
2776
                        function=self.modify_credential.__name__,
2777
                        argument='privacy_algorithm',
2778
                        arg_type=SnmpPrivacyAlgorithm.__name__,
2779
                    )
2780
2781
                _xmlprivacy.add_element("algorithm", privacy_algorithm.value)
2782
2783
            if privacy_password is not None:
2784
                _xmlprivacy.add_element("password", privacy_password)
2785
2786
        if public_key:
2787
            _xmlkey = cmd.add_element("key")
2788
            _xmlkey.add_element("public", public_key)
2789
2790
        return self._send_xml_command(cmd)
2791
2792
    def create_ticket(
2793
        self,
2794
        *,
2795
        result_id: str,
2796
        assigned_to_user_id: str,
2797
        note: str,
2798
        comment: Optional[str] = None,
2799
    ) -> Any:
2800
        """Create a new ticket
2801
2802
        Arguments:
2803
            result_id: UUID of the result the ticket applies to
2804
            assigned_to_user_id: UUID of a user the ticket should be assigned to
2805
            note: A note about opening the ticket
2806
            comment: Comment for the ticket
2807
2808
        Returns:
2809
            The response. See :py:meth:`send_command` for details.
2810
        """
2811
        if not result_id:
2812
            raise RequiredArgument(
2813
                function=self.create_ticket.__name__, argument='result_id'
2814
            )
2815
2816
        if not assigned_to_user_id:
2817
            raise RequiredArgument(
2818
                function=self.create_ticket.__name__,
2819
                argument='assigned_to_user_id',
2820
            )
2821
2822
        if not note:
2823
            raise RequiredArgument(
2824
                function=self.create_ticket.__name__, argument='note'
2825
            )
2826
2827
        cmd = XmlCommand("create_ticket")
2828
2829
        _result = cmd.add_element("result")
2830
        _result.set_attribute("id", result_id)
2831
2832
        _assigned = cmd.add_element("assigned_to")
2833
        _user = _assigned.add_element("user")
2834
        _user.set_attribute("id", assigned_to_user_id)
2835
2836
        _note = cmd.add_element("open_note", note)
2837
2838
        if comment:
2839
            cmd.add_element("comment", comment)
2840
2841
        return self._send_xml_command(cmd)
2842
2843
    def delete_ticket(
2844
        self, ticket_id: str, *, ultimate: Optional[bool] = False
2845
    ):
2846
        """Deletes an existing ticket
2847
2848
        Arguments:
2849
            ticket_id: UUID of the ticket to be deleted.
2850
            ultimate: Whether to remove entirely, or to the trashcan.
2851
        """
2852
        if not ticket_id:
2853
            raise RequiredArgument(
2854
                function=self.delete_ticket.__name__, argument='ticket_id'
2855
            )
2856
2857
        cmd = XmlCommand("delete_ticket")
2858
        cmd.set_attribute("ticket_id", ticket_id)
2859
        cmd.set_attribute("ultimate", _to_bool(ultimate))
2860
2861
        return self._send_xml_command(cmd)
2862
2863 View Code Duplication
    def get_tickets(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2864
        self,
2865
        *,
2866
        trash: Optional[bool] = None,
2867
        filter: Optional[str] = None,
2868
        filter_id: Optional[str] = None,
2869
    ) -> Any:
2870
        """Request a list of tickets
2871
2872
        Arguments:
2873
            filter: Filter term to use for the query
2874
            filter_id: UUID of an existing filter to use for the query
2875
            trash: True to request the tickets in the trashcan
2876
2877
        Returns:
2878
            The response. See :py:meth:`send_command` for details.
2879
        """
2880
        cmd = XmlCommand("get_tickets")
2881
2882
        _add_filter(cmd, filter, filter_id)
2883
2884
        if trash is not None:
2885
            cmd.set_attribute("trash", _to_bool(trash))
2886
2887
        return self._send_xml_command(cmd)
2888
2889
    def get_ticket(self, ticket_id: str) -> Any:
2890
        """Request a single ticket
2891
2892
        Arguments:
2893
            ticket_id: UUID of an existing ticket
2894
2895
        Returns:
2896
            The response. See :py:meth:`send_command` for details.
2897
        """
2898
        if not ticket_id:
2899
            raise RequiredArgument(
2900
                function=self.get_ticket.__name__, argument='ticket_id'
2901
            )
2902
2903
        cmd = XmlCommand("get_tickets")
2904
        cmd.set_attribute("ticket_id", ticket_id)
2905
        return self._send_xml_command(cmd)
2906
2907
    def get_vulnerabilities(
2908
        self, *, filter: Optional[str] = None, filter_id: Optional[str] = None
2909
    ) -> Any:
2910
        """Request a list of vulnerabilities
2911
2912
        Arguments:
2913
            filter: Filter term to use for the query
2914
            filter_id: UUID of an existing filter to use for the query
2915
        Returns:
2916
            The response. See :py:meth:`send_command` for details.
2917
        """
2918
        cmd = XmlCommand("get_vulns")
2919
2920
        _add_filter(cmd, filter, filter_id)
2921
2922
        return self._send_xml_command(cmd)
2923
2924
    def get_vulnerability(self, vulnerability_id: str) -> Any:
2925
        """Request a single vulnerability
2926
2927
        Arguments:
2928
            vulnerability_id: ID of an existing vulnerability
2929
2930
        Returns:
2931
            The response. See :py:meth:`send_command` for details.
2932
        """
2933
        if not vulnerability_id:
2934
            raise RequiredArgument(
2935
                function=self.get_vulnerability.__name__,
2936
                argument='vulnerability_id',
2937
            )
2938
2939
        cmd = XmlCommand("get_vulns")
2940
        cmd.set_attribute("vuln_id", vulnerability_id)
2941
        return self._send_xml_command(cmd)
2942
2943
    def modify_ticket(
2944
        self,
2945
        ticket_id: str,
2946
        *,
2947
        status: Optional[TicketStatus] = None,
2948
        note: Optional[str] = None,
2949
        assigned_to_user_id: Optional[str] = None,
2950
        comment: Optional[str] = None,
2951
    ) -> Any:
2952
        """Modify a single ticket
2953
2954
        Arguments:
2955
            ticket_id: UUID of an existing ticket
2956
            status: New status for the ticket
2957
            note: Note for the status change. Required if status is set.
2958
            assigned_to_user_id: UUID of the user the ticket should be assigned
2959
                to
2960
            comment: Comment for the ticket
2961
2962
        Returns:
2963
            The response. See :py:meth:`send_command` for details.
2964
        """
2965
        if not ticket_id:
2966
            raise RequiredArgument(
2967
                function=self.modify_ticket.__name__, argument='ticket_id'
2968
            )
2969
2970
        if status and not note:
2971
            raise RequiredArgument(
2972
                function=self.modify_ticket.__name__, argument='note'
2973
            )
2974
2975
        if note and not status:
2976
            raise RequiredArgument(
2977
                function=self.modify_ticket.__name__, argument='status'
2978
            )
2979
2980
        cmd = XmlCommand("modify_ticket")
2981
        cmd.set_attribute("ticket_id", ticket_id)
2982
2983
        if assigned_to_user_id:
2984
            _assigned = cmd.add_element("assigned_to")
2985
            _user = _assigned.add_element("user")
2986
            _user.set_attribute("id", assigned_to_user_id)
2987
2988
        if status:
2989
            if not isinstance(status, self.types.TicketStatus):
2990
                raise InvalidArgumentType(
2991
                    function=self.modify_ticket.__name__,
2992
                    argument='status',
2993
                    arg_type=TicketStatus.__name__,
2994
                )
2995
2996
            cmd.add_element('status', status.value)
2997
            cmd.add_element('{}_note'.format(status.name.lower()), note)
2998
2999
        if comment:
3000
            cmd.add_element("comment", comment)
3001
3002
        return self._send_xml_command(cmd)
3003
3004 View Code Duplication
    def create_filter(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3005
        self,
3006
        name: str,
3007
        *,
3008
        filter_type: Optional[FilterType] = None,
3009
        comment: Optional[str] = None,
3010
        term: Optional[str] = None,
3011
    ) -> Any:
3012
        """Create a new filter
3013
3014
        Arguments:
3015
            name: Name of the new filter
3016
            filter_type: Filter for entity type
3017
            comment: Comment for the filter
3018
            term: Filter term e.g. 'name=foo'
3019
3020
        Returns:
3021
            The response. See :py:meth:`send_command` for details.
3022
        """
3023
        if not name:
3024
            raise RequiredArgument(
3025
                function=self.create_filter.__name__, argument="name"
3026
            )
3027
3028
        cmd = XmlCommand("create_filter")
3029
        _xmlname = cmd.add_element("name", name)
3030
3031
        if comment:
3032
            cmd.add_element("comment", comment)
3033
3034
        if term:
3035
            cmd.add_element("term", term)
3036
3037
        if filter_type:
3038
            if not isinstance(filter_type, self.types.FilterType):
3039
                raise InvalidArgumentType(
3040
                    function=self.create_filter.__name__,
3041
                    argument="filter_type",
3042
                    arg_type=self.types.FilterType.__name__,
3043
                )
3044
3045
            cmd.add_element("type", filter_type.value)
3046
3047
        return self._send_xml_command(cmd)
3048
3049 View Code Duplication
    def modify_filter(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3050
        self,
3051
        filter_id: str,
3052
        *,
3053
        comment: Optional[str] = None,
3054
        name: Optional[str] = None,
3055
        term: Optional[str] = None,
3056
        filter_type: Optional[FilterType] = None,
3057
    ) -> Any:
3058
        """Modifies an existing filter.
3059
3060
        Arguments:
3061
            filter_id: UUID of the filter to be modified
3062
            comment: Comment on filter.
3063
            name: Name of filter.
3064
            term: Filter term.
3065
            filter_type: Resource type filter applies to.
3066
3067
        Returns:
3068
            The response. See :py:meth:`send_command` for details.
3069
        """
3070
        if not filter_id:
3071
            raise RequiredArgument(
3072
                function=self.modify_filter.__name__, argument='filter_id'
3073
            )
3074
3075
        cmd = XmlCommand("modify_filter")
3076
        cmd.set_attribute("filter_id", filter_id)
3077
3078
        if comment:
3079
            cmd.add_element("comment", comment)
3080
3081
        if name:
3082
            cmd.add_element("name", name)
3083
3084
        if term:
3085
            cmd.add_element("term", term)
3086
3087
        if filter_type:
3088
            if not isinstance(filter_type, self.types.FilterType):
3089
                raise InvalidArgumentType(
3090
                    function=self.modify_filter.__name__,
3091
                    argument='filter_type',
3092
                    arg_type=FilterType.__name__,
3093
                )
3094
            cmd.add_element("type", filter_type.value)
3095
3096
        return self._send_xml_command(cmd)
3097
3098
    def create_schedule(
3099
        self,
3100
        name: str,
3101
        icalendar: str,
3102
        timezone: str,
3103
        *,
3104
        comment: Optional[str] = None,
3105
    ) -> Any:
3106
        """Create a new schedule based in `iCalendar`_ data.
3107
3108
        Example:
3109
            Requires https://pypi.org/project/icalendar/
3110
3111
            .. code-block:: python
3112
3113
                import pytz
3114
3115
                from datetime import datetime
3116
3117
                from icalendar import Calendar, Event
3118
3119
                cal = Calendar()
3120
3121
                cal.add('prodid', '-//Foo Bar//')
3122
                cal.add('version', '2.0')
3123
3124
                event = Event()
3125
                event.add('dtstamp', datetime.now(tz=pytz.UTC))
3126
                event.add('dtstart', datetime(2020, 1, 1, tzinfo=pytz.utc))
3127
3128
                cal.add_component(event)
3129
3130
                gmp.create_schedule(
3131
                    name="My Schedule",
3132
                    icalendar=cal.to_ical(),
3133
                    timezone='UTC'
3134
                )
3135
3136
3137
        Arguments:
3138
            name: Name of the new schedule
3139
            icalendar: `iCalendar`_ (RFC 5545) based data.
3140
            timezone: Timezone to use for the icalender events e.g
3141
                Europe/Berlin. If the datetime values in the icalendar data are
3142
                missing timezone information this timezone gets applied.
3143
                Otherwise the datetime values from the icalendar data are
3144
                displayed in this timezone
3145
            comment: Comment on schedule.
3146
3147
        Returns:
3148
            The response. See :py:meth:`send_command` for details.
3149
3150
        .. _iCalendar:
3151
            https://tools.ietf.org/html/rfc5545
3152
        """
3153
        if not name:
3154
            raise RequiredArgument(
3155
                function=self.create_schedule.__name__, argument='name'
3156
            )
3157
        if not icalendar:
3158
            raise RequiredArgument(
3159
                function=self.create_schedule.__name__, argument='icalendar'
3160
            )
3161
        if not timezone:
3162
            raise RequiredArgument(
3163
                function=self.create_schedule.__name__, argument='timezone'
3164
            )
3165
3166
        cmd = XmlCommand("create_schedule")
3167
3168
        cmd.add_element("name", name)
3169
        cmd.add_element("icalendar", icalendar)
3170
        cmd.add_element("timezone", timezone)
3171
3172
        if comment:
3173
            cmd.add_element("comment", comment)
3174
3175
        return self._send_xml_command(cmd)
3176
3177
    def modify_schedule(
3178
        self,
3179
        schedule_id: str,
3180
        *,
3181
        name: Optional[str] = None,
3182
        icalendar: Optional[str] = None,
3183
        timezone: Optional[str] = None,
3184
        comment: Optional[str] = None,
3185
    ) -> Any:
3186
        """Modifies an existing schedule
3187
3188
        Arguments:
3189
            schedule_id: UUID of the schedule to be modified
3190
            name: Name of the schedule
3191
            icalendar: `iCalendar`_ (RFC 5545) based data.
3192
            timezone: Timezone to use for the icalender events e.g
3193
                Europe/Berlin. If the datetime values in the icalendar data are
3194
                missing timezone information this timezone gets applied.
3195
                Otherwise the datetime values from the icalendar data are
3196
                displayed in this timezone
3197
            commenhedule.
3198
3199
        Returns:
3200
            The response. See :py:meth:`send_command` for details.
3201
3202
        .. _iCalendar:
3203
            https://tools.ietf.org/html/rfc5545
3204
        """
3205
        if not schedule_id:
3206
            raise RequiredArgument(
3207
                function=self.modify_schedule.__name__, argument='schedule_id'
3208
            )
3209
3210
        cmd = XmlCommand("modify_schedule")
3211
        cmd.set_attribute("schedule_id", schedule_id)
3212
3213
        if name:
3214
            cmd.add_element("name", name)
3215
3216
        if icalendar:
3217
            cmd.add_element("icalendar", icalendar)
3218
3219
        if timezone:
3220
            cmd.add_element("timezone", timezone)
3221
3222
        if comment:
3223
            cmd.add_element("comment", comment)
3224
3225
        return self._send_xml_command(cmd)
3226
3227
    def clone_config(self, config_id: str) -> Any:
3228
        """Clone a scan config from an existing one
3229
3230
        Arguments:
3231
            config_id: UUID of the existing scan config
3232
3233
        Returns:
3234
            The response. See :py:meth:`send_command` for details.
3235
        """
3236
        if not config_id:
3237
            raise RequiredArgument(
3238
                function=self.clone_config.__name__, argument='config_id'
3239
            )
3240
3241
        cmd = XmlCommand("create_config")
3242
        cmd.add_element("copy", config_id)
3243
        return self._send_xml_command(cmd)
3244
3245
    def import_config(self, config: str) -> Any:
3246
        """Import a scan config from XML
3247
3248
        Arguments:
3249
            config: Scan Config XML as string to import. This XML must
3250
                contain a :code:`<get_configs_response>` root element.
3251
3252
        Returns:
3253
            The response. See :py:meth:`send_command` for details.
3254
        """
3255
        if not config:
3256
            raise RequiredArgument(
3257
                function=self.import_config.__name__, argument='config'
3258
            )
3259
3260
        cmd = XmlCommand("create_config")
3261
3262
        try:
3263
            cmd.append_xml_str(config)
3264
        except etree.XMLSyntaxError as e:
3265
            raise InvalidArgument(
3266
                function=self.import_config.__name__, argument='config'
3267
            ) from e
3268
3269
        return self._send_xml_command(cmd)
3270
3271
    def clone_credential(self, credential_id: str) -> Any:
3272
        """Clone an existing credential
3273
3274
        Arguments:
3275
            credential_id: UUID of an existing credential to clone from
3276
3277
        Returns:
3278
            The response. See :py:meth:`send_command` for details.
3279
        """
3280
        if not credential_id:
3281
            raise RequiredArgument(
3282
                function=self.clone_credential.__name__,
3283
                argument='credential_id',
3284
            )
3285
3286
        cmd = XmlCommand("create_credential")
3287
        cmd.add_element("copy", credential_id)
3288
        return self._send_xml_command(cmd)
3289
3290
    def clone_filter(self, filter_id: str) -> Any:
3291
        """Clone an existing filter
3292
3293
        Arguments:
3294
            filter_id: UUID of an existing filter to clone from
3295
3296
        Returns:
3297
            The response. See :py:meth:`send_command` for details.
3298
        """
3299
        if not filter_id:
3300
            raise RequiredArgument(
3301
                function=self.clone_filter.__name__, argument='filter_id'
3302
            )
3303
3304
        cmd = XmlCommand("create_filter")
3305
        cmd.add_element("copy", filter_id)
3306
        return self._send_xml_command(cmd)
3307
3308
    def create_group(
3309
        self,
3310
        name: str,
3311
        *,
3312
        comment: Optional[str] = None,
3313
        special: Optional[bool] = False,
3314
        users: Optional[List[str]] = None,
3315
    ) -> Any:
3316
        """Create a new group
3317
3318
        Arguments:
3319
            name: Name of the new group
3320
            comment: Comment for the group
3321
            special: Create permission giving members full access to each
3322
                other's entities
3323
            users: List of user names to be in the group
3324
3325
        Returns:
3326
            The response. See :py:meth:`send_command` for details.
3327
        """
3328
        if not name:
3329
            raise RequiredArgument(
3330
                function=self.create_group.__name__, argument='name'
3331
            )
3332
3333
        cmd = XmlCommand("create_group")
3334
        cmd.add_element("name", name)
3335
3336
        if comment:
3337
            cmd.add_element("comment", comment)
3338
3339
        if special:
3340
            _xmlspecial = cmd.add_element("specials")
3341
            _xmlspecial.add_element("full")
3342
3343
        if users:
3344
            cmd.add_element("users", _to_comma_list(users))
3345
3346
        return self._send_xml_command(cmd)
3347
3348
    def clone_group(self, group_id: str) -> Any:
3349
        """Clone an existing group
3350
3351
        Arguments:
3352
            group_id: UUID of an existing group to clone from
3353
3354
        Returns:
3355
            The response. See :py:meth:`send_command` for details.
3356
        """
3357
        if not group_id:
3358
            raise RequiredArgument(
3359
                function=self.clone_group.__name__, argument='group_id'
3360
            )
3361
3362
        cmd = XmlCommand("create_group")
3363
        cmd.add_element("copy", group_id)
3364
        return self._send_xml_command(cmd)
3365
3366
    def create_host(self, name: str, *, comment: Optional[str] = None) -> Any:
3367
        """Create a new host asset
3368
3369
        Arguments:
3370
            name: Name for the new host asset
3371
            comment: Comment for the new host asset
3372
3373
        Returns:
3374
            The response. See :py:meth:`send_command` for details.
3375
        """
3376
        if not name:
3377
            raise RequiredArgument(
3378
                function=self.create_host.__name__, argument='name'
3379
            )
3380
3381
        cmd = XmlCommand("create_asset")
3382
        asset = cmd.add_element("asset")
3383
        asset.add_element("type", "host")  # ignored for gmp7, required for gmp8
3384
        asset.add_element("name", name)
3385
3386
        if comment:
3387
            asset.add_element("comment", comment)
3388
3389
        return self._send_xml_command(cmd)
3390
3391 View Code Duplication
    def create_note(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3392
        self,
3393
        text: str,
3394
        nvt_oid: str,
3395
        *,
3396
        days_active: Optional[int] = None,
3397
        hosts: Optional[List[str]] = None,
3398
        port: Optional[int] = None,
3399
        result_id: Optional[str] = None,
3400
        severity: Optional[Severity] = None,
3401
        task_id: Optional[str] = None,
3402
        threat: Optional[SeverityLevel] = None,
3403
    ) -> Any:
3404
        """Create a new note
3405
3406
        Arguments:
3407
            text: Text of the new note
3408
            nvt_id: OID of the nvt to which note applies
3409
            days_active: Days note will be active. -1 on
3410
                always, 0 off
3411
            hosts: A list of hosts addresses
3412
            port: Port to which the note applies
3413
            result_id: UUID of a result to which note applies
3414
            severity: Severity to which note applies
3415
            task_id: UUID of task to which note applies
3416
            threat: Severity level to which note applies. Will be converted to
3417
                severity.
3418
3419
        Returns:
3420
            The response. See :py:meth:`send_command` for details.
3421
        """
3422
        if not text:
3423
            raise RequiredArgument(
3424
                function=self.create_note.__name__, argument='text'
3425
            )
3426
3427
        if not nvt_oid:
3428
            raise RequiredArgument(
3429
                function=self.create_note.__name__, argument='nvt_oid'
3430
            )
3431
3432
        cmd = XmlCommand("create_note")
3433
        cmd.add_element("text", text)
3434
        cmd.add_element("nvt", attrs={"oid": nvt_oid})
3435
3436
        if days_active is not None:
3437
            cmd.add_element("active", str(days_active))
3438
3439
        if hosts:
3440
            cmd.add_element("hosts", _to_comma_list(hosts))
3441
3442
        if port:
3443
            cmd.add_element("port", str(port))
3444
3445
        if result_id:
3446
            cmd.add_element("result", attrs={"id": result_id})
3447
3448
        if severity:
3449
            cmd.add_element("severity", str(severity))
3450
3451
        if task_id:
3452
            cmd.add_element("task", attrs={"id": task_id})
3453
3454
        if threat is not None:
3455
            if not isinstance(threat, SeverityLevel):
3456
                raise InvalidArgumentType(
3457
                    function="create_note",
3458
                    argument="threat",
3459
                    arg_type=SeverityLevel.__name__,
3460
                )
3461
3462
            cmd.add_element("threat", threat.value)
3463
3464
        return self._send_xml_command(cmd)
3465
3466
    def clone_note(self, note_id: str) -> Any:
3467
        """Clone an existing note
3468
3469
        Arguments:
3470
            note_id: UUID of an existing note to clone from
3471
3472
        Returns:
3473
            The response. See :py:meth:`send_command` for details.
3474
        """
3475
        if not note_id:
3476
            raise RequiredArgument(
3477
                function=self.clone_note.__name__, argument='note_id'
3478
            )
3479
3480
        cmd = XmlCommand("create_note")
3481
        cmd.add_element("copy", note_id)
3482
        return self._send_xml_command(cmd)
3483
3484 View Code Duplication
    def create_override(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3485
        self,
3486
        text: str,
3487
        nvt_oid: str,
3488
        *,
3489
        days_active: Optional[int] = None,
3490
        hosts: Optional[List[str]] = None,
3491
        port: Optional[int] = None,
3492
        result_id: Optional[str] = None,
3493
        severity: Optional[Severity] = None,
3494
        new_severity: Optional[Severity] = None,
3495
        task_id: Optional[str] = None,
3496
        threat: Optional[SeverityLevel] = None,
3497
        new_threat: Optional[SeverityLevel] = None,
3498
    ) -> Any:
3499
        """Create a new override
3500
3501
        Arguments:
3502
            text: Text of the new override
3503
            nvt_id: OID of the nvt to which override applies
3504
            days_active: Days override will be active. -1 on always, 0 off
3505
            hosts: A list of host addresses
3506
            port: Port to which the override applies
3507
            result_id: UUID of a result to which override applies
3508
            severity: Severity to which override applies
3509
            new_severity: New severity for result
3510
            task_id: UUID of task to which override applies
3511
            threat: Severity level to which override applies. Will be converted
3512
                to severity.
3513
            new_threat: New severity level for results. Will be converted to
3514
                new_severity.
3515
3516
        Returns:
3517
            The response. See :py:meth:`send_command` for details.
3518
        """
3519
        if not text:
3520
            raise RequiredArgument(
3521
                function=self.create_override.__name__, argument='text'
3522
            )
3523
3524
        if not nvt_oid:
3525
            raise RequiredArgument(
3526
                function=self.create_override.__name__, argument='nvt_oid'
3527
            )
3528
3529
        cmd = XmlCommand("create_override")
3530
        cmd.add_element("text", text)
3531
        cmd.add_element("nvt", attrs={"oid": nvt_oid})
3532
3533
        if days_active is not None:
3534
            cmd.add_element("active", str(days_active))
3535
3536
        if hosts:
3537
            cmd.add_element("hosts", _to_comma_list(hosts))
3538
3539
        if port:
3540
            cmd.add_element("port", str(port))
3541
3542
        if result_id:
3543
            cmd.add_element("result", attrs={"id": result_id})
3544
3545
        if severity:
3546
            cmd.add_element("severity", str(severity))
3547
3548
        if new_severity:
3549
            cmd.add_element("new_severity", str(new_severity))
3550
3551
        if task_id:
3552
            cmd.add_element("task", attrs={"id": task_id})
3553
3554
        if threat is not None:
3555
            if not isinstance(threat, SeverityLevel):
3556
                raise InvalidArgumentType(
3557
                    function=self.create_override.__name__,
3558
                    argument="threat",
3559
                    arg_type=SeverityLevel.__name__,
3560
                )
3561
3562
            cmd.add_element("threat", threat.value)
3563
3564
        if new_threat is not None:
3565
            if not isinstance(new_threat, SeverityLevel):
3566
                raise InvalidArgumentType(
3567
                    function=self.create_override.__name__,
3568
                    argument="new_threat",
3569
                    arg_type=SeverityLevel.__name__,
3570
                )
3571
3572
            cmd.add_element("new_threat", new_threat.value)
3573
3574
        return self._send_xml_command(cmd)
3575
3576
    def clone_override(self, override_id: str) -> Any:
3577
        """Clone an existing override
3578
3579
        Arguments:
3580
            override_id: UUID of an existing override to clone from
3581
3582
        Returns:
3583
            The response. See :py:meth:`send_command` for details.
3584
        """
3585
        if not override_id:
3586
            raise RequiredArgument(
3587
                function=self.clone_override.__name__, argument='override_id'
3588
            )
3589
3590
        cmd = XmlCommand("create_override")
3591
        cmd.add_element("copy", override_id)
3592
        return self._send_xml_command(cmd)
3593
3594
    def clone_permission(self, permission_id: str) -> Any:
3595
        """Clone an existing permission
3596
3597
        Arguments:
3598
            permission_id: UUID of an existing permission to clone from
3599
3600
        Returns:
3601
            The response. See :py:meth:`send_command` for details.
3602
        """
3603
        if not permission_id:
3604
            raise RequiredArgument(
3605
                function=self.clone_permission.__name__,
3606
                argument='permission_id',
3607
            )
3608
3609
        cmd = XmlCommand("create_permission")
3610
        cmd.add_element("copy", permission_id)
3611
        return self._send_xml_command(cmd)
3612
3613
    def create_port_list(
3614
        self, name: str, port_range: str, *, comment: Optional[str] = None
3615
    ) -> Any:
3616
        """Create a new port list
3617
3618
        Arguments:
3619
            name: Name of the new port list
3620
            port_range: Port list ranges e.g. `"T: 1-1234"` for tcp port
3621
                1 - 1234
3622
            comment: Comment for the port list
3623
3624
        Returns:
3625
            The response. See :py:meth:`send_command` for details.
3626
        """
3627
        if not name:
3628
            raise RequiredArgument(
3629
                function=self.create_port_list.__name__, argument='name'
3630
            )
3631
3632
        if not port_range:
3633
            raise RequiredArgument(
3634
                function=self.create_port_list.__name__, argument='port_range'
3635
            )
3636
3637
        cmd = XmlCommand("create_port_list")
3638
        cmd.add_element("name", name)
3639
        cmd.add_element("port_range", port_range)
3640
3641
        if comment:
3642
            cmd.add_element("comment", comment)
3643
3644
        return self._send_xml_command(cmd)
3645
3646
    def clone_port_list(self, port_list_id: str) -> Any:
3647
        """Clone an existing port list
3648
3649
        Arguments:
3650
            port_list_id: UUID of an existing port list to clone from
3651
3652
        Returns:
3653
            The response. See :py:meth:`send_command` for details.
3654
        """
3655
        if not port_list_id:
3656
            raise RequiredArgument(
3657
                function=self.clone_port_list.__name__, argument='port_list_id'
3658
            )
3659
3660
        cmd = XmlCommand("create_port_list")
3661
        cmd.add_element("copy", port_list_id)
3662
        return self._send_xml_command(cmd)
3663
3664
    def create_port_range(
3665
        self,
3666
        port_list_id: str,
3667
        start: int,
3668
        end: int,
3669
        port_range_type: PortRangeType,
3670
        *,
3671
        comment: Optional[str] = None,
3672
    ) -> Any:
3673
        """Create new port range
3674
3675
        Arguments:
3676
            port_list_id: UUID of the port list to which to add the range
3677
            start: The first port in the range
3678
            end: The last port in the range
3679
            port_range_type: The type of the ports: TCP, UDP, ...
3680
            comment: Comment for the port range
3681
3682
        Returns:
3683
            The response. See :py:meth:`send_command` for details.
3684
        """
3685
        if not port_list_id:
3686
            raise RequiredArgument(
3687
                function=self.create_port_range.__name__,
3688
                argument='port_list_id',
3689
            )
3690
3691
        if not port_range_type:
3692
            raise RequiredArgument(
3693
                function=self.create_port_range.__name__,
3694
                argument='port_range_type',
3695
            )
3696
3697
        if not start:
3698
            raise RequiredArgument(
3699
                function=self.create_port_range.__name__, argument='start'
3700
            )
3701
3702
        if not end:
3703
            raise RequiredArgument(
3704
                function=self.create_port_range.__name__, argument='end'
3705
            )
3706
3707
        if not isinstance(port_range_type, PortRangeType):
3708
            raise InvalidArgumentType(
3709
                function=self.create_port_range.__name__,
3710
                argument='port_range_type',
3711
                arg_type=PortRangeType.__name__,
3712
            )
3713
3714
        cmd = XmlCommand("create_port_range")
3715
        cmd.add_element("port_list", attrs={"id": port_list_id})
3716
        cmd.add_element("start", str(start))
3717
        cmd.add_element("end", str(end))
3718
        cmd.add_element("type", port_range_type.value)
3719
3720
        if comment:
3721
            cmd.add_element("comment", comment)
3722
3723
        return self._send_xml_command(cmd)
3724
3725
    def clone_report_format(
3726
        self, report_format_id: [Union[str, ReportFormatType]]
3727
    ) -> Any:
3728
        """Clone a report format from an existing one
3729
3730
        Arguments:
3731
            report_format_id: UUID of the existing report format
3732
                              or ReportFormatType (enum)
3733
3734
        Returns:
3735
            The response. See :py:meth:`send_command` for details.
3736
        """
3737
        if not report_format_id:
3738
            raise RequiredArgument(
3739
                function=self.clone_report_format.__name__,
3740
                argument='report_format_id',
3741
            )
3742
3743
        cmd = XmlCommand("create_report_format")
3744
3745
        if isinstance(report_format_id, ReportFormatType):
3746
            report_format_id = report_format_id.value
3747
3748
        cmd.add_element("copy", report_format_id)
3749
        return self._send_xml_command(cmd)
3750
3751
    def import_report_format(self, report_format: str) -> Any:
3752
        """Import a report format from XML
3753
3754
        Arguments:
3755
            report_format: Report format XML as string to import. This XML must
3756
                contain a :code:`<get_report_formats_response>` root element.
3757
3758
        Returns:
3759
            The response. See :py:meth:`send_command` for details.
3760
        """
3761
        if not report_format:
3762
            raise RequiredArgument(
3763
                function=self.import_report_format.__name__,
3764
                argument='report_format',
3765
            )
3766
3767
        cmd = XmlCommand("create_report_format")
3768
3769
        try:
3770
            cmd.append_xml_str(report_format)
3771
        except etree.XMLSyntaxError as e:
3772
            raise InvalidArgument(
3773
                function=self.import_report_format.__name__,
3774
                argument='report_format',
3775
            ) from e
3776
3777
        return self._send_xml_command(cmd)
3778
3779
    def create_role(
3780
        self,
3781
        name: str,
3782
        *,
3783
        comment: Optional[str] = None,
3784
        users: Optional[List[str]] = None,
3785
    ) -> Any:
3786
        """Create a new role
3787
3788
        Arguments:
3789
            name: Name of the role
3790
            comment: Comment for the role
3791
            users: List of user names to add to the role
3792
3793
        Returns:
3794
            The response. See :py:meth:`send_command` for details.
3795
        """
3796
3797
        if not name:
3798
            raise RequiredArgument(
3799
                function=self.create_role.__name__, argument='name'
3800
            )
3801
3802
        cmd = XmlCommand("create_role")
3803
        cmd.add_element("name", name)
3804
3805
        if comment:
3806
            cmd.add_element("comment", comment)
3807
3808
        if users:
3809
            cmd.add_element("users", _to_comma_list(users))
3810
3811
        return self._send_xml_command(cmd)
3812
3813
    def clone_role(self, role_id: str) -> Any:
3814
        """Clone an existing role
3815
3816
        Arguments:
3817
            role_id: UUID of an existing role to clone from
3818
3819
        Returns:
3820
            The response. See :py:meth:`send_command` for details.
3821
        """
3822
        if not role_id:
3823
            raise RequiredArgument(
3824
                function=self.clone_role.__name__, argument='role_id'
3825
            )
3826
3827
        cmd = XmlCommand("create_role")
3828
        cmd.add_element("copy", role_id)
3829
        return self._send_xml_command(cmd)
3830
3831
    def create_scanner(
3832
        self,
3833
        name: str,
3834
        host: str,
3835
        port: int,
3836
        scanner_type: ScannerType,
3837
        credential_id: str,
3838
        *,
3839
        ca_pub: Optional[str] = None,
3840
        comment: Optional[str] = None,
3841
    ) -> Any:
3842
        """Create a new scanner
3843
3844
        Arguments:
3845
            name: Name of the scanner
3846
            host: The host of the scanner
3847
            port: The port of the scanner
3848
            scanner_type: Type of the scanner.
3849
            credential_id: UUID of client certificate credential for the
3850
                scanner
3851
            ca_pub: Certificate of CA to verify scanner certificate
3852
            comment: Comment for the scanner
3853
3854
        Returns:
3855
            The response. See :py:meth:`send_command` for details.
3856
        """
3857
        if not name:
3858
            raise RequiredArgument(
3859
                function=self.create_scanner.__name__, argument='name'
3860
            )
3861
3862
        if not host:
3863
            raise RequiredArgument(
3864
                function=self.create_scanner.__name__, argument='host'
3865
            )
3866
3867
        if not port:
3868
            raise RequiredArgument(
3869
                function=self.create_scanner.__name__, argument='port'
3870
            )
3871
3872
        if not scanner_type:
3873
            raise RequiredArgument(
3874
                function=self.create_scanner.__name__, argument='scanner_type'
3875
            )
3876
3877
        if not credential_id:
3878
            raise RequiredArgument(
3879
                function=self.create_scanner.__name__, argument='credential_id'
3880
            )
3881
3882
        if not isinstance(scanner_type, self.types.ScannerType):
3883
            raise InvalidArgumentType(
3884
                function=self.create_scanner.__name__,
3885
                argument='scanner_type',
3886
                arg_type=self.types.ScannerType.__name__,
3887
            )
3888
3889
        cmd = XmlCommand("create_scanner")
3890
        cmd.add_element("name", name)
3891
        cmd.add_element("host", host)
3892
        cmd.add_element("port", str(port))
3893
        cmd.add_element("type", scanner_type.value)
3894
3895
        if ca_pub:
3896
            cmd.add_element("ca_pub", ca_pub)
3897
3898
        cmd.add_element("credential", attrs={"id": str(credential_id)})
3899
3900
        if comment:
3901
            cmd.add_element("comment", comment)
3902
3903
        return self._send_xml_command(cmd)
3904
3905
    def clone_scanner(self, scanner_id: str) -> Any:
3906
        """Clone an existing scanner
3907
3908
        Arguments:
3909
            scanner_id: UUID of an existing scanner to clone from
3910
3911
        Returns:
3912
            The response. See :py:meth:`send_command` for details.
3913
        """
3914
        if not scanner_id:
3915
            raise RequiredArgument(
3916
                function=self.clone_scanner.__name__, argument='scanner_id'
3917
            )
3918
3919
        cmd = XmlCommand("create_scanner")
3920
        cmd.add_element("copy", scanner_id)
3921
        return self._send_xml_command(cmd)
3922
3923
    def clone_schedule(self, schedule_id: str) -> Any:
3924
        """Clone an existing schedule
3925
3926
        Arguments:
3927
            schedule_id: UUID of an existing schedule to clone from
3928
3929
        Returns:
3930
            The response. See :py:meth:`send_command` for details.
3931
        """
3932
        if not schedule_id:
3933
            raise RequiredArgument(
3934
                function=self.clone_schedule.__name__, argument='schedule_id'
3935
            )
3936
3937
        cmd = XmlCommand("create_schedule")
3938
        cmd.add_element("copy", schedule_id)
3939
        return self._send_xml_command(cmd)
3940
3941
    def clone_tag(self, tag_id: str) -> Any:
3942
        """Clone an existing tag
3943
3944
        Arguments:
3945
            tag_id: UUID of an existing tag to clone from
3946
3947
        Returns:
3948
            The response. See :py:meth:`send_command` for details.
3949
        """
3950
        if not tag_id:
3951
            raise RequiredArgument(
3952
                function=self.clone_tag.__name__, argument='tag_id'
3953
            )
3954
3955
        cmd = XmlCommand("create_tag")
3956
        cmd.add_element("copy", tag_id)
3957
        return self._send_xml_command(cmd)
3958
3959
    def clone_target(self, target_id: str) -> Any:
3960
        """Clone an existing target
3961
3962
        Arguments:
3963
            target_id: UUID of an existing target to clone from
3964
3965
        Returns:
3966
            The response. See :py:meth:`send_command` for details.
3967
        """
3968
        if not target_id:
3969
            raise RequiredArgument(
3970
                function=self.clone_target.__name__, argument='target_id'
3971
            )
3972
3973
        cmd = XmlCommand("create_target")
3974
        cmd.add_element("copy", target_id)
3975
        return self._send_xml_command(cmd)
3976
3977
    def create_container_task(
3978
        self, name: str, *, comment: Optional[str] = None
3979
    ) -> Any:
3980
        """Create a new container task
3981
3982
        A container task is a "meta" task to import and view reports from other
3983
        systems.
3984
3985
        Arguments:
3986
            name: Name of the task
3987
            comment: Comment for the task
3988
3989
        Returns:
3990
            The response. See :py:meth:`send_command` for details.
3991
        """
3992
        if not name:
3993
            raise RequiredArgument(
3994
                function=self.create_container_task.__name__, argument='name'
3995
            )
3996
3997
        cmd = XmlCommand("create_task")
3998
        cmd.add_element("name", name)
3999
        cmd.add_element("target", attrs={"id": "0"})
4000
4001
        if comment:
4002
            cmd.add_element("comment", comment)
4003
4004
        return self._send_xml_command(cmd)
4005
4006
    def clone_task(self, task_id: str) -> Any:
4007
        """Clone an existing task
4008
4009
        Arguments:
4010
            task_id: UUID of existing task to clone from
4011
4012
        Returns:
4013
            The response. See :py:meth:`send_command` for details.
4014
        """
4015
        if not task_id:
4016
            raise RequiredArgument(
4017
                function=self.clone_task.__name__, argument='task_id'
4018
            )
4019
4020
        cmd = XmlCommand("create_task")
4021
        cmd.add_element("copy", task_id)
4022
        return self._send_xml_command(cmd)
4023
4024
    def create_user(
4025
        self,
4026
        name: str,
4027
        *,
4028
        password: Optional[str] = None,
4029
        hosts: Optional[List[str]] = None,
4030
        hosts_allow: Optional[bool] = False,
4031
        ifaces: Optional[List[str]] = None,
4032
        ifaces_allow: Optional[bool] = False,
4033
        role_ids: Optional[List[str]] = None,
4034
    ) -> Any:
4035
        """Create a new user
4036
4037
        Arguments:
4038
            name: Name of the user
4039
            password: Password of the user
4040
            hosts: A list of host addresses (IPs, DNS names)
4041
            hosts_allow: If True allow only access to passed hosts otherwise
4042
                deny access. Default is False for deny hosts.
4043
            ifaces: A list of interface names
4044
            ifaces_allow: If True allow only access to passed interfaces
4045
                otherwise deny access. Default is False for deny interfaces.
4046
            role_ids: A list of role UUIDs for the user
4047
4048
        Returns:
4049
            The response. See :py:meth:`send_command` for details.
4050
        """
4051
        if not name:
4052
            raise RequiredArgument(
4053
                function=self.create_user.__name__, argument='name'
4054
            )
4055
4056
        cmd = XmlCommand("create_user")
4057
        cmd.add_element("name", name)
4058
4059
        if password:
4060
            cmd.add_element("password", password)
4061
4062
        if hosts:
4063
            cmd.add_element(
4064
                "hosts",
4065
                _to_comma_list(hosts),
4066
                attrs={"allow": _to_bool(hosts_allow)},
4067
            )
4068
4069
        if ifaces:
4070
            cmd.add_element(
4071
                "ifaces",
4072
                _to_comma_list(ifaces),
4073
                attrs={"allow": _to_bool(ifaces_allow)},
4074
            )
4075
4076
        if role_ids:
4077
            for role in role_ids:
4078
                cmd.add_element("role", attrs={"id": role})
4079
4080
        return self._send_xml_command(cmd)
4081
4082
    def clone_user(self, user_id: str) -> Any:
4083
        """Clone an existing user
4084
4085
        Arguments:
4086
            user_id: UUID of existing user to clone from
4087
4088
        Returns:
4089
            The response. See :py:meth:`send_command` for details.
4090
        """
4091
        if not user_id:
4092
            raise RequiredArgument(
4093
                function=self.clone_user.__name__, argument='user_id'
4094
            )
4095
4096
        cmd = XmlCommand("create_user")
4097
        cmd.add_element("copy", user_id)
4098
        return self._send_xml_command(cmd)
4099
4100
    def delete_alert(
4101
        self, alert_id: str, *, ultimate: Optional[bool] = False
4102
    ) -> Any:
4103
        """Deletes an existing alert
4104
4105
        Arguments:
4106
            alert_id: UUID of the alert to be deleted.
4107
            ultimate: Whether to remove entirely, or to the trashcan.
4108
        """
4109
        if not alert_id:
4110
            raise RequiredArgument(
4111
                function=self.delete_alert.__name__, argument='alert_id'
4112
            )
4113
4114
        cmd = XmlCommand("delete_alert")
4115
        cmd.set_attribute("alert_id", alert_id)
4116
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4117
4118
        return self._send_xml_command(cmd)
4119
4120
    def delete_asset(
4121
        self, *, asset_id: Optional[str] = None, report_id: Optional[str] = None
4122
    ) -> Any:
4123
        """Deletes an existing asset
4124
4125
        Arguments:
4126
            asset_id: UUID of the single asset to delete.
4127
            report_id: UUID of report from which to get all
4128
                assets to delete.
4129
        """
4130
        if not asset_id and not report_id:
4131
            raise RequiredArgument(
4132
                function=self.delete_asset.__name__,
4133
                argument='asset_id or report_id',
4134
            )
4135
4136
        cmd = XmlCommand("delete_asset")
4137
        if asset_id:
4138
            cmd.set_attribute("asset_id", asset_id)
4139
        else:
4140
            cmd.set_attribute("report_id", report_id)
4141
4142
        return self._send_xml_command(cmd)
4143
4144
    def delete_config(
4145
        self, config_id: str, *, ultimate: Optional[bool] = False
4146
    ) -> Any:
4147
        """Deletes an existing config
4148
4149
        Arguments:
4150
            config_id: UUID of the config to be deleted.
4151
            ultimate: Whether to remove entirely, or to the trashcan.
4152
        """
4153
        if not config_id:
4154
            raise RequiredArgument(
4155
                function=self.delete_config.__name__, argument='config_id'
4156
            )
4157
4158
        cmd = XmlCommand("delete_config")
4159
        cmd.set_attribute("config_id", config_id)
4160
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4161
4162
        return self._send_xml_command(cmd)
4163
4164
    def delete_credential(
4165
        self, credential_id: str, *, ultimate: Optional[bool] = False
4166
    ) -> Any:
4167
        """Deletes an existing credential
4168
4169
        Arguments:
4170
            credential_id: UUID of the credential to be deleted.
4171
            ultimate: Whether to remove entirely, or to the trashcan.
4172
        """
4173
        if not credential_id:
4174
            raise RequiredArgument(
4175
                function=self.delete_credential.__name__,
4176
                argument='credential_id',
4177
            )
4178
4179
        cmd = XmlCommand("delete_credential")
4180
        cmd.set_attribute("credential_id", credential_id)
4181
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4182
4183
        return self._send_xml_command(cmd)
4184
4185
    def delete_filter(
4186
        self, filter_id: str, *, ultimate: Optional[bool] = False
4187
    ) -> Any:
4188
        """Deletes an existing filter
4189
4190
        Arguments:
4191
            filter_id: UUID of the filter to be deleted.
4192
            ultimate: Whether to remove entirely, or to the trashcan.
4193
        """
4194
        if not filter_id:
4195
            raise RequiredArgument(
4196
                function=self.delete_filter.__name__, argument='filter_id'
4197
            )
4198
4199
        cmd = XmlCommand("delete_filter")
4200
        cmd.set_attribute("filter_id", filter_id)
4201
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4202
4203
        return self._send_xml_command(cmd)
4204
4205
    def delete_group(
4206
        self, group_id: str, *, ultimate: Optional[bool] = False
4207
    ) -> Any:
4208
        """Deletes an existing group
4209
4210
        Arguments:
4211
            group_id: UUID of the group to be deleted.
4212
            ultimate: Whether to remove entirely, or to the trashcan.
4213
        """
4214
        if not group_id:
4215
            raise RequiredArgument(
4216
                function=self.delete_group.__name__, argument='group_id'
4217
            )
4218
4219
        cmd = XmlCommand("delete_group")
4220
        cmd.set_attribute("group_id", group_id)
4221
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4222
4223
        return self._send_xml_command(cmd)
4224
4225
    def delete_note(
4226
        self, note_id: str, *, ultimate: Optional[bool] = False
4227
    ) -> Any:
4228
        """Deletes an existing note
4229
4230
        Arguments:
4231
            note_id: UUID of the note to be deleted.
4232
            ultimate: Whether to remove entirely,or to the trashcan.
4233
        """
4234
        if not note_id:
4235
            raise RequiredArgument(
4236
                function=self.delete_note.__name__, argument='note_id'
4237
            )
4238
4239
        cmd = XmlCommand("delete_note")
4240
        cmd.set_attribute("note_id", note_id)
4241
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4242
4243
        return self._send_xml_command(cmd)
4244
4245
    def delete_override(
4246
        self, override_id: str, *, ultimate: Optional[bool] = False
4247
    ) -> Any:
4248
        """Deletes an existing override
4249
4250
        Arguments:
4251
            override_id: UUID of the override to be deleted.
4252
            ultimate: Whether to remove entirely, or to the trashcan.
4253
        """
4254
        if not override_id:
4255
            raise RequiredArgument(
4256
                function=self.delete_override.__name__, argument='override_id'
4257
            )
4258
4259
        cmd = XmlCommand("delete_override")
4260
        cmd.set_attribute("override_id", override_id)
4261
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4262
4263
        return self._send_xml_command(cmd)
4264
4265
    def delete_permission(
4266
        self, permission_id: str, *, ultimate: Optional[bool] = False
4267
    ) -> Any:
4268
        """Deletes an existing permission
4269
4270
        Arguments:
4271
            permission_id: UUID of the permission to be deleted.
4272
            ultimate: Whether to remove entirely, or to the trashcan.
4273
        """
4274
        if not permission_id:
4275
            raise RequiredArgument(
4276
                function=self.delete_permission.__name__,
4277
                argument='permission_id',
4278
            )
4279
4280
        cmd = XmlCommand("delete_permission")
4281
        cmd.set_attribute("permission_id", permission_id)
4282
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4283
4284
        return self._send_xml_command(cmd)
4285
4286
    def delete_port_list(
4287
        self, port_list_id: str, *, ultimate: Optional[bool] = False
4288
    ) -> Any:
4289
        """Deletes an existing port list
4290
4291
        Arguments:
4292
            port_list_id: UUID of the port list to be deleted.
4293
            ultimate: Whether to remove entirely, or to the trashcan.
4294
        """
4295
        if not port_list_id:
4296
            raise RequiredArgument(
4297
                function=self.delete_port_list.__name__, argument='port_list_id'
4298
            )
4299
4300
        cmd = XmlCommand("delete_port_list")
4301
        cmd.set_attribute("port_list_id", port_list_id)
4302
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4303
4304
        return self._send_xml_command(cmd)
4305
4306
    def delete_port_range(self, port_range_id: str) -> Any:
4307
        """Deletes an existing port range
4308
4309
        Arguments:
4310
            port_range_id: UUID of the port range to be deleted.
4311
        """
4312
        if not port_range_id:
4313
            raise RequiredArgument(
4314
                function=self.delete_port_range.__name__,
4315
                argument='port_range_id',
4316
            )
4317
4318
        cmd = XmlCommand("delete_port_range")
4319
        cmd.set_attribute("port_range_id", port_range_id)
4320
4321
        return self._send_xml_command(cmd)
4322
4323
    def delete_report(self, report_id: str) -> Any:
4324
        """Deletes an existing report
4325
4326
        Arguments:
4327
            report_id: UUID of the report to be deleted.
4328
        """
4329
        if not report_id:
4330
            raise RequiredArgument(
4331
                function=self.delete_report.__name__, argument='report_id'
4332
            )
4333
4334
        cmd = XmlCommand("delete_report")
4335
        cmd.set_attribute("report_id", report_id)
4336
4337
        return self._send_xml_command(cmd)
4338
4339
    def delete_report_format(
4340
        self,
4341
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
4342
        *,
4343
        ultimate: Optional[bool] = False,
4344
    ) -> Any:
4345
        """Deletes an existing report format
4346
4347
        Arguments:
4348
            report_format_id: UUID of the report format to be deleted.
4349
                              or ReportFormatType (enum)
4350
            ultimate: Whether to remove entirely, or to the trashcan.
4351
        """
4352
        if not report_format_id:
4353
            raise RequiredArgument(
4354
                function=self.delete_report_format.__name__,
4355
                argument='report_format_id',
4356
            )
4357
4358
        cmd = XmlCommand("delete_report_format")
4359
4360
        if isinstance(report_format_id, ReportFormatType):
4361
            report_format_id = report_format_id.value
4362
4363
        cmd.set_attribute("report_format_id", report_format_id)
4364
4365
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4366
4367
        return self._send_xml_command(cmd)
4368
4369
    def delete_role(
4370
        self, role_id: str, *, ultimate: Optional[bool] = False
4371
    ) -> Any:
4372
        """Deletes an existing role
4373
4374
        Arguments:
4375
            role_id: UUID of the role to be deleted.
4376
            ultimate: Whether to remove entirely, or to the trashcan.
4377
        """
4378
        if not role_id:
4379
            raise RequiredArgument(
4380
                function=self.delete_role.__name__, argument='role_id'
4381
            )
4382
4383
        cmd = XmlCommand("delete_role")
4384
        cmd.set_attribute("role_id", role_id)
4385
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4386
4387
        return self._send_xml_command(cmd)
4388
4389
    def delete_scanner(
4390
        self, scanner_id: str, *, ultimate: Optional[bool] = False
4391
    ) -> Any:
4392
        """Deletes an existing scanner
4393
4394
        Arguments:
4395
            scanner_id: UUID of the scanner to be deleted.
4396
            ultimate: Whether to remove entirely, or to the trashcan.
4397
        """
4398
        if not scanner_id:
4399
            raise RequiredArgument(
4400
                function=self.delete_scanner.__name__, argument='scanner_id'
4401
            )
4402
4403
        cmd = XmlCommand("delete_scanner")
4404
        cmd.set_attribute("scanner_id", scanner_id)
4405
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4406
4407
        return self._send_xml_command(cmd)
4408
4409
    def delete_schedule(
4410
        self, schedule_id: str, *, ultimate: Optional[bool] = False
4411
    ) -> Any:
4412
        """Deletes an existing schedule
4413
4414
        Arguments:
4415
            schedule_id: UUID of the schedule to be deleted.
4416
            ultimate: Whether to remove entirely, or to the trashcan.
4417
        """
4418
        if not schedule_id:
4419
            raise RequiredArgument(
4420
                function=self.delete_schedule.__name__, argument='schedule_id'
4421
            )
4422
4423
        cmd = XmlCommand("delete_schedule")
4424
        cmd.set_attribute("schedule_id", schedule_id)
4425
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4426
4427
        return self._send_xml_command(cmd)
4428
4429
    def delete_tag(
4430
        self, tag_id: str, *, ultimate: Optional[bool] = False
4431
    ) -> Any:
4432
        """Deletes an existing tag
4433
4434
        Arguments:
4435
            tag_id: UUID of the tag to be deleted.
4436
            ultimate: Whether to remove entirely, or to the trashcan.
4437
        """
4438
        if not tag_id:
4439
            raise RequiredArgument(
4440
                function=self.delete_tag.__name__, argument='tag_id'
4441
            )
4442
4443
        cmd = XmlCommand("delete_tag")
4444
        cmd.set_attribute("tag_id", tag_id)
4445
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4446
4447
        return self._send_xml_command(cmd)
4448
4449
    def delete_target(
4450
        self, target_id: str, *, ultimate: Optional[bool] = False
4451
    ) -> Any:
4452
        """Deletes an existing target
4453
4454
        Arguments:
4455
            target_id: UUID of the target to be deleted.
4456
            ultimate: Whether to remove entirely, or to the trashcan.
4457
        """
4458
        if not target_id:
4459
            raise RequiredArgument(
4460
                function=self.delete_target.__name__, argument='target_id'
4461
            )
4462
4463
        cmd = XmlCommand("delete_target")
4464
        cmd.set_attribute("target_id", target_id)
4465
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4466
4467
        return self._send_xml_command(cmd)
4468
4469
    def delete_task(
4470
        self, task_id: str, *, ultimate: Optional[bool] = False
4471
    ) -> Any:
4472
        """Deletes an existing task
4473
4474
        Arguments:
4475
            task_id: UUID of the task to be deleted.
4476
            ultimate: Whether to remove entirely, or to the trashcan.
4477
        """
4478
        if not task_id:
4479
            raise RequiredArgument(
4480
                function=self.delete_task.__name__, argument='task_id'
4481
            )
4482
4483
        cmd = XmlCommand("delete_task")
4484
        cmd.set_attribute("task_id", task_id)
4485
        cmd.set_attribute("ultimate", _to_bool(ultimate))
4486
4487
        return self._send_xml_command(cmd)
4488
4489
    def delete_user(
4490
        self,
4491
        user_id: str = None,
4492
        *,
4493
        name: Optional[str] = None,
4494
        inheritor_id: Optional[str] = None,
4495
        inheritor_name: Optional[str] = None,
4496
    ) -> Any:
4497
        """Deletes an existing user
4498
4499
        Either user_id or name must be passed.
4500
4501
        Arguments:
4502
            user_id: UUID of the task to be deleted.
4503
            name: The name of the user to be deleted.
4504
            inheritor_id: The ID of the inheriting user or "self". Overrides
4505
                inheritor_name.
4506
            inheritor_name: The name of the inheriting user.
4507
4508
        """
4509
        if not user_id and not name:
4510
            raise RequiredArgument(
4511
                function=self.delete_user.__name__, argument='user_id or name'
4512
            )
4513
4514
        cmd = XmlCommand("delete_user")
4515
4516
        if user_id:
4517
            cmd.set_attribute("user_id", user_id)
4518
4519
        if name:
4520
            cmd.set_attribute("name", name)
4521
4522
        if inheritor_id:
4523
            cmd.set_attribute("inheritor_id", inheritor_id)
4524
4525
        if inheritor_name:
4526
            cmd.set_attribute("inheritor_name", inheritor_name)
4527
4528
        return self._send_xml_command(cmd)
4529
4530
    def describe_auth(self) -> Any:
4531
        """Describe authentication methods
4532
4533
        Returns a list of all used authentication methods if such a list is
4534
        available.
4535
4536
        Returns:
4537
            The response. See :py:meth:`send_command` for details.
4538
        """
4539
        return self._send_xml_command(XmlCommand("describe_auth"))
4540
4541
    def empty_trashcan(self) -> Any:
4542
        """Empty the trashcan
4543
4544
        Remove all entities from the trashcan. **Attention:** this command can
4545
        not be reverted
4546
4547
        Returns:
4548
            The response. See :py:meth:`send_command` for details.
4549
        """
4550
        return self._send_xml_command(XmlCommand("empty_trashcan"))
4551
4552 View Code Duplication
    def get_alerts(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
4553
        self,
4554
        *,
4555
        filter: Optional[str] = None,
4556
        filter_id: Optional[str] = None,
4557
        trash: Optional[bool] = None,
4558
        tasks: Optional[bool] = None,
4559
    ) -> Any:
4560
        """Request a list of alerts
4561
4562
        Arguments:
4563
            filter: Filter term to use for the query
4564
            filter_id: UUID of an existing filter to use for the query
4565
            trash: True to request the alerts in the trashcan
4566
            tasks: Whether to include the tasks using the alerts
4567
        Returns:
4568
            The response. See :py:meth:`send_command` for details.
4569
        """
4570
        cmd = XmlCommand("get_alerts")
4571
4572
        _add_filter(cmd, filter, filter_id)
4573
4574
        if trash is not None:
4575
            cmd.set_attribute("trash", _to_bool(trash))
4576
4577
        if tasks is not None:
4578
            cmd.set_attribute("tasks", _to_bool(tasks))
4579
4580
        return self._send_xml_command(cmd)
4581
4582
    def get_alert(self, alert_id: str, *, tasks: Optional[bool] = None) -> Any:
4583
        """Request a single alert
4584
4585
        Arguments:
4586
            alert_id: UUID of an existing alert
4587
4588
        Returns:
4589
            The response. See :py:meth:`send_command` for details.
4590
        """
4591
        cmd = XmlCommand("get_alerts")
4592
4593
        if not alert_id:
4594
            raise RequiredArgument(
4595
                function=self.get_alert.__name__, argument='alert_id'
4596
            )
4597
4598
        cmd.set_attribute("alert_id", alert_id)
4599
4600
        if tasks is not None:
4601
            cmd.set_attribute("tasks", _to_bool(tasks))
4602
4603
        return self._send_xml_command(cmd)
4604
4605
    def get_assets(
4606
        self,
4607
        asset_type: AssetType,
4608
        *,
4609
        filter: Optional[str] = None,
4610
        filter_id: Optional[str] = None,
4611
    ) -> Any:
4612
        """Request a list of assets
4613
4614
        Arguments:
4615
            asset_type: Either 'os' or 'host'
4616
            filter: Filter term to use for the query
4617
            filter_id: UUID of an existing filter to use for the query
4618
4619
        Returns:
4620
            The response. See :py:meth:`send_command` for details.
4621
        """
4622
        if not isinstance(asset_type, AssetType):
4623
            raise InvalidArgumentType(
4624
                function=self.get_assets.__name__,
4625
                argument='asset_type',
4626
                arg_type=AssetType.__name__,
4627
            )
4628
4629
        cmd = XmlCommand("get_assets")
4630
4631
        cmd.set_attribute("type", asset_type.value)
4632
4633
        _add_filter(cmd, filter, filter_id)
4634
4635
        return self._send_xml_command(cmd)
4636
4637
    def get_asset(self, asset_id: str, asset_type: AssetType) -> Any:
4638
        """Request a single asset
4639
4640
        Arguments:
4641
            asset_id: UUID of an existing asset
4642
            asset_type: Either 'os' or 'host'
4643
4644
        Returns:
4645
            The response. See :py:meth:`send_command` for details.
4646
        """
4647
        cmd = XmlCommand("get_assets")
4648
4649
        if not isinstance(asset_type, AssetType):
4650
            raise InvalidArgumentType(
4651
                function=self.get_asset.__name__,
4652
                argument='asset_type',
4653
                arg_type=AssetType.__name__,
4654
            )
4655
4656
        if not asset_id:
4657
            raise RequiredArgument(
4658
                function=self.get_asset.__name__, argument='asset_id'
4659
            )
4660
4661
        cmd.set_attribute("asset_id", asset_id)
4662
        cmd.set_attribute("type", asset_type.value)
4663
4664
        return self._send_xml_command(cmd)
4665
4666 View Code Duplication
    def get_credentials(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
4667
        self,
4668
        *,
4669
        filter: Optional[str] = None,
4670
        filter_id: Optional[str] = None,
4671
        scanners: Optional[bool] = None,
4672
        trash: Optional[bool] = None,
4673
        targets: Optional[bool] = None,
4674
    ) -> Any:
4675
        """Request a list of credentials
4676
4677
        Arguments:
4678
            filter: Filter term to use for the query
4679
            filter_id: UUID of an existing filter to use for the query
4680
            scanners: Whether to include a list of scanners using the
4681
                credentials
4682
            trash: Whether to get the trashcan credentials instead
4683
            targets: Whether to include a list of targets using the credentials
4684
4685
        Returns:
4686
            The response. See :py:meth:`send_command` for details.
4687
        """
4688
        cmd = XmlCommand("get_credentials")
4689
4690
        _add_filter(cmd, filter, filter_id)
4691
4692
        if scanners is not None:
4693
            cmd.set_attribute("scanners", _to_bool(scanners))
4694
4695
        if trash is not None:
4696
            cmd.set_attribute("trash", _to_bool(trash))
4697
4698
        if targets is not None:
4699
            cmd.set_attribute("targets", _to_bool(targets))
4700
4701
        return self._send_xml_command(cmd)
4702
4703
    def get_credential(
4704
        self,
4705
        credential_id: str,
4706
        *,
4707
        scanners: Optional[bool] = None,
4708
        targets: Optional[bool] = None,
4709
        credential_format: Optional[CredentialFormat] = None,
4710
    ) -> Any:
4711
        """Request a single credential
4712
4713
        Arguments:
4714
            credential_id: UUID of an existing credential
4715
            scanners: Whether to include a list of scanners using the
4716
                credentials
4717
            targets: Whether to include a list of targets using the credentials
4718
            credential_format: One of "key", "rpm", "deb", "exe" or "pem"
4719
4720
        Returns:
4721
            The response. See :py:meth:`send_command` for details.
4722
        """
4723
        if not credential_id:
4724
            raise RequiredArgument(
4725
                function=self.get_credential.__name__, argument='credential_id'
4726
            )
4727
4728
        cmd = XmlCommand("get_credentials")
4729
        cmd.set_attribute("credential_id", credential_id)
4730
4731
        if credential_format:
4732
            if not isinstance(credential_format, CredentialFormat):
4733
                raise InvalidArgumentType(
4734
                    function=self.get_credential.__name__,
4735
                    argument='credential_format',
4736
                    arg_type=CredentialFormat.__name__,
4737
                )
4738
4739
            cmd.set_attribute("format", credential_format.value)
4740
4741
        if scanners is not None:
4742
            cmd.set_attribute("scanners", _to_bool(scanners))
4743
4744
        if targets is not None:
4745
            cmd.set_attribute("targets", _to_bool(targets))
4746
4747
        return self._send_xml_command(cmd)
4748
4749
    def get_feeds(self) -> Any:
4750
        """Request the list of feeds
4751
4752
        Returns:
4753
            The response. See :py:meth:`send_command` for details.
4754
        """
4755
        return self._send_xml_command(XmlCommand("get_feeds"))
4756
4757 View Code Duplication
    def get_filters(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
4758
        self,
4759
        *,
4760
        filter: Optional[str] = None,
4761
        filter_id: Optional[str] = None,
4762
        trash: Optional[bool] = None,
4763
        alerts: Optional[bool] = None,
4764
    ) -> Any:
4765
        """Request a list of filters
4766
4767
        Arguments:
4768
            filter: Filter term to use for the query
4769
            filter_id: UUID of an existing filter to use for the query
4770
            trash: Whether to get the trashcan filters instead
4771
            alerts: Whether to include list of alerts that use the filter.
4772
4773
        Returns:
4774
            The response. See :py:meth:`send_command` for details.
4775
        """
4776
        cmd = XmlCommand("get_filters")
4777
4778
        _add_filter(cmd, filter, filter_id)
4779
4780
        if trash is not None:
4781
            cmd.set_attribute("trash", _to_bool(trash))
4782
4783
        if alerts is not None:
4784
            cmd.set_attribute("alerts", _to_bool(alerts))
4785
4786
        return self._send_xml_command(cmd)
4787
4788
    def get_filter(
4789
        self, filter_id: str, *, alerts: Optional[bool] = None
4790
    ) -> Any:
4791
        """Request a single filter
4792
4793
        Arguments:
4794
            filter_id: UUID of an existing filter
4795
            alerts: Whether to include list of alerts that use the filter.
4796
4797
        Returns:
4798
            The response. See :py:meth:`send_command` for details.
4799
        """
4800
        cmd = XmlCommand("get_filters")
4801
4802
        if not filter_id:
4803
            raise RequiredArgument(
4804
                function=self.get_filter.__name__, argument='filter_id'
4805
            )
4806
4807
        cmd.set_attribute("filter_id", filter_id)
4808
4809
        if alerts is not None:
4810
            cmd.set_attribute("alerts", _to_bool(alerts))
4811
4812
        return self._send_xml_command(cmd)
4813
4814 View Code Duplication
    def get_groups(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
4815
        self,
4816
        *,
4817
        filter: Optional[str] = None,
4818
        filter_id: Optional[str] = None,
4819
        trash: Optional[bool] = None,
4820
    ) -> Any:
4821
        """Request a list of groups
4822
4823
        Arguments:
4824
            filter: Filter term to use for the query
4825
            filter_id: UUID of an existing filter to use for the query
4826
            trash: Whether to get the trashcan groups instead
4827
4828
        Returns:
4829
            The response. See :py:meth:`send_command` for details.
4830
        """
4831
        cmd = XmlCommand("get_groups")
4832
4833
        _add_filter(cmd, filter, filter_id)
4834
4835
        if trash is not None:
4836
            cmd.set_attribute("trash", _to_bool(trash))
4837
4838
        return self._send_xml_command(cmd)
4839
4840
    def get_group(self, group_id: str) -> Any:
4841
        """Request a single group
4842
4843
        Arguments:
4844
            group_id: UUID of an existing group
4845
4846
        Returns:
4847
            The response. See :py:meth:`send_command` for details.
4848
        """
4849
        cmd = XmlCommand("get_groups")
4850
4851
        if not group_id:
4852
            raise RequiredArgument(
4853
                function=self.get_group.__name__, argument='group_id'
4854
            )
4855
4856
        cmd.set_attribute("group_id", group_id)
4857
        return self._send_xml_command(cmd)
4858
4859
    def get_notes(
4860
        self,
4861
        *,
4862
        filter: Optional[str] = None,
4863
        filter_id: Optional[str] = None,
4864
        details: Optional[bool] = None,
4865
        result: Optional[bool] = None,
4866
    ) -> Any:
4867
        """Request a list of notes
4868
4869
        Arguments:
4870
            filter: Filter term to use for the query
4871
            filter_id: UUID of an existing filter to use for the query
4872
            details: Add info about connected results and tasks
4873
            result: Return the details of possible connected results.
4874
4875
        Returns:
4876
            The response. See :py:meth:`send_command` for details.
4877
        """
4878
        cmd = XmlCommand("get_notes")
4879
4880
        _add_filter(cmd, filter, filter_id)
4881
4882
        if details is not None:
4883
            cmd.set_attribute("details", _to_bool(details))
4884
4885
        if result is not None:
4886
            cmd.set_attribute("result", _to_bool(result))
4887
4888
        return self._send_xml_command(cmd)
4889
4890
    def get_note(self, note_id: str) -> Any:
4891
        """Request a single note
4892
4893
        Arguments:
4894
            note_id: UUID of an existing note
4895
4896
        Returns:
4897
            The response. See :py:meth:`send_command` for details.
4898
        """
4899
        if not note_id:
4900
            raise RequiredArgument(
4901
                function=self.get_note.__name__, argument='note_id'
4902
            )
4903
4904
        cmd = XmlCommand("get_notes")
4905
        cmd.set_attribute("note_id", note_id)
4906
4907
        # for single entity always request all details
4908
        cmd.set_attribute("details", "1")
4909
        return self._send_xml_command(cmd)
4910
4911
    def get_nvts(
4912
        self,
4913
        *,
4914
        details: Optional[bool] = None,
4915
        preferences: Optional[bool] = None,
4916
        preference_count: Optional[bool] = None,
4917
        timeout: Optional[bool] = None,
4918
        config_id: Optional[str] = None,
4919
        preferences_config_id: Optional[str] = None,
4920
        family: Optional[str] = None,
4921
        sort_order: Optional[str] = None,
4922
        sort_field: Optional[str] = None,
4923
    ):
4924
        """Request a list of nvts
4925
4926
        Arguments:
4927
            details: Whether to include full details
4928
            preferences: Whether to include nvt preferences
4929
            preference_count: Whether to include preference count
4930
            timeout: Whether to include the special timeout preference
4931
            config_id: UUID of scan config to which to limit the NVT listing
4932
            preferences_config_id: UUID of scan config to use for preference
4933
                values
4934
            family: Family to which to limit NVT listing
4935
            sort_order: Sort order
4936
            sort_field: Sort field
4937
4938
        Returns:
4939
            The response. See :py:meth:`send_command` for details.
4940
        """
4941
        cmd = XmlCommand("get_nvts")
4942
4943
        if details is not None:
4944
            cmd.set_attribute("details", _to_bool(details))
4945
4946
        if preferences is not None:
4947
            cmd.set_attribute("preferences", _to_bool(preferences))
4948
4949
        if preference_count is not None:
4950
            cmd.set_attribute("preference_count", _to_bool(preference_count))
4951
4952
        if timeout is not None:
4953
            cmd.set_attribute("timeout", _to_bool(timeout))
4954
4955
        if config_id:
4956
            cmd.set_attribute("config_id", config_id)
4957
4958
        if preferences_config_id:
4959
            cmd.set_attribute("preferences_config_id", preferences_config_id)
4960
4961
        if family:
4962
            cmd.set_attribute("family", family)
4963
4964
        if sort_order:
4965
            cmd.set_attribute("sort_order", sort_order)
4966
4967
        if sort_field:
4968
            cmd.set_attribute("sort_field", sort_field)
4969
4970
        return self._send_xml_command(cmd)
4971
4972
    def get_nvt(self, nvt_oid: str):
4973
        """Request a single nvt
4974
4975
        Arguments:
4976
            nvt_oid: OID of an existing nvt
4977
4978
        Returns:
4979
            The response. See :py:meth:`send_command` for details.
4980
        """
4981
        cmd = XmlCommand("get_nvts")
4982
4983
        if not nvt_oid:
4984
            raise RequiredArgument(
4985
                function=self.get_nvt.__name__, argument='nvt_oid'
4986
            )
4987
4988
        cmd.set_attribute("nvt_oid", nvt_oid)
4989
4990
        # for single entity always request all details
4991
        cmd.set_attribute("details", "1")
4992
        cmd.set_attribute("preferences", "1")
4993
        cmd.set_attribute("preference_count", "1")
4994
        return self._send_xml_command(cmd)
4995
4996
    def get_nvt_families(self, *, sort_order: Optional[str] = None):
4997
        """Request a list of nvt families
4998
4999
        Arguments:
5000
            sort_order: Sort order
5001
5002
        Returns:
5003
            The response. See :py:meth:`send_command` for details.
5004
        """
5005
        cmd = XmlCommand("get_nvt_families")
5006
5007
        if sort_order:
5008
            cmd.set_attribute("sort_order", sort_order)
5009
5010
        return self._send_xml_command(cmd)
5011
5012
    def get_overrides(
5013
        self,
5014
        *,
5015
        filter: Optional[str] = None,
5016
        filter_id: Optional[str] = None,
5017
        details: Optional[bool] = None,
5018
        result: Optional[bool] = None,
5019
    ) -> Any:
5020
        """Request a list of overrides
5021
5022
        Arguments:
5023
            filter: Filter term to use for the query
5024
            filter_id: UUID of an existing filter to use for the query
5025
            details: Whether to include full details
5026
            result: Whether to include results using the override
5027
5028
        Returns:
5029
            The response. See :py:meth:`send_command` for details.
5030
        """
5031
        cmd = XmlCommand("get_overrides")
5032
5033
        _add_filter(cmd, filter, filter_id)
5034
5035
        if details is not None:
5036
            cmd.set_attribute("details", _to_bool(details))
5037
5038
        if result is not None:
5039
            cmd.set_attribute("result", _to_bool(result))
5040
5041
        return self._send_xml_command(cmd)
5042
5043
    def get_override(self, override_id: str) -> Any:
5044
        """Request a single override
5045
5046
        Arguments:
5047
            override_id: UUID of an existing override
5048
5049
        Returns:
5050
            The response. See :py:meth:`send_command` for details.
5051
        """
5052
        cmd = XmlCommand("get_overrides")
5053
5054
        if not override_id:
5055
            raise RequiredArgument(
5056
                function=self.get_override.__name__, argument='override_id'
5057
            )
5058
5059
        cmd.set_attribute("override_id", override_id)
5060
5061
        # for single entity always request all details
5062
        cmd.set_attribute("details", "1")
5063
        return self._send_xml_command(cmd)
5064
5065 View Code Duplication
    def get_permissions(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5066
        self,
5067
        *,
5068
        filter: Optional[str] = None,
5069
        filter_id: Optional[str] = None,
5070
        trash: Optional[bool] = None,
5071
    ) -> Any:
5072
        """Request a list of permissions
5073
5074
        Arguments:
5075
            filter: Filter term to use for the query
5076
            filter_id: UUID of an existing filter to use for the query
5077
            trash: Whether to get permissions in the trashcan instead
5078
5079
        Returns:
5080
            The response. See :py:meth:`send_command` for details.
5081
        """
5082
        cmd = XmlCommand("get_permissions")
5083
5084
        _add_filter(cmd, filter, filter_id)
5085
5086
        if trash is not None:
5087
            cmd.set_attribute("trash", _to_bool(trash))
5088
5089
        return self._send_xml_command(cmd)
5090
5091
    def get_permission(self, permission_id: str) -> Any:
5092
        """Request a single permission
5093
5094
        Arguments:
5095
            permission_id: UUID of an existing permission
5096
5097
        Returns:
5098
            The response. See :py:meth:`send_command` for details.
5099
        """
5100
        cmd = XmlCommand("get_permissions")
5101
5102
        if not permission_id:
5103
            raise RequiredArgument(
5104
                function=self.get_permission.__name__, argument='permission_id'
5105
            )
5106
5107
        cmd.set_attribute("permission_id", permission_id)
5108
        return self._send_xml_command(cmd)
5109
5110 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...
5111
        self,
5112
        *,
5113
        filter: Optional[str] = None,
5114
        filter_id: Optional[str] = None,
5115
        details: Optional[bool] = None,
5116
        targets: Optional[bool] = None,
5117
        trash: Optional[bool] = None,
5118
    ) -> Any:
5119
        """Request a list of port lists
5120
5121
        Arguments:
5122
            filter: Filter term to use for the query
5123
            filter_id: UUID of an existing filter to use for the query
5124
            details: Whether to include full port list details
5125
            targets: Whether to include targets using this port list
5126
            trash: Whether to get port lists in the trashcan instead
5127
5128
        Returns:
5129
            The response. See :py:meth:`send_command` for details.
5130
        """
5131
        cmd = XmlCommand("get_port_lists")
5132
5133
        _add_filter(cmd, filter, filter_id)
5134
5135
        if details is not None:
5136
            cmd.set_attribute("details", _to_bool(details))
5137
5138
        if targets is not None:
5139
            cmd.set_attribute("targets", _to_bool(targets))
5140
5141
        if trash is not None:
5142
            cmd.set_attribute("trash", _to_bool(trash))
5143
5144
        return self._send_xml_command(cmd)
5145
5146
    def get_port_list(self, port_list_id: str):
5147
        """Request a single port list
5148
5149
        Arguments:
5150
            port_list_id: UUID of an existing port list
5151
5152
        Returns:
5153
            The response. See :py:meth:`send_command` for details.
5154
        """
5155
        cmd = XmlCommand("get_port_lists")
5156
5157
        if not port_list_id:
5158
            raise RequiredArgument(
5159
                function=self.get_port_list.__name__, argument='port_list_id'
5160
            )
5161
5162
        cmd.set_attribute("port_list_id", port_list_id)
5163
5164
        # for single entity always request all details
5165
        cmd.set_attribute("details", "1")
5166
        return self._send_xml_command(cmd)
5167
5168
    def get_preferences(
5169
        self, *, nvt_oid: Optional[str] = None, config_id: Optional[str] = None
5170
    ) -> Any:
5171
        """Request a list of preferences
5172
5173
        When the command includes a config_id attribute, the preference element
5174
        includes the preference name, type and value, and the NVT to which the
5175
        preference applies. Otherwise, the preference element includes just the
5176
        name and value, with the NVT and type built into the name.
5177
5178
        Arguments:
5179
            nvt_oid: OID of nvt
5180
            config_id: UUID of scan config of which to show preference values
5181
5182
        Returns:
5183
            The response. See :py:meth:`send_command` for details.
5184
        """
5185
        cmd = XmlCommand("get_preferences")
5186
5187
        if nvt_oid:
5188
            cmd.set_attribute("nvt_oid", nvt_oid)
5189
5190
        if config_id:
5191
            cmd.set_attribute("config_id", config_id)
5192
5193
        return self._send_xml_command(cmd)
5194
5195
    def get_preference(
5196
        self,
5197
        name: str,
5198
        *,
5199
        nvt_oid: Optional[str] = None,
5200
        config_id: Optional[str] = None,
5201
    ) -> Any:
5202
        """Request a nvt preference
5203
5204
        Arguments:
5205
            name: name of a particular preference
5206
            nvt_oid: OID of nvt
5207
            config_id: UUID of scan config of which to show preference values
5208
5209
        Returns:
5210
            The response. See :py:meth:`send_command` for details.
5211
        """
5212
        cmd = XmlCommand("get_preferences")
5213
5214
        if not name:
5215
            raise RequiredArgument(
5216
                function=self.get_preference.__name__, argument='name'
5217
            )
5218
5219
        cmd.set_attribute("preference", name)
5220
5221
        if nvt_oid:
5222
            cmd.set_attribute("nvt_oid", nvt_oid)
5223
5224
        if config_id:
5225
            cmd.set_attribute("config_id", config_id)
5226
5227
        return self._send_xml_command(cmd)
5228
5229 View Code Duplication
    def get_reports(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5230
        self,
5231
        *,
5232
        filter: Optional[str] = None,
5233
        filter_id: Optional[str] = None,
5234
        note_details: Optional[bool] = None,
5235
        override_details: Optional[bool] = None,
5236
        details: Optional[bool] = None,
5237
    ) -> Any:
5238
        """Request a list of reports
5239
5240
        Arguments:
5241
            filter: Filter term to use for the query
5242
            filter_id: UUID of an existing filter to use for the query
5243
            note_details: If notes are included, whether to include note details
5244
            override_details: If overrides are included, whether to include
5245
                override details
5246
            details: Whether to exclude results
5247
5248
        Returns:
5249
            The response. See :py:meth:`send_command` for details.
5250
        """
5251
        cmd = XmlCommand("get_reports")
5252
5253
        if filter:
5254
            cmd.set_attribute("report_filter", filter)
5255
5256
        if filter_id:
5257
            cmd.set_attribute("report_filt_id", filter_id)
5258
5259
        if note_details is not None:
5260
            cmd.set_attribute("note_details", _to_bool(note_details))
5261
5262
        if override_details is not None:
5263
            cmd.set_attribute("override_details", _to_bool(override_details))
5264
5265
        if details is not None:
5266
            cmd.set_attribute("details", _to_bool(details))
5267
5268
        cmd.set_attribute("ignore_pagination", "1")
5269
5270
        return self._send_xml_command(cmd)
5271
5272
    def get_report(
5273
        self,
5274
        report_id: str,
5275
        *,
5276
        filter: Optional[str] = None,
5277
        filter_id: Optional[str] = None,
5278
        delta_report_id: Optional[str] = None,
5279
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
5280
        ignore_pagination: Optional[bool] = None,
5281
        details: Optional[bool] = True,
5282
    ) -> Any:
5283
        """Request a single report
5284
5285
        Arguments:
5286
            report_id: UUID of an existing report
5287
            filter: Filter term to use to filter results in the report
5288
            filter_id: UUID of filter to use to filter results in the report
5289
            delta_report_id: UUID of an existing report to compare report to.
5290
            report_format_id: UUID of report format to use
5291
                              or ReportFormatType (enum)
5292
            ignore_pagination: Whether to ignore the filter terms "first" and
5293
                "rows".
5294
            details: Request additional report information details
5295
                     defaults to True
5296
5297
        Returns:
5298
            The response. See :py:meth:`send_command` for details.
5299
        """
5300
        cmd = XmlCommand("get_reports")
5301
5302
        if not report_id:
5303
            raise RequiredArgument(
5304
                function=self.get_report.__name__, argument='report_id'
5305
            )
5306
5307
        cmd.set_attribute("report_id", report_id)
5308
5309
        _add_filter(cmd, filter, filter_id)
5310
5311
        if delta_report_id:
5312
            cmd.set_attribute("delta_report_id", delta_report_id)
5313
5314
        if report_format_id:
5315
            if isinstance(report_format_id, ReportFormatType):
5316
                report_format_id = report_format_id.value
5317
5318
            cmd.set_attribute("format_id", report_format_id)
5319
5320
        if ignore_pagination is not None:
5321
            cmd.set_attribute("ignore_pagination", _to_bool(ignore_pagination))
5322
5323
        cmd.set_attribute("details", _to_bool(details))
5324
5325
        return self._send_xml_command(cmd)
5326
5327
    def get_report_formats(
5328
        self,
5329
        *,
5330
        filter: Optional[str] = None,
5331
        filter_id: Optional[str] = None,
5332
        trash: Optional[bool] = None,
5333
        alerts: Optional[bool] = None,
5334
        params: Optional[bool] = None,
5335
        details: Optional[bool] = None,
5336
    ) -> Any:
5337
        """Request a list of report formats
5338
5339
        Arguments:
5340
            filter: Filter term to use for the query
5341
            filter_id: UUID of an existing filter to use for the query
5342
            trash: Whether to get the trashcan report formats instead
5343
            alerts: Whether to include alerts that use the report format
5344
            params: Whether to include report format parameters
5345
            details: Include report format file, signature and parameters
5346
5347
        Returns:
5348
            The response. See :py:meth:`send_command` for details.
5349
        """
5350
        cmd = XmlCommand("get_report_formats")
5351
5352
        _add_filter(cmd, filter, filter_id)
5353
5354
        if details is not None:
5355
            cmd.set_attribute("details", _to_bool(details))
5356
5357
        if alerts is not None:
5358
            cmd.set_attribute("alerts", _to_bool(alerts))
5359
5360
        if params is not None:
5361
            cmd.set_attribute("params", _to_bool(params))
5362
5363
        if trash is not None:
5364
            cmd.set_attribute("trash", _to_bool(trash))
5365
5366
        return self._send_xml_command(cmd)
5367
5368 View Code Duplication
    def get_report_format(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5369
        self, report_format_id: Union[str, ReportFormatType]
5370
    ) -> Any:
5371
        """Request a single report format
5372
5373
        Arguments:
5374
            report_format_id: UUID of an existing report format
5375
                              or ReportFormatType (enum)
5376
5377
        Returns:
5378
            The response. See :py:meth:`send_command` for details.
5379
        """
5380
        cmd = XmlCommand("get_report_formats")
5381
5382
        if not report_format_id:
5383
            raise RequiredArgument(
5384
                function=self.get_report_format.__name__,
5385
                argument='report_format_id',
5386
            )
5387
5388
        if isinstance(report_format_id, ReportFormatType):
5389
            report_format_id = report_format_id.value
5390
5391
        cmd.set_attribute("report_format_id", report_format_id)
5392
5393
        # for single entity always request all details
5394
        cmd.set_attribute("details", "1")
5395
        return self._send_xml_command(cmd)
5396
5397 View Code Duplication
    def get_results(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5398
        self,
5399
        *,
5400
        filter: Optional[str] = None,
5401
        filter_id: Optional[str] = None,
5402
        task_id: Optional[str] = None,
5403
        note_details: Optional[bool] = None,
5404
        override_details: Optional[bool] = None,
5405
        details: Optional[bool] = None,
5406
    ) -> Any:
5407
        """Request a list of results
5408
5409
        Arguments:
5410
            filter: Filter term to use for the query
5411
            filter_id: UUID of an existing filter to use for the query
5412
            task_id: UUID of task for note and override handling
5413
            note_details: If notes are included, whether to include note details
5414
            override_details: If overrides are included, whether to include
5415
                override details
5416
            details: Whether to include additional details of the results
5417
5418
        Returns:
5419
            The response. See :py:meth:`send_command` for details.
5420
        """
5421
        cmd = XmlCommand("get_results")
5422
5423
        _add_filter(cmd, filter, filter_id)
5424
5425
        if task_id:
5426
            cmd.set_attribute("task_id", task_id)
5427
5428
        if details is not None:
5429
            cmd.set_attribute("details", _to_bool(details))
5430
5431
        if note_details is not None:
5432
            cmd.set_attribute("note_details", _to_bool(note_details))
5433
5434
        if override_details is not None:
5435
            cmd.set_attribute("override_details", _to_bool(override_details))
5436
5437
        return self._send_xml_command(cmd)
5438
5439
    def get_result(self, result_id: str) -> Any:
5440
        """Request a single result
5441
5442
        Arguments:
5443
            result_id: UUID of an existing result
5444
5445
        Returns:
5446
            The response. See :py:meth:`send_command` for details.
5447
        """
5448
        cmd = XmlCommand("get_results")
5449
5450
        if not result_id:
5451
            raise RequiredArgument(
5452
                function=self.get_result.__name__, argument='result_id'
5453
            )
5454
5455
        cmd.set_attribute("result_id", result_id)
5456
5457
        # for single entity always request all details
5458
        cmd.set_attribute("details", "1")
5459
        return self._send_xml_command(cmd)
5460
5461 View Code Duplication
    def get_roles(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5462
        self,
5463
        *,
5464
        filter: Optional[str] = None,
5465
        filter_id: Optional[str] = None,
5466
        trash: Optional[bool] = None,
5467
    ) -> Any:
5468
        """Request a list of roles
5469
5470
        Arguments:
5471
            filter: Filter term to use for the query
5472
            filter_id: UUID of an existing filter to use for the query
5473
            trash: Whether to get the trashcan roles instead
5474
5475
        Returns:
5476
            The response. See :py:meth:`send_command` for details.
5477
        """
5478
        cmd = XmlCommand("get_roles")
5479
5480
        _add_filter(cmd, filter, filter_id)
5481
5482
        if trash is not None:
5483
            cmd.set_attribute("trash", _to_bool(trash))
5484
5485
        return self._send_xml_command(cmd)
5486
5487
    def get_role(self, role_id: str) -> Any:
5488
        """Request a single role
5489
5490
        Arguments:
5491
            role_id: UUID of an existing role
5492
5493
        Returns:
5494
            The response. See :py:meth:`send_command` for details.
5495
        """
5496
        if not role_id:
5497
            raise RequiredArgument(
5498
                function=self.get_role.__name__, argument='role_id'
5499
            )
5500
5501
        cmd = XmlCommand("get_roles")
5502
        cmd.set_attribute("role_id", role_id)
5503
        return self._send_xml_command(cmd)
5504
5505 View Code Duplication
    def get_scanners(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5506
        self,
5507
        *,
5508
        filter: Optional[str] = None,
5509
        filter_id: Optional[str] = None,
5510
        trash: Optional[bool] = None,
5511
        details: Optional[bool] = None,
5512
    ) -> Any:
5513
        """Request a list of scanners
5514
5515
        Arguments:
5516
            filter: Filter term to use for the query
5517
            filter_id: UUID of an existing filter to use for the query
5518
            trash: Whether to get the trashcan scanners instead
5519
            details:  Whether to include extra details like tasks using this
5520
                scanner
5521
5522
        Returns:
5523
            The response. See :py:meth:`send_command` for details.
5524
        """
5525
        cmd = XmlCommand("get_scanners")
5526
5527
        _add_filter(cmd, filter, filter_id)
5528
5529
        if trash is not None:
5530
            cmd.set_attribute("trash", _to_bool(trash))
5531
5532
        if details is not None:
5533
            cmd.set_attribute("details", _to_bool(details))
5534
5535
        return self._send_xml_command(cmd)
5536
5537
    def get_scanner(self, scanner_id: str) -> Any:
5538
        """Request a single scanner
5539
5540
        Arguments:
5541
            scanner_id: UUID of an existing scanner
5542
5543
        Returns:
5544
            The response. See :py:meth:`send_command` for details.
5545
        """
5546
        cmd = XmlCommand("get_scanners")
5547
5548
        if not scanner_id:
5549
            raise RequiredArgument(
5550
                function=self.get_scanner.__name__, argument='scanner_id'
5551
            )
5552
5553
        cmd.set_attribute("scanner_id", scanner_id)
5554
5555
        # for single entity always request all details
5556
        cmd.set_attribute("details", "1")
5557
        return self._send_xml_command(cmd)
5558
5559 View Code Duplication
    def get_schedules(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5560
        self,
5561
        *,
5562
        filter: Optional[str] = None,
5563
        filter_id: Optional[str] = None,
5564
        trash: Optional[bool] = None,
5565
        tasks: Optional[bool] = None,
5566
    ) -> Any:
5567
        """Request a list of schedules
5568
5569
        Arguments:
5570
            filter: Filter term to use for the query
5571
            filter_id: UUID of an existing filter to use for the query
5572
            trash: Whether to get the trashcan schedules instead
5573
            tasks: Whether to include tasks using the schedules
5574
5575
        Returns:
5576
            The response. See :py:meth:`send_command` for details.
5577
        """
5578
        cmd = XmlCommand("get_schedules")
5579
5580
        _add_filter(cmd, filter, filter_id)
5581
5582
        if trash is not None:
5583
            cmd.set_attribute("trash", _to_bool(trash))
5584
5585
        if tasks is not None:
5586
            cmd.set_attribute("tasks", _to_bool(tasks))
5587
5588
        return self._send_xml_command(cmd)
5589
5590
    def get_schedule(
5591
        self, schedule_id: str, *, tasks: Optional[bool] = None
5592
    ) -> Any:
5593
        """Request a single schedule
5594
5595
        Arguments:
5596
            schedule_id: UUID of an existing schedule
5597
            tasks: Whether to include tasks using the schedules
5598
5599
        Returns:
5600
            The response. See :py:meth:`send_command` for details.
5601
        """
5602
        cmd = XmlCommand("get_schedules")
5603
5604
        if not schedule_id:
5605
            raise RequiredArgument(
5606
                function=self.get_schedule.__name__, argument='schedule_id'
5607
            )
5608
5609
        cmd.set_attribute("schedule_id", schedule_id)
5610
5611
        if tasks is not None:
5612
            cmd.set_attribute("tasks", _to_bool(tasks))
5613
5614
        return self._send_xml_command(cmd)
5615
5616
    def get_settings(self, *, filter: Optional[str] = None) -> Any:
5617
        """Request a list of user settings
5618
5619
        Arguments:
5620
            filter: Filter term to use for the query
5621
5622
        Returns:
5623
            The response. See :py:meth:`send_command` for details.
5624
        """
5625
        cmd = XmlCommand("get_settings")
5626
5627
        if filter:
5628
            cmd.set_attribute("filter", filter)
5629
5630
        return self._send_xml_command(cmd)
5631
5632
    def get_setting(self, setting_id: str) -> Any:
5633
        """Request a single setting
5634
5635
        Arguments:
5636
            setting_id: UUID of an existing setting
5637
5638
        Returns:
5639
            The response. See :py:meth:`send_command` for details.
5640
        """
5641
        cmd = XmlCommand("get_settings")
5642
5643
        if not setting_id:
5644
            raise RequiredArgument(
5645
                function=self.get_setting.__name__, argument='setting_id'
5646
            )
5647
5648
        cmd.set_attribute("setting_id", setting_id)
5649
        return self._send_xml_command(cmd)
5650
5651
    def get_system_reports(
5652
        self,
5653
        *,
5654
        name: Optional[str] = None,
5655
        duration: Optional[int] = None,
5656
        start_time: Optional[str] = None,
5657
        end_time: Optional[str] = None,
5658
        brief: Optional[bool] = None,
5659
        slave_id: Optional[str] = None,
5660
    ) -> Any:
5661
        """Request a list of system reports
5662
5663
        Arguments:
5664
            name: A string describing the required system report
5665
            duration: The number of seconds into the past that the system report
5666
                should include
5667
            start_time: The start of the time interval the system report should
5668
                include in ISO time format
5669
            end_time: The end of the time interval the system report should
5670
                include in ISO time format
5671
            brief: Whether to include the actual system reports
5672
            slave_id: UUID of GMP scanner from which to get the system reports
5673
5674
        Returns:
5675
            The response. See :py:meth:`send_command` for details.
5676
        """
5677
        cmd = XmlCommand("get_system_reports")
5678
5679
        if name:
5680
            cmd.set_attribute("name", name)
5681
5682
        if duration is not None:
5683
            if not isinstance(duration, numbers.Integral):
5684
                raise InvalidArgument("duration needs to be an integer number")
5685
5686
            cmd.set_attribute("duration", str(duration))
5687
5688
        if start_time:
5689
            cmd.set_attribute("start_time", str(start_time))
5690
5691
        if end_time:
5692
            cmd.set_attribute("end_time", str(end_time))
5693
5694
        if brief is not None:
5695
            cmd.set_attribute("brief", _to_bool(brief))
5696
5697
        if slave_id:
5698
            cmd.set_attribute("slave_id", slave_id)
5699
5700
        return self._send_xml_command(cmd)
5701
5702 View Code Duplication
    def get_tags(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5703
        self,
5704
        *,
5705
        filter: Optional[str] = None,
5706
        filter_id: Optional[str] = None,
5707
        trash: Optional[bool] = None,
5708
        names_only: Optional[bool] = None,
5709
    ) -> Any:
5710
        """Request a list of tags
5711
5712
        Arguments:
5713
            filter: Filter term to use for the query
5714
            filter_id: UUID of an existing filter to use for the query
5715
            trash: Whether to get tags from the trashcan instead
5716
            names_only: Whether to get only distinct tag names
5717
5718
        Returns:
5719
            The response. See :py:meth:`send_command` for details.
5720
        """
5721
        cmd = XmlCommand("get_tags")
5722
5723
        _add_filter(cmd, filter, filter_id)
5724
5725
        if trash is not None:
5726
            cmd.set_attribute("trash", _to_bool(trash))
5727
5728
        if names_only is not None:
5729
            cmd.set_attribute("names_only", _to_bool(names_only))
5730
5731
        return self._send_xml_command(cmd)
5732
5733
    def get_tag(self, tag_id: str) -> Any:
5734
        """Request a single tag
5735
5736
        Arguments:
5737
            tag_id: UUID of an existing tag
5738
5739
        Returns:
5740
            The response. See :py:meth:`send_command` for details.
5741
        """
5742
        cmd = XmlCommand("get_tags")
5743
5744
        if not tag_id:
5745
            raise RequiredArgument(
5746
                function=self.get_tag.__name__, argument='tag_id'
5747
            )
5748
5749
        cmd.set_attribute("tag_id", tag_id)
5750
        return self._send_xml_command(cmd)
5751
5752 View Code Duplication
    def get_targets(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5753
        self,
5754
        *,
5755
        filter: Optional[str] = None,
5756
        filter_id: Optional[str] = None,
5757
        trash: Optional[bool] = None,
5758
        tasks: Optional[bool] = None,
5759
    ) -> Any:
5760
        """Request a list of targets
5761
5762
        Arguments:
5763
            filter: Filter term to use for the query
5764
            filter_id: UUID of an existing filter to use for the query
5765
            trash: Whether to get the trashcan targets instead
5766
            tasks: Whether to include list of tasks that use the target
5767
5768
        Returns:
5769
            The response. See :py:meth:`send_command` for details.
5770
        """
5771
        cmd = XmlCommand("get_targets")
5772
5773
        _add_filter(cmd, filter, filter_id)
5774
5775
        if trash is not None:
5776
            cmd.set_attribute("trash", _to_bool(trash))
5777
5778
        if tasks is not None:
5779
            cmd.set_attribute("tasks", _to_bool(tasks))
5780
5781
        return self._send_xml_command(cmd)
5782
5783
    def get_target(
5784
        self, target_id: str, *, tasks: Optional[bool] = None
5785
    ) -> Any:
5786
        """Request a single target
5787
5788
        Arguments:
5789
            target_id: UUID of an existing target
5790
            tasks: Whether to include list of tasks that use the target
5791
5792
        Returns:
5793
            The response. See :py:meth:`send_command` for details.
5794
        """
5795
        cmd = XmlCommand("get_targets")
5796
5797
        if not target_id:
5798
            raise RequiredArgument(
5799
                function=self.get_target.__name__, argument='target_id'
5800
            )
5801
5802
        cmd.set_attribute("target_id", target_id)
5803
5804
        if tasks is not None:
5805
            cmd.set_attribute("tasks", _to_bool(tasks))
5806
5807
        return self._send_xml_command(cmd)
5808
5809
    def get_users(
5810
        self, *, filter: Optional[str] = None, filter_id: Optional[str] = None
5811
    ) -> Any:
5812
        """Request a list of users
5813
5814
        Arguments:
5815
            filter: Filter term to use for the query
5816
            filter_id: UUID of an existing filter to use for the query
5817
5818
        Returns:
5819
            The response. See :py:meth:`send_command` for details.
5820
        """
5821
        cmd = XmlCommand("get_users")
5822
5823
        _add_filter(cmd, filter, filter_id)
5824
5825
        return self._send_xml_command(cmd)
5826
5827
    def get_user(self, user_id: str) -> Any:
5828
        """Request a single user
5829
5830
        Arguments:
5831
            user_id: UUID of an existing user
5832
5833
        Returns:
5834
            The response. See :py:meth:`send_command` for details.
5835
        """
5836
        cmd = XmlCommand("get_users")
5837
5838
        if not user_id:
5839
            raise RequiredArgument(
5840
                function=self.get_user.__name__, argument='user_id'
5841
            )
5842
5843
        cmd.set_attribute("user_id", user_id)
5844
        return self._send_xml_command(cmd)
5845
5846
    def get_version(self) -> Any:
5847
        """Get the Greenbone Manager Protocol version used by the remote gvmd
5848
5849
        Returns:
5850
            The response. See :py:meth:`send_command` for details.
5851
        """
5852
        return self._send_xml_command(XmlCommand("get_version"))
5853
5854
    def help(
5855
        self, *, format: Optional[str] = None, help_type: Optional[str] = ""
5856
    ) -> Any:
5857
        """Get the help text
5858
5859
        Arguments:
5860
            format: One of "html", "rnc", "text" or "xml
5861
            help_type: One of "brief" or "". Default ""
5862
5863
        Returns:
5864
            The response. See :py:meth:`send_command` for details.
5865
        """
5866
        cmd = XmlCommand("help")
5867
5868
        if help_type not in ("", "brief"):
5869
            raise InvalidArgument(
5870
                'help_type argument must be an empty string or "brief"'
5871
            )
5872
5873
        cmd.set_attribute("type", help_type)
5874
5875
        if format:
5876
            if not format.lower() in ("html", "rnc", "text", "xml"):
5877
                raise InvalidArgument(
5878
                    "help format Argument must be one of html, rnc, text or "
5879
                    "xml"
5880
                )
5881
5882
            cmd.set_attribute("format", format)
5883
5884
        return self._send_xml_command(cmd)
5885
5886
    def modify_asset(self, asset_id: str, comment: Optional[str] = "") -> Any:
5887
        """Modifies an existing asset.
5888
5889
        Arguments:
5890
            asset_id: UUID of the asset to be modified.
5891
            comment: Comment for the asset.
5892
5893
        Returns:
5894
            The response. See :py:meth:`send_command` for details.
5895
        """
5896
        if not asset_id:
5897
            raise RequiredArgument(
5898
                function=self.modify_asset.__name__, argument='asset_id'
5899
            )
5900
5901
        cmd = XmlCommand("modify_asset")
5902
        cmd.set_attribute("asset_id", asset_id)
5903
        cmd.add_element("comment", comment)
5904
5905
        return self._send_xml_command(cmd)
5906
5907
    def modify_auth(self, group_name: str, auth_conf_settings: dict) -> Any:
5908
        """Modifies an existing auth.
5909
5910
        Arguments:
5911
            group_name: Name of the group to be modified.
5912
            auth_conf_settings: The new auth config.
5913
5914
        Returns:
5915
            The response. See :py:meth:`send_command` for details.
5916
        """
5917
        if not group_name:
5918
            raise RequiredArgument(
5919
                function=self.modify_auth.__name__, argument='group_name'
5920
            )
5921
        if not auth_conf_settings:
5922
            raise RequiredArgument(
5923
                function=self.modify_auth.__name__,
5924
                argument='auth_conf_settings',
5925
            )
5926
        cmd = XmlCommand("modify_auth")
5927
        _xmlgroup = cmd.add_element("group", attrs={"name": str(group_name)})
5928
5929
        for key, value in auth_conf_settings.items():
5930
            _xmlauthconf = _xmlgroup.add_element("auth_conf_setting")
5931
            _xmlauthconf.add_element("key", key)
5932
            _xmlauthconf.add_element("value", value)
5933
5934
        return self._send_xml_command(cmd)
5935
5936
    def modify_config_set_nvt_preference(
5937
        self,
5938
        config_id: str,
5939
        name: str,
5940
        nvt_oid: str,
5941
        *,
5942
        value: Optional[str] = None,
5943
    ) -> Any:
5944
        """Modifies the nvt preferences of an existing scan config.
5945
5946
        Arguments:
5947
            config_id: UUID of scan config to modify.
5948
            name: Name for nvt preference to change.
5949
            nvt_oid: OID of the NVT associated with preference to modify
5950
            value: New value for the preference. None to delete the preference
5951
                and to use the default instead.
5952
        """
5953
        if not config_id:
5954
            raise RequiredArgument(
5955
                function=self.modify_config_set_nvt_preference.__name__,
5956
                argument='config_id',
5957
            )
5958
5959
        if not nvt_oid:
5960
            raise RequiredArgument(
5961
                function=self.modify_config_set_nvt_preference.__name__,
5962
                argument='nvt_oid',
5963
            )
5964
5965
        if not name:
5966
            raise RequiredArgument(
5967
                function=self.modify_config_set_nvt_preference.__name__,
5968
                argument='name',
5969
            )
5970
5971
        cmd = XmlCommand("modify_config")
5972
        cmd.set_attribute("config_id", str(config_id))
5973
5974
        _xmlpref = cmd.add_element("preference")
5975
5976
        _xmlpref.add_element("nvt", attrs={"oid": nvt_oid})
5977
        _xmlpref.add_element("name", name)
5978
5979
        if value:
5980
            _xmlpref.add_element("value", _to_base64(value))
5981
5982
        return self._send_xml_command(cmd)
5983
5984
    def modify_config_set_name(self, config_id: str, name: str) -> Any:
5985
        """Modifies the name of an existing scan config
5986
5987
        Arguments:
5988
            config_id: UUID of scan config to modify.
5989
            name: New name for the config.
5990
        """
5991
        if not config_id:
5992
            raise RequiredArgument(
5993
                function=self.modify_config_set_name.__name__,
5994
                argument='config_id',
5995
            )
5996
5997
        if not name:
5998
            raise RequiredArgument(
5999
                function=self.modify_config_set_name.__name__, argument='name'
6000
            )
6001
6002
        cmd = XmlCommand("modify_config")
6003
        cmd.set_attribute("config_id", str(config_id))
6004
6005
        cmd.add_element("name", name)
6006
6007
        return self._send_xml_command(cmd)
6008
6009
    def modify_config_set_comment(
6010
        self, config_id: str, comment: Optional[str] = ""
6011
    ) -> Any:
6012
        """Modifies the comment of an existing scan config
6013
6014
        Arguments:
6015
            config_id: UUID of scan config to modify.
6016
            comment: Comment to set on a config. Default: ''
6017
        """
6018
        if not config_id:
6019
            raise RequiredArgument(
6020
                function=self.modify_config_set_comment.__name__,
6021
                argument='config_id argument',
6022
            )
6023
6024
        cmd = XmlCommand("modify_config")
6025
        cmd.set_attribute("config_id", str(config_id))
6026
6027
        cmd.add_element("comment", comment)
6028
6029
        return self._send_xml_command(cmd)
6030
6031
    def modify_config_set_scanner_preference(
6032
        self, config_id: str, name: str, *, value: Optional[str] = None
6033
    ) -> Any:
6034
        """Modifies the scanner preferences of an existing scan config
6035
6036
        Arguments:
6037
            config_id: UUID of scan config to modify.
6038
            name: Name of the scanner preference to change
6039
            value: New value for the preference. None to delete the preference
6040
                and to use the default instead.
6041
6042
        """
6043
        if not config_id:
6044
            raise RequiredArgument(
6045
                function=self.modify_config_set_scanner_preference.__name__,
6046
                argument='config_id',
6047
            )
6048
6049
        if not name:
6050
            raise RequiredArgument(
6051
                function=self.modify_config_set_scanner_preference.__name__,
6052
                argument='name argument',
6053
            )
6054
6055
        cmd = XmlCommand("modify_config")
6056
        cmd.set_attribute("config_id", str(config_id))
6057
6058
        _xmlpref = cmd.add_element("preference")
6059
6060
        _xmlpref.add_element("name", name)
6061
6062
        if value:
6063
            _xmlpref.add_element("value", _to_base64(value))
6064
6065
        return self._send_xml_command(cmd)
6066
6067
    def modify_config_set_nvt_selection(
6068
        self, config_id: str, family: str, nvt_oids: List[str]
6069
    ) -> Any:
6070
        """Modifies the selected nvts of an existing scan config
6071
6072
        The manager updates the given family in the config to include only the
6073
        given NVTs.
6074
6075
        Arguments:
6076
            config_id: UUID of scan config to modify.
6077
            family: Name of the NVT family to include NVTs from
6078
            nvt_oids: List of NVTs to select for the family.
6079
        """
6080
        if not config_id:
6081
            raise RequiredArgument(
6082
                function=self.modify_config_set_nvt_selection.__name__,
6083
                argument='config_id',
6084
            )
6085
6086
        if not family:
6087
            raise RequiredArgument(
6088
                function=self.modify_config_set_nvt_selection.__name__,
6089
                argument='family argument',
6090
            )
6091
6092
        if not _is_list_like(nvt_oids):
6093
            raise InvalidArgumentType(
6094
                function=self.modify_config_set_nvt_selection.__name__,
6095
                argument='nvt_oids',
6096
                arg_type='list',
6097
            )
6098
6099
        cmd = XmlCommand("modify_config")
6100
        cmd.set_attribute("config_id", str(config_id))
6101
6102
        _xmlnvtsel = cmd.add_element("nvt_selection")
6103
        _xmlnvtsel.add_element("family", family)
6104
6105
        for nvt in nvt_oids:
6106
            _xmlnvtsel.add_element("nvt", attrs={"oid": nvt})
6107
6108
        return self._send_xml_command(cmd)
6109
6110
    def modify_config_set_family_selection(
6111
        self,
6112
        config_id: str,
6113
        families: List[Tuple[str, bool, bool]],
6114
        *,
6115
        auto_add_new_families: Optional[bool] = True,
6116
    ) -> Any:
6117
        """
6118
        Selected the NVTs of a scan config at a family level.
6119
6120
        Arguments:
6121
            config_id: UUID of scan config to modify.
6122
            families: A list of tuples (str, bool, bool):
6123
                str: the name of the NVT family selected,
6124
                bool: add new NVTs  to the family automatically,
6125
                bool: include all NVTs from the family
6126
            auto_add_new_families: Whether new families should be added to the
6127
                scan config automatically. Default: True.
6128
        """
6129
        if not config_id:
6130
            raise RequiredArgument(
6131
                function=self.modify_config_set_family_selection.__name__,
6132
                argument='config_id',
6133
            )
6134
6135
        if not _is_list_like(families):
6136
            raise InvalidArgumentType(
6137
                function=self.modify_config_set_family_selection.__name__,
6138
                argument='families',
6139
                arg_type='list',
6140
            )
6141
6142
        cmd = XmlCommand("modify_config")
6143
        cmd.set_attribute("config_id", str(config_id))
6144
6145
        _xmlfamsel = cmd.add_element("family_selection")
6146
        _xmlfamsel.add_element("growing", _to_bool(auto_add_new_families))
6147
6148
        for family in families:
6149
            _xmlfamily = _xmlfamsel.add_element("family")
6150
            _xmlfamily.add_element("name", family[0])
6151
6152
            if len(family) != 3:
6153
                raise InvalidArgument(
6154
                    "Family must be a tuple of 3. (str, bool, bool)"
6155
                )
6156
6157
            if not isinstance(family[1], bool) or not isinstance(
6158
                family[2], bool
6159
            ):
6160
                raise InvalidArgumentType(
6161
                    function=self.modify_config_set_family_selection.__name__,
6162
                    argument='families',
6163
                    arg_type='[tuple(str, bool, bool)]',
6164
                )
6165
6166
            _xmlfamily.add_element("all", _to_bool(family[2]))
6167
            _xmlfamily.add_element("growing", _to_bool(family[1]))
6168
6169
        return self._send_xml_command(cmd)
6170
6171
    def modify_config(
6172
        self, config_id: str, selection: Optional[str] = None, **kwargs
6173
    ) -> Any:
6174
        """Modifies an existing scan config.
6175
6176
        DEPRECATED. Please use *modify_config_set_* methods instead.
6177
6178
        modify_config has four modes to operate depending on the selection.
6179
6180
        Arguments:
6181
            config_id: UUID of scan config to modify.
6182
            selection: one of 'scan_pref', 'nvt_pref', 'nvt_selection' or
6183
                'family_selection'
6184
            name: New name for preference.
6185
            value: New value for preference.
6186
            nvt_oids: List of NVTs associated with preference to modify.
6187
            family: Name of family to modify.
6188
6189
        Returns:
6190
            The response. See :py:meth:`send_command` for details.
6191
        """
6192
        if not config_id:
6193
            raise RequiredArgument(
6194
                function=self.modify_config.__name__,
6195
                argument='config_id argument',
6196
            )
6197
6198
        if selection is None:
6199
            deprecation(
6200
                "Using modify_config to update the comment of a scan config is"
6201
                "deprecated. Please use modify_config_set_comment instead."
6202
            )
6203
            return self.modify_config_set_comment(
6204
                config_id, kwargs.get("comment")
6205
            )
6206
6207
        if selection not in (
6208
            "nvt_pref",
6209
            "scan_pref",
6210
            "family_selection",
6211
            "nvt_selection",
6212
        ):
6213
            raise InvalidArgument(
6214
                "selection must be one of nvt_pref, "
6215
                "scan_pref, family_selection or "
6216
                "nvt_selection"
6217
            )
6218
6219
        if selection == "nvt_pref":
6220
            deprecation(
6221
                "Using modify_config to update a nvt preference of a scan "
6222
                "config is deprecated. Please use "
6223
                "modify_config_set_nvt_preference instead."
6224
            )
6225
            return self.modify_config_set_nvt_preference(config_id, **kwargs)
6226
6227
        if selection == "scan_pref":
6228
            deprecation(
6229
                "Using modify_config to update a scanner preference of a "
6230
                "scan config is deprecated. Please use "
6231
                "modify_config_set_scanner_preference instead."
6232
            )
6233
            return self.modify_config_set_scanner_preference(
6234
                config_id, **kwargs
6235
            )
6236
6237
        if selection == "nvt_selection":
6238
            deprecation(
6239
                "Using modify_config to update a nvt selection of a "
6240
                "scan config is deprecated. Please use "
6241
                "modify_config_set_nvt_selection instead."
6242
            )
6243
            return self.modify_config_set_nvt_selection(config_id, **kwargs)
6244
6245
        deprecation(
6246
            "Using modify_config to update a family selection of a "
6247
            "scan config is deprecated. Please use "
6248
            "modify_config_set_family_selection instead."
6249
        )
6250
        return self.modify_config_set_family_selection(config_id, **kwargs)
6251
6252 View Code Duplication
    def modify_group(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
6253
        self,
6254
        group_id: str,
6255
        *,
6256
        comment: Optional[str] = None,
6257
        name: Optional[str] = None,
6258
        users: Optional[List[str]] = None,
6259
    ) -> Any:
6260
        """Modifies an existing group.
6261
6262
        Arguments:
6263
            group_id: UUID of group to modify.
6264
            comment: Comment on group.
6265
            name: Name of group.
6266
            users: List of user names to be in the group
6267
6268
        Returns:
6269
            The response. See :py:meth:`send_command` for details.
6270
        """
6271
        if not group_id:
6272
            raise RequiredArgument(
6273
                function=self.modify_group.__name__, argument='group_id'
6274
            )
6275
6276
        cmd = XmlCommand("modify_group")
6277
        cmd.set_attribute("group_id", group_id)
6278
6279
        if comment:
6280
            cmd.add_element("comment", comment)
6281
6282
        if name:
6283
            cmd.add_element("name", name)
6284
6285
        if users:
6286
            cmd.add_element("users", _to_comma_list(users))
6287
6288
        return self._send_xml_command(cmd)
6289
6290 View Code Duplication
    def modify_note(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
6291
        self,
6292
        note_id: str,
6293
        text: str,
6294
        *,
6295
        days_active: Optional[int] = None,
6296
        hosts: Optional[List[str]] = None,
6297
        port: Optional[int] = None,
6298
        result_id: Optional[str] = None,
6299
        severity: Optional[Severity] = None,
6300
        task_id: Optional[str] = None,
6301
        threat: Optional[SeverityLevel] = None,
6302
    ) -> Any:
6303
        """Modifies an existing note.
6304
6305
        Arguments:
6306
            note_id: UUID of note to modify.
6307
            text: The text of the note.
6308
            days_active: Days note will be active. -1 on always, 0 off.
6309
            hosts: A list of hosts addresses
6310
            port: Port to which note applies.
6311
            result_id: Result to which note applies.
6312
            severity: Severity to which note applies.
6313
            task_id: Task to which note applies.
6314
            threat: Threat level to which note applies. Will be converted to
6315
                severity.
6316
6317
        Returns:
6318
            The response. See :py:meth:`send_command` for details.
6319
        """
6320
        if not note_id:
6321
            raise RequiredArgument(
6322
                function=self.modify_note.__name__, argument='note_id'
6323
            )
6324
6325
        if not text:
6326
            raise RequiredArgument(
6327
                function=self.modify_note.__name__, argument='text'
6328
            )
6329
6330
        cmd = XmlCommand("modify_note")
6331
        cmd.set_attribute("note_id", note_id)
6332
        cmd.add_element("text", text)
6333
6334
        if days_active is not None:
6335
            cmd.add_element("active", str(days_active))
6336
6337
        if hosts:
6338
            cmd.add_element("hosts", _to_comma_list(hosts))
6339
6340
        if port:
6341
            cmd.add_element("port", str(port))
6342
6343
        if result_id:
6344
            cmd.add_element("result", attrs={"id": result_id})
6345
6346
        if severity:
6347
            cmd.add_element("severity", str(severity))
6348
6349
        if task_id:
6350
            cmd.add_element("task", attrs={"id": task_id})
6351
6352
        if threat is not None:
6353
6354
            if not isinstance(threat, SeverityLevel):
6355
                raise InvalidArgumentType(
6356
                    function=self.modify_note.__name__,
6357
                    argument='threat',
6358
                    arg_type=SeverityLevel.__name__,
6359
                )
6360
6361
            cmd.add_element("threat", threat.value)
6362
6363
        return self._send_xml_command(cmd)
6364
6365 View Code Duplication
    def modify_override(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
6366
        self,
6367
        override_id: str,
6368
        text: str,
6369
        *,
6370
        days_active: Optional[int] = None,
6371
        hosts: Optional[List[str]] = None,
6372
        port: Optional[int] = None,
6373
        result_id: Optional[str] = None,
6374
        severity: Optional[Severity] = None,
6375
        new_severity: Optional[Severity] = None,
6376
        task_id: Optional[str] = None,
6377
        threat: Optional[SeverityLevel] = None,
6378
        new_threat: Optional[SeverityLevel] = None,
6379
    ) -> Any:
6380
        """Modifies an existing override.
6381
6382
        Arguments:
6383
            override_id: UUID of override to modify.
6384
            text: The text of the override.
6385
            days_active: Days override will be active. -1 on always,
6386
                0 off.
6387
            hosts: A list of host addresses
6388
            port: Port to which override applies.
6389
            result_id: Result to which override applies.
6390
            severity: Severity to which override applies.
6391
            new_severity: New severity score for result.
6392
            task_id: Task to which override applies.
6393
            threat: Threat level to which override applies.
6394
                Will be converted to severity.
6395
            new_threat: New threat level for results. Will be converted to
6396
                new_severity.
6397
6398
        Returns:
6399
            The response. See :py:meth:`send_command` for details.
6400
        """
6401
        if not override_id:
6402
            raise RequiredArgument(
6403
                function=self.modify_override.__name__, argument='override_id'
6404
            )
6405
        if not text:
6406
            raise RequiredArgument(
6407
                function=self.modify_override.__name__, argument='text'
6408
            )
6409
6410
        cmd = XmlCommand("modify_override")
6411
        cmd.set_attribute("override_id", override_id)
6412
        cmd.add_element("text", text)
6413
6414
        if days_active is not None:
6415
            cmd.add_element("active", str(days_active))
6416
6417
        if hosts:
6418
            cmd.add_element("hosts", _to_comma_list(hosts))
6419
6420
        if port:
6421
            cmd.add_element("port", str(port))
6422
6423
        if result_id:
6424
            cmd.add_element("result", attrs={"id": result_id})
6425
6426
        if severity:
6427
            cmd.add_element("severity", str(severity))
6428
6429
        if new_severity:
6430
            cmd.add_element("new_severity", str(new_severity))
6431
6432
        if task_id:
6433
            cmd.add_element("task", attrs={"id": task_id})
6434
6435
        if threat is not None:
6436
            if not isinstance(threat, SeverityLevel):
6437
                raise InvalidArgumentType(
6438
                    function=self.modify_override.__name__,
6439
                    argument='threat',
6440
                    arg_type=SeverityLevel.__name__,
6441
                )
6442
            cmd.add_element("threat", threat.value)
6443
6444
        if new_threat is not None:
6445
            if not isinstance(new_threat, SeverityLevel):
6446
                raise InvalidArgumentType(
6447
                    function=self.modify_override.__name__,
6448
                    argument='new_threat',
6449
                    arg_type=SeverityLevel.__name__,
6450
                )
6451
6452
            cmd.add_element("new_threat", new_threat.value)
6453
6454
        return self._send_xml_command(cmd)
6455
6456
    def modify_port_list(
6457
        self,
6458
        port_list_id: str,
6459
        *,
6460
        comment: Optional[str] = None,
6461
        name: Optional[str] = None,
6462
    ) -> Any:
6463
        """Modifies an existing port list.
6464
6465
        Arguments:
6466
            port_list_id: UUID of port list to modify.
6467
            name: Name of port list.
6468
            comment: Comment on port list.
6469
6470
        Returns:
6471
            The response. See :py:meth:`send_command` for details.
6472
        """
6473
        if not port_list_id:
6474
            raise RequiredArgument(
6475
                function=self.modify_port_list.__name__, argument='port_list_id'
6476
            )
6477
        cmd = XmlCommand("modify_port_list")
6478
        cmd.set_attribute("port_list_id", port_list_id)
6479
6480
        if comment:
6481
            cmd.add_element("comment", comment)
6482
6483
        if name:
6484
            cmd.add_element("name", name)
6485
6486
        return self._send_xml_command(cmd)
6487
6488
    def modify_report_format(
6489
        self,
6490
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
6491
        *,
6492
        active: Optional[bool] = None,
6493
        name: Optional[str] = None,
6494
        summary: Optional[str] = None,
6495
        param_name: Optional[str] = None,
6496
        param_value: Optional[str] = None,
6497
    ) -> Any:
6498
        """Modifies an existing report format.
6499
6500
        Arguments:
6501
            report_format_id: UUID of report format to modify
6502
                              or ReportFormatType (enum)
6503
            active: Whether the report format is active.
6504
            name: The name of the report format.
6505
            summary: A summary of the report format.
6506
            param_name: The name of the param.
6507
            param_value: The value of the param.
6508
6509
        Returns:
6510
            The response. See :py:meth:`send_command` for details.
6511
        """
6512
        if not report_format_id:
6513
            raise RequiredArgument(
6514
                function=self.modify_report_format.__name__,
6515
                argument='report_format_id ',
6516
            )
6517
6518
        cmd = XmlCommand("modify_report_format")
6519
6520
        if isinstance(report_format_id, ReportFormatType):
6521
            report_format_id = report_format_id.value
6522
6523
        cmd.set_attribute("report_format_id", report_format_id)
6524
6525
        if active is not None:
6526
            cmd.add_element("active", _to_bool(active))
6527
6528
        if name:
6529
            cmd.add_element("name", name)
6530
6531
        if summary:
6532
            cmd.add_element("summary", summary)
6533
6534
        if param_name:
6535
            _xmlparam = cmd.add_element("param")
6536
            _xmlparam.add_element("name", param_name)
6537
6538
            if param_value is not None:
6539
                _xmlparam.add_element("value", param_value)
6540
6541
        return self._send_xml_command(cmd)
6542
6543 View Code Duplication
    def modify_role(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
6544
        self,
6545
        role_id: str,
6546
        *,
6547
        comment: Optional[str] = None,
6548
        name: Optional[str] = None,
6549
        users: Optional[List[str]] = None,
6550
    ) -> Any:
6551
        """Modifies an existing role.
6552
6553
        Arguments:
6554
            role_id: UUID of role to modify.
6555
            comment: Name of role.
6556
            name: Comment on role.
6557
            users: List of user names.
6558
6559
        Returns:
6560
            The response. See :py:meth:`send_command` for details.
6561
        """
6562
        if not role_id:
6563
            raise RequiredArgument(
6564
                function=self.modify_role.__name__, argument='role_id argument'
6565
            )
6566
6567
        cmd = XmlCommand("modify_role")
6568
        cmd.set_attribute("role_id", role_id)
6569
6570
        if comment:
6571
            cmd.add_element("comment", comment)
6572
6573
        if name:
6574
            cmd.add_element("name", name)
6575
6576
        if users:
6577
            cmd.add_element("users", _to_comma_list(users))
6578
6579
        return self._send_xml_command(cmd)
6580
6581
    def modify_scanner(
6582
        self,
6583
        scanner_id: str,
6584
        *,
6585
        scanner_type: Optional[ScannerType] = None,
6586
        host: Optional[str] = None,
6587
        port: Optional[int] = None,
6588
        comment: Optional[str] = None,
6589
        name: Optional[str] = None,
6590
        ca_pub: Optional[str] = None,
6591
        credential_id: Optional[str] = None,
6592
    ) -> Any:
6593
        """Modifies an existing scanner.
6594
6595
        Arguments:
6596
            scanner_id: UUID of scanner to modify.
6597
            scanner_type: New type of the Scanner.
6598
            host: Host of the scanner.
6599
            port: Port of the scanner.
6600
            comment: Comment on scanner.
6601
            name: Name of scanner.
6602
            ca_pub: Certificate of CA to verify scanner's certificate.
6603
            credential_id: UUID of the client certificate credential for the
6604
                Scanner.
6605
6606
        Returns:
6607
            The response. See :py:meth:`send_command` for details.
6608
        """
6609
        if not scanner_id:
6610
            raise RequiredArgument(
6611
                function=self.modify_scanner.__name__,
6612
                argument='scanner_id argument',
6613
            )
6614
6615
        cmd = XmlCommand("modify_scanner")
6616
        cmd.set_attribute("scanner_id", scanner_id)
6617
6618
        if scanner_type is not None:
6619
            if not isinstance(scanner_type, self.types.ScannerType):
6620
                raise InvalidArgumentType(
6621
                    function=self.modify_scanner.__name__,
6622
                    argument='scanner_type',
6623
                    arg_type=self.types.ScannerType.__name__,
6624
                )
6625
6626
            cmd.add_element("type", scanner_type.value)
6627
6628
        if host:
6629
            cmd.add_element("host", host)
6630
6631
        if port:
6632
            cmd.add_element("port", str(port))
6633
6634
        if comment:
6635
            cmd.add_element("comment", comment)
6636
6637
        if name:
6638
            cmd.add_element("name", name)
6639
6640
        if ca_pub:
6641
            cmd.add_element("ca_pub", ca_pub)
6642
6643
        if credential_id:
6644
            cmd.add_element("credential", attrs={"id": str(credential_id)})
6645
6646
        return self._send_xml_command(cmd)
6647
6648
    def modify_setting(
6649
        self,
6650
        setting_id: Optional[str] = None,
6651
        name: Optional[str] = None,
6652
        value: Optional[str] = None,
6653
    ) -> Any:
6654
        """Modifies an existing setting.
6655
6656
        Arguments:
6657
            setting_id: UUID of the setting to be changed.
6658
            name: The name of the setting. Either setting_id or name must be
6659
                passed.
6660
            value: The value of the setting.
6661
6662
        Returns:
6663
            The response. See :py:meth:`send_command` for details.
6664
        """
6665
        if not setting_id and not name:
6666
            raise RequiredArgument(
6667
                function=self.modify_setting.__name__,
6668
                argument='setting_id or name argument',
6669
            )
6670
6671
        if value is None:
6672
            raise RequiredArgument(
6673
                function=self.modify_setting.__name__, argument='value argument'
6674
            )
6675
6676
        cmd = XmlCommand("modify_setting")
6677
6678
        if setting_id:
6679
            cmd.set_attribute("setting_id", setting_id)
6680
        else:
6681
            cmd.add_element("name", name)
6682
6683
        cmd.add_element("value", _to_base64(value))
6684
6685
        return self._send_xml_command(cmd)
6686
6687
    def modify_target(
6688
        self,
6689
        target_id: str,
6690
        *,
6691
        name: Optional[str] = None,
6692
        comment: Optional[str] = None,
6693
        hosts: Optional[List[str]] = None,
6694
        exclude_hosts: Optional[List[str]] = None,
6695
        ssh_credential_id: Optional[str] = None,
6696
        ssh_credential_port: Optional[bool] = None,
6697
        smb_credential_id: Optional[str] = None,
6698
        esxi_credential_id: Optional[str] = None,
6699
        snmp_credential_id: Optional[str] = None,
6700
        alive_test: Optional[AliveTest] = None,
6701
        reverse_lookup_only: Optional[bool] = None,
6702
        reverse_lookup_unify: Optional[bool] = None,
6703
        port_list_id: Optional[str] = None,
6704
    ) -> Any:
6705
        """Modifies an existing target.
6706
6707
        Arguments:
6708
            target_id: ID of target to modify.
6709
            comment: Comment on target.
6710
            name: Name of target.
6711
            hosts: List of target hosts.
6712
            exclude_hosts: A list of hosts to exclude.
6713
            ssh_credential_id: UUID of SSH credential to use on target.
6714
            ssh_credential_port: The port to use for ssh credential
6715
            smb_credential_id: UUID of SMB credential to use on target.
6716
            esxi_credential_id: UUID of ESXi credential to use on target.
6717
            snmp_credential_id: UUID of SNMP credential to use on target.
6718
            port_list_id: UUID of port list describing ports to scan.
6719
            alive_test: Which alive tests to use.
6720
            reverse_lookup_only: Whether to scan only hosts that have names.
6721
            reverse_lookup_unify: Whether to scan only one IP when multiple IPs
6722
                have the same name.
6723
6724
        Returns:
6725
            The response. See :py:meth:`send_command` for details.
6726
        """
6727
        if not target_id:
6728
            raise RequiredArgument(
6729
                function=self.modify_target.__name__, argument='target_id'
6730
            )
6731
6732
        cmd = XmlCommand("modify_target")
6733
        cmd.set_attribute("target_id", target_id)
6734
6735
        if comment:
6736
            cmd.add_element("comment", comment)
6737
6738
        if name:
6739
            cmd.add_element("name", name)
6740
6741
        if hosts:
6742
            cmd.add_element("hosts", _to_comma_list(hosts))
6743
            if exclude_hosts is None:
6744
                exclude_hosts = ['']
6745
6746
        if exclude_hosts:
6747
            cmd.add_element("exclude_hosts", _to_comma_list(exclude_hosts))
6748
6749
        if alive_test:
6750
            if not isinstance(alive_test, AliveTest):
6751
                raise InvalidArgumentType(
6752
                    function=self.modify_target.__name__,
6753
                    argument='alive_test',
6754
                    arg_type=AliveTest.__name__,
6755
                )
6756
            cmd.add_element("alive_tests", alive_test.value)
6757
6758
        if ssh_credential_id:
6759
            _xmlssh = cmd.add_element(
6760
                "ssh_credential", attrs={"id": ssh_credential_id}
6761
            )
6762
6763
            if ssh_credential_port:
6764
                _xmlssh.add_element("port", str(ssh_credential_port))
6765
6766
        if smb_credential_id:
6767
            cmd.add_element("smb_credential", attrs={"id": smb_credential_id})
6768
6769
        if esxi_credential_id:
6770
            cmd.add_element("esxi_credential", attrs={"id": esxi_credential_id})
6771
6772
        if snmp_credential_id:
6773
            cmd.add_element("snmp_credential", attrs={"id": snmp_credential_id})
6774
6775
        if reverse_lookup_only is not None:
6776
            cmd.add_element(
6777
                "reverse_lookup_only", _to_bool(reverse_lookup_only)
6778
            )
6779
6780
        if reverse_lookup_unify is not None:
6781
            cmd.add_element(
6782
                "reverse_lookup_unify", _to_bool(reverse_lookup_unify)
6783
            )
6784
6785
        if port_list_id:
6786
            cmd.add_element("port_list", attrs={"id": port_list_id})
6787
6788
        return self._send_xml_command(cmd)
6789
6790
    def modify_task(
6791
        self,
6792
        task_id: str,
6793
        *,
6794
        name: Optional[str] = None,
6795
        config_id: Optional[str] = None,
6796
        target_id: Optional[str] = None,
6797
        scanner_id: Optional[str] = None,
6798
        alterable: Optional[bool] = None,
6799
        hosts_ordering: Optional[HostsOrdering] = None,
6800
        schedule_id: Optional[str] = None,
6801
        schedule_periods: Optional[int] = None,
6802
        comment: Optional[str] = None,
6803
        alert_ids: Optional[List[str]] = None,
6804
        observers: Optional[List[str]] = None,
6805
        preferences: Optional[dict] = None,
6806
    ) -> Any:
6807
        """Modifies an existing task.
6808
6809
        Arguments:
6810
            task_id: UUID of task to modify.
6811
            name: The name of the task.
6812
            config_id: UUID of scan config to use by the task
6813
            target_id: UUID of target to be scanned
6814
            scanner_id: UUID of scanner to use for scanning the target
6815
            comment: The comment on the task.
6816
            alert_ids: List of UUIDs for alerts to be applied to the task
6817
            hosts_ordering: The order hosts are scanned in
6818
            schedule_id: UUID of a schedule when the task should be run.
6819
            schedule_periods: A limit to the number of times the task will be
6820
                scheduled, or 0 for no limit.
6821
            observers: List of names or ids of users which should be allowed to
6822
                observe this task
6823
            preferences: Name/Value pairs of scanner preferences.
6824
6825
        Returns:
6826
            The response. See :py:meth:`send_command` for details.
6827
        """
6828
        if not task_id:
6829
            raise RequiredArgument(
6830
                function=self.modify_task.__name__, argument='task_id argument'
6831
            )
6832
6833
        cmd = XmlCommand("modify_task")
6834
        cmd.set_attribute("task_id", task_id)
6835
6836
        if name:
6837
            cmd.add_element("name", name)
6838
6839
        if comment:
6840
            cmd.add_element("comment", comment)
6841
6842
        if config_id:
6843
            cmd.add_element("config", attrs={"id": config_id})
6844
6845
        if target_id:
6846
            cmd.add_element("target", attrs={"id": target_id})
6847
6848
        if alterable is not None:
6849
            cmd.add_element("alterable", _to_bool(alterable))
6850
6851
        if hosts_ordering:
6852
            if not isinstance(hosts_ordering, HostsOrdering):
6853
                raise InvalidArgumentType(
6854
                    function=self.modify_task.__name__,
6855
                    argument='hosts_ordering',
6856
                    arg_type=HostsOrdering.__name__,
6857
                )
6858
            cmd.add_element("hosts_ordering", hosts_ordering.value)
6859
6860
        if scanner_id:
6861
            cmd.add_element("scanner", attrs={"id": scanner_id})
6862
6863
        if schedule_id:
6864
            cmd.add_element("schedule", attrs={"id": schedule_id})
6865
6866 View Code Duplication
        if schedule_periods is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
6867
            if (
6868
                not isinstance(schedule_periods, numbers.Integral)
6869
                or schedule_periods < 0
6870
            ):
6871
                raise InvalidArgument(
6872
                    "schedule_periods must be an integer greater or equal "
6873
                    "than 0"
6874
                )
6875
            cmd.add_element("schedule_periods", str(schedule_periods))
6876
6877
        if alert_ids is not None:
6878
            if not _is_list_like(alert_ids):
6879
                raise InvalidArgumentType(
6880
                    function=self.modify_task.__name__,
6881
                    argument='alert_ids',
6882
                    arg_type='list',
6883
                )
6884
6885
            if len(alert_ids) == 0:
6886
                cmd.add_element("alert", attrs={"id": "0"})
6887
            else:
6888
                for alert in alert_ids:
6889
                    cmd.add_element("alert", attrs={"id": str(alert)})
6890
6891
        if observers is not None:
6892
            if not _is_list_like(observers):
6893
                raise InvalidArgumentType(
6894
                    function=self.modify_task.__name__,
6895
                    argument='observers',
6896
                    arg_type='list',
6897
                )
6898
6899
            cmd.add_element("observers", _to_comma_list(observers))
6900
6901 View Code Duplication
        if preferences is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
6902
            if not isinstance(preferences, collections.abc.Mapping):
6903
                raise InvalidArgumentType(
6904
                    function=self.modify_task.__name__,
6905
                    argument='preferences',
6906
                    arg_type=collections.abc.Mapping.__name__,
6907
                )
6908
6909
            _xmlprefs = cmd.add_element("preferences")
6910
            for pref_name, pref_value in preferences.items():
6911
                _xmlpref = _xmlprefs.add_element("preference")
6912
                _xmlpref.add_element("scanner_name", pref_name)
6913
                _xmlpref.add_element("value", str(pref_value))
6914
6915
        return self._send_xml_command(cmd)
6916
6917 View Code Duplication
    def modify_user(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
6918
        self,
6919
        user_id: str = None,
6920
        name: str = None,
6921
        *,
6922
        new_name: Optional[str] = None,
6923
        comment: Optional[str] = None,
6924
        password: Optional[str] = None,
6925
        auth_source: Optional[UserAuthType] = None,
6926
        role_ids: Optional[List[str]] = None,
6927
        hosts: Optional[List[str]] = None,
6928
        hosts_allow: Optional[bool] = False,
6929
        ifaces: Optional[List[str]] = None,
6930
        ifaces_allow: Optional[bool] = False,
6931
        group_ids: Optional[List[str]] = None,
6932
    ) -> Any:
6933
        """Modifies an existing user. Most of the fields need to be supplied
6934
        for changing a single field even if no change is wanted for those.
6935
        Else empty values are inserted for the missing fields instead.
6936
6937
        Arguments:
6938
            user_id: UUID of the user to be modified. Overrides name element
6939
                argument.
6940
            name: The name of the user to be modified. Either user_id or name
6941
                must be passed.
6942
            new_name: The new name for the user.
6943
            comment: Comment on the user.
6944
            password: The password for the user.
6945
            auth_source: Source allowed for authentication for this user.
6946
            roles_id: List of roles UUIDs for the user.
6947
            hosts: User access rules: List of hosts.
6948
            hosts_allow: Defines how the hosts list is to be interpreted.
6949
                If False (default) the list is treated as a deny list.
6950
                All hosts are allowed by default except those provided by
6951
                the hosts parameter. If True the list is treated as a
6952
                allow list. All hosts are denied by default except those
6953
                provided by the hosts parameter.
6954
            ifaces: User access rules: List of ifaces.
6955
            ifaces_allow: Defines how the ifaces list is to be interpreted.
6956
                If False (default) the list is treated as a deny list.
6957
                All ifaces are allowed by default except those provided by
6958
                the ifaces parameter. If True the list is treated as a
6959
                allow list. All ifaces are denied by default except those
6960
                provided by the ifaces parameter.
6961
            group_ids: List of group UUIDs for the user.
6962
6963
        Returns:
6964
            The response. See :py:meth:`send_command` for details.
6965
        """
6966
        if not user_id and not name:
6967
            raise RequiredArgument(
6968
                function=self.modify_user.__name__, argument='user_id or name'
6969
            )
6970
6971
        cmd = XmlCommand("modify_user")
6972
6973
        if user_id:
6974
            cmd.set_attribute("user_id", user_id)
6975
        else:
6976
            cmd.add_element("name", name)
6977
6978
        if new_name:
6979
            cmd.add_element("new_name", new_name)
6980
6981
        if role_ids:
6982
            for role in role_ids:
6983
                cmd.add_element("role", attrs={"id": role})
6984
6985
        if hosts:
6986
            cmd.add_element(
6987
                "hosts",
6988
                _to_comma_list(hosts),
6989
                attrs={"allow": _to_bool(hosts_allow)},
6990
            )
6991
6992
        if ifaces:
6993
            cmd.add_element(
6994
                "ifaces",
6995
                _to_comma_list(ifaces),
6996
                attrs={"allow": _to_bool(ifaces_allow)},
6997
            )
6998
6999
        if comment:
7000
            cmd.add_element("comment", comment)
7001
7002
        if password:
7003
            cmd.add_element("password", password)
7004
7005
        if auth_source:
7006
            _xmlauthsrc = cmd.add_element("sources")
7007
            _xmlauthsrc.add_element("source", auth_source.value)
7008
7009
        if group_ids:
7010
            _xmlgroups = cmd.add_element("groups")
7011
            for group_id in group_ids:
7012
                _xmlgroups.add_element("group", attrs={"id": group_id})
7013
7014
        return self._send_xml_command(cmd)
7015
7016
    def move_task(self, task_id: str, *, slave_id: Optional[str] = None) -> Any:
7017
        """Move an existing task to another GMP slave scanner or the master
7018
7019
        Arguments:
7020
            task_id: UUID of the task to be moved
7021
            slave_id: UUID of slave to reassign the task to, empty for master.
7022
7023
        Returns:
7024
            The response. See :py:meth:`send_command` for details.
7025
        """
7026
        if not task_id:
7027
            raise RequiredArgument(
7028
                function=self.move_task.__name__, argument='task_id'
7029
            )
7030
7031
        cmd = XmlCommand("move_task")
7032
        cmd.set_attribute("task_id", task_id)
7033
7034
        if slave_id is not None:
7035
            cmd.set_attribute("slave_id", slave_id)
7036
7037
        return self._send_xml_command(cmd)
7038
7039
    def restore(self, entity_id: str) -> Any:
7040
        """Restore an entity from the trashcan
7041
7042
        Arguments:
7043
            entity_id: ID of the entity to be restored from the trashcan
7044
7045
        Returns:
7046
            The response. See :py:meth:`send_command` for details.
7047
        """
7048
        if not entity_id:
7049
            raise RequiredArgument(
7050
                function=self.restore.__name__, argument='entity_id'
7051
            )
7052
7053
        cmd = XmlCommand("restore")
7054
        cmd.set_attribute("id", entity_id)
7055
7056
        return self._send_xml_command(cmd)
7057
7058
    def resume_task(self, task_id: str) -> Any:
7059
        """Resume an existing stopped task
7060
7061
        Arguments:
7062
            task_id: UUID of the task to be resumed
7063
7064
        Returns:
7065
            The response. See :py:meth:`send_command` for details.
7066
        """
7067
        if not task_id:
7068
            raise RequiredArgument(
7069
                function=self.resume_task.__name__, argument='task_id'
7070
            )
7071
7072
        cmd = XmlCommand("resume_task")
7073
        cmd.set_attribute("task_id", task_id)
7074
7075
        return self._send_xml_command(cmd)
7076
7077
    def start_task(self, task_id: str) -> Any:
7078
        """Start an existing task
7079
7080
        Arguments:
7081
            task_id: UUID of the task to be started
7082
7083
        Returns:
7084
            The response. See :py:meth:`send_command` for details.
7085
        """
7086
        if not task_id:
7087
            raise RequiredArgument(
7088
                function=self.start_task.__name__, argument='task_id'
7089
            )
7090
7091
        cmd = XmlCommand("start_task")
7092
        cmd.set_attribute("task_id", task_id)
7093
7094
        return self._send_xml_command(cmd)
7095
7096
    def stop_task(self, task_id: str) -> Any:
7097
        """Stop an existing running task
7098
7099
        Arguments:
7100
            task_id: UUID of the task to be stopped
7101
7102
        Returns:
7103
            The response. See :py:meth:`send_command` for details.
7104
        """
7105
        if not task_id:
7106
            raise RequiredArgument(
7107
                function=self.stop_task.__name__, argument='task_id'
7108
            )
7109
7110
        cmd = XmlCommand("stop_task")
7111
        cmd.set_attribute("task_id", task_id)
7112
7113
        return self._send_xml_command(cmd)
7114
7115
    def sync_cert(self) -> Any:
7116
        """Request a synchronization with the CERT feed service
7117
7118
        Returns:
7119
            The response. See :py:meth:`send_command` for details.
7120
        """
7121
        return self._send_xml_command(XmlCommand("sync_cert"))
7122
7123
    def sync_config(self) -> Any:
7124
        """Request an OSP config synchronization with scanner
7125
7126
        Returns:
7127
            The response. See :py:meth:`send_command` for details.
7128
        """
7129
        return self._send_xml_command(XmlCommand("sync_config"))
7130
7131
    def sync_feed(self) -> Any:
7132
        """Request a synchronization with the NVT feed service
7133
7134
        Returns:
7135
            The response. See :py:meth:`send_command` for details.
7136
        """
7137
        return self._send_xml_command(XmlCommand("sync_feed"))
7138
7139
    def sync_scap(self) -> Any:
7140
        """Request a synchronization with the SCAP feed service
7141
7142
        Returns:
7143
            The response. See :py:meth:`send_command` for details.
7144
        """
7145
        return self._send_xml_command(XmlCommand("sync_scap"))
7146
7147
    def test_alert(self, alert_id: str) -> Any:
7148
        """Run an alert
7149
7150
        Invoke a test run of an alert
7151
7152
        Arguments:
7153
            alert_id: UUID of the alert to be tested
7154
7155
        Returns:
7156
            The response. See :py:meth:`send_command` for details.
7157
        """
7158
        if not alert_id:
7159
            raise InvalidArgument("test_alert requires an alert_id argument")
7160
7161
        cmd = XmlCommand("test_alert")
7162
        cmd.set_attribute("alert_id", alert_id)
7163
7164
        return self._send_xml_command(cmd)
7165
7166
    def trigger_alert(
7167
        self,
7168
        alert_id: str,
7169
        report_id: str,
7170
        *,
7171
        filter: Optional[str] = None,
7172
        filter_id: Optional[str] = None,
7173
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
7174
        delta_report_id: Optional[str] = None,
7175
    ) -> Any:
7176
        """Run an alert by ignoring its event and conditions
7177
7178
        The alert is triggered to run immediately with the provided filtered
7179
        report by ignoring the even and condition settings.
7180
7181
        Arguments:
7182
            alert_id: UUID of the alert to be run
7183
            report_id: UUID of the report to be provided to the alert
7184
            filter: Filter term to use to filter results in the report
7185
            filter_id: UUID of filter to use to filter results in the report
7186
            report_format_id: UUID of report format to use
7187
                              or ReportFormatType (enum)
7188
            delta_report_id: UUID of an existing report to compare report to.
7189
7190
        Returns:
7191
            The response. See :py:meth:`send_command` for details.
7192
        """
7193
        if not alert_id:
7194
            raise RequiredArgument(
7195
                function=self.trigger_alert.__name__,
7196
                argument='alert_id argument',
7197
            )
7198
7199
        if not report_id:
7200
            raise RequiredArgument(
7201
                function=self.trigger_alert.__name__,
7202
                argument='report_id argument',
7203
            )
7204
7205
        cmd = XmlCommand("get_reports")
7206
        cmd.set_attribute("report_id", report_id)
7207
        cmd.set_attribute("alert_id", alert_id)
7208
7209
        if filter:
7210
            cmd.set_attribute("filter", filter)
7211
7212
        if filter_id:
7213
            cmd.set_attribute("filt_id", filter_id)
7214
7215
        if report_format_id:
7216
            if isinstance(report_format_id, ReportFormatType):
7217
                report_format_id = report_format_id.value
7218
7219
            cmd.set_attribute("format_id", report_format_id)
7220
7221
        if delta_report_id:
7222
            cmd.set_attribute("delta_report_id", delta_report_id)
7223
7224
        return self._send_xml_command(cmd)
7225
7226 View Code Duplication
    def verify_report_format(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
7227
        self, report_format_id: Union[str, ReportFormatType]
7228
    ) -> Any:
7229
        """Verify an existing report format
7230
7231
        Verifies the trust level of an existing report format. It will be
7232
        checked whether the signature of the report format currently matches the
7233
        report format. This includes the script and files used to generate
7234
        reports of this format. It is *not* verified if the report format works
7235
        as expected by the user.
7236
7237
        Arguments:
7238
            report_format_id: UUID of the report format to be verified
7239
                              or ReportFormatType (enum)
7240
7241
        Returns:
7242
            The response. See :py:meth:`send_command` for details.
7243
        """
7244
        if not report_format_id:
7245
            raise RequiredArgument(
7246
                function=self.verify_report_format.__name__,
7247
                argument='report_format_id',
7248
            )
7249
7250
        cmd = XmlCommand("verify_report_format")
7251
7252
        if isinstance(report_format_id, ReportFormatType):
7253
            report_format_id = report_format_id.value
7254
7255
        cmd.set_attribute("report_format_id", report_format_id)
7256
7257
        return self._send_xml_command(cmd)
7258
7259
    def verify_scanner(self, scanner_id: str) -> Any:
7260
        """Verify an existing scanner
7261
7262
        Verifies if it is possible to connect to an existing scanner. It is
7263
        *not* verified if the scanner works as expected by the user.
7264
7265
        Arguments:
7266
            scanner_id: UUID of the scanner to be verified
7267
7268
        Returns:
7269
            The response. See :py:meth:`send_command` for details.
7270
        """
7271
        if not scanner_id:
7272
            raise RequiredArgument(
7273
                function=self.verify_scanner.__name__, argument='scanner_id'
7274
            )
7275
7276
        cmd = XmlCommand("verify_scanner")
7277
        cmd.set_attribute("scanner_id", scanner_id)
7278
7279
        return self._send_xml_command(cmd)
7280