blob: 7358eb5c3af619fa28e785953814b7514194f4da [file] [log] [blame]
TamasBakaid38feb62019-02-28 09:06:19 +00001#!/usr/bin/env python3
2import argparse
3import sys
TamasBakaid38feb62019-02-28 09:06:19 +00004import subprocess
5import ipaddress
6import time
Bartek Grzybowski1f762342020-05-05 08:54:37 -07007import logging
Bartek Grzybowski8200d2a2020-05-05 03:50:38 -07008from requests import get
Bartek Grzybowski937fe442020-05-07 04:28:13 -07009from json import dumps
Bartek Grzybowski8200d2a2020-05-05 03:50:38 -070010from requests.exceptions import MissingSchema, InvalidSchema, InvalidURL, ConnectionError, ConnectTimeout
11
12def validate_url(url):
13 '''Helper function to perform --urlves input param validation'''
Bartek Grzybowski1f762342020-05-05 08:54:37 -070014 logger = logging.getLogger("urllib3")
15 logger.setLevel(logging.WARNING)
Bartek Grzybowski8200d2a2020-05-05 03:50:38 -070016 try:
17 get(url, timeout=0.001)
18 except (MissingSchema, InvalidSchema, InvalidURL):
19 raise argparse.ArgumentTypeError(f'{url} is not a valid URL')
20 except (ConnectionError, ConnectTimeout):
21 pass
22 return url
23
24def validate_ip(ip):
25 '''Helper function to validate input param is a vaild IP address'''
26 try:
27 ip_valid = ipaddress.ip_address(ip)
28 except ValueError:
29 raise argparse.ArgumentTypeError(f'{ip} is not a valid IP address')
30 else:
31 return ip_valid
TamasBakaid38feb62019-02-28 09:06:19 +000032
Bartek Grzybowski879d5672020-05-06 03:37:23 -070033if sys.stdout.isatty():
34 logging.basicConfig(level=logging.INFO, format='\033[92m[%(levelname)s]\033[0m %(message)s')
35else:
36 logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s')
37
TamasBakaid38feb62019-02-28 09:06:19 +000038parser = argparse.ArgumentParser()
Bartek Grzybowski70c116f2020-05-05 04:27:25 -070039parser.add_argument('--bootstrap', help='Bootstrap the system', type=int, metavar='COUNT')
40parser.add_argument('--trigger', help='Trigger one single VES event from each simulator', type=int,
41 metavar='COUNT')
42parser.add_argument('--triggerstart', help='Trigger only a subset of the simulators (note --triggerend)', type=int,
43 metavar='COUNT_START')
44parser.add_argument('--triggerend', help='Last instance to trigger', type=int, metavar='COUNT_END')
45parser.add_argument('--urlves', help='URL of the VES collector', type=validate_url, metavar='URL')
Bartek Grzybowski32fb5ab2020-05-05 03:54:01 -070046parser.add_argument('--ipfileserver', help='Visible IP of the file server (SFTP/FTPS) to be included in the VES event',
Bartek Grzybowski70c116f2020-05-05 04:27:25 -070047 type=validate_ip, metavar='IP')
Bartek Grzybowski32fb5ab2020-05-05 03:54:01 -070048parser.add_argument('--typefileserver', help='Type of the file server (SFTP/FTPS) to be included in the VES event',
49 type=str, choices=['sftp', 'ftps'])
Bartek Grzybowski70c116f2020-05-05 04:27:25 -070050parser.add_argument('--ipstart', help='IP address range beginning', type=validate_ip, metavar='IP')
Bartek Grzybowskic29b9462020-04-30 07:11:59 -070051parser.add_argument('--clean', action='store_true', help='Clean work-dirs')
Bartek Grzybowski70c116f2020-05-05 04:27:25 -070052parser.add_argument('--start', help='Start instances', type=int, metavar='COUNT')
53parser.add_argument('--status', help='Status', type=int, metavar='COUNT')
54parser.add_argument('--stop', help='Stop instances', type=int, metavar='COUNT')
Bartek Grzybowski1f762342020-05-05 08:54:37 -070055parser.add_argument('--verbose', help='Verbosity level', choices=['info', 'debug'],
56 type=str, default='debug')
TamasBakaid38feb62019-02-28 09:06:19 +000057
58args = parser.parse_args()
Bartek Grzybowski879d5672020-05-06 03:37:23 -070059
Bartek Grzybowski1f762342020-05-05 08:54:37 -070060logger = logging.getLogger(__name__)
61logger.setLevel(getattr(logging, args.verbose.upper()))
TamasBakaid38feb62019-02-28 09:06:19 +000062
TamasBakaibab325b2019-03-26 09:20:16 +000063if args.bootstrap and args.ipstart and args.urlves:
Bartek Grzybowski937fe442020-05-07 04:28:13 -070064 logger.info("Bootstrapping PNF instances")
TamasBakaid38feb62019-02-28 09:06:19 +000065
Bartek Grzybowski8ec08162020-05-06 04:42:18 -070066 start_port = 2000
67 ftps_pasv_port_start = 8000
68 ftps_pasv_port_num_of_ports = 10
Bartek Grzybowski3d3d3c22020-03-05 10:28:03 +010069
Bartek Grzybowski8ec08162020-05-06 04:42:18 -070070 ftps_pasv_port_end = ftps_pasv_port_start + ftps_pasv_port_num_of_ports
Bartek Grzybowski3d3d3c22020-03-05 10:28:03 +010071
Bartek Grzybowski32fb5ab2020-05-05 03:54:01 -070072 for i in range(args.bootstrap):
Bartek Grzybowskic9514c72020-05-06 05:56:20 -070073 logger.info(f"PNF simulator instance: {i}")
TamasBakaid38feb62019-02-28 09:06:19 +000074
TamasBakaid38feb62019-02-28 09:06:19 +000075 # The IP ranges are in distance of 16 compared to each other.
76 # This is matching the /28 subnet mask used in the dockerfile inside.
Bartek Grzybowski937fe442020-05-07 04:28:13 -070077 instance_ip_offset = i * 16
78 ip_properties = [
79 'subnet',
80 'gw',
81 'PnfSim',
82 'ftps',
83 'sftp'
84 ]
TamasBakaid38feb62019-02-28 09:06:19 +000085
Bartek Grzybowski937fe442020-05-07 04:28:13 -070086 ip_offset = 0
87 ip = {}
88 for prop in ip_properties:
89 ip.update({prop: str(args.ipstart + ip_offset + instance_ip_offset)})
90 ip_offset += 1
TamasBakaid38feb62019-02-28 09:06:19 +000091
Bartek Grzybowski937fe442020-05-07 04:28:13 -070092 logger.debug(f'Instance #{i} properties:\n {dumps(ip, indent=4)}')
TamasBakaid38feb62019-02-28 09:06:19 +000093
Bartek Grzybowski8ec08162020-05-06 04:42:18 -070094 PortSftp = start_port + 1
95 PortFtps = start_port + 2
96 start_port += 2
Bartek Grzybowski3d3d3c22020-03-05 10:28:03 +010097
Bartek Grzybowskic9514c72020-05-06 05:56:20 -070098 foldername = f"pnf-sim-lw-{i}"
TamasBakaid38feb62019-02-28 09:06:19 +000099 completed = subprocess.run('mkdir ' + foldername, shell=True)
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700100 logger.info(f'\tCreating folder: {completed.stdout}')
TamasBakaid38feb62019-02-28 09:06:19 +0000101 completed = subprocess.run(
102 'cp -r pnf-sim-lightweight/* ' +
103 foldername,
104 shell=True)
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700105 logger.info(f'\tCloning folder: {completed.stdout}')
TamasBakaid38feb62019-02-28 09:06:19 +0000106
Bartek Grzybowski937fe442020-05-07 04:28:13 -0700107 composercmd = " ".join([
108 "./simulator.sh compose",
109 ip['gw'],
110 ip['subnet'],
111 str(i),
112 args.urlves,
113 ip['PnfSim'],
114 str(args.ipfileserver),
115 args.typefileserver,
116 str(PortSftp),
117 str(PortFtps),
118 ip['ftps'],
119 ip['sftp'],
120 str(ftps_pasv_port_start),
121 str(ftps_pasv_port_end)
122 ])
123 logger.debug(f"Script cmdline: {composercmd}")
TamasBakaid38feb62019-02-28 09:06:19 +0000124
125 completed = subprocess.run(
126 'set -x; cd ' +
127 foldername +
128 '; ' +
129 composercmd,
130 shell=True)
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700131 logger.info(f'Cloning: {completed.stdout}')
Bartek Grzybowski3d3d3c22020-03-05 10:28:03 +0100132
TamasBakaie781c7c2019-07-11 11:26:20 +0000133 ftps_pasv_port_start += ftps_pasv_port_num_of_ports + 1
Bartek Grzybowski8ec08162020-05-06 04:42:18 -0700134 ftps_pasv_port_end += ftps_pasv_port_num_of_ports + 1
TamasBakaid38feb62019-02-28 09:06:19 +0000135
Bartek Grzybowski937fe442020-05-07 04:28:13 -0700136 logger.info(f'Done setting up instance #{i}')
137
TamasBakaibab325b2019-03-26 09:20:16 +0000138 completed = subprocess.run('set -x; cd pnf-sim-lightweight; ./simulator.sh build ', shell=True)
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700139 logger.info(f"Build docker image: {completed.stdout}")
TamasBakaibab325b2019-03-26 09:20:16 +0000140
TamasBakaid38feb62019-02-28 09:06:19 +0000141 sys.exit()
142
143if args.clean:
144 completed = subprocess.run('rm -rf ./pnf-sim-lw-*', shell=True)
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700145 logger.info(f'Deleting: {completed.stdout}')
TamasBakaid38feb62019-02-28 09:06:19 +0000146 sys.exit()
147
148if args.start:
149
Bartek Grzybowski32fb5ab2020-05-05 03:54:01 -0700150 for i in range(args.start):
Bartek Grzybowskic9514c72020-05-06 05:56:20 -0700151 foldername = f"pnf-sim-lw-{i}"
TamasBakaid38feb62019-02-28 09:06:19 +0000152
153 completed = subprocess.run(
154 'set -x ; cd ' +
155 foldername +
156 "; bash -x ./simulator.sh start",
157 shell=True)
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700158 logger.info(f'Starting: {completed.stdout}')
TamasBakaid38feb62019-02-28 09:06:19 +0000159
160 time.sleep(5)
161
162if args.status:
163
Bartek Grzybowski32fb5ab2020-05-05 03:54:01 -0700164 for i in range(args.status):
Bartek Grzybowskic9514c72020-05-06 05:56:20 -0700165 foldername = f"pnf-sim-lw-{i}"
TamasBakaid38feb62019-02-28 09:06:19 +0000166
167 completed = subprocess.run(
168 'cd ' +
169 foldername +
170 "; ./simulator.sh status",
171 shell=True)
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700172 logger.info(f'Status: {completed.stdout}')
TamasBakaid38feb62019-02-28 09:06:19 +0000173
174if args.stop:
Bartek Grzybowski32fb5ab2020-05-05 03:54:01 -0700175 for i in range(args.stop):
Bartek Grzybowskic9514c72020-05-06 05:56:20 -0700176 foldername = f"pnf-sim-lw-{i}"
TamasBakaid38feb62019-02-28 09:06:19 +0000177
178 completed = subprocess.run(
179 'cd ' +
180 foldername +
Bartek Grzybowskic9514c72020-05-06 05:56:20 -0700181 f"; ./simulator.sh stop {i}",
TamasBakaid38feb62019-02-28 09:06:19 +0000182 shell=True)
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700183 logger.info(f'Stopping: {completed.stdout}')
TamasBakaid38feb62019-02-28 09:06:19 +0000184
TamasBakaib59bffb2019-03-22 09:52:03 +0000185
186if args.trigger:
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700187 logger.info("Triggering VES sending:")
TamasBakaib59bffb2019-03-22 09:52:03 +0000188
Bartek Grzybowski32fb5ab2020-05-05 03:54:01 -0700189 for i in range(args.trigger):
Bartek Grzybowskic9514c72020-05-06 05:56:20 -0700190 foldername = f"pnf-sim-lw-{i}"
TamasBakaib59bffb2019-03-22 09:52:03 +0000191
192 completed = subprocess.run(
193 'cd ' +
194 foldername +
195 "; ./simulator.sh trigger-simulator",
196 shell=True)
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700197 logger.info(f'Status: {completed.stdout}')
Bartek Grzybowski3d3d3c22020-03-05 10:28:03 +0100198
TamasBakai34a6f112019-04-15 08:38:51 +0000199if args.triggerstart and args.triggerend:
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700200 logger.info("Triggering VES sending by a range of simulators:")
Bartek Grzybowski3d3d3c22020-03-05 10:28:03 +0100201
Bartek Grzybowski32fb5ab2020-05-05 03:54:01 -0700202 for i in range(args.triggerstart, args.triggerend+1):
Bartek Grzybowskic9514c72020-05-06 05:56:20 -0700203 foldername = f"pnf-sim-lw-{i}"
204 logger.info(f"Instance being processed: {i}")
Bartek Grzybowski3d3d3c22020-03-05 10:28:03 +0100205
TamasBakai34a6f112019-04-15 08:38:51 +0000206 completed = subprocess.run(
207 'cd ' +
208 foldername +
209 "; ./simulator.sh trigger-simulator",
210 shell=True)
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700211 logger.info(f'Status: {completed.stdout}')
TamasBakaid38feb62019-02-28 09:06:19 +0000212else:
Bartek Grzybowski1f762342020-05-05 08:54:37 -0700213 logger.warning("No instruction was defined")
Bartek Grzybowskic29b9462020-04-30 07:11:59 -0700214 parser.print_usage()
TamasBakaid38feb62019-02-28 09:06:19 +0000215 sys.exit()