Remove default section in the createrapid
[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.09.03"
35 stack = "rapidTestEnv" #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 admin_network="admin_internal_net"
45 loglevel="DEBUG" # sets log level for writing to file
46 runtime=10 # time in seconds for 1 test run
47
48 def usage():
49         print("usage: rapid       [--version] [-v]")
50         print("                   [--stack STACK_NAME]")
51         print("                   [--yaml YAML_FILE]")
52         print("                   [--key KEY_NAME]")
53         print("                   [--flavor FLAVOR_NAME]")
54         print("                   [--image IMAGE_NAME]")
55         print("                   [--image_file IMAGE_FILE]")
56         print("                   [--dataplane_network DP_NETWORK]")
57         print("                   [--admin_network ADMIN_NETWORK]")
58         print("                   [--log DEBUG|INFO|WARNING|ERROR|CRITICAL")
59         print("                   [-h] [--help]")
60         print("")
61         print("Command-line interface to RAPID")
62         print("")
63         print("optional arguments:")
64         print("  -v,  --version                 Show program's version number and exit")
65         print("  --stack STACK_NAME             Specify a name for the heat stack. Default is rapidTestEnv.")
66         print("  --yaml YAML_FILE               Specify the yaml file to be used. Default is rapid.yaml.")
67         print("  --key KEY_NAME                 Specify the key to be used. Default is prox.")
68         print("  --flavor FLAVOR_NAME           Specify the flavor to be used. Default is prox_flavor.")
69         print("  --image IMAGE_NAME             Specify the image to be used. Default is rapidVM.")
70         print("  --image_file IMAGE_FILE        Specify the image qcow2 file to be used. Default is rapidVM.qcow2.")
71         print("  --dataplane_network NETWORK    Specify the network name to be used for the dataplane. Default is dataplane-network.")
72         print("  --admin_network NETWORK        Specify the network name to be used for the control plane. Default is admin-network.")
73         print("  --log                          Specify logging level for log file output, screen output level is hard coded")
74         print("  -h, --help                     Show help message and exit.")
75         print("")
76         print("To delete the rapid stack, type the following command")
77         print("   openstack stack delete --yes --wait rapidTestEnv")
78         print("Note that rapidTestEnv is the default stack name. Replace with STACK_NAME if needed")
79
80 try:
81         opts, args = getopt.getopt(sys.argv[1:], "vh", ["version","help", "yaml=","stack=","key=","flavor=","image=","dataplane_network=","admin_network=","log="])
82 except getopt.GetoptError as err:
83         print("===========================================")
84         print(str(err))
85         print("===========================================")
86         usage()
87         sys.exit(2)
88 if args:
89         usage()
90         sys.exit(2)
91 for opt, arg in opts:
92         if opt in ("-h", "--help"):
93                 usage()
94                 sys.exit()
95         if opt in ("-v", "--version"):
96                 print("Rapid Automated Performance Indication for Dataplane "+version)
97                 sys.exit()
98         if opt in ("--stack"):
99                 stack = arg
100                 print ("Using '"+stack+"' as name for the stack")
101         elif opt in ("--yaml"):
102                 yaml = arg
103                 print ("Using stack: "+yaml)
104         elif opt in ("--key"):
105                 key = arg
106                 print ("Using key: "+key)
107         elif opt in ("--flavor"):
108                 flavor = arg
109                 print ("Using flavor: "+flavor)
110         elif opt in ("--image"):
111                 image = arg
112                 print ("Using image: "+image)
113         elif opt in ("--image_file"):
114                 image_file = arg
115                 print ("Using qcow2 file: "+image_file)
116         elif opt in ("--dataplane_network"):
117                 dataplane_network = arg
118                 print ("Using dataplane network: "+ dataplane_network)
119         elif opt in ("--admin_network"):
120                 admin_network = arg
121                 print ("Using controle plane network: "+ admin_network)
122         elif opt in ("--log"):
123                 loglevel = arg
124                 print ("Log level: "+ loglevel)
125
126
127 # create formatters
128 screen_formatter = logging.Formatter("%(message)s")
129 file_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
130
131 # get a top-level logger,
132 # set its log level,
133 # BUT PREVENT IT from propagating messages to the root logger
134 #
135 log = logging.getLogger()
136 numeric_level = getattr(logging, loglevel.upper(), None)
137 if not isinstance(numeric_level, int):
138     raise ValueError('Invalid log level: %s' % loglevel)
139 log.setLevel(numeric_level)
140 log.propagate = 0
141
142 # create a console handler
143 # and set its log level to the command-line option
144 #
145 console_handler = logging.StreamHandler(sys.stdout)
146 console_handler.setLevel(logging.INFO)
147 console_handler.setFormatter(screen_formatter)
148
149 # create a file handler
150 # and set its log level to DEBUG
151 #
152 log_file = 'CREATE' +stack +'.log'
153 file_handler = logging.handlers.RotatingFileHandler(log_file, backupCount=10)
154 #file_handler = log.handlers.TimedRotatingFileHandler(log_file, 'D', 1, 5)
155 file_handler.setLevel(numeric_level)
156 file_handler.setFormatter(file_formatter)
157
158 # add handlers to the logger
159 #
160 log.addHandler(file_handler)
161 log.addHandler(console_handler)
162
163 # Check if log exists and should therefore be rolled
164 needRoll = os.path.isfile(log_file)
165
166
167 # This is a stale log, so roll it
168 if needRoll:
169     # Add timestamp
170     log.debug('\n---------\nLog closed on %s.\n---------\n' % time.asctime())
171
172     # Roll over on application start
173     log.handlers[0].doRollover()
174
175 # Add timestamp
176 log.debug('\n---------\nLog started on %s.\n---------\n' % time.asctime())
177
178 log.debug("createrapid.py version: "+version)
179 # Checking if the control network already exists, if not, stop the script
180 log.debug("Checking control plane network: "+admin_network)
181 cmd = 'openstack network show '+admin_network
182 log.debug (cmd)
183 cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4'
184 NetworkExist = subprocess.check_output(cmd , shell=True).strip()
185 if NetworkExist == 'ACTIVE':
186         log.info("Control plane network ("+admin_network+")  already active")
187 else:
188         log.exception("Control plane network " + admin_network + " not existing")
189         raise Exception("Control plane network " + admin_network + " not existing")
190
191 # Checking if the image already exists, if not create it
192 log.debug("Checking image: "+image)
193 cmd = 'openstack image show '+image
194 log.debug(cmd)
195 cmd = cmd +' |grep "status " | tr -s " " | cut -d" " -f 4'
196 ImageExist = subprocess.check_output(cmd , shell=True).strip()
197 if ImageExist == 'active':
198         log.info("Image ("+image+") already available")
199 else:
200         log.info('Creating image ...')
201         cmd = 'openstack image create --disk-format qcow2 --container-format bare --public --file ./'+image_file+ ' ' +image
202         log.debug(cmd)
203         cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4'
204         ImageExist = subprocess.check_output(cmd , shell=True).strip()
205         if ImageExist == 'active':
206                 log.info('Image created and active')
207                 cmd = 'openstack image set --property hw_vif_multiqueue_enabled="true" ' +image
208 #               subprocess.check_call(cmd , shell=True)
209         else :
210                 log.exception("Failed to create image")
211                 raise Exception("Failed to create image")
212
213 # Checking if the key already exists, if not create it
214 log.debug("Checking key: "+key)
215 cmd = 'openstack keypair show '+key
216 log.debug (cmd)
217 cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4'
218 KeyExist = subprocess.check_output(cmd , shell=True).strip()
219 if KeyExist == key:
220         log.info("Key ("+key+") already installed")
221 else:
222         log.info('Creating key ...')
223         cmd = 'openstack keypair create '+ key + '>' +key+'.pem'
224         log.debug(cmd)
225         subprocess.check_call(cmd , shell=True)
226         cmd = 'chmod 600 ' +key+'.pem'
227         subprocess.check_call(cmd , shell=True)
228         cmd = 'openstack keypair show '+key
229         log.debug(cmd)
230         cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4'
231         KeyExist = subprocess.check_output(cmd , shell=True).strip()
232         if KeyExist == key:
233                 log.info("Key created")
234         else :
235                 log.exception("Failed to create key: " + key)
236                 raise Exception("Failed to create key: " + key)
237
238 # Checking if the flavor already exists, if not create it
239 log.debug("Checking flavor: "+flavor)
240 cmd = 'openstack flavor show '+flavor
241 log.debug (cmd)
242 cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4'
243 FlavorExist = subprocess.check_output(cmd , shell=True).strip()
244 if FlavorExist == flavor:
245         log.info("Flavor ("+flavor+") already installed")
246 else:
247         log.info('Creating flavor ...')
248         cmd = 'openstack flavor create '+flavor+' --ram 8192 --disk 20 --vcpus 4'
249         log.debug(cmd)
250         cmd = cmd + ' |grep "name " | tr -s " " | cut -d" " -f 4'
251         FlavorExist = subprocess.check_output(cmd , shell=True).strip()
252         if FlavorExist == flavor:
253                 cmd = 'openstack flavor set '+ flavor +' --property hw:mem_page_size="large" --property hw:cpu_policy="dedicated" --property hw:cpu_threads_policy="isolate"'
254                 log.debug(cmd)
255                 subprocess.check_call(cmd , shell=True)
256                 log.info("Flavor created")
257         else :
258                 log.exception("Failed to create flavor: " + flavor)
259                 raise Exception("Failed to create flavor: " + flavor)
260
261 # Checking if the dataplane network already exists, if not create it
262 log.debug("Checking dataplane network: "+dataplane_network)
263 cmd = 'openstack network show '+dataplane_network
264 log.debug (cmd)
265 cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4'
266 NetworkExist = subprocess.check_output(cmd , shell=True).strip()
267 if NetworkExist == 'ACTIVE':
268         log.info("Dataplane network ("+dataplane_network+") already active")
269 else:
270         log.info('Creating dataplane network ...')
271         cmd = 'openstack network create '+dataplane_network
272         log.debug(cmd)
273         cmd = cmd + ' |grep "status " | tr -s " " | cut -d" " -f 4'
274         NetworkExist = subprocess.check_output(cmd , shell=True).strip()
275         if NetworkExist == 'ACTIVE':
276                 log.info("Dataplane network created")
277         else :
278                 log.exception("Failed to create dataplane network: " + dataplane_network)
279                 raise Exception("Failed to create dataplane network: " + dataplane_network)
280
281 # Checking if the dataplane subnet already exists, if not create it
282 log.debug("Checking subnet: "+subnet)
283 cmd = 'openstack subnet show '+ subnet
284 log.debug (cmd)
285 cmd = cmd +' |grep "name " | tr -s " " | cut -d"|" -f 3'
286 SubnetExist = subprocess.check_output(cmd , shell=True).strip()
287 if SubnetExist == subnet:
288         log.info("Subnet (" +subnet+ ") already exists")
289 else:
290         log.info('Creating subnet ...')
291         cmd = 'openstack subnet create --network ' + dataplane_network + ' --subnet-range ' + subnet_cidr +' --gateway none ' + subnet
292         log.debug(cmd)
293         cmd = cmd + ' |grep "name " | tr -s " " | cut -d"|" -f 3'
294         SubnetExist = subprocess.check_output(cmd , shell=True).strip()
295         if SubnetExist == subnet:
296                 log.info("Subnet created")
297         else :
298                 log.exception("Failed to create subnet: " + subnet)
299                 raise Exception("Failed to create subnet: " + subnet)
300
301 # Checking if the stack already exists, if not create it
302 log.debug("Checking Stack: "+stack)
303 cmd = 'openstack stack show '+stack
304 log.debug (cmd)
305 cmd = cmd+' |grep "stack_status " | tr -s " " | cut -d"|" -f 3'
306 StackRunning = subprocess.check_output(cmd , shell=True).strip()
307 if StackRunning == '':
308         log.info('Creating Stack ...')
309         cmd = 'openstack stack create -t '+ yaml +  ' --parameter flavor="'+flavor  +'" --parameter key="'+ key + '" --parameter image="'+image  + '" --parameter dataplane_network="'+dataplane_network+ '" --parameter admin_network="'+admin_network+'" --wait '+stack
310         log.debug(cmd)
311         cmd = cmd + ' |grep "stack_status " | tr -s " " | cut -d"|" -f 3'
312         StackRunning = subprocess.check_output(cmd , shell=True).strip()
313 if StackRunning != 'CREATE_COMPLETE':
314         log.exception("Failed to create stack")
315         raise Exception("Failed to create stack")
316
317 # Obtaining IP & MAC addresses for the VMs created in the stack
318 log.info("Stack ("+stack+") running")
319 cmd='openstack stack show -f yaml -c outputs ' + stack
320 log.debug(cmd)
321 output = subprocess.check_output(cmd , shell=True).strip()
322 matchObj = re.search('.*gen_dataplane_ip.*?([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)', output, re.DOTALL)
323 genDPIP = matchObj.group(1)
324 matchObj = re.search('.*gen_public_ip.*?([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)', output, re.DOTALL)
325 genAdminIP = matchObj.group(1)
326 matchObj = re.search('.*gen_dataplane_mac.*?([a-fA-F0-9:]{17})', output, re.DOTALL)
327 genDPmac = matchObj.group(1)
328 matchObj = re.search('.*sut_dataplane_ip.*?([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)', output, re.DOTALL)
329 sutDPIP = matchObj.group(1)
330 matchObj = re.search('.*sut_public_ip.*?([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)', output, re.DOTALL)
331 sutAdminIP = matchObj.group(1)
332 matchObj = re.search('.*sut_dataplane_mac.*?([a-fA-F0-9:]{17})', output, re.DOTALL)
333 sutDPmac = matchObj.group(1)
334 log.info('Generator: (admin IP: '+ genAdminIP + '), (dataplane IP: ' + genDPIP+'), (dataplane MAC: ' +genDPmac+')')
335 log.info('SUT:       (admin IP: '+ sutAdminIP + '), (dataplane IP: ' + sutDPIP+'), (dataplane MAC: ' +sutDPmac+')')
336 config = ConfigParser.RawConfigParser()
337 config.add_section('Generator')
338 config.set('Generator', 'admin_ip', genAdminIP)
339 config.set('Generator', 'dp_ip', genDPIP)
340 config.set('Generator', 'dp_mac', genDPmac)
341 config.add_section('SUT')
342 config.set('SUT', 'admin_ip', sutAdminIP)
343 config.set('SUT', 'dp_ip', sutDPIP)
344 config.set('SUT', 'dp_mac', sutDPmac)
345 config.add_section('OpenStack')
346 config.set('OpenStack', 'stack', stack)
347 config.set('OpenStack', 'yaml', yaml)
348 config.set('OpenStack', 'key', key)
349 config.set('OpenStack', 'flavor', flavor)
350 config.set('OpenStack', 'image', image)
351 config.set('OpenStack', 'image_file', image_file)
352 config.set('OpenStack', 'dataplane_network', dataplane_network)
353 config.set('OpenStack', 'subnet', subnet)
354 config.set('OpenStack', 'subnet_cidr', subnet_cidr)
355 config.set('OpenStack', 'admin_network', admin_network)
356 config.add_section('rapid')
357 config.set('rapid', 'loglevel', loglevel)
358 config.set('rapid', 'version', version)
359 config.set('DEFAULT', 'admin_ip', 'none')
360 # Writing our configuration file
361 with open(stack+'.cfg', 'wb') as configfile:
362     config.write(configfile)
363