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