Passed
Pull Request — master (#344)
by Jaspar
01:41
created

send-tasks.gmp   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 128
dl 0
loc 229
rs 10
c 0
b 0
f 0
wmc 26

5 Functions

Rating   Name   Duplication   Size   Complexity  
A numerical_option() 0 9 2
A check_args() 0 17 2
B interactive_option() 0 47 8
A main() 0 51 2
D parse_send_xml_tree() 0 53 12
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2018-2020 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 argparse import ArgumentParser, RawTextHelpFormatter
21
22
from gvmtools.helper import create_xml_tree, error_and_exit, yes_or_no
23
24
HELP_TEXT = """
25
        This script makes an E-Mail alert scan.
26
27
        Usage examples: 
28
            $ gvm-script --gmp-username name --gmp-password pass ssh --hostname
29
            ... start-alert-scan.gmp.py +h
30
            ... start-alert-scan.gmp.py ++target-name ++hosts ++ports \
31
                    ++port-list-name +C ++recipient ++sender
32
            ... start-alert-scan.gmp.py ++target-name ++hosts ++port-list-id \
33
                    +C ++recipient ++sender
34
            ... start-alert-scan.gmp.py ++target-id +C ++recipient ++sender
35
    """
36
37
38
def check_args(args):
39
    len_args = len(args.script) - 1
40
    if len_args != 1:
41
        message = """
42
        This script pulls tasks data from an xml document and feeds it to \
43
    a desired GSM
44
        One parameter after the script name is required.
45
46
        1. <xml_doc>  -- .xml file containing tasks
47
48
        Example:
49
            $ gvm-script --gmp-username name --gmp-password pass \
50
    ssh --hostname <gsm> scripts/send-tasks.gmp.py example_file.xml
51
        """
52
53
        print(message)
54
        sys.exit()
55
56
57
def numerical_option(statement, list_range):
58
    choice = int(input(statement))
59
60
    if choice in range(1, list_range + 1):
61
        return choice
62
    else:
63
        return numerical_option(
64
            "Please enter valid number from {} to {}...".format(1, list_range),
65
            list_range,
66
        )
67
68
69
def interactive_option(gmp, task, keywords):
70
    options_dict = {}
71
    options_dict['config'] = gmp.get_configs()
72
    options_dict['scanner'] = gmp.get_scanners()
73
    options_dict['target'] = gmp.get_targets()
74
75
    for option in options_dict:
76
        object_dict, object_list = {}, []
77
        object_id = task.find(option).get('id')
78
        object_xml = options_dict[option]
79
80
        for i in object_xml.findall(option):
81
            object_dict[i.find('name').text] = i.xpath('@id')[0]
82
            object_list.append(i.find('name').text)
83
84
        if object_id in object_dict.values():
85
            keywords['{}_id'.format(option)] = object_id
86
        elif object_id not in object_dict.values() and len(object_dict) != 0:
87
            response = yes_or_no(
88
                "\nRequired Field: failed to detect {}_id: {}... "
89
                "\nWould you like to select from available options, or exit "
90
                "the script?".format(
91
                    option, task.xpath('{}/@id'.format(option))[0]
92
                )
93
            )
94
95
            if response is True:
96
                counter = 1
97
                print("{} options:".format(option.capitalize()))
98
                for j in object_list:
99
                    print("    {} - {}".format(counter, j))
100
                    counter += 1
101
                answer = numerical_option(
102
                    "\nPlease enter the number of your choice.",
103
                    len(object_list),
104
                )
105
                keywords['{}_id'.format(option)] = object_dict[
106
                    object_list[answer - 1]
107
                ]
108
            else:
109
                print("\nTerminating...")
110
                quit()
111
        else:
112
            error_and_exit(
113
                "Failed to detect {}_id"
114
                "\nThis field is required therefore the script is unable to "
115
                "continue.\n".format(option)
116
            )
117
118
119
def parse_send_xml_tree(gmp, xml_tree):
120
    task_xml_elements = xml_tree.xpath('task')
121
    print(task_xml_elements)
122
    if not task_xml_elements:
123
        error_and_exit("No tasks found.")
124
    tasks = []
125
    for task in task_xml_elements:
126
        keywords = {'name': task.find('name').text}
127
128
        if task.find('comment').text is not None:
129
            keywords['comment'] = task.find('comment').text
130
131
        interactive_options(gmp, task, keywords)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable interactive_options does not seem to be defined.
Loading history...
132
133
        new_task = gmp.create_task(**keywords)
134
135
        mod_keywords = {'task_id': new_task.xpath('//@id')[0]}
136
        tasks.append(mod_keywords['task_id'])
137
138
        if task.find('schedule_periods') is not None:
139
            mod_keywords['schedule_periods'] = int(
140
                task.find('schedule_periods').text
141
            )
142
143
        if task.find('observers').text:
144
            mod_keywords['observers'] = task.find('observers').text
145
146
        if task.xpath('schedule/@id')[0]:
147
            mod_keywords['schedule_id'] = task.xpath('schedule/@id')[0]
148
149
        if task.xpath('preferences/preference'):
150
            preferences, scanner_name_list, value_list = {}, [], []
151
152
            for preference in task.xpath('preferences/preference'):
153
                scanner_name_list.append(preference.find('scanner_name').text)
154
                if preference.find('value').text is not None:
155
                    value_list.append(preference.find('value').text)
156
                else:
157
                    value_list.append('')
158
            preferences['scanner_name'] = scanner_name_list
159
            preferences['value'] = value_list
160
            mod_keywords['preferences'] = preferences
161
162
        if task.xpath('file/@name'):
163
            file = dict(
164
                name=task.xpath('file/@name'), action=task.xpath('file/@action')
165
            )
166
167
            mod_keywords['file'] = file
168
169
        if len(mod_keywords) > 1:
170
            gmp.modify_task(**mod_keywords)
171
    return tasks
172
173
174
def main(gmp, args):
175
    # pylint: disable=undefined-variable, unused-argument
176
177
    parser = ArgumentParser(
178
        prefix_chars="+",
179
        add_help=False,
180
        formatter_class=RawTextHelpFormatter,
181
        description=HELP_TEXT,
182
    )
183
184
    parser.add_argument(
185
        "+x",
186
        "++xml-file",
187
        dest='xml',
188
        type=str,
189
        required=True,
190
        help='xml file containing tasks',
191
    )
192
193
    parser.add_argument(
194
        "++target-id",
195
        type=str,
196
        dest="target_id",
197
        help="Use an existing target by target id",
198
    )
199
200
    config.add_argument(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable config does not seem to be defined.
Loading history...
201
        "++scan-config-id",
202
        type=str,
203
        dest='scan_config_id',
204
        help="Use existing scan config by id",
205
    )
206
207
    parser.add_argument(
208
        "++scanner-id",
209
        type=str,
210
        dest='scanner_id',
211
        help="Use existing scanner by id",
212
    )
213
214
    script_args, _ = parser.parse_known_args()
215
216
    # check_args(args)
217
218
    print('\nSending task(s)...')
219
220
    xml_tree = create_xml_tree(script_args.xml)
221
    tasks = parse_send_xml_tree(gmp, xml_tree)
222
    for task in tasks:
223
        print(task)
224
    print('\nTask(s) sent!\n')
225
226
227
if __name__ == '__gmp__':
228
    main(gmp, args)  # pylint: disable=undefined-variable
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable args does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable gmp does not seem to be defined.
Loading history...
229