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 PortSftp = start_port + 1
86 PortFtps = start_port + 2
88 UrlFtps = str(args.ipstart + int(3 + (i * 16)))
89 logger.debug("\tUrl Ftps: " + str(UrlFtps))
91 UrlSftp = str(args.ipstart + int(4 + (i * 16)))
92 logger.debug("\tUrl Sftp: " + str(UrlSftp))
94 foldername = "pnf-sim-lw-" + str(i)
95 completed = subprocess.run('mkdir ' + foldername, shell=True)
96 logger.info(f'\tCreating folder: {completed.stdout}')
97 completed = subprocess.run(
98 'cp -r pnf-sim-lightweight/* ' +
101 logger.info(f'\tCloning folder: {completed.stdout}')
103 composercmd = "./simulator.sh compose " + \
105 str(ip_subnet) + " " + \
107 args.urlves + " " + \
108 str(IpPnfSim) + " " + \
109 str(args.ipfileserver) + " " + \
110 args.typefileserver + " " + \
111 str(PortSftp) + " " + \
112 str(PortFtps) + " " + \
113 str(UrlFtps) + " " + \
114 str(UrlSftp) + " " + \
115 str(ftps_pasv_port_start) + " " + \
116 str(ftps_pasv_port_end)
118 completed = subprocess.run(
124 logger.info(f'Cloning: {completed.stdout}')
126 ftps_pasv_port_start += ftps_pasv_port_num_of_ports + 1
127 ftps_pasv_port_end += ftps_pasv_port_num_of_ports + 1
129 completed = subprocess.run('set -x; cd pnf-sim-lightweight; ./simulator.sh build ', shell=True)
130 logger.info(f"Build docker image: {completed.stdout}")
135 completed = subprocess.run('rm -rf ./pnf-sim-lw-*', shell=True)
136 logger.info(f'Deleting: {completed.stdout}')
141 for i in range(args.start):
142 foldername = "pnf-sim-lw-" + str(i)
144 completed = subprocess.run(
147 "; bash -x ./simulator.sh start",
149 logger.info(f'Starting: {completed.stdout}')
155 for i in range(args.status):
156 foldername = "pnf-sim-lw-" + str(i)
158 completed = subprocess.run(
161 "; ./simulator.sh status",
163 logger.info(f'Status: {completed.stdout}')
166 for i in range(args.stop):
167 foldername = "pnf-sim-lw-" + str(i)
169 completed = subprocess.run(
172 "; ./simulator.sh stop " + str(i),
174 logger.info(f'Stopping: {completed.stdout}')
178 logger.info("Triggering VES sending:")
180 for i in range(args.trigger):
181 foldername = "pnf-sim-lw-" + str(i)
183 completed = subprocess.run(
186 "; ./simulator.sh trigger-simulator",
188 logger.info(f'Status: {completed.stdout}')
190 if args.triggerstart and args.triggerend:
191 logger.info("Triggering VES sending by a range of simulators:")
193 for i in range(args.triggerstart, args.triggerend+1):
194 foldername = "pnf-sim-lw-" + str(i)
195 logger.info("Instance being processed:" + str(i))
197 completed = subprocess.run(
200 "; ./simulator.sh trigger-simulator",
202 logger.info(f'Status: {completed.stdout}')
204 logger.warning("No instruction was defined")