Completed
Push — master ( f07019...0c998d )
by
unknown
18s queued 13s
created

send-tasks.gmp.create_xml_tree()   A

Complexity

Conditions 3

Size

Total Lines 12
Code Lines 10

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nop 1
dl 12
loc 12
rs 9.9
c 0
b 0
f 0
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
from lxml import etree as e
21
22
23
def check_args(args):
24
    len_args = len(args.script) - 1
25
    if len_args is not 1:
26
        message = """
27
        This script pulls tasks data from an xml document and feeds it to \
28
    a desired GSM
29
        One parameter after the script name is required.
30
31
        1. <xml_doc>  -- .xml file containing tasks
32
33
        Example:
34
            $ gvm-script --gmp-username name --gmp-password pass \
35
    ssh --hostname <gsm> scripts/send-tasks.gmp.py example_file.xml
36
        """
37
38
        print(message)
39
        quit()
40
41
42
def error_and_exit(msg):
43
    print("\nError: {}\n".format(msg), file=sys.stderr)
44
    sys.exit(1)
45
46
47
def inquire_yes_no(inquiry):
48
    reply = str(input(inquiry + ' [Y/n]: ')).lower().strip()
49
    if reply == 'y':
50
        answer = True
51
    elif reply == 'n':
52
        answer = False
53
    else:
54
        answer = inquire_yes_no("Please enter valid option dummy!")
55
56
    return answer
57
58
59
def numerical_option(statement, list_range):
60
    choice = int(input(statement))
61
62
    if choice in range(1, list_range + 1):
63
        return choice
64
    else:
65
        return numerical_option(
66
            "Please enter valid number from {} to {}...".format(1, list_range),
67
            list_range,
68
        )
69
70
71 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...
72
    try:
73
        xml_tree = e.parse(xml_doc)
74
        xml_tree = e.tostring(xml_tree)
75
        xml_tree = e.XML(xml_tree)
76
    except IOError as err:
77
        error_and_exit("Failed to read xml_file: {} (exit)".format(str(err)))
78
79
    if len(xml_tree) == 0:
80
        error_and_exit("XML file is empty (exit)")
81
82
    return xml_tree
83
84
85
def interactive_options(task, keywords):
86
    options_dict = {}
87
    options_dict['config'] = gmp.get_configs()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable gmp does not seem to be defined.
Loading history...
88
    options_dict['scanner'] = gmp.get_scanners()
89
    options_dict['target'] = gmp.get_targets()
90
91
    for option in options_dict:
92
        object_dict, object_list = {}, []
93
        object_id = task.xpath('{}/@id'.format(option))[0]
94
        object_xml = options_dict[option]
95
96
        for i in object_xml.xpath('{}'.format(option)):
97
            object_dict[i.find('name').text] = i.xpath('@id')[0]
98
            object_list.append(i.find('name').text)
99
100
        if object_id in object_dict.values():
101
            keywords['{}_id'.format(option)] = object_id
102
        elif object_id not in object_dict.values() and len(object_dict) != 0:
103
            response = inquire_yes_no(
104
                "\nRequired Field: failed to detect {}_id: {}... "
105
                "\nWould you like to select from available options, or exit "
106
                "the script?".format(
107
                    option, task.xpath('{}/@id'.format(option))[0]
108
                )
109
            )
110
111
            if response is True:
112
                counter = 1
113
                print("{} options:".format(option.capitalize()))
114
                for j in object_list:
115
                    print("    {} - {}".format(counter, j))
116
                    counter += 1
117
                answer = numerical_option(
118
                    "\nPlease enter the number of your choice.",
119
                    len(object_list),
120
                )
121
                keywords['{}_id'.format(option)] = object_dict[
122
                    object_list[answer - 1]
123
                ]
124
            else:
125
                print("\nTerminating...")
126
                quit()
127
        else:
128
            error_and_exit(
129
                "Failed to detect {}_id"
130
                "\nThis field is required therefore the script is unable to "
131
                "continue.\n".format(option)
132
            )
133
134
135
def parse_send_xml_tree(gmp, xml_tree):
136
    for task in xml_tree.xpath('task'):
137
        keywords = {'name': task.find('name').text}
138
139
        if task.find('comment').text is not None:
140
            keywords['comment'] = task.find('comment').text
141
142
        interactive_options(task, keywords)
143
144
        new_task = gmp.create_task(**keywords)
145
146
        mod_keywords = {'task_id': new_task.xpath('//@id')[0]}
147
148
        if task.find('schedule_periods') is not None:
149
            mod_keywords['schedule_periods'] = int(
150
                task.find('schedule_periods').text
151
            )
152
153
        if task.find('observers').text:
154
            mod_keywords['observers'] = task.find('observers').text
155
156
        if task.xpath('schedule/@id')[0]:
157
            mod_keywords['schedule_id'] = task.xpath('schedule/@id')[0]
158
159
        if task.xpath('preferences/preference'):
160
            preferences, scanner_name_list, value_list = {}, [], []
161
162
            for preference in task.xpath('preferences/preference'):
163
                scanner_name_list.append(preference.find('scanner_name').text)
164
                if preference.find('value').text is not None:
165
                    value_list.append(preference.find('value').text)
166
                else:
167
                    value_list.append('')
168
            preferences['scanner_name'] = scanner_name_list
169
            preferences['value'] = value_list
170
            mod_keywords['preferences'] = preferences
171
172
        if task.xpath('file/@name'):
173
            file = dict(
174
                name=task.xpath('file/@name'), action=task.xpath('file/@action')
175
            )
176
177
            mod_keywords['file'] = file
178
179
        if len(mod_keywords) > 1:
180
            gmp.modify_task(**mod_keywords)
181
182
183
def main(gmp, args):
184
    # pylint: disable=undefined-variable
185
    check_args(args)
186
    xml_doc = args.script[1]
187
188
    print('\nSending task(s)...')
189
190
    xml_tree = create_xml_tree(xml_doc)
191
    parse_send_xml_tree(gmp, xml_tree)
192
193
    print('\n  Task(s) sent!\n')
194
195
196
if __name__ == '__gmp__':
197
    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...
198