7dce96da1b5bf730d1b65bd6b1d29f077c4fd3c7
[functest.git] / testcases / functest_utils.py
1 #!/usr/bin/env python
2 #
3 # jose.lausuch@ericsson.com
4 # valentin.boucher@orange.com
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10
11
12 import os
13 import urllib2
14 import subprocess
15 import sys
16 import requests
17 import json
18 from git import Repo
19
20
21 # ############ CREDENTIALS OPENSTACK #############
22 def check_credentials():
23     """
24     Check if the OpenStack credentials (openrc) are sourced
25     """
26     env_vars = ['OS_AUTH_URL','OS_USERNAME','OS_PASSWORD','OS_TENANT_NAME']
27     return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
28
29
30 def get_credentials(service):
31     """Returns a creds dictionary filled with the following keys:
32     * username
33     * password/api_key (depending on the service)
34     * tenant_name/project_id (depending on the service)
35     * auth_url
36     :param service: a string indicating the name of the service
37                     requesting the credentials.
38     """
39     creds = {}
40     # Unfortunately, each of the OpenStack client will request slightly
41     # different entries in their credentials dict.
42     if service.lower() in ("nova", "cinder"):
43         password = "api_key"
44         tenant = "project_id"
45     else:
46         password = "password"
47         tenant = "tenant_name"
48
49     # The most common way to pass these info to the script is to do it through
50     # environment variables.
51     creds.update({
52         "username": os.environ.get('OS_USERNAME', "admin"),
53         password: os.environ.get("OS_PASSWORD", 'admin'),
54         "auth_url": os.environ.get("OS_AUTH_URL",
55                                    "http://192.168.20.71:5000/v2.0"),
56         tenant: os.environ.get("OS_TENANT_NAME", "admin"),
57     })
58
59     return creds
60
61
62 # ################ NOVA #################
63 def get_instance_status(nova_client, instance):
64     try:
65         instance = nova_client.servers.get(instance.id)
66         return instance.status
67     except:
68         return None
69
70
71 def get_instance_by_name(nova_client, instance_name):
72     try:
73         instance = nova_client.servers.find(name=instance_name)
74         return instance
75     except:
76         return None
77
78
79 def get_flavor_id(nova_client, flavor_name):
80     flavors = nova_client.flavors.list(detailed=True)
81     id = ''
82     for f in flavors:
83         if f.name == flavor_name:
84             id = f.id
85             break
86     return id
87
88
89 def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram):
90     flavors = nova_client.flavors.list(detailed=True)
91     id = ''
92     for f in flavors:
93         if min_ram <= f.ram and f.ram <= max_ram:
94             id = f.id
95             break
96     return id
97
98
99 # ################ NEUTRON #################
100 def create_neutron_net(neutron_client, name):
101     json_body = {'network': {'name': name,
102                              'admin_state_up': True}}
103     try:
104         network = neutron_client.create_network(body=json_body)
105         network_dict = network['network']
106         return network_dict['id']
107     except:
108         print "Error:", sys.exc_info()[0]
109         return False
110
111
112 def delete_neutron_net(neutron_client, network_id):
113     try:
114         neutron_client.delete_network(network_id)
115         return True
116     except:
117         print "Error:", sys.exc_info()[0]
118         return False
119
120
121 def create_neutron_subnet(neutron_client, name, cidr, net_id):
122     json_body = {'subnets': [{'name': name, 'cidr': cidr,
123                              'ip_version': 4, 'network_id': net_id}]}
124     try:
125         subnet = neutron_client.create_subnet(body=json_body)
126         return subnet['subnets'][0]['id']
127     except:
128         print "Error:", sys.exc_info()[0]
129         return False
130
131
132 def delete_neutron_subnet(neutron_client, subnet_id):
133     try:
134         neutron_client.delete_subnet(subnet_id)
135         return True
136     except:
137         print "Error:", sys.exc_info()[0]
138         return False
139
140
141 def create_neutron_router(neutron_client, name):
142     json_body = {'router': {'name': name, 'admin_state_up': True}}
143     try:
144         router = neutron_client.create_router(json_body)
145         return router['router']['id']
146     except:
147         print "Error:", sys.exc_info()[0]
148         return False
149
150
151 def delete_neutron_router(neutron_client, router_id):
152     json_body = {'router': {'id': router_id}}
153     try:
154         neutron_client.delete_router(router=router_id)
155         return True
156     except:
157         print "Error:", sys.exc_info()[0]
158         return False
159
160
161 def add_interface_router(neutron_client, router_id, subnet_id):
162     json_body = {"subnet_id": subnet_id}
163     try:
164         neutron_client.add_interface_router(router=router_id, body=json_body)
165         return True
166     except:
167         print "Error:", sys.exc_info()[0]
168         return False
169
170
171 def remove_interface_router(neutron_client, router_id, subnet_id):
172     json_body = {"subnet_id": subnet_id}
173     try:
174         neutron_client.remove_interface_router(router=router_id,
175                                                body=json_body)
176         return True
177     except:
178         print "Error:", sys.exc_info()[0]
179         return False
180
181
182 def create_neutron_port(neutron_client, name, network_id, ip):
183     json_body = {'port': {
184                  'admin_state_up': True,
185                  'name': name,
186                  'network_id': network_id,
187                  'fixed_ips': [{"ip_address": ip}]
188                  }}
189     try:
190         port = neutron_client.create_port(body=json_body)
191         return port['port']['id']
192     except:
193         print "Error:", sys.exc_info()[0]
194         return False
195
196
197 def delete_neutron_port(neutron_client, port_id):
198     try:
199         neutron_client.delete_port(port_id)
200         return True
201     except:
202         print "Error:", sys.exc_info()[0]
203         return False
204
205
206 def get_network_id(neutron_client, network_name):
207     networks = neutron_client.list_networks()['networks']
208     id = ''
209     for n in networks:
210         if n['name'] == network_name:
211             id = n['id']
212             break
213     return id
214
215
216 def check_neutron_net(neutron_client, net_name):
217     for network in neutron_client.list_networks()['networks']:
218         if network['name'] == net_name:
219             for subnet in network['subnets']:
220                 return True
221     return False
222
223
224 def get_network_list(neutron_client):
225     network_list = neutron_client.list_networks()['networks']
226     if len(network_list) == 0:
227         return None
228     else:
229         return network_list
230
231
232 def get_external_net(neutron_client):
233     for network in neutron_client.list_networks()['networks']:
234         if network['router:external']:
235             return network['name']
236     return False
237
238
239 def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
240     json_body = {"quota": {
241         "security_group": sg_quota,
242         "security_group_rule": sg_rule_quota
243     }}
244
245     try:
246         quota = neutron_client.update_quota(tenant_id=tenant_id,
247                                             body=json_body)
248         return True
249     except:
250         print "Error:", sys.exc_info()[0]
251         return False
252
253
254 def get_private_net(neutron_client):
255     # Checks if there is an existing private network
256     networks = neutron_client.list_networks()['networks']
257     if len(networks) == 0:
258         return None
259     for net in networks:
260         if net['router:external'] == False:
261             return net
262     return None
263
264 # ################ GLANCE #################
265
266
267 def get_image_id(glance_client, image_name):
268     images = glance_client.images.list()
269     id = ''
270     for i in images:
271         if i.name == image_name:
272             id = i.id
273             break
274     return id
275
276
277 def create_glance_image(glance_client, image_name, file_path, is_public=True):
278     try:
279         with open(file_path) as fimage:
280             image = glance_client.images.create(name=image_name,
281                                                 is_public=is_public,
282                                                 disk_format="qcow2",
283                                                 container_format="bare",
284                                                 data=fimage)
285         return image.id
286     except:
287         return False
288
289
290 # ################ KEYSTONE #################
291 def get_tenant_id(keystone_client, tenant_name):
292     tenants = keystone_client.tenants.list()
293     id = ''
294     for t in tenants:
295         if t.name == tenant_name:
296             id = t.id
297             break
298     return id
299
300
301 def get_role_id(keystone_client, role_name):
302     roles = keystone_client.roles.list()
303     id = ''
304     for r in roles:
305         if r.name == role_name:
306             id = r.id
307             break
308     return id
309
310
311 def get_user_id(keystone_client, user_name):
312     users = keystone_client.users.list()
313     id = ''
314     for u in users:
315         if u.name == user_name:
316             id = u.id
317             break
318     return id
319
320
321 def create_tenant(keystone_client, tenant_name, tenant_description):
322     try:
323         tenant = keystone_client.tenants.create(tenant_name,
324                                                 tenant_description,
325                                                 enabled=True)
326         return tenant.id
327     except:
328         print "Error:", sys.exc_info()[0]
329         return False
330
331
332 def delete_tenant(keystone_client, tenant_id):
333     try:
334         tenant = keystone_client.tenants.delete(tenant_id)
335         return True
336     except:
337         print "Error:", sys.exc_info()[0]
338         return False
339
340
341 def create_user(keystone_client, user_name, user_password,
342                 user_email, tenant_id):
343     try:
344         user = keystone_client.users.create(user_name, user_password,
345                                             user_email, tenant_id,
346                                             enabled=True)
347         return user.id
348     except:
349         print "Error:", sys.exc_info()[0]
350         return False
351
352
353 def delete_user(keystone_client, user_id):
354     try:
355         tenant = keystone_client.users.delete(user_id)
356         return True
357     except:
358         print "Error:", sys.exc_info()[0]
359         return False
360
361
362 def add_role_user(keystone_client, user_id, role_id, tenant_id):
363     try:
364         keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
365         return True
366     except:
367         print "Error:", sys.exc_info()[0]
368         return False
369
370
371 # ################ UTILS #################
372 def check_internet_connectivity(url='http://www.opnfv.org/'):
373     """
374     Check if there is access to the internet
375     """
376     try:
377         urllib2.urlopen(url, timeout=5)
378         return True
379     except urllib2.URLError:
380         return False
381
382
383 def download_url(url, dest_path):
384     """
385     Download a file to a destination path given a URL
386     """
387     name = url.rsplit('/')[-1]
388     dest = dest_path + "/" + name
389     try:
390         response = urllib2.urlopen(url)
391     except (urllib2.HTTPError, urllib2.URLError):
392         return False
393
394     with open(dest, 'wb') as f:
395         f.write(response.read())
396     return True
397
398
399 def execute_command(cmd, logger=None):
400     """
401     Execute Linux command
402     """
403     if logger:
404         logger.debug('Executing command : {}'.format(cmd))
405     output_file = "output.txt"
406     f = open(output_file, 'w+')
407     p = subprocess.call(cmd, shell=True, stdout=f, stderr=subprocess.STDOUT)
408     f.close()
409     f = open(output_file, 'r')
410     result = f.read()
411     if result != "" and logger:
412         logger.debug(result)
413     if p == 0:
414         return True
415     else:
416         if logger:
417             logger.error("Error when executing command %s" % cmd)
418         exit(-1)
419
420
421 def get_git_branch(repo_path):
422     """
423     Get git branch name
424     """
425     repo = Repo(repo_path)
426     branch = repo.active_branch
427     return branch.name
428
429
430 def get_installer_type(logger=None):
431     """
432     Get installer type (fuel, foreman, apex, joid, compass)
433     """
434     try:
435         installer = os.environ['INSTALLER_TYPE']
436     except KeyError:
437         if logger:
438             logger.error("Impossible to retrieve the installer type")
439         installer = "Unkown"
440
441     return installer
442
443
444 def get_pod_name(logger=None):
445     """
446     Get PoD Name from env variable NODE_NAME
447     """
448     try:
449         return os.environ['NODE_NAME']
450     except KeyError:
451         if logger:
452             logger.error("Unable to retrieve the POD name from environment.Using pod name 'unknown-pod'")
453         return "unknown-pod"
454
455
456 def push_results_to_db(db_url, case_name, logger, pod_name, git_version, payload):
457     url = db_url + "/results"
458     installer = get_installer_type(logger)
459     params = {"project_name": "functest", "case_name": case_name,
460               "pod_name": pod_name, "installer": installer,
461               "version": git_version, "details": payload}
462
463     headers = {'Content-Type': 'application/json'}
464     try:
465         r = requests.post(url, data=json.dumps(params), headers=headers)
466         logger.debug(r)
467         return True
468     except:
469         print "Error:", sys.exc_info()[0]
470         return False