A non default argument cannot be placed before a default one.
[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 import json
12 import os
13 import os.path
14 import re
15 import requests
16 import shutil
17 import socket
18 import subprocess
19 import sys
20 import urllib2
21 from git import Repo
22
23
24 # ----------------------------------------------------------
25 #
26 #               OPENSTACK UTILS
27 #
28 # -----------------------------------------------------------
29
30
31 #*********************************************
32 #   CREDENTIALS
33 #*********************************************
34 def check_credentials():
35     """
36     Check if the OpenStack credentials (openrc) are sourced
37     """
38     env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_TENANT_NAME']
39     return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
40
41
42 def get_credentials(service):
43     """Returns a creds dictionary filled with the following keys:
44     * username
45     * password/api_key (depending on the service)
46     * tenant_name/project_id (depending on the service)
47     * auth_url
48     :param service: a string indicating the name of the service
49                     requesting the credentials.
50     """
51     creds = {}
52     # Unfortunately, each of the OpenStack client will request slightly
53     # different entries in their credentials dict.
54     if service.lower() in ("nova", "cinder"):
55         password = "api_key"
56         tenant = "project_id"
57     else:
58         password = "password"
59         tenant = "tenant_name"
60
61     # The most common way to pass these info to the script is to do it through
62     # environment variables.
63     creds.update({
64         "username": os.environ.get('OS_USERNAME', "admin"),
65         password: os.environ.get("OS_PASSWORD", 'admin'),
66         "auth_url": os.environ.get("OS_AUTH_URL",
67                                    "http://192.168.20.71:5000/v2.0"),
68         tenant: os.environ.get("OS_TENANT_NAME", "admin"),
69     })
70     ssl = os.environ.get("OS_CACERT")
71     if ssl != None:
72         creds.update({"ca_cert":ssl})
73         if not os.path.isfile(ssl):
74             print "WARNING: The 'OS_CACERT' environment variable is set to %s "\
75                 "but the file does not exist." % ssl
76     return creds
77
78
79 #*********************************************
80 #   NOVA
81 #*********************************************
82 def get_instances(nova_client):
83     try:
84         instances = nova_client.servers.list(search_opts={'all_tenants': 1})
85         return instances
86     except Exception, e:
87         print "Error [get_instances(nova_client)]:", e
88         return None
89
90
91 def get_instance_status(nova_client, instance):
92     try:
93         instance = nova_client.servers.get(instance.id)
94         return instance.status
95     except Exception, e:
96         # print "Error [get_instance_status(nova_client, '%s')]:" % \
97         #    str(instance), e
98         return None
99
100
101 def get_instance_by_name(nova_client, instance_name):
102     try:
103         instance = nova_client.servers.find(name=instance_name)
104         return instance
105     except Exception, e:
106         print "Error [get_instance_by_name(nova_client, '%s')]:" % \
107             instance_name, e
108         return None
109
110
111 def get_flavor_id(nova_client, flavor_name):
112     flavors = nova_client.flavors.list(detailed=True)
113     id = ''
114     for f in flavors:
115         if f.name == flavor_name:
116             id = f.id
117             break
118     return id
119
120
121 def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram):
122     flavors = nova_client.flavors.list(detailed=True)
123     id = ''
124     for f in flavors:
125         if min_ram <= f.ram and f.ram <= max_ram:
126             id = f.id
127             break
128     return id
129
130
131 def get_floating_ips(nova_client):
132     try:
133         floating_ips = nova_client.floating_ips.list()
134         return floating_ips
135     except Exception, e:
136         print "Error [get_floating_ips(nova_client)]:", e
137         return None
138
139
140 def create_flavor(nova_client, flavor_name, ram, disk, vcpus):
141     try:
142         flavor = nova_client.flavors.create(flavor_name, ram, vcpus, disk)
143     except Exception, e:
144         print "Error [create_flavor(nova_client, '%s', '%s', '%s', "\
145             "'%s')]:" % (flavor_name, ram, disk, vcpus), e
146         return None
147     return flavor.id
148
149
150 def create_floating_ip(neutron_client):
151     extnet_id = get_external_net_id(neutron_client)
152     props = {'floating_network_id': extnet_id}
153     try:
154         ip_json = neutron_client.create_floatingip({'floatingip': props})
155         fip_addr = ip_json['floatingip']['floating_ip_address']
156         fip_id = ip_json['floatingip']['id']
157     except Exception, e:
158         print "Error [create_floating_ip(neutron_client)]:", e
159         return None
160     return {'fip_addr': fip_addr, 'fip_id': fip_id}
161
162
163 def add_floating_ip(nova_client, server_id, floatingip_id):
164     try:
165         nova_client.servers.add_floating_ip(server_id, floatingip_id)
166         return True
167     except Exception, e:
168         print "Error [add_floating_ip(nova_client, '%s', '%s')]:" % \
169             (server_id, floatingip_id), e
170         return False
171
172
173 def delete_instance(nova_client, instance_id):
174     try:
175         nova_client.servers.force_delete(instance_id)
176         return True
177     except Exception, e:
178         print "Error [delete_instance(nova_client, '%s')]:" % instance_id, e
179         return False
180
181
182 def delete_floating_ip(nova_client, floatingip_id):
183     try:
184         nova_client.floating_ips.delete(floatingip_id)
185         return True
186     except Exception, e:
187         print "Error [delete_floating_ip(nova_client, '%s')]:" % floatingip_id, e
188         return False
189
190
191 #*********************************************
192 #   NEUTRON
193 #*********************************************
194 def get_network_list(neutron_client):
195     network_list = neutron_client.list_networks()['networks']
196     if len(network_list) == 0:
197         return None
198     else:
199         return network_list
200
201
202 def get_router_list(neutron_client):
203     router_list = neutron_client.list_routers()['routers']
204     if len(router_list) == 0:
205         return None
206     else:
207         return router_list
208
209
210 def get_port_list(neutron_client):
211     port_list = neutron_client.list_ports()['ports']
212     if len(port_list) == 0:
213         return None
214     else:
215         return port_list
216
217
218 def get_network_id(neutron_client, network_name):
219     networks = neutron_client.list_networks()['networks']
220     id = ''
221     for n in networks:
222         if n['name'] == network_name:
223             id = n['id']
224             break
225     return id
226
227
228 def get_subnet_id(neutron_client, subnet_name):
229     subnets = neutron_client.list_subnets()['subnets']
230     id = ''
231     for s in subnets:
232         if s['name'] == subnet_name:
233             id = s['id']
234             break
235     return id
236
237
238 def get_router_id(neutron_client, router_name):
239     routers = neutron_client.list_routers()['routers']
240     id = ''
241     for r in routers:
242         if r['name'] == router_name:
243             id = r['id']
244             break
245     return id
246
247
248 def get_private_net(neutron_client):
249     # Checks if there is an existing shared private network
250     networks = neutron_client.list_networks()['networks']
251     if len(networks) == 0:
252         return None
253     for net in networks:
254         if (net['router:external'] is False) and (net['shared'] is True):
255             return net
256     return None
257
258
259 def get_external_net(neutron_client):
260     for network in neutron_client.list_networks()['networks']:
261         if network['router:external']:
262             return network['name']
263     return False
264
265
266 def get_external_net_id(neutron_client):
267     for network in neutron_client.list_networks()['networks']:
268         if network['router:external']:
269             return network['id']
270     return False
271
272
273 def check_neutron_net(neutron_client, net_name):
274     for network in neutron_client.list_networks()['networks']:
275         if network['name'] == net_name:
276             for subnet in network['subnets']:
277                 return True
278     return False
279
280
281 def create_neutron_net(neutron_client, name):
282     json_body = {'network': {'name': name,
283                              'admin_state_up': True}}
284     try:
285         network = neutron_client.create_network(body=json_body)
286         network_dict = network['network']
287         return network_dict['id']
288     except Exception, e:
289         print "Error [create_neutron_net(neutron_client, '%s')]:" % name, e
290         return False
291
292
293 def create_neutron_subnet(neutron_client, name, cidr, net_id):
294     json_body = {'subnets': [{'name': name, 'cidr': cidr,
295                               'ip_version': 4, 'network_id': net_id}]}
296     try:
297         subnet = neutron_client.create_subnet(body=json_body)
298         return subnet['subnets'][0]['id']
299     except Exception, e:
300         print "Error [create_neutron_subnet(neutron_client, '%s', '%s', "\
301             "'%s')]:" % (name, cidr, net_id), e
302         return False
303
304
305 def create_neutron_router(neutron_client, name):
306     json_body = {'router': {'name': name, 'admin_state_up': True}}
307     try:
308         router = neutron_client.create_router(json_body)
309         return router['router']['id']
310     except Exception, e:
311         print "Error [create_neutron_router(neutron_client, '%s')]:" % name, e
312         return False
313
314
315 def create_neutron_port(neutron_client, name, network_id, ip):
316     json_body = {'port': {
317                  'admin_state_up': True,
318                  'name': name,
319                  'network_id': network_id,
320                  'fixed_ips': [{"ip_address": ip}]
321                  }}
322     try:
323         port = neutron_client.create_port(body=json_body)
324         return port['port']['id']
325     except Exception, e:
326         print "Error [create_neutron_port(neutron_client, '%s', '%s', "\
327             "'%s')]:" % (name, network_id, ip), e
328         return False
329
330
331 def update_neutron_net(neutron_client, network_id, shared=False):
332     json_body = {'network': {'shared': shared}}
333     try:
334         neutron_client.update_network(network_id, body=json_body)
335         return True
336     except Exception, e:
337         print "Error [update_neutron_net(neutron_client, '%s', '%s')]:" % \
338             (network_id, str(shared)), e
339         return False
340
341
342 def update_neutron_port(neutron_client, port_id, device_owner):
343     json_body = {'port': {
344                  'device_owner': device_owner,
345                  }}
346     try:
347         port = neutron_client.update_port(port=port_id,
348                                           body=json_body)
349         return port['port']['id']
350     except Exception, e:
351         print "Error [update_neutron_port(neutron_client, '%s', '%s')]:" % \
352             (port_id, device_owner), e
353         return False
354
355
356 def add_interface_router(neutron_client, router_id, subnet_id):
357     json_body = {"subnet_id": subnet_id}
358     try:
359         neutron_client.add_interface_router(router=router_id, body=json_body)
360         return True
361     except Exception, e:
362         print "Error [add_interface_router(neutron_client, '%s', '%s')]:" % \
363             (router_id, subnet_id), e
364         return False
365
366
367 def add_gateway_router(neutron_client, router_id):
368     ext_net_id = get_external_net_id(neutron_client)
369     router_dict = {'network_id': ext_net_id}
370     try:
371         neutron_client.add_gateway_router(router_id, router_dict)
372         return True
373     except Exception, e:
374         print "Error [add_gateway_router(neutron_client, '%s')]:" % router_id, e
375         return False
376
377
378 def delete_neutron_net(neutron_client, network_id):
379     try:
380         neutron_client.delete_network(network_id)
381         return True
382     except Exception, e:
383         print "Error [delete_neutron_net(neutron_client, '%s')]:" % network_id, e
384         return False
385
386
387 def delete_neutron_subnet(neutron_client, subnet_id):
388     try:
389         neutron_client.delete_subnet(subnet_id)
390         return True
391     except Exception, e:
392         print "Error [delete_neutron_subnet(neutron_client, '%s')]:" % subnet_id, e
393         return False
394
395
396 def delete_neutron_router(neutron_client, router_id):
397     json_body = {'router': {'id': router_id}}
398     try:
399         neutron_client.delete_router(router=router_id)
400         return True
401     except Exception, e:
402         print "Error [delete_neutron_router(neutron_client, '%s')]:" % \
403             router_id, e
404         return False
405
406
407 def delete_neutron_port(neutron_client, port_id):
408     try:
409         neutron_client.delete_port(port_id)
410         return True
411     except Exception, e:
412         print "Error [delete_neutron_port(neutron_client, '%s')]:" % port_id, e
413         return False
414
415
416 def remove_interface_router(neutron_client, router_id, subnet_id):
417     json_body = {"subnet_id": subnet_id}
418     try:
419         neutron_client.remove_interface_router(router=router_id,
420                                                body=json_body)
421         return True
422     except Exception, e:
423         print "Error [remove_interface_router(neutron_client, '%s', '%s')]:" % \
424             (router_id, subnet_id), e
425         return False
426
427
428 def remove_gateway_router(neutron_client, router_id):
429     try:
430         neutron_client.remove_gateway_router(router_id)
431         return True
432     except Exception, e:
433         print "Error [remove_gateway_router(neutron_client, '%s')]:" % router_id, e
434         return False
435
436
437 #*********************************************
438 #   SEC GROUPS
439 #*********************************************
440 def get_security_groups(neutron_client):
441     try:
442         security_groups = neutron_client.list_security_groups()[
443             'security_groups']
444         return security_groups
445     except Exception, e:
446         print "Error [get_security_groups(neutron_client)]:", e
447         return None
448
449
450 def get_security_group_id(neutron_client, sg_name):
451     security_groups = get_security_groups(neutron_client)
452     id = ''
453     for sg in security_groups:
454         if sg['name'] == sg_name:
455             id = sg['id']
456             break
457     return id
458
459
460 def create_security_group(neutron_client, sg_name, sg_description):
461     json_body = {'security_group': {'name': sg_name,
462                                     'description': sg_description}}
463     try:
464         secgroup = neutron_client.create_security_group(json_body)
465         return secgroup['security_group']
466     except Exception, e:
467         print "Error [create_security_group(neutron_client, '%s', '%s')]:" % \
468             (sg_name, sg_description), e
469         return False
470
471
472 def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
473                          port_range_min=None, port_range_max=None):
474     if port_range_min is None and port_range_max is None:
475         json_body = {'security_group_rule': {'direction': direction,
476                                              'security_group_id': sg_id,
477                                              'protocol': protocol}}
478     elif port_range_min is not None and port_range_max is not None:
479         json_body = {'security_group_rule': {'direction': direction,
480                                              'security_group_id': sg_id,
481                                              'port_range_min': port_range_min,
482                                              'port_range_max': port_range_max,
483                                              'protocol': protocol}}
484     else:
485         print "Error [create_secgroup_rule(neutron_client, '%s', '%s', "\
486               "'%s', '%s', '%s', '%s')]:" % (neutron_client, sg_id, direction,
487                                              port_range_min, port_range_max, protocol),\
488               " Invalid values for port_range_min, port_range_max"
489         return False
490     try:
491         neutron_client.create_security_group_rule(json_body)
492         return True
493     except Exception, e:
494         print "Error [create_secgroup_rule(neutron_client, '%s', '%s', "\
495             "'%s', '%s', '%s', '%s')]:" % (neutron_client, sg_id, direction,
496                                            port_range_min, port_range_max,
497                                            protocol), e
498         return False
499
500
501 def add_secgroup_to_instance(nova_client, instance_id, secgroup_id):
502     try:
503         nova_client.servers.add_security_group(instance_id, secgroup_id)
504         return True
505     except Exception, e:
506         print "Error [add_secgroup_to_instance(nova_client, '%s', '%s')]: " % \
507             (instance_id, secgroup_id), e
508         return False
509
510
511 def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
512     json_body = {"quota": {
513         "security_group": sg_quota,
514         "security_group_rule": sg_rule_quota
515     }}
516
517     try:
518         quota = neutron_client.update_quota(tenant_id=tenant_id,
519                                             body=json_body)
520         return True
521     except Exception, e:
522         print "Error [update_sg_quota(neutron_client, '%s', '%s', "\
523             "'%s')]:" % (tenant_id, sg_quota, sg_rule_quota), e
524         return False
525
526
527 def delete_security_group(neutron_client, secgroup_id):
528     try:
529         neutron_client.delete_security_group(secgroup_id)
530         return True
531     except Exception, e:
532         print "Error [delete_security_group(neutron_client, '%s')]:" % secgroup_id, e
533         return False
534
535
536 #*********************************************
537 #   GLANCE
538 #*********************************************
539 def get_images(nova_client):
540     try:
541         images = nova_client.images.list()
542         return images
543     except Exception, e:
544         print "Error [get_images]:", e
545         return None
546
547
548 def get_image_id(glance_client, image_name):
549     images = glance_client.images.list()
550     id = ''
551     for i in images:
552         if i.name == image_name:
553             id = i.id
554             break
555     return id
556
557
558 def create_glance_image(glance_client, image_name, file_path, public=True):
559     if not os.path.isfile(file_path):
560         print "Error: file " + file_path + " does not exist."
561         return False
562     try:
563         with open(file_path) as fimage:
564             image = glance_client.images.create(name=image_name,
565                                                 is_public=public,
566                                                 disk_format="qcow2",
567                                                 container_format="bare",
568                                                 data=fimage)
569         return image.id
570     except Exception, e:
571         print "Error [create_glance_image(glance_client, '%s', '%s', "\
572             "'%s')]:" % (image_name, file_path, str(public)), e
573         return False
574
575
576 def delete_glance_image(nova_client, image_id):
577     try:
578         nova_client.images.delete(image_id)
579         return True
580     except Exception, e:
581         print "Error [delete_glance_image(nova_client, '%s')]:" % image_id, e
582         return False
583
584
585 #*********************************************
586 #   CINDER
587 #*********************************************
588 def get_volumes(cinder_client):
589     try:
590         volumes = cinder_client.volumes.list(search_opts={'all_tenants': 1})
591         return volumes
592     except Exception, e:
593         print "Error [get_volumes(cinder_client)]:", e
594         return None
595
596
597 def list_volume_types(cinder_client, public=True, private=True):
598     try:
599         volume_types = cinder_client.volume_types.list()
600         if not public:
601             volume_types = [vt for vt in volume_types if not vt.is_public]
602         if not private:
603             volume_types = [vt for vt in volume_types if vt.is_public]
604         return volume_types
605     except Exception, e:
606         print "Error [list_volume_types(cinder_client)]:", e
607         return None
608
609
610 def create_volume_type(cinder_client, name):
611     try:
612         volume_type = cinder_client.volume_types.create(name)
613         return volume_type
614     except Exception, e:
615         print "Error [create_volume_type(cinder_client, '%s')]:" % name, e
616         return None
617
618
619 def update_cinder_quota(cinder_client, tenant_id, vols_quota,
620                         snapshots_quota, gigabytes_quota):
621     quotas_values = {"volumes": vols_quota,
622                      "snapshots": snapshots_quota,
623                      "gigabytes": gigabytes_quota}
624
625     try:
626         quotas_default = cinder_client.quotas.update(tenant_id,
627                                                      **quotas_values)
628         return True
629     except Exception, e:
630         print "Error [update_cinder_quota(cinder_client, '%s', '%s', '%s'" \
631             "'%s')]:" % (tenant_id, vols_quota,
632                          snapshots_quota, gigabytes_quota), e
633         return False
634
635
636 def delete_volume(cinder_client, volume_id, forced=False):
637     try:
638         if forced:
639             try:
640                 cinder_client.volumes.detach(volume_id)
641             except:
642                 print "Error:", sys.exc_info()[0]
643             cinder_client.volumes.force_delete(volume_id)
644         else:
645             cinder_client.volumes.delete(volume_id)
646         return True
647     except Exception, e:
648         print "Error [delete_volume(cinder_client, '%s', '%s')]:" % \
649             (volume_id, str(forced)), e
650         return False
651
652
653 def delete_volume_type(cinder_client, volume_type):
654     try:
655         cinder_client.volume_types.delete(volume_type)
656         return True
657     except Exception, e:
658         print "Error [delete_volume_type(cinder_client, '%s')]:" % volume_type, e
659         return False
660
661
662 #*********************************************
663 #   KEYSTONE
664 #*********************************************
665 def get_tenants(keystone_client):
666     try:
667         tenants = keystone_client.tenants.list()
668         return tenants
669     except Exception, e:
670         print "Error [get_tenants(keystone_client)]:", e
671         return None
672
673
674 def get_users(keystone_client):
675     try:
676         users = keystone_client.users.list()
677         return users
678     except Exception, e:
679         print "Error [get_users(keystone_client)]:", e
680         return None
681
682
683 def get_tenant_id(keystone_client, tenant_name):
684     tenants = keystone_client.tenants.list()
685     id = ''
686     for t in tenants:
687         if t.name == tenant_name:
688             id = t.id
689             break
690     return id
691
692
693 def get_user_id(keystone_client, user_name):
694     users = keystone_client.users.list()
695     id = ''
696     for u in users:
697         if u.name == user_name:
698             id = u.id
699             break
700     return id
701
702
703 def get_role_id(keystone_client, role_name):
704     roles = keystone_client.roles.list()
705     id = ''
706     for r in roles:
707         if r.name == role_name:
708             id = r.id
709             break
710     return id
711
712
713 def create_tenant(keystone_client, tenant_name, tenant_description):
714     try:
715         tenant = keystone_client.tenants.create(tenant_name,
716                                                 tenant_description,
717                                                 enabled=True)
718         return tenant.id
719     except Exception, e:
720         print "Error [create_tenant(cinder_client, '%s', '%s')]:" % \
721             (tenant_name, tenant_description), e
722         return False
723
724
725 def create_user(keystone_client, user_name, user_password,
726                 user_email, tenant_id):
727     try:
728         user = keystone_client.users.create(user_name, user_password,
729                                             user_email, tenant_id,
730                                             enabled=True)
731         return user.id
732     except Exception, e:
733         print "Error [create_user(keystone_client, '%s', '%s', '%s'" \
734             "'%s')]:" % (user_name, user_password, user_email, tenant_id), e
735         return False
736
737
738 def add_role_user(keystone_client, user_id, role_id, tenant_id):
739     try:
740         keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
741         return True
742     except Exception, e:
743         print "Error [add_role_user(keystone_client, '%s', '%s'" \
744             "'%s')]:" % (user_id, role_id, tenant_id), e
745         return False
746
747
748 def delete_tenant(keystone_client, tenant_id):
749     try:
750         tenant = keystone_client.tenants.delete(tenant_id)
751         return True
752     except Exception, e:
753         print "Error [delete_tenant(keystone_client, '%s')]:" % tenant_id, e
754         return False
755
756
757 def delete_user(keystone_client, user_id):
758     try:
759         tenant = keystone_client.users.delete(user_id)
760         return True
761     except Exception, e:
762         print "Error [delete_user(keystone_client, '%s')]:" % user_id, e
763         return False
764
765
766 # ----------------------------------------------------------
767 #
768 #               INTERNET UTILS
769 #
770 # -----------------------------------------------------------
771 def check_internet_connectivity(url='http://www.opnfv.org/'):
772     """
773     Check if there is access to the internet
774     """
775     try:
776         urllib2.urlopen(url, timeout=5)
777         return True
778     except urllib2.URLError:
779         return False
780
781
782 def download_url(url, dest_path):
783     """
784     Download a file to a destination path given a URL
785     """
786     name = url.rsplit('/')[-1]
787     dest = dest_path + "/" + name
788     try:
789         response = urllib2.urlopen(url)
790     except (urllib2.HTTPError, urllib2.URLError):
791         return False
792
793     with open(dest, 'wb') as f:
794         shutil.copyfileobj(response, f)
795     return True
796
797
798 # ----------------------------------------------------------
799 #
800 #               CI UTILS
801 #
802 # -----------------------------------------------------------
803 def get_git_branch(repo_path):
804     """
805     Get git branch name
806     """
807     repo = Repo(repo_path)
808     branch = repo.active_branch
809     return branch.name
810
811
812 def get_installer_type(logger=None):
813     """
814     Get installer type (fuel, apex, joid, compass)
815     """
816     try:
817         installer = os.environ['INSTALLER_TYPE']
818     except KeyError:
819         if logger:
820             logger.error("Impossible to retrieve the installer type")
821         installer = "Unknown_installer"
822
823     return installer
824
825
826 def get_scenario(logger=None):
827     """
828     Get scenario
829     """
830     try:
831         scenario = os.environ['DEPLOY_SCENARIO']
832     except KeyError:
833         if logger:
834             logger.error("Impossible to retrieve the scenario")
835         scenario = "Unknown_scenario"
836
837     return scenario
838
839
840 def get_pod_name(logger=None):
841     """
842     Get PoD Name from env variable NODE_NAME
843     """
844     try:
845         return os.environ['NODE_NAME']
846     except KeyError:
847         if logger:
848             logger.error(
849                 "Unable to retrieve the POD name from environment.Using pod name 'unknown-pod'")
850         return "unknown-pod"
851
852
853 def get_build_tag(logger=None):
854     """
855     Get build tag of jenkins jobs
856     """
857     try:
858         build_tag = os.environ['BUILD_TAG']
859     except KeyError:
860         if logger:
861             logger.error("Impossible to retrieve the build tag")
862         build_tag = "unknown_build_tag"
863
864     return build_tag
865
866
867 def push_results_to_db(db_url, project, case_name, logger, pod_name,
868                        version, build_tag, payload):
869     """
870     POST results to the Result target DB
871     """
872     url = db_url + "/results"
873     installer = get_installer_type(logger)
874     params = {"project_name": project, "case_name": case_name,
875               "pod_name": pod_name, "installer": installer,
876               "version": version, "build_tag": build_tag, "details": payload}
877
878     headers = {'Content-Type': 'application/json'}
879     try:
880         r = requests.post(url, data=json.dumps(params), headers=headers)
881         if logger:
882             logger.debug(r)
883         return True
884     except Exception, e:
885         print "Error [push_results_to_db('%s', '%s', '%s', '%s', '%s', '%s', '%s')]:" \
886             % (db_url, project, case_name, pod_name, version, build_tag, payload), e
887         return False
888
889
890 def get_resolvconf_ns():
891     """
892     Get nameservers from current resolv.conf
893     """
894     nameservers = []
895     rconf = open("/etc/resolv.conf", "r")
896     line = rconf.readline()
897     while line:
898         ip = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b", line)
899         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
900         if ip:
901             result = sock.connect_ex((ip.group(), 53))
902             if result == 0:
903                 nameservers.append(ip.group())
904         line = rconf.readline()
905     return nameservers
906
907
908 def getTestEnv(test, functest_yaml):
909     """
910     Get the config of the testcase based on functest_config.yaml
911       2 options
912         - test = test project e.g; ovno
913         - test = testcase e.g. functest/odl
914        look for the / to see if it is a test project or a testcase
915     """
916     try:
917         TEST_ENV = functest_yaml.get("test-dependencies")
918
919         if test.find("/") < 0:
920             config_test = TEST_ENV[test]
921         else:
922             test_split = test.split("/")
923             testproject = test_split[0]
924             testcase = test_split[1]
925             config_test = TEST_ENV[testproject][testcase]
926     except KeyError:
927         # if not defined in dependencies => no dependencies
928         config_test = ""
929     except Exception, e:
930         print "Error [getTestEnv]:", e
931
932     return config_test
933
934
935 def get_ci_envvars():
936     """
937     Get the CI env variables
938     """
939     ci_env_var = {
940         "installer": os.environ.get('INSTALLER_TYPE'),
941         "scenario": os.environ.get('DEPLOY_SCENARIO')}
942     return ci_env_var
943
944
945 def isTestRunnable(test, functest_yaml):
946     """
947     Return True if the test is runnable in the current scenario
948     """
949     # By default we assume that all the tests are always runnable...
950     is_runnable = True
951     # Retrieve CI environment
952     ci_env = get_ci_envvars()
953     # Retrieve test environement from config file
954     test_env = getTestEnv(test, functest_yaml)
955
956     # if test_env not empty => dependencies to be checked
957     if test_env is not None and len(test_env) > 0:
958         # possible criteria = ["installer", "scenario"]
959         # consider test criteria from config file
960         # compare towards CI env through CI en variable
961         for criteria in test_env:
962             if re.search(test_env[criteria], ci_env[criteria]) is None:
963                 # print "Test "+ test + " cannot be run on the environment"
964                 is_runnable = False
965     return is_runnable
966
967
968 def generateTestcaseList(functest_yaml):
969     """
970     Generate a test file with the runnable test according to
971     the current scenario
972     """
973     test_list = ""
974     # get testcases
975     testcase_list = functest_yaml.get("test-dependencies")
976     projects = testcase_list.keys()
977
978     for project in projects:
979         testcases = testcase_list[project]
980         # 1 or 2 levels for testcases project[/case]l
981         # if only project name without controller or scenario
982         # => shall be runnable on any controller/scenario
983         if testcases is None:
984             test_list += project + " "
985         else:
986             for testcase in testcases:
987                 if testcase == "installer" or testcase == "scenario":
988                     # project (1 level)
989                     if isTestRunnable(project, functest_yaml):
990                         test_list += project + " "
991                 else:
992                     # project/testcase (2 levels)
993                     thetest = project + "/" + testcase
994                     if isTestRunnable(thetest, functest_yaml):
995                         test_list += testcase + " "
996
997     # sort the list to execute the test in the right order
998     test_order_list = functest_yaml.get("test_exec_priority")
999     test_sorted_list = ""
1000     for test in test_order_list:
1001         if test_order_list[test] in test_list:
1002             test_sorted_list += test_order_list[test] + " "
1003
1004     # create a file that could be consumed by run-test.sh
1005     # this method is used only for CI
1006     # so it can be run only in container
1007     # reuse default conf directory to store the list of runnable tests
1008     file = open("/home/opnfv/functest/conf/testcase-list.txt", 'w')
1009     file.write(test_sorted_list)
1010     file.close()
1011
1012     return test_sorted_list
1013
1014
1015 def execute_command(cmd, logger=None, exit_on_error=True):
1016     """
1017     Execute Linux command
1018         prints stdout to a file and depending on if there
1019         is a logger defined, it will print it or not.
1020     """
1021     if logger:
1022         logger.debug('Executing command : {}'.format(cmd))
1023     output_file = "output.txt"
1024     f = open(output_file, 'w+')
1025     p = subprocess.call(cmd, shell=True, stdout=f, stderr=subprocess.STDOUT)
1026     f.close()
1027     f = open(output_file, 'r')
1028     result = f.read()
1029     if result != "" and logger:
1030         logger.debug(result)
1031     if p == 0:
1032         return True
1033     else:
1034         if logger:
1035             logger.error("Error when executing command %s" % cmd)
1036         if exit_on_error:
1037             exit(-1)
1038         return False