TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | import argparse |
| 3 | import sys |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 4 | import subprocess |
| 5 | import ipaddress |
| 6 | import time |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 7 | import logging |
Bartek Grzybowski | 8200d2a | 2020-05-05 03:50:38 -0700 | [diff] [blame] | 8 | from requests import get |
| 9 | from requests.exceptions import MissingSchema, InvalidSchema, InvalidURL, ConnectionError, ConnectTimeout |
| 10 | |
| 11 | def validate_url(url): |
| 12 | '''Helper function to perform --urlves input param validation''' |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 13 | logger = logging.getLogger("urllib3") |
| 14 | logger.setLevel(logging.WARNING) |
Bartek Grzybowski | 8200d2a | 2020-05-05 03:50:38 -0700 | [diff] [blame] | 15 | try: |
| 16 | get(url, timeout=0.001) |
| 17 | except (MissingSchema, InvalidSchema, InvalidURL): |
| 18 | raise argparse.ArgumentTypeError(f'{url} is not a valid URL') |
| 19 | except (ConnectionError, ConnectTimeout): |
| 20 | pass |
| 21 | return url |
| 22 | |
| 23 | def validate_ip(ip): |
| 24 | '''Helper function to validate input param is a vaild IP address''' |
| 25 | try: |
| 26 | ip_valid = ipaddress.ip_address(ip) |
| 27 | except ValueError: |
| 28 | raise argparse.ArgumentTypeError(f'{ip} is not a valid IP address') |
| 29 | else: |
| 30 | return ip_valid |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 31 | |
Bartek Grzybowski | 879d567 | 2020-05-06 03:37:23 -0700 | [diff] [blame] | 32 | if sys.stdout.isatty(): |
| 33 | logging.basicConfig(level=logging.INFO, format='\033[92m[%(levelname)s]\033[0m %(message)s') |
| 34 | else: |
| 35 | logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') |
| 36 | |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 37 | parser = argparse.ArgumentParser() |
Bartek Grzybowski | 70c116f | 2020-05-05 04:27:25 -0700 | [diff] [blame] | 38 | parser.add_argument('--bootstrap', help='Bootstrap the system', type=int, metavar='COUNT') |
| 39 | parser.add_argument('--trigger', help='Trigger one single VES event from each simulator', type=int, |
| 40 | metavar='COUNT') |
| 41 | parser.add_argument('--triggerstart', help='Trigger only a subset of the simulators (note --triggerend)', type=int, |
| 42 | metavar='COUNT_START') |
| 43 | parser.add_argument('--triggerend', help='Last instance to trigger', type=int, metavar='COUNT_END') |
| 44 | parser.add_argument('--urlves', help='URL of the VES collector', type=validate_url, metavar='URL') |
Bartek Grzybowski | 32fb5ab | 2020-05-05 03:54:01 -0700 | [diff] [blame] | 45 | parser.add_argument('--ipfileserver', help='Visible IP of the file server (SFTP/FTPS) to be included in the VES event', |
Bartek Grzybowski | 70c116f | 2020-05-05 04:27:25 -0700 | [diff] [blame] | 46 | type=validate_ip, metavar='IP') |
Bartek Grzybowski | 32fb5ab | 2020-05-05 03:54:01 -0700 | [diff] [blame] | 47 | parser.add_argument('--typefileserver', help='Type of the file server (SFTP/FTPS) to be included in the VES event', |
| 48 | type=str, choices=['sftp', 'ftps']) |
Bartek Grzybowski | 70c116f | 2020-05-05 04:27:25 -0700 | [diff] [blame] | 49 | parser.add_argument('--ipstart', help='IP address range beginning', type=validate_ip, metavar='IP') |
Bartek Grzybowski | c29b946 | 2020-04-30 07:11:59 -0700 | [diff] [blame] | 50 | parser.add_argument('--clean', action='store_true', help='Clean work-dirs') |
Bartek Grzybowski | 70c116f | 2020-05-05 04:27:25 -0700 | [diff] [blame] | 51 | parser.add_argument('--start', help='Start instances', type=int, metavar='COUNT') |
| 52 | parser.add_argument('--status', help='Status', type=int, metavar='COUNT') |
| 53 | parser.add_argument('--stop', help='Stop instances', type=int, metavar='COUNT') |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 54 | parser.add_argument('--verbose', help='Verbosity level', choices=['info', 'debug'], |
| 55 | type=str, default='debug') |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 56 | |
| 57 | args = parser.parse_args() |
Bartek Grzybowski | 879d567 | 2020-05-06 03:37:23 -0700 | [diff] [blame] | 58 | |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 59 | logger = logging.getLogger(__name__) |
| 60 | logger.setLevel(getattr(logging, args.verbose.upper())) |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 61 | |
TamasBakai | bab325b | 2019-03-26 09:20:16 +0000 | [diff] [blame] | 62 | if args.bootstrap and args.ipstart and args.urlves: |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 63 | logger.info("Bootstrap:") |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 64 | |
Bartek Grzybowski | 8ec0816 | 2020-05-06 04:42:18 -0700 | [diff] [blame] | 65 | start_port = 2000 |
| 66 | ftps_pasv_port_start = 8000 |
| 67 | ftps_pasv_port_num_of_ports = 10 |
Bartek Grzybowski | 3d3d3c2 | 2020-03-05 10:28:03 +0100 | [diff] [blame] | 68 | |
Bartek Grzybowski | 8ec0816 | 2020-05-06 04:42:18 -0700 | [diff] [blame] | 69 | ftps_pasv_port_end = ftps_pasv_port_start + ftps_pasv_port_num_of_ports |
Bartek Grzybowski | 3d3d3c2 | 2020-03-05 10:28:03 +0100 | [diff] [blame] | 70 | |
Bartek Grzybowski | 32fb5ab | 2020-05-05 03:54:01 -0700 | [diff] [blame] | 71 | for i in range(args.bootstrap): |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 72 | logger.info(f"PNF simulator instance: {i}") |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 73 | |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 74 | # The IP ranges are in distance of 16 compared to each other. |
| 75 | # This is matching the /28 subnet mask used in the dockerfile inside. |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 76 | ip_offset = i * 16 |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 77 | |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 78 | ip_subnet = args.ipstart + ip_offset |
| 79 | logger.debug(f"\tIp Subnet: {ip_subnet}") |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 80 | |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 81 | ip_gw = args.ipstart + 1 + ip_offset |
| 82 | logger.debug(f"\tIP Gateway: {ip_gw}") |
| 83 | |
| 84 | ip_PnfSim = args.ipstart + 2 + ip_offset |
| 85 | logger.debug(f"\tIp Pnf SIM: {ip_PnfSim}") |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 86 | |
Bartek Grzybowski | 8ec0816 | 2020-05-06 04:42:18 -0700 | [diff] [blame] | 87 | PortSftp = start_port + 1 |
| 88 | PortFtps = start_port + 2 |
| 89 | start_port += 2 |
Bartek Grzybowski | 3d3d3c2 | 2020-03-05 10:28:03 +0100 | [diff] [blame] | 90 | |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 91 | ip_ftps = args.ipstart + 3 + ip_offset |
| 92 | logger.debug(f"\tUrl Ftps: {ip_ftps}") |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 93 | |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 94 | ip_sftp = args.ipstart + 4 + ip_offset |
| 95 | logger.debug(f"\tUrl Sftp: {ip_sftp}") |
| 96 | |
| 97 | foldername = f"pnf-sim-lw-{i}" |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 98 | completed = subprocess.run('mkdir ' + foldername, shell=True) |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 99 | logger.info(f'\tCreating folder: {completed.stdout}') |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 100 | completed = subprocess.run( |
| 101 | 'cp -r pnf-sim-lightweight/* ' + |
| 102 | foldername, |
| 103 | shell=True) |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 104 | logger.info(f'\tCloning folder: {completed.stdout}') |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 105 | |
TamasBakai | bab325b | 2019-03-26 09:20:16 +0000 | [diff] [blame] | 106 | composercmd = "./simulator.sh compose " + \ |
| 107 | str(ip_gw) + " " + \ |
| 108 | str(ip_subnet) + " " + \ |
| 109 | str(i) + " " + \ |
Bartek Grzybowski | 32fb5ab | 2020-05-05 03:54:01 -0700 | [diff] [blame] | 110 | args.urlves + " " + \ |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 111 | str(ip_PnfSim) + " " + \ |
Bartek Grzybowski | 8ec0816 | 2020-05-06 04:42:18 -0700 | [diff] [blame] | 112 | str(args.ipfileserver) + " " + \ |
| 113 | args.typefileserver + " " + \ |
TamasBakai | bab325b | 2019-03-26 09:20:16 +0000 | [diff] [blame] | 114 | str(PortSftp) + " " + \ |
| 115 | str(PortFtps) + " " + \ |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 116 | str(ip_ftps) + " " + \ |
| 117 | str(ip_sftp) + " " + \ |
TamasBakai | e781c7c | 2019-07-11 11:26:20 +0000 | [diff] [blame] | 118 | str(ftps_pasv_port_start) + " " + \ |
| 119 | str(ftps_pasv_port_end) |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 120 | |
| 121 | completed = subprocess.run( |
| 122 | 'set -x; cd ' + |
| 123 | foldername + |
| 124 | '; ' + |
| 125 | composercmd, |
| 126 | shell=True) |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 127 | logger.info(f'Cloning: {completed.stdout}') |
Bartek Grzybowski | 3d3d3c2 | 2020-03-05 10:28:03 +0100 | [diff] [blame] | 128 | |
TamasBakai | e781c7c | 2019-07-11 11:26:20 +0000 | [diff] [blame] | 129 | ftps_pasv_port_start += ftps_pasv_port_num_of_ports + 1 |
Bartek Grzybowski | 8ec0816 | 2020-05-06 04:42:18 -0700 | [diff] [blame] | 130 | ftps_pasv_port_end += ftps_pasv_port_num_of_ports + 1 |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 131 | |
TamasBakai | bab325b | 2019-03-26 09:20:16 +0000 | [diff] [blame] | 132 | completed = subprocess.run('set -x; cd pnf-sim-lightweight; ./simulator.sh build ', shell=True) |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 133 | logger.info(f"Build docker image: {completed.stdout}") |
TamasBakai | bab325b | 2019-03-26 09:20:16 +0000 | [diff] [blame] | 134 | |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 135 | sys.exit() |
| 136 | |
| 137 | if args.clean: |
| 138 | completed = subprocess.run('rm -rf ./pnf-sim-lw-*', shell=True) |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 139 | logger.info(f'Deleting: {completed.stdout}') |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 140 | sys.exit() |
| 141 | |
| 142 | if args.start: |
| 143 | |
Bartek Grzybowski | 32fb5ab | 2020-05-05 03:54:01 -0700 | [diff] [blame] | 144 | for i in range(args.start): |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 145 | foldername = f"pnf-sim-lw-{i}" |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 146 | |
| 147 | completed = subprocess.run( |
| 148 | 'set -x ; cd ' + |
| 149 | foldername + |
| 150 | "; bash -x ./simulator.sh start", |
| 151 | shell=True) |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 152 | logger.info(f'Starting: {completed.stdout}') |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 153 | |
| 154 | time.sleep(5) |
| 155 | |
| 156 | if args.status: |
| 157 | |
Bartek Grzybowski | 32fb5ab | 2020-05-05 03:54:01 -0700 | [diff] [blame] | 158 | for i in range(args.status): |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 159 | foldername = f"pnf-sim-lw-{i}" |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 160 | |
| 161 | completed = subprocess.run( |
| 162 | 'cd ' + |
| 163 | foldername + |
| 164 | "; ./simulator.sh status", |
| 165 | shell=True) |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 166 | logger.info(f'Status: {completed.stdout}') |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 167 | |
| 168 | if args.stop: |
Bartek Grzybowski | 32fb5ab | 2020-05-05 03:54:01 -0700 | [diff] [blame] | 169 | for i in range(args.stop): |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 170 | foldername = f"pnf-sim-lw-{i}" |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 171 | |
| 172 | completed = subprocess.run( |
| 173 | 'cd ' + |
| 174 | foldername + |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 175 | f"; ./simulator.sh stop {i}", |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 176 | shell=True) |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 177 | logger.info(f'Stopping: {completed.stdout}') |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 178 | |
TamasBakai | b59bffb | 2019-03-22 09:52:03 +0000 | [diff] [blame] | 179 | |
| 180 | if args.trigger: |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 181 | logger.info("Triggering VES sending:") |
TamasBakai | b59bffb | 2019-03-22 09:52:03 +0000 | [diff] [blame] | 182 | |
Bartek Grzybowski | 32fb5ab | 2020-05-05 03:54:01 -0700 | [diff] [blame] | 183 | for i in range(args.trigger): |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 184 | foldername = f"pnf-sim-lw-{i}" |
TamasBakai | b59bffb | 2019-03-22 09:52:03 +0000 | [diff] [blame] | 185 | |
| 186 | completed = subprocess.run( |
| 187 | 'cd ' + |
| 188 | foldername + |
| 189 | "; ./simulator.sh trigger-simulator", |
| 190 | shell=True) |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 191 | logger.info(f'Status: {completed.stdout}') |
Bartek Grzybowski | 3d3d3c2 | 2020-03-05 10:28:03 +0100 | [diff] [blame] | 192 | |
TamasBakai | 34a6f11 | 2019-04-15 08:38:51 +0000 | [diff] [blame] | 193 | if args.triggerstart and args.triggerend: |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 194 | logger.info("Triggering VES sending by a range of simulators:") |
Bartek Grzybowski | 3d3d3c2 | 2020-03-05 10:28:03 +0100 | [diff] [blame] | 195 | |
Bartek Grzybowski | 32fb5ab | 2020-05-05 03:54:01 -0700 | [diff] [blame] | 196 | for i in range(args.triggerstart, args.triggerend+1): |
Bartek Grzybowski | c9514c7 | 2020-05-06 05:56:20 -0700 | [diff] [blame^] | 197 | foldername = f"pnf-sim-lw-{i}" |
| 198 | logger.info(f"Instance being processed: {i}") |
Bartek Grzybowski | 3d3d3c2 | 2020-03-05 10:28:03 +0100 | [diff] [blame] | 199 | |
TamasBakai | 34a6f11 | 2019-04-15 08:38:51 +0000 | [diff] [blame] | 200 | completed = subprocess.run( |
| 201 | 'cd ' + |
| 202 | foldername + |
| 203 | "; ./simulator.sh trigger-simulator", |
| 204 | shell=True) |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 205 | logger.info(f'Status: {completed.stdout}') |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 206 | else: |
Bartek Grzybowski | 1f76234 | 2020-05-05 08:54:37 -0700 | [diff] [blame] | 207 | logger.warning("No instruction was defined") |
Bartek Grzybowski | c29b946 | 2020-04-30 07:11:59 -0700 | [diff] [blame] | 208 | parser.print_usage() |
TamasBakai | d38feb6 | 2019-02-28 09:06:19 +0000 | [diff] [blame] | 209 | sys.exit() |