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