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