Completed
Push — master ( b519bb...486e1a )
by Jaspar
25s queued 15s
created

ScannersMixin.get_scanners()   A

Complexity

Conditions 3

Size

Total Lines 31
Code Lines 14

Duplication

Lines 31
Ratio 100 %

Importance

Changes 0
Metric Value
cc 3
eloc 14
nop 6
dl 31
loc 31
rs 9.7
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 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=redefined-builtin
20
21
from enum import Enum
22
from typing import Any, Optional
23
24
from gvm.errors import InvalidArgument, InvalidArgumentType, RequiredArgument
25
from gvm.utils import add_filter, to_bool
26
from gvm.xml import XmlCommand
27
28
29
class ScannerType(Enum):
30
    """Enum for scanner type"""
31
32
    OSP_SCANNER_TYPE = "1"
33
    OPENVAS_SCANNER_TYPE = "2"
34
    CVE_SCANNER_TYPE = "3"
35
    GMP_SCANNER_TYPE = "4"  # formerly slave scanner
36
    GREENBONE_SENSOR_SCANNER_TYPE = "5"
37
38
39
def get_scanner_type_from_string(
40
    scanner_type: Optional[str],
41
) -> Optional[ScannerType]:
42
    """Convert a scanner type string to an actual ScannerType instance
43
44
    Arguments:
45
        scanner_type: Scanner type string to convert to a ScannerType
46
    """
47
    if not scanner_type:
48
        return None
49
50
    scanner_type = scanner_type.lower()
51
52
    if (
53
        scanner_type == ScannerType.OSP_SCANNER_TYPE.value
54
        or scanner_type == 'osp'
55
    ):
56
        return ScannerType.OSP_SCANNER_TYPE
57
58
    if (
59
        scanner_type == ScannerType.OPENVAS_SCANNER_TYPE.value
60
        or scanner_type == 'openvas'
61
    ):
62
        return ScannerType.OPENVAS_SCANNER_TYPE
63
64
    if (
65
        scanner_type == ScannerType.CVE_SCANNER_TYPE.value
66
        or scanner_type == 'cve'
67
    ):
68
        return ScannerType.CVE_SCANNER_TYPE
69
70
    if (
71
        scanner_type == ScannerType.GMP_SCANNER_TYPE.value
72
        or scanner_type == 'gmp'
73
    ):
74
        return ScannerType.GMP_SCANNER_TYPE
75
76
    if (
77
        scanner_type == ScannerType.GREENBONE_SENSOR_SCANNER_TYPE.value
78
        or scanner_type == 'greenbone'
79
    ):
80
        return ScannerType.GREENBONE_SENSOR_SCANNER_TYPE
81
82
    raise InvalidArgument(
83
        argument='scanner_type', function=get_scanner_type_from_string.__name__
84
    )
85
86
87
class ScannersMixin:
88
    def clone_scanner(self, scanner_id: str) -> Any:
89
        """Clone an existing scanner
90
91
        Arguments:
92
            scanner_id: UUID of an existing scanner to clone from
93
94
        Returns:
95
            The response. See :py:meth:`send_command` for details.
96
        """
97
        if not scanner_id:
98
            raise RequiredArgument(
99
                function=self.clone_scanner.__name__, argument='scanner_id'
100
            )
101
102
        cmd = XmlCommand("create_scanner")
103
        cmd.add_element("copy", scanner_id)
104
        return self._send_xml_command(cmd)
105
106 View Code Duplication
    def create_scanner(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
107
        self,
108
        name: str,
109
        host: str,
110
        port: int,
111
        scanner_type: ScannerType,
112
        credential_id: str,
113
        *,
114
        ca_pub: Optional[str] = None,
115
        comment: Optional[str] = None,
116
    ) -> Any:
117
        """Create a new scanner
118
119
        Arguments:
120
            name: Name of the scanner
121
            host: The host of the scanner
122
            port: The port of the scanner
123
            scanner_type: Type of the scanner.
124
            credential_id: UUID of client certificate credential for the
125
                scanner
126
            ca_pub: Certificate of CA to verify scanner certificate
127
            comment: Comment for the scanner
128
        Returns:
129
            The response. See :py:meth:`send_command` for details.
130
        """
131
        if not name:
132
            raise RequiredArgument(
133
                function=self.create_scanner.__name__, argument='name'
134
            )
135
136
        if not host:
137
            raise RequiredArgument(
138
                function=self.create_scanner.__name__, argument='host'
139
            )
140
141
        if not port:
142
            raise RequiredArgument(
143
                function=self.create_scanner.__name__, argument='port'
144
            )
145
146
        if not scanner_type:
147
            raise RequiredArgument(
148
                function=self.create_scanner.__name__, argument='scanner_type'
149
            )
150
151
        if not credential_id:
152
            raise RequiredArgument(
153
                function=self.create_scanner.__name__, argument='credential_id'
154
            )
155
156
        if not isinstance(scanner_type, ScannerType):
157
            raise InvalidArgumentType(
158
                function=self.create_scanner.__name__,
159
                argument='scanner_type',
160
                arg_type=ScannerType.__name__,
161
            )
162
163
        cmd = XmlCommand("create_scanner")
164
        cmd.add_element("name", name)
165
        cmd.add_element("host", host)
166
        cmd.add_element("port", str(port))
167
        cmd.add_element("type", scanner_type.value)
168
169
        if ca_pub:
170
            cmd.add_element("ca_pub", ca_pub)
171
172
        cmd.add_element("credential", attrs={"id": str(credential_id)})
173
174
        if comment:
175
            cmd.add_element("comment", comment)
176
177
        return self._send_xml_command(cmd)
178
179
    def delete_scanner(
180
        self, scanner_id: str, *, ultimate: Optional[bool] = False
181
    ) -> Any:
182
        """Deletes an existing scanner
183
184
        Arguments:
185
            scanner_id: UUID of the scanner to be deleted.
186
            ultimate: Whether to remove entirely, or to the trashcan.
187
        """
188
        if not scanner_id:
189
            raise RequiredArgument(
190
                function=self.delete_scanner.__name__, argument='scanner_id'
191
            )
192
193
        cmd = XmlCommand("delete_scanner")
194
        cmd.set_attribute("scanner_id", scanner_id)
195
        cmd.set_attribute("ultimate", to_bool(ultimate))
196
197
        return self._send_xml_command(cmd)
198
199 View Code Duplication
    def get_scanners(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
200
        self,
201
        *,
202
        filter: Optional[str] = None,
203
        filter_id: Optional[str] = None,
204
        trash: Optional[bool] = None,
205
        details: Optional[bool] = None,
206
    ) -> Any:
207
        """Request a list of scanners
208
209
        Arguments:
210
            filter: Filter term to use for the query
211
            filter_id: UUID of an existing filter to use for the query
212
            trash: Whether to get the trashcan scanners instead
213
            details:  Whether to include extra details like tasks using this
214
                scanner
215
216
        Returns:
217
            The response. See :py:meth:`send_command` for details.
218
        """
219
        cmd = XmlCommand("get_scanners")
220
221
        add_filter(cmd, filter, filter_id)
222
223
        if trash is not None:
224
            cmd.set_attribute("trash", to_bool(trash))
225
226
        if details is not None:
227
            cmd.set_attribute("details", to_bool(details))
228
229
        return self._send_xml_command(cmd)
230
231
    def get_scanner(self, scanner_id: str) -> Any:
232
        """Request a single scanner
233
234
        Arguments:
235
            scanner_id: UUID of an existing scanner
236
237
        Returns:
238
            The response. See :py:meth:`send_command` for details.
239
        """
240
        cmd = XmlCommand("get_scanners")
241
242
        if not scanner_id:
243
            raise RequiredArgument(
244
                function=self.get_scanner.__name__, argument='scanner_id'
245
            )
246
247
        cmd.set_attribute("scanner_id", scanner_id)
248
249
        # for single entity always request all details
250
        cmd.set_attribute("details", "1")
251
        return self._send_xml_command(cmd)
252
253 View Code Duplication
    def modify_scanner(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
254
        self,
255
        scanner_id: str,
256
        *,
257
        scanner_type: Optional[ScannerType] = None,
258
        host: Optional[str] = None,
259
        port: Optional[int] = None,
260
        comment: Optional[str] = None,
261
        name: Optional[str] = None,
262
        ca_pub: Optional[str] = None,
263
        credential_id: Optional[str] = None,
264
    ) -> Any:
265
        """Modifies an existing scanner.
266
267
        Arguments:
268
            scanner_id: UUID of scanner to modify.
269
            scanner_type: New type of the Scanner.
270
            host: Host of the scanner.
271
            port: Port of the scanner.
272
            comment: Comment on scanner.
273
            name: Name of scanner.
274
            ca_pub: Certificate of CA to verify scanner's certificate.
275
            credential_id: UUID of the client certificate credential for the
276
                Scanner.
277
278
        Returns:
279
            The response. See :py:meth:`send_command` for details.
280
        """
281
        if not scanner_id:
282
            raise RequiredArgument(
283
                function=self.modify_scanner.__name__,
284
                argument='scanner_id argument',
285
            )
286
287
        cmd = XmlCommand("modify_scanner")
288
        cmd.set_attribute("scanner_id", scanner_id)
289
290
        if scanner_type is not None:
291
            if not isinstance(scanner_type, ScannerType):
292
                raise InvalidArgumentType(
293
                    function=self.modify_scanner.__name__,
294
                    argument='scanner_type',
295
                    arg_type=ScannerType.__name__,
296
                )
297
298
            cmd.add_element("type", scanner_type.value)
299
300
        if host:
301
            cmd.add_element("host", host)
302
303
        if port:
304
            cmd.add_element("port", str(port))
305
306
        if comment:
307
            cmd.add_element("comment", comment)
308
309
        if name:
310
            cmd.add_element("name", name)
311
312
        if ca_pub:
313
            cmd.add_element("ca_pub", ca_pub)
314
315
        if credential_id:
316
            cmd.add_element("credential", attrs={"id": str(credential_id)})
317
318
        return self._send_xml_command(cmd)
319
320
    def verify_scanner(self, scanner_id: str) -> Any:
321
        """Verify an existing scanner
322
323
        Verifies if it is possible to connect to an existing scanner. It is
324
        *not* verified if the scanner works as expected by the user.
325
326
        Arguments:
327
            scanner_id: UUID of the scanner to be verified
328
329
        Returns:
330
            The response. See :py:meth:`send_command` for details.
331
        """
332
        if not scanner_id:
333
            raise RequiredArgument(
334
                function=self.verify_scanner.__name__, argument='scanner_id'
335
            )
336
337
        cmd = XmlCommand("verify_scanner")
338
        cmd.set_attribute("scanner_id", scanner_id)
339
340
        return self._send_xml_command(cmd)
341