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

GmpV208Mixin.sync_feed()   A

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2018-2021 Greenbone Networks GmbH
3
#
4
# SPDX-License-Identifier: GPL-3.0-or-later
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
# pylint: disable=arguments-differ, redefined-builtin, too-many-lines
20
21
"""
22
Module for communication with gvmd in
23
`Greenbone Management Protocol version 20.08`_
24
25
.. _Greenbone Management Protocol version 20.08:
26
    https://docs.greenbone.net/API/GMP/gmp-20.08.html
27
"""
28
import logging
29
from numbers import Integral
30
31
from typing import Any, List, Optional, Callable, Union
32
from lxml import etree
33
34
from gvm.connections import GvmConnection
35
from gvm.errors import InvalidArgument, InvalidArgumentType, RequiredArgument
36
from gvm.protocols.base import GvmProtocol
37
from gvm.protocols.gmpv208.entities.report_formats import (
38
    ReportFormatType,
39
)
40
from gvm.utils import (
41
    check_command_status,
42
    to_base64,
43
    to_bool,
44
    to_comma_list,
45
    add_filter,
46
)
47
from gvm.xml import XmlCommand
48
49
from . import types
50
from .types import *  # pylint: disable=unused-wildcard-import, wildcard-import
51
52
53
PROTOCOL_VERSION = (20, 8)
54
55
56
logger = logging.getLogger(__name__)
57
58
59
class GmpV208Mixin(GvmProtocol):
60
    """Python interface for Greenbone Management Protocol
61
62
    This class implements the `Greenbone Management Protocol version 20.08`_
63
64
    Arguments:
65
        connection: Connection to use to talk with the gvmd daemon. See
66
            :mod:`gvm.connections` for possible connection types.
67
        transform: Optional transform `callable`_ to convert response data.
68
            After each request the callable gets passed the plain response data
69
            which can be used to check the data and/or conversion into different
70
            representations like a xml dom.
71
72
            See :mod:`gvm.transforms` for existing transforms.
73
74
    .. _Greenbone Management Protocol version 20.08:
75
        https://docs.greenbone.net/API/GMP/gmp-20.08.html
76
    .. _callable:
77
        https://docs.python.org/3/library/functions.html#callable
78
    """
79
80
    types = types
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable types does not seem to be defined.
Loading history...
81
82
    def __init__(
83
        self,
84
        connection: GvmConnection,
85
        *,
86
        transform: Optional[Callable[[str], Any]] = None,
87
    ):
88
        super().__init__(connection, transform=transform)
89
90
        # Is authenticated on gvmd
91
        self._authenticated = False
92
93
    def is_authenticated(self) -> bool:
94
        """Checks if the user is authenticated
95
96
        If the user is authenticated privileged GMP commands like get_tasks
97
        may be send to gvmd.
98
99
        Returns:
100
            bool: True if an authenticated connection to gvmd has been
101
            established.
102
        """
103
        return self._authenticated
104
105
    def authenticate(self, username: str, password: str) -> Any:
106
        """Authenticate to gvmd.
107
108
        The generated authenticate command will be send to server.
109
        Afterwards the response is read, transformed and returned.
110
111
        Arguments:
112
            username: Username
113
            password: Password
114
115
        Returns:
116
            Transformed response from server.
117
        """
118
        cmd = XmlCommand("authenticate")
119
120
        if not username:
121
            raise RequiredArgument(
122
                function=self.authenticate.__name__, argument='username'
123
            )
124
125
        if not password:
126
            raise RequiredArgument(
127
                function=self.authenticate.__name__, argument='password'
128
            )
129
130
        credentials = cmd.add_element("credentials")
131
        credentials.add_element("username", username)
132
        credentials.add_element("password", password)
133
134
        self._send(cmd.to_string())
135
        response = self._read()
136
137
        if check_command_status(response):
138
            self._authenticated = True
139
140
        return self._transform(response)
141
142
    def create_permission(
143
        self,
144
        name: str,
145
        subject_id: str,
146
        subject_type: PermissionSubjectType,
147
        *,
148
        resource_id: Optional[str] = None,
149
        resource_type: Optional[EntityType] = None,
150
        comment: Optional[str] = None,
151
    ) -> Any:
152
        """Create a new permission
153
154
        Arguments:
155
            name: Name of the new permission
156
            subject_id: UUID of subject to whom the permission is granted
157
            subject_type: Type of the subject user, group or role
158
            comment: Comment for the permission
159
            resource_id: UUID of entity to which the permission applies
160
            resource_type: Type of the resource. For Super permissions user,
161
                group or role
162
163
        Returns:
164
            The response. See :py:meth:`send_command` for details.
165
        """
166
        if not name:
167
            raise RequiredArgument(
168
                function=self.create_permission.__name__, argument='name'
169
            )
170
171
        if not subject_id:
172
            raise RequiredArgument(
173
                function=self.create_permission.__name__, argument='subject_id'
174
            )
175
176
        if not isinstance(subject_type, PermissionSubjectType):
177
            raise InvalidArgumentType(
178
                function=self.create_permission.__name__,
179
                argument='subject_type',
180
                arg_type=PermissionSubjectType.__name__,
181
            )
182
183
        cmd = XmlCommand("create_permission")
184
        cmd.add_element("name", name)
185
186
        _xmlsubject = cmd.add_element("subject", attrs={"id": subject_id})
187
        _xmlsubject.add_element("type", subject_type.value)
188
189
        if comment:
190
            cmd.add_element("comment", comment)
191
192 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...
193
            if not resource_id:
194
                raise RequiredArgument(
195
                    function=self.create_permission.__name__,
196
                    argument='resource_id',
197
                )
198
199
            if not resource_type:
200
                raise RequiredArgument(
201
                    function=self.create_permission.__name__,
202
                    argument='resource_type',
203
                )
204
205
            if not isinstance(resource_type, self.types.EntityType):
206
                raise InvalidArgumentType(
207
                    function=self.create_permission.__name__,
208
                    argument='resource_type',
209
                    arg_type=self.types.EntityType.__name__,
210
                )
211
212
            _xmlresource = cmd.add_element(
213
                "resource", attrs={"id": resource_id}
214
            )
215
216
            _actual_resource_type = resource_type
217
            if resource_type.value == EntityType.AUDIT.value:
218
                _actual_resource_type = EntityType.TASK
219
            elif resource_type.value == EntityType.POLICY.value:
220
                _actual_resource_type = EntityType.SCAN_CONFIG
221
222
            _xmlresource.add_element("type", _actual_resource_type.value)
223
224
        return self._send_xml_command(cmd)
225
226
    def create_tag(
227
        self,
228
        name: str,
229
        resource_type: EntityType,
230
        *,
231
        resource_filter: Optional[str] = None,
232
        resource_ids: Optional[List[str]] = None,
233
        value: Optional[str] = None,
234
        comment: Optional[str] = None,
235
        active: Optional[bool] = None,
236
    ) -> Any:
237
        """Create a tag.
238
239
        Arguments:
240
            name: Name of the tag. A full tag name consisting of namespace and
241
                predicate e.g. `foo:bar`.
242
            resource_type: Entity type the tag is to be attached to.
243
            resource_filter: Filter term to select resources the tag is to be
244
                attached to. Only one of resource_filter or resource_ids can be
245
                provided.
246
            resource_ids: IDs of the resources the tag is to be attached to.
247
                Only one of resource_filter or resource_ids can be provided.
248
            value: Value associated with the tag.
249
            comment: Comment for the tag.
250
            active: Whether the tag should be active.
251
252
        Returns:
253
            The response. See :py:meth:`send_command` for details.
254
        """
255
        if not name:
256
            raise RequiredArgument(
257
                function=self.create_tag.__name__, argument='name'
258
            )
259
260
        if resource_filter and resource_ids:
261
            raise InvalidArgument(
262
                "create_tag accepts either resource_filter or resource_ids "
263
                "argument",
264
                function=self.create_tag.__name__,
265
            )
266
267
        if not resource_type:
268
            raise RequiredArgument(
269
                function=self.create_tag.__name__, argument='resource_type'
270
            )
271
272
        if not isinstance(resource_type, self.types.EntityType):
273
            raise InvalidArgumentType(
274
                function=self.create_tag.__name__,
275
                argument='resource_type',
276
                arg_type=EntityType.__name__,
277
            )
278
279
        cmd = XmlCommand('create_tag')
280
        cmd.add_element('name', name)
281
282
        _xmlresources = cmd.add_element("resources")
283
        if resource_filter is not None:
284
            _xmlresources.set_attribute("filter", resource_filter)
285
286
        for resource_id in resource_ids or []:
287
            _xmlresources.add_element(
288
                "resource", attrs={"id": str(resource_id)}
289
            )
290
291
        _actual_resource_type = resource_type
292
        if resource_type.value == EntityType.AUDIT.value:
293
            _actual_resource_type = EntityType.TASK
294
        elif resource_type.value == EntityType.POLICY.value:
295
            _actual_resource_type = EntityType.SCAN_CONFIG
296
        _xmlresources.add_element("type", _actual_resource_type.value)
297
298
        if comment:
299
            cmd.add_element("comment", comment)
300
301
        if value:
302
            cmd.add_element("value", value)
303
304
        if active is not None:
305
            if active:
306
                cmd.add_element("active", "1")
307
            else:
308
                cmd.add_element("active", "0")
309
310
        return self._send_xml_command(cmd)
311
312
    def get_aggregates(
313
        self,
314
        resource_type: EntityType,
315
        *,
316
        filter: Optional[str] = None,
317
        filter_id: Optional[str] = None,
318
        sort_criteria: Optional[list] = None,
319
        data_columns: Optional[list] = None,
320
        group_column: Optional[str] = None,
321
        subgroup_column: Optional[str] = None,
322
        text_columns: Optional[list] = None,
323
        first_group: Optional[int] = None,
324
        max_groups: Optional[int] = None,
325
        mode: Optional[int] = None,
326
        **kwargs,
327
    ) -> Any:
328
        """Request aggregated information on a resource / entity type
329
330
        Additional arguments can be set via the kwargs parameter for backward
331
        compatibility with older versions of python-gvm, but are not validated.
332
333
        Arguments:
334
            resource_type: The entity type to gather data from
335
            filter: Filter term to use for the query
336
            filter_id: UUID of an existing filter to use for the query
337
            sort_criteria: List of sort criteria (dicts that can contain
338
                a field, stat and order)
339
            data_columns: List of fields to aggregate data from
340
            group_column: The field to group the entities by
341
            subgroup_column: The field to further group the entities
342
                inside groups by
343
            text_columns: List of simple text columns which no statistics
344
                are calculated for
345
            first_group: The index of the first aggregate group to return
346
            max_groups: The maximum number of aggregate groups to return,
347
                -1 for all
348
            mode: Special mode for aggregation
349
350
        Returns:
351
            The response. See :py:meth:`send_command` for details.
352
        """
353
        if not resource_type:
354
            raise RequiredArgument(
355
                function=self.get_aggregates.__name__, argument='resource_type'
356
            )
357
358
        if not isinstance(resource_type, self.types.EntityType):
359
            raise InvalidArgumentType(
360
                function=self.get_aggregates.__name__,
361
                argument='resource_type',
362
                arg_type=self.types.EntityType.__name__,
363
            )
364
365
        cmd = XmlCommand('get_aggregates')
366
367
        _actual_resource_type = resource_type
368
        if resource_type.value == EntityType.AUDIT.value:
369
            _actual_resource_type = EntityType.TASK
370
            cmd.set_attribute('usage_type', 'audit')
371
        elif resource_type.value == EntityType.POLICY.value:
372
            _actual_resource_type = EntityType.SCAN_CONFIG
373
            cmd.set_attribute('usage_type', 'policy')
374
        elif resource_type.value == EntityType.SCAN_CONFIG.value:
375
            cmd.set_attribute('usage_type', 'scan')
376
        elif resource_type.value == EntityType.TASK.value:
377
            cmd.set_attribute('usage_type', 'scan')
378
        cmd.set_attribute('type', _actual_resource_type.value)
379
380
        add_filter(cmd, filter, filter_id)
381
382
        if first_group is not None:
383
            if not isinstance(first_group, int):
384
                raise InvalidArgumentType(
385
                    function=self.get_aggregates.__name__,
386
                    argument='first_group',
387
                    arg_type=int.__name__,
388
                )
389
            cmd.set_attribute('first_group', str(first_group))
390
391
        if max_groups is not None:
392
            if not isinstance(max_groups, int):
393
                raise InvalidArgumentType(
394
                    function=self.get_aggregates.__name__,
395
                    argument='max_groups',
396
                    arg_type=int.__name__,
397
                )
398
            cmd.set_attribute('max_groups', str(max_groups))
399
400
        if sort_criteria is not None:
401
            if not isinstance(sort_criteria, list):
402
                raise InvalidArgumentType(
403
                    function=self.get_aggregates.__name__,
404
                    argument='sort_criteria',
405
                    arg_type=list.__name__,
406
                )
407
            for sort in sort_criteria:
408
                if not isinstance(sort, dict):
409
                    raise InvalidArgumentType(
410
                        function=self.get_aggregates.__name__,
411
                        argument='sort_criteria',
412
                    )
413
414
                sort_elem = cmd.add_element('sort')
415
                if sort.get('field'):
416
                    sort_elem.set_attribute('field', sort.get('field'))
417
418
                if sort.get('stat'):
419
                    if isinstance(sort['stat'], AggregateStatistic):
420
                        sort_elem.set_attribute('stat', sort['stat'].value)
421
                    else:
422
                        stat = get_aggregate_statistic_from_string(sort['stat'])
423
                        sort_elem.set_attribute('stat', stat.value)
424
425
                if sort.get('order'):
426
                    if isinstance(sort['order'], SortOrder):
427
                        sort_elem.set_attribute('order', sort['order'].value)
428
                    else:
429
                        so = get_sort_order_from_string(sort['order'])
430
                        sort_elem.set_attribute('order', so.value)
431
432
        if data_columns is not None:
433
            if not isinstance(data_columns, list):
434
                raise InvalidArgumentType(
435
                    function=self.get_aggregates.__name__,
436
                    argument='data_columns',
437
                    arg_type=list.__name__,
438
                )
439
            for column in data_columns:
440
                cmd.add_element('data_column', column)
441
442
        if group_column is not None:
443
            cmd.set_attribute('group_column', group_column)
444
445
        if subgroup_column is not None:
446
            if not group_column:
447
                raise RequiredArgument(
448
                    '{} requires a group_column argument'
449
                    ' if subgroup_column is given'.format(
450
                        self.get_aggregates.__name__
451
                    ),
452
                    function=self.get_aggregates.__name__,
453
                    argument='subgroup_column',
454
                )
455
            cmd.set_attribute('subgroup_column', subgroup_column)
456
457
        if text_columns is not None:
458
            if not isinstance(text_columns, list):
459
                raise InvalidArgumentType(
460
                    function=self.get_aggregates.__name__,
461
                    argument='text_columns',
462
                    arg_type=list.__name__,
463
                )
464
            for column in text_columns:
465
                cmd.add_element('text_column', column)
466
467
        if mode is not None:
468
            cmd.set_attribute('mode', mode)
469
470
        # Add additional keyword args as attributes for backward compatibility.
471
        cmd.set_attributes(kwargs)
472
473
        return self._send_xml_command(cmd)
474
475
    def modify_permission(
476
        self,
477
        permission_id: str,
478
        *,
479
        comment: Optional[str] = None,
480
        name: Optional[str] = None,
481
        resource_id: Optional[str] = None,
482
        resource_type: Optional[EntityType] = None,
483
        subject_id: Optional[str] = None,
484
        subject_type: Optional[PermissionSubjectType] = None,
485
    ) -> Any:
486
        """Modifies an existing permission.
487
488
        Arguments:
489
            permission_id: UUID of permission to be modified.
490
            comment: The comment on the permission.
491
            name: Permission name, currently the name of a command.
492
            subject_id: UUID of subject to whom the permission is granted
493
            subject_type: Type of the subject user, group or role
494
            resource_id: UUID of entity to which the permission applies
495
            resource_type: Type of the resource. For Super permissions user,
496
                group or role
497
498
        Returns:
499
            The response. See :py:meth:`send_command` for details.
500
        """
501
        if not permission_id:
502
            raise RequiredArgument(
503
                function=self.modify_permission.__name__,
504
                argument='permission_id',
505
            )
506
507
        cmd = XmlCommand("modify_permission")
508
        cmd.set_attribute("permission_id", permission_id)
509
510
        if comment:
511
            cmd.add_element("comment", comment)
512
513
        if name:
514
            cmd.add_element("name", name)
515
516 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...
517
            if not resource_id:
518
                raise RequiredArgument(
519
                    function=self.modify_permission.__name__,
520
                    argument='resource_id',
521
                )
522
523
            if not resource_type:
524
                raise RequiredArgument(
525
                    function=self.modify_permission.__name__,
526
                    argument='resource_type',
527
                )
528
529
            if not isinstance(resource_type, self.types.EntityType):
530
                raise InvalidArgumentType(
531
                    function=self.modify_permission.__name__,
532
                    argument='resource_type',
533
                    arg_type=self.types.EntityType.__name__,
534
                )
535
536
            _xmlresource = cmd.add_element(
537
                "resource", attrs={"id": resource_id}
538
            )
539
            _actual_resource_type = resource_type
540
            if resource_type.value == EntityType.AUDIT.value:
541
                _actual_resource_type = EntityType.TASK
542
            elif resource_type.value == EntityType.POLICY.value:
543
                _actual_resource_type = EntityType.SCAN_CONFIG
544
            _xmlresource.add_element("type", _actual_resource_type.value)
545
546
        if subject_id or subject_type:
547
            if not subject_id:
548
                raise RequiredArgument(
549
                    function=self.modify_permission.__name__,
550
                    argument='subject_id',
551
                )
552
553
            if not isinstance(subject_type, PermissionSubjectType):
554
                raise InvalidArgumentType(
555
                    function=self.modify_permission.__name__,
556
                    argument='subject_type',
557
                    arg_type=PermissionSubjectType.__name__,
558
                )
559
560
            _xmlsubject = cmd.add_element("subject", attrs={"id": subject_id})
561
            _xmlsubject.add_element("type", subject_type.value)
562
563
        return self._send_xml_command(cmd)
564
565
    def modify_tag(
566
        self,
567
        tag_id: str,
568
        *,
569
        comment: Optional[str] = None,
570
        name: Optional[str] = None,
571
        value=None,
572
        active=None,
573
        resource_action: Optional[str] = None,
574
        resource_type: Optional[EntityType] = None,
575
        resource_filter: Optional[str] = None,
576
        resource_ids: Optional[List[str]] = None,
577
    ) -> Any:
578
        """Modifies an existing tag.
579
580
        Arguments:
581
            tag_id: UUID of the tag.
582
            comment: Comment to add to the tag.
583
            name: Name of the tag.
584
            value: Value of the tag.
585
            active: Whether the tag is active.
586
            resource_action: Whether to add or remove resources instead of
587
                overwriting. One of '', 'add', 'set' or 'remove'.
588
            resource_type: Type of the resources to which to attach the tag.
589
                Required if resource_filter is set.
590
            resource_filter: Filter term to select resources the tag is to be
591
                attached to.
592
            resource_ids: IDs of the resources to which to attach the tag.
593
594
        Returns:
595
            The response. See :py:meth:`send_command` for details.
596
        """
597
        if not tag_id:
598
            raise RequiredArgument(
599
                function=self.modify_tag.__name__, argument='tag_id'
600
            )
601
602
        cmd = XmlCommand("modify_tag")
603
        cmd.set_attribute("tag_id", str(tag_id))
604
605
        if comment:
606
            cmd.add_element("comment", comment)
607
608
        if name:
609
            cmd.add_element("name", name)
610
611
        if value:
612
            cmd.add_element("value", value)
613
614
        if active is not None:
615
            cmd.add_element("active", to_bool(active))
616
617
        if resource_action or resource_filter or resource_ids or resource_type:
618
            if resource_filter and not resource_type:
619
                raise RequiredArgument(
620
                    function=self.modify_tag.__name__, argument='resource_type'
621
                )
622
623
            _xmlresources = cmd.add_element("resources")
624
            if resource_action is not None:
625
                _xmlresources.set_attribute("action", resource_action)
626
627
            if resource_filter is not None:
628
                _xmlresources.set_attribute("filter", resource_filter)
629
630
            for resource_id in resource_ids or []:
631
                _xmlresources.add_element(
632
                    "resource", attrs={"id": str(resource_id)}
633
                )
634
635
            if resource_type is not None:
636
                if not isinstance(resource_type, self.types.EntityType):
637
                    raise InvalidArgumentType(
638
                        function=self.modify_tag.__name__,
639
                        argument="resource_type",
640
                        arg_type=EntityType.__name__,
641
                    )
642
                _actual_resource_type = resource_type
643
                if resource_type.value == EntityType.AUDIT.value:
644
                    _actual_resource_type = EntityType.TASK
645
                elif resource_type.value == EntityType.POLICY.value:
646
                    _actual_resource_type = EntityType.SCAN_CONFIG
647
                _xmlresources.add_element("type", _actual_resource_type.value)
648
649
        return self._send_xml_command(cmd)
650
651
    def clone_ticket(self, ticket_id: str) -> Any:
652
        """Clone an existing ticket
653
654
        Arguments:
655
            ticket_id: UUID of an existing ticket to clone from
656
657
        Returns:
658
            The response. See :py:meth:`send_command` for details.
659
        """
660
        if not ticket_id:
661
            raise RequiredArgument(
662
                function=self.clone_ticket.__name__, argument='ticket_id'
663
            )
664
665
        cmd = XmlCommand("create_ticket")
666
667
        _copy = cmd.add_element("copy", ticket_id)
668
669
        return self._send_xml_command(cmd)
670
671
    def get_feed(self, feed_type: Optional[FeedType]) -> Any:
672
        """Request a single feed
673
674
        Arguments:
675
            feed_type: Type of single feed to get: NVT, CERT or SCAP
676
677
        Returns:
678
            The response. See :py:meth:`send_command` for details.
679
        """
680
        if not feed_type:
681
            raise RequiredArgument(
682
                function=self.get_feed.__name__, argument='feed_type'
683
            )
684
685
        if not isinstance(feed_type, FeedType):
686
            raise InvalidArgumentType(
687
                function=self.get_feed.__name__,
688
                argument='feed_type',
689
                arg_type=FeedType.__name__,
690
            )
691
692
        cmd = XmlCommand("get_feeds")
693
        cmd.set_attribute("type", feed_type.value)
694
695
        return self._send_xml_command(cmd)
696
697
    def create_credential(
698
        self,
699
        name: str,
700
        credential_type: CredentialType,
701
        *,
702
        comment: Optional[str] = None,
703
        allow_insecure: Optional[bool] = None,
704
        certificate: Optional[str] = None,
705
        key_phrase: Optional[str] = None,
706
        private_key: Optional[str] = None,
707
        login: Optional[str] = None,
708
        password: Optional[str] = None,
709
        auth_algorithm: Optional[SnmpAuthAlgorithm] = None,
710
        community: Optional[str] = None,
711
        privacy_algorithm: Optional[SnmpPrivacyAlgorithm] = None,
712
        privacy_password: Optional[str] = None,
713
        public_key: Optional[str] = None,
714
    ) -> Any:
715
        """Create a new credential
716
717
        Create a new credential e.g. to be used in the method of an alert.
718
719
        Currently the following credential types are supported:
720
721
            - Username + Password
722
            - Username + SSH-Key
723
            - Client Certificates
724
            - SNMPv1 or SNMPv2c protocol
725
            - S/MIME Certificate
726
            - OpenPGP Key
727
            - Password only
728
729
        Arguments:
730
            name: Name of the new credential
731
            credential_type: The credential type.
732
            comment: Comment for the credential
733
            allow_insecure: Whether to allow insecure use of the credential
734
            certificate: Certificate for the credential.
735
                Required for client-certificate and smime credential types.
736
            key_phrase: Key passphrase for the private key.
737
                Used for the username+ssh-key credential type.
738
            private_key: Private key to use for login. Required
739
                for usk credential type. Also used for the cc credential type.
740
                The supported key types (dsa, rsa, ecdsa, ...) and formats (PEM,
741
                PKC#12, OpenSSL, ...) depend on your installed GnuTLS version.
742
            login: Username for the credential. Required for username+password,
743
                username+ssh-key and snmp credential type.
744
            password: Password for the credential. Used for username+password
745
                and snmp credential types.
746
            community: The SNMP community
747
            auth_algorithm: The SNMP authentication algorithm. Required for snmp
748
                credential type.
749
            privacy_algorithm: The SNMP privacy algorithm
750
            privacy_password: The SNMP privacy password
751
            public_key: PGP public key in *armor* plain text format. Required
752
                for pgp credential type.
753
754
        Examples:
755
            Creating a Username + Password credential
756
757
            .. code-block:: python
758
759
                gmp.create_credential(
760
                    name='UP Credential',
761
                    credential_type=CredentialType.USERNAME_PASSWORD,
762
                    login='foo',
763
                    password='bar',
764
                )
765
766
            Creating a Username + SSH Key credential
767
768
            .. code-block:: python
769
770
                with open('path/to/private-ssh-key') as f:
771
                    key = f.read()
772
773
                gmp.create_credential(
774
                    name='USK Credential',
775
                    credential_type=CredentialType.USERNAME_SSH_KEY,
776
                    login='foo',
777
                    key_phrase='foobar',
778
                    private_key=key,
779
                )
780
781
            Creating a PGP credential
782
783
            .. note::
784
785
                A compatible public pgp key file can be exported with GnuPG via
786
                ::
787
788
                    $ gpg --armor --export [email protected] > alice.asc
789
790
            .. code-block:: python
791
792
                with open('path/to/pgp.key.asc') as f:
793
                    key = f.read()
794
795
                gmp.create_credential(
796
                    name='PGP Credential',
797
                    credential_type=CredentialType.PGP_ENCRYPTION_KEY,
798
                    public_key=key,
799
                )
800
801
            Creating a S/MIME credential
802
803
            .. code-block:: python
804
805
                with open('path/to/smime-cert') as f:
806
                    cert = f.read()
807
808
                gmp.create_credential(
809
                    name='SMIME Credential',
810
                    credential_type=CredentialType.SMIME_CERTIFICATE,
811
                    certificate=cert,
812
                )
813
814
            Creating a Password-Only credential
815
816
            .. code-block:: python
817
818
                gmp.create_credential(
819
                    name='Password-Only Credential',
820
                    credential_type=CredentialType.PASSWORD_ONLY,
821
                    password='foo',
822
                )
823
        Returns:
824
            The response. See :py:meth:`send_command` for details.
825
        """
826
        if not name:
827
            raise RequiredArgument(
828
                function=self.create_credential.__name__, argument='name'
829
            )
830
831
        if not isinstance(credential_type, self.types.CredentialType):
832
            raise InvalidArgumentType(
833
                function=self.create_credential.__name__,
834
                argument='credential_type',
835
                arg_type=CredentialType.__name__,
836
            )
837
838
        cmd = XmlCommand("create_credential")
839
        cmd.add_element("name", name)
840
841
        cmd.add_element("type", credential_type.value)
842
843
        if comment:
844
            cmd.add_element("comment", comment)
845
846
        if allow_insecure is not None:
847
            cmd.add_element("allow_insecure", to_bool(allow_insecure))
848
849
        if (
850
            credential_type == CredentialType.CLIENT_CERTIFICATE
851
            or credential_type == CredentialType.SMIME_CERTIFICATE
852
        ):
853
            if not certificate:
854
                raise RequiredArgument(
855
                    function=self.create_credential.__name__,
856
                    argument='certificate',
857
                )
858
859
            cmd.add_element("certificate", certificate)
860
861
        if (
862
            credential_type == CredentialType.USERNAME_PASSWORD
863
            or credential_type == CredentialType.USERNAME_SSH_KEY
864
            or credential_type == CredentialType.SNMP
865
        ):
866
            if not login:
867
                raise RequiredArgument(
868
                    function=self.create_credential.__name__, argument='login'
869
                )
870
871
            cmd.add_element("login", login)
872
873
        if credential_type == CredentialType.PASSWORD_ONLY and not password:
874
            raise RequiredArgument(
875
                function=self.create_credential.__name__, argument='password'
876
            )
877
878
        if (
879
            credential_type == CredentialType.USERNAME_PASSWORD
880
            or credential_type == CredentialType.SNMP
881
            or credential_type == CredentialType.PASSWORD_ONLY
882
        ) and password:
883
            cmd.add_element("password", password)
884
885
        if credential_type == CredentialType.USERNAME_SSH_KEY:
886
            if not private_key:
887
                raise RequiredArgument(
888
                    function=self.create_credential.__name__,
889
                    argument='private_key',
890
                )
891
892
            _xmlkey = cmd.add_element("key")
893
            _xmlkey.add_element("private", private_key)
894
895
            if key_phrase:
896
                _xmlkey.add_element("phrase", key_phrase)
897
898
        if credential_type == CredentialType.CLIENT_CERTIFICATE and private_key:
899
            _xmlkey = cmd.add_element("key")
900
            _xmlkey.add_element("private", private_key)
901
902
        if credential_type == CredentialType.SNMP:
903
            if not isinstance(auth_algorithm, self.types.SnmpAuthAlgorithm):
904
                raise InvalidArgumentType(
905
                    function=self.create_credential.__name__,
906
                    argument='auth_algorithm',
907
                    arg_type=SnmpAuthAlgorithm.__name__,
908
                )
909
910
            cmd.add_element("auth_algorithm", auth_algorithm.value)
911
912
            if community:
913
                cmd.add_element("community", community)
914
915 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...
916
                _xmlprivacy = cmd.add_element("privacy")
917
918
                if privacy_algorithm is not None:
919
                    if not isinstance(
920
                        privacy_algorithm, self.types.SnmpPrivacyAlgorithm
921
                    ):
922
                        raise InvalidArgumentType(
923
                            function=self.create_credential.__name__,
924
                            argument='privacy_algorithm',
925
                            arg_type=SnmpPrivacyAlgorithm.__name__,
926
                        )
927
928
                    _xmlprivacy.add_element(
929
                        "algorithm", privacy_algorithm.value
930
                    )
931
932
                if privacy_password:
933
                    _xmlprivacy.add_element("password", privacy_password)
934
935
        if credential_type == CredentialType.PGP_ENCRYPTION_KEY:
936
            if not public_key:
937
                raise RequiredArgument(
938
                    function=self.create_credential.__name__,
939
                    argument='public_key',
940
                )
941
942
            _xmlkey = cmd.add_element("key")
943
            _xmlkey.add_element("public", public_key)
944
945
        return self._send_xml_command(cmd)
946
947
    def modify_credential(
948
        self,
949
        credential_id: str,
950
        *,
951
        name: Optional[str] = None,
952
        comment: Optional[str] = None,
953
        allow_insecure: Optional[bool] = None,
954
        certificate: Optional[str] = None,
955
        key_phrase: Optional[str] = None,
956
        private_key: Optional[str] = None,
957
        login: Optional[str] = None,
958
        password: Optional[str] = None,
959
        auth_algorithm: Optional[SnmpAuthAlgorithm] = None,
960
        community: Optional[str] = None,
961
        privacy_algorithm: Optional[SnmpPrivacyAlgorithm] = None,
962
        privacy_password: Optional[str] = None,
963
        public_key: Optional[str] = None,
964
    ) -> Any:
965
        """Modifies an existing credential.
966
967
        Arguments:
968
            credential_id: UUID of the credential
969
            name: Name of the credential
970
            comment: Comment for the credential
971
            allow_insecure: Whether to allow insecure use of the credential
972
            certificate: Certificate for the credential
973
            key_phrase: Key passphrase for the private key
974
            private_key: Private key to use for login
975
            login: Username for the credential
976
            password: Password for the credential
977
            auth_algorithm: The authentication algorithm for SNMP
978
            community: The SNMP community
979
            privacy_algorithm: The privacy algorithm for SNMP
980
            privacy_password: The SNMP privacy password
981
            public_key: PGP public key in *armor* plain text format
982
983
        Returns:
984
            The response. See :py:meth:`send_command` for details.
985
        """
986
        if not credential_id:
987
            raise RequiredArgument(
988
                function=self.modify_credential.__name__,
989
                argument='credential_id',
990
            )
991
992
        cmd = XmlCommand("modify_credential")
993
        cmd.set_attribute("credential_id", credential_id)
994
995
        if comment:
996
            cmd.add_element("comment", comment)
997
998
        if name:
999
            cmd.add_element("name", name)
1000
1001
        if allow_insecure is not None:
1002
            cmd.add_element("allow_insecure", to_bool(allow_insecure))
1003
1004
        if certificate:
1005
            cmd.add_element("certificate", certificate)
1006
1007
        if key_phrase and private_key:
1008
            _xmlkey = cmd.add_element("key")
1009
            _xmlkey.add_element("phrase", key_phrase)
1010
            _xmlkey.add_element("private", private_key)
1011
        elif (not key_phrase and private_key) or (
1012
            key_phrase and not private_key
1013
        ):
1014
            raise RequiredArgument(
1015
                function=self.modify_credential.__name__,
1016
                argument='key_phrase and private_key',
1017
            )
1018
1019
        if login:
1020
            cmd.add_element("login", login)
1021
1022
        if password:
1023
            cmd.add_element("password", password)
1024
1025
        if auth_algorithm:
1026
            if not isinstance(auth_algorithm, self.types.SnmpAuthAlgorithm):
1027
                raise InvalidArgumentType(
1028
                    function=self.modify_credential.__name__,
1029
                    argument='auth_algorithm',
1030
                    arg_type=SnmpAuthAlgorithm.__name__,
1031
                )
1032
            cmd.add_element("auth_algorithm", auth_algorithm.value)
1033
1034
        if community:
1035
            cmd.add_element("community", community)
1036
1037 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...
1038
            _xmlprivacy = cmd.add_element("privacy")
1039
1040
            if privacy_algorithm is not None:
1041
                if not isinstance(
1042
                    privacy_algorithm, self.types.SnmpPrivacyAlgorithm
1043
                ):
1044
                    raise InvalidArgumentType(
1045
                        function=self.modify_credential.__name__,
1046
                        argument='privacy_algorithm',
1047
                        arg_type=SnmpPrivacyAlgorithm.__name__,
1048
                    )
1049
1050
                _xmlprivacy.add_element("algorithm", privacy_algorithm.value)
1051
1052
            if privacy_password is not None:
1053
                _xmlprivacy.add_element("password", privacy_password)
1054
1055
        if public_key:
1056
            _xmlkey = cmd.add_element("key")
1057
            _xmlkey.add_element("public", public_key)
1058
1059
        return self._send_xml_command(cmd)
1060
1061
    def create_ticket(
1062
        self,
1063
        *,
1064
        result_id: str,
1065
        assigned_to_user_id: str,
1066
        note: str,
1067
        comment: Optional[str] = None,
1068
    ) -> Any:
1069
        """Create a new ticket
1070
1071
        Arguments:
1072
            result_id: UUID of the result the ticket applies to
1073
            assigned_to_user_id: UUID of a user the ticket should be assigned to
1074
            note: A note about opening the ticket
1075
            comment: Comment for the ticket
1076
1077
        Returns:
1078
            The response. See :py:meth:`send_command` for details.
1079
        """
1080
        if not result_id:
1081
            raise RequiredArgument(
1082
                function=self.create_ticket.__name__, argument='result_id'
1083
            )
1084
1085
        if not assigned_to_user_id:
1086
            raise RequiredArgument(
1087
                function=self.create_ticket.__name__,
1088
                argument='assigned_to_user_id',
1089
            )
1090
1091
        if not note:
1092
            raise RequiredArgument(
1093
                function=self.create_ticket.__name__, argument='note'
1094
            )
1095
1096
        cmd = XmlCommand("create_ticket")
1097
1098
        _result = cmd.add_element("result")
1099
        _result.set_attribute("id", result_id)
1100
1101
        _assigned = cmd.add_element("assigned_to")
1102
        _user = _assigned.add_element("user")
1103
        _user.set_attribute("id", assigned_to_user_id)
1104
1105
        _note = cmd.add_element("open_note", note)
1106
1107
        if comment:
1108
            cmd.add_element("comment", comment)
1109
1110
        return self._send_xml_command(cmd)
1111
1112
    def delete_ticket(
1113
        self, ticket_id: str, *, ultimate: Optional[bool] = False
1114
    ):
1115
        """Deletes an existing ticket
1116
1117
        Arguments:
1118
            ticket_id: UUID of the ticket to be deleted.
1119
            ultimate: Whether to remove entirely, or to the trashcan.
1120
        """
1121
        if not ticket_id:
1122
            raise RequiredArgument(
1123
                function=self.delete_ticket.__name__, argument='ticket_id'
1124
            )
1125
1126
        cmd = XmlCommand("delete_ticket")
1127
        cmd.set_attribute("ticket_id", ticket_id)
1128
        cmd.set_attribute("ultimate", to_bool(ultimate))
1129
1130
        return self._send_xml_command(cmd)
1131
1132 View Code Duplication
    def get_tickets(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1133
        self,
1134
        *,
1135
        trash: Optional[bool] = None,
1136
        filter: Optional[str] = None,
1137
        filter_id: Optional[str] = None,
1138
    ) -> Any:
1139
        """Request a list of tickets
1140
1141
        Arguments:
1142
            filter: Filter term to use for the query
1143
            filter_id: UUID of an existing filter to use for the query
1144
            trash: True to request the tickets in the trashcan
1145
1146
        Returns:
1147
            The response. See :py:meth:`send_command` for details.
1148
        """
1149
        cmd = XmlCommand("get_tickets")
1150
1151
        add_filter(cmd, filter, filter_id)
1152
1153
        if trash is not None:
1154
            cmd.set_attribute("trash", to_bool(trash))
1155
1156
        return self._send_xml_command(cmd)
1157
1158
    def get_ticket(self, ticket_id: str) -> Any:
1159
        """Request a single ticket
1160
1161
        Arguments:
1162
            ticket_id: UUID of an existing ticket
1163
1164
        Returns:
1165
            The response. See :py:meth:`send_command` for details.
1166
        """
1167
        if not ticket_id:
1168
            raise RequiredArgument(
1169
                function=self.get_ticket.__name__, argument='ticket_id'
1170
            )
1171
1172
        cmd = XmlCommand("get_tickets")
1173
        cmd.set_attribute("ticket_id", ticket_id)
1174
        return self._send_xml_command(cmd)
1175
1176
    def get_vulnerabilities(
1177
        self, *, filter: Optional[str] = None, filter_id: Optional[str] = None
1178
    ) -> Any:
1179
        """Request a list of vulnerabilities
1180
1181
        Arguments:
1182
            filter: Filter term to use for the query
1183
            filter_id: UUID of an existing filter to use for the query
1184
        Returns:
1185
            The response. See :py:meth:`send_command` for details.
1186
        """
1187
        cmd = XmlCommand("get_vulns")
1188
1189
        add_filter(cmd, filter, filter_id)
1190
1191
        return self._send_xml_command(cmd)
1192
1193
    def get_vulnerability(self, vulnerability_id: str) -> Any:
1194
        """Request a single vulnerability
1195
1196
        Arguments:
1197
            vulnerability_id: ID of an existing vulnerability
1198
1199
        Returns:
1200
            The response. See :py:meth:`send_command` for details.
1201
        """
1202
        if not vulnerability_id:
1203
            raise RequiredArgument(
1204
                function=self.get_vulnerability.__name__,
1205
                argument='vulnerability_id',
1206
            )
1207
1208
        cmd = XmlCommand("get_vulns")
1209
        cmd.set_attribute("vuln_id", vulnerability_id)
1210
        return self._send_xml_command(cmd)
1211
1212
    def modify_ticket(
1213
        self,
1214
        ticket_id: str,
1215
        *,
1216
        status: Optional[TicketStatus] = None,
1217
        note: Optional[str] = None,
1218
        assigned_to_user_id: Optional[str] = None,
1219
        comment: Optional[str] = None,
1220
    ) -> Any:
1221
        """Modify a single ticket
1222
1223
        Arguments:
1224
            ticket_id: UUID of an existing ticket
1225
            status: New status for the ticket
1226
            note: Note for the status change. Required if status is set.
1227
            assigned_to_user_id: UUID of the user the ticket should be assigned
1228
                to
1229
            comment: Comment for the ticket
1230
1231
        Returns:
1232
            The response. See :py:meth:`send_command` for details.
1233
        """
1234
        if not ticket_id:
1235
            raise RequiredArgument(
1236
                function=self.modify_ticket.__name__, argument='ticket_id'
1237
            )
1238
1239
        if status and not note:
1240
            raise RequiredArgument(
1241
                function=self.modify_ticket.__name__, argument='note'
1242
            )
1243
1244
        if note and not status:
1245
            raise RequiredArgument(
1246
                function=self.modify_ticket.__name__, argument='status'
1247
            )
1248
1249
        cmd = XmlCommand("modify_ticket")
1250
        cmd.set_attribute("ticket_id", ticket_id)
1251
1252
        if assigned_to_user_id:
1253
            _assigned = cmd.add_element("assigned_to")
1254
            _user = _assigned.add_element("user")
1255
            _user.set_attribute("id", assigned_to_user_id)
1256
1257
        if status:
1258
            if not isinstance(status, self.types.TicketStatus):
1259
                raise InvalidArgumentType(
1260
                    function=self.modify_ticket.__name__,
1261
                    argument='status',
1262
                    arg_type=TicketStatus.__name__,
1263
                )
1264
1265
            cmd.add_element('status', status.value)
1266
            cmd.add_element('{}_note'.format(status.name.lower()), note)
1267
1268
        if comment:
1269
            cmd.add_element("comment", comment)
1270
1271
        return self._send_xml_command(cmd)
1272
1273 View Code Duplication
    def create_filter(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1274
        self,
1275
        name: str,
1276
        *,
1277
        filter_type: Optional[FilterType] = None,
1278
        comment: Optional[str] = None,
1279
        term: Optional[str] = None,
1280
    ) -> Any:
1281
        """Create a new filter
1282
1283
        Arguments:
1284
            name: Name of the new filter
1285
            filter_type: Filter for entity type
1286
            comment: Comment for the filter
1287
            term: Filter term e.g. 'name=foo'
1288
1289
        Returns:
1290
            The response. See :py:meth:`send_command` for details.
1291
        """
1292
        if not name:
1293
            raise RequiredArgument(
1294
                function=self.create_filter.__name__, argument="name"
1295
            )
1296
1297
        cmd = XmlCommand("create_filter")
1298
        _xmlname = cmd.add_element("name", name)
1299
1300
        if comment:
1301
            cmd.add_element("comment", comment)
1302
1303
        if term:
1304
            cmd.add_element("term", term)
1305
1306
        if filter_type:
1307
            if not isinstance(filter_type, self.types.FilterType):
1308
                raise InvalidArgumentType(
1309
                    function=self.create_filter.__name__,
1310
                    argument="filter_type",
1311
                    arg_type=self.types.FilterType.__name__,
1312
                )
1313
1314
            cmd.add_element("type", filter_type.value)
1315
1316
        return self._send_xml_command(cmd)
1317
1318 View Code Duplication
    def modify_filter(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1319
        self,
1320
        filter_id: str,
1321
        *,
1322
        comment: Optional[str] = None,
1323
        name: Optional[str] = None,
1324
        term: Optional[str] = None,
1325
        filter_type: Optional[FilterType] = None,
1326
    ) -> Any:
1327
        """Modifies an existing filter.
1328
1329
        Arguments:
1330
            filter_id: UUID of the filter to be modified
1331
            comment: Comment on filter.
1332
            name: Name of filter.
1333
            term: Filter term.
1334
            filter_type: Resource type filter applies to.
1335
1336
        Returns:
1337
            The response. See :py:meth:`send_command` for details.
1338
        """
1339
        if not filter_id:
1340
            raise RequiredArgument(
1341
                function=self.modify_filter.__name__, argument='filter_id'
1342
            )
1343
1344
        cmd = XmlCommand("modify_filter")
1345
        cmd.set_attribute("filter_id", filter_id)
1346
1347
        if comment:
1348
            cmd.add_element("comment", comment)
1349
1350
        if name:
1351
            cmd.add_element("name", name)
1352
1353
        if term:
1354
            cmd.add_element("term", term)
1355
1356
        if filter_type:
1357
            if not isinstance(filter_type, self.types.FilterType):
1358
                raise InvalidArgumentType(
1359
                    function=self.modify_filter.__name__,
1360
                    argument='filter_type',
1361
                    arg_type=FilterType.__name__,
1362
                )
1363
            cmd.add_element("type", filter_type.value)
1364
1365
        return self._send_xml_command(cmd)
1366
1367
    def create_schedule(
1368
        self,
1369
        name: str,
1370
        icalendar: str,
1371
        timezone: str,
1372
        *,
1373
        comment: Optional[str] = None,
1374
    ) -> Any:
1375
        """Create a new schedule based in `iCalendar`_ data.
1376
1377
        Example:
1378
            Requires https://pypi.org/project/icalendar/
1379
1380
            .. code-block:: python
1381
1382
                import pytz
1383
1384
                from datetime import datetime
1385
1386
                from icalendar import Calendar, Event
1387
1388
                cal = Calendar()
1389
1390
                cal.add('prodid', '-//Foo Bar//')
1391
                cal.add('version', '2.0')
1392
1393
                event = Event()
1394
                event.add('dtstamp', datetime.now(tz=pytz.UTC))
1395
                event.add('dtstart', datetime(2020, 1, 1, tzinfo=pytz.utc))
1396
1397
                cal.add_component(event)
1398
1399
                gmp.create_schedule(
1400
                    name="My Schedule",
1401
                    icalendar=cal.to_ical(),
1402
                    timezone='UTC'
1403
                )
1404
1405
1406
        Arguments:
1407
            name: Name of the new schedule
1408
            icalendar: `iCalendar`_ (RFC 5545) based data.
1409
            timezone: Timezone to use for the icalender events e.g
1410
                Europe/Berlin. If the datetime values in the icalendar data are
1411
                missing timezone information this timezone gets applied.
1412
                Otherwise the datetime values from the icalendar data are
1413
                displayed in this timezone
1414
            comment: Comment on schedule.
1415
1416
        Returns:
1417
            The response. See :py:meth:`send_command` for details.
1418
1419
        .. _iCalendar:
1420
            https://tools.ietf.org/html/rfc5545
1421
        """
1422
        if not name:
1423
            raise RequiredArgument(
1424
                function=self.create_schedule.__name__, argument='name'
1425
            )
1426
        if not icalendar:
1427
            raise RequiredArgument(
1428
                function=self.create_schedule.__name__, argument='icalendar'
1429
            )
1430
        if not timezone:
1431
            raise RequiredArgument(
1432
                function=self.create_schedule.__name__, argument='timezone'
1433
            )
1434
1435
        cmd = XmlCommand("create_schedule")
1436
1437
        cmd.add_element("name", name)
1438
        cmd.add_element("icalendar", icalendar)
1439
        cmd.add_element("timezone", timezone)
1440
1441
        if comment:
1442
            cmd.add_element("comment", comment)
1443
1444
        return self._send_xml_command(cmd)
1445
1446
    def modify_schedule(
1447
        self,
1448
        schedule_id: str,
1449
        *,
1450
        name: Optional[str] = None,
1451
        icalendar: Optional[str] = None,
1452
        timezone: Optional[str] = None,
1453
        comment: Optional[str] = None,
1454
    ) -> Any:
1455
        """Modifies an existing schedule
1456
1457
        Arguments:
1458
            schedule_id: UUID of the schedule to be modified
1459
            name: Name of the schedule
1460
            icalendar: `iCalendar`_ (RFC 5545) based data.
1461
            timezone: Timezone to use for the icalender events e.g
1462
                Europe/Berlin. If the datetime values in the icalendar data are
1463
                missing timezone information this timezone gets applied.
1464
                Otherwise the datetime values from the icalendar data are
1465
                displayed in this timezone
1466
            commenhedule.
1467
1468
        Returns:
1469
            The response. See :py:meth:`send_command` for details.
1470
1471
        .. _iCalendar:
1472
            https://tools.ietf.org/html/rfc5545
1473
        """
1474
        if not schedule_id:
1475
            raise RequiredArgument(
1476
                function=self.modify_schedule.__name__, argument='schedule_id'
1477
            )
1478
1479
        cmd = XmlCommand("modify_schedule")
1480
        cmd.set_attribute("schedule_id", schedule_id)
1481
1482
        if name:
1483
            cmd.add_element("name", name)
1484
1485
        if icalendar:
1486
            cmd.add_element("icalendar", icalendar)
1487
1488
        if timezone:
1489
            cmd.add_element("timezone", timezone)
1490
1491
        if comment:
1492
            cmd.add_element("comment", comment)
1493
1494
        return self._send_xml_command(cmd)
1495
1496
    def clone_credential(self, credential_id: str) -> Any:
1497
        """Clone an existing credential
1498
1499
        Arguments:
1500
            credential_id: UUID of an existing credential to clone from
1501
1502
        Returns:
1503
            The response. See :py:meth:`send_command` for details.
1504
        """
1505
        if not credential_id:
1506
            raise RequiredArgument(
1507
                function=self.clone_credential.__name__,
1508
                argument='credential_id',
1509
            )
1510
1511
        cmd = XmlCommand("create_credential")
1512
        cmd.add_element("copy", credential_id)
1513
        return self._send_xml_command(cmd)
1514
1515
    def clone_filter(self, filter_id: str) -> Any:
1516
        """Clone an existing filter
1517
1518
        Arguments:
1519
            filter_id: UUID of an existing filter to clone from
1520
1521
        Returns:
1522
            The response. See :py:meth:`send_command` for details.
1523
        """
1524
        if not filter_id:
1525
            raise RequiredArgument(
1526
                function=self.clone_filter.__name__, argument='filter_id'
1527
            )
1528
1529
        cmd = XmlCommand("create_filter")
1530
        cmd.add_element("copy", filter_id)
1531
        return self._send_xml_command(cmd)
1532
1533
    def create_group(
1534
        self,
1535
        name: str,
1536
        *,
1537
        comment: Optional[str] = None,
1538
        special: Optional[bool] = False,
1539
        users: Optional[List[str]] = None,
1540
    ) -> Any:
1541
        """Create a new group
1542
1543
        Arguments:
1544
            name: Name of the new group
1545
            comment: Comment for the group
1546
            special: Create permission giving members full access to each
1547
                other's entities
1548
            users: List of user names to be in the group
1549
1550
        Returns:
1551
            The response. See :py:meth:`send_command` for details.
1552
        """
1553
        if not name:
1554
            raise RequiredArgument(
1555
                function=self.create_group.__name__, argument='name'
1556
            )
1557
1558
        cmd = XmlCommand("create_group")
1559
        cmd.add_element("name", name)
1560
1561
        if comment:
1562
            cmd.add_element("comment", comment)
1563
1564
        if special:
1565
            _xmlspecial = cmd.add_element("specials")
1566
            _xmlspecial.add_element("full")
1567
1568
        if users:
1569
            cmd.add_element("users", to_comma_list(users))
1570
1571
        return self._send_xml_command(cmd)
1572
1573
    def clone_group(self, group_id: str) -> Any:
1574
        """Clone an existing group
1575
1576
        Arguments:
1577
            group_id: UUID of an existing group to clone from
1578
1579
        Returns:
1580
            The response. See :py:meth:`send_command` for details.
1581
        """
1582
        if not group_id:
1583
            raise RequiredArgument(
1584
                function=self.clone_group.__name__, argument='group_id'
1585
            )
1586
1587
        cmd = XmlCommand("create_group")
1588
        cmd.add_element("copy", group_id)
1589
        return self._send_xml_command(cmd)
1590
1591
    def clone_permission(self, permission_id: str) -> Any:
1592
        """Clone an existing permission
1593
1594
        Arguments:
1595
            permission_id: UUID of an existing permission to clone from
1596
1597
        Returns:
1598
            The response. See :py:meth:`send_command` for details.
1599
        """
1600
        if not permission_id:
1601
            raise RequiredArgument(
1602
                function=self.clone_permission.__name__,
1603
                argument='permission_id',
1604
            )
1605
1606
        cmd = XmlCommand("create_permission")
1607
        cmd.add_element("copy", permission_id)
1608
        return self._send_xml_command(cmd)
1609
1610
    def clone_report_format(
1611
        self, report_format_id: [Union[str, ReportFormatType]]
1612
    ) -> Any:
1613
        """Clone a report format from an existing one
1614
1615
        Arguments:
1616
            report_format_id: UUID of the existing report format
1617
                              or ReportFormatType (enum)
1618
1619
        Returns:
1620
            The response. See :py:meth:`send_command` for details.
1621
        """
1622
        if not report_format_id:
1623
            raise RequiredArgument(
1624
                function=self.clone_report_format.__name__,
1625
                argument='report_format_id',
1626
            )
1627
1628
        cmd = XmlCommand("create_report_format")
1629
1630
        if isinstance(report_format_id, ReportFormatType):
1631
            report_format_id = report_format_id.value
1632
1633
        cmd.add_element("copy", report_format_id)
1634
        return self._send_xml_command(cmd)
1635
1636
    def import_report_format(self, report_format: str) -> Any:
1637
        """Import a report format from XML
1638
1639
        Arguments:
1640
            report_format: Report format XML as string to import. This XML must
1641
                contain a :code:`<get_report_formats_response>` root element.
1642
1643
        Returns:
1644
            The response. See :py:meth:`send_command` for details.
1645
        """
1646
        if not report_format:
1647
            raise RequiredArgument(
1648
                function=self.import_report_format.__name__,
1649
                argument='report_format',
1650
            )
1651
1652
        cmd = XmlCommand("create_report_format")
1653
1654
        try:
1655
            cmd.append_xml_str(report_format)
1656
        except etree.XMLSyntaxError as e:
1657
            raise InvalidArgument(
1658
                function=self.import_report_format.__name__,
1659
                argument='report_format',
1660
            ) from e
1661
1662
        return self._send_xml_command(cmd)
1663
1664
    def create_role(
1665
        self,
1666
        name: str,
1667
        *,
1668
        comment: Optional[str] = None,
1669
        users: Optional[List[str]] = None,
1670
    ) -> Any:
1671
        """Create a new role
1672
1673
        Arguments:
1674
            name: Name of the role
1675
            comment: Comment for the role
1676
            users: List of user names to add to the role
1677
1678
        Returns:
1679
            The response. See :py:meth:`send_command` for details.
1680
        """
1681
1682
        if not name:
1683
            raise RequiredArgument(
1684
                function=self.create_role.__name__, argument='name'
1685
            )
1686
1687
        cmd = XmlCommand("create_role")
1688
        cmd.add_element("name", name)
1689
1690
        if comment:
1691
            cmd.add_element("comment", comment)
1692
1693
        if users:
1694
            cmd.add_element("users", to_comma_list(users))
1695
1696
        return self._send_xml_command(cmd)
1697
1698
    def clone_role(self, role_id: str) -> Any:
1699
        """Clone an existing role
1700
1701
        Arguments:
1702
            role_id: UUID of an existing role to clone from
1703
1704
        Returns:
1705
            The response. See :py:meth:`send_command` for details.
1706
        """
1707
        if not role_id:
1708
            raise RequiredArgument(
1709
                function=self.clone_role.__name__, argument='role_id'
1710
            )
1711
1712
        cmd = XmlCommand("create_role")
1713
        cmd.add_element("copy", role_id)
1714
        return self._send_xml_command(cmd)
1715
1716
    def create_scanner(
1717
        self,
1718
        name: str,
1719
        host: str,
1720
        port: int,
1721
        scanner_type: ScannerType,
1722
        credential_id: str,
1723
        *,
1724
        ca_pub: Optional[str] = None,
1725
        comment: Optional[str] = None,
1726
    ) -> Any:
1727
        """Create a new scanner
1728
1729
        Arguments:
1730
            name: Name of the scanner
1731
            host: The host of the scanner
1732
            port: The port of the scanner
1733
            scanner_type: Type of the scanner.
1734
            credential_id: UUID of client certificate credential for the
1735
                scanner
1736
            ca_pub: Certificate of CA to verify scanner certificate
1737
            comment: Comment for the scanner
1738
        Returns:
1739
            The response. See :py:meth:`send_command` for details.
1740
        """
1741
        if not name:
1742
            raise RequiredArgument(
1743
                function=self.create_scanner.__name__, argument='name'
1744
            )
1745
1746
        if not host:
1747
            raise RequiredArgument(
1748
                function=self.create_scanner.__name__, argument='host'
1749
            )
1750
1751
        if not port:
1752
            raise RequiredArgument(
1753
                function=self.create_scanner.__name__, argument='port'
1754
            )
1755
1756
        if not scanner_type:
1757
            raise RequiredArgument(
1758
                function=self.create_scanner.__name__, argument='scanner_type'
1759
            )
1760
1761
        if not credential_id:
1762
            raise RequiredArgument(
1763
                function=self.create_scanner.__name__, argument='credential_id'
1764
            )
1765
1766
        if not isinstance(scanner_type, self.types.ScannerType):
1767
            raise InvalidArgumentType(
1768
                function=self.create_scanner.__name__,
1769
                argument='scanner_type',
1770
                arg_type=self.types.ScannerType.__name__,
1771
            )
1772
1773
        cmd = XmlCommand("create_scanner")
1774
        cmd.add_element("name", name)
1775
        cmd.add_element("host", host)
1776
        cmd.add_element("port", str(port))
1777
        cmd.add_element("type", scanner_type.value)
1778
1779
        if ca_pub:
1780
            cmd.add_element("ca_pub", ca_pub)
1781
1782
        cmd.add_element("credential", attrs={"id": str(credential_id)})
1783
1784
        if comment:
1785
            cmd.add_element("comment", comment)
1786
1787
        return self._send_xml_command(cmd)
1788
1789
    def clone_scanner(self, scanner_id: str) -> Any:
1790
        """Clone an existing scanner
1791
1792
        Arguments:
1793
            scanner_id: UUID of an existing scanner to clone from
1794
1795
        Returns:
1796
            The response. See :py:meth:`send_command` for details.
1797
        """
1798
        if not scanner_id:
1799
            raise RequiredArgument(
1800
                function=self.clone_scanner.__name__, argument='scanner_id'
1801
            )
1802
1803
        cmd = XmlCommand("create_scanner")
1804
        cmd.add_element("copy", scanner_id)
1805
        return self._send_xml_command(cmd)
1806
1807
    def clone_schedule(self, schedule_id: str) -> Any:
1808
        """Clone an existing schedule
1809
1810
        Arguments:
1811
            schedule_id: UUID of an existing schedule to clone from
1812
1813
        Returns:
1814
            The response. See :py:meth:`send_command` for details.
1815
        """
1816
        if not schedule_id:
1817
            raise RequiredArgument(
1818
                function=self.clone_schedule.__name__, argument='schedule_id'
1819
            )
1820
1821
        cmd = XmlCommand("create_schedule")
1822
        cmd.add_element("copy", schedule_id)
1823
        return self._send_xml_command(cmd)
1824
1825
    def clone_tag(self, tag_id: str) -> Any:
1826
        """Clone an existing tag
1827
1828
        Arguments:
1829
            tag_id: UUID of an existing tag to clone from
1830
1831
        Returns:
1832
            The response. See :py:meth:`send_command` for details.
1833
        """
1834
        if not tag_id:
1835
            raise RequiredArgument(
1836
                function=self.clone_tag.__name__, argument='tag_id'
1837
            )
1838
1839
        cmd = XmlCommand("create_tag")
1840
        cmd.add_element("copy", tag_id)
1841
        return self._send_xml_command(cmd)
1842
1843
    def create_user(
1844
        self,
1845
        name: str,
1846
        *,
1847
        password: Optional[str] = None,
1848
        hosts: Optional[List[str]] = None,
1849
        hosts_allow: Optional[bool] = False,
1850
        ifaces: Optional[List[str]] = None,
1851
        ifaces_allow: Optional[bool] = False,
1852
        role_ids: Optional[List[str]] = None,
1853
    ) -> Any:
1854
        """Create a new user
1855
1856
        Arguments:
1857
            name: Name of the user
1858
            password: Password of the user
1859
            hosts: A list of host addresses (IPs, DNS names)
1860
            hosts_allow: If True allow only access to passed hosts otherwise
1861
                deny access. Default is False for deny hosts.
1862
            ifaces: A list of interface names
1863
            ifaces_allow: If True allow only access to passed interfaces
1864
                otherwise deny access. Default is False for deny interfaces.
1865
            role_ids: A list of role UUIDs for the user
1866
1867
        Returns:
1868
            The response. See :py:meth:`send_command` for details.
1869
        """
1870
        if not name:
1871
            raise RequiredArgument(
1872
                function=self.create_user.__name__, argument='name'
1873
            )
1874
1875
        cmd = XmlCommand("create_user")
1876
        cmd.add_element("name", name)
1877
1878
        if password:
1879
            cmd.add_element("password", password)
1880
1881
        if hosts:
1882
            cmd.add_element(
1883
                "hosts",
1884
                to_comma_list(hosts),
1885
                attrs={"allow": to_bool(hosts_allow)},
1886
            )
1887
1888
        if ifaces:
1889
            cmd.add_element(
1890
                "ifaces",
1891
                to_comma_list(ifaces),
1892
                attrs={"allow": to_bool(ifaces_allow)},
1893
            )
1894
1895
        if role_ids:
1896
            for role in role_ids:
1897
                cmd.add_element("role", attrs={"id": role})
1898
1899
        return self._send_xml_command(cmd)
1900
1901
    def clone_user(self, user_id: str) -> Any:
1902
        """Clone an existing user
1903
1904
        Arguments:
1905
            user_id: UUID of existing user to clone from
1906
1907
        Returns:
1908
            The response. See :py:meth:`send_command` for details.
1909
        """
1910
        if not user_id:
1911
            raise RequiredArgument(
1912
                function=self.clone_user.__name__, argument='user_id'
1913
            )
1914
1915
        cmd = XmlCommand("create_user")
1916
        cmd.add_element("copy", user_id)
1917
        return self._send_xml_command(cmd)
1918
1919
    def delete_credential(
1920
        self, credential_id: str, *, ultimate: Optional[bool] = False
1921
    ) -> Any:
1922
        """Deletes an existing credential
1923
1924
        Arguments:
1925
            credential_id: UUID of the credential to be deleted.
1926
            ultimate: Whether to remove entirely, or to the trashcan.
1927
        """
1928
        if not credential_id:
1929
            raise RequiredArgument(
1930
                function=self.delete_credential.__name__,
1931
                argument='credential_id',
1932
            )
1933
1934
        cmd = XmlCommand("delete_credential")
1935
        cmd.set_attribute("credential_id", credential_id)
1936
        cmd.set_attribute("ultimate", to_bool(ultimate))
1937
1938
        return self._send_xml_command(cmd)
1939
1940
    def delete_filter(
1941
        self, filter_id: str, *, ultimate: Optional[bool] = False
1942
    ) -> Any:
1943
        """Deletes an existing filter
1944
1945
        Arguments:
1946
            filter_id: UUID of the filter to be deleted.
1947
            ultimate: Whether to remove entirely, or to the trashcan.
1948
        """
1949
        if not filter_id:
1950
            raise RequiredArgument(
1951
                function=self.delete_filter.__name__, argument='filter_id'
1952
            )
1953
1954
        cmd = XmlCommand("delete_filter")
1955
        cmd.set_attribute("filter_id", filter_id)
1956
        cmd.set_attribute("ultimate", to_bool(ultimate))
1957
1958
        return self._send_xml_command(cmd)
1959
1960
    def delete_group(
1961
        self, group_id: str, *, ultimate: Optional[bool] = False
1962
    ) -> Any:
1963
        """Deletes an existing group
1964
1965
        Arguments:
1966
            group_id: UUID of the group to be deleted.
1967
            ultimate: Whether to remove entirely, or to the trashcan.
1968
        """
1969
        if not group_id:
1970
            raise RequiredArgument(
1971
                function=self.delete_group.__name__, argument='group_id'
1972
            )
1973
1974
        cmd = XmlCommand("delete_group")
1975
        cmd.set_attribute("group_id", group_id)
1976
        cmd.set_attribute("ultimate", to_bool(ultimate))
1977
1978
        return self._send_xml_command(cmd)
1979
1980
    def delete_permission(
1981
        self, permission_id: str, *, ultimate: Optional[bool] = False
1982
    ) -> Any:
1983
        """Deletes an existing permission
1984
1985
        Arguments:
1986
            permission_id: UUID of the permission to be deleted.
1987
            ultimate: Whether to remove entirely, or to the trashcan.
1988
        """
1989
        if not permission_id:
1990
            raise RequiredArgument(
1991
                function=self.delete_permission.__name__,
1992
                argument='permission_id',
1993
            )
1994
1995
        cmd = XmlCommand("delete_permission")
1996
        cmd.set_attribute("permission_id", permission_id)
1997
        cmd.set_attribute("ultimate", to_bool(ultimate))
1998
1999
        return self._send_xml_command(cmd)
2000
2001
    def delete_report_format(
2002
        self,
2003
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
2004
        *,
2005
        ultimate: Optional[bool] = False,
2006
    ) -> Any:
2007
        """Deletes an existing report format
2008
2009
        Arguments:
2010
            report_format_id: UUID of the report format to be deleted.
2011
                              or ReportFormatType (enum)
2012
            ultimate: Whether to remove entirely, or to the trashcan.
2013
        """
2014
        if not report_format_id:
2015
            raise RequiredArgument(
2016
                function=self.delete_report_format.__name__,
2017
                argument='report_format_id',
2018
            )
2019
2020
        cmd = XmlCommand("delete_report_format")
2021
2022
        if isinstance(report_format_id, ReportFormatType):
2023
            report_format_id = report_format_id.value
2024
2025
        cmd.set_attribute("report_format_id", report_format_id)
2026
2027
        cmd.set_attribute("ultimate", to_bool(ultimate))
2028
2029
        return self._send_xml_command(cmd)
2030
2031
    def delete_role(
2032
        self, role_id: str, *, ultimate: Optional[bool] = False
2033
    ) -> Any:
2034
        """Deletes an existing role
2035
2036
        Arguments:
2037
            role_id: UUID of the role to be deleted.
2038
            ultimate: Whether to remove entirely, or to the trashcan.
2039
        """
2040
        if not role_id:
2041
            raise RequiredArgument(
2042
                function=self.delete_role.__name__, argument='role_id'
2043
            )
2044
2045
        cmd = XmlCommand("delete_role")
2046
        cmd.set_attribute("role_id", role_id)
2047
        cmd.set_attribute("ultimate", to_bool(ultimate))
2048
2049
        return self._send_xml_command(cmd)
2050
2051
    def delete_scanner(
2052
        self, scanner_id: str, *, ultimate: Optional[bool] = False
2053
    ) -> Any:
2054
        """Deletes an existing scanner
2055
2056
        Arguments:
2057
            scanner_id: UUID of the scanner to be deleted.
2058
            ultimate: Whether to remove entirely, or to the trashcan.
2059
        """
2060
        if not scanner_id:
2061
            raise RequiredArgument(
2062
                function=self.delete_scanner.__name__, argument='scanner_id'
2063
            )
2064
2065
        cmd = XmlCommand("delete_scanner")
2066
        cmd.set_attribute("scanner_id", scanner_id)
2067
        cmd.set_attribute("ultimate", to_bool(ultimate))
2068
2069
        return self._send_xml_command(cmd)
2070
2071
    def delete_schedule(
2072
        self, schedule_id: str, *, ultimate: Optional[bool] = False
2073
    ) -> Any:
2074
        """Deletes an existing schedule
2075
2076
        Arguments:
2077
            schedule_id: UUID of the schedule to be deleted.
2078
            ultimate: Whether to remove entirely, or to the trashcan.
2079
        """
2080
        if not schedule_id:
2081
            raise RequiredArgument(
2082
                function=self.delete_schedule.__name__, argument='schedule_id'
2083
            )
2084
2085
        cmd = XmlCommand("delete_schedule")
2086
        cmd.set_attribute("schedule_id", schedule_id)
2087
        cmd.set_attribute("ultimate", to_bool(ultimate))
2088
2089
        return self._send_xml_command(cmd)
2090
2091
    def delete_tag(
2092
        self, tag_id: str, *, ultimate: Optional[bool] = False
2093
    ) -> Any:
2094
        """Deletes an existing tag
2095
2096
        Arguments:
2097
            tag_id: UUID of the tag to be deleted.
2098
            ultimate: Whether to remove entirely, or to the trashcan.
2099
        """
2100
        if not tag_id:
2101
            raise RequiredArgument(
2102
                function=self.delete_tag.__name__, argument='tag_id'
2103
            )
2104
2105
        cmd = XmlCommand("delete_tag")
2106
        cmd.set_attribute("tag_id", tag_id)
2107
        cmd.set_attribute("ultimate", to_bool(ultimate))
2108
2109
        return self._send_xml_command(cmd)
2110
2111
    def delete_user(
2112
        self,
2113
        user_id: str = None,
2114
        *,
2115
        name: Optional[str] = None,
2116
        inheritor_id: Optional[str] = None,
2117
        inheritor_name: Optional[str] = None,
2118
    ) -> Any:
2119
        """Deletes an existing user
2120
2121
        Either user_id or name must be passed.
2122
2123
        Arguments:
2124
            user_id: UUID of the task to be deleted.
2125
            name: The name of the user to be deleted.
2126
            inheritor_id: The ID of the inheriting user or "self". Overrides
2127
                inheritor_name.
2128
            inheritor_name: The name of the inheriting user.
2129
2130
        """
2131
        if not user_id and not name:
2132
            raise RequiredArgument(
2133
                function=self.delete_user.__name__, argument='user_id or name'
2134
            )
2135
2136
        cmd = XmlCommand("delete_user")
2137
2138
        if user_id:
2139
            cmd.set_attribute("user_id", user_id)
2140
2141
        if name:
2142
            cmd.set_attribute("name", name)
2143
2144
        if inheritor_id:
2145
            cmd.set_attribute("inheritor_id", inheritor_id)
2146
        if inheritor_name:
2147
            cmd.set_attribute("inheritor_name", inheritor_name)
2148
2149
        return self._send_xml_command(cmd)
2150
2151
    def describe_auth(self) -> Any:
2152
        """Describe authentication methods
2153
2154
        Returns a list of all used authentication methods if such a list is
2155
        available.
2156
2157
        Returns:
2158
            The response. See :py:meth:`send_command` for details.
2159
        """
2160
        return self._send_xml_command(XmlCommand("describe_auth"))
2161
2162
    def empty_trashcan(self) -> Any:
2163
        """Empty the trashcan
2164
2165
        Remove all entities from the trashcan. **Attention:** this command can
2166
        not be reverted
2167
2168
        Returns:
2169
            The response. See :py:meth:`send_command` for details.
2170
        """
2171
        return self._send_xml_command(XmlCommand("empty_trashcan"))
2172
2173
    def get_credentials(
2174
        self,
2175
        *,
2176
        filter: Optional[str] = None,
2177
        filter_id: Optional[str] = None,
2178
        scanners: Optional[bool] = None,
2179
        trash: Optional[bool] = None,
2180
        targets: Optional[bool] = None,
2181
    ) -> Any:
2182
        """Request a list of credentials
2183
2184
        Arguments:
2185
            filter: Filter term to use for the query
2186
            filter_id: UUID of an existing filter to use for the query
2187
            scanners: Whether to include a list of scanners using the
2188
                credentials
2189
            trash: Whether to get the trashcan credentials instead
2190
            targets: Whether to include a list of targets using the credentials
2191
2192
        Returns:
2193
            The response. See :py:meth:`send_command` for details.
2194
        """
2195
        cmd = XmlCommand("get_credentials")
2196
2197
        add_filter(cmd, filter, filter_id)
2198
2199
        if scanners is not None:
2200
            cmd.set_attribute("scanners", to_bool(scanners))
2201
2202
        if trash is not None:
2203
            cmd.set_attribute("trash", to_bool(trash))
2204
2205
        if targets is not None:
2206
            cmd.set_attribute("targets", to_bool(targets))
2207
2208
        return self._send_xml_command(cmd)
2209
2210
    def get_credential(
2211
        self,
2212
        credential_id: str,
2213
        *,
2214
        scanners: Optional[bool] = None,
2215
        targets: Optional[bool] = None,
2216
        credential_format: Optional[CredentialFormat] = None,
2217
    ) -> Any:
2218
        """Request a single credential
2219
2220
        Arguments:
2221
            credential_id: UUID of an existing credential
2222
            scanners: Whether to include a list of scanners using the
2223
                credentials
2224
            targets: Whether to include a list of targets using the credentials
2225
            credential_format: One of "key", "rpm", "deb", "exe" or "pem"
2226
2227
        Returns:
2228
            The response. See :py:meth:`send_command` for details.
2229
        """
2230
        if not credential_id:
2231
            raise RequiredArgument(
2232
                function=self.get_credential.__name__, argument='credential_id'
2233
            )
2234
2235
        cmd = XmlCommand("get_credentials")
2236
        cmd.set_attribute("credential_id", credential_id)
2237
2238
        if credential_format:
2239
            if not isinstance(credential_format, CredentialFormat):
2240
                raise InvalidArgumentType(
2241
                    function=self.get_credential.__name__,
2242
                    argument='credential_format',
2243
                    arg_type=CredentialFormat.__name__,
2244
                )
2245
2246
            cmd.set_attribute("format", credential_format.value)
2247
2248
        if scanners is not None:
2249
            cmd.set_attribute("scanners", to_bool(scanners))
2250
2251
        if targets is not None:
2252
            cmd.set_attribute("targets", to_bool(targets))
2253
2254
        return self._send_xml_command(cmd)
2255
2256
    def get_feeds(self) -> Any:
2257
        """Request the list of feeds
2258
2259
        Returns:
2260
            The response. See :py:meth:`send_command` for details.
2261
        """
2262
        return self._send_xml_command(XmlCommand("get_feeds"))
2263
2264 View Code Duplication
    def get_filters(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2265
        self,
2266
        *,
2267
        filter: Optional[str] = None,
2268
        filter_id: Optional[str] = None,
2269
        trash: Optional[bool] = None,
2270
        alerts: Optional[bool] = None,
2271
    ) -> Any:
2272
        """Request a list of filters
2273
2274
        Arguments:
2275
            filter: Filter term to use for the query
2276
            filter_id: UUID of an existing filter to use for the query
2277
            trash: Whether to get the trashcan filters instead
2278
            alerts: Whether to include list of alerts that use the filter.
2279
2280
        Returns:
2281
            The response. See :py:meth:`send_command` for details.
2282
        """
2283
        cmd = XmlCommand("get_filters")
2284
2285
        add_filter(cmd, filter, filter_id)
2286
2287
        if trash is not None:
2288
            cmd.set_attribute("trash", to_bool(trash))
2289
2290
        if alerts is not None:
2291
            cmd.set_attribute("alerts", to_bool(alerts))
2292
2293
        return self._send_xml_command(cmd)
2294
2295
    def get_filter(
2296
        self, filter_id: str, *, alerts: Optional[bool] = None
2297
    ) -> Any:
2298
        """Request a single filter
2299
2300
        Arguments:
2301
            filter_id: UUID of an existing filter
2302
            alerts: Whether to include list of alerts that use the filter.
2303
2304
        Returns:
2305
            The response. See :py:meth:`send_command` for details.
2306
        """
2307
        cmd = XmlCommand("get_filters")
2308
2309
        if not filter_id:
2310
            raise RequiredArgument(
2311
                function=self.get_filter.__name__, argument='filter_id'
2312
            )
2313
2314
        cmd.set_attribute("filter_id", filter_id)
2315
2316
        if alerts is not None:
2317
            cmd.set_attribute("alerts", to_bool(alerts))
2318
2319
        return self._send_xml_command(cmd)
2320
2321 View Code Duplication
    def get_groups(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2322
        self,
2323
        *,
2324
        filter: Optional[str] = None,
2325
        filter_id: Optional[str] = None,
2326
        trash: Optional[bool] = None,
2327
    ) -> Any:
2328
        """Request a list of groups
2329
2330
        Arguments:
2331
            filter: Filter term to use for the query
2332
            filter_id: UUID of an existing filter to use for the query
2333
            trash: Whether to get the trashcan groups instead
2334
2335
        Returns:
2336
            The response. See :py:meth:`send_command` for details.
2337
        """
2338
        cmd = XmlCommand("get_groups")
2339
2340
        add_filter(cmd, filter, filter_id)
2341
2342
        if trash is not None:
2343
            cmd.set_attribute("trash", to_bool(trash))
2344
2345
        return self._send_xml_command(cmd)
2346
2347
    def get_group(self, group_id: str) -> Any:
2348
        """Request a single group
2349
2350
        Arguments:
2351
            group_id: UUID of an existing group
2352
2353
        Returns:
2354
            The response. See :py:meth:`send_command` for details.
2355
        """
2356
        cmd = XmlCommand("get_groups")
2357
2358
        if not group_id:
2359
            raise RequiredArgument(
2360
                function=self.get_group.__name__, argument='group_id'
2361
            )
2362
2363
        cmd.set_attribute("group_id", group_id)
2364
        return self._send_xml_command(cmd)
2365
2366 View Code Duplication
    def get_permissions(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2367
        self,
2368
        *,
2369
        filter: Optional[str] = None,
2370
        filter_id: Optional[str] = None,
2371
        trash: Optional[bool] = None,
2372
    ) -> Any:
2373
        """Request a list of permissions
2374
2375
        Arguments:
2376
            filter: Filter term to use for the query
2377
            filter_id: UUID of an existing filter to use for the query
2378
            trash: Whether to get permissions in the trashcan instead
2379
2380
        Returns:
2381
            The response. See :py:meth:`send_command` for details.
2382
        """
2383
        cmd = XmlCommand("get_permissions")
2384
2385
        add_filter(cmd, filter, filter_id)
2386
2387
        if trash is not None:
2388
            cmd.set_attribute("trash", to_bool(trash))
2389
2390
        return self._send_xml_command(cmd)
2391
2392
    def get_permission(self, permission_id: str) -> Any:
2393
        """Request a single permission
2394
2395
        Arguments:
2396
            permission_id: UUID of an existing permission
2397
2398
        Returns:
2399
            The response. See :py:meth:`send_command` for details.
2400
        """
2401
        cmd = XmlCommand("get_permissions")
2402
2403
        if not permission_id:
2404
            raise RequiredArgument(
2405
                function=self.get_permission.__name__, argument='permission_id'
2406
            )
2407
2408
        cmd.set_attribute("permission_id", permission_id)
2409
        return self._send_xml_command(cmd)
2410
2411
    def get_preferences(
2412
        self, *, nvt_oid: Optional[str] = None, config_id: Optional[str] = None
2413
    ) -> Any:
2414
        """Request a list of preferences
2415
2416
        When the command includes a config_id attribute, the preference element
2417
        includes the preference name, type and value, and the NVT to which the
2418
        preference applies. Otherwise, the preference element includes just the
2419
        name and value, with the NVT and type built into the name.
2420
2421
        Arguments:
2422
            nvt_oid: OID of nvt
2423
            config_id: UUID of scan config of which to show preference values
2424
2425
        Returns:
2426
            The response. See :py:meth:`send_command` for details.
2427
        """
2428
        cmd = XmlCommand("get_preferences")
2429
2430
        if nvt_oid:
2431
            cmd.set_attribute("nvt_oid", nvt_oid)
2432
2433
        if config_id:
2434
            cmd.set_attribute("config_id", config_id)
2435
2436
        return self._send_xml_command(cmd)
2437
2438
    def get_preference(
2439
        self,
2440
        name: str,
2441
        *,
2442
        nvt_oid: Optional[str] = None,
2443
        config_id: Optional[str] = None,
2444
    ) -> Any:
2445
        """Request a nvt preference
2446
2447
        Arguments:
2448
            name: name of a particular preference
2449
            nvt_oid: OID of nvt
2450
            config_id: UUID of scan config of which to show preference values
2451
2452
        Returns:
2453
            The response. See :py:meth:`send_command` for details.
2454
        """
2455
        cmd = XmlCommand("get_preferences")
2456
2457
        if not name:
2458
            raise RequiredArgument(
2459
                function=self.get_preference.__name__, argument='name'
2460
            )
2461
2462
        cmd.set_attribute("preference", name)
2463
2464
        if nvt_oid:
2465
            cmd.set_attribute("nvt_oid", nvt_oid)
2466
2467
        if config_id:
2468
            cmd.set_attribute("config_id", config_id)
2469
2470
        return self._send_xml_command(cmd)
2471
2472 View Code Duplication
    def get_report_formats(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2473
        self,
2474
        *,
2475
        filter: Optional[str] = None,
2476
        filter_id: Optional[str] = None,
2477
        trash: Optional[bool] = None,
2478
        alerts: Optional[bool] = None,
2479
        params: Optional[bool] = None,
2480
        details: Optional[bool] = None,
2481
    ) -> Any:
2482
        """Request a list of report formats
2483
2484
        Arguments:
2485
            filter: Filter term to use for the query
2486
            filter_id: UUID of an existing filter to use for the query
2487
            trash: Whether to get the trashcan report formats instead
2488
            alerts: Whether to include alerts that use the report format
2489
            params: Whether to include report format parameters
2490
            details: Include report format file, signature and parameters
2491
2492
        Returns:
2493
            The response. See :py:meth:`send_command` for details.
2494
        """
2495
        cmd = XmlCommand("get_report_formats")
2496
2497
        add_filter(cmd, filter, filter_id)
2498
2499
        if details is not None:
2500
            cmd.set_attribute("details", to_bool(details))
2501
2502
        if alerts is not None:
2503
            cmd.set_attribute("alerts", to_bool(alerts))
2504
2505
        if params is not None:
2506
            cmd.set_attribute("params", to_bool(params))
2507
2508
        if trash is not None:
2509
            cmd.set_attribute("trash", to_bool(trash))
2510
2511
        return self._send_xml_command(cmd)
2512
2513 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...
2514
        self, report_format_id: Union[str, ReportFormatType]
2515
    ) -> Any:
2516
        """Request a single report format
2517
2518
        Arguments:
2519
            report_format_id: UUID of an existing report format
2520
                              or ReportFormatType (enum)
2521
2522
        Returns:
2523
            The response. See :py:meth:`send_command` for details.
2524
        """
2525
        cmd = XmlCommand("get_report_formats")
2526
2527
        if not report_format_id:
2528
            raise RequiredArgument(
2529
                function=self.get_report_format.__name__,
2530
                argument='report_format_id',
2531
            )
2532
2533
        if isinstance(report_format_id, ReportFormatType):
2534
            report_format_id = report_format_id.value
2535
2536
        cmd.set_attribute("report_format_id", report_format_id)
2537
2538
        # for single entity always request all details
2539
        cmd.set_attribute("details", "1")
2540
        return self._send_xml_command(cmd)
2541
2542 View Code Duplication
    def get_roles(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2543
        self,
2544
        *,
2545
        filter: Optional[str] = None,
2546
        filter_id: Optional[str] = None,
2547
        trash: Optional[bool] = None,
2548
    ) -> Any:
2549
        """Request a list of roles
2550
2551
        Arguments:
2552
            filter: Filter term to use for the query
2553
            filter_id: UUID of an existing filter to use for the query
2554
            trash: Whether to get the trashcan roles instead
2555
2556
        Returns:
2557
            The response. See :py:meth:`send_command` for details.
2558
        """
2559
        cmd = XmlCommand("get_roles")
2560
2561
        add_filter(cmd, filter, filter_id)
2562
2563
        if trash is not None:
2564
            cmd.set_attribute("trash", to_bool(trash))
2565
2566
        return self._send_xml_command(cmd)
2567
2568
    def get_role(self, role_id: str) -> Any:
2569
        """Request a single role
2570
2571
        Arguments:
2572
            role_id: UUID of an existing role
2573
2574
        Returns:
2575
            The response. See :py:meth:`send_command` for details.
2576
        """
2577
        if not role_id:
2578
            raise RequiredArgument(
2579
                function=self.get_role.__name__, argument='role_id'
2580
            )
2581
2582
        cmd = XmlCommand("get_roles")
2583
        cmd.set_attribute("role_id", role_id)
2584
        return self._send_xml_command(cmd)
2585
2586 View Code Duplication
    def get_scanners(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2587
        self,
2588
        *,
2589
        filter: Optional[str] = None,
2590
        filter_id: Optional[str] = None,
2591
        trash: Optional[bool] = None,
2592
        details: Optional[bool] = None,
2593
    ) -> Any:
2594
        """Request a list of scanners
2595
2596
        Arguments:
2597
            filter: Filter term to use for the query
2598
            filter_id: UUID of an existing filter to use for the query
2599
            trash: Whether to get the trashcan scanners instead
2600
            details:  Whether to include extra details like tasks using this
2601
                scanner
2602
2603
        Returns:
2604
            The response. See :py:meth:`send_command` for details.
2605
        """
2606
        cmd = XmlCommand("get_scanners")
2607
2608
        add_filter(cmd, filter, filter_id)
2609
2610
        if trash is not None:
2611
            cmd.set_attribute("trash", to_bool(trash))
2612
2613
        if details is not None:
2614
            cmd.set_attribute("details", to_bool(details))
2615
2616
        return self._send_xml_command(cmd)
2617
2618
    def get_scanner(self, scanner_id: str) -> Any:
2619
        """Request a single scanner
2620
2621
        Arguments:
2622
            scanner_id: UUID of an existing scanner
2623
2624
        Returns:
2625
            The response. See :py:meth:`send_command` for details.
2626
        """
2627
        cmd = XmlCommand("get_scanners")
2628
2629
        if not scanner_id:
2630
            raise RequiredArgument(
2631
                function=self.get_scanner.__name__, argument='scanner_id'
2632
            )
2633
2634
        cmd.set_attribute("scanner_id", scanner_id)
2635
2636
        # for single entity always request all details
2637
        cmd.set_attribute("details", "1")
2638
        return self._send_xml_command(cmd)
2639
2640 View Code Duplication
    def get_schedules(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2641
        self,
2642
        *,
2643
        filter: Optional[str] = None,
2644
        filter_id: Optional[str] = None,
2645
        trash: Optional[bool] = None,
2646
        tasks: Optional[bool] = None,
2647
    ) -> Any:
2648
        """Request a list of schedules
2649
2650
        Arguments:
2651
            filter: Filter term to use for the query
2652
            filter_id: UUID of an existing filter to use for the query
2653
            trash: Whether to get the trashcan schedules instead
2654
            tasks: Whether to include tasks using the schedules
2655
2656
        Returns:
2657
            The response. See :py:meth:`send_command` for details.
2658
        """
2659
        cmd = XmlCommand("get_schedules")
2660
2661
        add_filter(cmd, filter, filter_id)
2662
2663
        if trash is not None:
2664
            cmd.set_attribute("trash", to_bool(trash))
2665
2666
        if tasks is not None:
2667
            cmd.set_attribute("tasks", to_bool(tasks))
2668
2669
        return self._send_xml_command(cmd)
2670
2671
    def get_schedule(
2672
        self, schedule_id: str, *, tasks: Optional[bool] = None
2673
    ) -> Any:
2674
        """Request a single schedule
2675
2676
        Arguments:
2677
            schedule_id: UUID of an existing schedule
2678
            tasks: Whether to include tasks using the schedules
2679
2680
        Returns:
2681
            The response. See :py:meth:`send_command` for details.
2682
        """
2683
        cmd = XmlCommand("get_schedules")
2684
2685
        if not schedule_id:
2686
            raise RequiredArgument(
2687
                function=self.get_schedule.__name__, argument='schedule_id'
2688
            )
2689
2690
        cmd.set_attribute("schedule_id", schedule_id)
2691
2692
        if tasks is not None:
2693
            cmd.set_attribute("tasks", to_bool(tasks))
2694
2695
        return self._send_xml_command(cmd)
2696
2697
    def get_settings(self, *, filter: Optional[str] = None) -> Any:
2698
        """Request a list of user settings
2699
2700
        Arguments:
2701
            filter: Filter term to use for the query
2702
2703
        Returns:
2704
            The response. See :py:meth:`send_command` for details.
2705
        """
2706
        cmd = XmlCommand("get_settings")
2707
2708
        if filter:
2709
            cmd.set_attribute("filter", filter)
2710
2711
        return self._send_xml_command(cmd)
2712
2713
    def get_setting(self, setting_id: str) -> Any:
2714
        """Request a single setting
2715
2716
        Arguments:
2717
            setting_id: UUID of an existing setting
2718
2719
        Returns:
2720
            The response. See :py:meth:`send_command` for details.
2721
        """
2722
        cmd = XmlCommand("get_settings")
2723
2724
        if not setting_id:
2725
            raise RequiredArgument(
2726
                function=self.get_setting.__name__, argument='setting_id'
2727
            )
2728
2729
        cmd.set_attribute("setting_id", setting_id)
2730
        return self._send_xml_command(cmd)
2731
2732
    def get_system_reports(
2733
        self,
2734
        *,
2735
        name: Optional[str] = None,
2736
        duration: Optional[int] = None,
2737
        start_time: Optional[str] = None,
2738
        end_time: Optional[str] = None,
2739
        brief: Optional[bool] = None,
2740
        slave_id: Optional[str] = None,
2741
    ) -> Any:
2742
        """Request a list of system reports
2743
2744
        Arguments:
2745
            name: A string describing the required system report
2746
            duration: The number of seconds into the past that the system report
2747
                should include
2748
            start_time: The start of the time interval the system report should
2749
                include in ISO time format
2750
            end_time: The end of the time interval the system report should
2751
                include in ISO time format
2752
            brief: Whether to include the actual system reports
2753
            slave_id: UUID of GMP scanner from which to get the system reports
2754
2755
        Returns:
2756
            The response. See :py:meth:`send_command` for details.
2757
        """
2758
        cmd = XmlCommand("get_system_reports")
2759
2760
        if name:
2761
            cmd.set_attribute("name", name)
2762
2763
        if duration is not None:
2764
            if not isinstance(duration, Integral):
2765
                raise InvalidArgument("duration needs to be an integer number")
2766
2767
            cmd.set_attribute("duration", str(duration))
2768
2769
        if start_time:
2770
            cmd.set_attribute("start_time", str(start_time))
2771
2772
        if end_time:
2773
            cmd.set_attribute("end_time", str(end_time))
2774
2775
        if brief is not None:
2776
            cmd.set_attribute("brief", to_bool(brief))
2777
2778
        if slave_id:
2779
            cmd.set_attribute("slave_id", slave_id)
2780
2781
        return self._send_xml_command(cmd)
2782
2783 View Code Duplication
    def get_tags(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2784
        self,
2785
        *,
2786
        filter: Optional[str] = None,
2787
        filter_id: Optional[str] = None,
2788
        trash: Optional[bool] = None,
2789
        names_only: Optional[bool] = None,
2790
    ) -> Any:
2791
        """Request a list of tags
2792
2793
        Arguments:
2794
            filter: Filter term to use for the query
2795
            filter_id: UUID of an existing filter to use for the query
2796
            trash: Whether to get tags from the trashcan instead
2797
            names_only: Whether to get only distinct tag names
2798
2799
        Returns:
2800
            The response. See :py:meth:`send_command` for details.
2801
        """
2802
        cmd = XmlCommand("get_tags")
2803
2804
        add_filter(cmd, filter, filter_id)
2805
2806
        if trash is not None:
2807
            cmd.set_attribute("trash", to_bool(trash))
2808
2809
        if names_only is not None:
2810
            cmd.set_attribute("names_only", to_bool(names_only))
2811
2812
        return self._send_xml_command(cmd)
2813
2814
    def get_tag(self, tag_id: str) -> Any:
2815
        """Request a single tag
2816
2817
        Arguments:
2818
            tag_id: UUID of an existing tag
2819
2820
        Returns:
2821
            The response. See :py:meth:`send_command` for details.
2822
        """
2823
        cmd = XmlCommand("get_tags")
2824
2825
        if not tag_id:
2826
            raise RequiredArgument(
2827
                function=self.get_tag.__name__, argument='tag_id'
2828
            )
2829
2830
        cmd.set_attribute("tag_id", tag_id)
2831
        return self._send_xml_command(cmd)
2832
2833
    def get_users(
2834
        self, *, filter: Optional[str] = None, filter_id: Optional[str] = None
2835
    ) -> Any:
2836
        """Request a list of users
2837
2838
        Arguments:
2839
            filter: Filter term to use for the query
2840
            filter_id: UUID of an existing filter to use for the query
2841
2842
        Returns:
2843
            The response. See :py:meth:`send_command` for details.
2844
        """
2845
        cmd = XmlCommand("get_users")
2846
2847
        add_filter(cmd, filter, filter_id)
2848
2849
        return self._send_xml_command(cmd)
2850
2851
    def get_user(self, user_id: str) -> Any:
2852
        """Request a single user
2853
2854
        Arguments:
2855
            user_id: UUID of an existing user
2856
2857
        Returns:
2858
            The response. See :py:meth:`send_command` for details.
2859
        """
2860
        cmd = XmlCommand("get_users")
2861
2862
        if not user_id:
2863
            raise RequiredArgument(
2864
                function=self.get_user.__name__, argument='user_id'
2865
            )
2866
2867
        cmd.set_attribute("user_id", user_id)
2868
        return self._send_xml_command(cmd)
2869
2870
    def get_version(self) -> Any:
2871
        """Get the Greenbone Manager Protocol version used by the remote gvmd
2872
2873
        Returns:
2874
            The response. See :py:meth:`send_command` for details.
2875
        """
2876
        return self._send_xml_command(XmlCommand("get_version"))
2877
2878
    def help(
2879
        self, *, format: Optional[str] = None, help_type: Optional[str] = None
2880
    ) -> Any:
2881
        """Get the help text
2882
2883
        Arguments:
2884
            format: One of "html", "rnc", "text" or "xml
2885
            help_type: One of "brief" or "". Default ""
2886
2887
        Returns:
2888
            The response. See :py:meth:`send_command` for details.
2889
        """
2890
        cmd = XmlCommand("help")
2891
2892
        if not help_type:
2893
            help_type = ""
2894
2895
        if help_type not in ("", "brief"):
2896
            raise InvalidArgument(
2897
                'help_type argument must be an empty string or "brief"'
2898
            )
2899
2900
        cmd.set_attribute("type", help_type)
2901
2902
        if format:
2903
            if not format.lower() in ("html", "rnc", "text", "xml"):
2904
                raise InvalidArgument(
2905
                    "help format Argument must be one of html, rnc, text or "
2906
                    "xml"
2907
                )
2908
2909
            cmd.set_attribute("format", format)
2910
2911
        return self._send_xml_command(cmd)
2912
2913
    def modify_auth(self, group_name: str, auth_conf_settings: dict) -> Any:
2914
        """Modifies an existing auth.
2915
2916
        Arguments:
2917
            group_name: Name of the group to be modified.
2918
            auth_conf_settings: The new auth config.
2919
2920
        Returns:
2921
            The response. See :py:meth:`send_command` for details.
2922
        """
2923
        if not group_name:
2924
            raise RequiredArgument(
2925
                function=self.modify_auth.__name__, argument='group_name'
2926
            )
2927
        if not auth_conf_settings:
2928
            raise RequiredArgument(
2929
                function=self.modify_auth.__name__,
2930
                argument='auth_conf_settings',
2931
            )
2932
        cmd = XmlCommand("modify_auth")
2933
        _xmlgroup = cmd.add_element("group", attrs={"name": str(group_name)})
2934
2935
        for key, value in auth_conf_settings.items():
2936
            _xmlauthconf = _xmlgroup.add_element("auth_conf_setting")
2937
            _xmlauthconf.add_element("key", key)
2938
            _xmlauthconf.add_element("value", value)
2939
2940
        return self._send_xml_command(cmd)
2941
2942 View Code Duplication
    def modify_group(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2943
        self,
2944
        group_id: str,
2945
        *,
2946
        comment: Optional[str] = None,
2947
        name: Optional[str] = None,
2948
        users: Optional[List[str]] = None,
2949
    ) -> Any:
2950
        """Modifies an existing group.
2951
2952
        Arguments:
2953
            group_id: UUID of group to modify.
2954
            comment: Comment on group.
2955
            name: Name of group.
2956
            users: List of user names to be in the group
2957
2958
        Returns:
2959
            The response. See :py:meth:`send_command` for details.
2960
        """
2961
        if not group_id:
2962
            raise RequiredArgument(
2963
                function=self.modify_group.__name__, argument='group_id'
2964
            )
2965
2966
        cmd = XmlCommand("modify_group")
2967
        cmd.set_attribute("group_id", group_id)
2968
2969
        if comment:
2970
            cmd.add_element("comment", comment)
2971
2972
        if name:
2973
            cmd.add_element("name", name)
2974
2975
        if users:
2976
            cmd.add_element("users", to_comma_list(users))
2977
2978
        return self._send_xml_command(cmd)
2979
2980
    def modify_report_format(
2981
        self,
2982
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
2983
        *,
2984
        active: Optional[bool] = None,
2985
        name: Optional[str] = None,
2986
        summary: Optional[str] = None,
2987
        param_name: Optional[str] = None,
2988
        param_value: Optional[str] = None,
2989
    ) -> Any:
2990
        """Modifies an existing report format.
2991
2992
        Arguments:
2993
            report_format_id: UUID of report format to modify
2994
                              or ReportFormatType (enum)
2995
            active: Whether the report format is active.
2996
            name: The name of the report format.
2997
            summary: A summary of the report format.
2998
            param_name: The name of the param.
2999
            param_value: The value of the param.
3000
3001
        Returns:
3002
            The response. See :py:meth:`send_command` for details.
3003
        """
3004
        if not report_format_id:
3005
            raise RequiredArgument(
3006
                function=self.modify_report_format.__name__,
3007
                argument='report_format_id ',
3008
            )
3009
3010
        cmd = XmlCommand("modify_report_format")
3011
3012
        if isinstance(report_format_id, ReportFormatType):
3013
            report_format_id = report_format_id.value
3014
3015
        cmd.set_attribute("report_format_id", report_format_id)
3016
3017
        if active is not None:
3018
            cmd.add_element("active", to_bool(active))
3019
3020
        if name:
3021
            cmd.add_element("name", name)
3022
3023
        if summary:
3024
            cmd.add_element("summary", summary)
3025
3026
        if param_name:
3027
            _xmlparam = cmd.add_element("param")
3028
            _xmlparam.add_element("name", param_name)
3029
3030
            if param_value is not None:
3031
                _xmlparam.add_element("value", param_value)
3032
3033
        return self._send_xml_command(cmd)
3034
3035 View Code Duplication
    def modify_role(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3036
        self,
3037
        role_id: str,
3038
        *,
3039
        comment: Optional[str] = None,
3040
        name: Optional[str] = None,
3041
        users: Optional[List[str]] = None,
3042
    ) -> Any:
3043
        """Modifies an existing role.
3044
3045
        Arguments:
3046
            role_id: UUID of role to modify.
3047
            comment: Name of role.
3048
            name: Comment on role.
3049
            users: List of user names.
3050
3051
        Returns:
3052
            The response. See :py:meth:`send_command` for details.
3053
        """
3054
        if not role_id:
3055
            raise RequiredArgument(
3056
                function=self.modify_role.__name__, argument='role_id argument'
3057
            )
3058
3059
        cmd = XmlCommand("modify_role")
3060
        cmd.set_attribute("role_id", role_id)
3061
3062
        if comment:
3063
            cmd.add_element("comment", comment)
3064
3065
        if name:
3066
            cmd.add_element("name", name)
3067
3068
        if users:
3069
            cmd.add_element("users", to_comma_list(users))
3070
3071
        return self._send_xml_command(cmd)
3072
3073
    def modify_scanner(
3074
        self,
3075
        scanner_id: str,
3076
        *,
3077
        scanner_type: Optional[ScannerType] = None,
3078
        host: Optional[str] = None,
3079
        port: Optional[int] = None,
3080
        comment: Optional[str] = None,
3081
        name: Optional[str] = None,
3082
        ca_pub: Optional[str] = None,
3083
        credential_id: Optional[str] = None,
3084
    ) -> Any:
3085
        """Modifies an existing scanner.
3086
3087
        Arguments:
3088
            scanner_id: UUID of scanner to modify.
3089
            scanner_type: New type of the Scanner.
3090
            host: Host of the scanner.
3091
            port: Port of the scanner.
3092
            comment: Comment on scanner.
3093
            name: Name of scanner.
3094
            ca_pub: Certificate of CA to verify scanner's certificate.
3095
            credential_id: UUID of the client certificate credential for the
3096
                Scanner.
3097
3098
        Returns:
3099
            The response. See :py:meth:`send_command` for details.
3100
        """
3101
        if not scanner_id:
3102
            raise RequiredArgument(
3103
                function=self.modify_scanner.__name__,
3104
                argument='scanner_id argument',
3105
            )
3106
3107
        cmd = XmlCommand("modify_scanner")
3108
        cmd.set_attribute("scanner_id", scanner_id)
3109
3110
        if scanner_type is not None:
3111
            if not isinstance(scanner_type, self.types.ScannerType):
3112
                raise InvalidArgumentType(
3113
                    function=self.modify_scanner.__name__,
3114
                    argument='scanner_type',
3115
                    arg_type=self.types.ScannerType.__name__,
3116
                )
3117
3118
            cmd.add_element("type", scanner_type.value)
3119
3120
        if host:
3121
            cmd.add_element("host", host)
3122
3123
        if port:
3124
            cmd.add_element("port", str(port))
3125
3126
        if comment:
3127
            cmd.add_element("comment", comment)
3128
3129
        if name:
3130
            cmd.add_element("name", name)
3131
3132
        if ca_pub:
3133
            cmd.add_element("ca_pub", ca_pub)
3134
3135
        if credential_id:
3136
            cmd.add_element("credential", attrs={"id": str(credential_id)})
3137
3138
        return self._send_xml_command(cmd)
3139
3140
    def modify_setting(
3141
        self,
3142
        setting_id: Optional[str] = None,
3143
        name: Optional[str] = None,
3144
        value: Optional[str] = None,
3145
    ) -> Any:
3146
        """Modifies an existing setting.
3147
3148
        Arguments:
3149
            setting_id: UUID of the setting to be changed.
3150
            name: The name of the setting. Either setting_id or name must be
3151
                passed.
3152
            value: The value of the setting.
3153
3154
        Returns:
3155
            The response. See :py:meth:`send_command` for details.
3156
        """
3157
        if not setting_id and not name:
3158
            raise RequiredArgument(
3159
                function=self.modify_setting.__name__,
3160
                argument='setting_id or name argument',
3161
            )
3162
3163
        if value is None:
3164
            raise RequiredArgument(
3165
                function=self.modify_setting.__name__, argument='value argument'
3166
            )
3167
3168
        cmd = XmlCommand("modify_setting")
3169
3170
        if setting_id:
3171
            cmd.set_attribute("setting_id", setting_id)
3172
        else:
3173
            cmd.add_element("name", name)
3174
3175
        cmd.add_element("value", to_base64(value))
3176
3177
        return self._send_xml_command(cmd)
3178
3179 View Code Duplication
    def modify_user(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3180
        self,
3181
        user_id: str = None,
3182
        name: str = None,
3183
        *,
3184
        new_name: Optional[str] = None,
3185
        comment: Optional[str] = None,
3186
        password: Optional[str] = None,
3187
        auth_source: Optional[UserAuthType] = None,
3188
        role_ids: Optional[List[str]] = None,
3189
        hosts: Optional[List[str]] = None,
3190
        hosts_allow: Optional[bool] = False,
3191
        ifaces: Optional[List[str]] = None,
3192
        ifaces_allow: Optional[bool] = False,
3193
        group_ids: Optional[List[str]] = None,
3194
    ) -> Any:
3195
        """Modifies an existing user. Most of the fields need to be supplied
3196
        for changing a single field even if no change is wanted for those.
3197
        Else empty values are inserted for the missing fields instead.
3198
        Arguments:
3199
            user_id: UUID of the user to be modified. Overrides name element
3200
                argument.
3201
            name: The name of the user to be modified. Either user_id or name
3202
                must be passed.
3203
            new_name: The new name for the user.
3204
            comment: Comment on the user.
3205
            password: The password for the user.
3206
            auth_source: Source allowed for authentication for this user.
3207
            roles_id: List of roles UUIDs for the user.
3208
            hosts: User access rules: List of hosts.
3209
            hosts_allow: Defines how the hosts list is to be interpreted.
3210
                If False (default) the list is treated as a deny list.
3211
                All hosts are allowed by default except those provided by
3212
                the hosts parameter. If True the list is treated as a
3213
                allow list. All hosts are denied by default except those
3214
                provided by the hosts parameter.
3215
            ifaces: User access rules: List of ifaces.
3216
            ifaces_allow: Defines how the ifaces list is to be interpreted.
3217
                If False (default) the list is treated as a deny list.
3218
                All ifaces are allowed by default except those provided by
3219
                the ifaces parameter. If True the list is treated as a
3220
                allow list. All ifaces are denied by default except those
3221
                provided by the ifaces parameter.
3222
            group_ids: List of group UUIDs for the user.
3223
3224
        Returns:
3225
            The response. See :py:meth:`send_command` for details.
3226
        """
3227
        if not user_id and not name:
3228
            raise RequiredArgument(
3229
                function=self.modify_user.__name__, argument='user_id or name'
3230
            )
3231
3232
        cmd = XmlCommand("modify_user")
3233
3234
        if user_id:
3235
            cmd.set_attribute("user_id", user_id)
3236
        else:
3237
            cmd.add_element("name", name)
3238
3239
        if new_name:
3240
            cmd.add_element("new_name", new_name)
3241
3242
        if role_ids:
3243
            for role in role_ids:
3244
                cmd.add_element("role", attrs={"id": role})
3245
3246
        if hosts:
3247
            cmd.add_element(
3248
                "hosts",
3249
                to_comma_list(hosts),
3250
                attrs={"allow": to_bool(hosts_allow)},
3251
            )
3252
3253
        if ifaces:
3254
            cmd.add_element(
3255
                "ifaces",
3256
                to_comma_list(ifaces),
3257
                attrs={"allow": to_bool(ifaces_allow)},
3258
            )
3259
3260
        if comment:
3261
            cmd.add_element("comment", comment)
3262
3263
        if password:
3264
            cmd.add_element("password", password)
3265
3266
        if auth_source:
3267
            _xmlauthsrc = cmd.add_element("sources")
3268
            _xmlauthsrc.add_element("source", auth_source.value)
3269
3270
        if group_ids:
3271
            _xmlgroups = cmd.add_element("groups")
3272
            for group_id in group_ids:
3273
                _xmlgroups.add_element("group", attrs={"id": group_id})
3274
3275
        return self._send_xml_command(cmd)
3276
3277
    def restore(self, entity_id: str) -> Any:
3278
        """Restore an entity from the trashcan
3279
3280
        Arguments:
3281
            entity_id: ID of the entity to be restored from the trashcan
3282
3283
        Returns:
3284
            The response. See :py:meth:`send_command` for details.
3285
        """
3286
        if not entity_id:
3287
            raise RequiredArgument(
3288
                function=self.restore.__name__, argument='entity_id'
3289
            )
3290
3291
        cmd = XmlCommand("restore")
3292
        cmd.set_attribute("id", entity_id)
3293
3294
        return self._send_xml_command(cmd)
3295
3296
    def sync_cert(self) -> Any:
3297
        """Request a synchronization with the CERT feed service
3298
3299
        Returns:
3300
            The response. See :py:meth:`send_command` for details.
3301
        """
3302
        return self._send_xml_command(XmlCommand("sync_cert"))
3303
3304
    def sync_feed(self) -> Any:
3305
        """Request a synchronization with the NVT feed service
3306
3307
        Returns:
3308
            The response. See :py:meth:`send_command` for details.
3309
        """
3310
        return self._send_xml_command(XmlCommand("sync_feed"))
3311
3312
    def sync_scap(self) -> Any:
3313
        """Request a synchronization with the SCAP feed service
3314
3315
        Returns:
3316
            The response. See :py:meth:`send_command` for details.
3317
        """
3318
        return self._send_xml_command(XmlCommand("sync_scap"))
3319
3320 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...
3321
        self, report_format_id: Union[str, ReportFormatType]
3322
    ) -> Any:
3323
        """Verify an existing report format
3324
3325
        Verifies the trust level of an existing report format. It will be
3326
        checked whether the signature of the report format currently matches the
3327
        report format. This includes the script and files used to generate
3328
        reports of this format. It is *not* verified if the report format works
3329
        as expected by the user.
3330
3331
        Arguments:
3332
            report_format_id: UUID of the report format to be verified
3333
                              or ReportFormatType (enum)
3334
3335
        Returns:
3336
            The response. See :py:meth:`send_command` for details.
3337
        """
3338
        if not report_format_id:
3339
            raise RequiredArgument(
3340
                function=self.verify_report_format.__name__,
3341
                argument='report_format_id',
3342
            )
3343
3344
        cmd = XmlCommand("verify_report_format")
3345
3346
        if isinstance(report_format_id, ReportFormatType):
3347
            report_format_id = report_format_id.value
3348
3349
        cmd.set_attribute("report_format_id", report_format_id)
3350
3351
        return self._send_xml_command(cmd)
3352
3353
    def verify_scanner(self, scanner_id: str) -> Any:
3354
        """Verify an existing scanner
3355
3356
        Verifies if it is possible to connect to an existing scanner. It is
3357
        *not* verified if the scanner works as expected by the user.
3358
3359
        Arguments:
3360
            scanner_id: UUID of the scanner to be verified
3361
3362
        Returns:
3363
            The response. See :py:meth:`send_command` for details.
3364
        """
3365
        if not scanner_id:
3366
            raise RequiredArgument(
3367
                function=self.verify_scanner.__name__, argument='scanner_id'
3368
            )
3369
3370
        cmd = XmlCommand("verify_scanner")
3371
        cmd.set_attribute("scanner_id", scanner_id)
3372
3373
        return self._send_xml_command(cmd)
3374