Merge "Support for customized tempest case list"
[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 os.path
14 import urllib2
15 import subprocess
16 import sys
17 import requests
18 import json
19 import shutil
20 from git import Repo
21
22
23 # ############ CREDENTIALS OPENSTACK #############
24 def check_credentials():
25     """
26     Check if the OpenStack credentials (openrc) are sourced
27     """
28     env_vars = ['OS_AUTH_URL','OS_USERNAME','OS_PASSWORD','OS_TENANT_NAME']
29     return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
30
31
32 def get_credentials(service):
33     """Returns a creds dictionary filled with the following keys:
34     * username
35     * password/api_key (depending on the service)
36     * tenant_name/project_id (depending on the service)
37     * auth_url
38     :param service: a string indicating the name of the service
39                     requesting the credentials.
40     """
41     creds = {}
42     # Unfortunately, each of the OpenStack client will request slightly
43     # different entries in their credentials dict.
44     if service.lower() in ("nova", "cinder"):
45         password = "api_key"
46         tenant = "project_id"
47     else:
48         password = "password"
49         tenant = "tenant_name"
50
51     # The most common way to pass these info to the script is to do it through
52     # environment variables.
53     creds.update({
54         "username": os.environ.get('OS_USERNAME', "admin"),
55         password: os.environ.get("OS_PASSWORD", 'admin'),
56         "auth_url": os.environ.get("OS_AUTH_URL",
57                                    "http://192.168.20.71:5000/v2.0"),
58         tenant: os.environ.get("OS_TENANT_NAME", "admin"),
59     })
60
61     return creds
62
63
64 # ################ NOVA #################
65 def get_instances(nova_client):
66     try:
67         instances = nova_client.servers.list(search_opts={'all_tenants': 1})
68         return instances
69     except:
70         return None
71
72 def get_instance_status(nova_client, instance):
73     try:
74         instance = nova_client.servers.get(instance.id)
75         return instance.status
76     except:
77         return None
78
79 def get_instance_by_name(nova_client, instance_name):
80     try:
81         instance = nova_client.servers.find(name=instance_name)
82         return instance
83     except:
84         return None
85
86
87
88 def get_flavor_id(nova_client, flavor_name):
89     flavors = nova_client.flavors.list(detailed=True)
90     id = ''
91     for f in flavors:
92         if f.name == flavor_name:
93             id = f.id
94             break
95     return id
96
97
98 def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram):
99     flavors = nova_client.flavors.list(detailed=True)
100     id = ''
101     for f in flavors:
102         if min_ram <= f.ram and f.ram <= max_ram:
103             id = f.id
104             break
105     return id
106
107
108 def delete_instance(nova_client, instance_id):
109     try:
110         nova_client.servers.force_delete(instance_id)
111         return True
112     except:
113         print "Error:", sys.exc_info()[0]
114         return False
115
116
117 def get_floating_ips(nova_client):
118     try:
119         floating_ips = nova_client.floating_ips.list()
120         return floating_ips
121     except:
122         return None
123
124 def delete_floating_ip(nova_client, floatingip_id):
125     try:
126         nova_client.floating_ips.delete(floatingip_id)
127         return True
128     except:
129         print "Error:", sys.exc_info()[0]
130         return None
131
132
133 # ################ NEUTRON #################
134 def create_neutron_net(neutron_client, name):
135     json_body = {'network': {'name': name,
136                              'admin_state_up': True}}
137     try:
138         network = neutron_client.create_network(body=json_body)
139         network_dict = network['network']
140         return network_dict['id']
141     except:
142         print "Error:", sys.exc_info()[0]
143         return False
144
145
146 def delete_neutron_net(neutron_client, network_id):
147     try:
148         neutron_client.delete_network(network_id)
149         return True
150     except:
151         print "Error:", sys.exc_info()[0]
152         return False
153
154
155 def create_neutron_subnet(neutron_client, name, cidr, net_id):
156     json_body = {'subnets': [{'name': name, 'cidr': cidr,
157                              'ip_version': 4, 'network_id': net_id}]}
158     try:
159         subnet = neutron_client.create_subnet(body=json_body)
160         return subnet['subnets'][0]['id']
161     except:
162         print "Error:", sys.exc_info()[0]
163         return False
164
165
166 def delete_neutron_subnet(neutron_client, subnet_id):
167     try:
168         neutron_client.delete_subnet(subnet_id)
169         return True
170     except:
171         print "Error:", sys.exc_info()[0]
172         return False
173
174
175 def create_neutron_router(neutron_client, name):
176     json_body = {'router': {'name': name, 'admin_state_up': True}}
177     try:
178         router = neutron_client.create_router(json_body)
179         return router['router']['id']
180     except:
181         print "Error:", sys.exc_info()[0]
182         return False
183
184
185 def delete_neutron_router(neutron_client, router_id):
186     json_body = {'router': {'id': router_id}}
187     try:
188         neutron_client.delete_router(router=router_id)
189         return True
190     except:
191         print "Error:", sys.exc_info()[0]
192         return False
193
194
195 def add_interface_router(neutron_client, router_id, subnet_id):
196     json_body = {"subnet_id": subnet_id}
197     try:
198         neutron_client.add_interface_router(router=router_id, body=json_body)
199         return True
200     except:
201         print "Error:", sys.exc_info()[0]
202         return False
203
204
205 def remove_interface_router(neutron_client, router_id, subnet_id):
206     json_body = {"subnet_id": subnet_id}
207     try:
208         neutron_client.remove_interface_router(router=router_id,
209                                                body=json_body)
210         return True
211     except:
212         print "Error:", sys.exc_info()[0]
213         return False
214
215 def remove_gateway_router(neutron_client, router_id):
216     try:
217         neutron_client.remove_gateway_router(router_id)
218         return True
219     except:
220         print "Error:", sys.exc_info()[0]
221         return False
222
223
224 def create_neutron_port(neutron_client, name, network_id, ip):
225     json_body = {'port': {
226                  'admin_state_up': True,
227                  'name': name,
228                  'network_id': network_id,
229                  'fixed_ips': [{"ip_address": ip}]
230                  }}
231     try:
232         port = neutron_client.create_port(body=json_body)
233         return port['port']['id']
234     except:
235         print "Error:", sys.exc_info()[0]
236         return False
237
238
239 def update_neutron_port(neutron_client, port_id, device_owner):
240     json_body = {'port': {
241                  'device_owner': device_owner,
242                  }}
243     try:
244         port = neutron_client.update_port(port=port_id,
245                                           body=json_body)
246         return port['port']['id']
247     except:
248         print "Error:", sys.exc_info()[0]
249         return False
250
251
252 def delete_neutron_port(neutron_client, port_id):
253     try:
254         neutron_client.delete_port(port_id)
255         return True
256     except:
257         print "Error:", sys.exc_info()[0]
258         return False
259
260
261 def get_network_id(neutron_client, network_name):
262     networks = neutron_client.list_networks()['networks']
263     id = ''
264     for n in networks:
265         if n['name'] == network_name:
266             id = n['id']
267             break
268     return id
269
270
271 def check_neutron_net(neutron_client, net_name):
272     for network in neutron_client.list_networks()['networks']:
273         if network['name'] == net_name:
274             for subnet in network['subnets']:
275                 return True
276     return False
277
278
279 def get_network_list(neutron_client):
280     network_list = neutron_client.list_networks()['networks']
281     if len(network_list) == 0:
282         return None
283     else:
284         return network_list
285
286
287 def get_router_list(neutron_client):
288     router_list = neutron_client.list_routers()['routers']
289     if len(router_list) == 0:
290         return None
291     else:
292         return router_list
293
294 def get_port_list(neutron_client):
295     port_list = neutron_client.list_ports()['ports']
296     if len(port_list) == 0:
297         return None
298     else:
299         return port_list
300
301
302
303 def get_external_net(neutron_client):
304     for network in neutron_client.list_networks()['networks']:
305         if network['router:external']:
306             return network['name']
307     return False
308
309
310 def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
311     json_body = {"quota": {
312         "security_group": sg_quota,
313         "security_group_rule": sg_rule_quota
314     }}
315
316     try:
317         quota = neutron_client.update_quota(tenant_id=tenant_id,
318                                             body=json_body)
319         return True
320     except:
321         print "Error:", sys.exc_info()[0]
322         return False
323
324
325 def get_private_net(neutron_client):
326     # Checks if there is an existing private network
327     networks = neutron_client.list_networks()['networks']
328     if len(networks) == 0:
329         return None
330     for net in networks:
331         if net['router:external'] == False:
332             return net
333     return None
334
335 # ################ GLANCE #################
336 def get_images(nova_client):
337     try:
338         images = nova_client.images.list()
339         return images
340     except:
341         return None
342
343
344 def get_image_id(glance_client, image_name):
345     images = glance_client.images.list()
346     id = ''
347     for i in images:
348         if i.name == image_name:
349             id = i.id
350             break
351     return id
352
353
354 def create_glance_image(glance_client, image_name, file_path, public=True):
355     if not os.path.isfile(file_path):
356         print "Error: file "+file_path+" does not exist."
357         return False
358     try:
359         with open(file_path) as fimage:
360             image = glance_client.images.create(name=image_name,
361                                                 is_public=public,
362                                                 disk_format="qcow2",
363                                                 container_format="bare",
364                                                 data=fimage)
365         return image.id
366     except:
367         print "Error:", sys.exc_info()[0]
368         return False
369
370 def delete_glance_image(nova_client, image_id):
371     try:
372         nova_client.images.delete(image_id)
373         return True
374     except:
375         print "Error:", sys.exc_info()[0]
376         return False
377
378 # ################ CINDER #################
379 def get_volumes(cinder_client):
380     try:
381         volumes = cinder_client.volumes.list(search_opts={'all_tenants': 1})
382         return volumes
383     except:
384         return None
385
386 def delete_volume(cinder_client, volume_id):
387     try:
388         cinder_client.volumes.delete(volume_id)
389         return True
390     except:
391         print "Error:", sys.exc_info()[0]
392         return False
393
394 # ################ CINDER #################
395 def get_security_groups(neutron_client):
396     try:
397         security_groups = neutron_client.list_security_groups()['security_groups']
398         return security_groups
399     except:
400         return None
401
402 def delete_security_group(neutron_client, secgroup_id):
403     try:
404         neutron_client.delete_security_group(secgroup_id)
405         return True
406     except:
407         print "Error:", sys.exc_info()[0]
408         return False
409
410
411 # ################ KEYSTONE #################
412 def get_tenants(keystone_client):
413     try:
414         tenants = keystone_client.tenants.list()
415         return tenants
416     except:
417         return None
418
419
420 def get_tenant_id(keystone_client, tenant_name):
421     tenants = keystone_client.tenants.list()
422     id = ''
423     for t in tenants:
424         if t.name == tenant_name:
425             id = t.id
426             break
427     return id
428
429 def get_users(keystone_client):
430     try:
431         users = keystone_client.users.list()
432         return users
433     except:
434         return None
435
436 def get_role_id(keystone_client, role_name):
437     roles = keystone_client.roles.list()
438     id = ''
439     for r in roles:
440         if r.name == role_name:
441             id = r.id
442             break
443     return id
444
445
446 def get_user_id(keystone_client, user_name):
447     users = keystone_client.users.list()
448     id = ''
449     for u in users:
450         if u.name == user_name:
451             id = u.id
452             break
453     return id
454
455
456 def create_tenant(keystone_client, tenant_name, tenant_description):
457     try:
458         tenant = keystone_client.tenants.create(tenant_name,
459                                                 tenant_description,
460                                                 enabled=True)
461         return tenant.id
462     except:
463         print "Error:", sys.exc_info()[0]
464         return False
465
466
467 def delete_tenant(keystone_client, tenant_id):
468     try:
469         tenant = keystone_client.tenants.delete(tenant_id)
470         return True
471     except:
472         print "Error:", sys.exc_info()[0]
473         return False
474
475
476 def create_user(keystone_client, user_name, user_password,
477                 user_email, tenant_id):
478     try:
479         user = keystone_client.users.create(user_name, user_password,
480                                             user_email, tenant_id,
481                                             enabled=True)
482         return user.id
483     except:
484         print "Error:", sys.exc_info()[0]
485         return False
486
487
488 def delete_user(keystone_client, user_id):
489     try:
490         tenant = keystone_client.users.delete(user_id)
491         return True
492     except:
493         print "Error:", sys.exc_info()[0]
494         return False
495
496
497 def add_role_user(keystone_client, user_id, role_id, tenant_id):
498     try:
499         keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
500         return True
501     except:
502         print "Error:", sys.exc_info()[0]
503         return False
504
505
506 # ################ UTILS #################
507 def check_internet_connectivity(url='http://www.opnfv.org/'):
508     """
509     Check if there is access to the internet
510     """
511     try:
512         urllib2.urlopen(url, timeout=5)
513         return True
514     except urllib2.URLError:
515         return False
516
517
518 def download_url(url, dest_path):
519     """
520     Download a file to a destination path given a URL
521     """
522     name = url.rsplit('/')[-1]
523     dest = dest_path + "/" + name
524     try:
525         response = urllib2.urlopen(url)
526     except (urllib2.HTTPError, urllib2.URLError):
527         return False
528
529     with open(dest, 'wb') as f:
530         shutil.copyfileobj(response, f)
531     return True
532
533
534 def execute_command(cmd, logger=None):
535     """
536     Execute Linux command
537     """
538     if logger:
539         logger.debug('Executing command : {}'.format(cmd))
540     output_file = "output.txt"
541     f = open(output_file, 'w+')
542     p = subprocess.call(cmd, shell=True, stdout=f, stderr=subprocess.STDOUT)
543     f.close()
544     f = open(output_file, 'r')
545     result = f.read()
546     if result != "" and logger:
547         logger.debug(result)
548     if p == 0:
549         return True
550     else:
551         if logger:
552             logger.error("Error when executing command %s" % cmd)
553         exit(-1)
554
555
556 def get_git_branch(repo_path):
557     """
558     Get git branch name
559     """
560     repo = Repo(repo_path)
561     branch = repo.active_branch
562     return branch.name
563
564
565 def get_installer_type(logger=None):
566     """
567     Get installer type (fuel, foreman, apex, joid, compass)
568     """
569     try:
570         installer = os.environ['INSTALLER_TYPE']
571     except KeyError:
572         if logger:
573             logger.error("Impossible to retrieve the installer type")
574         installer = "Unkown"
575
576     return installer
577
578
579 def get_pod_name(logger=None):
580     """
581     Get PoD Name from env variable NODE_NAME
582     """
583     try:
584         return os.environ['NODE_NAME']
585     except KeyError:
586         if logger:
587             logger.error("Unable to retrieve the POD name from environment.Using pod name 'unknown-pod'")
588         return "unknown-pod"
589
590
591 def push_results_to_db(db_url, case_name, logger, pod_name, git_version, payload):
592     url = db_url + "/results"
593     installer = get_installer_type(logger)
594     params = {"project_name": "functest", "case_name": case_name,
595               "pod_name": pod_name, "installer": installer,
596               "version": git_version, "details": payload}
597
598     headers = {'Content-Type': 'application/json'}
599     try:
600         r = requests.post(url, data=json.dumps(params), headers=headers)
601         logger.debug(r)
602         return True
603     except:
604         print "Error:", sys.exc_info()[0]
605         return False