Total Complexity | 135 |
Total Lines | 1238 |
Duplicated Lines | 20.11 % |
Changes | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like gvm.protocols.gmpv208.gmpv208 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
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.tickets import TicketStatus |
||
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 | PROTOCOL_VERSION = (20, 8) |
||
52 | |||
53 | |||
54 | logger = logging.getLogger(__name__) |
||
55 | |||
56 | |||
57 | class GmpV208Mixin(GvmProtocol): |
||
58 | """Python interface for Greenbone Management Protocol |
||
59 | |||
60 | This class implements the `Greenbone Management Protocol version 20.08`_ |
||
61 | |||
62 | Arguments: |
||
63 | connection: Connection to use to talk with the gvmd daemon. See |
||
64 | :mod:`gvm.connections` for possible connection types. |
||
65 | transform: Optional transform `callable`_ to convert response data. |
||
66 | After each request the callable gets passed the plain response data |
||
67 | which can be used to check the data and/or conversion into different |
||
68 | representations like a xml dom. |
||
69 | |||
70 | See :mod:`gvm.transforms` for existing transforms. |
||
71 | |||
72 | .. _Greenbone Management Protocol version 20.08: |
||
73 | https://docs.greenbone.net/API/GMP/gmp-20.08.html |
||
74 | .. _callable: |
||
75 | https://docs.python.org/3/library/functions.html#callable |
||
76 | """ |
||
77 | |||
78 | def __init__( |
||
79 | self, |
||
80 | connection: GvmConnection, |
||
81 | *, |
||
82 | transform: Optional[Callable[[str], Any]] = None, |
||
83 | ): |
||
84 | super().__init__(connection, transform=transform) |
||
85 | |||
86 | # Is authenticated on gvmd |
||
87 | self._authenticated = False |
||
88 | |||
89 | def is_authenticated(self) -> bool: |
||
90 | """Checks if the user is authenticated |
||
91 | |||
92 | If the user is authenticated privileged GMP commands like get_tasks |
||
93 | may be send to gvmd. |
||
94 | |||
95 | Returns: |
||
96 | bool: True if an authenticated connection to gvmd has been |
||
97 | established. |
||
98 | """ |
||
99 | return self._authenticated |
||
100 | |||
101 | def authenticate(self, username: str, password: str) -> Any: |
||
102 | """Authenticate to gvmd. |
||
103 | |||
104 | The generated authenticate command will be send to server. |
||
105 | Afterwards the response is read, transformed and returned. |
||
106 | |||
107 | Arguments: |
||
108 | username: Username |
||
109 | password: Password |
||
110 | |||
111 | Returns: |
||
112 | Transformed response from server. |
||
113 | """ |
||
114 | cmd = XmlCommand("authenticate") |
||
115 | |||
116 | if not username: |
||
117 | raise RequiredArgument( |
||
118 | function=self.authenticate.__name__, argument='username' |
||
119 | ) |
||
120 | |||
121 | if not password: |
||
122 | raise RequiredArgument( |
||
123 | function=self.authenticate.__name__, argument='password' |
||
124 | ) |
||
125 | |||
126 | credentials = cmd.add_element("credentials") |
||
127 | credentials.add_element("username", username) |
||
128 | credentials.add_element("password", password) |
||
129 | |||
130 | self._send(cmd.to_string()) |
||
131 | response = self._read() |
||
132 | |||
133 | if check_command_status(response): |
||
134 | self._authenticated = True |
||
135 | |||
136 | return self._transform(response) |
||
137 | |||
138 | def clone_ticket(self, ticket_id: str) -> Any: |
||
139 | """Clone an existing ticket |
||
140 | |||
141 | Arguments: |
||
142 | ticket_id: UUID of an existing ticket to clone from |
||
143 | |||
144 | Returns: |
||
145 | The response. See :py:meth:`send_command` for details. |
||
146 | """ |
||
147 | if not ticket_id: |
||
148 | raise RequiredArgument( |
||
149 | function=self.clone_ticket.__name__, argument='ticket_id' |
||
150 | ) |
||
151 | |||
152 | cmd = XmlCommand("create_ticket") |
||
153 | |||
154 | _copy = cmd.add_element("copy", ticket_id) |
||
155 | |||
156 | return self._send_xml_command(cmd) |
||
157 | |||
158 | def create_ticket( |
||
159 | self, |
||
160 | *, |
||
161 | result_id: str, |
||
162 | assigned_to_user_id: str, |
||
163 | note: str, |
||
164 | comment: Optional[str] = None, |
||
165 | ) -> Any: |
||
166 | """Create a new ticket |
||
167 | |||
168 | Arguments: |
||
169 | result_id: UUID of the result the ticket applies to |
||
170 | assigned_to_user_id: UUID of a user the ticket should be assigned to |
||
171 | note: A note about opening the ticket |
||
172 | comment: Comment for the ticket |
||
173 | |||
174 | Returns: |
||
175 | The response. See :py:meth:`send_command` for details. |
||
176 | """ |
||
177 | if not result_id: |
||
178 | raise RequiredArgument( |
||
179 | function=self.create_ticket.__name__, argument='result_id' |
||
180 | ) |
||
181 | |||
182 | if not assigned_to_user_id: |
||
183 | raise RequiredArgument( |
||
184 | function=self.create_ticket.__name__, |
||
185 | argument='assigned_to_user_id', |
||
186 | ) |
||
187 | |||
188 | if not note: |
||
189 | raise RequiredArgument( |
||
190 | function=self.create_ticket.__name__, argument='note' |
||
191 | ) |
||
192 | |||
193 | cmd = XmlCommand("create_ticket") |
||
194 | |||
195 | _result = cmd.add_element("result") |
||
196 | _result.set_attribute("id", result_id) |
||
197 | |||
198 | _assigned = cmd.add_element("assigned_to") |
||
199 | _user = _assigned.add_element("user") |
||
200 | _user.set_attribute("id", assigned_to_user_id) |
||
201 | |||
202 | _note = cmd.add_element("open_note", note) |
||
203 | |||
204 | if comment: |
||
205 | cmd.add_element("comment", comment) |
||
206 | |||
207 | return self._send_xml_command(cmd) |
||
208 | |||
209 | def delete_ticket( |
||
210 | self, ticket_id: str, *, ultimate: Optional[bool] = False |
||
211 | ): |
||
212 | """Deletes an existing ticket |
||
213 | |||
214 | Arguments: |
||
215 | ticket_id: UUID of the ticket to be deleted. |
||
216 | ultimate: Whether to remove entirely, or to the trashcan. |
||
217 | """ |
||
218 | if not ticket_id: |
||
219 | raise RequiredArgument( |
||
220 | function=self.delete_ticket.__name__, argument='ticket_id' |
||
221 | ) |
||
222 | |||
223 | cmd = XmlCommand("delete_ticket") |
||
224 | cmd.set_attribute("ticket_id", ticket_id) |
||
225 | cmd.set_attribute("ultimate", to_bool(ultimate)) |
||
226 | |||
227 | return self._send_xml_command(cmd) |
||
228 | |||
229 | View Code Duplication | def get_tickets( |
|
|
|||
230 | self, |
||
231 | *, |
||
232 | trash: Optional[bool] = None, |
||
233 | filter: Optional[str] = None, |
||
234 | filter_id: Optional[str] = None, |
||
235 | ) -> Any: |
||
236 | """Request a list of tickets |
||
237 | |||
238 | Arguments: |
||
239 | filter: Filter term to use for the query |
||
240 | filter_id: UUID of an existing filter to use for the query |
||
241 | trash: True to request the tickets in the trashcan |
||
242 | |||
243 | Returns: |
||
244 | The response. See :py:meth:`send_command` for details. |
||
245 | """ |
||
246 | cmd = XmlCommand("get_tickets") |
||
247 | |||
248 | add_filter(cmd, filter, filter_id) |
||
249 | |||
250 | if trash is not None: |
||
251 | cmd.set_attribute("trash", to_bool(trash)) |
||
252 | |||
253 | return self._send_xml_command(cmd) |
||
254 | |||
255 | def get_ticket(self, ticket_id: str) -> Any: |
||
256 | """Request a single ticket |
||
257 | |||
258 | Arguments: |
||
259 | ticket_id: UUID of an existing ticket |
||
260 | |||
261 | Returns: |
||
262 | The response. See :py:meth:`send_command` for details. |
||
263 | """ |
||
264 | if not ticket_id: |
||
265 | raise RequiredArgument( |
||
266 | function=self.get_ticket.__name__, argument='ticket_id' |
||
267 | ) |
||
268 | |||
269 | cmd = XmlCommand("get_tickets") |
||
270 | cmd.set_attribute("ticket_id", ticket_id) |
||
271 | return self._send_xml_command(cmd) |
||
272 | |||
273 | def get_vulnerabilities( |
||
274 | self, *, filter: Optional[str] = None, filter_id: Optional[str] = None |
||
275 | ) -> Any: |
||
276 | """Request a list of vulnerabilities |
||
277 | |||
278 | Arguments: |
||
279 | filter: Filter term to use for the query |
||
280 | filter_id: UUID of an existing filter to use for the query |
||
281 | Returns: |
||
282 | The response. See :py:meth:`send_command` for details. |
||
283 | """ |
||
284 | cmd = XmlCommand("get_vulns") |
||
285 | |||
286 | add_filter(cmd, filter, filter_id) |
||
287 | |||
288 | return self._send_xml_command(cmd) |
||
289 | |||
290 | def get_vulnerability(self, vulnerability_id: str) -> Any: |
||
291 | """Request a single vulnerability |
||
292 | |||
293 | Arguments: |
||
294 | vulnerability_id: ID of an existing vulnerability |
||
295 | |||
296 | Returns: |
||
297 | The response. See :py:meth:`send_command` for details. |
||
298 | """ |
||
299 | if not vulnerability_id: |
||
300 | raise RequiredArgument( |
||
301 | function=self.get_vulnerability.__name__, |
||
302 | argument='vulnerability_id', |
||
303 | ) |
||
304 | |||
305 | cmd = XmlCommand("get_vulns") |
||
306 | cmd.set_attribute("vuln_id", vulnerability_id) |
||
307 | return self._send_xml_command(cmd) |
||
308 | |||
309 | def modify_ticket( |
||
310 | self, |
||
311 | ticket_id: str, |
||
312 | *, |
||
313 | status: Optional[TicketStatus] = None, |
||
314 | note: Optional[str] = None, |
||
315 | assigned_to_user_id: Optional[str] = None, |
||
316 | comment: Optional[str] = None, |
||
317 | ) -> Any: |
||
318 | """Modify a single ticket |
||
319 | |||
320 | Arguments: |
||
321 | ticket_id: UUID of an existing ticket |
||
322 | status: New status for the ticket |
||
323 | note: Note for the status change. Required if status is set. |
||
324 | assigned_to_user_id: UUID of the user the ticket should be assigned |
||
325 | to |
||
326 | comment: Comment for the ticket |
||
327 | |||
328 | Returns: |
||
329 | The response. See :py:meth:`send_command` for details. |
||
330 | """ |
||
331 | if not ticket_id: |
||
332 | raise RequiredArgument( |
||
333 | function=self.modify_ticket.__name__, argument='ticket_id' |
||
334 | ) |
||
335 | |||
336 | if status and not note: |
||
337 | raise RequiredArgument( |
||
338 | function=self.modify_ticket.__name__, argument='note' |
||
339 | ) |
||
340 | |||
341 | if note and not status: |
||
342 | raise RequiredArgument( |
||
343 | function=self.modify_ticket.__name__, argument='status' |
||
344 | ) |
||
345 | |||
346 | cmd = XmlCommand("modify_ticket") |
||
347 | cmd.set_attribute("ticket_id", ticket_id) |
||
348 | |||
349 | if assigned_to_user_id: |
||
350 | _assigned = cmd.add_element("assigned_to") |
||
351 | _user = _assigned.add_element("user") |
||
352 | _user.set_attribute("id", assigned_to_user_id) |
||
353 | |||
354 | if status: |
||
355 | if not isinstance(status, TicketStatus): |
||
356 | raise InvalidArgumentType( |
||
357 | function=self.modify_ticket.__name__, |
||
358 | argument='status', |
||
359 | arg_type=TicketStatus.__name__, |
||
360 | ) |
||
361 | |||
362 | cmd.add_element('status', status.value) |
||
363 | cmd.add_element('{}_note'.format(status.name.lower()), note) |
||
364 | |||
365 | if comment: |
||
366 | cmd.add_element("comment", comment) |
||
367 | |||
368 | return self._send_xml_command(cmd) |
||
369 | |||
370 | def create_group( |
||
371 | self, |
||
372 | name: str, |
||
373 | *, |
||
374 | comment: Optional[str] = None, |
||
375 | special: Optional[bool] = False, |
||
376 | users: Optional[List[str]] = None, |
||
377 | ) -> Any: |
||
378 | """Create a new group |
||
379 | |||
380 | Arguments: |
||
381 | name: Name of the new group |
||
382 | comment: Comment for the group |
||
383 | special: Create permission giving members full access to each |
||
384 | other's entities |
||
385 | users: List of user names to be in the group |
||
386 | |||
387 | Returns: |
||
388 | The response. See :py:meth:`send_command` for details. |
||
389 | """ |
||
390 | if not name: |
||
391 | raise RequiredArgument( |
||
392 | function=self.create_group.__name__, argument='name' |
||
393 | ) |
||
394 | |||
395 | cmd = XmlCommand("create_group") |
||
396 | cmd.add_element("name", name) |
||
397 | |||
398 | if comment: |
||
399 | cmd.add_element("comment", comment) |
||
400 | |||
401 | if special: |
||
402 | _xmlspecial = cmd.add_element("specials") |
||
403 | _xmlspecial.add_element("full") |
||
404 | |||
405 | if users: |
||
406 | cmd.add_element("users", to_comma_list(users)) |
||
407 | |||
408 | return self._send_xml_command(cmd) |
||
409 | |||
410 | def clone_group(self, group_id: str) -> Any: |
||
411 | """Clone an existing group |
||
412 | |||
413 | Arguments: |
||
414 | group_id: UUID of an existing group to clone from |
||
415 | |||
416 | Returns: |
||
417 | The response. See :py:meth:`send_command` for details. |
||
418 | """ |
||
419 | if not group_id: |
||
420 | raise RequiredArgument( |
||
421 | function=self.clone_group.__name__, argument='group_id' |
||
422 | ) |
||
423 | |||
424 | cmd = XmlCommand("create_group") |
||
425 | cmd.add_element("copy", group_id) |
||
426 | return self._send_xml_command(cmd) |
||
427 | |||
428 | def clone_report_format( |
||
429 | self, report_format_id: [Union[str, ReportFormatType]] |
||
430 | ) -> Any: |
||
431 | """Clone a report format from an existing one |
||
432 | |||
433 | Arguments: |
||
434 | report_format_id: UUID of the existing report format |
||
435 | or ReportFormatType (enum) |
||
436 | |||
437 | Returns: |
||
438 | The response. See :py:meth:`send_command` for details. |
||
439 | """ |
||
440 | if not report_format_id: |
||
441 | raise RequiredArgument( |
||
442 | function=self.clone_report_format.__name__, |
||
443 | argument='report_format_id', |
||
444 | ) |
||
445 | |||
446 | cmd = XmlCommand("create_report_format") |
||
447 | |||
448 | if isinstance(report_format_id, ReportFormatType): |
||
449 | report_format_id = report_format_id.value |
||
450 | |||
451 | cmd.add_element("copy", report_format_id) |
||
452 | return self._send_xml_command(cmd) |
||
453 | |||
454 | def import_report_format(self, report_format: str) -> Any: |
||
455 | """Import a report format from XML |
||
456 | |||
457 | Arguments: |
||
458 | report_format: Report format XML as string to import. This XML must |
||
459 | contain a :code:`<get_report_formats_response>` root element. |
||
460 | |||
461 | Returns: |
||
462 | The response. See :py:meth:`send_command` for details. |
||
463 | """ |
||
464 | if not report_format: |
||
465 | raise RequiredArgument( |
||
466 | function=self.import_report_format.__name__, |
||
467 | argument='report_format', |
||
468 | ) |
||
469 | |||
470 | cmd = XmlCommand("create_report_format") |
||
471 | |||
472 | try: |
||
473 | cmd.append_xml_str(report_format) |
||
474 | except etree.XMLSyntaxError as e: |
||
475 | raise InvalidArgument( |
||
476 | function=self.import_report_format.__name__, |
||
477 | argument='report_format', |
||
478 | ) from e |
||
479 | |||
480 | return self._send_xml_command(cmd) |
||
481 | |||
482 | def create_role( |
||
483 | self, |
||
484 | name: str, |
||
485 | *, |
||
486 | comment: Optional[str] = None, |
||
487 | users: Optional[List[str]] = None, |
||
488 | ) -> Any: |
||
489 | """Create a new role |
||
490 | |||
491 | Arguments: |
||
492 | name: Name of the role |
||
493 | comment: Comment for the role |
||
494 | users: List of user names to add to the role |
||
495 | |||
496 | Returns: |
||
497 | The response. See :py:meth:`send_command` for details. |
||
498 | """ |
||
499 | |||
500 | if not name: |
||
501 | raise RequiredArgument( |
||
502 | function=self.create_role.__name__, argument='name' |
||
503 | ) |
||
504 | |||
505 | cmd = XmlCommand("create_role") |
||
506 | cmd.add_element("name", name) |
||
507 | |||
508 | if comment: |
||
509 | cmd.add_element("comment", comment) |
||
510 | |||
511 | if users: |
||
512 | cmd.add_element("users", to_comma_list(users)) |
||
513 | |||
514 | return self._send_xml_command(cmd) |
||
515 | |||
516 | def clone_role(self, role_id: str) -> Any: |
||
517 | """Clone an existing role |
||
518 | |||
519 | Arguments: |
||
520 | role_id: UUID of an existing role to clone from |
||
521 | |||
522 | Returns: |
||
523 | The response. See :py:meth:`send_command` for details. |
||
524 | """ |
||
525 | if not role_id: |
||
526 | raise RequiredArgument( |
||
527 | function=self.clone_role.__name__, argument='role_id' |
||
528 | ) |
||
529 | |||
530 | cmd = XmlCommand("create_role") |
||
531 | cmd.add_element("copy", role_id) |
||
532 | return self._send_xml_command(cmd) |
||
533 | |||
534 | def delete_group( |
||
535 | self, group_id: str, *, ultimate: Optional[bool] = False |
||
536 | ) -> Any: |
||
537 | """Deletes an existing group |
||
538 | |||
539 | Arguments: |
||
540 | group_id: UUID of the group to be deleted. |
||
541 | ultimate: Whether to remove entirely, or to the trashcan. |
||
542 | """ |
||
543 | if not group_id: |
||
544 | raise RequiredArgument( |
||
545 | function=self.delete_group.__name__, argument='group_id' |
||
546 | ) |
||
547 | |||
548 | cmd = XmlCommand("delete_group") |
||
549 | cmd.set_attribute("group_id", group_id) |
||
550 | cmd.set_attribute("ultimate", to_bool(ultimate)) |
||
551 | |||
552 | return self._send_xml_command(cmd) |
||
553 | |||
554 | def delete_report_format( |
||
555 | self, |
||
556 | report_format_id: Optional[Union[str, ReportFormatType]] = None, |
||
557 | *, |
||
558 | ultimate: Optional[bool] = False, |
||
559 | ) -> Any: |
||
560 | """Deletes an existing report format |
||
561 | |||
562 | Arguments: |
||
563 | report_format_id: UUID of the report format to be deleted. |
||
564 | or ReportFormatType (enum) |
||
565 | ultimate: Whether to remove entirely, or to the trashcan. |
||
566 | """ |
||
567 | if not report_format_id: |
||
568 | raise RequiredArgument( |
||
569 | function=self.delete_report_format.__name__, |
||
570 | argument='report_format_id', |
||
571 | ) |
||
572 | |||
573 | cmd = XmlCommand("delete_report_format") |
||
574 | |||
575 | if isinstance(report_format_id, ReportFormatType): |
||
576 | report_format_id = report_format_id.value |
||
577 | |||
578 | cmd.set_attribute("report_format_id", report_format_id) |
||
579 | |||
580 | cmd.set_attribute("ultimate", to_bool(ultimate)) |
||
581 | |||
582 | return self._send_xml_command(cmd) |
||
583 | |||
584 | def delete_role( |
||
585 | self, role_id: str, *, ultimate: Optional[bool] = False |
||
586 | ) -> Any: |
||
587 | """Deletes an existing role |
||
588 | |||
589 | Arguments: |
||
590 | role_id: UUID of the role to be deleted. |
||
591 | ultimate: Whether to remove entirely, or to the trashcan. |
||
592 | """ |
||
593 | if not role_id: |
||
594 | raise RequiredArgument( |
||
595 | function=self.delete_role.__name__, argument='role_id' |
||
596 | ) |
||
597 | |||
598 | cmd = XmlCommand("delete_role") |
||
599 | cmd.set_attribute("role_id", role_id) |
||
600 | cmd.set_attribute("ultimate", to_bool(ultimate)) |
||
601 | |||
602 | return self._send_xml_command(cmd) |
||
603 | |||
604 | def describe_auth(self) -> Any: |
||
605 | """Describe authentication methods |
||
606 | |||
607 | Returns a list of all used authentication methods if such a list is |
||
608 | available. |
||
609 | |||
610 | Returns: |
||
611 | The response. See :py:meth:`send_command` for details. |
||
612 | """ |
||
613 | return self._send_xml_command(XmlCommand("describe_auth")) |
||
614 | |||
615 | def empty_trashcan(self) -> Any: |
||
616 | """Empty the trashcan |
||
617 | |||
618 | Remove all entities from the trashcan. **Attention:** this command can |
||
619 | not be reverted |
||
620 | |||
621 | Returns: |
||
622 | The response. See :py:meth:`send_command` for details. |
||
623 | """ |
||
624 | return self._send_xml_command(XmlCommand("empty_trashcan")) |
||
625 | |||
626 | View Code Duplication | def get_groups( |
|
627 | self, |
||
628 | *, |
||
629 | filter: Optional[str] = None, |
||
630 | filter_id: Optional[str] = None, |
||
631 | trash: Optional[bool] = None, |
||
632 | ) -> Any: |
||
633 | """Request a list of groups |
||
634 | |||
635 | Arguments: |
||
636 | filter: Filter term to use for the query |
||
637 | filter_id: UUID of an existing filter to use for the query |
||
638 | trash: Whether to get the trashcan groups instead |
||
639 | |||
640 | Returns: |
||
641 | The response. See :py:meth:`send_command` for details. |
||
642 | """ |
||
643 | cmd = XmlCommand("get_groups") |
||
644 | |||
645 | add_filter(cmd, filter, filter_id) |
||
646 | |||
647 | if trash is not None: |
||
648 | cmd.set_attribute("trash", to_bool(trash)) |
||
649 | |||
650 | return self._send_xml_command(cmd) |
||
651 | |||
652 | def get_group(self, group_id: str) -> Any: |
||
653 | """Request a single group |
||
654 | |||
655 | Arguments: |
||
656 | group_id: UUID of an existing group |
||
657 | |||
658 | Returns: |
||
659 | The response. See :py:meth:`send_command` for details. |
||
660 | """ |
||
661 | cmd = XmlCommand("get_groups") |
||
662 | |||
663 | if not group_id: |
||
664 | raise RequiredArgument( |
||
665 | function=self.get_group.__name__, argument='group_id' |
||
666 | ) |
||
667 | |||
668 | cmd.set_attribute("group_id", group_id) |
||
669 | return self._send_xml_command(cmd) |
||
670 | |||
671 | def get_preferences( |
||
672 | self, *, nvt_oid: Optional[str] = None, config_id: Optional[str] = None |
||
673 | ) -> Any: |
||
674 | """Request a list of preferences |
||
675 | |||
676 | When the command includes a config_id attribute, the preference element |
||
677 | includes the preference name, type and value, and the NVT to which the |
||
678 | preference applies. Otherwise, the preference element includes just the |
||
679 | name and value, with the NVT and type built into the name. |
||
680 | |||
681 | Arguments: |
||
682 | nvt_oid: OID of nvt |
||
683 | config_id: UUID of scan config of which to show preference values |
||
684 | |||
685 | Returns: |
||
686 | The response. See :py:meth:`send_command` for details. |
||
687 | """ |
||
688 | cmd = XmlCommand("get_preferences") |
||
689 | |||
690 | if nvt_oid: |
||
691 | cmd.set_attribute("nvt_oid", nvt_oid) |
||
692 | |||
693 | if config_id: |
||
694 | cmd.set_attribute("config_id", config_id) |
||
695 | |||
696 | return self._send_xml_command(cmd) |
||
697 | |||
698 | def get_preference( |
||
699 | self, |
||
700 | name: str, |
||
701 | *, |
||
702 | nvt_oid: Optional[str] = None, |
||
703 | config_id: Optional[str] = None, |
||
704 | ) -> Any: |
||
705 | """Request a nvt preference |
||
706 | |||
707 | Arguments: |
||
708 | name: name of a particular preference |
||
709 | nvt_oid: OID of nvt |
||
710 | config_id: UUID of scan config of which to show preference values |
||
711 | |||
712 | Returns: |
||
713 | The response. See :py:meth:`send_command` for details. |
||
714 | """ |
||
715 | cmd = XmlCommand("get_preferences") |
||
716 | |||
717 | if not name: |
||
718 | raise RequiredArgument( |
||
719 | function=self.get_preference.__name__, argument='name' |
||
720 | ) |
||
721 | |||
722 | cmd.set_attribute("preference", name) |
||
723 | |||
724 | if nvt_oid: |
||
725 | cmd.set_attribute("nvt_oid", nvt_oid) |
||
726 | |||
727 | if config_id: |
||
728 | cmd.set_attribute("config_id", config_id) |
||
729 | |||
730 | return self._send_xml_command(cmd) |
||
731 | |||
732 | View Code Duplication | def get_report_formats( |
|
733 | self, |
||
734 | *, |
||
735 | filter: Optional[str] = None, |
||
736 | filter_id: Optional[str] = None, |
||
737 | trash: Optional[bool] = None, |
||
738 | alerts: Optional[bool] = None, |
||
739 | params: Optional[bool] = None, |
||
740 | details: Optional[bool] = None, |
||
741 | ) -> Any: |
||
742 | """Request a list of report formats |
||
743 | |||
744 | Arguments: |
||
745 | filter: Filter term to use for the query |
||
746 | filter_id: UUID of an existing filter to use for the query |
||
747 | trash: Whether to get the trashcan report formats instead |
||
748 | alerts: Whether to include alerts that use the report format |
||
749 | params: Whether to include report format parameters |
||
750 | details: Include report format file, signature and parameters |
||
751 | |||
752 | Returns: |
||
753 | The response. See :py:meth:`send_command` for details. |
||
754 | """ |
||
755 | cmd = XmlCommand("get_report_formats") |
||
756 | |||
757 | add_filter(cmd, filter, filter_id) |
||
758 | |||
759 | if details is not None: |
||
760 | cmd.set_attribute("details", to_bool(details)) |
||
761 | |||
762 | if alerts is not None: |
||
763 | cmd.set_attribute("alerts", to_bool(alerts)) |
||
764 | |||
765 | if params is not None: |
||
766 | cmd.set_attribute("params", to_bool(params)) |
||
767 | |||
768 | if trash is not None: |
||
769 | cmd.set_attribute("trash", to_bool(trash)) |
||
770 | |||
771 | return self._send_xml_command(cmd) |
||
772 | |||
773 | View Code Duplication | def get_report_format( |
|
774 | self, report_format_id: Union[str, ReportFormatType] |
||
775 | ) -> Any: |
||
776 | """Request a single report format |
||
777 | |||
778 | Arguments: |
||
779 | report_format_id: UUID of an existing report format |
||
780 | or ReportFormatType (enum) |
||
781 | Returns: |
||
782 | The response. See :py:meth:`send_command` for details. |
||
783 | """ |
||
784 | cmd = XmlCommand("get_report_formats") |
||
785 | if not report_format_id: |
||
786 | raise RequiredArgument( |
||
787 | function=self.get_report_format.__name__, |
||
788 | argument='report_format_id', |
||
789 | ) |
||
790 | |||
791 | if isinstance(report_format_id, ReportFormatType): |
||
792 | report_format_id = report_format_id.value |
||
793 | |||
794 | cmd.set_attribute("report_format_id", report_format_id) |
||
795 | |||
796 | # for single entity always request all details |
||
797 | cmd.set_attribute("details", "1") |
||
798 | return self._send_xml_command(cmd) |
||
799 | |||
800 | View Code Duplication | def get_roles( |
|
801 | self, |
||
802 | *, |
||
803 | filter: Optional[str] = None, |
||
804 | filter_id: Optional[str] = None, |
||
805 | trash: Optional[bool] = None, |
||
806 | ) -> Any: |
||
807 | """Request a list of roles |
||
808 | |||
809 | Arguments: |
||
810 | filter: Filter term to use for the query |
||
811 | filter_id: UUID of an existing filter to use for the query |
||
812 | trash: Whether to get the trashcan roles instead |
||
813 | |||
814 | Returns: |
||
815 | The response. See :py:meth:`send_command` for details. |
||
816 | """ |
||
817 | cmd = XmlCommand("get_roles") |
||
818 | |||
819 | add_filter(cmd, filter, filter_id) |
||
820 | |||
821 | if trash is not None: |
||
822 | cmd.set_attribute("trash", to_bool(trash)) |
||
823 | |||
824 | return self._send_xml_command(cmd) |
||
825 | |||
826 | def get_role(self, role_id: str) -> Any: |
||
827 | """Request a single role |
||
828 | |||
829 | Arguments: |
||
830 | role_id: UUID of an existing role |
||
831 | |||
832 | Returns: |
||
833 | The response. See :py:meth:`send_command` for details. |
||
834 | """ |
||
835 | if not role_id: |
||
836 | raise RequiredArgument( |
||
837 | function=self.get_role.__name__, argument='role_id' |
||
838 | ) |
||
839 | |||
840 | cmd = XmlCommand("get_roles") |
||
841 | cmd.set_attribute("role_id", role_id) |
||
842 | return self._send_xml_command(cmd) |
||
843 | |||
844 | def get_settings(self, *, filter: Optional[str] = None) -> Any: |
||
845 | """Request a list of user settings |
||
846 | |||
847 | Arguments: |
||
848 | filter: Filter term to use for the query |
||
849 | |||
850 | Returns: |
||
851 | The response. See :py:meth:`send_command` for details. |
||
852 | """ |
||
853 | cmd = XmlCommand("get_settings") |
||
854 | |||
855 | if filter: |
||
856 | cmd.set_attribute("filter", filter) |
||
857 | |||
858 | return self._send_xml_command(cmd) |
||
859 | |||
860 | def get_setting(self, setting_id: str) -> Any: |
||
861 | """Request a single setting |
||
862 | |||
863 | Arguments: |
||
864 | setting_id: UUID of an existing setting |
||
865 | |||
866 | Returns: |
||
867 | The response. See :py:meth:`send_command` for details. |
||
868 | """ |
||
869 | cmd = XmlCommand("get_settings") |
||
870 | |||
871 | if not setting_id: |
||
872 | raise RequiredArgument( |
||
873 | function=self.get_setting.__name__, argument='setting_id' |
||
874 | ) |
||
875 | |||
876 | cmd.set_attribute("setting_id", setting_id) |
||
877 | return self._send_xml_command(cmd) |
||
878 | |||
879 | def get_system_reports( |
||
880 | self, |
||
881 | *, |
||
882 | name: Optional[str] = None, |
||
883 | duration: Optional[int] = None, |
||
884 | start_time: Optional[str] = None, |
||
885 | end_time: Optional[str] = None, |
||
886 | brief: Optional[bool] = None, |
||
887 | slave_id: Optional[str] = None, |
||
888 | ) -> Any: |
||
889 | """Request a list of system reports |
||
890 | |||
891 | Arguments: |
||
892 | name: A string describing the required system report |
||
893 | duration: The number of seconds into the past that the system report |
||
894 | should include |
||
895 | start_time: The start of the time interval the system report should |
||
896 | include in ISO time format |
||
897 | end_time: The end of the time interval the system report should |
||
898 | include in ISO time format |
||
899 | brief: Whether to include the actual system reports |
||
900 | slave_id: UUID of GMP scanner from which to get the system reports |
||
901 | |||
902 | Returns: |
||
903 | The response. See :py:meth:`send_command` for details. |
||
904 | """ |
||
905 | cmd = XmlCommand("get_system_reports") |
||
906 | |||
907 | if name: |
||
908 | cmd.set_attribute("name", name) |
||
909 | |||
910 | if duration is not None: |
||
911 | if not isinstance(duration, Integral): |
||
912 | raise InvalidArgument("duration needs to be an integer number") |
||
913 | |||
914 | cmd.set_attribute("duration", str(duration)) |
||
915 | |||
916 | if start_time: |
||
917 | cmd.set_attribute("start_time", str(start_time)) |
||
918 | |||
919 | if end_time: |
||
920 | cmd.set_attribute("end_time", str(end_time)) |
||
921 | |||
922 | if brief is not None: |
||
923 | cmd.set_attribute("brief", to_bool(brief)) |
||
924 | |||
925 | if slave_id: |
||
926 | cmd.set_attribute("slave_id", slave_id) |
||
927 | |||
928 | return self._send_xml_command(cmd) |
||
929 | |||
930 | def get_version(self) -> Any: |
||
931 | """Get the Greenbone Manager Protocol version used by the remote gvmd |
||
932 | Returns: |
||
933 | The response. See :py:meth:`send_command` for details. |
||
934 | """ |
||
935 | return self._send_xml_command(XmlCommand("get_version")) |
||
936 | |||
937 | def help( |
||
938 | self, *, format: Optional[str] = None, help_type: Optional[str] = None |
||
939 | ) -> Any: |
||
940 | """Get the help text |
||
941 | |||
942 | Arguments: |
||
943 | format: One of "html", "rnc", "text" or "xml |
||
944 | help_type: One of "brief" or "". Default "" |
||
945 | |||
946 | Returns: |
||
947 | The response. See :py:meth:`send_command` for details. |
||
948 | """ |
||
949 | cmd = XmlCommand("help") |
||
950 | |||
951 | if not help_type: |
||
952 | help_type = "" |
||
953 | |||
954 | if help_type not in ("", "brief"): |
||
955 | raise InvalidArgument( |
||
956 | 'help_type argument must be an empty string or "brief"' |
||
957 | ) |
||
958 | |||
959 | cmd.set_attribute("type", help_type) |
||
960 | |||
961 | if format: |
||
962 | if not format.lower() in ("html", "rnc", "text", "xml"): |
||
963 | raise InvalidArgument( |
||
964 | "help format Argument must be one of html, rnc, text or " |
||
965 | "xml" |
||
966 | ) |
||
967 | |||
968 | cmd.set_attribute("format", format) |
||
969 | |||
970 | return self._send_xml_command(cmd) |
||
971 | |||
972 | def modify_auth(self, group_name: str, auth_conf_settings: dict) -> Any: |
||
973 | """Modifies an existing auth. |
||
974 | |||
975 | Arguments: |
||
976 | group_name: Name of the group to be modified. |
||
977 | auth_conf_settings: The new auth config. |
||
978 | |||
979 | Returns: |
||
980 | The response. See :py:meth:`send_command` for details. |
||
981 | """ |
||
982 | if not group_name: |
||
983 | raise RequiredArgument( |
||
984 | function=self.modify_auth.__name__, argument='group_name' |
||
985 | ) |
||
986 | if not auth_conf_settings: |
||
987 | raise RequiredArgument( |
||
988 | function=self.modify_auth.__name__, |
||
989 | argument='auth_conf_settings', |
||
990 | ) |
||
991 | cmd = XmlCommand("modify_auth") |
||
992 | _xmlgroup = cmd.add_element("group", attrs={"name": str(group_name)}) |
||
993 | |||
994 | for key, value in auth_conf_settings.items(): |
||
995 | _xmlauthconf = _xmlgroup.add_element("auth_conf_setting") |
||
996 | _xmlauthconf.add_element("key", key) |
||
997 | _xmlauthconf.add_element("value", value) |
||
998 | |||
999 | return self._send_xml_command(cmd) |
||
1000 | |||
1001 | View Code Duplication | def modify_group( |
|
1002 | self, |
||
1003 | group_id: str, |
||
1004 | *, |
||
1005 | comment: Optional[str] = None, |
||
1006 | name: Optional[str] = None, |
||
1007 | users: Optional[List[str]] = None, |
||
1008 | ) -> Any: |
||
1009 | """Modifies an existing group. |
||
1010 | |||
1011 | Arguments: |
||
1012 | group_id: UUID of group to modify. |
||
1013 | comment: Comment on group. |
||
1014 | name: Name of group. |
||
1015 | users: List of user names to be in the group |
||
1016 | |||
1017 | Returns: |
||
1018 | The response. See :py:meth:`send_command` for details. |
||
1019 | """ |
||
1020 | if not group_id: |
||
1021 | raise RequiredArgument( |
||
1022 | function=self.modify_group.__name__, argument='group_id' |
||
1023 | ) |
||
1024 | |||
1025 | cmd = XmlCommand("modify_group") |
||
1026 | cmd.set_attribute("group_id", group_id) |
||
1027 | |||
1028 | if comment: |
||
1029 | cmd.add_element("comment", comment) |
||
1030 | |||
1031 | if name: |
||
1032 | cmd.add_element("name", name) |
||
1033 | |||
1034 | if users: |
||
1035 | cmd.add_element("users", to_comma_list(users)) |
||
1036 | |||
1037 | return self._send_xml_command(cmd) |
||
1038 | |||
1039 | def modify_report_format( |
||
1040 | self, |
||
1041 | report_format_id: Optional[Union[str, ReportFormatType]] = None, |
||
1042 | *, |
||
1043 | active: Optional[bool] = None, |
||
1044 | name: Optional[str] = None, |
||
1045 | summary: Optional[str] = None, |
||
1046 | param_name: Optional[str] = None, |
||
1047 | param_value: Optional[str] = None, |
||
1048 | ) -> Any: |
||
1049 | """Modifies an existing report format. |
||
1050 | |||
1051 | Arguments: |
||
1052 | report_format_id: UUID of report format to modify |
||
1053 | or ReportFormatType (enum) |
||
1054 | active: Whether the report format is active. |
||
1055 | name: The name of the report format. |
||
1056 | summary: A summary of the report format. |
||
1057 | param_name: The name of the param. |
||
1058 | param_value: The value of the param. |
||
1059 | |||
1060 | Returns: |
||
1061 | The response. See :py:meth:`send_command` for details. |
||
1062 | """ |
||
1063 | if not report_format_id: |
||
1064 | raise RequiredArgument( |
||
1065 | function=self.modify_report_format.__name__, |
||
1066 | argument='report_format_id ', |
||
1067 | ) |
||
1068 | |||
1069 | cmd = XmlCommand("modify_report_format") |
||
1070 | |||
1071 | if isinstance(report_format_id, ReportFormatType): |
||
1072 | report_format_id = report_format_id.value |
||
1073 | |||
1074 | cmd.set_attribute("report_format_id", report_format_id) |
||
1075 | |||
1076 | if active is not None: |
||
1077 | cmd.add_element("active", to_bool(active)) |
||
1078 | |||
1079 | if name: |
||
1080 | cmd.add_element("name", name) |
||
1081 | |||
1082 | if summary: |
||
1083 | cmd.add_element("summary", summary) |
||
1084 | |||
1085 | if param_name: |
||
1086 | _xmlparam = cmd.add_element("param") |
||
1087 | _xmlparam.add_element("name", param_name) |
||
1088 | |||
1089 | if param_value is not None: |
||
1090 | _xmlparam.add_element("value", param_value) |
||
1091 | |||
1092 | return self._send_xml_command(cmd) |
||
1093 | |||
1094 | View Code Duplication | def modify_role( |
|
1095 | self, |
||
1096 | role_id: str, |
||
1097 | *, |
||
1098 | comment: Optional[str] = None, |
||
1099 | name: Optional[str] = None, |
||
1100 | users: Optional[List[str]] = None, |
||
1101 | ) -> Any: |
||
1102 | """Modifies an existing role. |
||
1103 | |||
1104 | Arguments: |
||
1105 | role_id: UUID of role to modify. |
||
1106 | comment: Name of role. |
||
1107 | name: Comment on role. |
||
1108 | users: List of user names. |
||
1109 | |||
1110 | Returns: |
||
1111 | The response. See :py:meth:`send_command` for details. |
||
1112 | """ |
||
1113 | if not role_id: |
||
1114 | raise RequiredArgument( |
||
1115 | function=self.modify_role.__name__, argument='role_id argument' |
||
1116 | ) |
||
1117 | |||
1118 | cmd = XmlCommand("modify_role") |
||
1119 | cmd.set_attribute("role_id", role_id) |
||
1120 | |||
1121 | if comment: |
||
1122 | cmd.add_element("comment", comment) |
||
1123 | |||
1124 | if name: |
||
1125 | cmd.add_element("name", name) |
||
1126 | |||
1127 | if users: |
||
1128 | cmd.add_element("users", to_comma_list(users)) |
||
1129 | |||
1130 | return self._send_xml_command(cmd) |
||
1131 | |||
1132 | def modify_setting( |
||
1133 | self, |
||
1134 | setting_id: Optional[str] = None, |
||
1135 | name: Optional[str] = None, |
||
1136 | value: Optional[str] = None, |
||
1137 | ) -> Any: |
||
1138 | """Modifies an existing setting. |
||
1139 | |||
1140 | Arguments: |
||
1141 | setting_id: UUID of the setting to be changed. |
||
1142 | name: The name of the setting. Either setting_id or name must be |
||
1143 | passed. |
||
1144 | value: The value of the setting. |
||
1145 | |||
1146 | Returns: |
||
1147 | The response. See :py:meth:`send_command` for details. |
||
1148 | """ |
||
1149 | if not setting_id and not name: |
||
1150 | raise RequiredArgument( |
||
1151 | function=self.modify_setting.__name__, |
||
1152 | argument='setting_id or name argument', |
||
1153 | ) |
||
1154 | |||
1155 | if value is None: |
||
1156 | raise RequiredArgument( |
||
1157 | function=self.modify_setting.__name__, argument='value argument' |
||
1158 | ) |
||
1159 | |||
1160 | cmd = XmlCommand("modify_setting") |
||
1161 | |||
1162 | if setting_id: |
||
1163 | cmd.set_attribute("setting_id", setting_id) |
||
1164 | else: |
||
1165 | cmd.add_element("name", name) |
||
1166 | |||
1167 | cmd.add_element("value", to_base64(value)) |
||
1168 | |||
1169 | return self._send_xml_command(cmd) |
||
1170 | |||
1171 | def restore(self, entity_id: str) -> Any: |
||
1172 | """Restore an entity from the trashcan |
||
1173 | |||
1174 | Arguments: |
||
1175 | entity_id: ID of the entity to be restored from the trashcan |
||
1176 | |||
1177 | Returns: |
||
1178 | The response. See :py:meth:`send_command` for details. |
||
1179 | """ |
||
1180 | if not entity_id: |
||
1181 | raise RequiredArgument( |
||
1182 | function=self.restore.__name__, argument='entity_id' |
||
1183 | ) |
||
1184 | |||
1185 | cmd = XmlCommand("restore") |
||
1186 | cmd.set_attribute("id", entity_id) |
||
1187 | |||
1188 | return self._send_xml_command(cmd) |
||
1189 | |||
1190 | def sync_cert(self) -> Any: |
||
1191 | """Request a synchronization with the CERT feed service |
||
1192 | |||
1193 | Returns: |
||
1194 | The response. See :py:meth:`send_command` for details. |
||
1195 | """ |
||
1196 | return self._send_xml_command(XmlCommand("sync_cert")) |
||
1197 | |||
1198 | def sync_scap(self) -> Any: |
||
1199 | """Request a synchronization with the SCAP feed service |
||
1200 | |||
1201 | Returns: |
||
1202 | The response. See :py:meth:`send_command` for details. |
||
1203 | """ |
||
1204 | return self._send_xml_command(XmlCommand("sync_scap")) |
||
1205 | |||
1206 | View Code Duplication | def verify_report_format( |
|
1207 | self, report_format_id: Union[str, ReportFormatType] |
||
1208 | ) -> Any: |
||
1209 | """Verify an existing report format |
||
1210 | |||
1211 | Verifies the trust level of an existing report format. It will be |
||
1212 | checked whether the signature of the report format currently matches the |
||
1213 | report format. This includes the script and files used to generate |
||
1214 | reports of this format. It is *not* verified if the report format works |
||
1215 | as expected by the user. |
||
1216 | |||
1217 | Arguments: |
||
1218 | report_format_id: UUID of the report format to be verified |
||
1219 | or ReportFormatType (enum) |
||
1220 | |||
1221 | Returns: |
||
1222 | The response. See :py:meth:`send_command` for details. |
||
1223 | """ |
||
1224 | if not report_format_id: |
||
1225 | raise RequiredArgument( |
||
1226 | function=self.verify_report_format.__name__, |
||
1227 | argument='report_format_id', |
||
1228 | ) |
||
1229 | |||
1230 | cmd = XmlCommand("verify_report_format") |
||
1231 | |||
1232 | if isinstance(report_format_id, ReportFormatType): |
||
1233 | report_format_id = report_format_id.value |
||
1234 | |||
1235 | cmd.set_attribute("report_format_id", report_format_id) |
||
1236 | |||
1237 | return self._send_xml_command(cmd) |
||
1238 |