Completed
Push — master ( 52721c...da306e )
by Jaspar
18s queued 14s
created

GmpV208Mixin.modify_auth()   A

Complexity

Conditions 4

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 15
nop 3
dl 0
loc 28
rs 9.65
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 collections
29
import logging
30
from numbers import Integral
31
32
from typing import Any, List, Optional, Callable, Union, Tuple
33
from lxml import etree
34
35
from gvm.connections import GvmConnection
36
from gvm.errors import InvalidArgument, InvalidArgumentType, RequiredArgument
37
from gvm.protocols.base import GvmProtocol
38
from gvm.protocols.gmpv208.entities.report_formats import (
39
    ReportFormatType,
40
)
41
from gvm.utils import (
42
    deprecation,
43
    check_command_status,
44
    is_list_like,
45
    to_base64,
46
    to_bool,
47
    to_comma_list,
48
    add_filter,
49
)
50
from gvm.xml import XmlCommand
51
52
from . import types
53
from .types import *  # pylint: disable=unused-wildcard-import, wildcard-import
54
from .types import _UsageType as UsageType
55
56
_EMPTY_POLICY_ID = '085569ce-73ed-11df-83c3-002264764cea'
57
58
PROTOCOL_VERSION = (20, 8)
59
60
61
logger = logging.getLogger(__name__)
62
63
# put this into the Alert Entity
64
def _check_event(
65
    event: AlertEvent, condition: AlertCondition, method: AlertMethod
66
):
67
    if event == AlertEvent.TASK_RUN_STATUS_CHANGED:
68
        if not condition:
69
            raise RequiredArgument(
70
                "condition is required for event {}".format(event.name)
71
            )
72
73
        if not method:
74
            raise RequiredArgument(
75
                "method is required for event {}".format(event.name)
76
            )
77
78
        if condition not in (
79
            AlertCondition.ALWAYS,
80
            AlertCondition.FILTER_COUNT_CHANGED,
81
            AlertCondition.FILTER_COUNT_AT_LEAST,
82
            AlertCondition.SEVERITY_AT_LEAST,
83
            AlertCondition.SEVERITY_CHANGED,
84
        ):
85
            raise InvalidArgument(
86
                "Invalid condition {} for event {}".format(
87
                    condition.name, event.name
88
                )
89
            )
90
    elif event in (
91
        AlertEvent.NEW_SECINFO_ARRIVED,
92
        AlertEvent.UPDATED_SECINFO_ARRIVED,
93
    ):
94
        if not condition:
95
            raise RequiredArgument(
96
                "condition is required for event {}".format(event.name)
97
            )
98
99
        if not method:
100
            raise RequiredArgument(
101
                "method is required for event {}".format(event.name)
102
            )
103
104
        if condition != AlertCondition.ALWAYS:
105
            raise InvalidArgument(
106
                "Invalid condition {} for event {}".format(
107
                    condition.name, event.name
108
                )
109
            )
110
        if method not in (
111
            AlertMethod.SCP,
112
            AlertMethod.SEND,
113
            AlertMethod.SMB,
114
            AlertMethod.SNMP,
115
            AlertMethod.SYSLOG,
116
            AlertMethod.EMAIL,
117
        ):
118
            raise InvalidArgument(
119
                "Invalid method {} for event {}".format(method.name, event.name)
120
            )
121
    elif event in (
122
        AlertEvent.TICKET_RECEIVED,
123
        AlertEvent.OWNED_TICKET_CHANGED,
124
        AlertEvent.ASSIGNED_TICKET_CHANGED,
125
    ):
126
        if not condition:
127
            raise RequiredArgument(
128
                "condition is required for event {}".format(event.name)
129
            )
130
131
        if not method:
132
            raise RequiredArgument(
133
                "method is required for event {}".format(event.name)
134
            )
135
        if condition != AlertCondition.ALWAYS:
136
            raise InvalidArgument(
137
                "Invalid condition {} for event {}".format(
138
                    condition.name, event.name
139
                )
140
            )
141
        if method not in (
142
            AlertMethod.EMAIL,
143
            AlertMethod.START_TASK,
144
            AlertMethod.SYSLOG,
145
        ):
146
            raise InvalidArgument(
147
                "Invalid method {} for event {}".format(method.name, event.name)
148
            )
149
    elif event is not None:
150
        raise InvalidArgument('Invalid event "{}"'.format(event.name))
151
152
153
class GmpV208Mixin(GvmProtocol):
154
    """Python interface for Greenbone Management Protocol
155
156
    This class implements the `Greenbone Management Protocol version 20.08`_
157
158
    Arguments:
159
        connection: Connection to use to talk with the gvmd daemon. See
160
            :mod:`gvm.connections` for possible connection types.
161
        transform: Optional transform `callable`_ to convert response data.
162
            After each request the callable gets passed the plain response data
163
            which can be used to check the data and/or conversion into different
164
            representations like a xml dom.
165
166
            See :mod:`gvm.transforms` for existing transforms.
167
168
    .. _Greenbone Management Protocol version 20.08:
169
        https://docs.greenbone.net/API/GMP/gmp-20.08.html
170
    .. _callable:
171
        https://docs.python.org/3/library/functions.html#callable
172
    """
173
174
    types = types
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable types does not seem to be defined.
Loading history...
175
176
    def __init__(
177
        self,
178
        connection: GvmConnection,
179
        *,
180
        transform: Optional[Callable[[str], Any]] = None,
181
    ):
182
        super().__init__(connection, transform=transform)
183
184
        # Is authenticated on gvmd
185
        self._authenticated = False
186
187
    def is_authenticated(self) -> bool:
188
        """Checks if the user is authenticated
189
190
        If the user is authenticated privileged GMP commands like get_tasks
191
        may be send to gvmd.
192
193
        Returns:
194
            bool: True if an authenticated connection to gvmd has been
195
            established.
196
        """
197
        return self._authenticated
198
199
    def authenticate(self, username: str, password: str) -> Any:
200
        """Authenticate to gvmd.
201
202
        The generated authenticate command will be send to server.
203
        Afterwards the response is read, transformed and returned.
204
205
        Arguments:
206
            username: Username
207
            password: Password
208
209
        Returns:
210
            Transformed response from server.
211
        """
212
        cmd = XmlCommand("authenticate")
213
214
        if not username:
215
            raise RequiredArgument(
216
                function=self.authenticate.__name__, argument='username'
217
            )
218
219
        if not password:
220
            raise RequiredArgument(
221
                function=self.authenticate.__name__, argument='password'
222
            )
223
224
        credentials = cmd.add_element("credentials")
225
        credentials.add_element("username", username)
226
        credentials.add_element("password", password)
227
228
        self._send(cmd.to_string())
229
        response = self._read()
230
231
        if check_command_status(response):
232
            self._authenticated = True
233
234
        return self._transform(response)
235
236
    def create_alert(
237
        self,
238
        name: str,
239
        condition: AlertCondition,
240
        event: AlertEvent,
241
        method: AlertMethod,
242
        *,
243
        method_data: Optional[dict] = None,
244
        event_data: Optional[dict] = None,
245
        condition_data: Optional[dict] = None,
246
        filter_id: Optional[int] = None,
247
        comment: Optional[str] = None,
248
    ) -> Any:
249
        """Create a new alert
250
251
        Arguments:
252
            name: Name of the new Alert
253
            condition: The condition that must be satisfied for the alert
254
                to occur; if the event is either 'Updated SecInfo arrived' or
255
                'New SecInfo arrived', condition must be 'Always'. Otherwise,
256
                condition can also be on of 'Severity at least', 'Filter count
257
                changed' or 'Filter count at least'.
258
            event: The event that must happen for the alert to occur, one
259
                of 'Task run status changed', 'Updated SecInfo arrived' or 'New
260
                SecInfo arrived'
261
            method: The method by which the user is alerted, one of 'SCP',
262
                'Send', 'SMB', 'SNMP', 'Syslog' or 'Email'; if the event is
263
                neither 'Updated SecInfo arrived' nor 'New SecInfo arrived',
264
                method can also be one of 'Start Task', 'HTTP Get', 'Sourcefire
265
                Connector' or 'verinice Connector'.
266
            condition_data: Data that defines the condition
267
            event_data: Data that defines the event
268
            method_data: Data that defines the method
269
            filter_id: Filter to apply when executing alert
270
            comment: Comment for the alert
271
272
        Returns:
273
            The response. See :py:meth:`send_command` for details.
274
        """
275
        if not name:
276
            raise RequiredArgument(
277
                function=self.create_alert.__name__, argument='name'
278
            )
279
280
        if not condition:
281
            raise RequiredArgument(
282
                function=self.create_alert.__name__, argument='condition'
283
            )
284
285
        if not event:
286
            raise RequiredArgument(
287
                function=self.create_alert.__name__, argument='event'
288
            )
289
290
        if not method:
291
            raise RequiredArgument(
292
                function=self.create_alert.__name__, argument='method'
293
            )
294
295
        if not isinstance(condition, AlertCondition):
296
            raise InvalidArgumentType(
297
                function=self.create_alert.__name__,
298
                argument='condition',
299
                arg_type=AlertCondition.__name__,
300
            )
301
302
        if not isinstance(event, AlertEvent):
303
            raise InvalidArgumentType(
304
                function=self.create_alert.__name__,
305
                argument='even',
306
                arg_type=AlertEvent.__name__,
307
            )
308
309
        if not isinstance(method, AlertMethod):
310
            raise InvalidArgumentType(
311
                function=self.create_alert.__name__,
312
                argument='method',
313
                arg_type=AlertMethod.__name__,
314
            )
315
316
        _check_event(event, condition, method)
317
318
        cmd = XmlCommand("create_alert")
319
        cmd.add_element("name", name)
320
321
        conditions = cmd.add_element("condition", condition.value)
322
323
        if condition_data is not None:
324
            for key, value in condition_data.items():
325
                _data = conditions.add_element("data", value)
326
                _data.add_element("name", key)
327
328
        events = cmd.add_element("event", event.value)
329
330
        if event_data is not None:
331
            for key, value in event_data.items():
332
                _data = events.add_element("data", value)
333
                _data.add_element("name", key)
334
335
        methods = cmd.add_element("method", method.value)
336
337
        if method_data is not None:
338
            for key, value in method_data.items():
339
                _data = methods.add_element("data", value)
340
                _data.add_element("name", key)
341
342
        if filter_id:
343
            cmd.add_element("filter", attrs={"id": filter_id})
344
345
        if comment:
346
            cmd.add_element("comment", comment)
347
348
        return self._send_xml_command(cmd)
349
350
    def create_audit(
351
        self,
352
        name: str,
353
        policy_id: str,
354
        target_id: str,
355
        scanner_id: str,
356
        *,
357
        alterable: Optional[bool] = None,
358
        hosts_ordering: Optional[HostsOrdering] = None,
359
        schedule_id: Optional[str] = None,
360
        alert_ids: Optional[List[str]] = None,
361
        comment: Optional[str] = None,
362
        schedule_periods: Optional[int] = None,
363
        observers: Optional[List[str]] = None,
364
        preferences: Optional[dict] = None,
365
    ) -> Any:
366
        """Create a new audit task
367
368
        Arguments:
369
            name: Name of the new audit
370
            policy_id: UUID of policy to use by the audit
371
            target_id: UUID of target to be scanned
372
            scanner_id: UUID of scanner to use for scanning the target
373
            comment: Comment for the audit
374
            alterable: Whether the task should be alterable
375
            alert_ids: List of UUIDs for alerts to be applied to the audit
376
            hosts_ordering: The order hosts are scanned in
377
            schedule_id: UUID of a schedule when the audit should be run.
378
            schedule_periods: A limit to the number of times the audit will be
379
                scheduled, or 0 for no limit
380
            observers: List of names or ids of users which should be allowed to
381
                observe this audit
382
            preferences: Name/Value pairs of scanner preferences.
383
384
        Returns:
385
            The response. See :py:meth:`send_command` for details.
386
        """
387
388
        return self.__create_task(
389
            name=name,
390
            config_id=policy_id,
391
            target_id=target_id,
392
            scanner_id=scanner_id,
393
            usage_type=UsageType.AUDIT,
394
            function=self.create_audit.__name__,
395
            alterable=alterable,
396
            hosts_ordering=hosts_ordering,
397
            schedule_id=schedule_id,
398
            alert_ids=alert_ids,
399
            comment=comment,
400
            schedule_periods=schedule_periods,
401
            observers=observers,
402
            preferences=preferences,
403
        )
404
405
    def create_config(
406
        self, config_id: str, name: str, *, comment: Optional[str] = None
407
    ) -> Any:
408
        """Create a new scan config
409
410
        Arguments:
411
            config_id: UUID of the existing scan config
412
            name: Name of the new scan config
413
            comment: A comment on the config
414
415
        Returns:
416
            The response. See :py:meth:`send_command` for details.
417
        """
418
        return self.__create_config(
419
            config_id=config_id,
420
            name=name,
421
            comment=comment,
422
            usage_type=UsageType.SCAN,
423
            function=self.create_config.__name__,
424
        )
425
426
    def create_config_from_osp_scanner(
427
        self, scanner_id: str, name: str, *, comment: Optional[str] = None
428
    ) -> Any:
429
        """Create a new scan config from an ospd scanner.
430
431
        Create config by retrieving the expected preferences from the given
432
        scanner via OSP.
433
434
        Arguments:
435
            scanner_id: UUID of an OSP scanner to get config data from
436
            name: Name of the new scan config
437
            comment: A comment on the config
438
439
        Returns:
440
            The response. See :py:meth:`send_command` for details.
441
        """
442
        return self.__create_config_from_osp_scanner(
443
            scanner_id=scanner_id,
444
            name=name,
445
            comment=comment,
446
            usage_type=UsageType.SCAN,
447
            function=self.create_config.__name__,
448
        )
449
450
    def create_permission(
451
        self,
452
        name: str,
453
        subject_id: str,
454
        subject_type: PermissionSubjectType,
455
        *,
456
        resource_id: Optional[str] = None,
457
        resource_type: Optional[EntityType] = None,
458
        comment: Optional[str] = None,
459
    ) -> Any:
460
        """Create a new permission
461
462
        Arguments:
463
            name: Name of the new permission
464
            subject_id: UUID of subject to whom the permission is granted
465
            subject_type: Type of the subject user, group or role
466
            comment: Comment for the permission
467
            resource_id: UUID of entity to which the permission applies
468
            resource_type: Type of the resource. For Super permissions user,
469
                group or role
470
471
        Returns:
472
            The response. See :py:meth:`send_command` for details.
473
        """
474
        if not name:
475
            raise RequiredArgument(
476
                function=self.create_permission.__name__, argument='name'
477
            )
478
479
        if not subject_id:
480
            raise RequiredArgument(
481
                function=self.create_permission.__name__, argument='subject_id'
482
            )
483
484
        if not isinstance(subject_type, PermissionSubjectType):
485
            raise InvalidArgumentType(
486
                function=self.create_permission.__name__,
487
                argument='subject_type',
488
                arg_type=PermissionSubjectType.__name__,
489
            )
490
491
        cmd = XmlCommand("create_permission")
492
        cmd.add_element("name", name)
493
494
        _xmlsubject = cmd.add_element("subject", attrs={"id": subject_id})
495
        _xmlsubject.add_element("type", subject_type.value)
496
497
        if comment:
498
            cmd.add_element("comment", comment)
499
500 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...
501
            if not resource_id:
502
                raise RequiredArgument(
503
                    function=self.create_permission.__name__,
504
                    argument='resource_id',
505
                )
506
507
            if not resource_type:
508
                raise RequiredArgument(
509
                    function=self.create_permission.__name__,
510
                    argument='resource_type',
511
                )
512
513
            if not isinstance(resource_type, self.types.EntityType):
514
                raise InvalidArgumentType(
515
                    function=self.create_permission.__name__,
516
                    argument='resource_type',
517
                    arg_type=self.types.EntityType.__name__,
518
                )
519
520
            _xmlresource = cmd.add_element(
521
                "resource", attrs={"id": resource_id}
522
            )
523
524
            _actual_resource_type = resource_type
525
            if resource_type.value == EntityType.AUDIT.value:
526
                _actual_resource_type = EntityType.TASK
527
            elif resource_type.value == EntityType.POLICY.value:
528
                _actual_resource_type = EntityType.SCAN_CONFIG
529
530
            _xmlresource.add_element("type", _actual_resource_type.value)
531
532
        return self._send_xml_command(cmd)
533
534
    def create_policy(
535
        self, name: str, *, policy_id: str = None, comment: Optional[str] = None
536
    ) -> Any:
537
        """Create a new policy config
538
539
        Arguments:
540
            name: Name of the new policy
541
            policy_id: UUID of an existing policy as base. By default the empty
542
                policy is used.
543
            comment: A comment on the policy
544
545
        Returns:
546
            The response. See :py:meth:`send_command` for details.
547
        """
548
        if policy_id is None:
549
            policy_id = _EMPTY_POLICY_ID
550
        return self.__create_config(
551
            config_id=policy_id,
552
            name=name,
553
            comment=comment,
554
            usage_type=UsageType.POLICY,
555
            function=self.create_policy.__name__,
556
        )
557
558
    def create_tag(
559
        self,
560
        name: str,
561
        resource_type: EntityType,
562
        *,
563
        resource_filter: Optional[str] = None,
564
        resource_ids: Optional[List[str]] = None,
565
        value: Optional[str] = None,
566
        comment: Optional[str] = None,
567
        active: Optional[bool] = None,
568
    ) -> Any:
569
        """Create a tag.
570
571
        Arguments:
572
            name: Name of the tag. A full tag name consisting of namespace and
573
                predicate e.g. `foo:bar`.
574
            resource_type: Entity type the tag is to be attached to.
575
            resource_filter: Filter term to select resources the tag is to be
576
                attached to. Only one of resource_filter or resource_ids can be
577
                provided.
578
            resource_ids: IDs of the resources the tag is to be attached to.
579
                Only one of resource_filter or resource_ids can be provided.
580
            value: Value associated with the tag.
581
            comment: Comment for the tag.
582
            active: Whether the tag should be active.
583
584
        Returns:
585
            The response. See :py:meth:`send_command` for details.
586
        """
587
        if not name:
588
            raise RequiredArgument(
589
                function=self.create_tag.__name__, argument='name'
590
            )
591
592
        if resource_filter and resource_ids:
593
            raise InvalidArgument(
594
                "create_tag accepts either resource_filter or resource_ids "
595
                "argument",
596
                function=self.create_tag.__name__,
597
            )
598
599
        if not resource_type:
600
            raise RequiredArgument(
601
                function=self.create_tag.__name__, argument='resource_type'
602
            )
603
604
        if not isinstance(resource_type, self.types.EntityType):
605
            raise InvalidArgumentType(
606
                function=self.create_tag.__name__,
607
                argument='resource_type',
608
                arg_type=EntityType.__name__,
609
            )
610
611
        cmd = XmlCommand('create_tag')
612
        cmd.add_element('name', name)
613
614
        _xmlresources = cmd.add_element("resources")
615
        if resource_filter is not None:
616
            _xmlresources.set_attribute("filter", resource_filter)
617
618
        for resource_id in resource_ids or []:
619
            _xmlresources.add_element(
620
                "resource", attrs={"id": str(resource_id)}
621
            )
622
623
        _actual_resource_type = resource_type
624
        if resource_type.value == EntityType.AUDIT.value:
625
            _actual_resource_type = EntityType.TASK
626
        elif resource_type.value == EntityType.POLICY.value:
627
            _actual_resource_type = EntityType.SCAN_CONFIG
628
        _xmlresources.add_element("type", _actual_resource_type.value)
629
630
        if comment:
631
            cmd.add_element("comment", comment)
632
633
        if value:
634
            cmd.add_element("value", value)
635
636
        if active is not None:
637
            if active:
638
                cmd.add_element("active", "1")
639
            else:
640
                cmd.add_element("active", "0")
641
642
        return self._send_xml_command(cmd)
643
644 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...
645
        self,
646
        name: str,
647
        certificate: str,
648
        *,
649
        comment: Optional[str] = None,
650
        trust: Optional[bool] = None,
651
    ) -> Any:
652
        """Create a new TLS certificate
653
654
        Arguments:
655
            name: Name of the TLS certificate, defaulting to the MD5
656
                fingerprint.
657
            certificate: The Base64 encoded certificate data (x.509 DER or PEM).
658
            comment: Comment for the TLS certificate.
659
            trust: Whether the certificate is trusted.
660
661
        Returns:
662
            The response. See :py:meth:`send_command` for details.
663
        """
664
        if not name:
665
            raise RequiredArgument(
666
                function=self.create_tls_certificate.__name__, argument='name'
667
            )
668
        if not certificate:
669
            raise RequiredArgument(
670
                function=self.create_tls_certificate.__name__,
671
                argument='certificate',
672
            )
673
674
        cmd = XmlCommand("create_tls_certificate")
675
676
        if comment:
677
            cmd.add_element("comment", comment)
678
679
        cmd.add_element("name", name)
680
        cmd.add_element("certificate", certificate)
681
682
        if trust:
683
            cmd.add_element("trust", to_bool(trust))
684
685
        return self._send_xml_command(cmd)
686
687
    def get_aggregates(
688
        self,
689
        resource_type: EntityType,
690
        *,
691
        filter: Optional[str] = None,
692
        filter_id: Optional[str] = None,
693
        sort_criteria: Optional[list] = None,
694
        data_columns: Optional[list] = None,
695
        group_column: Optional[str] = None,
696
        subgroup_column: Optional[str] = None,
697
        text_columns: Optional[list] = None,
698
        first_group: Optional[int] = None,
699
        max_groups: Optional[int] = None,
700
        mode: Optional[int] = None,
701
        **kwargs,
702
    ) -> Any:
703
        """Request aggregated information on a resource / entity type
704
705
        Additional arguments can be set via the kwargs parameter for backward
706
        compatibility with older versions of python-gvm, but are not validated.
707
708
        Arguments:
709
            resource_type: The entity type to gather data from
710
            filter: Filter term to use for the query
711
            filter_id: UUID of an existing filter to use for the query
712
            sort_criteria: List of sort criteria (dicts that can contain
713
                a field, stat and order)
714
            data_columns: List of fields to aggregate data from
715
            group_column: The field to group the entities by
716
            subgroup_column: The field to further group the entities
717
                inside groups by
718
            text_columns: List of simple text columns which no statistics
719
                are calculated for
720
            first_group: The index of the first aggregate group to return
721
            max_groups: The maximum number of aggregate groups to return,
722
                -1 for all
723
            mode: Special mode for aggregation
724
725
        Returns:
726
            The response. See :py:meth:`send_command` for details.
727
        """
728
        if not resource_type:
729
            raise RequiredArgument(
730
                function=self.get_aggregates.__name__, argument='resource_type'
731
            )
732
733
        if not isinstance(resource_type, self.types.EntityType):
734
            raise InvalidArgumentType(
735
                function=self.get_aggregates.__name__,
736
                argument='resource_type',
737
                arg_type=self.types.EntityType.__name__,
738
            )
739
740
        cmd = XmlCommand('get_aggregates')
741
742
        _actual_resource_type = resource_type
743
        if resource_type.value == EntityType.AUDIT.value:
744
            _actual_resource_type = EntityType.TASK
745
            cmd.set_attribute('usage_type', 'audit')
746
        elif resource_type.value == EntityType.POLICY.value:
747
            _actual_resource_type = EntityType.SCAN_CONFIG
748
            cmd.set_attribute('usage_type', 'policy')
749
        elif resource_type.value == EntityType.SCAN_CONFIG.value:
750
            cmd.set_attribute('usage_type', 'scan')
751
        elif resource_type.value == EntityType.TASK.value:
752
            cmd.set_attribute('usage_type', 'scan')
753
        cmd.set_attribute('type', _actual_resource_type.value)
754
755
        add_filter(cmd, filter, filter_id)
756
757
        if first_group is not None:
758
            if not isinstance(first_group, int):
759
                raise InvalidArgumentType(
760
                    function=self.get_aggregates.__name__,
761
                    argument='first_group',
762
                    arg_type=int.__name__,
763
                )
764
            cmd.set_attribute('first_group', str(first_group))
765
766
        if max_groups is not None:
767
            if not isinstance(max_groups, int):
768
                raise InvalidArgumentType(
769
                    function=self.get_aggregates.__name__,
770
                    argument='max_groups',
771
                    arg_type=int.__name__,
772
                )
773
            cmd.set_attribute('max_groups', str(max_groups))
774
775
        if sort_criteria is not None:
776
            if not isinstance(sort_criteria, list):
777
                raise InvalidArgumentType(
778
                    function=self.get_aggregates.__name__,
779
                    argument='sort_criteria',
780
                    arg_type=list.__name__,
781
                )
782
            for sort in sort_criteria:
783
                if not isinstance(sort, dict):
784
                    raise InvalidArgumentType(
785
                        function=self.get_aggregates.__name__,
786
                        argument='sort_criteria',
787
                    )
788
789
                sort_elem = cmd.add_element('sort')
790
                if sort.get('field'):
791
                    sort_elem.set_attribute('field', sort.get('field'))
792
793
                if sort.get('stat'):
794
                    if isinstance(sort['stat'], AggregateStatistic):
795
                        sort_elem.set_attribute('stat', sort['stat'].value)
796
                    else:
797
                        stat = get_aggregate_statistic_from_string(sort['stat'])
798
                        sort_elem.set_attribute('stat', stat.value)
799
800
                if sort.get('order'):
801
                    if isinstance(sort['order'], SortOrder):
802
                        sort_elem.set_attribute('order', sort['order'].value)
803
                    else:
804
                        so = get_sort_order_from_string(sort['order'])
805
                        sort_elem.set_attribute('order', so.value)
806
807
        if data_columns is not None:
808
            if not isinstance(data_columns, list):
809
                raise InvalidArgumentType(
810
                    function=self.get_aggregates.__name__,
811
                    argument='data_columns',
812
                    arg_type=list.__name__,
813
                )
814
            for column in data_columns:
815
                cmd.add_element('data_column', column)
816
817
        if group_column is not None:
818
            cmd.set_attribute('group_column', group_column)
819
820
        if subgroup_column is not None:
821
            if not group_column:
822
                raise RequiredArgument(
823
                    '{} requires a group_column argument'
824
                    ' if subgroup_column is given'.format(
825
                        self.get_aggregates.__name__
826
                    ),
827
                    function=self.get_aggregates.__name__,
828
                    argument='subgroup_column',
829
                )
830
            cmd.set_attribute('subgroup_column', subgroup_column)
831
832
        if text_columns is not None:
833
            if not isinstance(text_columns, list):
834
                raise InvalidArgumentType(
835
                    function=self.get_aggregates.__name__,
836
                    argument='text_columns',
837
                    arg_type=list.__name__,
838
                )
839
            for column in text_columns:
840
                cmd.add_element('text_column', column)
841
842
        if mode is not None:
843
            cmd.set_attribute('mode', mode)
844
845
        # Add additional keyword args as attributes for backward compatibility.
846
        cmd.set_attributes(kwargs)
847
848
        return self._send_xml_command(cmd)
849
850 View Code Duplication
    def get_tls_certificates(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
851
        self,
852
        *,
853
        filter: Optional[str] = None,
854
        filter_id: Optional[str] = None,
855
        include_certificate_data: Optional[bool] = None,
856
        details: Optional[bool] = None,
857
    ) -> Any:
858
        """Request a list of TLS certificates
859
860
        Arguments:
861
            filter: Filter term to use for the query
862
            filter_id: UUID of an existing filter to use for the query
863
            include_certificate_data: Whether to include the certificate data in
864
                the response
865
866
        Returns:
867
            The response. See :py:meth:`send_command` for details.
868
        """
869
870
        cmd = XmlCommand("get_tls_certificates")
871
872
        add_filter(cmd, filter, filter_id)
873
874
        if details is not None:
875
            cmd.set_attribute("details", to_bool(details))
876
877
        if include_certificate_data is not None:
878
            cmd.set_attribute(
879
                "include_certificate_data", to_bool(include_certificate_data)
880
            )
881
882
        return self._send_xml_command(cmd)
883
884
    def get_tls_certificate(self, tls_certificate_id: str) -> Any:
885
        """Request a single TLS certificate
886
887
        Arguments:
888
            tls_certificate_id: UUID of an existing TLS certificate
889
890
        Returns:
891
            The response. See :py:meth:`send_command` for details.
892
        """
893
        cmd = XmlCommand("get_tls_certificates")
894
895
        if not tls_certificate_id:
896
            raise RequiredArgument(
897
                function=self.get_tls_certificate.__name__,
898
                argument='tls_certificate_id',
899
            )
900
901
        cmd.set_attribute("tls_certificate_id", tls_certificate_id)
902
903
        # for single tls certificate always request cert data
904
        cmd.set_attribute("include_certificate_data", "1")
905
906
        # for single entity always request all details
907
        cmd.set_attribute("details", "1")
908
909
        return self._send_xml_command(cmd)
910
911
    def modify_alert(
912
        self,
913
        alert_id: str,
914
        *,
915
        name: Optional[str] = None,
916
        comment: Optional[str] = None,
917
        filter_id: Optional[str] = None,
918
        event: Optional[AlertEvent] = None,
919
        event_data: Optional[dict] = None,
920
        condition: Optional[AlertCondition] = None,
921
        condition_data: Optional[dict] = None,
922
        method: Optional[AlertMethod] = None,
923
        method_data: Optional[dict] = None,
924
    ) -> Any:
925
        """Modifies an existing alert.
926
927
        Arguments:
928
            alert_id: UUID of the alert to be modified.
929
            name: Name of the Alert.
930
            condition: The condition that must be satisfied for the alert to
931
                occur. If the event is either 'Updated SecInfo
932
                arrived' or 'New SecInfo arrived', condition must be 'Always'.
933
                Otherwise, condition can also be on of 'Severity at least',
934
                'Filter count changed' or 'Filter count at least'.
935
            condition_data: Data that defines the condition
936
            event: The event that must happen for the alert to occur, one of
937
                'Task run status changed', 'Updated SecInfo arrived' or
938
                'New SecInfo arrived'
939
            event_data: Data that defines the event
940
            method: The method by which the user is alerted, one of 'SCP',
941
                'Send', 'SMB', 'SNMP', 'Syslog' or 'Email';
942
                if the event is neither 'Updated SecInfo arrived' nor
943
                'New SecInfo arrived', method can also be one of 'Start Task',
944
                'HTTP Get', 'Sourcefire Connector' or 'verinice Connector'.
945
            method_data: Data that defines the method
946
            filter_id: Filter to apply when executing alert
947
            comment: Comment for the alert
948
949
        Returns:
950
            The response. See :py:meth:`send_command` for details.
951
        """
952
953
        if not alert_id:
954
            raise RequiredArgument(
955
                function=self.modify_alert.__name__, argument='alert_id'
956
            )
957
958
        cmd = XmlCommand("modify_alert")
959
        cmd.set_attribute("alert_id", str(alert_id))
960
961
        if name:
962
            cmd.add_element("name", name)
963
964
        if comment:
965
            cmd.add_element("comment", comment)
966
967
        if filter_id:
968
            cmd.add_element("filter", attrs={"id": filter_id})
969
970
        if condition:
971
            if not isinstance(condition, AlertCondition):
972
                raise InvalidArgumentType(
973
                    function=self.modify_alert.__name__,
974
                    argument='condition',
975
                    arg_type=AlertCondition.__name__,
976
                )
977
978
            conditions = cmd.add_element("condition", condition.value)
979
980
            if condition_data is not None:
981
                for key, value in condition_data.items():
982
                    _data = conditions.add_element("data", value)
983
                    _data.add_element("name", key)
984
985
        if method:
986
            if not isinstance(method, AlertMethod):
987
                raise InvalidArgumentType(
988
                    function=self.modify_alert.__name__,
989
                    argument='method',
990
                    arg_type=AlertMethod.__name__,
991
                )
992
993
            methods = cmd.add_element("method", method.value)
994
995
            if method_data is not None:
996
                for key, value in method_data.items():
997
                    _data = methods.add_element("data", value)
998
                    _data.add_element("name", key)
999
1000
        if event:
1001
            if not isinstance(event, AlertEvent):
1002
                raise InvalidArgumentType(
1003
                    function=self.modify_alert.__name__,
1004
                    argument='event',
1005
                    arg_type=AlertEvent.__name__,
1006
                )
1007
1008
            _check_event(event, condition, method)
1009
1010
            events = cmd.add_element("event", event.value)
1011
1012
            if event_data is not None:
1013
                for key, value in event_data.items():
1014
                    _data = events.add_element("data", value)
1015
                    _data.add_element("name", key)
1016
1017
        return self._send_xml_command(cmd)
1018
1019
    def modify_audit(
1020
        self,
1021
        audit_id: str,
1022
        *,
1023
        name: Optional[str] = None,
1024
        policy_id: Optional[str] = None,
1025
        target_id: Optional[str] = None,
1026
        scanner_id: Optional[str] = None,
1027
        alterable: Optional[bool] = None,
1028
        hosts_ordering: Optional[HostsOrdering] = None,
1029
        schedule_id: Optional[str] = None,
1030
        schedule_periods: Optional[int] = None,
1031
        comment: Optional[str] = None,
1032
        alert_ids: Optional[List[str]] = None,
1033
        observers: Optional[List[str]] = None,
1034
        preferences: Optional[dict] = None,
1035
    ) -> Any:
1036
        """Modifies an existing task.
1037
1038
        Arguments:
1039
            audit_id: UUID of audit to modify.
1040
            name: The name of the audit.
1041
            policy_id: UUID of policy to use by the audit
1042
            target_id: UUID of target to be scanned
1043
            scanner_id: UUID of scanner to use for scanning the target
1044
            comment: The comment on the audit.
1045
            alert_ids: List of UUIDs for alerts to be applied to the audit
1046
            hosts_ordering: The order hosts are scanned in
1047
            schedule_id: UUID of a schedule when the audit should be run.
1048
            schedule_periods: A limit to the number of times the audit will be
1049
                scheduled, or 0 for no limit.
1050
            observers: List of names or ids of users which should be allowed to
1051
                observe this audit
1052
            preferences: Name/Value pairs of scanner preferences.
1053
1054
        Returns:
1055
            The response. See :py:meth:`send_command` for details.
1056
        """
1057
        self.modify_task(
1058
            task_id=audit_id,
1059
            name=name,
1060
            config_id=policy_id,
1061
            target_id=target_id,
1062
            scanner_id=scanner_id,
1063
            alterable=alterable,
1064
            hosts_ordering=hosts_ordering,
1065
            schedule_id=schedule_id,
1066
            schedule_periods=schedule_periods,
1067
            comment=comment,
1068
            alert_ids=alert_ids,
1069
            observers=observers,
1070
            preferences=preferences,
1071
        )
1072
1073
    def modify_permission(
1074
        self,
1075
        permission_id: str,
1076
        *,
1077
        comment: Optional[str] = None,
1078
        name: Optional[str] = None,
1079
        resource_id: Optional[str] = None,
1080
        resource_type: Optional[EntityType] = None,
1081
        subject_id: Optional[str] = None,
1082
        subject_type: Optional[PermissionSubjectType] = None,
1083
    ) -> Any:
1084
        """Modifies an existing permission.
1085
1086
        Arguments:
1087
            permission_id: UUID of permission to be modified.
1088
            comment: The comment on the permission.
1089
            name: Permission name, currently the name of a command.
1090
            subject_id: UUID of subject to whom the permission is granted
1091
            subject_type: Type of the subject user, group or role
1092
            resource_id: UUID of entity to which the permission applies
1093
            resource_type: Type of the resource. For Super permissions user,
1094
                group or role
1095
1096
        Returns:
1097
            The response. See :py:meth:`send_command` for details.
1098
        """
1099
        if not permission_id:
1100
            raise RequiredArgument(
1101
                function=self.modify_permission.__name__,
1102
                argument='permission_id',
1103
            )
1104
1105
        cmd = XmlCommand("modify_permission")
1106
        cmd.set_attribute("permission_id", permission_id)
1107
1108
        if comment:
1109
            cmd.add_element("comment", comment)
1110
1111
        if name:
1112
            cmd.add_element("name", name)
1113
1114 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...
1115
            if not resource_id:
1116
                raise RequiredArgument(
1117
                    function=self.modify_permission.__name__,
1118
                    argument='resource_id',
1119
                )
1120
1121
            if not resource_type:
1122
                raise RequiredArgument(
1123
                    function=self.modify_permission.__name__,
1124
                    argument='resource_type',
1125
                )
1126
1127
            if not isinstance(resource_type, self.types.EntityType):
1128
                raise InvalidArgumentType(
1129
                    function=self.modify_permission.__name__,
1130
                    argument='resource_type',
1131
                    arg_type=self.types.EntityType.__name__,
1132
                )
1133
1134
            _xmlresource = cmd.add_element(
1135
                "resource", attrs={"id": resource_id}
1136
            )
1137
            _actual_resource_type = resource_type
1138
            if resource_type.value == EntityType.AUDIT.value:
1139
                _actual_resource_type = EntityType.TASK
1140
            elif resource_type.value == EntityType.POLICY.value:
1141
                _actual_resource_type = EntityType.SCAN_CONFIG
1142
            _xmlresource.add_element("type", _actual_resource_type.value)
1143
1144
        if subject_id or subject_type:
1145
            if not subject_id:
1146
                raise RequiredArgument(
1147
                    function=self.modify_permission.__name__,
1148
                    argument='subject_id',
1149
                )
1150
1151
            if not isinstance(subject_type, PermissionSubjectType):
1152
                raise InvalidArgumentType(
1153
                    function=self.modify_permission.__name__,
1154
                    argument='subject_type',
1155
                    arg_type=PermissionSubjectType.__name__,
1156
                )
1157
1158
            _xmlsubject = cmd.add_element("subject", attrs={"id": subject_id})
1159
            _xmlsubject.add_element("type", subject_type.value)
1160
1161
        return self._send_xml_command(cmd)
1162
1163
    def modify_policy_set_nvt_preference(
1164
        self,
1165
        policy_id: str,
1166
        name: str,
1167
        nvt_oid: str,
1168
        *,
1169
        value: Optional[str] = None,
1170
    ) -> Any:
1171
        """Modifies the nvt preferences of an existing policy.
1172
1173
        Arguments:
1174
            policy_id: UUID of policy to modify.
1175
            name: Name for preference to change.
1176
            nvt_oid: OID of the NVT associated with preference to modify
1177
            value: New value for the preference. None to delete the preference
1178
                and to use the default instead.
1179
        """
1180
        self.modify_config_set_nvt_preference(
1181
            config_id=policy_id, name=name, nvt_oid=nvt_oid, value=value
1182
        )
1183
1184
    def modify_policy_set_name(self, policy_id: str, name: str) -> Any:
1185
        """Modifies the name of an existing policy
1186
1187
        Arguments:
1188
            config_id: UUID of policy to modify.
1189
            name: New name for the config.
1190
        """
1191
        self.modify_config_set_name(config_id=policy_id, name=name)
1192
1193
    def modify_policy_set_comment(
1194
        self, policy_id: str, comment: Optional[str] = ""
1195
    ) -> Any:
1196
        """Modifies the comment of an existing policy
1197
1198
        Arguments:
1199
            policy_id: UUID of policy to modify.
1200
            comment: Comment to set on a config. Default: ''
1201
        """
1202
        self.modify_config_set_comment(config_id=policy_id, comment=comment)
1203
1204
    def modify_policy_set_scanner_preference(
1205
        self, policy_id: str, name: str, *, value: Optional[str] = None
1206
    ) -> Any:
1207
        """Modifies the scanner preferences of an existing policy
1208
1209
        Arguments:
1210
            policy_id: UUID of policy to modify.
1211
            name: Name of the scanner preference to change
1212
            value: New value for the preference. None to delete the preference
1213
                and to use the default instead.
1214
1215
        """
1216
        self.modify_config_set_scanner_preference(
1217
            config_id=policy_id, name=name, value=value
1218
        )
1219
1220
    def modify_policy_set_nvt_selection(
1221
        self, policy_id: str, family: str, nvt_oids: List[str]
1222
    ) -> Any:
1223
        """Modifies the selected nvts of an existing policy
1224
1225
        The manager updates the given family in the config to include only the
1226
        given NVTs.
1227
1228
        Arguments:
1229
            policy_id: UUID of policy to modify.
1230
            family: Name of the NVT family to include NVTs from
1231
            nvt_oids: List of NVTs to select for the family.
1232
        """
1233
        self.modify_config_set_nvt_selection(
1234
            config_id=policy_id, family=family, nvt_oids=nvt_oids
1235
        )
1236
1237
    def modify_policy_set_family_selection(
1238
        self,
1239
        policy_id: str,
1240
        families: List[Tuple[str, bool, bool]],
1241
        *,
1242
        auto_add_new_families: Optional[bool] = True,
1243
    ) -> Any:
1244
        """
1245
        Selected the NVTs of a policy at a family level.
1246
1247
        Arguments:
1248
            policy_id: UUID of policy to modify.
1249
            families: A list of tuples with the first entry being the name
1250
                of the NVT family selected, second entry a boolean indicating
1251
                whether new NVTs should be added to the family automatically,
1252
                and third entry a boolean indicating whether all nvts from
1253
                the family should be included.
1254
            auto_add_new_families: Whether new families should be added to the
1255
                policy automatically. Default: True.
1256
        """
1257
        self.modify_config_set_family_selection(
1258
            config_id=policy_id,
1259
            families=families,
1260
            auto_add_new_families=auto_add_new_families,
1261
        )
1262
1263
    def modify_tag(
1264
        self,
1265
        tag_id: str,
1266
        *,
1267
        comment: Optional[str] = None,
1268
        name: Optional[str] = None,
1269
        value=None,
1270
        active=None,
1271
        resource_action: Optional[str] = None,
1272
        resource_type: Optional[EntityType] = None,
1273
        resource_filter: Optional[str] = None,
1274
        resource_ids: Optional[List[str]] = None,
1275
    ) -> Any:
1276
        """Modifies an existing tag.
1277
1278
        Arguments:
1279
            tag_id: UUID of the tag.
1280
            comment: Comment to add to the tag.
1281
            name: Name of the tag.
1282
            value: Value of the tag.
1283
            active: Whether the tag is active.
1284
            resource_action: Whether to add or remove resources instead of
1285
                overwriting. One of '', 'add', 'set' or 'remove'.
1286
            resource_type: Type of the resources to which to attach the tag.
1287
                Required if resource_filter is set.
1288
            resource_filter: Filter term to select resources the tag is to be
1289
                attached to.
1290
            resource_ids: IDs of the resources to which to attach the tag.
1291
1292
        Returns:
1293
            The response. See :py:meth:`send_command` for details.
1294
        """
1295
        if not tag_id:
1296
            raise RequiredArgument(
1297
                function=self.modify_tag.__name__, argument='tag_id'
1298
            )
1299
1300
        cmd = XmlCommand("modify_tag")
1301
        cmd.set_attribute("tag_id", str(tag_id))
1302
1303
        if comment:
1304
            cmd.add_element("comment", comment)
1305
1306
        if name:
1307
            cmd.add_element("name", name)
1308
1309
        if value:
1310
            cmd.add_element("value", value)
1311
1312
        if active is not None:
1313
            cmd.add_element("active", to_bool(active))
1314
1315
        if resource_action or resource_filter or resource_ids or resource_type:
1316
            if resource_filter and not resource_type:
1317
                raise RequiredArgument(
1318
                    function=self.modify_tag.__name__, argument='resource_type'
1319
                )
1320
1321
            _xmlresources = cmd.add_element("resources")
1322
            if resource_action is not None:
1323
                _xmlresources.set_attribute("action", resource_action)
1324
1325
            if resource_filter is not None:
1326
                _xmlresources.set_attribute("filter", resource_filter)
1327
1328
            for resource_id in resource_ids or []:
1329
                _xmlresources.add_element(
1330
                    "resource", attrs={"id": str(resource_id)}
1331
                )
1332
1333
            if resource_type is not None:
1334
                if not isinstance(resource_type, self.types.EntityType):
1335
                    raise InvalidArgumentType(
1336
                        function=self.modify_tag.__name__,
1337
                        argument="resource_type",
1338
                        arg_type=EntityType.__name__,
1339
                    )
1340
                _actual_resource_type = resource_type
1341
                if resource_type.value == EntityType.AUDIT.value:
1342
                    _actual_resource_type = EntityType.TASK
1343
                elif resource_type.value == EntityType.POLICY.value:
1344
                    _actual_resource_type = EntityType.SCAN_CONFIG
1345
                _xmlresources.add_element("type", _actual_resource_type.value)
1346
1347
        return self._send_xml_command(cmd)
1348
1349 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...
1350
        self,
1351
        tls_certificate_id: str,
1352
        *,
1353
        name: Optional[str] = None,
1354
        comment: Optional[str] = None,
1355
        trust: Optional[bool] = None,
1356
    ) -> Any:
1357
        """Modifies an existing TLS certificate.
1358
1359
        Arguments:
1360
            tls_certificate_id: UUID of the TLS certificate to be modified.
1361
            name: Name of the TLS certificate, defaulting to the MD5 fingerprint
1362
            comment: Comment for the TLS certificate.
1363
            trust: Whether the certificate is trusted.
1364
1365
        Returns:
1366
            The response. See :py:meth:`send_command` for details.
1367
        """
1368
        if not tls_certificate_id:
1369
            raise RequiredArgument(
1370
                function=self.modify_tls_certificate.__name__,
1371
                argument='tls_certificate_id',
1372
            )
1373
1374
        cmd = XmlCommand("modify_tls_certificate")
1375
        cmd.set_attribute("tls_certificate_id", str(tls_certificate_id))
1376
1377
        if comment:
1378
            cmd.add_element("comment", comment)
1379
1380
        if name:
1381
            cmd.add_element("name", name)
1382
1383
        if trust:
1384
            cmd.add_element("trust", to_bool(trust))
1385
1386
        return self._send_xml_command(cmd)
1387
1388
    def clone_alert(self, alert_id: str) -> Any:
1389
        """Clone an existing alert
1390
1391
        Arguments:
1392
            alert_id: UUID of an existing alert to clone from
1393
1394
        Returns:
1395
            The response. See :py:meth:`send_command` for details.
1396
        """
1397
        if not alert_id:
1398
            raise RequiredArgument(
1399
                function=self.clone_alert.__name__, argument='alert_id'
1400
            )
1401
1402
        cmd = XmlCommand("create_alert")
1403
        cmd.add_element("copy", alert_id)
1404
        return self._send_xml_command(cmd)
1405
1406
    def clone_ticket(self, ticket_id: str) -> Any:
1407
        """Clone an existing ticket
1408
1409
        Arguments:
1410
            ticket_id: UUID of an existing ticket to clone from
1411
1412
        Returns:
1413
            The response. See :py:meth:`send_command` for details.
1414
        """
1415
        if not ticket_id:
1416
            raise RequiredArgument(
1417
                function=self.clone_ticket.__name__, argument='ticket_id'
1418
            )
1419
1420
        cmd = XmlCommand("create_ticket")
1421
1422
        _copy = cmd.add_element("copy", ticket_id)
1423
1424
        return self._send_xml_command(cmd)
1425
1426
    def clone_tls_certificate(self, tls_certificate_id: str) -> Any:
1427
        """Modifies an existing TLS certificate.
1428
1429
        Arguments:
1430
            tls_certificate_id: The UUID of an existing TLS certificate
1431
1432
        Returns:
1433
            The response. See :py:meth:`send_command` for details.
1434
        """
1435
        if not tls_certificate_id:
1436
            raise RequiredArgument(
1437
                function=self.clone_tls_certificate.__name__,
1438
                argument='tls_certificate_id',
1439
            )
1440
1441
        cmd = XmlCommand("create_tls_certificate")
1442
1443
        cmd.add_element("copy", tls_certificate_id)
1444
1445
        return self._send_xml_command(cmd)
1446
1447
    def get_configs(
1448
        self,
1449
        *,
1450
        filter: Optional[str] = None,
1451
        filter_id: Optional[str] = None,
1452
        trash: Optional[bool] = None,
1453
        details: Optional[bool] = None,
1454
        families: Optional[bool] = None,
1455
        preferences: Optional[bool] = None,
1456
        tasks: Optional[bool] = None,
1457
    ) -> Any:
1458
        """Request a list of scan configs
1459
1460
        Arguments:
1461
            filter: Filter term to use for the query
1462
            filter_id: UUID of an existing filter to use for the query
1463
            trash: Whether to get the trashcan scan configs instead
1464
            details: Whether to get config families, preferences, nvt selectors
1465
                and tasks.
1466
            families: Whether to include the families if no details are
1467
                requested
1468
            preferences: Whether to include the preferences if no details are
1469
                requested
1470
            tasks: Whether to get tasks using this config
1471
1472
        Returns:
1473
            The response. See :py:meth:`send_command` for details.
1474
        """
1475
        return self.__get_configs(
1476
            UsageType.SCAN,
1477
            filter=filter,
1478
            filter_id=filter_id,
1479
            trash=trash,
1480
            details=details,
1481
            families=families,
1482
            preferences=preferences,
1483
            tasks=tasks,
1484
        )
1485
1486
    def get_policies(
1487
        self,
1488
        *,
1489
        audits: Optional[bool] = None,
1490
        filter: Optional[str] = None,
1491
        filter_id: Optional[str] = None,
1492
        details: Optional[bool] = None,
1493
        families: Optional[bool] = None,
1494
        preferences: Optional[bool] = None,
1495
        trash: Optional[bool] = None,
1496
    ) -> Any:
1497
        """Request a list of policies
1498
1499
        Arguments:
1500
            audits: Whether to get audits using the policy
1501
            filter: Filter term to use for the query
1502
            filter_id: UUID of an existing filter to use for the query
1503
            details: Whether to get  families, preferences, nvt selectors
1504
                and tasks.
1505
            families: Whether to include the families if no details are
1506
                requested
1507
            preferences: Whether to include the preferences if no details are
1508
                requested
1509
            trash: Whether to get the trashcan audits instead
1510
1511
        Returns:
1512
            The response. See :py:meth:`send_command` for details.
1513
        """
1514
        return self.__get_configs(
1515
            UsageType.POLICY,
1516
            filter=filter,
1517
            filter_id=filter_id,
1518
            details=details,
1519
            families=families,
1520
            preferences=preferences,
1521
            tasks=audits,
1522
            trash=trash,
1523
        )
1524
1525
    def get_config(
1526
        self, config_id: str, *, tasks: Optional[bool] = None
1527
    ) -> Any:
1528
        """Request a single scan config
1529
1530
        Arguments:
1531
            config_id: UUID of an existing scan config
1532
            tasks: Whether to get tasks using this config
1533
1534
        Returns:
1535
            The response. See :py:meth:`send_command` for details.
1536
        """
1537
        return self.__get_config(
1538
            config_id=config_id, usage_type=UsageType.SCAN, tasks=tasks
1539
        )
1540
1541
    def get_policy(
1542
        self, policy_id: str, *, audits: Optional[bool] = None
1543
    ) -> Any:
1544
        """Request a single policy
1545
1546
        Arguments:
1547
            policy_id: UUID of an existing policy
1548
            audits: Whether to get audits using this config
1549
1550
        Returns:
1551
            The response. See :py:meth:`send_command` for details.
1552
        """
1553
        return self.__get_config(policy_id, UsageType.POLICY, tasks=audits)
1554
1555
    def get_tasks(
1556
        self,
1557
        *,
1558
        filter: Optional[str] = None,
1559
        filter_id: Optional[str] = None,
1560
        trash: Optional[bool] = None,
1561
        details: Optional[bool] = None,
1562
        schedules_only: Optional[bool] = None,
1563
    ) -> Any:
1564
        """Request a list of tasks
1565
1566
        Arguments:
1567
            filter: Filter term to use for the query
1568
            filter_id: UUID of an existing filter to use for the query
1569
            trash: Whether to get the trashcan tasks instead
1570
            details: Whether to include full task details
1571
            schedules_only: Whether to only include id, name and schedule
1572
                details
1573
1574
        Returns:
1575
            The response. See :py:meth:`send_command` for details.
1576
        """
1577
        return self.__get_tasks(
1578
            UsageType.SCAN,
1579
            filter=filter,
1580
            filter_id=filter_id,
1581
            trash=trash,
1582
            details=details,
1583
            schedules_only=schedules_only,
1584
        )
1585
1586
    def get_audits(
1587
        self,
1588
        *,
1589
        filter: Optional[str] = None,
1590
        filter_id: Optional[str] = None,
1591
        trash: Optional[bool] = None,
1592
        details: Optional[bool] = None,
1593
        schedules_only: Optional[bool] = None,
1594
    ) -> Any:
1595
        """Request a list of audits
1596
1597
        Arguments:
1598
            filter: Filter term to use for the query
1599
            filter_id: UUID of an existing filter to use for the query
1600
            trash: Whether to get the trashcan audits instead
1601
            details: Whether to include full audit details
1602
            schedules_only: Whether to only include id, name and schedule
1603
                details
1604
1605
        Returns:
1606
            The response. See :py:meth:`send_command` for details.
1607
        """
1608
        return self.__get_tasks(
1609
            UsageType.AUDIT,
1610
            filter=filter,
1611
            filter_id=filter_id,
1612
            trash=trash,
1613
            details=details,
1614
            schedules_only=schedules_only,
1615
        )
1616
1617
    def get_task(self, task_id: str) -> Any:
1618
        """Request a single task
1619
1620
        Arguments:
1621
            task_id: UUID of an existing task
1622
1623
        Returns:
1624
            The response. See :py:meth:`send_command` for details.
1625
        """
1626
        return self.__get_task(task_id, UsageType.SCAN)
1627
1628
    def get_audit(self, audit_id: str) -> Any:
1629
        """Request a single audit
1630
1631
        Arguments:
1632
            audit_id: UUID of an existing audit
1633
1634
        Returns:
1635
            The response. See :py:meth:`send_command` for details.
1636
        """
1637
        return self.__get_task(audit_id, UsageType.AUDIT)
1638
1639
    def clone_audit(self, audit_id: str) -> Any:
1640
        """Clone an existing audit
1641
1642
        Arguments:
1643
            audit_id: UUID of existing audit to clone from
1644
1645
        Returns:
1646
            The response. See :py:meth:`send_command` for details.
1647
        """
1648
        if not audit_id:
1649
            raise RequiredArgument(
1650
                function=self.clone_audit.__name__, argument='audit_id'
1651
            )
1652
1653
        cmd = XmlCommand("create_task")
1654
        cmd.add_element("copy", audit_id)
1655
        return self._send_xml_command(cmd)
1656
1657
    def clone_policy(self, policy_id: str) -> Any:
1658
        """Clone a policy from an existing one
1659
1660
        Arguments:
1661
            policy_id: UUID of the existing policy
1662
1663
        Returns:
1664
            The response. See :py:meth:`send_command` for details.
1665
        """
1666
        if not policy_id:
1667
            raise RequiredArgument(
1668
                function=self.clone_policy.__name__, argument='policy_id'
1669
            )
1670
1671
        cmd = XmlCommand("create_config")
1672
        cmd.add_element("copy", policy_id)
1673
        return self._send_xml_command(cmd)
1674
1675
    def delete_audit(
1676
        self, audit_id: str, *, ultimate: Optional[bool] = False
1677
    ) -> Any:
1678
        """Deletes an existing audit
1679
1680
        Arguments:
1681
            audit_id: UUID of the audit to be deleted.
1682
            ultimate: Whether to remove entirely, or to the trashcan.
1683
        """
1684
        if not audit_id:
1685
            raise RequiredArgument(
1686
                function=self.delete_audit.__name__, argument='audit_id'
1687
            )
1688
1689
        cmd = XmlCommand("delete_task")
1690
        cmd.set_attribute("task_id", audit_id)
1691
        cmd.set_attribute("ultimate", to_bool(ultimate))
1692
1693
        return self._send_xml_command(cmd)
1694
1695
    def delete_policy(
1696
        self, policy_id: str, *, ultimate: Optional[bool] = False
1697
    ) -> Any:
1698
        """Deletes an existing policy
1699
1700
        Arguments:
1701
            policy_id: UUID of the policy to be deleted.
1702
            ultimate: Whether to remove entirely, or to the trashcan.
1703
        """
1704
        if not policy_id:
1705
            raise RequiredArgument(
1706
                function=self.delete_policy.__name__, argument='policy_id'
1707
            )
1708
1709
        cmd = XmlCommand("delete_config")
1710
        cmd.set_attribute("config_id", policy_id)
1711
        cmd.set_attribute("ultimate", to_bool(ultimate))
1712
1713
        return self._send_xml_command(cmd)
1714
1715
    def delete_tls_certificate(self, tls_certificate_id: str) -> Any:
1716
        """Deletes an existing tls certificate
1717
1718
        Arguments:
1719
            tls_certificate_id: UUID of the tls certificate to be deleted.
1720
        """
1721
        if not tls_certificate_id:
1722
            raise RequiredArgument(
1723
                function=self.delete_tls_certificate.__name__,
1724
                argument='tls_certificate_id',
1725
            )
1726
1727
        cmd = XmlCommand("delete_tls_certificate")
1728
        cmd.set_attribute("tls_certificate_id", tls_certificate_id)
1729
1730
        return self._send_xml_command(cmd)
1731
1732
    def __create_task(
1733
        self,
1734
        name: str,
1735
        config_id: str,
1736
        target_id: str,
1737
        scanner_id: str,
1738
        usage_type: UsageType,
1739
        function: str,
1740
        *,
1741
        alterable: Optional[bool] = None,
1742
        hosts_ordering: Optional[HostsOrdering] = None,
1743
        schedule_id: Optional[str] = None,
1744
        alert_ids: Optional[List[str]] = None,
1745
        comment: Optional[str] = None,
1746
        schedule_periods: Optional[int] = None,
1747
        observers: Optional[List[str]] = None,
1748
        preferences: Optional[dict] = None,
1749
    ) -> Any:
1750
        if not name:
1751
            raise RequiredArgument(function=function, argument='name')
1752
1753
        if not config_id:
1754
            raise RequiredArgument(function=function, argument='config_id')
1755
1756
        if not target_id:
1757
            raise RequiredArgument(function=function, argument='target_id')
1758
1759
        if not scanner_id:
1760
            raise RequiredArgument(function=function, argument='scanner_id')
1761
1762
        # don't allow to create a container task with create_task
1763
        if target_id == '0':
1764
            raise InvalidArgument(function=function, argument='target_id')
1765
1766
        cmd = XmlCommand("create_task")
1767
        cmd.add_element("name", name)
1768
        cmd.add_element("usage_type", usage_type.value)
1769
        cmd.add_element("config", attrs={"id": config_id})
1770
        cmd.add_element("target", attrs={"id": target_id})
1771
        cmd.add_element("scanner", attrs={"id": scanner_id})
1772
1773
        if comment:
1774
            cmd.add_element("comment", comment)
1775
1776
        if alterable is not None:
1777
            cmd.add_element("alterable", to_bool(alterable))
1778
1779
        if hosts_ordering:
1780
            if not isinstance(hosts_ordering, self.types.HostsOrdering):
1781
                raise InvalidArgumentType(
1782
                    function=function,
1783
                    argument='hosts_ordering',
1784
                    arg_type=HostsOrdering.__name__,
1785
                )
1786
            cmd.add_element("hosts_ordering", hosts_ordering.value)
1787
1788
        if alert_ids:
1789
            if isinstance(alert_ids, str):
1790
                deprecation(
1791
                    "Please pass a list as alert_ids parameter to {}. "
1792
                    "Passing a string is deprecated and will be removed in "
1793
                    "future.".format(function)
1794
                )
1795
1796
                # if a single id is given as a string wrap it into a list
1797
                alert_ids = [alert_ids]
1798
            if is_list_like(alert_ids):
1799
                # parse all given alert id's
1800
                for alert in alert_ids:
1801
                    cmd.add_element("alert", attrs={"id": str(alert)})
1802
1803 View Code Duplication
        if schedule_id:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1804
            cmd.add_element("schedule", attrs={"id": schedule_id})
1805
1806
            if schedule_periods is not None:
1807
                if (
1808
                    not isinstance(schedule_periods, Integral)
1809
                    or schedule_periods < 0
1810
                ):
1811
                    raise InvalidArgument(
1812
                        "schedule_periods must be an integer greater or equal "
1813
                        "than 0"
1814
                    )
1815
                cmd.add_element("schedule_periods", str(schedule_periods))
1816
1817
        if observers is not None:
1818
            if not is_list_like(observers):
1819
                raise InvalidArgumentType(
1820
                    function=function, argument='observers', arg_type='list'
1821
                )
1822
1823
            # gvmd splits by comma and space
1824
            # gvmd tries to lookup each value as user name and afterwards as
1825
            # user id. So both user name and user id are possible
1826
            cmd.add_element("observers", to_comma_list(observers))
1827
1828 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...
1829
            if not isinstance(preferences, collections.abc.Mapping):
1830
                raise InvalidArgumentType(
1831
                    function=function,
1832
                    argument='preferences',
1833
                    arg_type=collections.abc.Mapping.__name__,
1834
                )
1835
1836
            _xmlprefs = cmd.add_element("preferences")
1837
            for pref_name, pref_value in preferences.items():
1838
                _xmlpref = _xmlprefs.add_element("preference")
1839
                _xmlpref.add_element("scanner_name", pref_name)
1840
                _xmlpref.add_element("value", str(pref_value))
1841
1842
        return self._send_xml_command(cmd)
1843
1844
    def __create_config(
1845
        self,
1846
        config_id: str,
1847
        name: str,
1848
        usage_type: UsageType,
1849
        function: str,
1850
        *,
1851
        comment: Optional[str] = None,
1852
    ) -> Any:
1853
        if not name:
1854
            raise RequiredArgument(function=function, argument='name')
1855
1856
        if not config_id:
1857
            raise RequiredArgument(function=function, argument='config_id')
1858
1859
        cmd = XmlCommand("create_config")
1860
        if comment is not None:
1861
            cmd.add_element("comment", comment)
1862
        cmd.add_element("copy", config_id)
1863
        cmd.add_element("name", name)
1864
        cmd.add_element("usage_type", usage_type.value)
1865
        return self._send_xml_command(cmd)
1866
1867
    def __create_config_from_osp_scanner(
1868
        self,
1869
        scanner_id: str,
1870
        name: str,
1871
        usage_type: UsageType,
1872
        function: str,
1873
        *,
1874
        comment: Optional[str] = None,
1875
    ) -> Any:
1876
        if not name:
1877
            raise RequiredArgument(function=function, argument='name')
1878
1879
        if not scanner_id:
1880
            raise RequiredArgument(function=function, argument='scanner_id')
1881
1882
        cmd = XmlCommand("create_config")
1883
        if comment is not None:
1884
            cmd.add_element("comment", comment)
1885
        cmd.add_element("scanner", scanner_id)
1886
        cmd.add_element("name", name)
1887
        cmd.add_element("usage_type", usage_type.value)
1888
        return self._send_xml_command(cmd)
1889
1890
    def __get_configs(
1891
        self,
1892
        usage_type: UsageType,
1893
        *,
1894
        filter: Optional[str] = None,
1895
        filter_id: Optional[str] = None,
1896
        trash: Optional[bool] = None,
1897
        details: Optional[bool] = None,
1898
        families: Optional[bool] = None,
1899
        preferences: Optional[bool] = None,
1900
        tasks: Optional[bool] = None,
1901
    ) -> Any:
1902
        cmd = XmlCommand("get_configs")
1903
        cmd.set_attribute("usage_type", usage_type.value)
1904
1905
        add_filter(cmd, filter, filter_id)
1906
1907
        if trash is not None:
1908
            cmd.set_attribute("trash", to_bool(trash))
1909
1910
        if details is not None:
1911
            cmd.set_attribute("details", to_bool(details))
1912
1913
        if families is not None:
1914
            cmd.set_attribute("families", to_bool(families))
1915
1916
        if preferences is not None:
1917
            cmd.set_attribute("preferences", to_bool(preferences))
1918
1919
        if tasks is not None:
1920
            cmd.set_attribute("tasks", to_bool(tasks))
1921
1922
        return self._send_xml_command(cmd)
1923
1924
    def __get_config(
1925
        self,
1926
        config_id: str,
1927
        usage_type: UsageType,
1928
        *,
1929
        tasks: Optional[bool] = None,
1930
    ) -> Any:
1931
        if not config_id:
1932
            raise RequiredArgument(
1933
                function=self.get_config.__name__, argument='config_id'
1934
            )
1935
1936
        cmd = XmlCommand("get_configs")
1937
        cmd.set_attribute("config_id", config_id)
1938
1939
        cmd.set_attribute("usage_type", usage_type.value)
1940
1941
        if tasks is not None:
1942
            cmd.set_attribute("tasks", to_bool(tasks))
1943
1944
        # for single entity always request all details
1945
        cmd.set_attribute("details", "1")
1946
1947
        return self._send_xml_command(cmd)
1948
1949
    def __get_tasks(
1950
        self,
1951
        usage_type: UsageType,
1952
        *,
1953
        filter: Optional[str] = None,
1954
        filter_id: Optional[str] = None,
1955
        trash: Optional[bool] = None,
1956
        details: Optional[bool] = None,
1957
        schedules_only: Optional[bool] = None,
1958
    ) -> Any:
1959
        cmd = XmlCommand("get_tasks")
1960
        cmd.set_attribute("usage_type", usage_type.value)
1961
1962
        add_filter(cmd, filter, filter_id)
1963
1964
        if trash is not None:
1965
            cmd.set_attribute("trash", to_bool(trash))
1966
1967
        if details is not None:
1968
            cmd.set_attribute("details", to_bool(details))
1969
1970
        if schedules_only is not None:
1971
            cmd.set_attribute("schedules_only", to_bool(schedules_only))
1972
1973
        return self._send_xml_command(cmd)
1974
1975
    def __get_task(self, task_id: str, usage_type: UsageType) -> Any:
1976
        if not task_id:
1977
            raise RequiredArgument(
1978
                function=self.get_task.__name__, argument='task_id'
1979
            )
1980
1981
        cmd = XmlCommand("get_tasks")
1982
        cmd.set_attribute("task_id", task_id)
1983
        cmd.set_attribute("usage_type", usage_type.value)
1984
1985
        # for single entity always request all details
1986
        cmd.set_attribute("details", "1")
1987
        return self._send_xml_command(cmd)
1988
1989
    def resume_audit(self, audit_id: str) -> Any:
1990
        """Resume an existing stopped audit
1991
1992
        Arguments:
1993
            audit_id: UUID of the audit to be resumed
1994
1995
        Returns:
1996
            The response. See :py:meth:`send_command` for details.
1997
        """
1998
        if not audit_id:
1999
            raise RequiredArgument(
2000
                function=self.resume_audit.__name__, argument='audit_id'
2001
            )
2002
2003
        cmd = XmlCommand("resume_task")
2004
        cmd.set_attribute("task_id", audit_id)
2005
2006
        return self._send_xml_command(cmd)
2007
2008
    def start_audit(self, audit_id: str) -> Any:
2009
        """Start an existing audit
2010
2011
        Arguments:
2012
            audit_id: UUID of the audit to be started
2013
2014
        Returns:
2015
            The response. See :py:meth:`send_command` for details.
2016
        """
2017
        if not audit_id:
2018
            raise RequiredArgument(
2019
                function=self.start_audit.__name__, argument='audit_id'
2020
            )
2021
2022
        cmd = XmlCommand("start_task")
2023
        cmd.set_attribute("task_id", audit_id)
2024
2025
        return self._send_xml_command(cmd)
2026
2027
    def stop_audit(self, audit_id: str) -> Any:
2028
        """Stop an existing running audit
2029
2030
        Arguments:
2031
            audit_id: UUID of the audit to be stopped
2032
2033
        Returns:
2034
            The response. See :py:meth:`send_command` for details.
2035
        """
2036
        if not audit_id:
2037
            raise RequiredArgument(
2038
                function=self.stop_audit.__name__, argument='audit_id'
2039
            )
2040
2041
        cmd = XmlCommand("stop_task")
2042
        cmd.set_attribute("task_id", audit_id)
2043
2044
        return self._send_xml_command(cmd)
2045
2046
    def get_feed(self, feed_type: Optional[FeedType]) -> Any:
2047
        """Request a single feed
2048
2049
        Arguments:
2050
            feed_type: Type of single feed to get: NVT, CERT or SCAP
2051
2052
        Returns:
2053
            The response. See :py:meth:`send_command` for details.
2054
        """
2055
        if not feed_type:
2056
            raise RequiredArgument(
2057
                function=self.get_feed.__name__, argument='feed_type'
2058
            )
2059
2060
        if not isinstance(feed_type, FeedType):
2061
            raise InvalidArgumentType(
2062
                function=self.get_feed.__name__,
2063
                argument='feed_type',
2064
                arg_type=FeedType.__name__,
2065
            )
2066
2067
        cmd = XmlCommand("get_feeds")
2068
        cmd.set_attribute("type", feed_type.value)
2069
2070
        return self._send_xml_command(cmd)
2071
2072
    def create_credential(
2073
        self,
2074
        name: str,
2075
        credential_type: CredentialType,
2076
        *,
2077
        comment: Optional[str] = None,
2078
        allow_insecure: Optional[bool] = None,
2079
        certificate: Optional[str] = None,
2080
        key_phrase: Optional[str] = None,
2081
        private_key: Optional[str] = None,
2082
        login: Optional[str] = None,
2083
        password: Optional[str] = None,
2084
        auth_algorithm: Optional[SnmpAuthAlgorithm] = None,
2085
        community: Optional[str] = None,
2086
        privacy_algorithm: Optional[SnmpPrivacyAlgorithm] = None,
2087
        privacy_password: Optional[str] = None,
2088
        public_key: Optional[str] = None,
2089
    ) -> Any:
2090
        """Create a new credential
2091
2092
        Create a new credential e.g. to be used in the method of an alert.
2093
2094
        Currently the following credential types are supported:
2095
2096
            - Username + Password
2097
            - Username + SSH-Key
2098
            - Client Certificates
2099
            - SNMPv1 or SNMPv2c protocol
2100
            - S/MIME Certificate
2101
            - OpenPGP Key
2102
            - Password only
2103
2104
        Arguments:
2105
            name: Name of the new credential
2106
            credential_type: The credential type.
2107
            comment: Comment for the credential
2108
            allow_insecure: Whether to allow insecure use of the credential
2109
            certificate: Certificate for the credential.
2110
                Required for client-certificate and smime credential types.
2111
            key_phrase: Key passphrase for the private key.
2112
                Used for the username+ssh-key credential type.
2113
            private_key: Private key to use for login. Required
2114
                for usk credential type. Also used for the cc credential type.
2115
                The supported key types (dsa, rsa, ecdsa, ...) and formats (PEM,
2116
                PKC#12, OpenSSL, ...) depend on your installed GnuTLS version.
2117
            login: Username for the credential. Required for username+password,
2118
                username+ssh-key and snmp credential type.
2119
            password: Password for the credential. Used for username+password
2120
                and snmp credential types.
2121
            community: The SNMP community
2122
            auth_algorithm: The SNMP authentication algorithm. Required for snmp
2123
                credential type.
2124
            privacy_algorithm: The SNMP privacy algorithm
2125
            privacy_password: The SNMP privacy password
2126
            public_key: PGP public key in *armor* plain text format. Required
2127
                for pgp credential type.
2128
2129
        Examples:
2130
            Creating a Username + Password credential
2131
2132
            .. code-block:: python
2133
2134
                gmp.create_credential(
2135
                    name='UP Credential',
2136
                    credential_type=CredentialType.USERNAME_PASSWORD,
2137
                    login='foo',
2138
                    password='bar',
2139
                )
2140
2141
            Creating a Username + SSH Key credential
2142
2143
            .. code-block:: python
2144
2145
                with open('path/to/private-ssh-key') as f:
2146
                    key = f.read()
2147
2148
                gmp.create_credential(
2149
                    name='USK Credential',
2150
                    credential_type=CredentialType.USERNAME_SSH_KEY,
2151
                    login='foo',
2152
                    key_phrase='foobar',
2153
                    private_key=key,
2154
                )
2155
2156
            Creating a PGP credential
2157
2158
            .. note::
2159
2160
                A compatible public pgp key file can be exported with GnuPG via
2161
                ::
2162
2163
                    $ gpg --armor --export [email protected] > alice.asc
2164
2165
            .. code-block:: python
2166
2167
                with open('path/to/pgp.key.asc') as f:
2168
                    key = f.read()
2169
2170
                gmp.create_credential(
2171
                    name='PGP Credential',
2172
                    credential_type=CredentialType.PGP_ENCRYPTION_KEY,
2173
                    public_key=key,
2174
                )
2175
2176
            Creating a S/MIME credential
2177
2178
            .. code-block:: python
2179
2180
                with open('path/to/smime-cert') as f:
2181
                    cert = f.read()
2182
2183
                gmp.create_credential(
2184
                    name='SMIME Credential',
2185
                    credential_type=CredentialType.SMIME_CERTIFICATE,
2186
                    certificate=cert,
2187
                )
2188
2189
            Creating a Password-Only credential
2190
2191
            .. code-block:: python
2192
2193
                gmp.create_credential(
2194
                    name='Password-Only Credential',
2195
                    credential_type=CredentialType.PASSWORD_ONLY,
2196
                    password='foo',
2197
                )
2198
        Returns:
2199
            The response. See :py:meth:`send_command` for details.
2200
        """
2201
        if not name:
2202
            raise RequiredArgument(
2203
                function=self.create_credential.__name__, argument='name'
2204
            )
2205
2206
        if not isinstance(credential_type, self.types.CredentialType):
2207
            raise InvalidArgumentType(
2208
                function=self.create_credential.__name__,
2209
                argument='credential_type',
2210
                arg_type=CredentialType.__name__,
2211
            )
2212
2213
        cmd = XmlCommand("create_credential")
2214
        cmd.add_element("name", name)
2215
2216
        cmd.add_element("type", credential_type.value)
2217
2218
        if comment:
2219
            cmd.add_element("comment", comment)
2220
2221
        if allow_insecure is not None:
2222
            cmd.add_element("allow_insecure", to_bool(allow_insecure))
2223
2224
        if (
2225
            credential_type == CredentialType.CLIENT_CERTIFICATE
2226
            or credential_type == CredentialType.SMIME_CERTIFICATE
2227
        ):
2228
            if not certificate:
2229
                raise RequiredArgument(
2230
                    function=self.create_credential.__name__,
2231
                    argument='certificate',
2232
                )
2233
2234
            cmd.add_element("certificate", certificate)
2235
2236
        if (
2237
            credential_type == CredentialType.USERNAME_PASSWORD
2238
            or credential_type == CredentialType.USERNAME_SSH_KEY
2239
            or credential_type == CredentialType.SNMP
2240
        ):
2241
            if not login:
2242
                raise RequiredArgument(
2243
                    function=self.create_credential.__name__, argument='login'
2244
                )
2245
2246
            cmd.add_element("login", login)
2247
2248
        if credential_type == CredentialType.PASSWORD_ONLY and not password:
2249
            raise RequiredArgument(
2250
                function=self.create_credential.__name__, argument='password'
2251
            )
2252
2253
        if (
2254
            credential_type == CredentialType.USERNAME_PASSWORD
2255
            or credential_type == CredentialType.SNMP
2256
            or credential_type == CredentialType.PASSWORD_ONLY
2257
        ) and password:
2258
            cmd.add_element("password", password)
2259
2260
        if credential_type == CredentialType.USERNAME_SSH_KEY:
2261
            if not private_key:
2262
                raise RequiredArgument(
2263
                    function=self.create_credential.__name__,
2264
                    argument='private_key',
2265
                )
2266
2267
            _xmlkey = cmd.add_element("key")
2268
            _xmlkey.add_element("private", private_key)
2269
2270
            if key_phrase:
2271
                _xmlkey.add_element("phrase", key_phrase)
2272
2273
        if credential_type == CredentialType.CLIENT_CERTIFICATE and private_key:
2274
            _xmlkey = cmd.add_element("key")
2275
            _xmlkey.add_element("private", private_key)
2276
2277
        if credential_type == CredentialType.SNMP:
2278
            if not isinstance(auth_algorithm, self.types.SnmpAuthAlgorithm):
2279
                raise InvalidArgumentType(
2280
                    function=self.create_credential.__name__,
2281
                    argument='auth_algorithm',
2282
                    arg_type=SnmpAuthAlgorithm.__name__,
2283
                )
2284
2285
            cmd.add_element("auth_algorithm", auth_algorithm.value)
2286
2287
            if community:
2288
                cmd.add_element("community", community)
2289
2290 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...
2291
                _xmlprivacy = cmd.add_element("privacy")
2292
2293
                if privacy_algorithm is not None:
2294
                    if not isinstance(
2295
                        privacy_algorithm, self.types.SnmpPrivacyAlgorithm
2296
                    ):
2297
                        raise InvalidArgumentType(
2298
                            function=self.create_credential.__name__,
2299
                            argument='privacy_algorithm',
2300
                            arg_type=SnmpPrivacyAlgorithm.__name__,
2301
                        )
2302
2303
                    _xmlprivacy.add_element(
2304
                        "algorithm", privacy_algorithm.value
2305
                    )
2306
2307
                if privacy_password:
2308
                    _xmlprivacy.add_element("password", privacy_password)
2309
2310
        if credential_type == CredentialType.PGP_ENCRYPTION_KEY:
2311
            if not public_key:
2312
                raise RequiredArgument(
2313
                    function=self.create_credential.__name__,
2314
                    argument='public_key',
2315
                )
2316
2317
            _xmlkey = cmd.add_element("key")
2318
            _xmlkey.add_element("public", public_key)
2319
2320
        return self._send_xml_command(cmd)
2321
2322
    def modify_credential(
2323
        self,
2324
        credential_id: str,
2325
        *,
2326
        name: Optional[str] = None,
2327
        comment: Optional[str] = None,
2328
        allow_insecure: Optional[bool] = None,
2329
        certificate: Optional[str] = None,
2330
        key_phrase: Optional[str] = None,
2331
        private_key: Optional[str] = None,
2332
        login: Optional[str] = None,
2333
        password: Optional[str] = None,
2334
        auth_algorithm: Optional[SnmpAuthAlgorithm] = None,
2335
        community: Optional[str] = None,
2336
        privacy_algorithm: Optional[SnmpPrivacyAlgorithm] = None,
2337
        privacy_password: Optional[str] = None,
2338
        public_key: Optional[str] = None,
2339
    ) -> Any:
2340
        """Modifies an existing credential.
2341
2342
        Arguments:
2343
            credential_id: UUID of the credential
2344
            name: Name of the credential
2345
            comment: Comment for the credential
2346
            allow_insecure: Whether to allow insecure use of the credential
2347
            certificate: Certificate for the credential
2348
            key_phrase: Key passphrase for the private key
2349
            private_key: Private key to use for login
2350
            login: Username for the credential
2351
            password: Password for the credential
2352
            auth_algorithm: The authentication algorithm for SNMP
2353
            community: The SNMP community
2354
            privacy_algorithm: The privacy algorithm for SNMP
2355
            privacy_password: The SNMP privacy password
2356
            public_key: PGP public key in *armor* plain text format
2357
2358
        Returns:
2359
            The response. See :py:meth:`send_command` for details.
2360
        """
2361
        if not credential_id:
2362
            raise RequiredArgument(
2363
                function=self.modify_credential.__name__,
2364
                argument='credential_id',
2365
            )
2366
2367
        cmd = XmlCommand("modify_credential")
2368
        cmd.set_attribute("credential_id", credential_id)
2369
2370
        if comment:
2371
            cmd.add_element("comment", comment)
2372
2373
        if name:
2374
            cmd.add_element("name", name)
2375
2376
        if allow_insecure is not None:
2377
            cmd.add_element("allow_insecure", to_bool(allow_insecure))
2378
2379
        if certificate:
2380
            cmd.add_element("certificate", certificate)
2381
2382
        if key_phrase and private_key:
2383
            _xmlkey = cmd.add_element("key")
2384
            _xmlkey.add_element("phrase", key_phrase)
2385
            _xmlkey.add_element("private", private_key)
2386
        elif (not key_phrase and private_key) or (
2387
            key_phrase and not private_key
2388
        ):
2389
            raise RequiredArgument(
2390
                function=self.modify_credential.__name__,
2391
                argument='key_phrase and private_key',
2392
            )
2393
2394
        if login:
2395
            cmd.add_element("login", login)
2396
2397
        if password:
2398
            cmd.add_element("password", password)
2399
2400
        if auth_algorithm:
2401
            if not isinstance(auth_algorithm, self.types.SnmpAuthAlgorithm):
2402
                raise InvalidArgumentType(
2403
                    function=self.modify_credential.__name__,
2404
                    argument='auth_algorithm',
2405
                    arg_type=SnmpAuthAlgorithm.__name__,
2406
                )
2407
            cmd.add_element("auth_algorithm", auth_algorithm.value)
2408
2409
        if community:
2410
            cmd.add_element("community", community)
2411
2412 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...
2413
            _xmlprivacy = cmd.add_element("privacy")
2414
2415
            if privacy_algorithm is not None:
2416
                if not isinstance(
2417
                    privacy_algorithm, self.types.SnmpPrivacyAlgorithm
2418
                ):
2419
                    raise InvalidArgumentType(
2420
                        function=self.modify_credential.__name__,
2421
                        argument='privacy_algorithm',
2422
                        arg_type=SnmpPrivacyAlgorithm.__name__,
2423
                    )
2424
2425
                _xmlprivacy.add_element("algorithm", privacy_algorithm.value)
2426
2427
            if privacy_password is not None:
2428
                _xmlprivacy.add_element("password", privacy_password)
2429
2430
        if public_key:
2431
            _xmlkey = cmd.add_element("key")
2432
            _xmlkey.add_element("public", public_key)
2433
2434
        return self._send_xml_command(cmd)
2435
2436
    def create_ticket(
2437
        self,
2438
        *,
2439
        result_id: str,
2440
        assigned_to_user_id: str,
2441
        note: str,
2442
        comment: Optional[str] = None,
2443
    ) -> Any:
2444
        """Create a new ticket
2445
2446
        Arguments:
2447
            result_id: UUID of the result the ticket applies to
2448
            assigned_to_user_id: UUID of a user the ticket should be assigned to
2449
            note: A note about opening the ticket
2450
            comment: Comment for the ticket
2451
2452
        Returns:
2453
            The response. See :py:meth:`send_command` for details.
2454
        """
2455
        if not result_id:
2456
            raise RequiredArgument(
2457
                function=self.create_ticket.__name__, argument='result_id'
2458
            )
2459
2460
        if not assigned_to_user_id:
2461
            raise RequiredArgument(
2462
                function=self.create_ticket.__name__,
2463
                argument='assigned_to_user_id',
2464
            )
2465
2466
        if not note:
2467
            raise RequiredArgument(
2468
                function=self.create_ticket.__name__, argument='note'
2469
            )
2470
2471
        cmd = XmlCommand("create_ticket")
2472
2473
        _result = cmd.add_element("result")
2474
        _result.set_attribute("id", result_id)
2475
2476
        _assigned = cmd.add_element("assigned_to")
2477
        _user = _assigned.add_element("user")
2478
        _user.set_attribute("id", assigned_to_user_id)
2479
2480
        _note = cmd.add_element("open_note", note)
2481
2482
        if comment:
2483
            cmd.add_element("comment", comment)
2484
2485
        return self._send_xml_command(cmd)
2486
2487
    def delete_ticket(
2488
        self, ticket_id: str, *, ultimate: Optional[bool] = False
2489
    ):
2490
        """Deletes an existing ticket
2491
2492
        Arguments:
2493
            ticket_id: UUID of the ticket to be deleted.
2494
            ultimate: Whether to remove entirely, or to the trashcan.
2495
        """
2496
        if not ticket_id:
2497
            raise RequiredArgument(
2498
                function=self.delete_ticket.__name__, argument='ticket_id'
2499
            )
2500
2501
        cmd = XmlCommand("delete_ticket")
2502
        cmd.set_attribute("ticket_id", ticket_id)
2503
        cmd.set_attribute("ultimate", to_bool(ultimate))
2504
2505
        return self._send_xml_command(cmd)
2506
2507 View Code Duplication
    def get_tickets(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2508
        self,
2509
        *,
2510
        trash: Optional[bool] = None,
2511
        filter: Optional[str] = None,
2512
        filter_id: Optional[str] = None,
2513
    ) -> Any:
2514
        """Request a list of tickets
2515
2516
        Arguments:
2517
            filter: Filter term to use for the query
2518
            filter_id: UUID of an existing filter to use for the query
2519
            trash: True to request the tickets in the trashcan
2520
2521
        Returns:
2522
            The response. See :py:meth:`send_command` for details.
2523
        """
2524
        cmd = XmlCommand("get_tickets")
2525
2526
        add_filter(cmd, filter, filter_id)
2527
2528
        if trash is not None:
2529
            cmd.set_attribute("trash", to_bool(trash))
2530
2531
        return self._send_xml_command(cmd)
2532
2533
    def get_ticket(self, ticket_id: str) -> Any:
2534
        """Request a single ticket
2535
2536
        Arguments:
2537
            ticket_id: UUID of an existing ticket
2538
2539
        Returns:
2540
            The response. See :py:meth:`send_command` for details.
2541
        """
2542
        if not ticket_id:
2543
            raise RequiredArgument(
2544
                function=self.get_ticket.__name__, argument='ticket_id'
2545
            )
2546
2547
        cmd = XmlCommand("get_tickets")
2548
        cmd.set_attribute("ticket_id", ticket_id)
2549
        return self._send_xml_command(cmd)
2550
2551
    def get_vulnerabilities(
2552
        self, *, filter: Optional[str] = None, filter_id: Optional[str] = None
2553
    ) -> Any:
2554
        """Request a list of vulnerabilities
2555
2556
        Arguments:
2557
            filter: Filter term to use for the query
2558
            filter_id: UUID of an existing filter to use for the query
2559
        Returns:
2560
            The response. See :py:meth:`send_command` for details.
2561
        """
2562
        cmd = XmlCommand("get_vulns")
2563
2564
        add_filter(cmd, filter, filter_id)
2565
2566
        return self._send_xml_command(cmd)
2567
2568
    def get_vulnerability(self, vulnerability_id: str) -> Any:
2569
        """Request a single vulnerability
2570
2571
        Arguments:
2572
            vulnerability_id: ID of an existing vulnerability
2573
2574
        Returns:
2575
            The response. See :py:meth:`send_command` for details.
2576
        """
2577
        if not vulnerability_id:
2578
            raise RequiredArgument(
2579
                function=self.get_vulnerability.__name__,
2580
                argument='vulnerability_id',
2581
            )
2582
2583
        cmd = XmlCommand("get_vulns")
2584
        cmd.set_attribute("vuln_id", vulnerability_id)
2585
        return self._send_xml_command(cmd)
2586
2587
    def modify_ticket(
2588
        self,
2589
        ticket_id: str,
2590
        *,
2591
        status: Optional[TicketStatus] = None,
2592
        note: Optional[str] = None,
2593
        assigned_to_user_id: Optional[str] = None,
2594
        comment: Optional[str] = None,
2595
    ) -> Any:
2596
        """Modify a single ticket
2597
2598
        Arguments:
2599
            ticket_id: UUID of an existing ticket
2600
            status: New status for the ticket
2601
            note: Note for the status change. Required if status is set.
2602
            assigned_to_user_id: UUID of the user the ticket should be assigned
2603
                to
2604
            comment: Comment for the ticket
2605
2606
        Returns:
2607
            The response. See :py:meth:`send_command` for details.
2608
        """
2609
        if not ticket_id:
2610
            raise RequiredArgument(
2611
                function=self.modify_ticket.__name__, argument='ticket_id'
2612
            )
2613
2614
        if status and not note:
2615
            raise RequiredArgument(
2616
                function=self.modify_ticket.__name__, argument='note'
2617
            )
2618
2619
        if note and not status:
2620
            raise RequiredArgument(
2621
                function=self.modify_ticket.__name__, argument='status'
2622
            )
2623
2624
        cmd = XmlCommand("modify_ticket")
2625
        cmd.set_attribute("ticket_id", ticket_id)
2626
2627
        if assigned_to_user_id:
2628
            _assigned = cmd.add_element("assigned_to")
2629
            _user = _assigned.add_element("user")
2630
            _user.set_attribute("id", assigned_to_user_id)
2631
2632
        if status:
2633
            if not isinstance(status, self.types.TicketStatus):
2634
                raise InvalidArgumentType(
2635
                    function=self.modify_ticket.__name__,
2636
                    argument='status',
2637
                    arg_type=TicketStatus.__name__,
2638
                )
2639
2640
            cmd.add_element('status', status.value)
2641
            cmd.add_element('{}_note'.format(status.name.lower()), note)
2642
2643
        if comment:
2644
            cmd.add_element("comment", comment)
2645
2646
        return self._send_xml_command(cmd)
2647
2648 View Code Duplication
    def create_filter(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2649
        self,
2650
        name: str,
2651
        *,
2652
        filter_type: Optional[FilterType] = None,
2653
        comment: Optional[str] = None,
2654
        term: Optional[str] = None,
2655
    ) -> Any:
2656
        """Create a new filter
2657
2658
        Arguments:
2659
            name: Name of the new filter
2660
            filter_type: Filter for entity type
2661
            comment: Comment for the filter
2662
            term: Filter term e.g. 'name=foo'
2663
2664
        Returns:
2665
            The response. See :py:meth:`send_command` for details.
2666
        """
2667
        if not name:
2668
            raise RequiredArgument(
2669
                function=self.create_filter.__name__, argument="name"
2670
            )
2671
2672
        cmd = XmlCommand("create_filter")
2673
        _xmlname = cmd.add_element("name", name)
2674
2675
        if comment:
2676
            cmd.add_element("comment", comment)
2677
2678
        if term:
2679
            cmd.add_element("term", term)
2680
2681
        if filter_type:
2682
            if not isinstance(filter_type, self.types.FilterType):
2683
                raise InvalidArgumentType(
2684
                    function=self.create_filter.__name__,
2685
                    argument="filter_type",
2686
                    arg_type=self.types.FilterType.__name__,
2687
                )
2688
2689
            cmd.add_element("type", filter_type.value)
2690
2691
        return self._send_xml_command(cmd)
2692
2693 View Code Duplication
    def modify_filter(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2694
        self,
2695
        filter_id: str,
2696
        *,
2697
        comment: Optional[str] = None,
2698
        name: Optional[str] = None,
2699
        term: Optional[str] = None,
2700
        filter_type: Optional[FilterType] = None,
2701
    ) -> Any:
2702
        """Modifies an existing filter.
2703
2704
        Arguments:
2705
            filter_id: UUID of the filter to be modified
2706
            comment: Comment on filter.
2707
            name: Name of filter.
2708
            term: Filter term.
2709
            filter_type: Resource type filter applies to.
2710
2711
        Returns:
2712
            The response. See :py:meth:`send_command` for details.
2713
        """
2714
        if not filter_id:
2715
            raise RequiredArgument(
2716
                function=self.modify_filter.__name__, argument='filter_id'
2717
            )
2718
2719
        cmd = XmlCommand("modify_filter")
2720
        cmd.set_attribute("filter_id", filter_id)
2721
2722
        if comment:
2723
            cmd.add_element("comment", comment)
2724
2725
        if name:
2726
            cmd.add_element("name", name)
2727
2728
        if term:
2729
            cmd.add_element("term", term)
2730
2731
        if filter_type:
2732
            if not isinstance(filter_type, self.types.FilterType):
2733
                raise InvalidArgumentType(
2734
                    function=self.modify_filter.__name__,
2735
                    argument='filter_type',
2736
                    arg_type=FilterType.__name__,
2737
                )
2738
            cmd.add_element("type", filter_type.value)
2739
2740
        return self._send_xml_command(cmd)
2741
2742
    def create_schedule(
2743
        self,
2744
        name: str,
2745
        icalendar: str,
2746
        timezone: str,
2747
        *,
2748
        comment: Optional[str] = None,
2749
    ) -> Any:
2750
        """Create a new schedule based in `iCalendar`_ data.
2751
2752
        Example:
2753
            Requires https://pypi.org/project/icalendar/
2754
2755
            .. code-block:: python
2756
2757
                import pytz
2758
2759
                from datetime import datetime
2760
2761
                from icalendar import Calendar, Event
2762
2763
                cal = Calendar()
2764
2765
                cal.add('prodid', '-//Foo Bar//')
2766
                cal.add('version', '2.0')
2767
2768
                event = Event()
2769
                event.add('dtstamp', datetime.now(tz=pytz.UTC))
2770
                event.add('dtstart', datetime(2020, 1, 1, tzinfo=pytz.utc))
2771
2772
                cal.add_component(event)
2773
2774
                gmp.create_schedule(
2775
                    name="My Schedule",
2776
                    icalendar=cal.to_ical(),
2777
                    timezone='UTC'
2778
                )
2779
2780
2781
        Arguments:
2782
            name: Name of the new schedule
2783
            icalendar: `iCalendar`_ (RFC 5545) based data.
2784
            timezone: Timezone to use for the icalender events e.g
2785
                Europe/Berlin. If the datetime values in the icalendar data are
2786
                missing timezone information this timezone gets applied.
2787
                Otherwise the datetime values from the icalendar data are
2788
                displayed in this timezone
2789
            comment: Comment on schedule.
2790
2791
        Returns:
2792
            The response. See :py:meth:`send_command` for details.
2793
2794
        .. _iCalendar:
2795
            https://tools.ietf.org/html/rfc5545
2796
        """
2797
        if not name:
2798
            raise RequiredArgument(
2799
                function=self.create_schedule.__name__, argument='name'
2800
            )
2801
        if not icalendar:
2802
            raise RequiredArgument(
2803
                function=self.create_schedule.__name__, argument='icalendar'
2804
            )
2805
        if not timezone:
2806
            raise RequiredArgument(
2807
                function=self.create_schedule.__name__, argument='timezone'
2808
            )
2809
2810
        cmd = XmlCommand("create_schedule")
2811
2812
        cmd.add_element("name", name)
2813
        cmd.add_element("icalendar", icalendar)
2814
        cmd.add_element("timezone", timezone)
2815
2816
        if comment:
2817
            cmd.add_element("comment", comment)
2818
2819
        return self._send_xml_command(cmd)
2820
2821
    def modify_schedule(
2822
        self,
2823
        schedule_id: str,
2824
        *,
2825
        name: Optional[str] = None,
2826
        icalendar: Optional[str] = None,
2827
        timezone: Optional[str] = None,
2828
        comment: Optional[str] = None,
2829
    ) -> Any:
2830
        """Modifies an existing schedule
2831
2832
        Arguments:
2833
            schedule_id: UUID of the schedule to be modified
2834
            name: Name of the schedule
2835
            icalendar: `iCalendar`_ (RFC 5545) based data.
2836
            timezone: Timezone to use for the icalender events e.g
2837
                Europe/Berlin. If the datetime values in the icalendar data are
2838
                missing timezone information this timezone gets applied.
2839
                Otherwise the datetime values from the icalendar data are
2840
                displayed in this timezone
2841
            commenhedule.
2842
2843
        Returns:
2844
            The response. See :py:meth:`send_command` for details.
2845
2846
        .. _iCalendar:
2847
            https://tools.ietf.org/html/rfc5545
2848
        """
2849
        if not schedule_id:
2850
            raise RequiredArgument(
2851
                function=self.modify_schedule.__name__, argument='schedule_id'
2852
            )
2853
2854
        cmd = XmlCommand("modify_schedule")
2855
        cmd.set_attribute("schedule_id", schedule_id)
2856
2857
        if name:
2858
            cmd.add_element("name", name)
2859
2860
        if icalendar:
2861
            cmd.add_element("icalendar", icalendar)
2862
2863
        if timezone:
2864
            cmd.add_element("timezone", timezone)
2865
2866
        if comment:
2867
            cmd.add_element("comment", comment)
2868
2869
        return self._send_xml_command(cmd)
2870
2871
    def clone_config(self, config_id: str) -> Any:
2872
        """Clone a scan config from an existing one
2873
2874
        Arguments:
2875
            config_id: UUID of the existing scan config
2876
2877
        Returns:
2878
            The response. See :py:meth:`send_command` for details.
2879
        """
2880
        if not config_id:
2881
            raise RequiredArgument(
2882
                function=self.clone_config.__name__, argument='config_id'
2883
            )
2884
2885
        cmd = XmlCommand("create_config")
2886
        cmd.add_element("copy", config_id)
2887
        return self._send_xml_command(cmd)
2888
2889
    def import_config(self, config: str) -> Any:
2890
        """Import a scan config from XML
2891
2892
        Arguments:
2893
            config: Scan Config XML as string to import. This XML must
2894
                contain a :code:`<get_configs_response>` root element.
2895
2896
        Returns:
2897
            The response. See :py:meth:`send_command` for details.
2898
        """
2899
        if not config:
2900
            raise RequiredArgument(
2901
                function=self.import_config.__name__, argument='config'
2902
            )
2903
2904
        cmd = XmlCommand("create_config")
2905
2906
        try:
2907
            cmd.append_xml_str(config)
2908
        except etree.XMLSyntaxError as e:
2909
            raise InvalidArgument(
2910
                function=self.import_config.__name__, argument='config'
2911
            ) from e
2912
2913
        return self._send_xml_command(cmd)
2914
2915
    def clone_credential(self, credential_id: str) -> Any:
2916
        """Clone an existing credential
2917
2918
        Arguments:
2919
            credential_id: UUID of an existing credential to clone from
2920
2921
        Returns:
2922
            The response. See :py:meth:`send_command` for details.
2923
        """
2924
        if not credential_id:
2925
            raise RequiredArgument(
2926
                function=self.clone_credential.__name__,
2927
                argument='credential_id',
2928
            )
2929
2930
        cmd = XmlCommand("create_credential")
2931
        cmd.add_element("copy", credential_id)
2932
        return self._send_xml_command(cmd)
2933
2934
    def clone_filter(self, filter_id: str) -> Any:
2935
        """Clone an existing filter
2936
2937
        Arguments:
2938
            filter_id: UUID of an existing filter to clone from
2939
2940
        Returns:
2941
            The response. See :py:meth:`send_command` for details.
2942
        """
2943
        if not filter_id:
2944
            raise RequiredArgument(
2945
                function=self.clone_filter.__name__, argument='filter_id'
2946
            )
2947
2948
        cmd = XmlCommand("create_filter")
2949
        cmd.add_element("copy", filter_id)
2950
        return self._send_xml_command(cmd)
2951
2952
    def create_group(
2953
        self,
2954
        name: str,
2955
        *,
2956
        comment: Optional[str] = None,
2957
        special: Optional[bool] = False,
2958
        users: Optional[List[str]] = None,
2959
    ) -> Any:
2960
        """Create a new group
2961
2962
        Arguments:
2963
            name: Name of the new group
2964
            comment: Comment for the group
2965
            special: Create permission giving members full access to each
2966
                other's entities
2967
            users: List of user names to be in the group
2968
2969
        Returns:
2970
            The response. See :py:meth:`send_command` for details.
2971
        """
2972
        if not name:
2973
            raise RequiredArgument(
2974
                function=self.create_group.__name__, argument='name'
2975
            )
2976
2977
        cmd = XmlCommand("create_group")
2978
        cmd.add_element("name", name)
2979
2980
        if comment:
2981
            cmd.add_element("comment", comment)
2982
2983
        if special:
2984
            _xmlspecial = cmd.add_element("specials")
2985
            _xmlspecial.add_element("full")
2986
2987
        if users:
2988
            cmd.add_element("users", to_comma_list(users))
2989
2990
        return self._send_xml_command(cmd)
2991
2992
    def clone_group(self, group_id: str) -> Any:
2993
        """Clone an existing group
2994
2995
        Arguments:
2996
            group_id: UUID of an existing group to clone from
2997
2998
        Returns:
2999
            The response. See :py:meth:`send_command` for details.
3000
        """
3001
        if not group_id:
3002
            raise RequiredArgument(
3003
                function=self.clone_group.__name__, argument='group_id'
3004
            )
3005
3006
        cmd = XmlCommand("create_group")
3007
        cmd.add_element("copy", group_id)
3008
        return self._send_xml_command(cmd)
3009
3010
    def create_host(self, name: str, *, comment: Optional[str] = None) -> Any:
3011
        """Create a new host asset
3012
3013
        Arguments:
3014
            name: Name for the new host asset
3015
            comment: Comment for the new host asset
3016
3017
        Returns:
3018
            The response. See :py:meth:`send_command` for details.
3019
        """
3020
        if not name:
3021
            raise RequiredArgument(
3022
                function=self.create_host.__name__, argument='name'
3023
            )
3024
3025
        cmd = XmlCommand("create_asset")
3026
        asset = cmd.add_element("asset")
3027
        asset.add_element("type", "host")  # ignored for gmp7, required for gmp8
3028
        asset.add_element("name", name)
3029
3030
        if comment:
3031
            asset.add_element("comment", comment)
3032
3033
        return self._send_xml_command(cmd)
3034
3035
    def clone_permission(self, permission_id: str) -> Any:
3036
        """Clone an existing permission
3037
3038
        Arguments:
3039
            permission_id: UUID of an existing permission to clone from
3040
3041
        Returns:
3042
            The response. See :py:meth:`send_command` for details.
3043
        """
3044
        if not permission_id:
3045
            raise RequiredArgument(
3046
                function=self.clone_permission.__name__,
3047
                argument='permission_id',
3048
            )
3049
3050
        cmd = XmlCommand("create_permission")
3051
        cmd.add_element("copy", permission_id)
3052
        return self._send_xml_command(cmd)
3053
3054
    def clone_report_format(
3055
        self, report_format_id: [Union[str, ReportFormatType]]
3056
    ) -> Any:
3057
        """Clone a report format from an existing one
3058
3059
        Arguments:
3060
            report_format_id: UUID of the existing report format
3061
                              or ReportFormatType (enum)
3062
3063
        Returns:
3064
            The response. See :py:meth:`send_command` for details.
3065
        """
3066
        if not report_format_id:
3067
            raise RequiredArgument(
3068
                function=self.clone_report_format.__name__,
3069
                argument='report_format_id',
3070
            )
3071
3072
        cmd = XmlCommand("create_report_format")
3073
3074
        if isinstance(report_format_id, ReportFormatType):
3075
            report_format_id = report_format_id.value
3076
3077
        cmd.add_element("copy", report_format_id)
3078
        return self._send_xml_command(cmd)
3079
3080
    def import_report_format(self, report_format: str) -> Any:
3081
        """Import a report format from XML
3082
3083
        Arguments:
3084
            report_format: Report format XML as string to import. This XML must
3085
                contain a :code:`<get_report_formats_response>` root element.
3086
3087
        Returns:
3088
            The response. See :py:meth:`send_command` for details.
3089
        """
3090
        if not report_format:
3091
            raise RequiredArgument(
3092
                function=self.import_report_format.__name__,
3093
                argument='report_format',
3094
            )
3095
3096
        cmd = XmlCommand("create_report_format")
3097
3098
        try:
3099
            cmd.append_xml_str(report_format)
3100
        except etree.XMLSyntaxError as e:
3101
            raise InvalidArgument(
3102
                function=self.import_report_format.__name__,
3103
                argument='report_format',
3104
            ) from e
3105
3106
        return self._send_xml_command(cmd)
3107
3108
    def create_role(
3109
        self,
3110
        name: str,
3111
        *,
3112
        comment: Optional[str] = None,
3113
        users: Optional[List[str]] = None,
3114
    ) -> Any:
3115
        """Create a new role
3116
3117
        Arguments:
3118
            name: Name of the role
3119
            comment: Comment for the role
3120
            users: List of user names to add to the role
3121
3122
        Returns:
3123
            The response. See :py:meth:`send_command` for details.
3124
        """
3125
3126
        if not name:
3127
            raise RequiredArgument(
3128
                function=self.create_role.__name__, argument='name'
3129
            )
3130
3131
        cmd = XmlCommand("create_role")
3132
        cmd.add_element("name", name)
3133
3134
        if comment:
3135
            cmd.add_element("comment", comment)
3136
3137
        if users:
3138
            cmd.add_element("users", to_comma_list(users))
3139
3140
        return self._send_xml_command(cmd)
3141
3142
    def clone_role(self, role_id: str) -> Any:
3143
        """Clone an existing role
3144
3145
        Arguments:
3146
            role_id: UUID of an existing role to clone from
3147
3148
        Returns:
3149
            The response. See :py:meth:`send_command` for details.
3150
        """
3151
        if not role_id:
3152
            raise RequiredArgument(
3153
                function=self.clone_role.__name__, argument='role_id'
3154
            )
3155
3156
        cmd = XmlCommand("create_role")
3157
        cmd.add_element("copy", role_id)
3158
        return self._send_xml_command(cmd)
3159
3160
    def create_scanner(
3161
        self,
3162
        name: str,
3163
        host: str,
3164
        port: int,
3165
        scanner_type: ScannerType,
3166
        credential_id: str,
3167
        *,
3168
        ca_pub: Optional[str] = None,
3169
        comment: Optional[str] = None,
3170
    ) -> Any:
3171
        """Create a new scanner
3172
3173
        Arguments:
3174
            name: Name of the scanner
3175
            host: The host of the scanner
3176
            port: The port of the scanner
3177
            scanner_type: Type of the scanner.
3178
            credential_id: UUID of client certificate credential for the
3179
                scanner
3180
            ca_pub: Certificate of CA to verify scanner certificate
3181
            comment: Comment for the scanner
3182
        Returns:
3183
            The response. See :py:meth:`send_command` for details.
3184
        """
3185
        if not name:
3186
            raise RequiredArgument(
3187
                function=self.create_scanner.__name__, argument='name'
3188
            )
3189
3190
        if not host:
3191
            raise RequiredArgument(
3192
                function=self.create_scanner.__name__, argument='host'
3193
            )
3194
3195
        if not port:
3196
            raise RequiredArgument(
3197
                function=self.create_scanner.__name__, argument='port'
3198
            )
3199
3200
        if not scanner_type:
3201
            raise RequiredArgument(
3202
                function=self.create_scanner.__name__, argument='scanner_type'
3203
            )
3204
3205
        if not credential_id:
3206
            raise RequiredArgument(
3207
                function=self.create_scanner.__name__, argument='credential_id'
3208
            )
3209
3210
        if not isinstance(scanner_type, self.types.ScannerType):
3211
            raise InvalidArgumentType(
3212
                function=self.create_scanner.__name__,
3213
                argument='scanner_type',
3214
                arg_type=self.types.ScannerType.__name__,
3215
            )
3216
3217
        cmd = XmlCommand("create_scanner")
3218
        cmd.add_element("name", name)
3219
        cmd.add_element("host", host)
3220
        cmd.add_element("port", str(port))
3221
        cmd.add_element("type", scanner_type.value)
3222
3223
        if ca_pub:
3224
            cmd.add_element("ca_pub", ca_pub)
3225
3226
        cmd.add_element("credential", attrs={"id": str(credential_id)})
3227
3228
        if comment:
3229
            cmd.add_element("comment", comment)
3230
3231
        return self._send_xml_command(cmd)
3232
3233
    def clone_scanner(self, scanner_id: str) -> Any:
3234
        """Clone an existing scanner
3235
3236
        Arguments:
3237
            scanner_id: UUID of an existing scanner to clone from
3238
3239
        Returns:
3240
            The response. See :py:meth:`send_command` for details.
3241
        """
3242
        if not scanner_id:
3243
            raise RequiredArgument(
3244
                function=self.clone_scanner.__name__, argument='scanner_id'
3245
            )
3246
3247
        cmd = XmlCommand("create_scanner")
3248
        cmd.add_element("copy", scanner_id)
3249
        return self._send_xml_command(cmd)
3250
3251
    def clone_schedule(self, schedule_id: str) -> Any:
3252
        """Clone an existing schedule
3253
3254
        Arguments:
3255
            schedule_id: UUID of an existing schedule to clone from
3256
3257
        Returns:
3258
            The response. See :py:meth:`send_command` for details.
3259
        """
3260
        if not schedule_id:
3261
            raise RequiredArgument(
3262
                function=self.clone_schedule.__name__, argument='schedule_id'
3263
            )
3264
3265
        cmd = XmlCommand("create_schedule")
3266
        cmd.add_element("copy", schedule_id)
3267
        return self._send_xml_command(cmd)
3268
3269
    def clone_tag(self, tag_id: str) -> Any:
3270
        """Clone an existing tag
3271
3272
        Arguments:
3273
            tag_id: UUID of an existing tag to clone from
3274
3275
        Returns:
3276
            The response. See :py:meth:`send_command` for details.
3277
        """
3278
        if not tag_id:
3279
            raise RequiredArgument(
3280
                function=self.clone_tag.__name__, argument='tag_id'
3281
            )
3282
3283
        cmd = XmlCommand("create_tag")
3284
        cmd.add_element("copy", tag_id)
3285
        return self._send_xml_command(cmd)
3286
3287
    def create_user(
3288
        self,
3289
        name: str,
3290
        *,
3291
        password: Optional[str] = None,
3292
        hosts: Optional[List[str]] = None,
3293
        hosts_allow: Optional[bool] = False,
3294
        ifaces: Optional[List[str]] = None,
3295
        ifaces_allow: Optional[bool] = False,
3296
        role_ids: Optional[List[str]] = None,
3297
    ) -> Any:
3298
        """Create a new user
3299
3300
        Arguments:
3301
            name: Name of the user
3302
            password: Password of the user
3303
            hosts: A list of host addresses (IPs, DNS names)
3304
            hosts_allow: If True allow only access to passed hosts otherwise
3305
                deny access. Default is False for deny hosts.
3306
            ifaces: A list of interface names
3307
            ifaces_allow: If True allow only access to passed interfaces
3308
                otherwise deny access. Default is False for deny interfaces.
3309
            role_ids: A list of role UUIDs for the user
3310
3311
        Returns:
3312
            The response. See :py:meth:`send_command` for details.
3313
        """
3314
        if not name:
3315
            raise RequiredArgument(
3316
                function=self.create_user.__name__, argument='name'
3317
            )
3318
3319
        cmd = XmlCommand("create_user")
3320
        cmd.add_element("name", name)
3321
3322
        if password:
3323
            cmd.add_element("password", password)
3324
3325
        if hosts:
3326
            cmd.add_element(
3327
                "hosts",
3328
                to_comma_list(hosts),
3329
                attrs={"allow": to_bool(hosts_allow)},
3330
            )
3331
3332
        if ifaces:
3333
            cmd.add_element(
3334
                "ifaces",
3335
                to_comma_list(ifaces),
3336
                attrs={"allow": to_bool(ifaces_allow)},
3337
            )
3338
3339
        if role_ids:
3340
            for role in role_ids:
3341
                cmd.add_element("role", attrs={"id": role})
3342
3343
        return self._send_xml_command(cmd)
3344
3345
    def clone_user(self, user_id: str) -> Any:
3346
        """Clone an existing user
3347
3348
        Arguments:
3349
            user_id: UUID of existing user to clone from
3350
3351
        Returns:
3352
            The response. See :py:meth:`send_command` for details.
3353
        """
3354
        if not user_id:
3355
            raise RequiredArgument(
3356
                function=self.clone_user.__name__, argument='user_id'
3357
            )
3358
3359
        cmd = XmlCommand("create_user")
3360
        cmd.add_element("copy", user_id)
3361
        return self._send_xml_command(cmd)
3362
3363
    def delete_alert(
3364
        self, alert_id: str, *, ultimate: Optional[bool] = False
3365
    ) -> Any:
3366
        """Deletes an existing alert
3367
3368
        Arguments:
3369
            alert_id: UUID of the alert to be deleted.
3370
            ultimate: Whether to remove entirely, or to the trashcan.
3371
        """
3372
        if not alert_id:
3373
            raise RequiredArgument(
3374
                function=self.delete_alert.__name__, argument='alert_id'
3375
            )
3376
3377
        cmd = XmlCommand("delete_alert")
3378
        cmd.set_attribute("alert_id", alert_id)
3379
        cmd.set_attribute("ultimate", to_bool(ultimate))
3380
3381
        return self._send_xml_command(cmd)
3382
3383
    def delete_asset(
3384
        self, *, asset_id: Optional[str] = None, report_id: Optional[str] = None
3385
    ) -> Any:
3386
        """Deletes an existing asset
3387
3388
        Arguments:
3389
            asset_id: UUID of the single asset to delete.
3390
            report_id: UUID of report from which to get all
3391
                assets to delete.
3392
        """
3393
        if not asset_id and not report_id:
3394
            raise RequiredArgument(
3395
                function=self.delete_asset.__name__,
3396
                argument='asset_id or report_id',
3397
            )
3398
3399
        cmd = XmlCommand("delete_asset")
3400
        if asset_id:
3401
            cmd.set_attribute("asset_id", asset_id)
3402
        else:
3403
            cmd.set_attribute("report_id", report_id)
3404
3405
        return self._send_xml_command(cmd)
3406
3407
    def delete_config(
3408
        self, config_id: str, *, ultimate: Optional[bool] = False
3409
    ) -> Any:
3410
        """Deletes an existing config
3411
3412
        Arguments:
3413
            config_id: UUID of the config to be deleted.
3414
            ultimate: Whether to remove entirely, or to the trashcan.
3415
        """
3416
        if not config_id:
3417
            raise RequiredArgument(
3418
                function=self.delete_config.__name__, argument='config_id'
3419
            )
3420
3421
        cmd = XmlCommand("delete_config")
3422
        cmd.set_attribute("config_id", config_id)
3423
        cmd.set_attribute("ultimate", to_bool(ultimate))
3424
3425
        return self._send_xml_command(cmd)
3426
3427
    def delete_credential(
3428
        self, credential_id: str, *, ultimate: Optional[bool] = False
3429
    ) -> Any:
3430
        """Deletes an existing credential
3431
3432
        Arguments:
3433
            credential_id: UUID of the credential to be deleted.
3434
            ultimate: Whether to remove entirely, or to the trashcan.
3435
        """
3436
        if not credential_id:
3437
            raise RequiredArgument(
3438
                function=self.delete_credential.__name__,
3439
                argument='credential_id',
3440
            )
3441
3442
        cmd = XmlCommand("delete_credential")
3443
        cmd.set_attribute("credential_id", credential_id)
3444
        cmd.set_attribute("ultimate", to_bool(ultimate))
3445
3446
        return self._send_xml_command(cmd)
3447
3448
    def delete_filter(
3449
        self, filter_id: str, *, ultimate: Optional[bool] = False
3450
    ) -> Any:
3451
        """Deletes an existing filter
3452
3453
        Arguments:
3454
            filter_id: UUID of the filter to be deleted.
3455
            ultimate: Whether to remove entirely, or to the trashcan.
3456
        """
3457
        if not filter_id:
3458
            raise RequiredArgument(
3459
                function=self.delete_filter.__name__, argument='filter_id'
3460
            )
3461
3462
        cmd = XmlCommand("delete_filter")
3463
        cmd.set_attribute("filter_id", filter_id)
3464
        cmd.set_attribute("ultimate", to_bool(ultimate))
3465
3466
        return self._send_xml_command(cmd)
3467
3468
    def delete_group(
3469
        self, group_id: str, *, ultimate: Optional[bool] = False
3470
    ) -> Any:
3471
        """Deletes an existing group
3472
3473
        Arguments:
3474
            group_id: UUID of the group to be deleted.
3475
            ultimate: Whether to remove entirely, or to the trashcan.
3476
        """
3477
        if not group_id:
3478
            raise RequiredArgument(
3479
                function=self.delete_group.__name__, argument='group_id'
3480
            )
3481
3482
        cmd = XmlCommand("delete_group")
3483
        cmd.set_attribute("group_id", group_id)
3484
        cmd.set_attribute("ultimate", to_bool(ultimate))
3485
3486
        return self._send_xml_command(cmd)
3487
3488
    def delete_permission(
3489
        self, permission_id: str, *, ultimate: Optional[bool] = False
3490
    ) -> Any:
3491
        """Deletes an existing permission
3492
3493
        Arguments:
3494
            permission_id: UUID of the permission to be deleted.
3495
            ultimate: Whether to remove entirely, or to the trashcan.
3496
        """
3497
        if not permission_id:
3498
            raise RequiredArgument(
3499
                function=self.delete_permission.__name__,
3500
                argument='permission_id',
3501
            )
3502
3503
        cmd = XmlCommand("delete_permission")
3504
        cmd.set_attribute("permission_id", permission_id)
3505
        cmd.set_attribute("ultimate", to_bool(ultimate))
3506
3507
        return self._send_xml_command(cmd)
3508
3509
    def delete_report_format(
3510
        self,
3511
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
3512
        *,
3513
        ultimate: Optional[bool] = False,
3514
    ) -> Any:
3515
        """Deletes an existing report format
3516
3517
        Arguments:
3518
            report_format_id: UUID of the report format to be deleted.
3519
                              or ReportFormatType (enum)
3520
            ultimate: Whether to remove entirely, or to the trashcan.
3521
        """
3522
        if not report_format_id:
3523
            raise RequiredArgument(
3524
                function=self.delete_report_format.__name__,
3525
                argument='report_format_id',
3526
            )
3527
3528
        cmd = XmlCommand("delete_report_format")
3529
3530
        if isinstance(report_format_id, ReportFormatType):
3531
            report_format_id = report_format_id.value
3532
3533
        cmd.set_attribute("report_format_id", report_format_id)
3534
3535
        cmd.set_attribute("ultimate", to_bool(ultimate))
3536
3537
        return self._send_xml_command(cmd)
3538
3539
    def delete_role(
3540
        self, role_id: str, *, ultimate: Optional[bool] = False
3541
    ) -> Any:
3542
        """Deletes an existing role
3543
3544
        Arguments:
3545
            role_id: UUID of the role to be deleted.
3546
            ultimate: Whether to remove entirely, or to the trashcan.
3547
        """
3548
        if not role_id:
3549
            raise RequiredArgument(
3550
                function=self.delete_role.__name__, argument='role_id'
3551
            )
3552
3553
        cmd = XmlCommand("delete_role")
3554
        cmd.set_attribute("role_id", role_id)
3555
        cmd.set_attribute("ultimate", to_bool(ultimate))
3556
3557
        return self._send_xml_command(cmd)
3558
3559
    def delete_scanner(
3560
        self, scanner_id: str, *, ultimate: Optional[bool] = False
3561
    ) -> Any:
3562
        """Deletes an existing scanner
3563
3564
        Arguments:
3565
            scanner_id: UUID of the scanner to be deleted.
3566
            ultimate: Whether to remove entirely, or to the trashcan.
3567
        """
3568
        if not scanner_id:
3569
            raise RequiredArgument(
3570
                function=self.delete_scanner.__name__, argument='scanner_id'
3571
            )
3572
3573
        cmd = XmlCommand("delete_scanner")
3574
        cmd.set_attribute("scanner_id", scanner_id)
3575
        cmd.set_attribute("ultimate", to_bool(ultimate))
3576
3577
        return self._send_xml_command(cmd)
3578
3579
    def delete_schedule(
3580
        self, schedule_id: str, *, ultimate: Optional[bool] = False
3581
    ) -> Any:
3582
        """Deletes an existing schedule
3583
3584
        Arguments:
3585
            schedule_id: UUID of the schedule to be deleted.
3586
            ultimate: Whether to remove entirely, or to the trashcan.
3587
        """
3588
        if not schedule_id:
3589
            raise RequiredArgument(
3590
                function=self.delete_schedule.__name__, argument='schedule_id'
3591
            )
3592
3593
        cmd = XmlCommand("delete_schedule")
3594
        cmd.set_attribute("schedule_id", schedule_id)
3595
        cmd.set_attribute("ultimate", to_bool(ultimate))
3596
3597
        return self._send_xml_command(cmd)
3598
3599
    def delete_tag(
3600
        self, tag_id: str, *, ultimate: Optional[bool] = False
3601
    ) -> Any:
3602
        """Deletes an existing tag
3603
3604
        Arguments:
3605
            tag_id: UUID of the tag to be deleted.
3606
            ultimate: Whether to remove entirely, or to the trashcan.
3607
        """
3608
        if not tag_id:
3609
            raise RequiredArgument(
3610
                function=self.delete_tag.__name__, argument='tag_id'
3611
            )
3612
3613
        cmd = XmlCommand("delete_tag")
3614
        cmd.set_attribute("tag_id", tag_id)
3615
        cmd.set_attribute("ultimate", to_bool(ultimate))
3616
3617
        return self._send_xml_command(cmd)
3618
3619
    def delete_user(
3620
        self,
3621
        user_id: str = None,
3622
        *,
3623
        name: Optional[str] = None,
3624
        inheritor_id: Optional[str] = None,
3625
        inheritor_name: Optional[str] = None,
3626
    ) -> Any:
3627
        """Deletes an existing user
3628
3629
        Either user_id or name must be passed.
3630
3631
        Arguments:
3632
            user_id: UUID of the task to be deleted.
3633
            name: The name of the user to be deleted.
3634
            inheritor_id: The ID of the inheriting user or "self". Overrides
3635
                inheritor_name.
3636
            inheritor_name: The name of the inheriting user.
3637
3638
        """
3639
        if not user_id and not name:
3640
            raise RequiredArgument(
3641
                function=self.delete_user.__name__, argument='user_id or name'
3642
            )
3643
3644
        cmd = XmlCommand("delete_user")
3645
3646
        if user_id:
3647
            cmd.set_attribute("user_id", user_id)
3648
3649
        if name:
3650
            cmd.set_attribute("name", name)
3651
3652
        if inheritor_id:
3653
            cmd.set_attribute("inheritor_id", inheritor_id)
3654
        if inheritor_name:
3655
            cmd.set_attribute("inheritor_name", inheritor_name)
3656
3657
        return self._send_xml_command(cmd)
3658
3659
    def describe_auth(self) -> Any:
3660
        """Describe authentication methods
3661
3662
        Returns a list of all used authentication methods if such a list is
3663
        available.
3664
3665
        Returns:
3666
            The response. See :py:meth:`send_command` for details.
3667
        """
3668
        return self._send_xml_command(XmlCommand("describe_auth"))
3669
3670
    def empty_trashcan(self) -> Any:
3671
        """Empty the trashcan
3672
3673
        Remove all entities from the trashcan. **Attention:** this command can
3674
        not be reverted
3675
3676
        Returns:
3677
            The response. See :py:meth:`send_command` for details.
3678
        """
3679
        return self._send_xml_command(XmlCommand("empty_trashcan"))
3680
3681
    def get_alerts(
3682
        self,
3683
        *,
3684
        filter: Optional[str] = None,
3685
        filter_id: Optional[str] = None,
3686
        trash: Optional[bool] = None,
3687
        tasks: Optional[bool] = None,
3688
    ) -> Any:
3689
        """Request a list of alerts
3690
3691
        Arguments:
3692
            filter: Filter term to use for the query
3693
            filter_id: UUID of an existing filter to use for the query
3694
            trash: True to request the alerts in the trashcan
3695
            tasks: Whether to include the tasks using the alerts
3696
        Returns:
3697
            The response. See :py:meth:`send_command` for details.
3698
        """
3699
        cmd = XmlCommand("get_alerts")
3700
3701
        add_filter(cmd, filter, filter_id)
3702
3703
        if trash is not None:
3704
            cmd.set_attribute("trash", to_bool(trash))
3705
3706
        if tasks is not None:
3707
            cmd.set_attribute("tasks", to_bool(tasks))
3708
3709
        return self._send_xml_command(cmd)
3710
3711
    def get_alert(self, alert_id: str, *, tasks: Optional[bool] = None) -> Any:
3712
        """Request a single alert
3713
3714
        Arguments:
3715
            alert_id: UUID of an existing alert
3716
3717
        Returns:
3718
            The response. See :py:meth:`send_command` for details.
3719
        """
3720
        cmd = XmlCommand("get_alerts")
3721
3722
        if not alert_id:
3723
            raise RequiredArgument(
3724
                function=self.get_alert.__name__, argument='alert_id'
3725
            )
3726
3727
        cmd.set_attribute("alert_id", alert_id)
3728
3729
        if tasks is not None:
3730
            cmd.set_attribute("tasks", to_bool(tasks))
3731
3732
        return self._send_xml_command(cmd)
3733
3734
    def get_assets(
3735
        self,
3736
        asset_type: AssetType,
3737
        *,
3738
        filter: Optional[str] = None,
3739
        filter_id: Optional[str] = None,
3740
    ) -> Any:
3741
        """Request a list of assets
3742
3743
        Arguments:
3744
            asset_type: Either 'os' or 'host'
3745
            filter: Filter term to use for the query
3746
            filter_id: UUID of an existing filter to use for the query
3747
3748
        Returns:
3749
            The response. See :py:meth:`send_command` for details.
3750
        """
3751
        if not isinstance(asset_type, AssetType):
3752
            raise InvalidArgumentType(
3753
                function=self.get_assets.__name__,
3754
                argument='asset_type',
3755
                arg_type=AssetType.__name__,
3756
            )
3757
3758
        cmd = XmlCommand("get_assets")
3759
3760
        cmd.set_attribute("type", asset_type.value)
3761
3762
        add_filter(cmd, filter, filter_id)
3763
3764
        return self._send_xml_command(cmd)
3765
3766
    def get_asset(self, asset_id: str, asset_type: AssetType) -> Any:
3767
        """Request a single asset
3768
3769
        Arguments:
3770
            asset_id: UUID of an existing asset
3771
            asset_type: Either 'os' or 'host'
3772
3773
        Returns:
3774
            The response. See :py:meth:`send_command` for details.
3775
        """
3776
        cmd = XmlCommand("get_assets")
3777
3778
        if not isinstance(asset_type, AssetType):
3779
            raise InvalidArgumentType(
3780
                function=self.get_asset.__name__,
3781
                argument='asset_type',
3782
                arg_type=AssetType.__name__,
3783
            )
3784
3785
        if not asset_id:
3786
            raise RequiredArgument(
3787
                function=self.get_asset.__name__, argument='asset_id'
3788
            )
3789
3790
        cmd.set_attribute("asset_id", asset_id)
3791
        cmd.set_attribute("type", asset_type.value)
3792
3793
        return self._send_xml_command(cmd)
3794
3795 View Code Duplication
    def get_credentials(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3796
        self,
3797
        *,
3798
        filter: Optional[str] = None,
3799
        filter_id: Optional[str] = None,
3800
        scanners: Optional[bool] = None,
3801
        trash: Optional[bool] = None,
3802
        targets: Optional[bool] = None,
3803
    ) -> Any:
3804
        """Request a list of credentials
3805
3806
        Arguments:
3807
            filter: Filter term to use for the query
3808
            filter_id: UUID of an existing filter to use for the query
3809
            scanners: Whether to include a list of scanners using the
3810
                credentials
3811
            trash: Whether to get the trashcan credentials instead
3812
            targets: Whether to include a list of targets using the credentials
3813
3814
        Returns:
3815
            The response. See :py:meth:`send_command` for details.
3816
        """
3817
        cmd = XmlCommand("get_credentials")
3818
3819
        add_filter(cmd, filter, filter_id)
3820
3821
        if scanners is not None:
3822
            cmd.set_attribute("scanners", to_bool(scanners))
3823
3824
        if trash is not None:
3825
            cmd.set_attribute("trash", to_bool(trash))
3826
3827
        if targets is not None:
3828
            cmd.set_attribute("targets", to_bool(targets))
3829
3830
        return self._send_xml_command(cmd)
3831
3832
    def get_credential(
3833
        self,
3834
        credential_id: str,
3835
        *,
3836
        scanners: Optional[bool] = None,
3837
        targets: Optional[bool] = None,
3838
        credential_format: Optional[CredentialFormat] = None,
3839
    ) -> Any:
3840
        """Request a single credential
3841
3842
        Arguments:
3843
            credential_id: UUID of an existing credential
3844
            scanners: Whether to include a list of scanners using the
3845
                credentials
3846
            targets: Whether to include a list of targets using the credentials
3847
            credential_format: One of "key", "rpm", "deb", "exe" or "pem"
3848
3849
        Returns:
3850
            The response. See :py:meth:`send_command` for details.
3851
        """
3852
        if not credential_id:
3853
            raise RequiredArgument(
3854
                function=self.get_credential.__name__, argument='credential_id'
3855
            )
3856
3857
        cmd = XmlCommand("get_credentials")
3858
        cmd.set_attribute("credential_id", credential_id)
3859
3860
        if credential_format:
3861
            if not isinstance(credential_format, CredentialFormat):
3862
                raise InvalidArgumentType(
3863
                    function=self.get_credential.__name__,
3864
                    argument='credential_format',
3865
                    arg_type=CredentialFormat.__name__,
3866
                )
3867
3868
            cmd.set_attribute("format", credential_format.value)
3869
3870
        if scanners is not None:
3871
            cmd.set_attribute("scanners", to_bool(scanners))
3872
3873
        if targets is not None:
3874
            cmd.set_attribute("targets", to_bool(targets))
3875
3876
        return self._send_xml_command(cmd)
3877
3878
    def get_feeds(self) -> Any:
3879
        """Request the list of feeds
3880
3881
        Returns:
3882
            The response. See :py:meth:`send_command` for details.
3883
        """
3884
        return self._send_xml_command(XmlCommand("get_feeds"))
3885
3886
    def get_filters(
3887
        self,
3888
        *,
3889
        filter: Optional[str] = None,
3890
        filter_id: Optional[str] = None,
3891
        trash: Optional[bool] = None,
3892
        alerts: Optional[bool] = None,
3893
    ) -> Any:
3894
        """Request a list of filters
3895
3896
        Arguments:
3897
            filter: Filter term to use for the query
3898
            filter_id: UUID of an existing filter to use for the query
3899
            trash: Whether to get the trashcan filters instead
3900
            alerts: Whether to include list of alerts that use the filter.
3901
3902
        Returns:
3903
            The response. See :py:meth:`send_command` for details.
3904
        """
3905
        cmd = XmlCommand("get_filters")
3906
3907
        add_filter(cmd, filter, filter_id)
3908
3909
        if trash is not None:
3910
            cmd.set_attribute("trash", to_bool(trash))
3911
3912
        if alerts is not None:
3913
            cmd.set_attribute("alerts", to_bool(alerts))
3914
3915
        return self._send_xml_command(cmd)
3916
3917
    def get_filter(
3918
        self, filter_id: str, *, alerts: Optional[bool] = None
3919
    ) -> Any:
3920
        """Request a single filter
3921
3922
        Arguments:
3923
            filter_id: UUID of an existing filter
3924
            alerts: Whether to include list of alerts that use the filter.
3925
3926
        Returns:
3927
            The response. See :py:meth:`send_command` for details.
3928
        """
3929
        cmd = XmlCommand("get_filters")
3930
3931
        if not filter_id:
3932
            raise RequiredArgument(
3933
                function=self.get_filter.__name__, argument='filter_id'
3934
            )
3935
3936
        cmd.set_attribute("filter_id", filter_id)
3937
3938
        if alerts is not None:
3939
            cmd.set_attribute("alerts", to_bool(alerts))
3940
3941
        return self._send_xml_command(cmd)
3942
3943 View Code Duplication
    def get_groups(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3944
        self,
3945
        *,
3946
        filter: Optional[str] = None,
3947
        filter_id: Optional[str] = None,
3948
        trash: Optional[bool] = None,
3949
    ) -> Any:
3950
        """Request a list of groups
3951
3952
        Arguments:
3953
            filter: Filter term to use for the query
3954
            filter_id: UUID of an existing filter to use for the query
3955
            trash: Whether to get the trashcan groups instead
3956
3957
        Returns:
3958
            The response. See :py:meth:`send_command` for details.
3959
        """
3960
        cmd = XmlCommand("get_groups")
3961
3962
        add_filter(cmd, filter, filter_id)
3963
3964
        if trash is not None:
3965
            cmd.set_attribute("trash", to_bool(trash))
3966
3967
        return self._send_xml_command(cmd)
3968
3969
    def get_group(self, group_id: str) -> Any:
3970
        """Request a single group
3971
3972
        Arguments:
3973
            group_id: UUID of an existing group
3974
3975
        Returns:
3976
            The response. See :py:meth:`send_command` for details.
3977
        """
3978
        cmd = XmlCommand("get_groups")
3979
3980
        if not group_id:
3981
            raise RequiredArgument(
3982
                function=self.get_group.__name__, argument='group_id'
3983
            )
3984
3985
        cmd.set_attribute("group_id", group_id)
3986
        return self._send_xml_command(cmd)
3987
3988 View Code Duplication
    def get_permissions(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3989
        self,
3990
        *,
3991
        filter: Optional[str] = None,
3992
        filter_id: Optional[str] = None,
3993
        trash: Optional[bool] = None,
3994
    ) -> Any:
3995
        """Request a list of permissions
3996
3997
        Arguments:
3998
            filter: Filter term to use for the query
3999
            filter_id: UUID of an existing filter to use for the query
4000
            trash: Whether to get permissions in the trashcan instead
4001
4002
        Returns:
4003
            The response. See :py:meth:`send_command` for details.
4004
        """
4005
        cmd = XmlCommand("get_permissions")
4006
4007
        add_filter(cmd, filter, filter_id)
4008
4009
        if trash is not None:
4010
            cmd.set_attribute("trash", to_bool(trash))
4011
4012
        return self._send_xml_command(cmd)
4013
4014
    def get_permission(self, permission_id: str) -> Any:
4015
        """Request a single permission
4016
4017
        Arguments:
4018
            permission_id: UUID of an existing permission
4019
4020
        Returns:
4021
            The response. See :py:meth:`send_command` for details.
4022
        """
4023
        cmd = XmlCommand("get_permissions")
4024
4025
        if not permission_id:
4026
            raise RequiredArgument(
4027
                function=self.get_permission.__name__, argument='permission_id'
4028
            )
4029
4030
        cmd.set_attribute("permission_id", permission_id)
4031
        return self._send_xml_command(cmd)
4032
4033
    def get_preferences(
4034
        self, *, nvt_oid: Optional[str] = None, config_id: Optional[str] = None
4035
    ) -> Any:
4036
        """Request a list of preferences
4037
4038
        When the command includes a config_id attribute, the preference element
4039
        includes the preference name, type and value, and the NVT to which the
4040
        preference applies. Otherwise, the preference element includes just the
4041
        name and value, with the NVT and type built into the name.
4042
4043
        Arguments:
4044
            nvt_oid: OID of nvt
4045
            config_id: UUID of scan config of which to show preference values
4046
4047
        Returns:
4048
            The response. See :py:meth:`send_command` for details.
4049
        """
4050
        cmd = XmlCommand("get_preferences")
4051
4052
        if nvt_oid:
4053
            cmd.set_attribute("nvt_oid", nvt_oid)
4054
4055
        if config_id:
4056
            cmd.set_attribute("config_id", config_id)
4057
4058
        return self._send_xml_command(cmd)
4059
4060
    def get_preference(
4061
        self,
4062
        name: str,
4063
        *,
4064
        nvt_oid: Optional[str] = None,
4065
        config_id: Optional[str] = None,
4066
    ) -> Any:
4067
        """Request a nvt preference
4068
4069
        Arguments:
4070
            name: name of a particular preference
4071
            nvt_oid: OID of nvt
4072
            config_id: UUID of scan config of which to show preference values
4073
4074
        Returns:
4075
            The response. See :py:meth:`send_command` for details.
4076
        """
4077
        cmd = XmlCommand("get_preferences")
4078
4079
        if not name:
4080
            raise RequiredArgument(
4081
                function=self.get_preference.__name__, argument='name'
4082
            )
4083
4084
        cmd.set_attribute("preference", name)
4085
4086
        if nvt_oid:
4087
            cmd.set_attribute("nvt_oid", nvt_oid)
4088
4089
        if config_id:
4090
            cmd.set_attribute("config_id", config_id)
4091
4092
        return self._send_xml_command(cmd)
4093
4094
    def get_report_formats(
4095
        self,
4096
        *,
4097
        filter: Optional[str] = None,
4098
        filter_id: Optional[str] = None,
4099
        trash: Optional[bool] = None,
4100
        alerts: Optional[bool] = None,
4101
        params: Optional[bool] = None,
4102
        details: Optional[bool] = None,
4103
    ) -> Any:
4104
        """Request a list of report formats
4105
4106
        Arguments:
4107
            filter: Filter term to use for the query
4108
            filter_id: UUID of an existing filter to use for the query
4109
            trash: Whether to get the trashcan report formats instead
4110
            alerts: Whether to include alerts that use the report format
4111
            params: Whether to include report format parameters
4112
            details: Include report format file, signature and parameters
4113
4114
        Returns:
4115
            The response. See :py:meth:`send_command` for details.
4116
        """
4117
        cmd = XmlCommand("get_report_formats")
4118
4119
        add_filter(cmd, filter, filter_id)
4120
4121
        if details is not None:
4122
            cmd.set_attribute("details", to_bool(details))
4123
4124
        if alerts is not None:
4125
            cmd.set_attribute("alerts", to_bool(alerts))
4126
4127
        if params is not None:
4128
            cmd.set_attribute("params", to_bool(params))
4129
4130
        if trash is not None:
4131
            cmd.set_attribute("trash", to_bool(trash))
4132
4133
        return self._send_xml_command(cmd)
4134
4135 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...
4136
        self, report_format_id: Union[str, ReportFormatType]
4137
    ) -> Any:
4138
        """Request a single report format
4139
4140
        Arguments:
4141
            report_format_id: UUID of an existing report format
4142
                              or ReportFormatType (enum)
4143
4144
        Returns:
4145
            The response. See :py:meth:`send_command` for details.
4146
        """
4147
        cmd = XmlCommand("get_report_formats")
4148
4149
        if not report_format_id:
4150
            raise RequiredArgument(
4151
                function=self.get_report_format.__name__,
4152
                argument='report_format_id',
4153
            )
4154
4155
        if isinstance(report_format_id, ReportFormatType):
4156
            report_format_id = report_format_id.value
4157
4158
        cmd.set_attribute("report_format_id", report_format_id)
4159
4160
        # for single entity always request all details
4161
        cmd.set_attribute("details", "1")
4162
        return self._send_xml_command(cmd)
4163
4164 View Code Duplication
    def get_roles(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
4165
        self,
4166
        *,
4167
        filter: Optional[str] = None,
4168
        filter_id: Optional[str] = None,
4169
        trash: Optional[bool] = None,
4170
    ) -> Any:
4171
        """Request a list of roles
4172
4173
        Arguments:
4174
            filter: Filter term to use for the query
4175
            filter_id: UUID of an existing filter to use for the query
4176
            trash: Whether to get the trashcan roles instead
4177
4178
        Returns:
4179
            The response. See :py:meth:`send_command` for details.
4180
        """
4181
        cmd = XmlCommand("get_roles")
4182
4183
        add_filter(cmd, filter, filter_id)
4184
4185
        if trash is not None:
4186
            cmd.set_attribute("trash", to_bool(trash))
4187
4188
        return self._send_xml_command(cmd)
4189
4190
    def get_role(self, role_id: str) -> Any:
4191
        """Request a single role
4192
4193
        Arguments:
4194
            role_id: UUID of an existing role
4195
4196
        Returns:
4197
            The response. See :py:meth:`send_command` for details.
4198
        """
4199
        if not role_id:
4200
            raise RequiredArgument(
4201
                function=self.get_role.__name__, argument='role_id'
4202
            )
4203
4204
        cmd = XmlCommand("get_roles")
4205
        cmd.set_attribute("role_id", role_id)
4206
        return self._send_xml_command(cmd)
4207
4208 View Code Duplication
    def get_scanners(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
4209
        self,
4210
        *,
4211
        filter: Optional[str] = None,
4212
        filter_id: Optional[str] = None,
4213
        trash: Optional[bool] = None,
4214
        details: Optional[bool] = None,
4215
    ) -> Any:
4216
        """Request a list of scanners
4217
4218
        Arguments:
4219
            filter: Filter term to use for the query
4220
            filter_id: UUID of an existing filter to use for the query
4221
            trash: Whether to get the trashcan scanners instead
4222
            details:  Whether to include extra details like tasks using this
4223
                scanner
4224
4225
        Returns:
4226
            The response. See :py:meth:`send_command` for details.
4227
        """
4228
        cmd = XmlCommand("get_scanners")
4229
4230
        add_filter(cmd, filter, filter_id)
4231
4232
        if trash is not None:
4233
            cmd.set_attribute("trash", to_bool(trash))
4234
4235
        if details is not None:
4236
            cmd.set_attribute("details", to_bool(details))
4237
4238
        return self._send_xml_command(cmd)
4239
4240
    def get_scanner(self, scanner_id: str) -> Any:
4241
        """Request a single scanner
4242
4243
        Arguments:
4244
            scanner_id: UUID of an existing scanner
4245
4246
        Returns:
4247
            The response. See :py:meth:`send_command` for details.
4248
        """
4249
        cmd = XmlCommand("get_scanners")
4250
4251
        if not scanner_id:
4252
            raise RequiredArgument(
4253
                function=self.get_scanner.__name__, argument='scanner_id'
4254
            )
4255
4256
        cmd.set_attribute("scanner_id", scanner_id)
4257
4258
        # for single entity always request all details
4259
        cmd.set_attribute("details", "1")
4260
        return self._send_xml_command(cmd)
4261
4262
    def get_schedules(
4263
        self,
4264
        *,
4265
        filter: Optional[str] = None,
4266
        filter_id: Optional[str] = None,
4267
        trash: Optional[bool] = None,
4268
        tasks: Optional[bool] = None,
4269
    ) -> Any:
4270
        """Request a list of schedules
4271
4272
        Arguments:
4273
            filter: Filter term to use for the query
4274
            filter_id: UUID of an existing filter to use for the query
4275
            trash: Whether to get the trashcan schedules instead
4276
            tasks: Whether to include tasks using the schedules
4277
4278
        Returns:
4279
            The response. See :py:meth:`send_command` for details.
4280
        """
4281
        cmd = XmlCommand("get_schedules")
4282
4283
        add_filter(cmd, filter, filter_id)
4284
4285
        if trash is not None:
4286
            cmd.set_attribute("trash", to_bool(trash))
4287
4288
        if tasks is not None:
4289
            cmd.set_attribute("tasks", to_bool(tasks))
4290
4291
        return self._send_xml_command(cmd)
4292
4293
    def get_schedule(
4294
        self, schedule_id: str, *, tasks: Optional[bool] = None
4295
    ) -> Any:
4296
        """Request a single schedule
4297
4298
        Arguments:
4299
            schedule_id: UUID of an existing schedule
4300
            tasks: Whether to include tasks using the schedules
4301
4302
        Returns:
4303
            The response. See :py:meth:`send_command` for details.
4304
        """
4305
        cmd = XmlCommand("get_schedules")
4306
4307
        if not schedule_id:
4308
            raise RequiredArgument(
4309
                function=self.get_schedule.__name__, argument='schedule_id'
4310
            )
4311
4312
        cmd.set_attribute("schedule_id", schedule_id)
4313
4314
        if tasks is not None:
4315
            cmd.set_attribute("tasks", to_bool(tasks))
4316
4317
        return self._send_xml_command(cmd)
4318
4319
    def get_settings(self, *, filter: Optional[str] = None) -> Any:
4320
        """Request a list of user settings
4321
4322
        Arguments:
4323
            filter: Filter term to use for the query
4324
4325
        Returns:
4326
            The response. See :py:meth:`send_command` for details.
4327
        """
4328
        cmd = XmlCommand("get_settings")
4329
4330
        if filter:
4331
            cmd.set_attribute("filter", filter)
4332
4333
        return self._send_xml_command(cmd)
4334
4335
    def get_setting(self, setting_id: str) -> Any:
4336
        """Request a single setting
4337
4338
        Arguments:
4339
            setting_id: UUID of an existing setting
4340
4341
        Returns:
4342
            The response. See :py:meth:`send_command` for details.
4343
        """
4344
        cmd = XmlCommand("get_settings")
4345
4346
        if not setting_id:
4347
            raise RequiredArgument(
4348
                function=self.get_setting.__name__, argument='setting_id'
4349
            )
4350
4351
        cmd.set_attribute("setting_id", setting_id)
4352
        return self._send_xml_command(cmd)
4353
4354
    def get_system_reports(
4355
        self,
4356
        *,
4357
        name: Optional[str] = None,
4358
        duration: Optional[int] = None,
4359
        start_time: Optional[str] = None,
4360
        end_time: Optional[str] = None,
4361
        brief: Optional[bool] = None,
4362
        slave_id: Optional[str] = None,
4363
    ) -> Any:
4364
        """Request a list of system reports
4365
4366
        Arguments:
4367
            name: A string describing the required system report
4368
            duration: The number of seconds into the past that the system report
4369
                should include
4370
            start_time: The start of the time interval the system report should
4371
                include in ISO time format
4372
            end_time: The end of the time interval the system report should
4373
                include in ISO time format
4374
            brief: Whether to include the actual system reports
4375
            slave_id: UUID of GMP scanner from which to get the system reports
4376
4377
        Returns:
4378
            The response. See :py:meth:`send_command` for details.
4379
        """
4380
        cmd = XmlCommand("get_system_reports")
4381
4382
        if name:
4383
            cmd.set_attribute("name", name)
4384
4385
        if duration is not None:
4386
            if not isinstance(duration, Integral):
4387
                raise InvalidArgument("duration needs to be an integer number")
4388
4389
            cmd.set_attribute("duration", str(duration))
4390
4391
        if start_time:
4392
            cmd.set_attribute("start_time", str(start_time))
4393
4394
        if end_time:
4395
            cmd.set_attribute("end_time", str(end_time))
4396
4397
        if brief is not None:
4398
            cmd.set_attribute("brief", to_bool(brief))
4399
4400
        if slave_id:
4401
            cmd.set_attribute("slave_id", slave_id)
4402
4403
        return self._send_xml_command(cmd)
4404
4405
    def get_tags(
4406
        self,
4407
        *,
4408
        filter: Optional[str] = None,
4409
        filter_id: Optional[str] = None,
4410
        trash: Optional[bool] = None,
4411
        names_only: Optional[bool] = None,
4412
    ) -> Any:
4413
        """Request a list of tags
4414
4415
        Arguments:
4416
            filter: Filter term to use for the query
4417
            filter_id: UUID of an existing filter to use for the query
4418
            trash: Whether to get tags from the trashcan instead
4419
            names_only: Whether to get only distinct tag names
4420
4421
        Returns:
4422
            The response. See :py:meth:`send_command` for details.
4423
        """
4424
        cmd = XmlCommand("get_tags")
4425
4426
        add_filter(cmd, filter, filter_id)
4427
4428
        if trash is not None:
4429
            cmd.set_attribute("trash", to_bool(trash))
4430
4431
        if names_only is not None:
4432
            cmd.set_attribute("names_only", to_bool(names_only))
4433
4434
        return self._send_xml_command(cmd)
4435
4436
    def get_tag(self, tag_id: str) -> Any:
4437
        """Request a single tag
4438
4439
        Arguments:
4440
            tag_id: UUID of an existing tag
4441
4442
        Returns:
4443
            The response. See :py:meth:`send_command` for details.
4444
        """
4445
        cmd = XmlCommand("get_tags")
4446
4447
        if not tag_id:
4448
            raise RequiredArgument(
4449
                function=self.get_tag.__name__, argument='tag_id'
4450
            )
4451
4452
        cmd.set_attribute("tag_id", tag_id)
4453
        return self._send_xml_command(cmd)
4454
4455
    def get_users(
4456
        self, *, filter: Optional[str] = None, filter_id: Optional[str] = None
4457
    ) -> Any:
4458
        """Request a list of users
4459
4460
        Arguments:
4461
            filter: Filter term to use for the query
4462
            filter_id: UUID of an existing filter to use for the query
4463
4464
        Returns:
4465
            The response. See :py:meth:`send_command` for details.
4466
        """
4467
        cmd = XmlCommand("get_users")
4468
4469
        add_filter(cmd, filter, filter_id)
4470
4471
        return self._send_xml_command(cmd)
4472
4473
    def get_user(self, user_id: str) -> Any:
4474
        """Request a single user
4475
4476
        Arguments:
4477
            user_id: UUID of an existing user
4478
4479
        Returns:
4480
            The response. See :py:meth:`send_command` for details.
4481
        """
4482
        cmd = XmlCommand("get_users")
4483
4484
        if not user_id:
4485
            raise RequiredArgument(
4486
                function=self.get_user.__name__, argument='user_id'
4487
            )
4488
4489
        cmd.set_attribute("user_id", user_id)
4490
        return self._send_xml_command(cmd)
4491
4492
    def get_version(self) -> Any:
4493
        """Get the Greenbone Manager Protocol version used by the remote gvmd
4494
4495
        Returns:
4496
            The response. See :py:meth:`send_command` for details.
4497
        """
4498
        return self._send_xml_command(XmlCommand("get_version"))
4499
4500
    def help(
4501
        self, *, format: Optional[str] = None, help_type: Optional[str] = ""
4502
    ) -> Any:
4503
        """Get the help text
4504
4505
        Arguments:
4506
            format: One of "html", "rnc", "text" or "xml
4507
            help_type: One of "brief" or "". Default ""
4508
4509
        Returns:
4510
            The response. See :py:meth:`send_command` for details.
4511
        """
4512
        cmd = XmlCommand("help")
4513
4514
        if help_type not in ("", "brief"):
4515
            raise InvalidArgument(
4516
                'help_type argument must be an empty string or "brief"'
4517
            )
4518
4519
        cmd.set_attribute("type", help_type)
4520
4521
        if format:
4522
            if not format.lower() in ("html", "rnc", "text", "xml"):
4523
                raise InvalidArgument(
4524
                    "help format Argument must be one of html, rnc, text or "
4525
                    "xml"
4526
                )
4527
4528
            cmd.set_attribute("format", format)
4529
4530
        return self._send_xml_command(cmd)
4531
4532
    def modify_asset(self, asset_id: str, comment: Optional[str] = "") -> Any:
4533
        """Modifies an existing asset.
4534
4535
        Arguments:
4536
            asset_id: UUID of the asset to be modified.
4537
            comment: Comment for the asset.
4538
4539
        Returns:
4540
            The response. See :py:meth:`send_command` for details.
4541
        """
4542
        if not asset_id:
4543
            raise RequiredArgument(
4544
                function=self.modify_asset.__name__, argument='asset_id'
4545
            )
4546
4547
        cmd = XmlCommand("modify_asset")
4548
        cmd.set_attribute("asset_id", asset_id)
4549
        cmd.add_element("comment", comment)
4550
4551
        return self._send_xml_command(cmd)
4552
4553
    def modify_auth(self, group_name: str, auth_conf_settings: dict) -> Any:
4554
        """Modifies an existing auth.
4555
4556
        Arguments:
4557
            group_name: Name of the group to be modified.
4558
            auth_conf_settings: The new auth config.
4559
4560
        Returns:
4561
            The response. See :py:meth:`send_command` for details.
4562
        """
4563
        if not group_name:
4564
            raise RequiredArgument(
4565
                function=self.modify_auth.__name__, argument='group_name'
4566
            )
4567
        if not auth_conf_settings:
4568
            raise RequiredArgument(
4569
                function=self.modify_auth.__name__,
4570
                argument='auth_conf_settings',
4571
            )
4572
        cmd = XmlCommand("modify_auth")
4573
        _xmlgroup = cmd.add_element("group", attrs={"name": str(group_name)})
4574
4575
        for key, value in auth_conf_settings.items():
4576
            _xmlauthconf = _xmlgroup.add_element("auth_conf_setting")
4577
            _xmlauthconf.add_element("key", key)
4578
            _xmlauthconf.add_element("value", value)
4579
4580
        return self._send_xml_command(cmd)
4581
4582
    def modify_config_set_nvt_preference(
4583
        self,
4584
        config_id: str,
4585
        name: str,
4586
        nvt_oid: str,
4587
        *,
4588
        value: Optional[str] = None,
4589
    ) -> Any:
4590
        """Modifies the nvt preferences of an existing scan config.
4591
4592
        Arguments:
4593
            config_id: UUID of scan config to modify.
4594
            name: Name for nvt preference to change.
4595
            nvt_oid: OID of the NVT associated with preference to modify
4596
            value: New value for the preference. None to delete the preference
4597
                and to use the default instead.
4598
        """
4599
        if not config_id:
4600
            raise RequiredArgument(
4601
                function=self.modify_config_set_nvt_preference.__name__,
4602
                argument='config_id',
4603
            )
4604
4605
        if not nvt_oid:
4606
            raise RequiredArgument(
4607
                function=self.modify_config_set_nvt_preference.__name__,
4608
                argument='nvt_oid',
4609
            )
4610
4611
        if not name:
4612
            raise RequiredArgument(
4613
                function=self.modify_config_set_nvt_preference.__name__,
4614
                argument='name',
4615
            )
4616
4617
        cmd = XmlCommand("modify_config")
4618
        cmd.set_attribute("config_id", str(config_id))
4619
4620
        _xmlpref = cmd.add_element("preference")
4621
4622
        _xmlpref.add_element("nvt", attrs={"oid": nvt_oid})
4623
        _xmlpref.add_element("name", name)
4624
4625
        if value:
4626
            _xmlpref.add_element("value", to_base64(value))
4627
4628
        return self._send_xml_command(cmd)
4629
4630
    def modify_config_set_name(self, config_id: str, name: str) -> Any:
4631
        """Modifies the name of an existing scan config
4632
4633
        Arguments:
4634
            config_id: UUID of scan config to modify.
4635
            name: New name for the config.
4636
        """
4637
        if not config_id:
4638
            raise RequiredArgument(
4639
                function=self.modify_config_set_name.__name__,
4640
                argument='config_id',
4641
            )
4642
4643
        if not name:
4644
            raise RequiredArgument(
4645
                function=self.modify_config_set_name.__name__, argument='name'
4646
            )
4647
4648
        cmd = XmlCommand("modify_config")
4649
        cmd.set_attribute("config_id", str(config_id))
4650
4651
        cmd.add_element("name", name)
4652
4653
        return self._send_xml_command(cmd)
4654
4655
    def modify_config_set_comment(
4656
        self, config_id: str, comment: Optional[str] = ""
4657
    ) -> Any:
4658
        """Modifies the comment of an existing scan config
4659
4660
        Arguments:
4661
            config_id: UUID of scan config to modify.
4662
            comment: Comment to set on a config. Default: ''
4663
        """
4664
        if not config_id:
4665
            raise RequiredArgument(
4666
                function=self.modify_config_set_comment.__name__,
4667
                argument='config_id argument',
4668
            )
4669
4670
        cmd = XmlCommand("modify_config")
4671
        cmd.set_attribute("config_id", str(config_id))
4672
4673
        cmd.add_element("comment", comment)
4674
4675
        return self._send_xml_command(cmd)
4676
4677
    def modify_config_set_scanner_preference(
4678
        self, config_id: str, name: str, *, value: Optional[str] = None
4679
    ) -> Any:
4680
        """Modifies the scanner preferences of an existing scan config
4681
4682
        Arguments:
4683
            config_id: UUID of scan config to modify.
4684
            name: Name of the scanner preference to change
4685
            value: New value for the preference. None to delete the preference
4686
                and to use the default instead.
4687
4688
        """
4689
        if not config_id:
4690
            raise RequiredArgument(
4691
                function=self.modify_config_set_scanner_preference.__name__,
4692
                argument='config_id',
4693
            )
4694
4695
        if not name:
4696
            raise RequiredArgument(
4697
                function=self.modify_config_set_scanner_preference.__name__,
4698
                argument='name argument',
4699
            )
4700
4701
        cmd = XmlCommand("modify_config")
4702
        cmd.set_attribute("config_id", str(config_id))
4703
4704
        _xmlpref = cmd.add_element("preference")
4705
4706
        _xmlpref.add_element("name", name)
4707
4708
        if value:
4709
            _xmlpref.add_element("value", to_base64(value))
4710
4711
        return self._send_xml_command(cmd)
4712
4713
    def modify_config_set_nvt_selection(
4714
        self, config_id: str, family: str, nvt_oids: List[str]
4715
    ) -> Any:
4716
        """Modifies the selected nvts of an existing scan config
4717
4718
        The manager updates the given family in the config to include only the
4719
        given NVTs.
4720
4721
        Arguments:
4722
            config_id: UUID of scan config to modify.
4723
            family: Name of the NVT family to include NVTs from
4724
            nvt_oids: List of NVTs to select for the family.
4725
        """
4726
        if not config_id:
4727
            raise RequiredArgument(
4728
                function=self.modify_config_set_nvt_selection.__name__,
4729
                argument='config_id',
4730
            )
4731
4732
        if not family:
4733
            raise RequiredArgument(
4734
                function=self.modify_config_set_nvt_selection.__name__,
4735
                argument='family argument',
4736
            )
4737
4738
        if not is_list_like(nvt_oids):
4739
            raise InvalidArgumentType(
4740
                function=self.modify_config_set_nvt_selection.__name__,
4741
                argument='nvt_oids',
4742
                arg_type='list',
4743
            )
4744
4745
        cmd = XmlCommand("modify_config")
4746
        cmd.set_attribute("config_id", str(config_id))
4747
4748
        _xmlnvtsel = cmd.add_element("nvt_selection")
4749
        _xmlnvtsel.add_element("family", family)
4750
4751
        for nvt in nvt_oids:
4752
            _xmlnvtsel.add_element("nvt", attrs={"oid": nvt})
4753
4754
        return self._send_xml_command(cmd)
4755
4756
    def modify_config_set_family_selection(
4757
        self,
4758
        config_id: str,
4759
        families: List[Tuple[str, bool, bool]],
4760
        *,
4761
        auto_add_new_families: Optional[bool] = True,
4762
    ) -> Any:
4763
        """
4764
        Selected the NVTs of a scan config at a family level.
4765
4766
        Arguments:
4767
            config_id: UUID of scan config to modify.
4768
            families: A list of tuples (str, bool, bool):
4769
                str: the name of the NVT family selected,
4770
                bool: add new NVTs  to the family automatically,
4771
                bool: include all NVTs from the family
4772
            auto_add_new_families: Whether new families should be added to the
4773
                scan config automatically. Default: True.
4774
        """
4775
        if not config_id:
4776
            raise RequiredArgument(
4777
                function=self.modify_config_set_family_selection.__name__,
4778
                argument='config_id',
4779
            )
4780
4781
        if not is_list_like(families):
4782
            raise InvalidArgumentType(
4783
                function=self.modify_config_set_family_selection.__name__,
4784
                argument='families',
4785
                arg_type='list',
4786
            )
4787
4788
        cmd = XmlCommand("modify_config")
4789
        cmd.set_attribute("config_id", str(config_id))
4790
4791
        _xmlfamsel = cmd.add_element("family_selection")
4792
        _xmlfamsel.add_element("growing", to_bool(auto_add_new_families))
4793
4794
        for family in families:
4795
            _xmlfamily = _xmlfamsel.add_element("family")
4796
            _xmlfamily.add_element("name", family[0])
4797
4798
            if len(family) != 3:
4799
                raise InvalidArgument(
4800
                    "Family must be a tuple of 3. (str, bool, bool)"
4801
                )
4802
4803
            if not isinstance(family[1], bool) or not isinstance(
4804
                family[2], bool
4805
            ):
4806
                raise InvalidArgumentType(
4807
                    function=self.modify_config_set_family_selection.__name__,
4808
                    argument='families',
4809
                    arg_type='[tuple(str, bool, bool)]',
4810
                )
4811
4812
            _xmlfamily.add_element("all", to_bool(family[2]))
4813
            _xmlfamily.add_element("growing", to_bool(family[1]))
4814
4815
        return self._send_xml_command(cmd)
4816
4817
    def modify_config(
4818
        self, config_id: str, selection: Optional[str] = None, **kwargs
4819
    ) -> Any:
4820
        """Modifies an existing scan config.
4821
4822
        DEPRECATED. Please use *modify_config_set_* methods instead.
4823
4824
        modify_config has four modes to operate depending on the selection.
4825
4826
        Arguments:
4827
            config_id: UUID of scan config to modify.
4828
            selection: one of 'scan_pref', 'nvt_pref', 'nvt_selection' or
4829
                'family_selection'
4830
            name: New name for preference.
4831
            value: New value for preference.
4832
            nvt_oids: List of NVTs associated with preference to modify.
4833
            family: Name of family to modify.
4834
4835
        Returns:
4836
            The response. See :py:meth:`send_command` for details.
4837
        """
4838
        if not config_id:
4839
            raise RequiredArgument(
4840
                function=self.modify_config.__name__,
4841
                argument='config_id argument',
4842
            )
4843
4844
        if selection is None:
4845
            deprecation(
4846
                "Using modify_config to update the comment of a scan config is"
4847
                "deprecated. Please use modify_config_set_comment instead."
4848
            )
4849
            return self.modify_config_set_comment(
4850
                config_id, kwargs.get("comment")
4851
            )
4852
4853
        if selection not in (
4854
            "nvt_pref",
4855
            "scan_pref",
4856
            "family_selection",
4857
            "nvt_selection",
4858
        ):
4859
            raise InvalidArgument(
4860
                "selection must be one of nvt_pref, "
4861
                "scan_pref, family_selection or "
4862
                "nvt_selection"
4863
            )
4864
4865
        if selection == "nvt_pref":
4866
            deprecation(
4867
                "Using modify_config to update a nvt preference of a scan "
4868
                "config is deprecated. Please use "
4869
                "modify_config_set_nvt_preference instead."
4870
            )
4871
            return self.modify_config_set_nvt_preference(config_id, **kwargs)
4872
4873
        if selection == "scan_pref":
4874
            deprecation(
4875
                "Using modify_config to update a scanner preference of a "
4876
                "scan config is deprecated. Please use "
4877
                "modify_config_set_scanner_preference instead."
4878
            )
4879
            return self.modify_config_set_scanner_preference(
4880
                config_id, **kwargs
4881
            )
4882
4883
        if selection == "nvt_selection":
4884
            deprecation(
4885
                "Using modify_config to update a nvt selection of a "
4886
                "scan config is deprecated. Please use "
4887
                "modify_config_set_nvt_selection instead."
4888
            )
4889
            return self.modify_config_set_nvt_selection(config_id, **kwargs)
4890
4891
        deprecation(
4892
            "Using modify_config to update a family selection of a "
4893
            "scan config is deprecated. Please use "
4894
            "modify_config_set_family_selection instead."
4895
        )
4896
        return self.modify_config_set_family_selection(config_id, **kwargs)
4897
4898 View Code Duplication
    def modify_group(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
4899
        self,
4900
        group_id: str,
4901
        *,
4902
        comment: Optional[str] = None,
4903
        name: Optional[str] = None,
4904
        users: Optional[List[str]] = None,
4905
    ) -> Any:
4906
        """Modifies an existing group.
4907
4908
        Arguments:
4909
            group_id: UUID of group to modify.
4910
            comment: Comment on group.
4911
            name: Name of group.
4912
            users: List of user names to be in the group
4913
4914
        Returns:
4915
            The response. See :py:meth:`send_command` for details.
4916
        """
4917
        if not group_id:
4918
            raise RequiredArgument(
4919
                function=self.modify_group.__name__, argument='group_id'
4920
            )
4921
4922
        cmd = XmlCommand("modify_group")
4923
        cmd.set_attribute("group_id", group_id)
4924
4925
        if comment:
4926
            cmd.add_element("comment", comment)
4927
4928
        if name:
4929
            cmd.add_element("name", name)
4930
4931
        if users:
4932
            cmd.add_element("users", to_comma_list(users))
4933
4934
        return self._send_xml_command(cmd)
4935
4936
    def modify_report_format(
4937
        self,
4938
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
4939
        *,
4940
        active: Optional[bool] = None,
4941
        name: Optional[str] = None,
4942
        summary: Optional[str] = None,
4943
        param_name: Optional[str] = None,
4944
        param_value: Optional[str] = None,
4945
    ) -> Any:
4946
        """Modifies an existing report format.
4947
4948
        Arguments:
4949
            report_format_id: UUID of report format to modify
4950
                              or ReportFormatType (enum)
4951
            active: Whether the report format is active.
4952
            name: The name of the report format.
4953
            summary: A summary of the report format.
4954
            param_name: The name of the param.
4955
            param_value: The value of the param.
4956
4957
        Returns:
4958
            The response. See :py:meth:`send_command` for details.
4959
        """
4960
        if not report_format_id:
4961
            raise RequiredArgument(
4962
                function=self.modify_report_format.__name__,
4963
                argument='report_format_id ',
4964
            )
4965
4966
        cmd = XmlCommand("modify_report_format")
4967
4968
        if isinstance(report_format_id, ReportFormatType):
4969
            report_format_id = report_format_id.value
4970
4971
        cmd.set_attribute("report_format_id", report_format_id)
4972
4973
        if active is not None:
4974
            cmd.add_element("active", to_bool(active))
4975
4976
        if name:
4977
            cmd.add_element("name", name)
4978
4979
        if summary:
4980
            cmd.add_element("summary", summary)
4981
4982
        if param_name:
4983
            _xmlparam = cmd.add_element("param")
4984
            _xmlparam.add_element("name", param_name)
4985
4986
            if param_value is not None:
4987
                _xmlparam.add_element("value", param_value)
4988
4989
        return self._send_xml_command(cmd)
4990
4991 View Code Duplication
    def modify_role(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
4992
        self,
4993
        role_id: str,
4994
        *,
4995
        comment: Optional[str] = None,
4996
        name: Optional[str] = None,
4997
        users: Optional[List[str]] = None,
4998
    ) -> Any:
4999
        """Modifies an existing role.
5000
5001
        Arguments:
5002
            role_id: UUID of role to modify.
5003
            comment: Name of role.
5004
            name: Comment on role.
5005
            users: List of user names.
5006
5007
        Returns:
5008
            The response. See :py:meth:`send_command` for details.
5009
        """
5010
        if not role_id:
5011
            raise RequiredArgument(
5012
                function=self.modify_role.__name__, argument='role_id argument'
5013
            )
5014
5015
        cmd = XmlCommand("modify_role")
5016
        cmd.set_attribute("role_id", role_id)
5017
5018
        if comment:
5019
            cmd.add_element("comment", comment)
5020
5021
        if name:
5022
            cmd.add_element("name", name)
5023
5024
        if users:
5025
            cmd.add_element("users", to_comma_list(users))
5026
5027
        return self._send_xml_command(cmd)
5028
5029
    def modify_scanner(
5030
        self,
5031
        scanner_id: str,
5032
        *,
5033
        scanner_type: Optional[ScannerType] = None,
5034
        host: Optional[str] = None,
5035
        port: Optional[int] = None,
5036
        comment: Optional[str] = None,
5037
        name: Optional[str] = None,
5038
        ca_pub: Optional[str] = None,
5039
        credential_id: Optional[str] = None,
5040
    ) -> Any:
5041
        """Modifies an existing scanner.
5042
5043
        Arguments:
5044
            scanner_id: UUID of scanner to modify.
5045
            scanner_type: New type of the Scanner.
5046
            host: Host of the scanner.
5047
            port: Port of the scanner.
5048
            comment: Comment on scanner.
5049
            name: Name of scanner.
5050
            ca_pub: Certificate of CA to verify scanner's certificate.
5051
            credential_id: UUID of the client certificate credential for the
5052
                Scanner.
5053
5054
        Returns:
5055
            The response. See :py:meth:`send_command` for details.
5056
        """
5057
        if not scanner_id:
5058
            raise RequiredArgument(
5059
                function=self.modify_scanner.__name__,
5060
                argument='scanner_id argument',
5061
            )
5062
5063
        cmd = XmlCommand("modify_scanner")
5064
        cmd.set_attribute("scanner_id", scanner_id)
5065
5066
        if scanner_type is not None:
5067
            if not isinstance(scanner_type, self.types.ScannerType):
5068
                raise InvalidArgumentType(
5069
                    function=self.modify_scanner.__name__,
5070
                    argument='scanner_type',
5071
                    arg_type=self.types.ScannerType.__name__,
5072
                )
5073
5074
            cmd.add_element("type", scanner_type.value)
5075
5076
        if host:
5077
            cmd.add_element("host", host)
5078
5079
        if port:
5080
            cmd.add_element("port", str(port))
5081
5082
        if comment:
5083
            cmd.add_element("comment", comment)
5084
5085
        if name:
5086
            cmd.add_element("name", name)
5087
5088
        if ca_pub:
5089
            cmd.add_element("ca_pub", ca_pub)
5090
5091
        if credential_id:
5092
            cmd.add_element("credential", attrs={"id": str(credential_id)})
5093
5094
        return self._send_xml_command(cmd)
5095
5096
    def modify_setting(
5097
        self,
5098
        setting_id: Optional[str] = None,
5099
        name: Optional[str] = None,
5100
        value: Optional[str] = None,
5101
    ) -> Any:
5102
        """Modifies an existing setting.
5103
5104
        Arguments:
5105
            setting_id: UUID of the setting to be changed.
5106
            name: The name of the setting. Either setting_id or name must be
5107
                passed.
5108
            value: The value of the setting.
5109
5110
        Returns:
5111
            The response. See :py:meth:`send_command` for details.
5112
        """
5113
        if not setting_id and not name:
5114
            raise RequiredArgument(
5115
                function=self.modify_setting.__name__,
5116
                argument='setting_id or name argument',
5117
            )
5118
5119
        if value is None:
5120
            raise RequiredArgument(
5121
                function=self.modify_setting.__name__, argument='value argument'
5122
            )
5123
5124
        cmd = XmlCommand("modify_setting")
5125
5126
        if setting_id:
5127
            cmd.set_attribute("setting_id", setting_id)
5128
        else:
5129
            cmd.add_element("name", name)
5130
5131
        cmd.add_element("value", to_base64(value))
5132
5133
        return self._send_xml_command(cmd)
5134
5135 View Code Duplication
    def modify_user(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5136
        self,
5137
        user_id: str = None,
5138
        name: str = None,
5139
        *,
5140
        new_name: Optional[str] = None,
5141
        comment: Optional[str] = None,
5142
        password: Optional[str] = None,
5143
        auth_source: Optional[UserAuthType] = None,
5144
        role_ids: Optional[List[str]] = None,
5145
        hosts: Optional[List[str]] = None,
5146
        hosts_allow: Optional[bool] = False,
5147
        ifaces: Optional[List[str]] = None,
5148
        ifaces_allow: Optional[bool] = False,
5149
        group_ids: Optional[List[str]] = None,
5150
    ) -> Any:
5151
        """Modifies an existing user. Most of the fields need to be supplied
5152
        for changing a single field even if no change is wanted for those.
5153
        Else empty values are inserted for the missing fields instead.
5154
        Arguments:
5155
            user_id: UUID of the user to be modified. Overrides name element
5156
                argument.
5157
            name: The name of the user to be modified. Either user_id or name
5158
                must be passed.
5159
            new_name: The new name for the user.
5160
            comment: Comment on the user.
5161
            password: The password for the user.
5162
            auth_source: Source allowed for authentication for this user.
5163
            roles_id: List of roles UUIDs for the user.
5164
            hosts: User access rules: List of hosts.
5165
            hosts_allow: Defines how the hosts list is to be interpreted.
5166
                If False (default) the list is treated as a deny list.
5167
                All hosts are allowed by default except those provided by
5168
                the hosts parameter. If True the list is treated as a
5169
                allow list. All hosts are denied by default except those
5170
                provided by the hosts parameter.
5171
            ifaces: User access rules: List of ifaces.
5172
            ifaces_allow: Defines how the ifaces list is to be interpreted.
5173
                If False (default) the list is treated as a deny list.
5174
                All ifaces are allowed by default except those provided by
5175
                the ifaces parameter. If True the list is treated as a
5176
                allow list. All ifaces are denied by default except those
5177
                provided by the ifaces parameter.
5178
            group_ids: List of group UUIDs for the user.
5179
5180
        Returns:
5181
            The response. See :py:meth:`send_command` for details.
5182
        """
5183
        if not user_id and not name:
5184
            raise RequiredArgument(
5185
                function=self.modify_user.__name__, argument='user_id or name'
5186
            )
5187
5188
        cmd = XmlCommand("modify_user")
5189
5190
        if user_id:
5191
            cmd.set_attribute("user_id", user_id)
5192
        else:
5193
            cmd.add_element("name", name)
5194
5195
        if new_name:
5196
            cmd.add_element("new_name", new_name)
5197
5198
        if role_ids:
5199
            for role in role_ids:
5200
                cmd.add_element("role", attrs={"id": role})
5201
5202
        if hosts:
5203
            cmd.add_element(
5204
                "hosts",
5205
                to_comma_list(hosts),
5206
                attrs={"allow": to_bool(hosts_allow)},
5207
            )
5208
5209
        if ifaces:
5210
            cmd.add_element(
5211
                "ifaces",
5212
                to_comma_list(ifaces),
5213
                attrs={"allow": to_bool(ifaces_allow)},
5214
            )
5215
5216
        if comment:
5217
            cmd.add_element("comment", comment)
5218
5219
        if password:
5220
            cmd.add_element("password", password)
5221
5222
        if auth_source:
5223
            _xmlauthsrc = cmd.add_element("sources")
5224
            _xmlauthsrc.add_element("source", auth_source.value)
5225
5226
        if group_ids:
5227
            _xmlgroups = cmd.add_element("groups")
5228
            for group_id in group_ids:
5229
                _xmlgroups.add_element("group", attrs={"id": group_id})
5230
5231
        return self._send_xml_command(cmd)
5232
5233
    def restore(self, entity_id: str) -> Any:
5234
        """Restore an entity from the trashcan
5235
5236
        Arguments:
5237
            entity_id: ID of the entity to be restored from the trashcan
5238
5239
        Returns:
5240
            The response. See :py:meth:`send_command` for details.
5241
        """
5242
        if not entity_id:
5243
            raise RequiredArgument(
5244
                function=self.restore.__name__, argument='entity_id'
5245
            )
5246
5247
        cmd = XmlCommand("restore")
5248
        cmd.set_attribute("id", entity_id)
5249
5250
        return self._send_xml_command(cmd)
5251
5252
    def sync_cert(self) -> Any:
5253
        """Request a synchronization with the CERT feed service
5254
5255
        Returns:
5256
            The response. See :py:meth:`send_command` for details.
5257
        """
5258
        return self._send_xml_command(XmlCommand("sync_cert"))
5259
5260
    def sync_config(self) -> Any:
5261
        """Request an OSP config synchronization with scanner
5262
5263
        Returns:
5264
            The response. See :py:meth:`send_command` for details.
5265
        """
5266
        return self._send_xml_command(XmlCommand("sync_config"))
5267
5268
    def sync_feed(self) -> Any:
5269
        """Request a synchronization with the NVT feed service
5270
5271
        Returns:
5272
            The response. See :py:meth:`send_command` for details.
5273
        """
5274
        return self._send_xml_command(XmlCommand("sync_feed"))
5275
5276
    def sync_scap(self) -> Any:
5277
        """Request a synchronization with the SCAP feed service
5278
5279
        Returns:
5280
            The response. See :py:meth:`send_command` for details.
5281
        """
5282
        return self._send_xml_command(XmlCommand("sync_scap"))
5283
5284
    def test_alert(self, alert_id: str) -> Any:
5285
        """Run an alert
5286
5287
        Invoke a test run of an alert
5288
5289
        Arguments:
5290
            alert_id: UUID of the alert to be tested
5291
5292
        Returns:
5293
            The response. See :py:meth:`send_command` for details.
5294
        """
5295
        if not alert_id:
5296
            raise InvalidArgument("test_alert requires an alert_id argument")
5297
5298
        cmd = XmlCommand("test_alert")
5299
        cmd.set_attribute("alert_id", alert_id)
5300
5301
        return self._send_xml_command(cmd)
5302
5303
    def trigger_alert(
5304
        self,
5305
        alert_id: str,
5306
        report_id: str,
5307
        *,
5308
        filter: Optional[str] = None,
5309
        filter_id: Optional[str] = None,
5310
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
5311
        delta_report_id: Optional[str] = None,
5312
    ) -> Any:
5313
        """Run an alert by ignoring its event and conditions
5314
5315
        The alert is triggered to run immediately with the provided filtered
5316
        report by ignoring the even and condition settings.
5317
5318
        Arguments:
5319
            alert_id: UUID of the alert to be run
5320
            report_id: UUID of the report to be provided to the alert
5321
            filter: Filter term to use to filter results in the report
5322
            filter_id: UUID of filter to use to filter results in the report
5323
            report_format_id: UUID of report format to use
5324
                              or ReportFormatType (enum)
5325
            delta_report_id: UUID of an existing report to compare report to.
5326
5327
        Returns:
5328
            The response. See :py:meth:`send_command` for details.
5329
        """
5330
        if not alert_id:
5331
            raise RequiredArgument(
5332
                function=self.trigger_alert.__name__,
5333
                argument='alert_id argument',
5334
            )
5335
5336
        if not report_id:
5337
            raise RequiredArgument(
5338
                function=self.trigger_alert.__name__,
5339
                argument='report_id argument',
5340
            )
5341
5342
        cmd = XmlCommand("get_reports")
5343
        cmd.set_attribute("report_id", report_id)
5344
        cmd.set_attribute("alert_id", alert_id)
5345
5346
        if filter:
5347
            cmd.set_attribute("filter", filter)
5348
5349
        if filter_id:
5350
            cmd.set_attribute("filt_id", filter_id)
5351
5352
        if report_format_id:
5353
            if isinstance(report_format_id, ReportFormatType):
5354
                report_format_id = report_format_id.value
5355
5356
            cmd.set_attribute("format_id", report_format_id)
5357
5358
        if delta_report_id:
5359
            cmd.set_attribute("delta_report_id", delta_report_id)
5360
5361
        return self._send_xml_command(cmd)
5362
5363 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...
5364
        self, report_format_id: Union[str, ReportFormatType]
5365
    ) -> Any:
5366
        """Verify an existing report format
5367
5368
        Verifies the trust level of an existing report format. It will be
5369
        checked whether the signature of the report format currently matches the
5370
        report format. This includes the script and files used to generate
5371
        reports of this format. It is *not* verified if the report format works
5372
        as expected by the user.
5373
5374
        Arguments:
5375
            report_format_id: UUID of the report format to be verified
5376
                              or ReportFormatType (enum)
5377
5378
        Returns:
5379
            The response. See :py:meth:`send_command` for details.
5380
        """
5381
        if not report_format_id:
5382
            raise RequiredArgument(
5383
                function=self.verify_report_format.__name__,
5384
                argument='report_format_id',
5385
            )
5386
5387
        cmd = XmlCommand("verify_report_format")
5388
5389
        if isinstance(report_format_id, ReportFormatType):
5390
            report_format_id = report_format_id.value
5391
5392
        cmd.set_attribute("report_format_id", report_format_id)
5393
5394
        return self._send_xml_command(cmd)
5395
5396
    def verify_scanner(self, scanner_id: str) -> Any:
5397
        """Verify an existing scanner
5398
5399
        Verifies if it is possible to connect to an existing scanner. It is
5400
        *not* verified if the scanner works as expected by the user.
5401
5402
        Arguments:
5403
            scanner_id: UUID of the scanner to be verified
5404
5405
        Returns:
5406
            The response. See :py:meth:`send_command` for details.
5407
        """
5408
        if not scanner_id:
5409
            raise RequiredArgument(
5410
                function=self.verify_scanner.__name__, argument='scanner_id'
5411
            )
5412
5413
        cmd = XmlCommand("verify_scanner")
5414
        cmd.set_attribute("scanner_id", scanner_id)
5415
5416
        return self._send_xml_command(cmd)
5417