|
9 | 9 |
|
10 | 10 | """
|
11 | 11 |
|
| 12 | +import os |
12 | 13 | import sys
|
13 | 14 | import re
|
14 | 15 | import pprint
|
15 | 16 | import argparse
|
16 | 17 | import requests
|
17 | 18 | import IPy
|
| 19 | +import http.server |
| 20 | +import socketserver |
18 | 21 |
|
19 | 22 | XFORCE_API_BASE = 'https://api.xforce.ibmcloud.com'
|
20 | 23 | XFORCE_API_IP_REP = 'ipr'
|
@@ -28,19 +31,31 @@ def parse_args():
|
28 | 31 | :return: a Namespace object of parsed arguments
|
29 | 32 | """
|
30 | 33 | parser = argparse.ArgumentParser(description="Use the X-Force API to check IP address reputation.")
|
31 |
| -parser.add_argument('-o', '--out', metavar='output_file', |
| 34 | +subparsers = parser.add_subparsers(help="Mutually exclusive sub-commands") |
| 35 | + |
| 36 | +cli_parser = subparsers.add_parser('cli', help="Command-line Interface; run 'xfipchk cli -h' to see options") |
| 37 | +cli_parser.add_argument('-o', '--out', metavar='output_file', |
32 | 38 | type=argparse.FileType('w'), help="Write result of X-Force call to file.")
|
33 |
| -parser.add_argument('authN', type=argparse.FileType('r'), |
34 |
| -help='Path to a file containing your X-Force credentials, key and password on first and second ' |
| 39 | +cli_parser.add_argument('authN', type=argparse.FileType('r'), |
| 40 | +help='Path to a file containing your X-Force credentials, key and password on first and second ' |
35 | 41 | 'lines, respectively.')
|
36 | 42 |
|
37 | 43 | # user should not be able to specify both IP on cmdline and in a file
|
38 |
| -ip_group = parser.add_mutually_exclusive_group() |
| 44 | +ip_group = cli_parser.add_mutually_exclusive_group() |
39 | 45 | # TODO: nargs='N' and loop through list
|
40 |
| -ip_group.add_argument('-i', '--ip', nargs='?', metavar='ip_address', help='An IP address to be checked via ' |
41 |
| -'X-Force. If the IP address is omitted or invalid, the user will be prompted for one.') |
| 46 | +ip_group.add_argument('-i', '--ip', metavar='ip_address', help='An IP address to be checked via X-Force. If the IP' |
| 47 | +'address is omitted or invalid, the user will be ' |
| 48 | +'prompted for one.') |
42 | 49 | ip_group.add_argument('-I', '--Ips', type=argparse.FileType('r'), metavar='file_of_ip_addresses',
|
43 | 50 | help='A file containing IP addresses, one per line.')
|
| 51 | + |
| 52 | +web_parser = subparsers.add_parser('web', help="Web interface; run 'xfipchk web -h' to see options") |
| 53 | +w_group = web_parser.add_argument_group(title="Web Interface", description="You may specify the address and port to" |
| 54 | +" bind to; defaults are 127.0.0.1 and " |
| 55 | +"8000") |
| 56 | +w_group.add_argument('-p', '--port', default=8000) |
| 57 | +w_group.add_argument('-a', '--address', default='127.0.0.1') |
| 58 | + |
44 | 59 | return parser.parse_args()
|
45 | 60 |
|
46 | 61 |
|
@@ -164,27 +179,47 @@ def print_json_file(results, file):
|
164 | 179 | file.write('######################################\n')
|
165 | 180 |
|
166 | 181 |
|
167 |
| -def main(): |
| 182 | +def start_server(ip_address="127.0.0.1", port=8000): |
| 183 | +# we want to serve out of the web directory |
| 184 | +handler = http.server.SimpleHTTPRequestHandler |
| 185 | +with socketserver.TCPServer((ip_address, port), handler) as httpd: |
| 186 | +print("Starting HTTP server on port {0}".format(port)) |
| 187 | +httpd.serve_forever() |
168 | 188 |
|
169 |
| -ip = None |
170 |
| -addresses = list() |
| 189 | + |
| 190 | +def main(): |
171 | 191 | args = parse_args()
|
172 |
| -if args.Ips: |
173 |
| -addresses = read_in_address_file(args.Ips) |
174 |
| -else: |
175 |
| -# get user-supplied IP address from the cmd line |
176 |
| -if args.ip: |
177 |
| -ip = validate_ip(args.ip) |
178 |
| -# prompt user for valid IP in case of typo on cmdline |
179 |
| -while not ip: |
180 |
| -ip = request_valid_ip() |
181 |
| -addresses.append(ip) |
182 |
| -creds = read_in_xforce_keys(args.authN) |
183 |
| -results = call_xforce_api(addresses, creds[0], creds[1]) |
184 |
| -if args.out: |
185 |
| -print_json_file(results, args.out) |
186 |
| -else: |
187 |
| -print_json_stdout(results) |
| 192 | +# if port is in Namespace object, assume web interface |
| 193 | +if args.port: |
| 194 | +# TODO: should use a context manager here |
| 195 | +current = os.curdir |
| 196 | +try: |
| 197 | +os.chdir('./web') |
| 198 | +start_server(args.address, args.port) |
| 199 | +except OSError as ose: |
| 200 | +print(ose.strerror) |
| 201 | +finally: |
| 202 | +os.chdir(current) |
| 203 | + |
| 204 | +elif args.cli: |
| 205 | +ip = None |
| 206 | +addresses = list() |
| 207 | +if args.Ips: |
| 208 | +addresses = read_in_address_file(args.Ips) |
| 209 | +else: |
| 210 | +# get user-supplied IP address from the cmd line |
| 211 | +if args.ip: |
| 212 | +ip = validate_ip(args.ip) |
| 213 | +# prompt user for valid IP in case of typo on cmdline |
| 214 | +while not ip: |
| 215 | +ip = request_valid_ip() |
| 216 | +addresses.append(ip) |
| 217 | +creds = read_in_xforce_keys(args.authN) |
| 218 | +results = call_xforce_api(addresses, creds[0], creds[1]) |
| 219 | +if args.out: |
| 220 | +print_json_file(results, args.out) |
| 221 | +else: |
| 222 | +print_json_stdout(results) |
188 | 223 |
|
189 | 224 | return 0
|
190 | 225 |
|
|
0 commit comments