Passed
Pull Request — master (#143)
by
unknown
02:10
created

gvm.protocols.gmpv7.types   F

Complexity

Total Complexity 86

Size/Duplication

Total Lines 712
Duplicated Lines 16.99 %

Importance

Changes 0
Metric Value
eloc 434
dl 121
loc 712
rs 2
c 0
b 0
f 0
wmc 86

19 Functions

Rating   Name   Duplication   Size   Complexity  
B get_alert_method_from_string() 0 27 7
B get_filter_type_from_string() 26 26 6
A get_info_type_from_string() 0 13 3
A get_snmp_auth_algorithm_from_string() 0 14 3
A get_port_range_type_from_string() 0 17 3
A get_time_unit_from_string() 0 13 3
A get_permission_subject_type_from_string() 0 19 3
A get_snmp_privacy_algorithm_from_string() 0 15 3
A get_alert_condition_from_string() 0 21 5
A get_hosts_ordering_from_string() 0 16 3
C get_scanner_type_from_string() 0 39 10
A get_entity_type_from_string() 22 22 5
A get_alert_event_from_string() 0 20 5
A get_credential_type_from_string() 14 14 3
A get_asset_type_from_string() 0 14 4
A get_feed_type_from_string() 0 11 3
C get_alive_test_from_string() 0 38 11
A get_credential_format_from_string() 0 12 3
A get_severity_level_from_string() 0 13 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

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:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like gvm.protocols.gmpv7.types 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) 2019 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
21
from typing import Optional
22
23
from gvm.errors import InvalidArgument
24
25
__all__ = [
26
    "AlertCondition",
27
    "AlertEvent",
28
    "AlertMethod",
29
    "AliveTest",
30
    "AssetType",
31
    "CredentialType",
32
    "CredentialFormat",
33
    "EntityType",
34
    "FeedType",
35
    "FilterType",
36
    "HostsOrdering",
37
    "InfoType",
38
    "PermissionSubjectType",
39
    "PortRangeType",
40
    "ScannerType",
41
    "SeverityLevel",
42
    "SnmpAuthAlgorithm",
43
    "SnmpPrivacyAlgorithm",
44
    "TimeUnit",
45
    "get_alive_test_from_string",
46
    "get_alert_condition_from_string",
47
    "get_alert_event_from_string",
48
    "get_alert_method_from_string",
49
    "get_asset_type_from_string",
50
    "get_credential_format_from_string",
51
    "get_credential_type_from_string",
52
    "get_entity_type_from_string",
53
    "get_feed_type_from_string",
54
    "get_filter_type_from_string",
55
    "get_hosts_ordering_from_string",
56
    "get_info_type_from_string",
57
    "get_permission_subject_type_from_string",
58
    "get_port_range_type_from_string",
59
    "get_scanner_type_from_string",
60
    "get_severity_level_from_string",
61
    "get_snmp_auth_algorithm_from_string",
62
    "get_snmp_privacy_algorithm_from_string",
63
    "get_time_unit_from_string",
64
]
65
66
67
class AlertEvent(Enum):
68
    """ Enum for alert event types """
69
70
    TASK_RUN_STATUS_CHANGED = 'Task run status changed'
71
    UPDATED_SECINFO_ARRIVED = 'Updated SecInfo arrived'
72
    NEW_SECINFO_ARRIVED = 'New SecInfo arrived'
73
74
75
def get_alert_event_from_string(
76
    alert_event: Optional[str]
77
) -> Optional[AlertEvent]:
78
    """ Convert an alert event string into a AlertEvent instance """
79
    if not alert_event:
80
        return None
81
82
    alert_event = alert_event.lower()
83
84
    if alert_event == 'task run status changed':
85
        return AlertEvent.TASK_RUN_STATUS_CHANGED
86
87
    if alert_event == 'updated secinfo arrived':
88
        return AlertEvent.UPDATED_SECINFO_ARRIVED
89
90
    if alert_event == 'new secinfo arrived':
91
        return AlertEvent.NEW_SECINFO_ARRIVED
92
93
    raise InvalidArgument(
94
        argument='alert_event', function=get_alert_event_from_string.__name__
95
    )
96
97
98
class AlertCondition(Enum):
99
    """ Enum for alert condition types """
100
101
    ALWAYS = 'Always'
102
    SEVERITY_AT_LEAST = 'Severity at least'
103
    FILTER_COUNT_CHANGED = 'Filter count changed'
104
    FILTER_COUNT_AT_LEAST = 'Filter count at least'
105
106
107
def get_alert_condition_from_string(
108
    alert_condition: Optional[str]
109
) -> Optional[AlertCondition]:
110
    """ Convert an alert condition string into a AlertCondition instance """
111
    if not alert_condition:
112
        return None
113
114
    alert_condition = alert_condition.lower()
115
116
    if alert_condition == 'always':
117
        return AlertCondition.ALWAYS
118
119
    if alert_condition == 'filter count changed':
120
        return AlertCondition.FILTER_COUNT_CHANGED
121
122
    if alert_condition == 'filter count at least':
123
        return AlertCondition.FILTER_COUNT_AT_LEAST
124
125
    raise InvalidArgument(
126
        argument='alert_condition',
127
        function=get_alert_condition_from_string.__name__,
128
    )
129
130
131
class AlertMethod(Enum):
132
    """ Enum for alert method type"""
133
134
    SCP = "SCP"
135
    SEND = "Send"
136
    SMB = "SMB"
137
    SNMP = "SNMP"
138
    SYSLOG = "Syslog"
139
    EMAIL = "Email"
140
    START_TASK = "Start Task"
141
    HTTP_GET = "HTTP Get"
142
    SOURCEFIRE_CONNECTOR = "Sourcefire Connector"
143
    VERINICE_CONNECTOR = "verinice Connector"
144
145
146
def get_alert_method_from_string(
147
    alert_method: Optional[str]
148
) -> Optional[AlertMethod]:
149
    """ Convert an alert method string into a AlertCondition instance """
150
    if not alert_method:
151
        return None
152
153
    alert_method = alert_method.upper()
154
155
    if alert_method == 'START TASK':
156
        return AlertMethod.START_TASK
157
158
    if alert_method == 'HTTP GET':
159
        return AlertMethod.HTTP_GET
160
161
    if alert_method == 'SOURCEFIRE CONNECTOR':
162
        return AlertMethod.SOURCEFIRE_CONNECTOR
163
164
    if alert_method == 'VERINICE CONNECTOR':
165
        return AlertMethod.VERINICE_CONNECTOR
166
167
    try:
168
        return AlertMethod[alert_method]
169
    except KeyError:
170
        raise InvalidArgument(
171
            argument='alert_method',
172
            function=get_alert_method_from_string.__name__,
173
        )
174
175
176
class AliveTest(Enum):
177
    """ Enum for choosing an alive test """
178
179
    ICMP_PING = 'ICMP Ping'
180
    TCP_ACK_SERVICE_PING = 'TCP-ACK Service Ping'
181
    TCP_SYN_SERVICE_PING = 'TCP-SYN Service Ping'
182
    APR_PING = 'ARP Ping'
183
    ICMP_AND_TCP_ACK_SERVICE_PING = 'ICMP & TCP-ACK Service Ping'
184
    ICMP_AND_ARP_PING = 'ICMP & ARP Ping'
185
    TCP_ACK_SERVICE_AND_ARP_PING = 'TCP-ACK Service & ARP Ping'
186
    ICMP_TCP_ACK_SERVICE_AND_ARP_PING = (  # pylint: disable=invalid-name
187
        'ICMP, TCP-ACK Service & ARP Ping'
188
    )
189
    CONSIDER_ALIVE = 'Consider Alive'
190
191
192
def get_alive_test_from_string(
0 ignored issues
show
best-practice introduced by
Too many return statements (10/6)
Loading history...
193
    alive_test: Optional[str]
194
) -> Optional[AliveTest]:
195
    """ Convert an alive test string into a AliveTest instance """
196
    if not alive_test:
197
        return None
198
199
    alive_test = alive_test.lower()
200
201
    if alive_test == 'icmp ping':
202
        return AliveTest.ICMP_PING
203
204
    if alive_test == 'tcp-ack service ping':
205
        return AliveTest.TCP_ACK_SERVICE_PING
206
207
    if alive_test == 'tcp-syn service ping':
208
        return AliveTest.TCP_SYN_SERVICE_PING
209
210
    if alive_test == 'arp ping':
211
        return AliveTest.APR_PING
212
213
    if alive_test == 'icmp & tcp-ack service ping':
214
        return AliveTest.ICMP_AND_TCP_ACK_SERVICE_PING
215
216
    if alive_test == 'icmp & arp ping':
217
        return AliveTest.ICMP_AND_ARP_PING
218
219
    if alive_test == 'tcp-ack service & arp ping':
220
        return AliveTest.TCP_ACK_SERVICE_AND_ARP_PING
221
222
    if alive_test == 'icmp, tcp-ack service & arp ping':
223
        return AliveTest.ICMP_TCP_ACK_SERVICE_AND_ARP_PING
224
225
    if alive_test == 'consider alive':
226
        return AliveTest.CONSIDER_ALIVE
227
228
    raise InvalidArgument(
229
        argument='alive_test', function=get_alive_test_from_string.__name__
230
    )
231
232
233
class AssetType(Enum):
234
    """" Enum for asset types """
235
236
    OPERATING_SYSTEM = 'os'
237
    HOST = 'host'
238
239
240
def get_asset_type_from_string(
241
    asset_type: Optional[str]
242
) -> Optional[AssetType]:
243
    if not asset_type:
244
        return None
245
246
    if asset_type == 'os':
247
        return AssetType.OPERATING_SYSTEM
248
249
    try:
250
        return AssetType[asset_type.upper()]
251
    except KeyError:
252
        raise InvalidArgument(
253
            argument='asset_type', function=get_asset_type_from_string.__name__
254
        )
255
256
257
class CredentialFormat(Enum):
258
    """ Enum for credential format """
259
260
    KEY = 'key'
261
    RPM = 'rpm'
262
    DEB = 'deb'
263
    EXE = 'exe'
264
    PEM = 'pem'
265
266
267
def get_credential_format_from_string(
268
    credential_format: Optional[str]
269
) -> Optional[CredentialFormat]:
270
    if not credential_format:
271
        return None
272
273
    try:
274
        return CredentialFormat[credential_format.upper()]
275
    except KeyError:
276
        raise InvalidArgument(
277
            argument='credential_format',
278
            function=get_credential_format_from_string.__name__,
279
        )
280
281
282
class CredentialType(Enum):
283
    """ Enum for credential types """
284
285
    CLIENT_CERTIFICATE = 'cc'
286
    SNMP = 'snmp'
287
    USERNAME_PASSWORD = 'up'
288
    USERNAME_SSH_KEY = 'usk'
289
290
291 View Code Duplication
def get_credential_type_from_string(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
292
    credential_type: Optional[str]
293
) -> Optional[CredentialType]:
294
    """ Convert a credential type string into a CredentialType instance
295
    """
296
    if not credential_type:
297
        return None
298
299
    try:
300
        return CredentialType[credential_type.upper()]
301
    except KeyError:
302
        raise InvalidArgument(
303
            argument='credential_type',
304
            function=get_credential_type_from_string.__name__,
305
        )
306
307
308 View Code Duplication
class EntityType(Enum):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
309
    """ Enum for entity types """
310
311
    AGENT = "note"
312
    ALERT = "alert"
313
    ASSET = "asset"
314
    CERT_BUND_ADV = "cert_bund_adv"
315
    CPE = "cpe"
316
    CREDENTIAL = "credential"
317
    CVE = "cve"
318
    DFN_CERT_ADV = "dfn_cert_adv"
319
    FILTER = "filter"
320
    GROUP = "group"
321
    HOST = "host"
322
    INFO = "info"
323
    NOTE = "note"
324
    NVT = "nvt"
325
    OPERATING_SYSTEM = "os"
326
    OVALDEF = "ovaldef"
327
    OVERRIDE = "override"
328
    PERMISSION = "permission"
329
    PORT_LIST = "port_list"
330
    REPORT = "report"
331
    REPORT_FORMAT = "report_format"
332
    RESULT = "result"
333
    ROLE = "role"
334
    SCAN_CONFIG = "config"
335
    SCANNER = "scanner"
336
    SCHEDULE = "schedule"
337
    TAG = "tag"
338
    TARGET = "target"
339
    TASK = "task"
340
    USER = "user"
341
342
343 View Code Duplication
def get_entity_type_from_string(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
344
    entity_type: Optional[str]
345
) -> Optional[EntityType]:
346
    """ Convert a entity type string to an actual EntityType instance
347
348
    Arguments:
349
        entity_type: Resource type string to convert to a EntityType
350
    """
351
    if not entity_type:
352
        return None
353
354
    if entity_type == 'config':
355
        return EntityType.SCAN_CONFIG
356
    if entity_type == 'os':
357
        return EntityType.OPERATING_SYSTEM
358
359
    try:
360
        return EntityType[entity_type.upper()]
361
    except KeyError:
362
        raise InvalidArgument(
363
            argument='entity_type',
364
            function=get_entity_type_from_string.__name__,
365
        )
366
367
368
class FeedType(Enum):
369
    """ Enum for feed types """
370
371
    NVT = "NVT"
372
    CERT = "CERT"
373
    SCAP = "SCAP"
374
375
376
def get_feed_type_from_string(feed_type: Optional[str]) -> Optional[FeedType]:
377
    """ Convert a feed type string into a FeedType instance
378
    """
379
    if not feed_type:
380
        return None
381
382
    try:
383
        return FeedType[feed_type.upper()]
384
    except KeyError:
385
        raise InvalidArgument(
386
            argument='feed_type', function=get_feed_type_from_string.__name__
387
        )
388
389
390 View Code Duplication
class FilterType(Enum):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
391
    """ Enum for filter types """
392
393
    AGENT = "agent"
394
    ALERT = "alert"
395
    ASSET = "asset"
396
    SCAN_CONFIG = "config"
397
    CREDENTIAL = "credential"
398
    FILTER = "filter"
399
    GROUP = "group"
400
    HOST = "host"
401
    NOTE = "note"
402
    OPERATING_SYSTEM = "os"
403
    OVERRIDE = "override"
404
    PERMISSION = "permission"
405
    PORT_LIST = "port_list"
406
    REPORT = "report"
407
    REPORT_FORMAT = "report_format"
408
    RESULT = "result"
409
    ROLE = "role"
410
    SCHEDULE = "schedule"
411
    ALL_SECINFO = "secinfo"
412
    TAG = "tag"
413
    TARGET = "target"
414
    TASK = "task"
415
    USER = "user"
416
417
418 View Code Duplication
def get_filter_type_from_string(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
419
    filter_type: Optional[str]
420
) -> Optional[FilterType]:
421
    """ Convert a filter type string to an actual FilterType instance
422
423
    Arguments:
424
        filter_type: Filter type string to convert to a FilterType
425
    """
426
    if not filter_type:
427
        return None
428
429
    if filter_type == 'os':
430
        return FilterType.OPERATING_SYSTEM
431
432
    if filter_type == 'config':
433
        return FilterType.SCAN_CONFIG
434
435
    if filter_type == 'secinfo':
436
        return FilterType.ALL_SECINFO
437
438
    try:
439
        return FilterType[filter_type.upper()]
440
    except KeyError:
441
        raise InvalidArgument(
442
            argument='filter_type',
443
            function=get_filter_type_from_string.__name__,
444
        )
445
446
447
class HostsOrdering(Enum):
448
    """ Enum for host ordering during scans """
449
450
    SEQUENTIAL = "sequential"
451
    RANDOM = "random"
452
    REVERSE = "reverse"
453
454
455
def get_hosts_ordering_from_string(
456
    hosts_ordering: Optional[str]
457
) -> Optional[HostsOrdering]:
458
    """ Convert a hosts ordering string to an actual HostsOrdering instance
459
460
    Arguments:
461
        hosts_ordering: Host ordering string to convert to a HostsOrdering
462
    """
463
    if not hosts_ordering:
464
        return None
465
    try:
466
        return HostsOrdering[hosts_ordering.upper()]
467
    except KeyError:
468
        raise InvalidArgument(
469
            argument='hosts_ordering',
470
            function=get_hosts_ordering_from_string.__name__,
471
        )
472
473
474
class InfoType(Enum):
475
    """ Enum for info types """
476
477
    CERT_BUND_ADV = "CERT_BUND_ADV"
478
    CPE = "CPE"
479
    CVE = "CVE"
480
    DFN_CERT_ADV = "DFN_CERT_ADV"
481
    OVALDEF = "OVALDEF"
482
    NVT = "NVT"
483
    ALLINFO = "ALLINFO"
484
485
486
def get_info_type_from_string(info_type: Optional[str]) -> Optional[InfoType]:
487
    """ Convert a info type string to an actual InfoType instance
488
489
    Arguments:
490
        info_type: Info type string to convert to a InfoType
491
    """
492
    if not info_type:
493
        return None
494
    try:
495
        return InfoType[info_type.upper()]
496
    except KeyError:
497
        raise InvalidArgument(
498
            argument='info_type', function=get_info_type_from_string.__name__
499
        )
500
501
502
class PermissionSubjectType(Enum):
503
    """ Enum for permission subject type """
504
505
    USER = 'user'
506
    GROUP = 'group'
507
    ROLE = 'role'
508
509
510
def get_permission_subject_type_from_string(
511
    subject_type: Optional[str]
512
) -> Optional[PermissionSubjectType]:
513
    """ Convert a permission subject type string to an actual
514
    PermissionSubjectType instance
515
516
    Arguments:
517
        subject_type: Permission subject type string to convert to a
518
            PermissionSubjectType
519
    """
520
    if not subject_type:
521
        return None
522
523
    try:
524
        return PermissionSubjectType[subject_type.upper()]
525
    except KeyError:
526
        raise InvalidArgument(
527
            argument='subject_type',
528
            function=get_permission_subject_type_from_string.__name__,
529
        )
530
531
532
class PortRangeType(Enum):
533
    """ Enum for port range type """
534
535
    TCP = 'TCP'
536
    UDP = 'UDP'
537
538
539
def get_port_range_type_from_string(
540
    port_range_type: Optional[str]
541
) -> Optional[PortRangeType]:
542
    """ Convert a port range type string to an actual PortRangeType instance
543
544
    Arguments:
545
        port_range_type: Port range type string to convert to a PortRangeType
546
    """
547
    if not port_range_type:
548
        return None
549
550
    try:
551
        return PortRangeType[port_range_type.upper()]
552
    except KeyError:
553
        raise InvalidArgument(
554
            argument='port_range_type',
555
            function=get_port_range_type_from_string.__name__,
556
        )
557
558
559
class ScannerType(Enum):
560
    """ Enum for scanner type """
561
562
    OSP_SCANNER_TYPE = "1"
563
    OPENVAS_SCANNER_TYPE = "2"
564
    CVE_SCANNER_TYPE = "3"
565
    GMP_SCANNER_TYPE = "4"  # formerly slave scanner
566
567
568
def get_scanner_type_from_string(
569
    scanner_type: Optional[str]
570
) -> Optional[ScannerType]:
571
    """ Convert a scanner type string to an actual ScannerType instance
572
573
    Arguments:
574
        scanner_type: Scanner type string to convert to a ScannerType
575
    """
576
    if not scanner_type:
577
        return None
578
579
    scanner_type = scanner_type.lower()
580
581
    if (
582
        scanner_type == ScannerType.OSP_SCANNER_TYPE.value
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "scanner_type in (ScannerType.OSP_SCANNER_TYPE.value, 'osp')"
Loading history...
583
        or scanner_type == 'osp'
584
    ):
585
        return ScannerType.OSP_SCANNER_TYPE
586
587
    if (
588
        scanner_type == ScannerType.OPENVAS_SCANNER_TYPE.value
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "scanner_type in (ScannerType.OPENVAS_SCANNER_TYPE.value, 'openvas')"
Loading history...
589
        or scanner_type == 'openvas'
590
    ):
591
        return ScannerType.OPENVAS_SCANNER_TYPE
592
593
    if (
594
        scanner_type == ScannerType.CVE_SCANNER_TYPE.value
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "scanner_type in (ScannerType.CVE_SCANNER_TYPE.value, 'cve')"
Loading history...
595
        or scanner_type == 'cve'
596
    ):
597
        return ScannerType.CVE_SCANNER_TYPE
598
599
    if (
600
        scanner_type == ScannerType.GMP_SCANNER_TYPE.value
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "scanner_type in (ScannerType.GMP_SCANNER_TYPE.value, 'gmp')"
Loading history...
601
        or scanner_type == 'gmp'
602
    ):
603
        return ScannerType.GMP_SCANNER_TYPE
604
605
    raise InvalidArgument(
606
        argument='scanner_type', function=get_scanner_type_from_string.__name__
607
    )
608
609
610
class SnmpAuthAlgorithm(Enum):
611
    """ Enum for SNMP auth algorithm """
612
613
    SHA1 = 'sha1'
614
    MD5 = 'md5'
615
616
617
def get_snmp_auth_algorithm_from_string(
618
    algorithm: Optional[str]
619
) -> Optional[SnmpAuthAlgorithm]:
620
    """ Convert a SNMP auth algorithm string into a SnmpAuthAlgorithm instance
621
    """
622
    if not algorithm:
623
        return None
624
625
    try:
626
        return SnmpAuthAlgorithm[algorithm.upper()]
627
    except KeyError:
628
        raise InvalidArgument(
629
            argument='algorithm',
630
            function=get_snmp_auth_algorithm_from_string.__name__,
631
        )
632
633
634
class SnmpPrivacyAlgorithm(Enum):
635
    """ Enum for SNMP privacy algorithm """
636
637
    AES = 'aes'
638
    DES = 'des'
639
640
641
def get_snmp_privacy_algorithm_from_string(
642
    algorithm: Optional[str]
643
) -> Optional[SnmpPrivacyAlgorithm]:
644
    """ Convert a SNMP privacy algorithm string into a SnmpPrivacyAlgorithm
645
        instance
646
    """
647
    if not algorithm:
648
        return None
649
650
    try:
651
        return SnmpPrivacyAlgorithm[algorithm.upper()]
652
    except KeyError:
653
        raise InvalidArgument(
654
            argument='algorithm',
655
            function=get_snmp_privacy_algorithm_from_string.__name__,
656
        )
657
658
659
class SeverityLevel(Enum):
660
    """ Enum for severity levels """
661
662
    HIGH = "High"
663
    MEDIUM = "Medium"
664
    LOW = "Low"
665
    LOG = "Log"
666
    ALARM = "Alarm"
667
    DEBUG = "Debug"
668
669
670
def get_severity_level_from_string(
671
    severity_level: Optional[str]
672
) -> Optional[SeverityLevel]:
673
    """ Convert a severity level string into a SeverityLevel instance """
674
    if not severity_level:
675
        return None
676
677
    try:
678
        return SeverityLevel[severity_level.upper()]
679
    except KeyError:
680
        raise InvalidArgument(
681
            argument='severity_level',
682
            function=get_severity_level_from_string.__name__,
683
        )
684
685
686
class TimeUnit(Enum):
687
    """ Enum for time units """
688
689
    SECOND = "second"
690
    MINUTE = "minute"
691
    HOUR = "hour"
692
    DAY = "day"
693
    WEEK = "week"
694
    MONTH = "month"
695
    YEAR = "year"
696
    DECADE = "decade"
697
698
699
def get_time_unit_from_string(
700
    time_unit: Optional[str]
701
) -> Optional[SeverityLevel]:
702
    """ Convert a time unit string into a TimeUnit instance """
703
    if not time_unit:
704
        return None
705
706
    try:
707
        return TimeUnit[time_unit.upper()]
708
    except KeyError:
709
        raise InvalidArgument(
710
            argument='severity_level',
711
            function=get_severity_level_from_string.__name__,
712
        )
713