8 from requests import get
9 from requests.exceptions import MissingSchema, InvalidSchema, InvalidURL, ConnectionError, ConnectTimeout
11 logging.basicConfig(level=logging.INFO, format='\033[92m[%(levelname)s]\033[0m %(message)s')
13 def validate_url(url):
14 '''Helper function to perform --urlves input param validation'''
15 logger = logging.getLogger("urllib3")
16 logger.setLevel(logging.WARNING)
18 get(url, timeout=0.001)
19 except (MissingSchema, InvalidSchema, InvalidURL):
20 raise argparse.ArgumentTypeError(f'{url} is not a valid URL')
21 except (ConnectionError, ConnectTimeout):
26 '''Helper function to validate input param is a vaild IP address'''
28 ip_valid = ipaddress.ip_address(ip)
30 raise argparse.ArgumentTypeError(f'{ip} is not a valid IP address')
34 parser = argparse.ArgumentParser()
35 parser.add_argument('--bootstrap', help='Bootstrap the system', type=int, metavar='COUNT')
36 parser.add_argument('--trigger', help='Trigger one single VES event from each simulator', type=int,
38 parser.add_argument('--triggerstart', help='Trigger only a subset of the simulators (note --triggerend)', type=int,
39 metavar='COUNT_START')
40 parser.add_argument('--triggerend', help='Last instance to trigger', type=int, metavar='COUNT_END')
41 parser.add_argument('--urlves', help='URL of the VES collector', type=validate_url, metavar='URL')
42 parser.add_argument('--ipfileserver', help='Visible IP of the file server (SFTP/FTPS) to be included in the VES event',
43 type=validate_ip, metavar='IP')
44 parser.add_argument('--typefileserver', help='Type of the file server (SFTP/FTPS) to be included in the VES event',
45 type=str, choices=['sftp', 'ftps'])
46 parser.add_argument('--ipstart', help='IP address range beginning', type=validate_ip, metavar='IP')
47 parser.add_argument('--clean', action='store_true', help='Clean work-dirs')
48 parser.add_argument('--start', help='Start instances', type=int, metavar='COUNT')
49 parser.add_argument('--status', help='Status', type=int, metavar='COUNT')
50 parser.add_argument('--stop', help='Stop instances', type=int, metavar='COUNT')
51 parser.add_argument('--verbose', help='Verbosity level', choices=['info', 'debug'],
52 type=str, default='debug')
54 args = parser.parse_args()
55 logger = logging.getLogger(__name__)
56 logger.setLevel(getattr(logging, args.verbose.upper()))
58 if args.bootstrap and args.ipstart and args.urlves:
59 logger.info("Bootstrap:")
62 ftps_pasv_port_start=8000
63 ftps_pasv_port_num_of_ports=10
65 ftps_pasv_port_end=ftps_pasv_port_start + ftps_pasv_port_num_of_ports
67 for i in range(args.bootstrap):
68 logger.info("PNF simulator instance: " + str(i) + ".")
70 ip_subnet = args.ipstart + int(0 + (i * 16))
71 logger.debug("\tIp Subnet:" + str(ip_subnet))
72 # The IP ranges are in distance of 16 compared to each other.
73 # This is matching the /28 subnet mask used in the dockerfile inside.
75 ip_gw = args.ipstart + int(1 + (i * 16))
76 logger.debug("\tIP Gateway:" + str(ip_gw))
78 IpPnfSim = args.ipstart + int(2 + (i * 16))
79 logger.debug("\tIp Pnf SIM:" + str(IpPnfSim))
81 IpFileServer = str(args.ipfileserver)
82 TypeFileServer = args.typefileserver
84 PortSftp=start_port +1
85 PortFtps=start_port +2
87 UrlFtps = str(args.ipstart + int(3 + (i * 16)))
88 logger.debug("\tUrl Ftps: " + str(UrlFtps))
90 UrlSftp = str(args.ipstart + int(4 + (i * 16)))
91 logger.debug("\tUrl Sftp: " + str(UrlSftp))
93 foldername = "pnf-sim-lw-" + str(i)
94 completed = subprocess.run('mkdir ' + foldername, shell=True)
95 logger.info(f'\tCreating folder: {completed.stdout}')
96 completed = subprocess.run(
97 'cp -r pnf-sim-lightweight/* ' +
100 logger.info(f'\tCloning folder: {completed.stdout}')
102 composercmd = "./simulator.sh compose " + \
104 str(ip_subnet) + " " + \
106 args.urlves + " " + \
107 str(IpPnfSim) + " " + \
108 IpFileServer + " " + \
109 TypeFileServer + " " + \
110 str(PortSftp) + " " + \
111 str(PortFtps) + " " + \
112 str(UrlFtps) + " " + \
113 str(UrlSftp) + " " + \
114 str(ftps_pasv_port_start) + " " + \
115 str(ftps_pasv_port_end)
117 completed = subprocess.run(
123 logger.info(f'Cloning: {completed.stdout}')
125 ftps_pasv_port_start += ftps_pasv_port_num_of_ports + 1
126 ftps_pasv_port_end += ftps_pasv_port_num_of_ports +1
128 completed = subprocess.run('set -x; cd pnf-sim-lightweight; ./simulator.sh build ', shell=True)
129 logger.info(f"Build docker image: {completed.stdout}")
134 completed = subprocess.run('rm -rf ./pnf-sim-lw-*', shell=True)
135 logger.info(f'Deleting: {completed.stdout}')
140 for i in range(args.start):
141 foldername = "pnf-sim-lw-" + str(i)
143 completed = subprocess.run(
146 "; bash -x ./simulator.sh start",
148 logger.info(f'Starting: {completed.stdout}')
154 for i in range(args.status):
155 foldername = "pnf-sim-lw-" + str(i)
157 completed = subprocess.run(
160 "; ./simulator.sh status",
162 logger.info(f'Status: {completed.stdout}')
165 for i in range(args.stop):
166 foldername = "pnf-sim-lw-" + str(i)
168 completed = subprocess.run(
171 "; ./simulator.sh stop " + str(i),
173 logger.info(f'Stopping: {completed.stdout}')
177 logger.info("Triggering VES sending:")
179 for i in range(args.trigger):
180 foldername = "pnf-sim-lw-" + str(i)
182 completed = subprocess.run(
185 "; ./simulator.sh trigger-simulator",
187 logger.info(f'Status: {completed.stdout}')
189 if args.triggerstart and args.triggerend:
190 logger.info("Triggering VES sending by a range of simulators:")
192 for i in range(args.triggerstart, args.triggerend+1):
193 foldername = "pnf-sim-lw-" + str(i)
194 logger.info("Instance being processed:" + str(i))
196 completed = subprocess.run(
199 "; ./simulator.sh trigger-simulator",
201 logger.info(f'Status: {completed.stdout}')
203 logger.warning("No instruction was defined")