Introduce a sanity test mode for Rally test
[functest-xtesting.git] / testcases / openstack_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 os
12 import os.path
13 import sys
14
15 # ----------------------------------------------------------
16 #
17 #               OPENSTACK UTILS
18 #
19 # -----------------------------------------------------------
20
21
22 # *********************************************
23 #   CREDENTIALS
24 # *********************************************
25 def check_credentials():
26     """
27     Check if the OpenStack credentials (openrc) are sourced
28     """
29     env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_TENANT_NAME']
30     return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
31
32
33 def get_credentials(service):
34     """Returns a creds dictionary filled with the following keys:
35     * username
36     * password/api_key (depending on the service)
37     * tenant_name/project_id (depending on the service)
38     * auth_url
39     :param service: a string indicating the name of the service
40                     requesting the credentials.
41     """
42     creds = {}
43     # Unfortunately, each of the OpenStack client will request slightly
44     # different entries in their credentials dict.
45     if service.lower() in ("nova", "cinder"):
46         password = "api_key"
47         tenant = "project_id"
48     else:
49         password = "password"
50         tenant = "tenant_name"
51
52     # The most common way to pass these info to the script is to do it through
53     # environment variables.
54     creds.update({
55         "username": os.environ.get('OS_USERNAME', "admin"),
56         password: os.environ.get("OS_PASSWORD", 'admin'),
57         "auth_url": os.environ.get("OS_AUTH_URL",
58                                    "http://192.168.20.71:5000/v2.0"),
59         tenant: os.environ.get("OS_TENANT_NAME", "admin"),
60     })
61     cacert = os.environ.get("OS_CACERT")
62     if cacert is not None:
63         # each openstack client uses differnt kwargs for this
64         creds.update({"cacert": cacert,
65                       "ca_cert": cacert,
66                       "https_ca_cert": cacert,
67                       "https_cacert": cacert,
68                       "ca_file": cacert})
69         creds.update({"insecure": "True", "https_insecure": "True"})
70         if not os.path.isfile(cacert):
71             print "WARNING: The 'OS_CACERT' environment variable is " + \
72                 "set to %s but the file does not exist." % cacert
73     return creds
74
75
76 # *********************************************
77 #   NOVA
78 # *********************************************
79 def get_instances(nova_client):
80     try:
81         instances = nova_client.servers.list(search_opts={'all_tenants': 1})
82         return instances
83     except Exception, e:
84         print "Error [get_instances(nova_client)]:", e
85         return None
86
87
88 def get_instance_status(nova_client, instance):
89     try:
90         instance = nova_client.servers.get(instance.id)
91         return instance.status
92     except:
93         # print "Error [get_instance_status(nova_client, '%s')]:" % \
94         #    str(instance), e
95         return None
96
97
98 def get_instance_by_name(nova_client, instance_name):
99     try:
100         instance = nova_client.servers.find(name=instance_name)
101         return instance
102     except Exception, e:
103         print "Error [get_instance_by_name(nova_client, '%s')]:" % \
104             instance_name, e
105         return None
106
107
108 def get_flavor_id(nova_client, flavor_name):
109     flavors = nova_client.flavors.list(detailed=True)
110     id = ''
111     for f in flavors:
112         if f.name == flavor_name:
113             id = f.id
114             break
115     return id
116
117
118 def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram):
119     flavors = nova_client.flavors.list(detailed=True)
120     id = ''
121     for f in flavors:
122         if min_ram <= f.ram and f.ram <= max_ram:
123             id = f.id
124             break
125     return id
126
127
128 def get_floating_ips(nova_client):
129     try:
130         floating_ips = nova_client.floating_ips.list()
131         return floating_ips
132     except Exception, e:
133         print "Error [get_floating_ips(nova_client)]:", e
134         return None
135
136
137 def create_flavor(nova_client, flavor_name, ram, disk, vcpus):
138     try:
139         flavor = nova_client.flavors.create(flavor_name, ram, vcpus, disk)
140     except Exception, e:
141         print "Error [create_flavor(nova_client, '%s', '%s', '%s', "\
142             "'%s')]:" % (flavor_name, ram, disk, vcpus), e
143         return None
144     return flavor.id
145
146
147 def create_floating_ip(neutron_client):
148     extnet_id = get_external_net_id(neutron_client)
149     props = {'floating_network_id': extnet_id}
150     try:
151         ip_json = neutron_client.create_floatingip({'floatingip': props})
152         fip_addr = ip_json['floatingip']['floating_ip_address']
153         fip_id = ip_json['floatingip']['id']
154     except Exception, e:
155         print "Error [create_floating_ip(neutron_client)]:", e
156         return None
157     return {'fip_addr': fip_addr, 'fip_id': fip_id}
158
159
160 def add_floating_ip(nova_client, server_id, floatingip_id):
161     try:
162         nova_client.servers.add_floating_ip(server_id, floatingip_id)
163         return True
164     except Exception, e:
165         print "Error [add_floating_ip(nova_client, '%s', '%s')]:" % \
166             (server_id, floatingip_id), e
167         return False
168
169
170 def delete_instance(nova_client, instance_id):
171     try:
172         nova_client.servers.force_delete(instance_id)
173         return True
174     except Exception, e:
175         print "Error [delete_instance(nova_client, '%s')]:" % instance_id, e
176         return False
177
178
179 def delete_floating_ip(nova_client, floatingip_id):
180     try:
181         nova_client.floating_ips.delete(floatingip_id)
182         return True
183     except Exception, e:
184         print "Error [delete_floating_ip(nova_client, '%s')]:" \
185             % floatingip_id, e
186         return False
187
188
189 # *********************************************
190 #   NEUTRON
191 # *********************************************
192 def get_network_list(neutron_client):
193     network_list = neutron_client.list_networks()['networks']
194     if len(network_list) == 0:
195         return None
196     else:
197         return network_list
198
199
200 def get_router_list(neutron_client):
201     router_list = neutron_client.list_routers()['routers']
202     if len(router_list) == 0:
203         return None
204     else:
205         return router_list
206
207
208 def get_port_list(neutron_client):
209     port_list = neutron_client.list_ports()['ports']
210     if len(port_list) == 0:
211         return None
212     else:
213         return port_list
214
215
216 def get_network_id(neutron_client, network_name):
217     networks = neutron_client.list_networks()['networks']
218     id = ''
219     for n in networks:
220         if n['name'] == network_name:
221             id = n['id']
222             break
223     return id
224
225
226 def get_subnet_id(neutron_client, subnet_name):
227     subnets = neutron_client.list_subnets()['subnets']
228     id = ''
229     for s in subnets:
230         if s['name'] == subnet_name:
231             id = s['id']
232             break
233     return id
234
235
236 def get_router_id(neutron_client, router_name):
237     routers = neutron_client.list_routers()['routers']
238     id = ''
239     for r in routers:
240         if r['name'] == router_name:
241             id = r['id']
242             break
243     return id
244
245
246 def get_private_net(neutron_client):
247     # Checks if there is an existing shared private network
248     networks = neutron_client.list_networks()['networks']
249     if len(networks) == 0:
250         return None
251     for net in networks:
252         if (net['router:external'] is False) and (net['shared'] is True):
253             return net
254     return None
255
256
257 def get_external_net(neutron_client):
258     for network in neutron_client.list_networks()['networks']:
259         if network['router:external']:
260             return network['name']
261     return False
262
263
264 def get_external_net_id(neutron_client):
265     for network in neutron_client.list_networks()['networks']:
266         if network['router:external']:
267             return network['id']
268     return False
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 create_neutron_net(neutron_client, name):
280     json_body = {'network': {'name': name,
281                              'admin_state_up': True}}
282     try:
283         network = neutron_client.create_network(body=json_body)
284         network_dict = network['network']
285         return network_dict['id']
286     except Exception, e:
287         print "Error [create_neutron_net(neutron_client, '%s')]:" % name, e
288         return False
289
290
291 def create_neutron_subnet(neutron_client, name, cidr, net_id):
292     json_body = {'subnets': [{'name': name, 'cidr': cidr,
293                               'ip_version': 4, 'network_id': net_id}]}
294     try:
295         subnet = neutron_client.create_subnet(body=json_body)
296         return subnet['subnets'][0]['id']
297     except Exception, e:
298         print "Error [create_neutron_subnet(neutron_client, '%s', '%s', "\
299             "'%s')]:" % (name, cidr, net_id), e
300         return False
301
302
303 def create_neutron_router(neutron_client, name):
304     json_body = {'router': {'name': name, 'admin_state_up': True}}
305     try:
306         router = neutron_client.create_router(json_body)
307         return router['router']['id']
308     except Exception, e:
309         print "Error [create_neutron_router(neutron_client, '%s')]:" % name, e
310         return False
311
312
313 def create_neutron_port(neutron_client, name, network_id, ip):
314     json_body = {'port': {
315                  'admin_state_up': True,
316                  'name': name,
317                  'network_id': network_id,
318                  'fixed_ips': [{"ip_address": ip}]
319                  }}
320     try:
321         port = neutron_client.create_port(body=json_body)
322         return port['port']['id']
323     except Exception, e:
324         print "Error [create_neutron_port(neutron_client, '%s', '%s', "\
325             "'%s')]:" % (name, network_id, ip), e
326         return False
327
328
329 def update_neutron_net(neutron_client, network_id, shared=False):
330     json_body = {'network': {'shared': shared}}
331     try:
332         neutron_client.update_network(network_id, body=json_body)
333         return True
334     except Exception, e:
335         print "Error [update_neutron_net(neutron_client, '%s', '%s')]:" % \
336             (network_id, str(shared)), e
337         return False
338
339
340 def update_neutron_port(neutron_client, port_id, device_owner):
341     json_body = {'port': {
342                  'device_owner': device_owner,
343                  }}
344     try:
345         port = neutron_client.update_port(port=port_id,
346                                           body=json_body)
347         return port['port']['id']
348     except Exception, e:
349         print "Error [update_neutron_port(neutron_client, '%s', '%s')]:" % \
350             (port_id, device_owner), e
351         return False
352
353
354 def add_interface_router(neutron_client, router_id, subnet_id):
355     json_body = {"subnet_id": subnet_id}
356     try:
357         neutron_client.add_interface_router(router=router_id, body=json_body)
358         return True
359     except Exception, e:
360         print "Error [add_interface_router(neutron_client, '%s', '%s')]:" % \
361             (router_id, subnet_id), e
362         return False
363
364
365 def add_gateway_router(neutron_client, router_id):
366     ext_net_id = get_external_net_id(neutron_client)
367     router_dict = {'network_id': ext_net_id}
368     try:
369         neutron_client.add_gateway_router(router_id, router_dict)
370         return True
371     except Exception, e:
372         print "Error [add_gateway_router(neutron_client, '%s')]:" \
373             % router_id, e
374         return False
375
376
377 def delete_neutron_net(neutron_client, network_id):
378     try:
379         neutron_client.delete_network(network_id)
380         return True
381     except Exception, e:
382         print "Error [delete_neutron_net(neutron_client, '%s')]:" \
383             % 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')]:" \
393             % subnet_id, e
394         return False
395
396
397 def delete_neutron_router(neutron_client, 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')]:" \
434             % router_id, e
435         return False
436
437
438 # *********************************************
439 #   SEC GROUPS
440 # *********************************************
441 def get_security_groups(neutron_client):
442     try:
443         security_groups = neutron_client.list_security_groups()[
444             'security_groups']
445         return security_groups
446     except Exception, e:
447         print "Error [get_security_groups(neutron_client)]:", e
448         return None
449
450
451 def get_security_group_id(neutron_client, sg_name):
452     security_groups = get_security_groups(neutron_client)
453     id = ''
454     for sg in security_groups:
455         if sg['name'] == sg_name:
456             id = sg['id']
457             break
458     return id
459
460
461 def create_security_group(neutron_client, sg_name, sg_description):
462     json_body = {'security_group': {'name': sg_name,
463                                     'description': sg_description}}
464     try:
465         secgroup = neutron_client.create_security_group(json_body)
466         return secgroup['security_group']
467     except Exception, e:
468         print "Error [create_security_group(neutron_client, '%s', '%s')]:" % \
469             (sg_name, sg_description), e
470         return False
471
472
473 def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
474                          port_range_min=None, port_range_max=None):
475     if port_range_min is None and port_range_max is None:
476         json_body = {'security_group_rule': {'direction': direction,
477                                              'security_group_id': sg_id,
478                                              'protocol': protocol}}
479     elif port_range_min is not None and port_range_max is not None:
480         json_body = {'security_group_rule': {'direction': direction,
481                                              'security_group_id': sg_id,
482                                              'port_range_min': port_range_min,
483                                              'port_range_max': port_range_max,
484                                              'protocol': protocol}}
485     else:
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),\
490               " Invalid values for port_range_min, port_range_max"
491         return False
492     try:
493         neutron_client.create_security_group_rule(json_body)
494         return True
495     except Exception, e:
496         print "Error [create_secgroup_rule(neutron_client, '%s', '%s', "\
497             "'%s', '%s', '%s', '%s')]:" % (neutron_client, sg_id, direction,
498                                            port_range_min, port_range_max,
499                                            protocol), e
500         return False
501
502
503 def add_secgroup_to_instance(nova_client, instance_id, secgroup_id):
504     try:
505         nova_client.servers.add_security_group(instance_id, secgroup_id)
506         return True
507     except Exception, e:
508         print "Error [add_secgroup_to_instance(nova_client, '%s', '%s')]: " % \
509             (instance_id, secgroup_id), e
510         return False
511
512
513 def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
514     json_body = {"quota": {
515         "security_group": sg_quota,
516         "security_group_rule": sg_rule_quota
517     }}
518
519     try:
520         neutron_client.update_quota(tenant_id=tenant_id,
521                                     body=json_body)
522         return True
523     except Exception, e:
524         print "Error [update_sg_quota(neutron_client, '%s', '%s', " \
525             "'%s')]:" % (tenant_id, sg_quota, sg_rule_quota), e
526         return False
527
528
529 def delete_security_group(neutron_client, secgroup_id):
530     try:
531         neutron_client.delete_security_group(secgroup_id)
532         return True
533     except Exception, e:
534         print "Error [delete_security_group(neutron_client, '%s')]:"  \
535             % secgroup_id, e
536         return False
537
538
539 # *********************************************
540 #   GLANCE
541 # *********************************************
542 def get_images(nova_client):
543     try:
544         images = nova_client.images.list()
545         return images
546     except Exception, e:
547         print "Error [get_images]:", e
548         return None
549
550
551 def get_image_id(glance_client, image_name):
552     images = glance_client.images.list()
553     id = ''
554     for i in images:
555         if i.name == image_name:
556             id = i.id
557             break
558     return id
559
560
561 def create_glance_image(glance_client, image_name, file_path, public=True):
562     if not os.path.isfile(file_path):
563         print "Error: file " + file_path + " does not exist."
564         return False
565     try:
566         with open(file_path) as fimage:
567             image = glance_client.images.create(name=image_name,
568                                                 is_public=public,
569                                                 disk_format="qcow2",
570                                                 container_format="bare",
571                                                 data=fimage)
572         return image.id
573     except Exception, e:
574         print "Error [create_glance_image(glance_client, '%s', '%s', "\
575             "'%s')]:" % (image_name, file_path, str(public)), e
576         return False
577
578
579 def delete_glance_image(nova_client, image_id):
580     try:
581         nova_client.images.delete(image_id)
582         return True
583     except Exception, e:
584         print "Error [delete_glance_image(nova_client, '%s')]:" % image_id, e
585         return False
586
587
588 # *********************************************
589 #   CINDER
590 # *********************************************
591 def get_volumes(cinder_client):
592     try:
593         volumes = cinder_client.volumes.list(search_opts={'all_tenants': 1})
594         return volumes
595     except Exception, e:
596         print "Error [get_volumes(cinder_client)]:", e
597         return None
598
599
600 def list_volume_types(cinder_client, public=True, private=True):
601     try:
602         volume_types = cinder_client.volume_types.list()
603         if not public:
604             volume_types = [vt for vt in volume_types if not vt.is_public]
605         if not private:
606             volume_types = [vt for vt in volume_types if vt.is_public]
607         return volume_types
608     except Exception, e:
609         print "Error [list_volume_types(cinder_client)]:", e
610         return None
611
612
613 def create_volume_type(cinder_client, name):
614     try:
615         volume_type = cinder_client.volume_types.create(name)
616         return volume_type
617     except Exception, e:
618         print "Error [create_volume_type(cinder_client, '%s')]:" % name, e
619         return None
620
621
622 def update_cinder_quota(cinder_client, tenant_id, vols_quota,
623                         snapshots_quota, gigabytes_quota):
624     quotas_values = {"volumes": vols_quota,
625                      "snapshots": snapshots_quota,
626                      "gigabytes": gigabytes_quota}
627
628     try:
629         cinder_client.quotas.update(tenant_id, **quotas_values)
630         return True
631     except Exception, e:
632         print "Error [update_cinder_quota(cinder_client, '%s', '%s', '%s'" \
633             "'%s')]:" % (tenant_id, vols_quota,
634                          snapshots_quota, gigabytes_quota), e
635         return False
636
637
638 def delete_volume(cinder_client, volume_id, forced=False):
639     try:
640         if forced:
641             try:
642                 cinder_client.volumes.detach(volume_id)
643             except:
644                 print "Error:", sys.exc_info()[0]
645             cinder_client.volumes.force_delete(volume_id)
646         else:
647             cinder_client.volumes.delete(volume_id)
648         return True
649     except Exception, e:
650         print "Error [delete_volume(cinder_client, '%s', '%s')]:" % \
651             (volume_id, str(forced)), e
652         return False
653
654
655 def delete_volume_type(cinder_client, volume_type):
656     try:
657         cinder_client.volume_types.delete(volume_type)
658         return True
659     except Exception, e:
660         print "Error [delete_volume_type(cinder_client, '%s')]:" \
661             % volume_type, e
662         return False
663
664
665 # *********************************************
666 #   KEYSTONE
667 # *********************************************
668 def get_tenants(keystone_client):
669     try:
670         tenants = keystone_client.tenants.list()
671         return tenants
672     except Exception, e:
673         print "Error [get_tenants(keystone_client)]:", e
674         return None
675
676
677 def get_users(keystone_client):
678     try:
679         users = keystone_client.users.list()
680         return users
681     except Exception, e:
682         print "Error [get_users(keystone_client)]:", e
683         return None
684
685
686 def get_tenant_id(keystone_client, tenant_name):
687     tenants = keystone_client.tenants.list()
688     id = ''
689     for t in tenants:
690         if t.name == tenant_name:
691             id = t.id
692             break
693     return id
694
695
696 def get_user_id(keystone_client, user_name):
697     users = keystone_client.users.list()
698     id = ''
699     for u in users:
700         if u.name == user_name:
701             id = u.id
702             break
703     return id
704
705
706 def get_role_id(keystone_client, role_name):
707     roles = keystone_client.roles.list()
708     id = ''
709     for r in roles:
710         if r.name == role_name:
711             id = r.id
712             break
713     return id
714
715
716 def create_tenant(keystone_client, tenant_name, tenant_description):
717     try:
718         tenant = keystone_client.tenants.create(tenant_name,
719                                                 tenant_description,
720                                                 enabled=True)
721         return tenant.id
722     except Exception, e:
723         print "Error [create_tenant(cinder_client, '%s', '%s')]:" % \
724             (tenant_name, tenant_description), e
725         return False
726
727
728 def create_user(keystone_client, user_name, user_password,
729                 user_email, tenant_id):
730     try:
731         user = keystone_client.users.create(user_name, user_password,
732                                             user_email, tenant_id,
733                                             enabled=True)
734         return user.id
735     except Exception, e:
736         print "Error [create_user(keystone_client, '%s', '%s', '%s'" \
737             "'%s')]:" % (user_name, user_password, user_email, tenant_id), e
738         return False
739
740
741 def add_role_user(keystone_client, user_id, role_id, tenant_id):
742     try:
743         keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
744         return True
745     except Exception, e:
746         print "Error [add_role_user(keystone_client, '%s', '%s'" \
747             "'%s')]:" % (user_id, role_id, tenant_id), e
748         return False
749
750
751 def delete_tenant(keystone_client, tenant_id):
752     try:
753         keystone_client.tenants.delete(tenant_id)
754         return True
755     except Exception, e:
756         print "Error [delete_tenant(keystone_client, '%s')]:" % tenant_id, e
757         return False
758
759
760 def delete_user(keystone_client, user_id):
761     try:
762         keystone_client.users.delete(user_id)
763         return True
764     except Exception, e:
765         print "Error [delete_user(keystone_client, '%s')]:" % user_id, e
766         return False