Completed
Push — master ( 486e1a...9be8a7 )
by Jaspar
02:33 queued 36s
created

GmpV208Mixin.get_schedule()   A

Complexity

Conditions 3

Size

Total Lines 25
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nop 4
dl 0
loc 25
rs 9.9
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.protocols.gmpv208.entities.entities import EntityType
41
42
from gvm.utils import (
43
    check_command_status,
44
    to_base64,
45
    to_bool,
46
    to_comma_list,
47
    add_filter,
48
)
49
from gvm.xml import XmlCommand
50
51
from . import types
52
from .types import *  # pylint: disable=unused-wildcard-import, wildcard-import
53
54
55
PROTOCOL_VERSION = (20, 8)
56
57
58
logger = logging.getLogger(__name__)
59
60
61
class GmpV208Mixin(GvmProtocol):
62
    """Python interface for Greenbone Management Protocol
63
64
    This class implements the `Greenbone Management Protocol version 20.08`_
65
66
    Arguments:
67
        connection: Connection to use to talk with the gvmd daemon. See
68
            :mod:`gvm.connections` for possible connection types.
69
        transform: Optional transform `callable`_ to convert response data.
70
            After each request the callable gets passed the plain response data
71
            which can be used to check the data and/or conversion into different
72
            representations like a xml dom.
73
74
            See :mod:`gvm.transforms` for existing transforms.
75
76
    .. _Greenbone Management Protocol version 20.08:
77
        https://docs.greenbone.net/API/GMP/gmp-20.08.html
78
    .. _callable:
79
        https://docs.python.org/3/library/functions.html#callable
80
    """
81
82
    types = types
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable types does not seem to be defined.
Loading history...
83
84
    def __init__(
85
        self,
86
        connection: GvmConnection,
87
        *,
88
        transform: Optional[Callable[[str], Any]] = None,
89
    ):
90
        super().__init__(connection, transform=transform)
91
92
        # Is authenticated on gvmd
93
        self._authenticated = False
94
95
    def is_authenticated(self) -> bool:
96
        """Checks if the user is authenticated
97
98
        If the user is authenticated privileged GMP commands like get_tasks
99
        may be send to gvmd.
100
101
        Returns:
102
            bool: True if an authenticated connection to gvmd has been
103
            established.
104
        """
105
        return self._authenticated
106
107
    def authenticate(self, username: str, password: str) -> Any:
108
        """Authenticate to gvmd.
109
110
        The generated authenticate command will be send to server.
111
        Afterwards the response is read, transformed and returned.
112
113
        Arguments:
114
            username: Username
115
            password: Password
116
117
        Returns:
118
            Transformed response from server.
119
        """
120
        cmd = XmlCommand("authenticate")
121
122
        if not username:
123
            raise RequiredArgument(
124
                function=self.authenticate.__name__, argument='username'
125
            )
126
127
        if not password:
128
            raise RequiredArgument(
129
                function=self.authenticate.__name__, argument='password'
130
            )
131
132
        credentials = cmd.add_element("credentials")
133
        credentials.add_element("username", username)
134
        credentials.add_element("password", password)
135
136
        self._send(cmd.to_string())
137
        response = self._read()
138
139
        if check_command_status(response):
140
            self._authenticated = True
141
142
        return self._transform(response)
143
144
    def create_tag(
145
        self,
146
        name: str,
147
        resource_type: EntityType,
148
        *,
149
        resource_filter: Optional[str] = None,
150
        resource_ids: Optional[List[str]] = None,
151
        value: Optional[str] = None,
152
        comment: Optional[str] = None,
153
        active: Optional[bool] = None,
154
    ) -> Any:
155
        """Create a tag.
156
157
        Arguments:
158
            name: Name of the tag. A full tag name consisting of namespace and
159
                predicate e.g. `foo:bar`.
160
            resource_type: Entity type the tag is to be attached to.
161
            resource_filter: Filter term to select resources the tag is to be
162
                attached to. Only one of resource_filter or resource_ids can be
163
                provided.
164
            resource_ids: IDs of the resources the tag is to be attached to.
165
                Only one of resource_filter or resource_ids can be provided.
166
            value: Value associated with the tag.
167
            comment: Comment for the tag.
168
            active: Whether the tag should be active.
169
170
        Returns:
171
            The response. See :py:meth:`send_command` for details.
172
        """
173
        if not name:
174
            raise RequiredArgument(
175
                function=self.create_tag.__name__, argument='name'
176
            )
177
178
        if resource_filter and resource_ids:
179
            raise InvalidArgument(
180
                "create_tag accepts either resource_filter or resource_ids "
181
                "argument",
182
                function=self.create_tag.__name__,
183
            )
184
185
        if not resource_type:
186
            raise RequiredArgument(
187
                function=self.create_tag.__name__, argument='resource_type'
188
            )
189
190
        if not isinstance(resource_type, EntityType):
191
            raise InvalidArgumentType(
192
                function=self.create_tag.__name__,
193
                argument='resource_type',
194
                arg_type=EntityType.__name__,
195
            )
196
197
        cmd = XmlCommand('create_tag')
198
        cmd.add_element('name', name)
199
200
        _xmlresources = cmd.add_element("resources")
201
        if resource_filter is not None:
202
            _xmlresources.set_attribute("filter", resource_filter)
203
204
        for resource_id in resource_ids or []:
205
            _xmlresources.add_element(
206
                "resource", attrs={"id": str(resource_id)}
207
            )
208
209
        _actual_resource_type = resource_type
210
        if resource_type.value == EntityType.AUDIT.value:
211
            _actual_resource_type = EntityType.TASK
212
        elif resource_type.value == EntityType.POLICY.value:
213
            _actual_resource_type = EntityType.SCAN_CONFIG
214
        _xmlresources.add_element("type", _actual_resource_type.value)
215
216
        if comment:
217
            cmd.add_element("comment", comment)
218
219
        if value:
220
            cmd.add_element("value", value)
221
222
        if active is not None:
223
            if active:
224
                cmd.add_element("active", "1")
225
            else:
226
                cmd.add_element("active", "0")
227
228
        return self._send_xml_command(cmd)
229
230
    def get_aggregates(
231
        self,
232
        resource_type: EntityType,
233
        *,
234
        filter: Optional[str] = None,
235
        filter_id: Optional[str] = None,
236
        sort_criteria: Optional[list] = None,
237
        data_columns: Optional[list] = None,
238
        group_column: Optional[str] = None,
239
        subgroup_column: Optional[str] = None,
240
        text_columns: Optional[list] = None,
241
        first_group: Optional[int] = None,
242
        max_groups: Optional[int] = None,
243
        mode: Optional[int] = None,
244
        **kwargs,
245
    ) -> Any:
246
        """Request aggregated information on a resource / entity type
247
248
        Additional arguments can be set via the kwargs parameter for backward
249
        compatibility with older versions of python-gvm, but are not validated.
250
251
        Arguments:
252
            resource_type: The entity type to gather data from
253
            filter: Filter term to use for the query
254
            filter_id: UUID of an existing filter to use for the query
255
            sort_criteria: List of sort criteria (dicts that can contain
256
                a field, stat and order)
257
            data_columns: List of fields to aggregate data from
258
            group_column: The field to group the entities by
259
            subgroup_column: The field to further group the entities
260
                inside groups by
261
            text_columns: List of simple text columns which no statistics
262
                are calculated for
263
            first_group: The index of the first aggregate group to return
264
            max_groups: The maximum number of aggregate groups to return,
265
                -1 for all
266
            mode: Special mode for aggregation
267
268
        Returns:
269
            The response. See :py:meth:`send_command` for details.
270
        """
271
        if not resource_type:
272
            raise RequiredArgument(
273
                function=self.get_aggregates.__name__, argument='resource_type'
274
            )
275
276
        if not isinstance(resource_type, EntityType):
277
            raise InvalidArgumentType(
278
                function=self.get_aggregates.__name__,
279
                argument='resource_type',
280
                arg_type=EntityType.__name__,
281
            )
282
283
        cmd = XmlCommand('get_aggregates')
284
285
        _actual_resource_type = resource_type
286
        if resource_type.value == EntityType.AUDIT.value:
287
            _actual_resource_type = EntityType.TASK
288
            cmd.set_attribute('usage_type', 'audit')
289
        elif resource_type.value == EntityType.POLICY.value:
290
            _actual_resource_type = EntityType.SCAN_CONFIG
291
            cmd.set_attribute('usage_type', 'policy')
292
        elif resource_type.value == EntityType.SCAN_CONFIG.value:
293
            cmd.set_attribute('usage_type', 'scan')
294
        elif resource_type.value == EntityType.TASK.value:
295
            cmd.set_attribute('usage_type', 'scan')
296
        cmd.set_attribute('type', _actual_resource_type.value)
297
298
        add_filter(cmd, filter, filter_id)
299
300
        if first_group is not None:
301
            if not isinstance(first_group, int):
302
                raise InvalidArgumentType(
303
                    function=self.get_aggregates.__name__,
304
                    argument='first_group',
305
                    arg_type=int.__name__,
306
                )
307
            cmd.set_attribute('first_group', str(first_group))
308
309
        if max_groups is not None:
310
            if not isinstance(max_groups, int):
311
                raise InvalidArgumentType(
312
                    function=self.get_aggregates.__name__,
313
                    argument='max_groups',
314
                    arg_type=int.__name__,
315
                )
316
            cmd.set_attribute('max_groups', str(max_groups))
317
318
        if sort_criteria is not None:
319
            if not isinstance(sort_criteria, list):
320
                raise InvalidArgumentType(
321
                    function=self.get_aggregates.__name__,
322
                    argument='sort_criteria',
323
                    arg_type=list.__name__,
324
                )
325
            for sort in sort_criteria:
326
                if not isinstance(sort, dict):
327
                    raise InvalidArgumentType(
328
                        function=self.get_aggregates.__name__,
329
                        argument='sort_criteria',
330
                    )
331
332
                sort_elem = cmd.add_element('sort')
333
                if sort.get('field'):
334
                    sort_elem.set_attribute('field', sort.get('field'))
335
336
                if sort.get('stat'):
337
                    if isinstance(sort['stat'], AggregateStatistic):
338
                        sort_elem.set_attribute('stat', sort['stat'].value)
339
                    else:
340
                        stat = get_aggregate_statistic_from_string(sort['stat'])
341
                        sort_elem.set_attribute('stat', stat.value)
342
343
                if sort.get('order'):
344
                    if isinstance(sort['order'], SortOrder):
345
                        sort_elem.set_attribute('order', sort['order'].value)
346
                    else:
347
                        so = get_sort_order_from_string(sort['order'])
348
                        sort_elem.set_attribute('order', so.value)
349
350
        if data_columns is not None:
351
            if not isinstance(data_columns, list):
352
                raise InvalidArgumentType(
353
                    function=self.get_aggregates.__name__,
354
                    argument='data_columns',
355
                    arg_type=list.__name__,
356
                )
357
            for column in data_columns:
358
                cmd.add_element('data_column', column)
359
360
        if group_column is not None:
361
            cmd.set_attribute('group_column', group_column)
362
363
        if subgroup_column is not None:
364
            if not group_column:
365
                raise RequiredArgument(
366
                    '{} requires a group_column argument'
367
                    ' if subgroup_column is given'.format(
368
                        self.get_aggregates.__name__
369
                    ),
370
                    function=self.get_aggregates.__name__,
371
                    argument='subgroup_column',
372
                )
373
            cmd.set_attribute('subgroup_column', subgroup_column)
374
375
        if text_columns is not None:
376
            if not isinstance(text_columns, list):
377
                raise InvalidArgumentType(
378
                    function=self.get_aggregates.__name__,
379
                    argument='text_columns',
380
                    arg_type=list.__name__,
381
                )
382
            for column in text_columns:
383
                cmd.add_element('text_column', column)
384
385
        if mode is not None:
386
            cmd.set_attribute('mode', mode)
387
388
        # Add additional keyword args as attributes for backward compatibility.
389
        cmd.set_attributes(kwargs)
390
391
        return self._send_xml_command(cmd)
392
393
    def modify_tag(
394
        self,
395
        tag_id: str,
396
        *,
397
        comment: Optional[str] = None,
398
        name: Optional[str] = None,
399
        value=None,
400
        active=None,
401
        resource_action: Optional[str] = None,
402
        resource_type: Optional[EntityType] = None,
403
        resource_filter: Optional[str] = None,
404
        resource_ids: Optional[List[str]] = None,
405
    ) -> Any:
406
        """Modifies an existing tag.
407
408
        Arguments:
409
            tag_id: UUID of the tag.
410
            comment: Comment to add to the tag.
411
            name: Name of the tag.
412
            value: Value of the tag.
413
            active: Whether the tag is active.
414
            resource_action: Whether to add or remove resources instead of
415
                overwriting. One of '', 'add', 'set' or 'remove'.
416
            resource_type: Type of the resources to which to attach the tag.
417
                Required if resource_filter is set.
418
            resource_filter: Filter term to select resources the tag is to be
419
                attached to.
420
            resource_ids: IDs of the resources to which to attach the tag.
421
422
        Returns:
423
            The response. See :py:meth:`send_command` for details.
424
        """
425
        if not tag_id:
426
            raise RequiredArgument(
427
                function=self.modify_tag.__name__, argument='tag_id'
428
            )
429
430
        cmd = XmlCommand("modify_tag")
431
        cmd.set_attribute("tag_id", str(tag_id))
432
433
        if comment:
434
            cmd.add_element("comment", comment)
435
436
        if name:
437
            cmd.add_element("name", name)
438
439
        if value:
440
            cmd.add_element("value", value)
441
442
        if active is not None:
443
            cmd.add_element("active", to_bool(active))
444
445
        if resource_action or resource_filter or resource_ids or resource_type:
446
            if resource_filter and not resource_type:
447
                raise RequiredArgument(
448
                    function=self.modify_tag.__name__, argument='resource_type'
449
                )
450
451
            _xmlresources = cmd.add_element("resources")
452
            if resource_action is not None:
453
                _xmlresources.set_attribute("action", resource_action)
454
455
            if resource_filter is not None:
456
                _xmlresources.set_attribute("filter", resource_filter)
457
458
            for resource_id in resource_ids or []:
459
                _xmlresources.add_element(
460
                    "resource", attrs={"id": str(resource_id)}
461
                )
462
463
            if resource_type is not None:
464
                if not isinstance(resource_type, EntityType):
465
                    raise InvalidArgumentType(
466
                        function=self.modify_tag.__name__,
467
                        argument="resource_type",
468
                        arg_type=EntityType.__name__,
469
                    )
470
                _actual_resource_type = resource_type
471
                if resource_type.value == EntityType.AUDIT.value:
472
                    _actual_resource_type = EntityType.TASK
473
                elif resource_type.value == EntityType.POLICY.value:
474
                    _actual_resource_type = EntityType.SCAN_CONFIG
475
                _xmlresources.add_element("type", _actual_resource_type.value)
476
477
        return self._send_xml_command(cmd)
478
479
    def clone_ticket(self, ticket_id: str) -> Any:
480
        """Clone an existing ticket
481
482
        Arguments:
483
            ticket_id: UUID of an existing ticket to clone from
484
485
        Returns:
486
            The response. See :py:meth:`send_command` for details.
487
        """
488
        if not ticket_id:
489
            raise RequiredArgument(
490
                function=self.clone_ticket.__name__, argument='ticket_id'
491
            )
492
493
        cmd = XmlCommand("create_ticket")
494
495
        _copy = cmd.add_element("copy", ticket_id)
496
497
        return self._send_xml_command(cmd)
498
499
    def get_feed(self, feed_type: Optional[FeedType]) -> Any:
500
        """Request a single feed
501
502
        Arguments:
503
            feed_type: Type of single feed to get: NVT, CERT or SCAP
504
505
        Returns:
506
            The response. See :py:meth:`send_command` for details.
507
        """
508
        if not feed_type:
509
            raise RequiredArgument(
510
                function=self.get_feed.__name__, argument='feed_type'
511
            )
512
513
        if not isinstance(feed_type, FeedType):
514
            raise InvalidArgumentType(
515
                function=self.get_feed.__name__,
516
                argument='feed_type',
517
                arg_type=FeedType.__name__,
518
            )
519
520
        cmd = XmlCommand("get_feeds")
521
        cmd.set_attribute("type", feed_type.value)
522
523
        return self._send_xml_command(cmd)
524
525
    def create_ticket(
526
        self,
527
        *,
528
        result_id: str,
529
        assigned_to_user_id: str,
530
        note: str,
531
        comment: Optional[str] = None,
532
    ) -> Any:
533
        """Create a new ticket
534
535
        Arguments:
536
            result_id: UUID of the result the ticket applies to
537
            assigned_to_user_id: UUID of a user the ticket should be assigned to
538
            note: A note about opening the ticket
539
            comment: Comment for the ticket
540
541
        Returns:
542
            The response. See :py:meth:`send_command` for details.
543
        """
544
        if not result_id:
545
            raise RequiredArgument(
546
                function=self.create_ticket.__name__, argument='result_id'
547
            )
548
549
        if not assigned_to_user_id:
550
            raise RequiredArgument(
551
                function=self.create_ticket.__name__,
552
                argument='assigned_to_user_id',
553
            )
554
555
        if not note:
556
            raise RequiredArgument(
557
                function=self.create_ticket.__name__, argument='note'
558
            )
559
560
        cmd = XmlCommand("create_ticket")
561
562
        _result = cmd.add_element("result")
563
        _result.set_attribute("id", result_id)
564
565
        _assigned = cmd.add_element("assigned_to")
566
        _user = _assigned.add_element("user")
567
        _user.set_attribute("id", assigned_to_user_id)
568
569
        _note = cmd.add_element("open_note", note)
570
571
        if comment:
572
            cmd.add_element("comment", comment)
573
574
        return self._send_xml_command(cmd)
575
576
    def delete_ticket(
577
        self, ticket_id: str, *, ultimate: Optional[bool] = False
578
    ):
579
        """Deletes an existing ticket
580
581
        Arguments:
582
            ticket_id: UUID of the ticket to be deleted.
583
            ultimate: Whether to remove entirely, or to the trashcan.
584
        """
585
        if not ticket_id:
586
            raise RequiredArgument(
587
                function=self.delete_ticket.__name__, argument='ticket_id'
588
            )
589
590
        cmd = XmlCommand("delete_ticket")
591
        cmd.set_attribute("ticket_id", ticket_id)
592
        cmd.set_attribute("ultimate", to_bool(ultimate))
593
594
        return self._send_xml_command(cmd)
595
596 View Code Duplication
    def get_tickets(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
597
        self,
598
        *,
599
        trash: Optional[bool] = None,
600
        filter: Optional[str] = None,
601
        filter_id: Optional[str] = None,
602
    ) -> Any:
603
        """Request a list of tickets
604
605
        Arguments:
606
            filter: Filter term to use for the query
607
            filter_id: UUID of an existing filter to use for the query
608
            trash: True to request the tickets in the trashcan
609
610
        Returns:
611
            The response. See :py:meth:`send_command` for details.
612
        """
613
        cmd = XmlCommand("get_tickets")
614
615
        add_filter(cmd, filter, filter_id)
616
617
        if trash is not None:
618
            cmd.set_attribute("trash", to_bool(trash))
619
620
        return self._send_xml_command(cmd)
621
622
    def get_ticket(self, ticket_id: str) -> Any:
623
        """Request a single ticket
624
625
        Arguments:
626
            ticket_id: UUID of an existing ticket
627
628
        Returns:
629
            The response. See :py:meth:`send_command` for details.
630
        """
631
        if not ticket_id:
632
            raise RequiredArgument(
633
                function=self.get_ticket.__name__, argument='ticket_id'
634
            )
635
636
        cmd = XmlCommand("get_tickets")
637
        cmd.set_attribute("ticket_id", ticket_id)
638
        return self._send_xml_command(cmd)
639
640
    def get_vulnerabilities(
641
        self, *, filter: Optional[str] = None, filter_id: Optional[str] = None
642
    ) -> Any:
643
        """Request a list of vulnerabilities
644
645
        Arguments:
646
            filter: Filter term to use for the query
647
            filter_id: UUID of an existing filter to use for the query
648
        Returns:
649
            The response. See :py:meth:`send_command` for details.
650
        """
651
        cmd = XmlCommand("get_vulns")
652
653
        add_filter(cmd, filter, filter_id)
654
655
        return self._send_xml_command(cmd)
656
657
    def get_vulnerability(self, vulnerability_id: str) -> Any:
658
        """Request a single vulnerability
659
660
        Arguments:
661
            vulnerability_id: ID of an existing vulnerability
662
663
        Returns:
664
            The response. See :py:meth:`send_command` for details.
665
        """
666
        if not vulnerability_id:
667
            raise RequiredArgument(
668
                function=self.get_vulnerability.__name__,
669
                argument='vulnerability_id',
670
            )
671
672
        cmd = XmlCommand("get_vulns")
673
        cmd.set_attribute("vuln_id", vulnerability_id)
674
        return self._send_xml_command(cmd)
675
676
    def modify_ticket(
677
        self,
678
        ticket_id: str,
679
        *,
680
        status: Optional[TicketStatus] = None,
681
        note: Optional[str] = None,
682
        assigned_to_user_id: Optional[str] = None,
683
        comment: Optional[str] = None,
684
    ) -> Any:
685
        """Modify a single ticket
686
687
        Arguments:
688
            ticket_id: UUID of an existing ticket
689
            status: New status for the ticket
690
            note: Note for the status change. Required if status is set.
691
            assigned_to_user_id: UUID of the user the ticket should be assigned
692
                to
693
            comment: Comment for the ticket
694
695
        Returns:
696
            The response. See :py:meth:`send_command` for details.
697
        """
698
        if not ticket_id:
699
            raise RequiredArgument(
700
                function=self.modify_ticket.__name__, argument='ticket_id'
701
            )
702
703
        if status and not note:
704
            raise RequiredArgument(
705
                function=self.modify_ticket.__name__, argument='note'
706
            )
707
708
        if note and not status:
709
            raise RequiredArgument(
710
                function=self.modify_ticket.__name__, argument='status'
711
            )
712
713
        cmd = XmlCommand("modify_ticket")
714
        cmd.set_attribute("ticket_id", ticket_id)
715
716
        if assigned_to_user_id:
717
            _assigned = cmd.add_element("assigned_to")
718
            _user = _assigned.add_element("user")
719
            _user.set_attribute("id", assigned_to_user_id)
720
721
        if status:
722
            if not isinstance(status, self.types.TicketStatus):
723
                raise InvalidArgumentType(
724
                    function=self.modify_ticket.__name__,
725
                    argument='status',
726
                    arg_type=TicketStatus.__name__,
727
                )
728
729
            cmd.add_element('status', status.value)
730
            cmd.add_element('{}_note'.format(status.name.lower()), note)
731
732
        if comment:
733
            cmd.add_element("comment", comment)
734
735
        return self._send_xml_command(cmd)
736
737 View Code Duplication
    def create_filter(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
738
        self,
739
        name: str,
740
        *,
741
        filter_type: Optional[FilterType] = None,
742
        comment: Optional[str] = None,
743
        term: Optional[str] = None,
744
    ) -> Any:
745
        """Create a new filter
746
747
        Arguments:
748
            name: Name of the new filter
749
            filter_type: Filter for entity type
750
            comment: Comment for the filter
751
            term: Filter term e.g. 'name=foo'
752
753
        Returns:
754
            The response. See :py:meth:`send_command` for details.
755
        """
756
        if not name:
757
            raise RequiredArgument(
758
                function=self.create_filter.__name__, argument="name"
759
            )
760
761
        cmd = XmlCommand("create_filter")
762
        _xmlname = cmd.add_element("name", name)
763
764
        if comment:
765
            cmd.add_element("comment", comment)
766
767
        if term:
768
            cmd.add_element("term", term)
769
770
        if filter_type:
771
            if not isinstance(filter_type, self.types.FilterType):
772
                raise InvalidArgumentType(
773
                    function=self.create_filter.__name__,
774
                    argument="filter_type",
775
                    arg_type=self.types.FilterType.__name__,
776
                )
777
778
            cmd.add_element("type", filter_type.value)
779
780
        return self._send_xml_command(cmd)
781
782 View Code Duplication
    def modify_filter(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
783
        self,
784
        filter_id: str,
785
        *,
786
        comment: Optional[str] = None,
787
        name: Optional[str] = None,
788
        term: Optional[str] = None,
789
        filter_type: Optional[FilterType] = None,
790
    ) -> Any:
791
        """Modifies an existing filter.
792
793
        Arguments:
794
            filter_id: UUID of the filter to be modified
795
            comment: Comment on filter.
796
            name: Name of filter.
797
            term: Filter term.
798
            filter_type: Resource type filter applies to.
799
800
        Returns:
801
            The response. See :py:meth:`send_command` for details.
802
        """
803
        if not filter_id:
804
            raise RequiredArgument(
805
                function=self.modify_filter.__name__, argument='filter_id'
806
            )
807
808
        cmd = XmlCommand("modify_filter")
809
        cmd.set_attribute("filter_id", filter_id)
810
811
        if comment:
812
            cmd.add_element("comment", comment)
813
814
        if name:
815
            cmd.add_element("name", name)
816
817
        if term:
818
            cmd.add_element("term", term)
819
820
        if filter_type:
821
            if not isinstance(filter_type, self.types.FilterType):
822
                raise InvalidArgumentType(
823
                    function=self.modify_filter.__name__,
824
                    argument='filter_type',
825
                    arg_type=FilterType.__name__,
826
                )
827
            cmd.add_element("type", filter_type.value)
828
829
        return self._send_xml_command(cmd)
830
831
    def create_schedule(
832
        self,
833
        name: str,
834
        icalendar: str,
835
        timezone: str,
836
        *,
837
        comment: Optional[str] = None,
838
    ) -> Any:
839
        """Create a new schedule based in `iCalendar`_ data.
840
841
        Example:
842
            Requires https://pypi.org/project/icalendar/
843
844
            .. code-block:: python
845
846
                import pytz
847
848
                from datetime import datetime
849
850
                from icalendar import Calendar, Event
851
852
                cal = Calendar()
853
854
                cal.add('prodid', '-//Foo Bar//')
855
                cal.add('version', '2.0')
856
857
                event = Event()
858
                event.add('dtstamp', datetime.now(tz=pytz.UTC))
859
                event.add('dtstart', datetime(2020, 1, 1, tzinfo=pytz.utc))
860
861
                cal.add_component(event)
862
863
                gmp.create_schedule(
864
                    name="My Schedule",
865
                    icalendar=cal.to_ical(),
866
                    timezone='UTC'
867
                )
868
        Arguments:
869
            name: Name of the new schedule
870
            icalendar: `iCalendar`_ (RFC 5545) based data.
871
            timezone: Timezone to use for the icalender events e.g
872
                Europe/Berlin. If the datetime values in the icalendar data are
873
                missing timezone information this timezone gets applied.
874
                Otherwise the datetime values from the icalendar data are
875
                displayed in this timezone
876
            comment: Comment on schedule.
877
878
        Returns:
879
            The response. See :py:meth:`send_command` for details.
880
881
        .. _iCalendar:
882
            https://tools.ietf.org/html/rfc5545
883
        """
884
        if not name:
885
            raise RequiredArgument(
886
                function=self.create_schedule.__name__, argument='name'
887
            )
888
        if not icalendar:
889
            raise RequiredArgument(
890
                function=self.create_schedule.__name__, argument='icalendar'
891
            )
892
        if not timezone:
893
            raise RequiredArgument(
894
                function=self.create_schedule.__name__, argument='timezone'
895
            )
896
897
        cmd = XmlCommand("create_schedule")
898
899
        cmd.add_element("name", name)
900
        cmd.add_element("icalendar", icalendar)
901
        cmd.add_element("timezone", timezone)
902
903
        if comment:
904
            cmd.add_element("comment", comment)
905
906
        return self._send_xml_command(cmd)
907
908
    def modify_schedule(
909
        self,
910
        schedule_id: str,
911
        *,
912
        name: Optional[str] = None,
913
        icalendar: Optional[str] = None,
914
        timezone: Optional[str] = None,
915
        comment: Optional[str] = None,
916
    ) -> Any:
917
        """Modifies an existing schedule
918
919
        Arguments:
920
            schedule_id: UUID of the schedule to be modified
921
            name: Name of the schedule
922
            icalendar: `iCalendar`_ (RFC 5545) based data.
923
            timezone: Timezone to use for the icalender events e.g
924
                Europe/Berlin. If the datetime values in the icalendar data are
925
                missing timezone information this timezone gets applied.
926
                Otherwise the datetime values from the icalendar data are
927
                displayed in this timezone
928
            commenhedule.
929
930
        Returns:
931
            The response. See :py:meth:`send_command` for details.
932
933
        .. _iCalendar:
934
            https://tools.ietf.org/html/rfc5545
935
        """
936
        if not schedule_id:
937
            raise RequiredArgument(
938
                function=self.modify_schedule.__name__, argument='schedule_id'
939
            )
940
941
        cmd = XmlCommand("modify_schedule")
942
        cmd.set_attribute("schedule_id", schedule_id)
943
944
        if name:
945
            cmd.add_element("name", name)
946
947
        if icalendar:
948
            cmd.add_element("icalendar", icalendar)
949
950
        if timezone:
951
            cmd.add_element("timezone", timezone)
952
953
        if comment:
954
            cmd.add_element("comment", comment)
955
956
        return self._send_xml_command(cmd)
957
958
    def clone_filter(self, filter_id: str) -> Any:
959
        """Clone an existing filter
960
961
        Arguments:
962
            filter_id: UUID of an existing filter to clone from
963
964
        Returns:
965
            The response. See :py:meth:`send_command` for details.
966
        """
967
        if not filter_id:
968
            raise RequiredArgument(
969
                function=self.clone_filter.__name__, argument='filter_id'
970
            )
971
972
        cmd = XmlCommand("create_filter")
973
        cmd.add_element("copy", filter_id)
974
        return self._send_xml_command(cmd)
975
976
    def create_group(
977
        self,
978
        name: str,
979
        *,
980
        comment: Optional[str] = None,
981
        special: Optional[bool] = False,
982
        users: Optional[List[str]] = None,
983
    ) -> Any:
984
        """Create a new group
985
986
        Arguments:
987
            name: Name of the new group
988
            comment: Comment for the group
989
            special: Create permission giving members full access to each
990
                other's entities
991
            users: List of user names to be in the group
992
993
        Returns:
994
            The response. See :py:meth:`send_command` for details.
995
        """
996
        if not name:
997
            raise RequiredArgument(
998
                function=self.create_group.__name__, argument='name'
999
            )
1000
1001
        cmd = XmlCommand("create_group")
1002
        cmd.add_element("name", name)
1003
1004
        if comment:
1005
            cmd.add_element("comment", comment)
1006
1007
        if special:
1008
            _xmlspecial = cmd.add_element("specials")
1009
            _xmlspecial.add_element("full")
1010
1011
        if users:
1012
            cmd.add_element("users", to_comma_list(users))
1013
1014
        return self._send_xml_command(cmd)
1015
1016
    def clone_group(self, group_id: str) -> Any:
1017
        """Clone an existing group
1018
1019
        Arguments:
1020
            group_id: UUID of an existing group to clone from
1021
1022
        Returns:
1023
            The response. See :py:meth:`send_command` for details.
1024
        """
1025
        if not group_id:
1026
            raise RequiredArgument(
1027
                function=self.clone_group.__name__, argument='group_id'
1028
            )
1029
1030
        cmd = XmlCommand("create_group")
1031
        cmd.add_element("copy", group_id)
1032
        return self._send_xml_command(cmd)
1033
1034
    def clone_report_format(
1035
        self, report_format_id: [Union[str, ReportFormatType]]
1036
    ) -> Any:
1037
        """Clone a report format from an existing one
1038
1039
        Arguments:
1040
            report_format_id: UUID of the existing report format
1041
                              or ReportFormatType (enum)
1042
1043
        Returns:
1044
            The response. See :py:meth:`send_command` for details.
1045
        """
1046
        if not report_format_id:
1047
            raise RequiredArgument(
1048
                function=self.clone_report_format.__name__,
1049
                argument='report_format_id',
1050
            )
1051
1052
        cmd = XmlCommand("create_report_format")
1053
1054
        if isinstance(report_format_id, ReportFormatType):
1055
            report_format_id = report_format_id.value
1056
1057
        cmd.add_element("copy", report_format_id)
1058
        return self._send_xml_command(cmd)
1059
1060
    def import_report_format(self, report_format: str) -> Any:
1061
        """Import a report format from XML
1062
1063
        Arguments:
1064
            report_format: Report format XML as string to import. This XML must
1065
                contain a :code:`<get_report_formats_response>` root element.
1066
1067
        Returns:
1068
            The response. See :py:meth:`send_command` for details.
1069
        """
1070
        if not report_format:
1071
            raise RequiredArgument(
1072
                function=self.import_report_format.__name__,
1073
                argument='report_format',
1074
            )
1075
1076
        cmd = XmlCommand("create_report_format")
1077
1078
        try:
1079
            cmd.append_xml_str(report_format)
1080
        except etree.XMLSyntaxError as e:
1081
            raise InvalidArgument(
1082
                function=self.import_report_format.__name__,
1083
                argument='report_format',
1084
            ) from e
1085
1086
        return self._send_xml_command(cmd)
1087
1088
    def create_role(
1089
        self,
1090
        name: str,
1091
        *,
1092
        comment: Optional[str] = None,
1093
        users: Optional[List[str]] = None,
1094
    ) -> Any:
1095
        """Create a new role
1096
1097
        Arguments:
1098
            name: Name of the role
1099
            comment: Comment for the role
1100
            users: List of user names to add to the role
1101
1102
        Returns:
1103
            The response. See :py:meth:`send_command` for details.
1104
        """
1105
1106
        if not name:
1107
            raise RequiredArgument(
1108
                function=self.create_role.__name__, argument='name'
1109
            )
1110
1111
        cmd = XmlCommand("create_role")
1112
        cmd.add_element("name", name)
1113
1114
        if comment:
1115
            cmd.add_element("comment", comment)
1116
1117
        if users:
1118
            cmd.add_element("users", to_comma_list(users))
1119
1120
        return self._send_xml_command(cmd)
1121
1122
    def clone_role(self, role_id: str) -> Any:
1123
        """Clone an existing role
1124
1125
        Arguments:
1126
            role_id: UUID of an existing role to clone from
1127
1128
        Returns:
1129
            The response. See :py:meth:`send_command` for details.
1130
        """
1131
        if not role_id:
1132
            raise RequiredArgument(
1133
                function=self.clone_role.__name__, argument='role_id'
1134
            )
1135
1136
        cmd = XmlCommand("create_role")
1137
        cmd.add_element("copy", role_id)
1138
        return self._send_xml_command(cmd)
1139
1140
    def clone_schedule(self, schedule_id: str) -> Any:
1141
        """Clone an existing schedule
1142
1143
        Arguments:
1144
            schedule_id: UUID of an existing schedule to clone from
1145
1146
        Returns:
1147
            The response. See :py:meth:`send_command` for details.
1148
        """
1149
        if not schedule_id:
1150
            raise RequiredArgument(
1151
                function=self.clone_schedule.__name__, argument='schedule_id'
1152
            )
1153
1154
        cmd = XmlCommand("create_schedule")
1155
        cmd.add_element("copy", schedule_id)
1156
        return self._send_xml_command(cmd)
1157
1158
    def clone_tag(self, tag_id: str) -> Any:
1159
        """Clone an existing tag
1160
1161
        Arguments:
1162
            tag_id: UUID of an existing tag to clone from
1163
1164
        Returns:
1165
            The response. See :py:meth:`send_command` for details.
1166
        """
1167
        if not tag_id:
1168
            raise RequiredArgument(
1169
                function=self.clone_tag.__name__, argument='tag_id'
1170
            )
1171
1172
        cmd = XmlCommand("create_tag")
1173
        cmd.add_element("copy", tag_id)
1174
        return self._send_xml_command(cmd)
1175
1176
    def delete_filter(
1177
        self, filter_id: str, *, ultimate: Optional[bool] = False
1178
    ) -> Any:
1179
        """Deletes an existing filter
1180
1181
        Arguments:
1182
            filter_id: UUID of the filter to be deleted.
1183
            ultimate: Whether to remove entirely, or to the trashcan.
1184
        """
1185
        if not filter_id:
1186
            raise RequiredArgument(
1187
                function=self.delete_filter.__name__, argument='filter_id'
1188
            )
1189
1190
        cmd = XmlCommand("delete_filter")
1191
        cmd.set_attribute("filter_id", filter_id)
1192
        cmd.set_attribute("ultimate", to_bool(ultimate))
1193
1194
        return self._send_xml_command(cmd)
1195
1196
    def delete_group(
1197
        self, group_id: str, *, ultimate: Optional[bool] = False
1198
    ) -> Any:
1199
        """Deletes an existing group
1200
1201
        Arguments:
1202
            group_id: UUID of the group to be deleted.
1203
            ultimate: Whether to remove entirely, or to the trashcan.
1204
        """
1205
        if not group_id:
1206
            raise RequiredArgument(
1207
                function=self.delete_group.__name__, argument='group_id'
1208
            )
1209
1210
        cmd = XmlCommand("delete_group")
1211
        cmd.set_attribute("group_id", group_id)
1212
        cmd.set_attribute("ultimate", to_bool(ultimate))
1213
1214
        return self._send_xml_command(cmd)
1215
1216
    def delete_report_format(
1217
        self,
1218
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
1219
        *,
1220
        ultimate: Optional[bool] = False,
1221
    ) -> Any:
1222
        """Deletes an existing report format
1223
1224
        Arguments:
1225
            report_format_id: UUID of the report format to be deleted.
1226
                              or ReportFormatType (enum)
1227
            ultimate: Whether to remove entirely, or to the trashcan.
1228
        """
1229
        if not report_format_id:
1230
            raise RequiredArgument(
1231
                function=self.delete_report_format.__name__,
1232
                argument='report_format_id',
1233
            )
1234
1235
        cmd = XmlCommand("delete_report_format")
1236
1237
        if isinstance(report_format_id, ReportFormatType):
1238
            report_format_id = report_format_id.value
1239
1240
        cmd.set_attribute("report_format_id", report_format_id)
1241
1242
        cmd.set_attribute("ultimate", to_bool(ultimate))
1243
1244
        return self._send_xml_command(cmd)
1245
1246
    def delete_role(
1247
        self, role_id: str, *, ultimate: Optional[bool] = False
1248
    ) -> Any:
1249
        """Deletes an existing role
1250
1251
        Arguments:
1252
            role_id: UUID of the role to be deleted.
1253
            ultimate: Whether to remove entirely, or to the trashcan.
1254
        """
1255
        if not role_id:
1256
            raise RequiredArgument(
1257
                function=self.delete_role.__name__, argument='role_id'
1258
            )
1259
1260
        cmd = XmlCommand("delete_role")
1261
        cmd.set_attribute("role_id", role_id)
1262
        cmd.set_attribute("ultimate", to_bool(ultimate))
1263
1264
        return self._send_xml_command(cmd)
1265
1266
    def delete_schedule(
1267
        self, schedule_id: str, *, ultimate: Optional[bool] = False
1268
    ) -> Any:
1269
        """Deletes an existing schedule
1270
1271
        Arguments:
1272
            schedule_id: UUID of the schedule to be deleted.
1273
            ultimate: Whether to remove entirely, or to the trashcan.
1274
        """
1275
        if not schedule_id:
1276
            raise RequiredArgument(
1277
                function=self.delete_schedule.__name__, argument='schedule_id'
1278
            )
1279
1280
        cmd = XmlCommand("delete_schedule")
1281
        cmd.set_attribute("schedule_id", schedule_id)
1282
        cmd.set_attribute("ultimate", to_bool(ultimate))
1283
1284
        return self._send_xml_command(cmd)
1285
1286
    def delete_tag(
1287
        self, tag_id: str, *, ultimate: Optional[bool] = False
1288
    ) -> Any:
1289
        """Deletes an existing tag
1290
1291
        Arguments:
1292
            tag_id: UUID of the tag to be deleted.
1293
            ultimate: Whether to remove entirely, or to the trashcan.
1294
        """
1295
        if not tag_id:
1296
            raise RequiredArgument(
1297
                function=self.delete_tag.__name__, argument='tag_id'
1298
            )
1299
1300
        cmd = XmlCommand("delete_tag")
1301
        cmd.set_attribute("tag_id", tag_id)
1302
        cmd.set_attribute("ultimate", to_bool(ultimate))
1303
1304
        return self._send_xml_command(cmd)
1305
1306
    def describe_auth(self) -> Any:
1307
        """Describe authentication methods
1308
1309
        Returns a list of all used authentication methods if such a list is
1310
        available.
1311
1312
        Returns:
1313
            The response. See :py:meth:`send_command` for details.
1314
        """
1315
        return self._send_xml_command(XmlCommand("describe_auth"))
1316
1317
    def empty_trashcan(self) -> Any:
1318
        """Empty the trashcan
1319
1320
        Remove all entities from the trashcan. **Attention:** this command can
1321
        not be reverted
1322
1323
        Returns:
1324
            The response. See :py:meth:`send_command` for details.
1325
        """
1326
        return self._send_xml_command(XmlCommand("empty_trashcan"))
1327
1328
    def get_feeds(self) -> Any:
1329
        """Request the list of feeds
1330
1331
        Returns:
1332
            The response. See :py:meth:`send_command` for details.
1333
        """
1334
        return self._send_xml_command(XmlCommand("get_feeds"))
1335
1336 View Code Duplication
    def get_filters(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1337
        self,
1338
        *,
1339
        filter: Optional[str] = None,
1340
        filter_id: Optional[str] = None,
1341
        trash: Optional[bool] = None,
1342
        alerts: Optional[bool] = None,
1343
    ) -> Any:
1344
        """Request a list of filters
1345
1346
        Arguments:
1347
            filter: Filter term to use for the query
1348
            filter_id: UUID of an existing filter to use for the query
1349
            trash: Whether to get the trashcan filters instead
1350
            alerts: Whether to include list of alerts that use the filter.
1351
1352
        Returns:
1353
            The response. See :py:meth:`send_command` for details.
1354
        """
1355
        cmd = XmlCommand("get_filters")
1356
1357
        add_filter(cmd, filter, filter_id)
1358
1359
        if trash is not None:
1360
            cmd.set_attribute("trash", to_bool(trash))
1361
1362
        if alerts is not None:
1363
            cmd.set_attribute("alerts", to_bool(alerts))
1364
1365
        return self._send_xml_command(cmd)
1366
1367
    def get_filter(
1368
        self, filter_id: str, *, alerts: Optional[bool] = None
1369
    ) -> Any:
1370
        """Request a single filter
1371
1372
        Arguments:
1373
            filter_id: UUID of an existing filter
1374
            alerts: Whether to include list of alerts that use the filter.
1375
1376
        Returns:
1377
            The response. See :py:meth:`send_command` for details.
1378
        """
1379
        cmd = XmlCommand("get_filters")
1380
1381
        if not filter_id:
1382
            raise RequiredArgument(
1383
                function=self.get_filter.__name__, argument='filter_id'
1384
            )
1385
1386
        cmd.set_attribute("filter_id", filter_id)
1387
1388
        if alerts is not None:
1389
            cmd.set_attribute("alerts", to_bool(alerts))
1390
1391
        return self._send_xml_command(cmd)
1392
1393 View Code Duplication
    def get_groups(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1394
        self,
1395
        *,
1396
        filter: Optional[str] = None,
1397
        filter_id: Optional[str] = None,
1398
        trash: Optional[bool] = None,
1399
    ) -> Any:
1400
        """Request a list of groups
1401
1402
        Arguments:
1403
            filter: Filter term to use for the query
1404
            filter_id: UUID of an existing filter to use for the query
1405
            trash: Whether to get the trashcan groups instead
1406
1407
        Returns:
1408
            The response. See :py:meth:`send_command` for details.
1409
        """
1410
        cmd = XmlCommand("get_groups")
1411
1412
        add_filter(cmd, filter, filter_id)
1413
1414
        if trash is not None:
1415
            cmd.set_attribute("trash", to_bool(trash))
1416
1417
        return self._send_xml_command(cmd)
1418
1419
    def get_group(self, group_id: str) -> Any:
1420
        """Request a single group
1421
1422
        Arguments:
1423
            group_id: UUID of an existing group
1424
1425
        Returns:
1426
            The response. See :py:meth:`send_command` for details.
1427
        """
1428
        cmd = XmlCommand("get_groups")
1429
1430
        if not group_id:
1431
            raise RequiredArgument(
1432
                function=self.get_group.__name__, argument='group_id'
1433
            )
1434
1435
        cmd.set_attribute("group_id", group_id)
1436
        return self._send_xml_command(cmd)
1437
1438
    def get_preferences(
1439
        self, *, nvt_oid: Optional[str] = None, config_id: Optional[str] = None
1440
    ) -> Any:
1441
        """Request a list of preferences
1442
1443
        When the command includes a config_id attribute, the preference element
1444
        includes the preference name, type and value, and the NVT to which the
1445
        preference applies. Otherwise, the preference element includes just the
1446
        name and value, with the NVT and type built into the name.
1447
1448
        Arguments:
1449
            nvt_oid: OID of nvt
1450
            config_id: UUID of scan config of which to show preference values
1451
1452
        Returns:
1453
            The response. See :py:meth:`send_command` for details.
1454
        """
1455
        cmd = XmlCommand("get_preferences")
1456
1457
        if nvt_oid:
1458
            cmd.set_attribute("nvt_oid", nvt_oid)
1459
1460
        if config_id:
1461
            cmd.set_attribute("config_id", config_id)
1462
1463
        return self._send_xml_command(cmd)
1464
1465
    def get_preference(
1466
        self,
1467
        name: str,
1468
        *,
1469
        nvt_oid: Optional[str] = None,
1470
        config_id: Optional[str] = None,
1471
    ) -> Any:
1472
        """Request a nvt preference
1473
1474
        Arguments:
1475
            name: name of a particular preference
1476
            nvt_oid: OID of nvt
1477
            config_id: UUID of scan config of which to show preference values
1478
1479
        Returns:
1480
            The response. See :py:meth:`send_command` for details.
1481
        """
1482
        cmd = XmlCommand("get_preferences")
1483
1484
        if not name:
1485
            raise RequiredArgument(
1486
                function=self.get_preference.__name__, argument='name'
1487
            )
1488
1489
        cmd.set_attribute("preference", name)
1490
1491
        if nvt_oid:
1492
            cmd.set_attribute("nvt_oid", nvt_oid)
1493
1494
        if config_id:
1495
            cmd.set_attribute("config_id", config_id)
1496
1497
        return self._send_xml_command(cmd)
1498
1499 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...
1500
        self,
1501
        *,
1502
        filter: Optional[str] = None,
1503
        filter_id: Optional[str] = None,
1504
        trash: Optional[bool] = None,
1505
        alerts: Optional[bool] = None,
1506
        params: Optional[bool] = None,
1507
        details: Optional[bool] = None,
1508
    ) -> Any:
1509
        """Request a list of report formats
1510
1511
        Arguments:
1512
            filter: Filter term to use for the query
1513
            filter_id: UUID of an existing filter to use for the query
1514
            trash: Whether to get the trashcan report formats instead
1515
            alerts: Whether to include alerts that use the report format
1516
            params: Whether to include report format parameters
1517
            details: Include report format file, signature and parameters
1518
1519
        Returns:
1520
            The response. See :py:meth:`send_command` for details.
1521
        """
1522
        cmd = XmlCommand("get_report_formats")
1523
1524
        add_filter(cmd, filter, filter_id)
1525
1526
        if details is not None:
1527
            cmd.set_attribute("details", to_bool(details))
1528
1529
        if alerts is not None:
1530
            cmd.set_attribute("alerts", to_bool(alerts))
1531
1532
        if params is not None:
1533
            cmd.set_attribute("params", to_bool(params))
1534
1535
        if trash is not None:
1536
            cmd.set_attribute("trash", to_bool(trash))
1537
1538
        return self._send_xml_command(cmd)
1539
1540 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...
1541
        self, report_format_id: Union[str, ReportFormatType]
1542
    ) -> Any:
1543
        """Request a single report format
1544
1545
        Arguments:
1546
            report_format_id: UUID of an existing report format
1547
                              or ReportFormatType (enum)
1548
        Returns:
1549
            The response. See :py:meth:`send_command` for details.
1550
        """
1551
        cmd = XmlCommand("get_report_formats")
1552
        if not report_format_id:
1553
            raise RequiredArgument(
1554
                function=self.get_report_format.__name__,
1555
                argument='report_format_id',
1556
            )
1557
1558
        if isinstance(report_format_id, ReportFormatType):
1559
            report_format_id = report_format_id.value
1560
1561
        cmd.set_attribute("report_format_id", report_format_id)
1562
1563
        # for single entity always request all details
1564
        cmd.set_attribute("details", "1")
1565
        return self._send_xml_command(cmd)
1566
1567 View Code Duplication
    def get_roles(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1568
        self,
1569
        *,
1570
        filter: Optional[str] = None,
1571
        filter_id: Optional[str] = None,
1572
        trash: Optional[bool] = None,
1573
    ) -> Any:
1574
        """Request a list of roles
1575
1576
        Arguments:
1577
            filter: Filter term to use for the query
1578
            filter_id: UUID of an existing filter to use for the query
1579
            trash: Whether to get the trashcan roles instead
1580
1581
        Returns:
1582
            The response. See :py:meth:`send_command` for details.
1583
        """
1584
        cmd = XmlCommand("get_roles")
1585
1586
        add_filter(cmd, filter, filter_id)
1587
1588
        if trash is not None:
1589
            cmd.set_attribute("trash", to_bool(trash))
1590
1591
        return self._send_xml_command(cmd)
1592
1593
    def get_role(self, role_id: str) -> Any:
1594
        """Request a single role
1595
1596
        Arguments:
1597
            role_id: UUID of an existing role
1598
1599
        Returns:
1600
            The response. See :py:meth:`send_command` for details.
1601
        """
1602
        if not role_id:
1603
            raise RequiredArgument(
1604
                function=self.get_role.__name__, argument='role_id'
1605
            )
1606
1607
        cmd = XmlCommand("get_roles")
1608
        cmd.set_attribute("role_id", role_id)
1609
        return self._send_xml_command(cmd)
1610
1611 View Code Duplication
    def get_schedules(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1612
        self,
1613
        *,
1614
        filter: Optional[str] = None,
1615
        filter_id: Optional[str] = None,
1616
        trash: Optional[bool] = None,
1617
        tasks: Optional[bool] = None,
1618
    ) -> Any:
1619
        """Request a list of schedules
1620
1621
        Arguments:
1622
            filter: Filter term to use for the query
1623
            filter_id: UUID of an existing filter to use for the query
1624
            trash: Whether to get the trashcan schedules instead
1625
            tasks: Whether to include tasks using the schedules
1626
1627
        Returns:
1628
            The response. See :py:meth:`send_command` for details.
1629
        """
1630
        cmd = XmlCommand("get_schedules")
1631
1632
        add_filter(cmd, filter, filter_id)
1633
1634
        if trash is not None:
1635
            cmd.set_attribute("trash", to_bool(trash))
1636
1637
        if tasks is not None:
1638
            cmd.set_attribute("tasks", to_bool(tasks))
1639
1640
        return self._send_xml_command(cmd)
1641
1642
    def get_schedule(
1643
        self, schedule_id: str, *, tasks: Optional[bool] = None
1644
    ) -> Any:
1645
        """Request a single schedule
1646
1647
        Arguments:
1648
            schedule_id: UUID of an existing schedule
1649
            tasks: Whether to include tasks using the schedules
1650
1651
        Returns:
1652
            The response. See :py:meth:`send_command` for details.
1653
        """
1654
        cmd = XmlCommand("get_schedules")
1655
1656
        if not schedule_id:
1657
            raise RequiredArgument(
1658
                function=self.get_schedule.__name__, argument='schedule_id'
1659
            )
1660
1661
        cmd.set_attribute("schedule_id", schedule_id)
1662
1663
        if tasks is not None:
1664
            cmd.set_attribute("tasks", to_bool(tasks))
1665
1666
        return self._send_xml_command(cmd)
1667
1668
    def get_settings(self, *, filter: Optional[str] = None) -> Any:
1669
        """Request a list of user settings
1670
1671
        Arguments:
1672
            filter: Filter term to use for the query
1673
1674
        Returns:
1675
            The response. See :py:meth:`send_command` for details.
1676
        """
1677
        cmd = XmlCommand("get_settings")
1678
1679
        if filter:
1680
            cmd.set_attribute("filter", filter)
1681
1682
        return self._send_xml_command(cmd)
1683
1684
    def get_setting(self, setting_id: str) -> Any:
1685
        """Request a single setting
1686
1687
        Arguments:
1688
            setting_id: UUID of an existing setting
1689
1690
        Returns:
1691
            The response. See :py:meth:`send_command` for details.
1692
        """
1693
        cmd = XmlCommand("get_settings")
1694
1695
        if not setting_id:
1696
            raise RequiredArgument(
1697
                function=self.get_setting.__name__, argument='setting_id'
1698
            )
1699
1700
        cmd.set_attribute("setting_id", setting_id)
1701
        return self._send_xml_command(cmd)
1702
1703
    def get_system_reports(
1704
        self,
1705
        *,
1706
        name: Optional[str] = None,
1707
        duration: Optional[int] = None,
1708
        start_time: Optional[str] = None,
1709
        end_time: Optional[str] = None,
1710
        brief: Optional[bool] = None,
1711
        slave_id: Optional[str] = None,
1712
    ) -> Any:
1713
        """Request a list of system reports
1714
1715
        Arguments:
1716
            name: A string describing the required system report
1717
            duration: The number of seconds into the past that the system report
1718
                should include
1719
            start_time: The start of the time interval the system report should
1720
                include in ISO time format
1721
            end_time: The end of the time interval the system report should
1722
                include in ISO time format
1723
            brief: Whether to include the actual system reports
1724
            slave_id: UUID of GMP scanner from which to get the system reports
1725
1726
        Returns:
1727
            The response. See :py:meth:`send_command` for details.
1728
        """
1729
        cmd = XmlCommand("get_system_reports")
1730
1731
        if name:
1732
            cmd.set_attribute("name", name)
1733
1734
        if duration is not None:
1735
            if not isinstance(duration, Integral):
1736
                raise InvalidArgument("duration needs to be an integer number")
1737
1738
            cmd.set_attribute("duration", str(duration))
1739
1740
        if start_time:
1741
            cmd.set_attribute("start_time", str(start_time))
1742
1743
        if end_time:
1744
            cmd.set_attribute("end_time", str(end_time))
1745
1746
        if brief is not None:
1747
            cmd.set_attribute("brief", to_bool(brief))
1748
1749
        if slave_id:
1750
            cmd.set_attribute("slave_id", slave_id)
1751
1752
        return self._send_xml_command(cmd)
1753
1754 View Code Duplication
    def get_tags(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1755
        self,
1756
        *,
1757
        filter: Optional[str] = None,
1758
        filter_id: Optional[str] = None,
1759
        trash: Optional[bool] = None,
1760
        names_only: Optional[bool] = None,
1761
    ) -> Any:
1762
        """Request a list of tags
1763
1764
        Arguments:
1765
            filter: Filter term to use for the query
1766
            filter_id: UUID of an existing filter to use for the query
1767
            trash: Whether to get tags from the trashcan instead
1768
            names_only: Whether to get only distinct tag names
1769
1770
        Returns:
1771
            The response. See :py:meth:`send_command` for details.
1772
        """
1773
        cmd = XmlCommand("get_tags")
1774
1775
        add_filter(cmd, filter, filter_id)
1776
1777
        if trash is not None:
1778
            cmd.set_attribute("trash", to_bool(trash))
1779
1780
        if names_only is not None:
1781
            cmd.set_attribute("names_only", to_bool(names_only))
1782
1783
        return self._send_xml_command(cmd)
1784
1785
    def get_tag(self, tag_id: str) -> Any:
1786
        """Request a single tag
1787
1788
        Arguments:
1789
            tag_id: UUID of an existing tag
1790
1791
        Returns:
1792
            The response. See :py:meth:`send_command` for details.
1793
        """
1794
        cmd = XmlCommand("get_tags")
1795
1796
        if not tag_id:
1797
            raise RequiredArgument(
1798
                function=self.get_tag.__name__, argument='tag_id'
1799
            )
1800
1801
        cmd.set_attribute("tag_id", tag_id)
1802
        return self._send_xml_command(cmd)
1803
1804
    def get_version(self) -> Any:
1805
        """Get the Greenbone Manager Protocol version used by the remote gvmd
1806
        Returns:
1807
            The response. See :py:meth:`send_command` for details.
1808
        """
1809
        return self._send_xml_command(XmlCommand("get_version"))
1810
1811
    def help(
1812
        self, *, format: Optional[str] = None, help_type: Optional[str] = None
1813
    ) -> Any:
1814
        """Get the help text
1815
1816
        Arguments:
1817
            format: One of "html", "rnc", "text" or "xml
1818
            help_type: One of "brief" or "". Default ""
1819
1820
        Returns:
1821
            The response. See :py:meth:`send_command` for details.
1822
        """
1823
        cmd = XmlCommand("help")
1824
1825
        if not help_type:
1826
            help_type = ""
1827
1828
        if help_type not in ("", "brief"):
1829
            raise InvalidArgument(
1830
                'help_type argument must be an empty string or "brief"'
1831
            )
1832
1833
        cmd.set_attribute("type", help_type)
1834
1835
        if format:
1836
            if not format.lower() in ("html", "rnc", "text", "xml"):
1837
                raise InvalidArgument(
1838
                    "help format Argument must be one of html, rnc, text or "
1839
                    "xml"
1840
                )
1841
1842
            cmd.set_attribute("format", format)
1843
1844
        return self._send_xml_command(cmd)
1845
1846
    def modify_auth(self, group_name: str, auth_conf_settings: dict) -> Any:
1847
        """Modifies an existing auth.
1848
1849
        Arguments:
1850
            group_name: Name of the group to be modified.
1851
            auth_conf_settings: The new auth config.
1852
1853
        Returns:
1854
            The response. See :py:meth:`send_command` for details.
1855
        """
1856
        if not group_name:
1857
            raise RequiredArgument(
1858
                function=self.modify_auth.__name__, argument='group_name'
1859
            )
1860
        if not auth_conf_settings:
1861
            raise RequiredArgument(
1862
                function=self.modify_auth.__name__,
1863
                argument='auth_conf_settings',
1864
            )
1865
        cmd = XmlCommand("modify_auth")
1866
        _xmlgroup = cmd.add_element("group", attrs={"name": str(group_name)})
1867
1868
        for key, value in auth_conf_settings.items():
1869
            _xmlauthconf = _xmlgroup.add_element("auth_conf_setting")
1870
            _xmlauthconf.add_element("key", key)
1871
            _xmlauthconf.add_element("value", value)
1872
1873
        return self._send_xml_command(cmd)
1874
1875 View Code Duplication
    def modify_group(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1876
        self,
1877
        group_id: str,
1878
        *,
1879
        comment: Optional[str] = None,
1880
        name: Optional[str] = None,
1881
        users: Optional[List[str]] = None,
1882
    ) -> Any:
1883
        """Modifies an existing group.
1884
1885
        Arguments:
1886
            group_id: UUID of group to modify.
1887
            comment: Comment on group.
1888
            name: Name of group.
1889
            users: List of user names to be in the group
1890
1891
        Returns:
1892
            The response. See :py:meth:`send_command` for details.
1893
        """
1894
        if not group_id:
1895
            raise RequiredArgument(
1896
                function=self.modify_group.__name__, argument='group_id'
1897
            )
1898
1899
        cmd = XmlCommand("modify_group")
1900
        cmd.set_attribute("group_id", group_id)
1901
1902
        if comment:
1903
            cmd.add_element("comment", comment)
1904
1905
        if name:
1906
            cmd.add_element("name", name)
1907
1908
        if users:
1909
            cmd.add_element("users", to_comma_list(users))
1910
1911
        return self._send_xml_command(cmd)
1912
1913
    def modify_report_format(
1914
        self,
1915
        report_format_id: Optional[Union[str, ReportFormatType]] = None,
1916
        *,
1917
        active: Optional[bool] = None,
1918
        name: Optional[str] = None,
1919
        summary: Optional[str] = None,
1920
        param_name: Optional[str] = None,
1921
        param_value: Optional[str] = None,
1922
    ) -> Any:
1923
        """Modifies an existing report format.
1924
1925
        Arguments:
1926
            report_format_id: UUID of report format to modify
1927
                              or ReportFormatType (enum)
1928
            active: Whether the report format is active.
1929
            name: The name of the report format.
1930
            summary: A summary of the report format.
1931
            param_name: The name of the param.
1932
            param_value: The value of the param.
1933
1934
        Returns:
1935
            The response. See :py:meth:`send_command` for details.
1936
        """
1937
        if not report_format_id:
1938
            raise RequiredArgument(
1939
                function=self.modify_report_format.__name__,
1940
                argument='report_format_id ',
1941
            )
1942
1943
        cmd = XmlCommand("modify_report_format")
1944
1945
        if isinstance(report_format_id, ReportFormatType):
1946
            report_format_id = report_format_id.value
1947
1948
        cmd.set_attribute("report_format_id", report_format_id)
1949
1950
        if active is not None:
1951
            cmd.add_element("active", to_bool(active))
1952
1953
        if name:
1954
            cmd.add_element("name", name)
1955
1956
        if summary:
1957
            cmd.add_element("summary", summary)
1958
1959
        if param_name:
1960
            _xmlparam = cmd.add_element("param")
1961
            _xmlparam.add_element("name", param_name)
1962
1963
            if param_value is not None:
1964
                _xmlparam.add_element("value", param_value)
1965
1966
        return self._send_xml_command(cmd)
1967
1968 View Code Duplication
    def modify_role(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1969
        self,
1970
        role_id: str,
1971
        *,
1972
        comment: Optional[str] = None,
1973
        name: Optional[str] = None,
1974
        users: Optional[List[str]] = None,
1975
    ) -> Any:
1976
        """Modifies an existing role.
1977
1978
        Arguments:
1979
            role_id: UUID of role to modify.
1980
            comment: Name of role.
1981
            name: Comment on role.
1982
            users: List of user names.
1983
1984
        Returns:
1985
            The response. See :py:meth:`send_command` for details.
1986
        """
1987
        if not role_id:
1988
            raise RequiredArgument(
1989
                function=self.modify_role.__name__, argument='role_id argument'
1990
            )
1991
1992
        cmd = XmlCommand("modify_role")
1993
        cmd.set_attribute("role_id", role_id)
1994
1995
        if comment:
1996
            cmd.add_element("comment", comment)
1997
1998
        if name:
1999
            cmd.add_element("name", name)
2000
2001
        if users:
2002
            cmd.add_element("users", to_comma_list(users))
2003
2004
        return self._send_xml_command(cmd)
2005
2006
    def modify_setting(
2007
        self,
2008
        setting_id: Optional[str] = None,
2009
        name: Optional[str] = None,
2010
        value: Optional[str] = None,
2011
    ) -> Any:
2012
        """Modifies an existing setting.
2013
2014
        Arguments:
2015
            setting_id: UUID of the setting to be changed.
2016
            name: The name of the setting. Either setting_id or name must be
2017
                passed.
2018
            value: The value of the setting.
2019
2020
        Returns:
2021
            The response. See :py:meth:`send_command` for details.
2022
        """
2023
        if not setting_id and not name:
2024
            raise RequiredArgument(
2025
                function=self.modify_setting.__name__,
2026
                argument='setting_id or name argument',
2027
            )
2028
2029
        if value is None:
2030
            raise RequiredArgument(
2031
                function=self.modify_setting.__name__, argument='value argument'
2032
            )
2033
2034
        cmd = XmlCommand("modify_setting")
2035
2036
        if setting_id:
2037
            cmd.set_attribute("setting_id", setting_id)
2038
        else:
2039
            cmd.add_element("name", name)
2040
2041
        cmd.add_element("value", to_base64(value))
2042
2043
        return self._send_xml_command(cmd)
2044
2045
    def restore(self, entity_id: str) -> Any:
2046
        """Restore an entity from the trashcan
2047
2048
        Arguments:
2049
            entity_id: ID of the entity to be restored from the trashcan
2050
2051
        Returns:
2052
            The response. See :py:meth:`send_command` for details.
2053
        """
2054
        if not entity_id:
2055
            raise RequiredArgument(
2056
                function=self.restore.__name__, argument='entity_id'
2057
            )
2058
2059
        cmd = XmlCommand("restore")
2060
        cmd.set_attribute("id", entity_id)
2061
2062
        return self._send_xml_command(cmd)
2063
2064
    def sync_cert(self) -> Any:
2065
        """Request a synchronization with the CERT feed service
2066
2067
        Returns:
2068
            The response. See :py:meth:`send_command` for details.
2069
        """
2070
        return self._send_xml_command(XmlCommand("sync_cert"))
2071
2072
    def sync_feed(self) -> Any:
2073
        """Request a synchronization with the NVT feed service
2074
2075
        Returns:
2076
            The response. See :py:meth:`send_command` for details.
2077
        """
2078
        return self._send_xml_command(XmlCommand("sync_feed"))
2079
2080
    def sync_scap(self) -> Any:
2081
        """Request a synchronization with the SCAP feed service
2082
2083
        Returns:
2084
            The response. See :py:meth:`send_command` for details.
2085
        """
2086
        return self._send_xml_command(XmlCommand("sync_scap"))
2087
2088 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...
2089
        self, report_format_id: Union[str, ReportFormatType]
2090
    ) -> Any:
2091
        """Verify an existing report format
2092
2093
        Verifies the trust level of an existing report format. It will be
2094
        checked whether the signature of the report format currently matches the
2095
        report format. This includes the script and files used to generate
2096
        reports of this format. It is *not* verified if the report format works
2097
        as expected by the user.
2098
2099
        Arguments:
2100
            report_format_id: UUID of the report format to be verified
2101
                              or ReportFormatType (enum)
2102
2103
        Returns:
2104
            The response. See :py:meth:`send_command` for details.
2105
        """
2106
        if not report_format_id:
2107
            raise RequiredArgument(
2108
                function=self.verify_report_format.__name__,
2109
                argument='report_format_id',
2110
            )
2111
2112
        cmd = XmlCommand("verify_report_format")
2113
2114
        if isinstance(report_format_id, ReportFormatType):
2115
            report_format_id = report_format_id.value
2116
2117
        cmd.set_attribute("report_format_id", report_format_id)
2118
2119
        return self._send_xml_command(cmd)
2120