3 #######################################################################
5 # Copyright (c) 2015 Orange
6 # valentin.boucher@orange.com
8 # All rights reserved. This program and the accompanying materials
9 # are made available under the terms of the Apache License, Version 2.0
10 # which accompanies this distribution, and is available at
11 # http://www.apache.org/licenses/LICENSE-2.0
12 ########################################################################
24 import keystoneclient.v2_0.client as ksclient
25 import glanceclient.client as glclient
26 import novaclient.client as nvclient
27 from neutronclient.v2_0 import client as ntclient
32 import functest.utils.functest_logger as ft_logger
33 import functest.utils.functest_utils as functest_utils
34 import functest.utils.openstack_utils as os_utils
37 pp = pprint.PrettyPrinter(indent=4)
40 parser = argparse.ArgumentParser()
41 parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
42 parser.add_argument("-r", "--report",
43 help="Create json result file",
45 parser.add_argument("-n", "--noclean",
46 help="Don't clean the created resources for this test.",
48 args = parser.parse_args()
50 """ logging configuration """
51 logger = ft_logger.Logger("vIMS").getLogger()
53 REPO_PATH = os.environ['repos_dir'] + '/functest/'
54 if not os.path.exists(REPO_PATH):
55 logger.error("Functest repository directory not found '%s'" % REPO_PATH)
58 with open(os.environ["CONFIG_FUNCTEST_YAML"]) as f:
59 functest_yaml = yaml.safe_load(f)
63 VIMS_DIR = (REPO_PATH +
64 functest_yaml.get("general").get("directories").get("dir_vIMS"))
65 VIMS_DATA_DIR = functest_yaml.get("general").get(
66 "directories").get("dir_vIMS_data") + "/"
67 VIMS_TEST_DIR = functest_yaml.get("general").get(
68 "directories").get("dir_repo_vims_test") + "/"
69 DB_URL = functest_yaml.get("results").get("test_db_url")
71 TENANT_NAME = functest_yaml.get("vIMS").get("general").get("tenant_name")
72 TENANT_DESCRIPTION = functest_yaml.get("vIMS").get(
73 "general").get("tenant_description")
74 IMAGES = functest_yaml.get("vIMS").get("general").get("images")
76 CFY_MANAGER_BLUEPRINT = functest_yaml.get(
77 "vIMS").get("cloudify").get("blueprint")
78 CFY_MANAGER_REQUIERMENTS = functest_yaml.get(
79 "vIMS").get("cloudify").get("requierments")
80 CFY_INPUTS = functest_yaml.get("vIMS").get("cloudify").get("inputs")
82 CW_BLUEPRINT = functest_yaml.get("vIMS").get("clearwater").get("blueprint")
83 CW_DEPLOYMENT_NAME = functest_yaml.get("vIMS").get(
84 "clearwater").get("deployment-name")
85 CW_INPUTS = functest_yaml.get("vIMS").get("clearwater").get("inputs")
86 CW_REQUIERMENTS = functest_yaml.get("vIMS").get(
87 "clearwater").get("requierments")
89 CFY_DEPLOYMENT_DURATION = 0
90 CW_DEPLOYMENT_DURATION = 0
92 RESULTS = {'orchestrator': {'duration': 0, 'result': ''},
93 'vIMS': {'duration': 0, 'result': ''},
94 'sig_test': {'duration': 0, 'result': ''}}
97 def download_and_add_image_on_glance(glance, image_name, image_url):
98 dest_path = VIMS_DATA_DIR + "tmp/"
99 if not os.path.exists(dest_path):
100 os.makedirs(dest_path)
101 file_name = image_url.rsplit('/')[-1]
102 if not functest_utils.download_url(image_url, dest_path):
103 logger.error("Failed to download image %s" % file_name)
106 image = os_utils.create_glance_image(
107 glance, image_name, dest_path + file_name)
109 logger.error("Failed to upload image on glance")
115 def step_failure(step_name, error_msg):
116 logger.error(error_msg)
117 set_result(step_name, 0, error_msg)
119 if step_name == "sig_test":
125 def push_results(status):
127 logger.debug("Pushing results to DB....")
129 scenario = functest_utils.get_scenario(logger)
130 version = functest_utils.get_version(logger)
131 pod_name = functest_utils.get_pod_name(logger)
132 build_tag = functest_utils.get_build_tag(logger)
134 functest_utils.push_results_to_db(db_url=DB_URL,
137 logger=logger, pod_name=pod_name,
145 def set_result(step_name, duration=0, result=""):
146 RESULTS[step_name] = {'duration': duration, 'result': result}
149 def test_clearwater():
150 script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
151 script += "cd " + VIMS_DATA_DIR + "; "
152 script += "cfy status | grep -Eo \"([0-9]{1,3}\.){3}[0-9]{1,3}\""
153 cmd = "/bin/bash -c '" + script + "'"
156 logger.debug("Trying to get clearwater manager IP ... ")
157 mgr_ip = os.popen(cmd).read()
158 mgr_ip = mgr_ip.splitlines()[0]
160 step_failure("sig_test", "Unable to retrieve the IP of the "
161 "cloudify manager server !")
163 api_url = "http://" + mgr_ip + "/api/v2"
164 dep_outputs = requests.get(api_url + "/deployments/" +
165 CW_DEPLOYMENT_NAME + "/outputs")
166 dns_ip = dep_outputs.json()['outputs']['dns_ip']
167 ellis_ip = dep_outputs.json()['outputs']['ellis_ip']
169 ellis_url = "http://" + ellis_ip + "/"
170 url = ellis_url + "accounts"
172 params = {"password": "functest",
173 "full_name": "opnfv functest user",
174 "email": "functest@opnfv.fr",
175 "signup_code": "secret"}
177 rq = requests.post(url, data=params)
179 while rq.status_code != 201 and i > 0:
180 rq = requests.post(url, data=params)
184 if rq.status_code == 201:
185 url = ellis_url + "session"
186 rq = requests.post(url, data=params)
189 url = ellis_url + "accounts/" + params['email'] + "/numbers"
191 rq = requests.post(url, cookies=cookies)
193 while rq.status_code != 200 and i > 0:
194 rq = requests.post(url, cookies=cookies)
198 if rq.status_code != 200:
199 step_failure("sig_test", "Unable to create a number: %s"
200 % rq.json()['reason'])
202 start_time_ts = time.time()
203 end_time_ts = start_time_ts
204 logger.info("vIMS functional test Start Time:'%s'" % (
205 datetime.datetime.fromtimestamp(start_time_ts).strftime(
206 '%Y-%m-%d %H:%M:%S')))
207 nameservers = functest_utils.get_resolvconf_ns()
209 for ns in nameservers:
210 resolvconf += "\nnameserver " + ns
213 script = ('echo -e "nameserver ' + dns_ip + resolvconf +
214 '" > /etc/resolv.conf; ')
215 script += 'source /etc/profile.d/rvm.sh; '
216 script += 'cd ' + VIMS_TEST_DIR + '; '
217 script += ('rake test[' + CW_INPUTS["public_domain"] +
218 '] SIGNUP_CODE="secret"')
220 cmd = "/bin/bash -c '" + script + "'"
221 output_file = "output.txt"
222 f = open(output_file, 'w+')
223 subprocess.call(cmd, shell=True, stdout=f,
224 stderr=subprocess.STDOUT)
226 end_time_ts = time.time()
227 duration = round(end_time_ts - start_time_ts, 1)
228 logger.info("vIMS functional test duration:'%s'" % duration)
229 f = open(output_file, 'r')
231 if result != "" and logger:
234 vims_test_result = ""
236 logger.debug("Trying to load test results")
237 with open(VIMS_TEST_DIR + "temp.json") as f:
238 vims_test_result = json.load(f)
241 logger.error("Unable to retrieve test results")
243 set_result("sig_test", duration, vims_test_result)
245 # success criteria for vIMS (for Brahmaputra)
246 # - orchestrator deployed
250 if (RESULTS['orchestrator']['duration'] > 0 and
251 RESULTS['vIMS']['duration'] > 0):
254 logger.error("Unable to set test status")
258 os.remove(VIMS_TEST_DIR + "temp.json")
260 logger.error("Deleting file failed")
265 # ############### GENERAL INITIALISATION ################
267 if not os.path.exists(VIMS_DATA_DIR):
268 os.makedirs(VIMS_DATA_DIR)
270 ks_creds = os_utils.get_credentials("keystone")
271 nv_creds = os_utils.get_credentials("nova")
272 nt_creds = os_utils.get_credentials("neutron")
274 logger.info("Prepare OpenStack plateform (create tenant and user)")
275 keystone = ksclient.Client(**ks_creds)
277 user_id = os_utils.get_user_id(keystone, ks_creds['username'])
279 step_failure("init", "Error : Failed to get id of " +
280 ks_creds['username'])
282 tenant_id = os_utils.create_tenant(
283 keystone, TENANT_NAME, TENANT_DESCRIPTION)
285 step_failure("init", "Error : Failed to create " +
286 TENANT_NAME + " tenant")
288 roles_name = ["admin", "Admin"]
290 for role_name in roles_name:
292 role_id = os_utils.get_role_id(keystone, role_name)
295 logger.error("Error : Failed to get id for %s role" % role_name)
297 if not os_utils.add_role_user(keystone, user_id, role_id, tenant_id):
298 logger.error("Error : Failed to add %s on tenant" %
299 ks_creds['username'])
301 user_id = os_utils.create_user(
302 keystone, TENANT_NAME, TENANT_NAME, None, tenant_id)
304 logger.error("Error : Failed to create %s user" % TENANT_NAME)
306 logger.info("Update OpenStack creds informations")
308 "username": TENANT_NAME,
309 "password": TENANT_NAME,
310 "tenant_name": TENANT_NAME,
314 "tenant_name": TENANT_NAME,
318 "project_id": TENANT_NAME,
321 logger.info("Upload some OS images if it doesn't exist")
322 glance_endpoint = keystone.service_catalog.url_for(
323 service_type='image', endpoint_type='publicURL')
324 glance = glclient.Client(1, glance_endpoint, token=keystone.auth_token)
326 for img in IMAGES.keys():
327 image_name = IMAGES[img]['image_name']
328 image_url = IMAGES[img]['image_url']
330 image_id = os_utils.get_image_id(glance, image_name)
333 logger.info("""%s image doesn't exist on glance repository. Try
334 downloading this image and upload on glance !""" % image_name)
335 image_id = download_and_add_image_on_glance(
336 glance, image_name, image_url)
341 "Error : Failed to find or upload required OS "
342 "image for this deployment")
344 nova = nvclient.Client("2", **nv_creds)
346 logger.info("Update security group quota for this tenant")
347 neutron = ntclient.Client(**nt_creds)
348 if not os_utils.update_sg_quota(neutron, tenant_id, 50, 100):
351 "Failed to update security group quota for tenant " + TENANT_NAME)
353 logger.info("Update cinder quota for this tenant")
354 from cinderclient import client as cinderclient
356 creds_cinder = os_utils.get_credentials("cinder")
357 cinder_client = cinderclient.Client('1', creds_cinder['username'],
358 creds_cinder['api_key'],
359 creds_cinder['project_id'],
360 creds_cinder['auth_url'],
361 service_type="volume")
362 if not os_utils.update_cinder_quota(cinder_client, tenant_id, 20, 10, 150):
364 "init", "Failed to update cinder quota for tenant " + TENANT_NAME)
366 # ############### CLOUDIFY INITIALISATION ################
368 cfy = orchestrator(VIMS_DATA_DIR, CFY_INPUTS, logger)
370 cfy.set_credentials(username=ks_creds['username'], password=ks_creds[
371 'password'], tenant_name=ks_creds['tenant_name'],
372 auth_url=ks_creds['auth_url'])
374 logger.info("Collect flavor id for cloudify manager server")
375 nova = nvclient.Client("2", **nv_creds)
377 flavor_name = "m1.medium"
378 flavor_id = os_utils.get_flavor_id(nova, flavor_name)
379 for requirement in CFY_MANAGER_REQUIERMENTS:
380 if requirement == 'ram_min':
381 flavor_id = os_utils.get_flavor_id_by_ram_range(
382 nova, CFY_MANAGER_REQUIERMENTS['ram_min'], 8196)
386 "Failed to find %s flavor. "
387 "Try with ram range default requirement !" % flavor_name)
388 flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
391 step_failure("orchestrator",
392 "Failed to find required flavor for this deployment")
394 cfy.set_flavor_id(flavor_id)
396 image_name = "centos_7"
397 image_id = os_utils.get_image_id(glance, image_name)
398 for requirement in CFY_MANAGER_REQUIERMENTS:
399 if requirement == 'os_image':
400 image_id = os_utils.get_image_id(
401 glance, CFY_MANAGER_REQUIERMENTS['os_image'])
406 "Error : Failed to find required OS image for cloudify manager")
408 cfy.set_image_id(image_id)
410 ext_net = os_utils.get_external_net(neutron)
412 step_failure("orchestrator", "Failed to get external network")
414 cfy.set_external_network_name(ext_net)
416 ns = functest_utils.get_resolvconf_ns()
418 cfy.set_nameservers(ns)
420 logger.info("Prepare virtualenv for cloudify-cli")
421 cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
422 functest_utils.execute_command(cmd, logger)
424 cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
425 functest_utils.execute_command(cmd, logger)
427 cfy.download_manager_blueprint(
428 CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch'])
430 # ############### CLOUDIFY DEPLOYMENT ################
431 start_time_ts = time.time()
432 end_time_ts = start_time_ts
433 logger.info("Cloudify deployment Start Time:'%s'" % (
434 datetime.datetime.fromtimestamp(start_time_ts).strftime(
435 '%Y-%m-%d %H:%M:%S')))
437 error = cfy.deploy_manager()
439 step_failure("orchestrator", error)
441 end_time_ts = time.time()
442 duration = round(end_time_ts - start_time_ts, 1)
443 logger.info("Cloudify deployment duration:'%s'" % duration)
444 set_result("orchestrator", duration, "")
446 # ############### CLEARWATER INITIALISATION ################
448 cw = clearwater(CW_INPUTS, cfy, logger)
450 logger.info("Collect flavor id for all clearwater vm")
451 nova = nvclient.Client("2", **nv_creds)
453 flavor_name = "m1.small"
454 flavor_id = os_utils.get_flavor_id(nova, flavor_name)
455 for requirement in CW_REQUIERMENTS:
456 if requirement == 'ram_min':
457 flavor_id = os_utils.get_flavor_id_by_ram_range(
458 nova, CW_REQUIERMENTS['ram_min'], 8196)
462 "Failed to find %s flavor. Try with ram range "
463 "default requirement !" % flavor_name)
464 flavor_id = os_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
468 "vIMS", "Failed to find required flavor for this deployment")
470 cw.set_flavor_id(flavor_id)
472 image_name = "ubuntu_14.04"
473 image_id = os_utils.get_image_id(glance, image_name)
474 for requirement in CW_REQUIERMENTS:
475 if requirement == 'os_image':
476 image_id = os_utils.get_image_id(
477 glance, CW_REQUIERMENTS['os_image'])
482 "Error : Failed to find required OS image for cloudify manager")
484 cw.set_image_id(image_id)
486 ext_net = os_utils.get_external_net(neutron)
488 step_failure("vIMS", "Failed to get external network")
490 cw.set_external_network_name(ext_net)
492 # ############### CLEARWATER DEPLOYMENT ################
494 start_time_ts = time.time()
495 end_time_ts = start_time_ts
496 logger.info("vIMS VNF deployment Start Time:'%s'" % (
497 datetime.datetime.fromtimestamp(start_time_ts).strftime(
498 '%Y-%m-%d %H:%M:%S')))
500 error = cw.deploy_vnf(CW_BLUEPRINT)
502 step_failure("vIMS", error)
504 end_time_ts = time.time()
505 duration = round(end_time_ts - start_time_ts, 1)
506 logger.info("vIMS VNF deployment duration:'%s'" % duration)
507 set_result("vIMS", duration, "")
509 # ############### CLEARWATER TEST ################
513 # ########## CLEARWATER UNDEPLOYMENT ############
517 # ########### CLOUDIFY UNDEPLOYMENT #############
519 cfy.undeploy_manager()
521 # ############## GENERAL CLEANUP ################
525 ks_creds = os_utils.get_credentials("keystone")
527 keystone = ksclient.Client(**ks_creds)
529 logger.info("Removing %s tenant .." % CFY_INPUTS['keystone_tenant_name'])
530 tenant_id = os_utils.get_tenant_id(
531 keystone, CFY_INPUTS['keystone_tenant_name'])
533 logger.error("Error : Failed to get id of %s tenant" %
534 CFY_INPUTS['keystone_tenant_name'])
536 if not os_utils.delete_tenant(keystone, tenant_id):
537 logger.error("Error : Failed to remove %s tenant" %
538 CFY_INPUTS['keystone_tenant_name'])
540 logger.info("Removing %s user .." % CFY_INPUTS['keystone_username'])
541 user_id = os_utils.get_user_id(
542 keystone, CFY_INPUTS['keystone_username'])
544 logger.error("Error : Failed to get id of %s user" %
545 CFY_INPUTS['keystone_username'])
547 if not os_utils.delete_user(keystone, user_id):
548 logger.error("Error : Failed to remove %s user" %
549 CFY_INPUTS['keystone_username'])
552 if __name__ == '__main__':