Bugfix: venv path
[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, time, subprocess, logging, argparse, yaml, pprint, sys, shutil
15 from git import Repo
16 import keystoneclient.v2_0.client as ksclient
17 import glanceclient.client as glclient
18 import novaclient.client as nvclient
19 from neutronclient.v2_0 import client as ntclient
20
21 import urllib
22 pp = pprint.PrettyPrinter(indent=4)
23
24
25 parser = argparse.ArgumentParser()
26 parser.add_argument("repo_path", help="Path to the repository")
27 parser.add_argument("-d", "--debug", help="Debug mode",  action="store_true")
28 args = parser.parse_args()
29
30 sys.path.append(args.repo_path + "testcases/")
31
32 import functest_utils
33
34 """ logging configuration """
35 logger = logging.getLogger('vIMS')
36 logger.setLevel(logging.DEBUG)
37
38 ch = logging.StreamHandler()
39 if args.debug:
40     ch.setLevel(logging.DEBUG)
41 else:
42     ch.setLevel(logging.INFO)
43 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
44 ch.setFormatter(formatter)
45 logger.addHandler(ch)
46
47
48 HOME = os.environ['HOME']+"/"
49 # with open(args.repo_path+"config_functest.yaml") as f:
50 with open(args.repo_path + "testcases/config_functest.yaml") as f:
51     functest_yaml = yaml.safe_load(f)
52 f.close()
53
54 # Cloudify parameters
55 REPO_PATH = args.repo_path
56 HOME = os.environ['HOME']+"/"
57 VIMS_DIR = REPO_PATH + functest_yaml.get("general").get("directories").get("dir_vIMS")
58 VIMS_DATA_DIR = HOME + functest_yaml.get("general").get("directories").get("dir_vIMS_data")+"/"
59
60 TENANT_NAME = functest_yaml.get("vIMS").get("general").get("tenant_name")
61 TENANT_DESCRIPTION = functest_yaml.get("vIMS").get("general").get("tenant_description")
62 BASE_IMAGE_URL = functest_yaml.get("vIMS").get("general").get("base_image_url")
63 BASE_IMAGE_NAME = functest_yaml.get("vIMS").get("general").get("base_image_name")
64 GLANCE_IMAGE_NAME = functest_yaml.get("vIMS").get("cloudify").get("inputs").get("image_id")
65
66 CFY_MANAGER_BLUEPRINT = functest_yaml.get("vIMS").get("cloudify").get("blueprint")
67 CFY_INPUTS =  functest_yaml.get("vIMS").get("cloudify").get("inputs")
68 CFY_INPUTS_PATH =  functest_yaml.get("vIMS").get("cloudify").get("inputs_path")
69
70 CW_BLUEPRINT = functest_yaml.get("vIMS").get("clearwater").get("blueprint")
71 CW_DEPLOYMENT_NAME = functest_yaml.get("vIMS").get("clearwater").get("deployment-name")
72 CW_INPUTS =  functest_yaml.get("vIMS").get("clearwater").get("inputs")
73 CW_DOMAIN_NAME =  functest_yaml.get("vIMS").get("clearwater").get("inputs").get("public_domain")
74
75
76 def pMsg(value):
77     """pretty printing"""
78     pp.pprint(value)
79
80 def download_and_add_image_on_glance(glance, image_name, image_url):
81     dest_path = VIMS_DATA_DIR + "tmp/"
82     if not os.path.exists(dest_path):
83         os.makedirs(dest_path)
84     file_name = image_url.rsplit('/')[-1]
85     if not functest_utils.download_url(image_url, dest_path):
86         logger.error("Failed to download image %s" %file_name)
87         return False
88
89     image = functest_utils.create_glance_image(glance, image_name, dest_path + file_name)
90     if not image:
91         logger.error("Failed to upload image on glance")
92         return False
93
94     return image
95
96 def download_blueprints(blueprint_url, branch, dest_path):
97     if os.path.exists(dest_path):
98         shutil.rmtree(dest_path)
99     try:
100         Repo.clone_from(blueprint_url, dest_path, branch=branch)
101         return True
102     except:
103         return False
104
105 def initialize_deployments():
106     if not os.path.exists(VIMS_DATA_DIR):
107         os.makedirs(VIMS_DATA_DIR)
108
109     ks_creds = functest_utils.get_credentials("keystone")
110     nv_creds = functest_utils.get_credentials("nova")
111     nt_creds = functest_utils.get_credentials("neutron")
112
113     logger.info("Prepare OpenStack plateform (create tenant and user)")
114     keystone = ksclient.Client(**ks_creds)
115
116     user_id = functest_utils.get_user_id(keystone, ks_creds['username'])
117     if user_id == '':
118         logger.error("Error : Failed to get id of %s user" %ks_creds['username'])
119         exit(-1)
120
121     tenant_id = functest_utils.create_tenant(keystone, TENANT_NAME, TENANT_DESCRIPTION)
122     if tenant_id == '':
123         logger.error("Error : Failed to create %s tenant" %TENANT_NAME)
124         exit(-1)
125
126     role_name = "admin"
127     role_id = functest_utils.get_role_id(keystone, role_name)
128     if role_id == '':
129         logger.error("Error : Failed to get id for %s role" %role_name)
130
131     if not functest_utils.add_role_user(keystone, user_id, role_id, tenant_id):
132         logger.error("Error : Failed to add %s on tenant" %ks_creds['username'])
133
134     user_id = functest_utils.create_user(keystone, TENANT_NAME, TENANT_NAME, None, tenant_id)
135     if user_id == '':
136         logger.error("Error : Failed to create %s user" %TENANT_NAME)
137
138     logger.info("Update OpenStack creds informations")
139     ks_creds.update({
140         "username": TENANT_NAME,
141         "password": TENANT_NAME,
142         "tenant_name": TENANT_NAME,
143         })
144
145     nt_creds.update({
146         "tenant_name": TENANT_NAME,
147         })
148
149     nv_creds.update({
150         "project_id": TENANT_NAME,
151         })
152
153     logger.info("Upload ubuntu image if it doesn't exist")
154     glance_endpoint = keystone.service_catalog.url_for(service_type='image',
155                                                    endpoint_type='publicURL')
156     glance = glclient.Client(1, glance_endpoint, token=keystone.auth_token)
157
158     image_id = functest_utils.get_image_id(glance, BASE_IMAGE_NAME)
159     if image_id == '':
160         logger.info("""%s image doesn't exist on glance repository.
161                         Try downloading this image and upload on glance !""" %BASE_IMAGE_NAME)
162         image_id = download_and_add_image_on_glance(glance, BASE_IMAGE_NAME, BASE_IMAGE_URL)
163
164     if image_id == '':
165         logger.error("Error : Failed to find or upload required OS image for this deployment" %flavor_name)
166         exit(-1)
167
168     logger.info("Collect flavor id for cloudify and clearwater VMs")
169     nova = nvclient.Client("2", **nv_creds)
170
171     flavor_name = "m1.small"
172     flavor_id = functest_utils.get_flavor_id(nova, flavor_name)
173     if flavor_id == '':
174         logger.error("Failed to find %s flavor. Try with ram range requirement !" %flavor_name)
175         flavor_id = get_flavor_id_by_ram_range(nova, 1792, 2048)
176
177     if flavor_id == '':
178         logger.error("Failed to find required flavor for this deployment" %flavor_name)
179         exit(-1)
180
181     logger.info("Update security group quota for this tenant")
182     neutron = ntclient.Client(**nt_creds)
183     if not functest_utils.update_sg_quota(neutron, tenant_id, 50, 100):
184         logger.error("Failed to update security group quota for tenant %s" %TENANT_NAME)
185         exit(-1)
186
187     ext_net = functest_utils.get_external_net(neutron)
188     if not ext_net:
189         logger.error("Failed to get external network")
190         exit(-1)
191
192     logger.info("Update inputs informations")
193     CFY_INPUTS['image_id'] = image_id
194     CFY_INPUTS['flavor_id'] = flavor_id
195     CFY_INPUTS['external_network_name'] = ext_net
196
197     CW_INPUTS['image_id'] = image_id
198     CW_INPUTS['flavor_id'] = flavor_id
199     CW_INPUTS['external_network_name'] = ext_net
200
201     CFY_INPUTS['keystone_username'] = ks_creds['username']
202     CFY_INPUTS['keystone_password'] = ks_creds['password']
203     CFY_INPUTS['keystone_url'] = ks_creds['auth_url']
204     CFY_INPUTS['keystone_tenant_name'] = ks_creds['tenant_name']
205
206     logger.info("Prepare virtualenv for cloudify-cli")
207     cmd = "chmod +x " + VIMS_DIR + "create_venv.sh"
208     functest_utils.execute_command(cmd,logger)
209     cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR
210     functest_utils.execute_command(cmd,logger)
211
212 def cleanup_deployments():
213     ks_creds = functest_utils.get_credentials("keystone")
214
215     keystone = ksclient.Client(**ks_creds)
216
217     logger.info("Removing %s tenant .." %CFY_INPUTS['keystone_tenant_name'])
218     tenant_id = functest_utils.get_tenant_id(keystone, CFY_INPUTS['keystone_tenant_name'])
219     if tenant_id == '':
220         logger.error("Error : Failed to get id of %s tenant" %CFY_INPUTS['keystone_tenant_name'])
221     else:
222         if not functest_utils.delete_tenant(keystone, tenant_id):
223             logger.error("Error : Failed to remove %s tenant" %CFY_INPUTS['keystone_tenant_name'])
224
225     logger.info("Removing %s user .." %CFY_INPUTS['keystone_username'])
226     user_id = functest_utils.get_user_id(keystone, CFY_INPUTS['keystone_username'])
227     if user_id == '':
228         logger.error("Error : Failed to get id of %s user" %CFY_INPUTS['keystone_username'])
229     else:
230         if not functest_utils.delete_user(keystone, user_id):
231             logger.error("Error : Failed to remove %s user" %CFY_INPUTS['keystone_username'])
232
233 def deploy_cloudify_manager():
234
235     logger.info("Downloading the cloudify manager server blueprint")
236     download_result = download_blueprints(CFY_MANAGER_BLUEPRINT['url'],
237                                                         CFY_MANAGER_BLUEPRINT['branch'],
238                                                         VIMS_DATA_DIR + 'cloudify-manager-blueprint/')
239
240     if not download_result:
241         logger.error("Failed to download manager blueprint")
242         exit(-1)
243
244     logger.info("Writing the inputs file")
245     with open( VIMS_DATA_DIR + 'cloudify-manager-blueprint/' + CFY_INPUTS_PATH, "w") as f:
246         f.write(yaml.dump(CFY_INPUTS, default_style='"') )
247     f.close()
248
249     logger.info("Launching the cloudify-manager deployment")
250     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
251     script += "cd " + VIMS_DATA_DIR + "; "
252     script += "cfy init -r; "
253     script += "cd cloudify-manager-blueprint/openstack; "
254     script += "cfy local create-requirements -o requirements.txt -p openstack-manager-blueprint.yaml; "
255     script += "pip install -r requirements.txt; "
256     script += "cfy bootstrap --install-plugins -p openstack-manager-blueprint.yaml -i inputs.yaml; "
257     cmd = "/bin/bash -c '" + script + "'"
258     functest_utils.execute_command(cmd, logger)
259
260     logger.info("Cloudify-manager server is UP !")
261
262 def undeploy_cloudify_manager():
263
264     logger.info("Launching the cloudify-manager undeployment")
265     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
266     script += "cd " + VIMS_DATA_DIR + "; "
267     script += "cfy teardown -f; "
268     cmd = "/bin/bash -c '" + script + "'"
269     functest_utils.execute_command(cmd, logger)
270
271     logger.info("Cloudify-manager server has been successfully removed!")
272
273 def deploy_clearwater():
274
275     logger.info("Downloading the {0} blueprint".format(CW_BLUEPRINT['file_name']))
276     download_result = download_blueprints(CW_BLUEPRINT['url'], CW_BLUEPRINT['branch'],
277                                               VIMS_DATA_DIR + CW_BLUEPRINT['destination_folder'])
278
279     if not download_result:
280         logger.error("Failed to download blueprint {0}".format(CW_BLUEPRINT['file_name']))
281         exit(-1)
282
283     logger.info("Writing the inputs file")
284     with open(VIMS_DATA_DIR + CW_BLUEPRINT['destination_folder'] + "/inputs.yaml", "w") as f:
285         f.write(yaml.dump(CW_INPUTS, default_style='"') )
286     f.close()
287
288     logger.info("Launching the {0} deployment".format(CW_BLUEPRINT['name']))
289     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
290     script += "cd " + VIMS_DATA_DIR + CW_BLUEPRINT['destination_folder'] + "; "
291     script += "cfy blueprints upload -b " + CW_BLUEPRINT['name'] + " -p openstack-blueprint.yaml; "
292     script += "cfy deployments create -b " + CW_BLUEPRINT['name'] + " -d " + CW_DEPLOYMENT_NAME + " --inputs inputs.yaml; "
293     script += "cfy executions start -w install -d " + CW_DEPLOYMENT_NAME + "; "
294
295     cmd = "/bin/bash -c '" + script + "'"
296     functest_utils.execute_command(cmd, logger)
297
298     logger.info("Clearwater vIMS is UP !")
299
300 def undeploy_clearwater():
301
302     logger.info("Launching the {0} undeployment".format(CW_BLUEPRINT['name']))
303     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
304     script += "cd " + VIMS_DATA_DIR + "; "
305     script += "cfy executions start -w uninstall -d " + CW_DEPLOYMENT_NAME + "; "
306     script += "cfy deployments delete -d " + CW_DEPLOYMENT_NAME + "; "
307
308     cmd = "/bin/bash -c '" + script + "'"
309     functest_utils.execute_command(cmd, logger)
310
311 def test_clearwater():
312
313     script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; "
314     script += "cd " + VIMS_DATA_DIR + "; "
315     script += "cfy deployments outputs -d clearwater-opnfv | grep Value: | sed \"s/ *Value: //g\";"
316     cmd = "/bin/bash -c '" + script + "'"
317     dns_ip = os.popen(cmd).read()
318     dns_ip = dns_ip.splitlines()[0]
319
320     # Coming soon
321
322 def main():
323     initialize_deployments()
324     deploy_cloudify_manager()
325     deploy_clearwater()
326
327     #test_clearwater()
328
329     undeploy_clearwater()
330     undeploy_cloudify_manager()
331     cleanup_deployments()
332
333 if __name__ == '__main__':
334     main()