ScannersMixin.create_scanner()   C
last analyzed

Complexity

Conditions 9

Size

Total Lines 72
Code Lines 41

Duplication

Lines 72
Ratio 100 %

Importance

Changes 0
Metric Value
cc 9
eloc 41
nop 9
dl 72
loc 72
rs 6.5626
c 0
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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