Merge "Corrected project lead"
[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("/home/opnfv/functest/conf/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     nameservers = functest_utils.get_resolvconf_ns()
142     resolvconf = ""
143     for ns in nameservers:
144         resolvconf += "\nnameserver " + ns
145
146     if dns_ip != "":
147         script = 'echo -e "nameserver ' + dns_ip + resolvconf + '" > /etc/resolv.conf; '
148         script += 'source /etc/profile.d/rvm.sh; '
149         script += 'cd ' + VIMS_TEST_DIR + '; '
150         script += 'rake test[' + \
151             CW_INPUTS["public_domain"] + '] SIGNUP_CODE="secret"'
152
153         cmd = "/bin/bash -c '" + script + "'"
154         output_file = "output.txt"
155         f = open(output_file, 'w+')
156         p = subprocess.call(cmd, shell=True, stdout=f,
157                             stderr=subprocess.STDOUT)
158         f.close()
159         end_time_ts = time.time()
160         duration = round(end_time_ts - start_time_ts, 1)
161         logger.info("vIMS functional test duration:'%s'" % duration)
162         f = open(output_file, 'r')
163         result = f.read()
164         if result != "" and logger:
165             logger.debug(result)
166
167         vims_test_result = ""
168         try:
169             logger.debug("Trying to load test results")
170             with open(VIMS_TEST_DIR + "temp.json") as f:
171                 vims_test_result = json.load(f)
172             f.close()
173         except:
174             logger.error("Unable to retrieve test results")
175
176         if vims_test_result != "":
177             if args.report:
178                 logger.debug("Push result into DB")
179                 logger.debug("Pushing results to DB....")
180                 git_version = functest_utils.get_git_branch(REPO_PATH)
181                 functest_utils.push_results_to_db(db_url=TEST_DB, case_name="vIMS",
182                                                   logger=logger, pod_name=functest_utils.get_pod_name(logger), git_version=git_version,
183                                                   payload={'orchestrator': {'duration': CFY_DEPLOYMENT_DURATION,
184                                                                             'result': ""},
185                                                            'vIMS': {'duration': CW_DEPLOYMENT_DURATION,
186                                                                     'result': ""},
187                                                            'sig_test': {'duration': duration,
188                                                                         'result': vims_test_result}})
189         try:
190             os.remove(VIMS_TEST_DIR + "temp.json")
191         except:
192             logger.error("Deleting file failed")
193
194
195 def main():
196
197     ################ GENERAL INITIALISATION ################
198
199     if not os.path.exists(VIMS_DATA_DIR):
200         os.makedirs(VIMS_DATA_DIR)
201
202     ks_creds = functest_utils.get_credentials("keystone")
203     nv_creds = functest_utils.get_credentials("nova")
204     nt_creds = functest_utils.get_credentials("neutron")
205
206     logger.info("Prepare OpenStack plateform (create tenant and user)")
207     keystone = ksclient.Client(**ks_creds)
208
209     user_id = functest_utils.get_user_id(keystone, ks_creds['username'])
210     if user_id == '':
211         logger.error("Error : Failed to get id of %s user" %
212                      ks_creds['username'])
213         exit(-1)
214
215     tenant_id = functest_utils.create_tenant(
216         keystone, TENANT_NAME, TENANT_DESCRIPTION)
217     if tenant_id == '':
218         logger.error("Error : Failed to create %s tenant" % TENANT_NAME)
219         exit(-1)
220
221     roles_name = ["admin", "Admin"]
222     role_id = ''
223     for role_name in roles_name:
224         if role_id == '':
225             role_id = functest_utils.get_role_id(keystone, role_name)
226
227     if role_id == '':
228         logger.error("Error : Failed to get id for %s role" % role_name)
229
230     if not functest_utils.add_role_user(keystone, user_id, role_id, tenant_id):
231         logger.error("Error : Failed to add %s on tenant" %
232                      ks_creds['username'])
233
234     user_id = functest_utils.create_user(
235         keystone, TENANT_NAME, TENANT_NAME, None, tenant_id)
236     if user_id == '':
237         logger.error("Error : Failed to create %s user" % TENANT_NAME)
238
239     logger.info("Update OpenStack creds informations")
240     ks_creds.update({
241         "username": TENANT_NAME,
242         "password": TENANT_NAME,
243         "tenant_name": TENANT_NAME,
244     })
245
246     nt_creds.update({
247         "tenant_name": TENANT_NAME,
248     })
249
250     nv_creds.update({
251         "project_id": TENANT_NAME,
252     })
253
254     logger.info("Upload some OS images if it doesn't exist")
255     glance_endpoint = keystone.service_catalog.url_for(service_type='image',
256                                                        endpoint_type='publicURL')
257     glance = glclient.Client(1, glance_endpoint, token=keystone.auth_token)
258
259     for img in IMAGES.keys():
260         image_name = IMAGES[img]['image_name']
261         image_url = IMAGES[img]['image_url']
262
263         image_id = functest_utils.get_image_id(glance, image_name)
264
265         if image_id == '':
266             logger.info("""%s image doesn't exist on glance repository.
267                             Try downloading this image and upload on glance !""" % image_name)
268             image_id = download_and_add_image_on_glance(
269                 glance, image_name, image_url)
270
271         if image_id == '':
272             logger.error(
273                 "Error : Failed to find or upload required OS image for this deployment")
274             exit(-1)
275
276     nova = nvclient.Client("2", **nv_creds)
277
278     logger.info("Update security group quota for this tenant")
279     neutron = ntclient.Client(**nt_creds)
280     if not functest_utils.update_sg_quota(neutron, tenant_id, 50, 100):
281         logger.error(
282             "Failed to update security group quota for tenant %s" % TENANT_NAME)
283         exit(-1)
284
285     logger.info("Update cinder quota for this tenant")
286     from cinderclient import client as cinderclient
287
288     creds_cinder = functest_utils.get_credentials("cinder")
289     cinder_client = cinderclient.Client('1', creds_cinder['username'],
290                                         creds_cinder['api_key'],
291                                         creds_cinder['project_id'],
292                                         creds_cinder['auth_url'],
293                                         service_type="volume")
294     if not functest_utils.update_cinder_quota(cinder_client, tenant_id, 20, 10, 150):
295         logger.error("Failed to update cinder quota for tenant %s" %
296                      TENANT_NAME)
297         exit(-1)
298
299     ################ CLOUDIFY INITIALISATION ################
300
301     cfy = orchestrator(VIMS_DATA_DIR, CFY_INPUTS, logger)
302
303     cfy.set_credentials(username=ks_creds['username'], password=ks_creds[
304                         'password'], tenant_name=ks_creds['tenant_name'], auth_url=ks_creds['auth_url'])
305
306     logger.info("Collect flavor id for cloudify manager server")
307     nova = nvclient.Client("2", **nv_creds)
308
309     flavor_name = "m1.medium"
310     flavor_id = functest_utils.get_flavor_id(nova, flavor_name)
311     for requirement in CFY_MANAGER_REQUIERMENTS:
312         if requirement == 'ram_min':
313             flavor_id = functest_utils.get_flavor_id_by_ram_range(
314                 nova, CFY_MANAGER_REQUIERMENTS['ram_min'], 8196)
315
316     if flavor_id == '':
317         logger.error(
318             "Failed to find %s flavor. Try with ram range default requirement !" % flavor_name)
319         flavor_id = functest_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
320
321     if flavor_id == '':
322         logger.error(
323             "Failed to find required flavor for this deployment" % flavor_name)
324         exit(-1)
325
326     cfy.set_flavor_id(flavor_id)
327
328     image_name = "centos_7"
329     image_id = functest_utils.get_image_id(glance, image_name)
330     for requirement in CFY_MANAGER_REQUIERMENTS:
331         if requirement == 'os_image':
332             image_id = functest_utils.get_image_id(
333                 glance, CFY_MANAGER_REQUIERMENTS['os_image'])
334
335     if image_id == '':
336         logger.error(
337             "Error : Failed to find required OS image for cloudify manager")
338         exit(-1)
339
340     cfy.set_image_id(image_id)
341
342     ext_net = functest_utils.get_external_net(neutron)
343     if not ext_net:
344         logger.error("Failed to get external network")
345         exit(-1)
346
347     cfy.set_external_network_name(ext_net)
348
349     ns = functest_utils.get_resolvconf_ns()
350     if ns:
351         cfy.set_nameservers(ns)
352
353     logger.info("Prepare virtualenv for cloudify-cli")
354     cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
355     functest_utils.execute_command(cmd, logger)
356     cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
357     functest_utils.execute_command(cmd, logger)
358
359     cfy.download_manager_blueprint(
360         CFY_MANAGER_BLUEPRINT['url'], CFY_MANAGER_BLUEPRINT['branch'])
361
362     ################ CLOUDIFY DEPLOYMENT ################
363     start_time_ts = time.time()
364     end_time_ts = start_time_ts
365     logger.info("Cloudify deployment Start Time:'%s'" % (
366         datetime.datetime.fromtimestamp(start_time_ts).strftime(
367             '%Y-%m-%d %H:%M:%S')))
368
369     cfy.deploy_manager()
370
371     global CFY_DEPLOYMENT_DURATION
372     end_time_ts = time.time()
373     CFY_DEPLOYMENT_DURATION = round(end_time_ts - start_time_ts, 1)
374     logger.info("Cloudify deployment duration:'%s'" % CFY_DEPLOYMENT_DURATION)
375
376     ################ CLEARWATER INITIALISATION ################
377
378     cw = clearwater(CW_INPUTS, cfy, logger)
379
380     logger.info("Collect flavor id for all clearwater vm")
381     nova = nvclient.Client("2", **nv_creds)
382
383     flavor_name = "m1.small"
384     flavor_id = functest_utils.get_flavor_id(nova, flavor_name)
385     for requirement in CW_REQUIERMENTS:
386         if requirement == 'ram_min':
387             flavor_id = functest_utils.get_flavor_id_by_ram_range(
388                 nova, CW_REQUIERMENTS['ram_min'], 8196)
389
390     if flavor_id == '':
391         logger.error(
392             "Failed to find %s flavor. Try with ram range default requirement !" % flavor_name)
393         flavor_id = functest_utils.get_flavor_id_by_ram_range(nova, 4000, 8196)
394
395     if flavor_id == '':
396         logger.error(
397             "Failed to find required flavor for this deployment" % flavor_name)
398         exit(-1)
399
400     cw.set_flavor_id(flavor_id)
401
402     image_name = "ubuntu_14.04"
403     image_id = functest_utils.get_image_id(glance, image_name)
404     for requirement in CW_REQUIERMENTS:
405         if requirement == 'os_image':
406             image_id = functest_utils.get_image_id(
407                 glance, CW_REQUIERMENTS['os_image'])
408
409     if image_id == '':
410         logger.error(
411             "Error : Failed to find required OS image for cloudify manager")
412         exit(-1)
413
414     cw.set_image_id(image_id)
415
416     ext_net = functest_utils.get_external_net(neutron)
417     if not ext_net:
418         logger.error("Failed to get external network")
419         exit(-1)
420
421     cw.set_external_network_name(ext_net)
422
423     ################ CLEARWATER DEPLOYMENT ################
424
425     start_time_ts = time.time()
426     end_time_ts = start_time_ts
427     logger.info("vIMS VNF deployment Start Time:'%s'" % (
428         datetime.datetime.fromtimestamp(start_time_ts).strftime(
429             '%Y-%m-%d %H:%M:%S')))
430
431     cw.deploy_vnf(CW_BLUEPRINT)
432
433     global CW_DEPLOYMENT_DURATION
434     end_time_ts = time.time()
435     CW_DEPLOYMENT_DURATION = round(end_time_ts - start_time_ts, 1)
436     logger.info("vIMS VNF deployment duration:'%s'" % CW_DEPLOYMENT_DURATION)
437
438     ################ CLEARWATER TEST ################
439
440     test_clearwater()
441
442     ########### CLEARWATER UNDEPLOYMENT ############
443
444     cw.undeploy_vnf()
445
446     ############ CLOUDIFY UNDEPLOYMENT #############
447
448     cfy.undeploy_manager()
449
450     ############### GENERAL CLEANUP ################
451
452     ks_creds = functest_utils.get_credentials("keystone")
453
454     keystone = ksclient.Client(**ks_creds)
455
456     logger.info("Removing %s tenant .." % CFY_INPUTS['keystone_tenant_name'])
457     tenant_id = functest_utils.get_tenant_id(
458         keystone, CFY_INPUTS['keystone_tenant_name'])
459     if tenant_id == '':
460         logger.error("Error : Failed to get id of %s tenant" %
461                      CFY_INPUTS['keystone_tenant_name'])
462     else:
463         if not functest_utils.delete_tenant(keystone, tenant_id):
464             logger.error("Error : Failed to remove %s tenant" %
465                          CFY_INPUTS['keystone_tenant_name'])
466
467     logger.info("Removing %s user .." % CFY_INPUTS['keystone_username'])
468     user_id = functest_utils.get_user_id(
469         keystone, CFY_INPUTS['keystone_username'])
470     if user_id == '':
471         logger.error("Error : Failed to get id of %s user" %
472                      CFY_INPUTS['keystone_username'])
473     else:
474         if not functest_utils.delete_user(keystone, user_id):
475             logger.error("Error : Failed to remove %s user" %
476                          CFY_INPUTS['keystone_username'])
477
478
479 if __name__ == '__main__':
480     main()