8 from requests import get
9 from requests.exceptions import MissingSchema, InvalidSchema, InvalidURL, ConnectionError, ConnectTimeout
11 def validate_url(url):
12 '''Helper function to perform --urlves input param validation'''
13 logger = logging.getLogger("urllib3")
14 logger.setLevel(logging.WARNING)
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):
24 '''Helper function to validate input param is a vaild IP address'''
26 ip_valid = ipaddress.ip_address(ip)
28 raise argparse.ArgumentTypeError(f'{ip} is not a valid IP address')
32 if sys.stdout.isatty():
33 logging.basicConfig(level=logging.INFO, format='\033[92m[%(levelname)s]\033[0m %(message)s')
35 logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s')
37 parser = argparse.ArgumentParser()
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,
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')
45 parser.add_argument('--ipfileserver', help='Visible IP of the file server (SFTP/FTPS) to be included in the VES event',
46 type=validate_ip, metavar='IP')
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'])
49 parser.add_argument('--ipstart', help='IP address range beginning', type=validate_ip, metavar='IP')
50 parser.add_argument('--clean', action='store_true', help='Clean work-dirs')
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')
54 parser.add_argument('--verbose', help='Verbosity level', choices=['info', 'debug'],
55 type=str, default='debug')
57 args = parser.parse_args()
59 logger = logging.getLogger(__name__)
60 logger.setLevel(getattr(logging, args.verbose.upper()))
62 if args.bootstrap and args.ipstart and args.urlves:
63 logger.info("Bootstrap:")
66 ftps_pasv_port_start=8000
67 ftps_pasv_port_num_of_ports=10
69 ftps_pasv_port_end=ftps_pasv_port_start + ftps_pasv_port_num_of_ports
71 for i in range(args.bootstrap):
72 logger.info("PNF simulator instance: " + str(i) + ".")
74 ip_subnet = args.ipstart + int(0 + (i * 16))
75 logger.debug("\tIp Subnet:" + str(ip_subnet))
76 # The IP ranges are in distance of 16 compared to each other.
77 # This is matching the /28 subnet mask used in the dockerfile inside.
79 ip_gw = args.ipstart + int(1 + (i * 16))
80 logger.debug("\tIP Gateway:" + str(ip_gw))
82 IpPnfSim = args.ipstart + int(2 + (i * 16))
83 logger.debug("\tIp Pnf SIM:" + str(IpPnfSim))
85 IpFileServer = str(args.ipfileserver)
86 TypeFileServer = args.typefileserver
88 PortSftp=start_port +1
89 PortFtps=start_port +2
91 UrlFtps = str(args.ipstart + int(3 + (i * 16)))
92 logger.debug("\tUrl Ftps: " + str(UrlFtps))
94 UrlSftp = str(args.ipstart + int(4 + (i * 16)))
95 logger.debug("\tUrl Sftp: " + str(UrlSftp))
97 foldername = "pnf-sim-lw-" + str(i)
98 completed = subprocess.run('mkdir ' + foldername, shell=True)
99 logger.info(f'\tCreating folder: {completed.stdout}')
100 completed = subprocess.run(
101 'cp -r pnf-sim-lightweight/* ' +
104 logger.info(f'\tCloning folder: {completed.stdout}')
106 composercmd = "./simulator.sh compose " + \
108 str(ip_subnet) + " " + \
110 args.urlves + " " + \
111 str(IpPnfSim) + " " + \
112 IpFileServer + " " + \
113 TypeFileServer + " " + \
114 str(PortSftp) + " " + \
115 str(PortFtps) + " " + \
116 str(UrlFtps) + " " + \
117 str(UrlSftp) + " " + \
118 str(ftps_pasv_port_start) + " " + \
119 str(ftps_pasv_port_end)
121 completed = subprocess.run(
127 logger.info(f'Cloning: {completed.stdout}')
129 ftps_pasv_port_start += ftps_pasv_port_num_of_ports + 1
130 ftps_pasv_port_end += ftps_pasv_port_num_of_ports +1
132 completed = subprocess.run('set -x; cd pnf-sim-lightweight; ./simulator.sh build ', shell=True)
133 logger.info(f"Build docker image: {completed.stdout}")
138 completed = subprocess.run('rm -rf ./pnf-sim-lw-*', shell=True)
139 logger.info(f'Deleting: {completed.stdout}')
144 for i in range(args.start):
145 foldername = "pnf-sim-lw-" + str(i)
147 completed = subprocess.run(
150 "; bash -x ./simulator.sh start",
152 logger.info(f'Starting: {completed.stdout}')
158 for i in range(args.status):
159 foldername = "pnf-sim-lw-" + str(i)
161 completed = subprocess.run(
164 "; ./simulator.sh status",
166 logger.info(f'Status: {completed.stdout}')
169 for i in range(args.stop):
170 foldername = "pnf-sim-lw-" + str(i)
172 completed = subprocess.run(
175 "; ./simulator.sh stop " + str(i),
177 logger.info(f'Stopping: {completed.stdout}')
181 logger.info("Triggering VES sending:")
183 for i in range(args.trigger):
184 foldername = "pnf-sim-lw-" + str(i)
186 completed = subprocess.run(
189 "; ./simulator.sh trigger-simulator",
191 logger.info(f'Status: {completed.stdout}')
193 if args.triggerstart and args.triggerend:
194 logger.info("Triggering VES sending by a range of simulators:")
196 for i in range(args.triggerstart, args.triggerend+1):
197 foldername = "pnf-sim-lw-" + str(i)
198 logger.info("Instance being processed:" + str(i))
200 completed = subprocess.run(
203 "; ./simulator.sh trigger-simulator",
205 logger.info(f'Status: {completed.stdout}')
207 logger.warning("No instruction was defined")