bugfix: get admin role on joid installer
[functest.git] / testcases / vIMS / CI / vIMS.py
1 #!/usr/bin/python
2 # coding: utf8
3 #######################################################################
4 #
5 #   Copyright (c) 2015 Orange
6 #   valentin.boucher@orange.com
7 #
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 ########################################################################
13
14 import os
15 import time
16 import subprocess
17 import logging
18 import argparse
19 import yaml
20 import pprint
21 import sys
22 import shutil
23 import json
24 import datetime
25 from git import Repo
26 import keystoneclient.v2_0.client as ksclient
27 import glanceclient.client as glclient
28 import novaclient.client as nvclient
29 from neutronclient.v2_0 import client as ntclient
30
31 from orchestrator import *
32 from clearwater import *
33
34 import urllib
35 pp = pprint.PrettyPrinter(indent=4)
36
37
38 parser = argparse.ArgumentParser()
39 parser.add_argument("-d", "--debug", help="Debug mode",  action="store_true")
40 parser.add_argument("-r", "--report",
41                     help="Create json result file",
42                     action="store_true")
43 args = parser.parse_args()
44
45 """ logging configuration """
46 logger = logging.getLogger('vIMS')
47 logger.setLevel(logging.DEBUG)
48
49 ch = logging.StreamHandler()
50 if args.debug:
51     ch.setLevel(logging.DEBUG)
52 else:
53     ch.setLevel(logging.INFO)
54 formatter = logging.Formatter(
55     '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
56 ch.setFormatter(formatter)
57 logger.addHandler(ch)
58
59 REPO_PATH = os.environ['repos_dir'] + '/functest/'
60 if not os.path.exists(REPO_PATH):
61     logger.error("Functest repository directory not found '%s'" % REPO_PATH)
62     exit(-1)
63 sys.path.append(REPO_PATH + "testcases/")
64 import functest_utils
65
66 with open(REPO_PATH + "testcases/config_functest.yaml") as f:
67     functest_yaml = yaml.safe_load(f)
68 f.close()
69
70 # Cloudify parameters
71 VIMS_DIR = REPO_PATH + \
72     functest_yaml.get("general").get("directories").get("dir_vIMS")
73 VIMS_DATA_DIR = functest_yaml.get("general").get(
74     "directories").get("dir_vIMS_data") + "/"
75 VIMS_TEST_DIR = functest_yaml.get("general").get(
76     "directories").get("dir_repo_vims_test") + "/"
77 TEST_DB = functest_yaml.get("results").get("test_db_url")
78
79 TENANT_NAME = functest_yaml.get("vIMS").get("general").get("tenant_name")
80 TENANT_DESCRIPTION = functest_yaml.get("vIMS").get(
81     "general").get("tenant_description")
82 IMAGES = functest_yaml.get("vIMS").get("general").get("images")
83
84 CFY_MANAGER_BLUEPRINT = functest_yaml.get(
85     "vIMS").get("cloudify").get("blueprint")
86 CFY_MANAGER_REQUIERMENTS = functest_yaml.get(
87     "vIMS").get("cloudify").get("requierments")
88 CFY_INPUTS = functest_yaml.get("vIMS").get("cloudify").get("inputs")
89
90 CW_BLUEPRINT = functest_yaml.get("vIMS").get("clearwater").get("blueprint")
91 CW_DEPLOYMENT_NAME = functest_yaml.get("vIMS").get(
92     "clearwater").get("deployment-name")
93 CW_INPUTS = functest_yaml.get("vIMS").get("clearwater").get("inputs")
94 CW_REQUIERMENTS = functest_yaml.get("vIMS").get(
95     "clearwater").get("requierments")
96
97 CFY_DEPLOYMENT_DURATION = 0
98 CW_DEPLOYMENT_DURATION = 0
99
100
101 def download_and_add_image_on_glance(glance, image_name, image_url):
102     dest_path = VIMS_DATA_DIR + "tmp/"
103     if not os.path.exists(dest_path):
104         os.makedirs(dest_path)
105     file_name = image_url.rsplit('/')[-1]
106     if not functest_utils.download_url(image_url, dest_path):
107         logger.error("Failed to download image %s" % file_name)
108         return False
109
110     image = functest_utils.create_glance_image(
111         glance, image_name, dest_path + file_name)
112     if not image:
113         logger.error("Failed to upload image on glance")
114         return False
115
116     return image
117
118
119 def test_clearwater():
120
121     time.sleep(180)
122
123     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
124     script += "cd " + VIMS_DATA_DIR + "; "
125     script += "cfy deployments outputs -d " + CW_DEPLOYMENT_NAME + \
126         " | grep Value: | sed \"s/ *Value: //g\";"
127     cmd = "/bin/bash -c '" + script + "'"
128
129     try:
130         logger.debug("Trying to get clearwater nameserver IP ... ")
131         dns_ip = os.popen(cmd).read()
132         dns_ip = dns_ip.splitlines()[0]
133     except:
134         logger.error("Unable to retrieve the IP of the DNS server !")
135
136     start_time_ts = time.time()
137     end_time_ts = start_time_ts
138     logger.info("vIMS functional test Start Time:'%s'" % (
139         datetime.datetime.fromtimestamp(start_time_ts).strftime(
140             '%Y-%m-%d %H:%M:%S')))
141
142     if dns_ip != "":
143         script = 'echo -e "nameserver ' + dns_ip + \
144             '\nnameserver 8.8.8.8\nnameserver 8.8.4.4" > /etc/resolv.conf; '
145         script += 'source /etc/profile.d/rvm.sh; '
146         script += 'cd ' + VIMS_TEST_DIR + '; '
147         script += 'rake test[' + \
148             CW_INPUTS["public_domain"] + '] SIGNUP_CODE="secret"'
149
150         cmd = "/bin/bash -c '" + script + "'"
151         print cmd
152         output_file = "output.txt"
153         f = open(output_file, 'w+')
154         p = subprocess.call(cmd, shell=True, stdout=f,
155                             stderr=subprocess.STDOUT)
156         f.close()
157         end_time_ts = time.time()
158         duration = round(end_time_ts - start_time_ts, 1)
159         logger.info("vIMS functional test duration:'%s'" % duration)
160         f = open(output_file, 'r')
161         result = f.read()
162         if result != "" and logger:
163             logger.debug(result)
164
165         vims_test_result = ""
166         try:
167             logger.debug("Trying to load test results")
168             with open(VIMS_TEST_DIR + "temp.json") as f:
169                 vims_test_result = json.load(f)
170             f.close()
171         except:
172             logger.error("Unable to retrieve test results")
173
174         if vims_test_result != "":
175             if args.report:
176                 logger.debug("Push result into DB")
177                 logger.debug("Pushing results to DB....")
178                 git_version = functest_utils.get_git_branch(REPO_PATH)
179                 functest_utils.push_results_to_db(db_url=TEST_DB, case_name="vIMS",
180                                                   logger=logger, pod_name="opnfv-jump-2", git_version=git_version,
181                                                   payload={'orchestrator': {'duration': CFY_DEPLOYMENT_DURATION,
182                                                                             'result': ""},
183                                                            'vIMS': {'duration': CW_DEPLOYMENT_DURATION,
184                                                                     'result': ""},
185                                                            'sig_test': {'duration': duration,
186                                                                         'result': vims_test_result}})
187         try:
188             os.remove(VIMS_TEST_DIR + "temp.json")
189         except:
190             logger.error("Deleting file failed")
191
192
193 def main():
194
195     ################ GENERAL INITIALISATION ################
196
197     if not os.path.exists(VIMS_DATA_DIR):
198         os.makedirs(VIMS_DATA_DIR)
199
200     ks_creds = functest_utils.get_credentials("keystone")
201     nv_creds = functest_utils.get_credentials("nova")
202     nt_creds = functest_utils.get_credentials("neutron")
203
204     logger.info("Prepare OpenStack plateform (create tenant and user)")
205     keystone = ksclient.Client(**ks_creds)
206
207     user_id = functest_utils.get_user_id(keystone, ks_creds['username'])
208     if user_id == '':
209         logger.error("Error : Failed to get id of %s user" %
210                      ks_creds['username'])
211         exit(-1)
212
213     tenant_id = functest_utils.create_tenant(
214         keystone, TENANT_NAME, TENANT_DESCRIPTION)
215     if tenant_id == '':
216         logger.error("Error : Failed to create %s tenant" % TENANT_NAME)
217         exit(-1)
218
219     roles_name = ["admin", "Admin"]
220     role_id = ''
221     for role_name in roles_name:
222         if role_id == '':
223             role_id = functest_utils.get_role_id(keystone, role_name)
224
225     if role_id == '':
226         logger.error("Error : Failed to get id for %s role" % role_name)
227
228     if not functest_utils.add_role_user(keystone, user_id, role_id, tenant_id):
229         logger.error("Error : Failed to add %s on tenant" %
230                      ks_creds['username'])
231
232     user_id = functest_utils.create_user(
233         keystone, TENANT_NAME, TENANT_NAME, None, tenant_id)
234     if user_id == '':
235         logger.error("Error : Failed to create %s user" % TENANT_NAME)
236
237     logger.info("Update OpenStack creds informations")
238     ks_creds.update({
239         "username": TENANT_NAME,
240         "password": TENANT_NAME,
241         "tenant_name": TENANT_NAME,
242     })
243
244     nt_creds.update({
245         "tenant_name": TENANT_NAME,
246     })
247
248     nv_creds.update({
249         "project_id": TENANT_NAME,
250     })
251
252     logger.info("Upload some OS images if it doesn't exist")
253     glance_endpoint = keystone.service_catalog.url_for(service_type='image',
254                                                        endpoint_type='publicURL')
255     glance = glclient.Client(1, glance_endpoint, token=keystone.auth_token)
256
257     for img in IMAGES.keys():
258         image_name = IMAGES[img]['image_name']
259         image_url = IMAGES[img]['image_url']
260
261         image_id = functest_utils.get_image_id(glance, image_name)
262
263         if image_id == '':
264             logger.info("""%s image doesn't exist on glance repository.
265                             Try downloading this image and upload on glance !""" % image_name)
266             image_id = download_and_add_image_on_glance(
267                 glance, image_name, image_url)
268
269         if image_id == '':
270             logger.error(
271                 "Error : Failed to find or upload required OS image for this deployment")
272             exit(-1)
273
274     nova = nvclient.Client("2", **nv_creds)
275
276     logger.info("Update security group quota for this tenant")
277     neutron = ntclient.Client(**nt_creds)
278     if not functest_utils.update_sg_quota(neutron, tenant_id, 50, 100):
279         logger.error(
280             "Failed to update security group quota for tenant %s" % TENANT_NAME)
281         exit(-1)
282
283     logger.info("Update cinder quota for this tenant")
284     from cinderclient import client as cinderclient
285
286     creds_cinder = functest_utils.get_credentials("cinder")
287     cinder_client = cinderclient.Client('1', creds_cinder['username'],
288                                         creds_cinder['api_key'],
289                                         creds_cinder['project_id'],
290                                         creds_cinder['auth_url'],
291                                         service_type="volume")
292     if not functest_utils.update_cinder_quota(cinder_client, tenant_id, 20, 50, 1500):
293         logger.error("Failed to update cinder quota for tenant %s" %
294                      TENANT_NAME)
295         exit(-1)
296
297     ################ CLOUDIFY INITIALISATION ################
298
299     cfy = orchestrator(VIMS_DATA_DIR, CFY_INPUTS, logger)
300
301     cfy.set_credentials(username=ks_creds['username'], password=ks_creds[
302                         'password'], tenant_name=ks_creds['tenant_name'], auth_url=ks_creds['auth_url'])
303
304     logger.info("Collect flavor id for cloudify manager server")
305     nova = nvclient.Client("2", **nv_creds)
306
307     flavor_name = "m1.medium"
308     flavor_id = functest_utils.get_flavor_id(nova, flavor_name)
309     for requirement in CFY_MANAGER_REQUIERMENTS:
310         if requirement == 'ram_min':
311             flavor_id = functest_utils.get_flavor_id_by_ram_range(
312                 nova, CFY_MANAGER_REQUIERMENTS['ram_min'], 8196)
313
314     if flavor_id == '':
315         logger.error(
316             "Failed to find %s flavor. Try with ram range default requirement !" % flavor_name)
317         flavor_id = functest_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
318
319     if flavor_id == '':
320         logger.error(
321             "Failed to find required flavor for this deployment" % flavor_name)
322         exit(-1)
323
324     cfy.set_flavor_id(flavor_id)
325
326     image_name = "centos_7"
327     image_id = functest_utils.get_image_id(glance, image_name)
328     for requirement in CFY_MANAGER_REQUIERMENTS:
329         if requirement == 'os_image':
330             image_id = functest_utils.get_image_id(
331                 glance, CFY_MANAGER_REQUIERMENTS['os_image'])
332
333     if image_id == '':
334         logger.error(
335             "Error : Failed to find required OS image for cloudify manager")
336         exit(-1)
337
338     cfy.set_image_id(image_id)
339
340     ext_net = functest_utils.get_external_net(neutron)
341     if not ext_net:
342         logger.error("Failed to get external network")
343         exit(-1)
344
345     cfy.set_external_network_name(ext_net)
346
347     logger.info("Prepare virtualenv for cloudify-cli")
348     cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
349     functest_utils.execute_command(cmd, logger)
350     cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
351     functest_utils.execute_command(cmd, logger)
352
353     cfy.download_manager_blueprint(
354         CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch'])
355
356     ################ CLOUDIFY DEPLOYMENT ################
357     start_time_ts = time.time()
358     end_time_ts = start_time_ts
359     logger.info("Cloudify deployment Start Time:'%s'" % (
360         datetime.datetime.fromtimestamp(start_time_ts).strftime(
361             '%Y-%m-%d %H:%M:%S')))
362
363     cfy.deploy_manager()
364
365     global CFY_DEPLOYMENT_DURATION
366     end_time_ts = time.time()
367     CFY_DEPLOYMENT_DURATION = round(end_time_ts - start_time_ts, 1)
368     logger.info("Cloudify deployment duration:'%s'" % CFY_DEPLOYMENT_DURATION)
369
370     ################ CLEARWATER INITIALISATION ################
371
372     cw = clearwater(CW_INPUTS, cfy, logger)
373
374     logger.info("Collect flavor id for all clearwater vm")
375     nova = nvclient.Client("2", **nv_creds)
376
377     flavor_name = "m1.small"
378     flavor_id = functest_utils.get_flavor_id(nova, flavor_name)
379     for requirement in CW_REQUIERMENTS:
380         if requirement == 'ram_min':
381             flavor_id = functest_utils.get_flavor_id_by_ram_range(
382                 nova, CW_REQUIERMENTS['ram_min'], 8196)
383
384     if flavor_id == '':
385         logger.error(
386             "Failed to find %s flavor. Try with ram range default requirement !" % flavor_name)
387         flavor_id = functest_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
388
389     if flavor_id == '':
390         logger.error(
391             "Failed to find required flavor for this deployment" % flavor_name)
392         exit(-1)
393
394     cw.set_flavor_id(flavor_id)
395
396     image_name = "ubuntu_14.04"
397     image_id = functest_utils.get_image_id(glance, image_name)
398     for requirement in CW_REQUIERMENTS:
399         if requirement == 'os_image':
400             image_id = functest_utils.get_image_id(
401                 glance, CW_REQUIERMENTS['os_image'])
402
403     if image_id == '':
404         logger.error(
405             "Error : Failed to find required OS image for cloudify manager")
406         exit(-1)
407
408     cw.set_image_id(image_id)
409
410     ext_net = functest_utils.get_external_net(neutron)
411     if not ext_net:
412         logger.error("Failed to get external network")
413         exit(-1)
414
415     cw.set_external_network_name(ext_net)
416
417     ################ CLEARWATER DEPLOYMENT ################
418
419     start_time_ts = time.time()
420     end_time_ts = start_time_ts
421     logger.info("vIMS VNF deployment Start Time:'%s'" % (
422         datetime.datetime.fromtimestamp(start_time_ts).strftime(
423             '%Y-%m-%d %H:%M:%S')))
424
425     cw.deploy_vnf(CW_BLUEPRINT)
426
427     global CW_DEPLOYMENT_DURATION
428     end_time_ts = time.time()
429     CW_DEPLOYMENT_DURATION = round(end_time_ts - start_time_ts, 1)
430     logger.info("vIMS VNF deployment duration:'%s'" % CW_DEPLOYMENT_DURATION)
431
432     ################ CLEARWATER TEST ################
433
434     test_clearwater()
435
436     ########### CLEARWATER UNDEPLOYMENT ############
437
438     cw.undeploy_vnf()
439
440     ############ CLOUDIFY UNDEPLOYMENT #############
441
442     cfy.undeploy_manager()
443
444     ############### GENERAL CLEANUP ################
445
446     ks_creds = functest_utils.get_credentials("keystone")
447
448     keystone = ksclient.Client(**ks_creds)
449
450     logger.info("Removing %s tenant .." % CFY_INPUTS['keystone_tenant_name'])
451     tenant_id = functest_utils.get_tenant_id(
452         keystone, CFY_INPUTS['keystone_tenant_name'])
453     if tenant_id == '':
454         logger.error("Error : Failed to get id of %s tenant" %
455                      CFY_INPUTS['keystone_tenant_name'])
456     else:
457         if not functest_utils.delete_tenant(keystone, tenant_id):
458             logger.error("Error : Failed to remove %s tenant" %
459                          CFY_INPUTS['keystone_tenant_name'])
460
461     logger.info("Removing %s user .." % CFY_INPUTS['keystone_username'])
462     user_id = functest_utils.get_user_id(
463         keystone, CFY_INPUTS['keystone_username'])
464     if user_id == '':
465         logger.error("Error : Failed to get id of %s user" %
466                      CFY_INPUTS['keystone_username'])
467     else:
468         if not functest_utils.delete_user(keystone, user_id):
469             logger.error("Error : Failed to remove %s user" %
470                          CFY_INPUTS['keystone_username'])
471
472
473 if __name__ == '__main__':
474     main()