Passed
Pull Request — master (#297)
by
unknown
01:21
created

send-targets.gmp.alive_test_convert()   C

Complexity

Conditions 10

Size

Total Lines 21
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 20
nop 1
dl 0
loc 21
rs 5.9999
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like send-targets.gmp.alive_test_convert() 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-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
import sys
20
21
from lxml import etree as e
22
23
24
def check_args(args):
25
    len_args = len(args.script) - 1
26
    if len_args !=1:
27
        message = """
28
        This script pulls target data from an xml document and feeds it to \
29
    a desired GSM
30
        One parameter after the script name is required.
31
32
        1. <xml_doc>  -- .xml file containing targets
33
34
        Example:
35
            $ gvm-script --gmp-username name --gmp-password pass \
36
    ssh --hostname <gsm> scripts/send-targets.gmp.py example_file.xml
37
        """
38
        print(message)
39
        quit()
40
41
42
def error_and_exit(msg):
43
    print("Error: {}\n".format(msg), file=sys.stderr)
44
    sys.exit(1)
45
46
47
def yes_or_no(question):
48
    reply = str(input(question + ' (y/n): ')).lower().strip()
49
    if reply[0] == ('y'):
50
        return True
51
    if reply[0] == ('n'):
52
        return False
53
    else:
54
        return yes_or_no("Please enter 'y' or 'n'")
55
56
def alive_test_convert(alive_tests):
57
    if alive_tests == ('ARP Ping'):
58
        return gmp.types.AliveTest.ARP_PING
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable gmp does not seem to be defined.
Loading history...
59
    if alive_tests == ('Consider Alive'):
60
        return gmp.types.AliveTest.CONSIDER_ALIVE
61
    if alive_tests == ('ICMP & ARP Ping'):
62
        return gmp.types.AliveTest.ICMP_AND_ARP_PING
63
    if alive_tests == ('ICMP & TCP-ACK Service Ping'):
64
        return gmp.types.AliveTest.ICMP_AND_TCP_ACK_SERVICE_PING
65
    if alive_tests == ('ICMP Ping'):
66
        return gmp.types.AliveTest.ICMP_PING
67
    if alive_tests == ('ICMP, TCP-ACK Service & ARP Ping'):
68
        return gmp.types.AliveTest.ICMP_TCP_ACK_SERVICE_AND_ARP_PING
69
    if alive_tests == ('TCP-ACK Service & ARP Ping'):
70
        return gmp.types.AliveTest.TCP_ACK_SERVICE_AND_ARP_PING
71
    if alive_tests == ('TCP-ACK Service Ping'):
72
        return gmp.types.AliveTest.TCP_ACK_SERVICE_PING
73
    if alive_tests == ('TCP-SYN Service Ping'):
74
        return gmp.types.AliveTest.TCP_SYN_SERVICE_PING
75
    else:
76
        return gmp.types.AliveTest.SCAN_CONFIG_DEFAULT
77
78 View Code Duplication
def create_xml_tree(xml_doc):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
79
    try:
80
        xml_tree = e.parse(xml_doc)
81
        xml_tree = e.tostring(xml_tree)
82
        xml_tree = e.XML(xml_tree)
83
    except IOError as err:
84
        error_and_exit("Failed to read xml_file: {} (exit)".format(str(err)))
85
86
    if len(xml_tree) == 0:
87
        error_and_exit("XML file is empty (exit)")
88
89
    return xml_tree
90
91
92
def parse_send_xml_tree(gmp, xml_tree):
93
    credential_options = [
94
        'ssh_credential',
95
        'smb_credential',
96
        'esxi_credential',
97
        'snmp_credential',
98
    ]
99
    counter = 1
100
101
    for target in xml_tree.xpath('target'):
102
        keywords = {}  # {'make_unique': True}
103
104
        keywords['name'] = target.find('name').text
105
106
        keywords['hosts'] = target.find('hosts').text.split(',')
107
108
        exclude_hosts = target.find('exclude_hosts').text
109
        if exclude_hosts is not None:
110
            keywords['exclude_hosts'] = exclude_hosts.split(',')
111
112
        comment = target.find('comment').text
113
        if comment is not None:
114
            keywords['comment'] = comment
115
116
        credentials = gmp.get_credentials()[0].xpath("//credential/@id")
117
118
        for credential in credential_options:
119
            cred_id = target.find(credential).xpath('@id')[0]
120
            if cred_id == '':
121
                continue
122
            if cred_id not in credentials:
123
                response = yes_or_no(
124
                    "\nThe credential '{}' for 'target {}' could not be "
125
                    "located...\nWould you like to continue?".format(
126
                        credential, counter
127
                    )
128
                )
129
130
                if response is False:
131
                    print("Terminating...\n")
132
                    quit()
133
                else:
134
                    continue
135
136
            temp_dict = {}
137
            temp_dict['id'] = cred_id
138
            elem_path = target.find(credential)
139
            if elem_path.find('port').text is not None:
140
                temp_dict['port'] = elem_path.find('port').text
141
142
            keywords[credential] = temp_dict
143
144
        alive_test = alive_test_convert(target.find('alive_tests').text)
145
        print(alive_test)
146
147
        if alive_test is not None:
148
            keywords['alive_test'] = alive_test
149
            print(keywords['alive_test'])
150
151
        reverse_lookup_only = target.find('reverse_lookup_only').text
152
        if reverse_lookup_only == '1':
153
            keywords['reverse_lookup_only'] = 1
154
155
        reverse_lookup_unify = target.find('reverse_lookup_unify').text
156
        if reverse_lookup_unify == '1':
157
            keywords['reverse_lookup_unify'] = 1
158
159
        port_range = target.find('port_range')
160
        if port_range is not None:
161
            keywords['port_range'] = port_range.text
162
163
        if target.xpath('port_list/@id') is not None:
164
            port_list = {}
165
            port_list = target.xpath('port_list/@id')[0]
166
            keywords['port_list_id'] = port_list
167
168
        print(keywords)
169
170
        gmp.create_target(**keywords)
171
172
        counter += 1
173
174
175
def main(gmp, args):
176
    # pylint: disable=undefined-variable
177
178
    check_args(args)
179
180
    xml_doc = args.script[1]
181
182
    print('\nSending targets...')
183
184
    xml_tree = create_xml_tree(xml_doc)
185
    parse_send_xml_tree(gmp, xml_tree)
186
187
    print('\n  Target(s) created!\n')
188
189
190
if __name__ == '__gmp__':
191
    main(gmp, args)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable gmp does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable args does not seem to be defined.
Loading history...
192