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