Adding Security gateway testing
[samplevnf.git] / VNFs / DPPD-PROX / helper-scripts / openstackrapid / createrapid.py
1 #!/usr/bin/python
2
3 ##
4 ## Copyright (c) 2010-2017 Intel Corporation
5 ##
6 ## Licensed under the Apache License, Version 2.0 (the "License");
7 ## you may not use this file except in compliance with the License.
8 ## You may obtain a copy of the License at
9 ##
10 ##     http://www.apache.org/licenses/LICENSE-2.0
11 ##
12 ## Unless required by applicable law or agreed to in writing, software
13 ## distributed under the License is distributed on an "AS IS" BASIS,
14 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ## See the License for the specific language governing permissions and
16 ## limitations under the License.
17 ##
18
19 from __future__ import print_function
20
21 import os
22 import stat
23 import sys
24 import time
25 import subprocess
26 import getopt
27 import re
28 import logging
29 from logging.handlers import RotatingFileHandler
30 from logging import handlers
31 from prox_ctrl import prox_ctrl
32 import ConfigParser
33
34 version="17.12.15"
35 stack = "rapid" #Default string for stack
36 yaml = "rapid.yaml" #Default string for yaml file
37 key = "prox" # This is also the default in the yaml file....
38 flavor = "prox_flavor" # This is also the default in the yaml file....
39 image = "rapidVM" # This is also the default in the yaml file....
40 image_file = "rapidVM.qcow2"
41 dataplane_network = "dataplane-network" # This is also the default in the yaml file....
42 subnet = "dpdk-subnet" #Hardcoded at this moment
43 subnet_cidr="10.10.10.0/24" # cidr for dataplane
44 internal_network="admin_internal_net"
45 floating_network="admin_floating_net"
46 loglevel="DEBUG" # sets log level for writing to file
47 runtime=10 # time in seconds for 1 test run
48
49 def usage():
50         print("usage: createrapid [--version] [-v]")
51         print("                   [--stack STACK_NAME]")
52         print("                   [--yaml YAML_FILE]")
53         print("                   [--key KEY_NAME]")
54         print("                   [--flavor FLAVOR_NAME]")
55         print("                   [--image IMAGE_NAME]")
56         print("                   [--image_file IMAGE_FILE]")
57         print("                   [--dataplane_network DP_NETWORK]")
58         print("                   [--subnet DP_SUBNET]")
59         print("                   [--subnet_cidr SUBNET_CIDR]")
60         print("                   [--internal_network ADMIN_NETWORK]")
61         print("                   [--floating_network ADMIN_NETWORK]")
62         print("                   [--log DEBUG|INFO|WARNING|ERROR|CRITICAL")
63         print("                   [-h] [--help]")
64         print("")
65         print("Command-line interface to createrapid")
66         print("")
67         print("optional arguments:")
68         print("  -v,  --version                 Show program's version number and exit")
69         print("  --stack STACK_NAME             Specify a name for the heat stack. Default is %s."%stack)
70         print("  --yaml YAML_FILE               Specify the yaml file to be used. Default is %s."%yaml)
71         print("  --key KEY_NAME                 Specify the key to be used. Default is %s."%key)
72         print("  --flavor FLAVOR_NAME           Specify the flavor to be used. Default is %s."%flavor)
73         print("  --image IMAGE_NAME             Specify the image to be used. Default is %s."%image)
74         print("  --image_file IMAGE_FILE        Specify the image qcow2 file to be used. Default is %s."%image_file)
75         print("  --dataplane_network NETWORK    Specify the network name to be used for the dataplane. Default is %s."%dataplane_network)
76         print("  --subnet DP_SUBNET             Specify the subnet name to be used for the dataplane. Default is %s."%subnet)
77         print("  --subnet_cidr SUBNET_CIDR      Specify the subnet CIDR to be used for the dataplane. Default is %s."%subnet_cidr)
78         print("  --internal_network NETWORK     Specify the network name to be used for the control plane. Default is %s."%internal_network)
79         print("  --floating_network NETWORK     Specify the external floating ip network name. Default is %s."%floating_network)
80         print("  --log                          Specify logging level for log file output, screen output level is hard coded")
81         print("  -h, --help                     Show help message and exit.")
82         print("")
83         print("To delete the rapid stack, type the following command")
84         print("   openstack stack delete --yes --wait %s"%stack)
85         print("Note that %s is the default stack name. Replace with STACK_NAME if needed"%stack)
86
87 try:
88         opts, args = getopt.getopt(sys.argv[1:], "vh", ["version","help", "yaml=","stack=","key=","flavor=","image=","image_file=","dataplane_network=","subnet=","subnet_cidr=","internal_network=","floating_network=","log="])
89 except getopt.GetoptError as err:
90         print("===========================================")
91         print(str(err))
92         print("===========================================")
93         usage()
94         sys.exit(2)
95 if args:
96         usage()
97         sys.exit(2)
98 for opt, arg in opts:
99         if opt in ("-h", "--help"):
100                 usage()
101                 sys.exit()
102         if opt in ("-v", "--version"):
103                 print("Rapid Automated Performance Indication for Dataplane "+version)
104                 sys.exit()
105         if opt in ("--stack"):
106                 stack = arg
107                 print ("Using '"+stack+"' as name for the stack")
108         elif opt in ("--yaml"):
109                 yaml = arg
110                 print ("Using stack: "+yaml)
111         elif opt in ("--key"):
112                 key = arg
113                 print ("Using key: "+key)
114         elif opt in ("--flavor"):
115                 flavor = arg
116                 print ("Using flavor: "+flavor)
117         elif opt in ("--image"):
118                 image = arg
119                 print ("Using image: "+image)
120         elif opt in ("--image_file"):
121                 image_file = arg
122                 print ("Using qcow2 file: "+image_file)
123         elif opt in ("--dataplane_network"):
124                 dataplane_network = arg
125                 print ("Using dataplane network: "+ dataplane_network)
126         elif opt in ("--subnet"):
127                 subnet = arg
128                 print ("Using dataplane subnet: "+ subnet)
129         elif opt in ("--subnet_cidr"):
130                 subnet_cidr = arg
131                 print ("Using dataplane subnet: "+ subnet_cidr)
132         elif opt in ("--internal_network"):
133                 internal_network = arg
134                 print ("Using controle plane network: "+ internal_network)
135         elif opt in ("--floating_network"):
136                 floating_network = arg
137                 print ("Using floating ip network: "+ floating_network)
138         elif opt in ("--log"):
139                 loglevel = arg
140                 print ("Log level: "+ loglevel)
141
142
143 # create formatters
144 screen_formatter = logging.Formatter("%(message)s")
145 file_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
146
147 # get a top-level logger,
148 # set its log level,
149 # BUT PREVENT IT from propagating messages to the root logger
150 #
151 log = logging.getLogger()
152 numeric_level = getattr(logging, loglevel.upper(), None)
153 if not isinstance(numeric_level, int):
154     raise ValueError('Invalid log level: %s' % loglevel)
155 log.setLevel(numeric_level)
156 log.propagate = 0
157
158 # create a console handler
159 # and set its log level to the command-line option 
160
161 console_handler = logging.StreamHandler(sys.stdout)
162 console_handler.setLevel(logging.INFO)
163 console_handler.setFormatter(screen_formatter)
164
165 # create a file handler
166 # and set its log level to DEBUG
167 #
168 log_file = 'CREATE' +stack +'.log'
169 file_handler = logging.handlers.RotatingFileHandler(log_file, backupCount=10)
170 #file_handler = log.handlers.TimedRotatingFileHandler(log_file, 'D', 1, 5)
171 file_handler.setLevel(numeric_level)
172 file_handler.setFormatter(file_formatter)
173
174 # add handlers to the logger
175 #
176 log.addHandler(file_handler)
177 log.addHandler(console_handler)
178
179 # Check if log exists and should therefore be rolled
180 needRoll = os.path.isfile(log_file)
181
182
183 # This is a stale log, so roll it
184 if needRoll:    
185     # Add timestamp
186     log.debug('\n---------\nLog closed on %s.\n---------\n' % time.asctime())
187
188     # Roll over on application start
189     log.handlers[0].doRollover()
190
191 # Add timestamp
192 log.debug('\n---------\nLog started on %s.\n---------\n' % time.asctime())
193
194 log.debug("createrapid.py version: "+version)
195 # Checking if the control network already exists, if not, stop the script
196 log.debug("Checking control plane network: "+internal_network)
197 cmd = 'openstack network show '+internal_network
198 log.debug (cmd)
199 cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4'
200 NetworkExist = subprocess.check_output(cmd , shell=True).strip()
201 if NetworkExist == 'ACTIVE':
202         log.info("Control plane network ("+internal_network+")  already active")
203 else:
204         log.exception("Control plane network " + internal_network + " not existing")
205         raise Exception("Control plane network " + internal_network + " not existing")
206
207 # Checking if the floating ip network already exists, if not, stop the script
208 log.debug("Checking floating ip network: "+floating_network)
209 cmd = 'openstack network show '+floating_network
210 log.debug (cmd)
211 cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4'
212 NetworkExist = subprocess.check_output(cmd , shell=True).strip()
213 if NetworkExist == 'ACTIVE':
214         log.info("Floating ip network ("+floating_network+")  already active")
215 else:
216         log.exception("Floating ip network " + floating_network + " not existing")
217         raise Exception("Floating ip network " + floating_network + " not existing")
218
219 # Checking if the image already exists, if not create it
220 log.debug("Checking image: "+image)
221 cmd = 'openstack image show '+image
222 log.debug(cmd)
223 cmd = cmd +' |grep "status " | tr -s " " | cut -d" " -f 4'
224 ImageExist = subprocess.check_output(cmd , shell=True).strip()
225 if ImageExist == 'active':
226         log.info("Image ("+image+") already available")
227 else:
228         log.info('Creating image ...')
229         cmd = 'openstack image create --disk-format qcow2 --container-format bare --public --file ./'+image_file+ ' ' +image
230         log.debug(cmd)
231         cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4'
232         ImageExist = subprocess.check_output(cmd , shell=True).strip()
233         if ImageExist == 'active':
234                 log.info('Image created and active')
235                 cmd = 'openstack image set --property hw_vif_multiqueue_enabled="true" ' +image
236 #               subprocess.check_call(cmd , shell=True)
237         else :
238                 log.exception("Failed to create image")
239                 raise Exception("Failed to create image")
240
241 # Checking if the key already exists, if not create it
242 log.debug("Checking key: "+key)
243 cmd = 'openstack keypair show '+key
244 log.debug (cmd)
245 cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4'
246 KeyExist = subprocess.check_output(cmd , shell=True).strip()
247 if KeyExist == key:
248         log.info("Key ("+key+") already installed")
249 else:
250         log.info('Creating key ...')
251         cmd = 'openstack keypair create '+ key + '>' +key+'.pem'
252         log.debug(cmd)
253         subprocess.check_call(cmd , shell=True)
254         cmd = 'chmod 600 ' +key+'.pem'
255         subprocess.check_call(cmd , shell=True)
256         cmd = 'openstack keypair show '+key
257         log.debug(cmd)
258         cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4'
259         KeyExist = subprocess.check_output(cmd , shell=True).strip()
260         if KeyExist == key:
261                 log.info("Key created")
262         else :
263                 log.exception("Failed to create key: " + key)
264                 raise Exception("Failed to create key: " + key)
265
266 # Checking if the flavor already exists, if not create it
267 log.debug("Checking flavor: "+flavor)
268 cmd = 'openstack flavor show '+flavor
269 log.debug (cmd)
270 cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4'
271 FlavorExist = subprocess.check_output(cmd , shell=True).strip()
272 if FlavorExist == flavor:
273         log.info("Flavor ("+flavor+") already installed")
274 else:
275         log.info('Creating flavor ...')
276         cmd = 'openstack flavor create '+flavor+' --ram 8192 --disk 20 --vcpus 4'
277         log.debug(cmd)
278         cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4'
279         FlavorExist = subprocess.check_output(cmd , shell=True).strip()
280         if FlavorExist == flavor:
281                 cmd = 'openstack flavor set '+ flavor +' --property hw:mem_page_size="large" --property hw:cpu_policy="dedicated" --property hw:cpu_threads_policy="isolate"'
282                 log.debug(cmd)
283                 subprocess.check_call(cmd , shell=True)
284                 log.info("Flavor created")
285         else :
286                 log.exception("Failed to create flavor: " + flavor)
287                 raise Exception("Failed to create flavor: " + flavor)
288
289 # Checking if the dataplane network already exists, if not create it
290 log.debug("Checking dataplane network: "+dataplane_network)
291 cmd = 'openstack network show '+dataplane_network
292 log.debug (cmd)
293 cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4'
294 NetworkExist = subprocess.check_output(cmd , shell=True).strip()
295 if NetworkExist == 'ACTIVE':
296         log.info("Dataplane network ("+dataplane_network+") already active")
297 else:
298         log.info('Creating dataplane network ...')
299         cmd = 'openstack network create '+dataplane_network
300         log.debug(cmd)
301         cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4'
302         NetworkExist = subprocess.check_output(cmd , shell=True).strip()
303         if NetworkExist == 'ACTIVE':
304                 log.info("Dataplane network created")
305         else :
306                 log.exception("Failed to create dataplane network: " + dataplane_network)
307                 raise Exception("Failed to create dataplane network: " + dataplane_network)
308
309 # Checking if the dataplane subnet already exists, if not create it
310 log.debug("Checking subnet: "+subnet)
311 cmd = 'openstack subnet show '+ subnet
312 log.debug (cmd)
313 cmd = cmd +' |grep "name " | tr -s " " | cut -d"|" -f 3'
314 SubnetExist = subprocess.check_output(cmd , shell=True).strip()
315 if SubnetExist == subnet:
316         log.info("Subnet (" +subnet+ ") already exists")
317 else:
318         log.info('Creating subnet ...')
319         cmd = 'openstack subnet create --network ' + dataplane_network + ' --subnet-range ' + subnet_cidr +' --gateway none ' + subnet
320         log.debug(cmd)
321         cmd = cmd + ' |grep "name " | tr -s " " | cut -d"|" -f 3'
322         SubnetExist = subprocess.check_output(cmd , shell=True).strip()
323         if SubnetExist == subnet:
324                 log.info("Subnet created")
325         else :
326                 log.exception("Failed to create subnet: " + subnet)
327                 raise Exception("Failed to create subnet: " + subnet)
328
329 # Checking if the stack already exists, if not create it
330 log.debug("Checking Stack: "+stack)
331 cmd = 'openstack stack show '+stack
332 log.debug (cmd)
333 cmd = cmd+' |grep "stack_status " | tr -s " " | cut -d"|" -f 3'
334 StackRunning = subprocess.check_output(cmd , shell=True).strip()
335 if StackRunning == '':
336         log.info('Creating Stack ...')
337         cmd = 'openstack stack create -t '+ yaml +  ' --parameter flavor="'+flavor  +'" --parameter key="'+ key + '" --parameter image="'+image  + '" --parameter dataplane_network="'+dataplane_network+ '" --parameter internal_network="'+internal_network+'" --parameter floating_network="'+floating_network+'" --wait '+stack 
338         log.debug(cmd)
339         cmd = cmd + ' |grep "stack_status " | tr -s " " | cut -d"|" -f 3'
340         StackRunning = subprocess.check_output(cmd , shell=True).strip()
341 if StackRunning != 'CREATE_COMPLETE':
342         log.exception("Failed to create stack")
343         raise Exception("Failed to create stack")
344
345 # Obtaining IP & MAC addresses for the VMs created in the stack
346 log.info("Stack ("+stack+") running")
347 cmd='openstack stack show -f yaml -c outputs ' + stack
348 log.debug(cmd)
349 output = subprocess.check_output(cmd , shell=True).strip()
350 matchObj = re.search('.*total_number_of_VMs.*?([0-9])', output, re.DOTALL)
351 total_number_of_VMs = matchObj.group(1)
352 vmDPIP =[]
353 vmAdminIP =[]
354 vmDPmac =[]
355 config = ConfigParser.RawConfigParser()
356 for vm in range(1, int(total_number_of_VMs)+1):
357         searchString = '.*vm%d_dataplane_ip.*?([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)' % vm
358         matchObj = re.search(searchString, output, re.DOTALL)
359         vmDPIP.append(matchObj.group(1))
360         searchString = '.*vm%d_public_ip.*?([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)' % vm
361         matchObj = re.search(searchString, output, re.DOTALL)
362         vmAdminIP.append(matchObj.group(1))
363         searchString = '.*vm%d_dataplane_mac.*?([a-fA-F0-9:]{17})' % vm
364         matchObj = re.search(searchString, output, re.DOTALL)
365         vmDPmac.append(matchObj.group(1))
366         log.info('VM%d: (admin IP: %s), (dataplane IP: %s), (dataplane MAC: %s)' % (vm,vmAdminIP[-1],vmDPIP[-1],vmDPmac[-1]))
367         config.add_section('VM%d'%vm)
368         config.set('VM%d'%vm, 'admin_ip', vmAdminIP[-1])
369         config.set('VM%d'%vm, 'dp_ip', vmDPIP[-1])
370         config.set('VM%d'%vm, 'dp_mac', vmDPmac[-1])
371 config.add_section('OpenStack')
372 config.set('OpenStack', 'stack', stack)
373 config.set('OpenStack', 'yaml', yaml)
374 config.set('OpenStack', 'key', key)
375 config.set('OpenStack', 'flavor', flavor)
376 config.set('OpenStack', 'image', image)
377 config.set('OpenStack', 'image_file', image_file)
378 config.set('OpenStack', 'dataplane_network', dataplane_network)
379 config.set('OpenStack', 'subnet', subnet)
380 config.set('OpenStack', 'subnet_cidr', subnet_cidr)
381 config.set('OpenStack', 'internal_network', internal_network)
382 config.set('OpenStack', 'floating_network', floating_network)
383 config.add_section('rapid')
384 config.set('rapid', 'loglevel', loglevel)
385 config.set('rapid', 'version', version)
386 config.set('rapid', 'total_number_of_VMs', total_number_of_VMs)
387 config.set('DEFAULT', 'admin_ip', 'none')
388 # Writing the environment file
389 with open(stack+'.env', 'wb') as envfile:
390     config.write(envfile)
391