Fix onos sfc's block.
[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 import time
16
17 from glanceclient import client as glanceclient
18 from keystoneclient.v2_0 import client as keystoneclient
19 from neutronclient.v2_0 import client as neutronclient
20 from novaclient import client as novaclient
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 #   CLIENTS
95 # *********************************************
96 def get_keystone_client():
97     creds_keystone = get_credentials("keystone")
98     return keystoneclient.Client(**creds_keystone)
99
100
101 def get_nova_client():
102     creds_nova = get_credentials("nova")
103     return novaclient.Client('2', **creds_nova)
104
105
106 def get_neutron_client():
107     creds_neutron = get_credentials("neutron")
108     return neutronclient.Client(**creds_neutron)
109
110
111 def get_glance_client():
112     keystone_client = get_keystone_client()
113     glance_endpoint = keystone_client.service_catalog.url_for(
114         service_type='image', endpoint_type='publicURL')
115     return glanceclient.Client(1, glance_endpoint,
116                                token=keystone_client.auth_token)
117
118 # *********************************************
119 #   NOVA
120 # *********************************************
121
122
123 def get_instances(nova_client):
124     try:
125         instances = nova_client.servers.list(search_opts={'all_tenants': 1})
126         return instances
127     except Exception, e:
128         print "Error [get_instances(nova_client)]:", e
129         return None
130
131
132 def get_instance_status(nova_client, instance):
133     try:
134         instance = nova_client.servers.get(instance.id)
135         return instance.status
136     except:
137         # print ("Error [get_instance_status(nova_client, '%s')]:" %
138         #        str(instance)), e
139         return None
140
141
142 def get_instance_by_name(nova_client, instance_name):
143     try:
144         instance = nova_client.servers.find(name=instance_name)
145         return instance
146     except Exception, e:
147         print ("Error [get_instance_by_name(nova_client, '%s')]:" %
148                instance_name), e
149         return None
150
151
152 def get_flavor_id(nova_client, flavor_name):
153     flavors = nova_client.flavors.list(detailed=True)
154     id = ''
155     for f in flavors:
156         if f.name == flavor_name:
157             id = f.id
158             break
159     return id
160
161
162 def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram):
163     flavors = nova_client.flavors.list(detailed=True)
164     id = ''
165     for f in flavors:
166         if min_ram <= f.ram and f.ram <= max_ram:
167             id = f.id
168             break
169     return id
170
171
172 def get_floating_ips(nova_client):
173     try:
174         floating_ips = nova_client.floating_ips.list()
175         return floating_ips
176     except Exception, e:
177         print "Error [get_floating_ips(nova_client)]:", e
178         return None
179
180
181 def get_hypervisors(nova_client):
182     try:
183         nodes = []
184         hypervisors = nova_client.hypervisors.list()
185         for hypervisor in hypervisors:
186             if hypervisor.state == "up":
187                 nodes.append(hypervisor.hypervisor_hostname)
188         return nodes
189     except Exception, e:
190         print "Error [get_hypervisors(nova_client)]:", e
191         return None
192
193
194 def create_flavor(nova_client, flavor_name, ram, disk, vcpus):
195     try:
196         flavor = nova_client.flavors.create(flavor_name, ram, vcpus, disk)
197     except Exception, e:
198         print ("Error [create_flavor(nova_client, '%s', '%s', '%s', "
199                "'%s')]:" % (flavor_name, ram, disk, vcpus)), e
200         return None
201     return flavor.id
202
203
204 def create_instance(flavor_name,
205                     image_id,
206                     network_id,
207                     instance_name="functest-vm",
208                     confdrive=True,
209                     userdata=None,
210                     av_zone=''):
211     nova_client = get_nova_client()
212     try:
213         flavor = nova_client.flavors.find(name=flavor_name)
214     except:
215         print("Error: Flavor '%s' not found. Available flavors are:" %
216               flavor_name)
217         print(nova_client.flavor.list())
218         return -1
219     if userdata is None:
220         instance = nova_client.servers.create(
221             name=instance_name,
222             flavor=flavor,
223             image=image_id,
224             nics=[{"net-id": network_id}],
225             availability_zone=av_zone
226         )
227     else:
228         instance = nova_client.servers.create(
229             name=instance_name,
230             flavor=flavor,
231             image=image_id,
232             nics=[{"net-id": network_id}],
233             config_drive=confdrive,
234             userdata=userdata,
235             availability_zone=av_zone
236         )
237     return instance
238
239
240 def create_instance_and_wait_for_active(flavor_name,
241                                         image_id,
242                                         network_id,
243                                         instance_name="",
244                                         config_drive=False,
245                                         userdata="",
246                                         av_zone=''):
247     SLEEP = 3
248     VM_BOOT_TIMEOUT = 180
249     nova_client = get_nova_client()
250     instance = create_instance(flavor_name,
251                                image_id,
252                                network_id,
253                                instance_name,
254                                config_drive,
255                                userdata,
256                                av_zone)
257
258     count = VM_BOOT_TIMEOUT / SLEEP
259     for n in range(count, -1, -1):
260         status = get_instance_status(nova_client, instance)
261         if status.lower() == "active":
262             return instance
263         elif status.lower() == "error":
264             print("The instance %s went to ERROR status." % instance_name)
265             return None
266         time.sleep(SLEEP)
267     print("Timeout booting the instance %s." % instance_name)
268     return None
269
270
271 def create_floating_ip(neutron_client):
272     extnet_id = get_external_net_id(neutron_client)
273     props = {'floating_network_id': extnet_id}
274     try:
275         ip_json = neutron_client.create_floatingip({'floatingip': props})
276         fip_addr = ip_json['floatingip']['floating_ip_address']
277         fip_id = ip_json['floatingip']['id']
278     except Exception, e:
279         print "Error [create_floating_ip(neutron_client)]:", e
280         return None
281     return {'fip_addr': fip_addr, 'fip_id': fip_id}
282
283
284 def add_floating_ip(nova_client, server_id, floatingip_id):
285     try:
286         nova_client.servers.add_floating_ip(server_id, floatingip_id)
287         return True
288     except Exception, e:
289         print ("Error [add_floating_ip(nova_client, '%s', '%s')]:" %
290                (server_id, floatingip_id)), e
291         return False
292
293
294 def delete_instance(nova_client, instance_id):
295     try:
296         nova_client.servers.force_delete(instance_id)
297         return True
298     except Exception, e:
299         print "Error [delete_instance(nova_client, '%s')]:" % instance_id, e
300         return False
301
302
303 def delete_floating_ip(nova_client, floatingip_id):
304     try:
305         nova_client.floating_ips.delete(floatingip_id)
306         return True
307     except Exception, e:
308         print ("Error [delete_floating_ip(nova_client, '%s')]:" %
309                floatingip_id), e
310         return False
311
312
313 # *********************************************
314 #   NEUTRON
315 # *********************************************
316 def get_network_list(neutron_client):
317     network_list = neutron_client.list_networks()['networks']
318     if len(network_list) == 0:
319         return None
320     else:
321         return network_list
322
323
324 def get_router_list(neutron_client):
325     router_list = neutron_client.list_routers()['routers']
326     if len(router_list) == 0:
327         return None
328     else:
329         return router_list
330
331
332 def get_port_list(neutron_client):
333     port_list = neutron_client.list_ports()['ports']
334     if len(port_list) == 0:
335         return None
336     else:
337         return port_list
338
339
340 def get_network_id(neutron_client, network_name):
341     networks = neutron_client.list_networks()['networks']
342     id = ''
343     for n in networks:
344         if n['name'] == network_name:
345             id = n['id']
346             break
347     return id
348
349
350 def get_subnet_id(neutron_client, subnet_name):
351     subnets = neutron_client.list_subnets()['subnets']
352     id = ''
353     for s in subnets:
354         if s['name'] == subnet_name:
355             id = s['id']
356             break
357     return id
358
359
360 def get_router_id(neutron_client, router_name):
361     routers = neutron_client.list_routers()['routers']
362     id = ''
363     for r in routers:
364         if r['name'] == router_name:
365             id = r['id']
366             break
367     return id
368
369
370 def get_private_net(neutron_client):
371     # Checks if there is an existing shared private network
372     networks = neutron_client.list_networks()['networks']
373     if len(networks) == 0:
374         return None
375     for net in networks:
376         if (net['router:external'] is False) and (net['shared'] is True):
377             return net
378     return None
379
380
381 def get_external_net(neutron_client):
382     for network in neutron_client.list_networks()['networks']:
383         if network['router:external']:
384             return network['name']
385     return False
386
387
388 def get_external_net_id(neutron_client):
389     for network in neutron_client.list_networks()['networks']:
390         if network['router:external']:
391             return network['id']
392     return False
393
394
395 def check_neutron_net(neutron_client, net_name):
396     for network in neutron_client.list_networks()['networks']:
397         if network['name'] == net_name:
398             for subnet in network['subnets']:
399                 return True
400     return False
401
402
403 def create_neutron_net(neutron_client, name):
404     json_body = {'network': {'name': name,
405                              'admin_state_up': True}}
406     try:
407         network = neutron_client.create_network(body=json_body)
408         network_dict = network['network']
409         return network_dict['id']
410     except Exception, e:
411         print "Error [create_neutron_net(neutron_client, '%s')]:" % name, e
412         return False
413
414
415 def create_neutron_subnet(neutron_client, name, cidr, net_id):
416     json_body = {'subnets': [{'name': name, 'cidr': cidr,
417                               'ip_version': 4, 'network_id': net_id}]}
418     try:
419         subnet = neutron_client.create_subnet(body=json_body)
420         return subnet['subnets'][0]['id']
421     except Exception, e:
422         print ("Error [create_neutron_subnet(neutron_client, '%s', '%s', "
423                "'%s')]:" % (name, cidr, net_id)), e
424         return False
425
426
427 def create_neutron_router(neutron_client, name):
428     json_body = {'router': {'name': name, 'admin_state_up': True}}
429     try:
430         router = neutron_client.create_router(json_body)
431         return router['router']['id']
432     except Exception, e:
433         print "Error [create_neutron_router(neutron_client, '%s')]:" % name, e
434         return False
435
436
437 def create_neutron_port(neutron_client, name, network_id, ip):
438     json_body = {'port': {
439                  'admin_state_up': True,
440                  'name': name,
441                  'network_id': network_id,
442                  'fixed_ips': [{"ip_address": ip}]
443                  }}
444     try:
445         port = neutron_client.create_port(body=json_body)
446         return port['port']['id']
447     except Exception, e:
448         print ("Error [create_neutron_port(neutron_client, '%s', '%s', "
449                "'%s')]:" % (name, network_id, ip)), e
450         return False
451
452
453 def update_neutron_net(neutron_client, network_id, shared=False):
454     json_body = {'network': {'shared': shared}}
455     try:
456         neutron_client.update_network(network_id, body=json_body)
457         return True
458     except Exception, e:
459         print ("Error [update_neutron_net(neutron_client, '%s', '%s')]:" %
460                (network_id, str(shared))), e
461         return False
462
463
464 def update_neutron_port(neutron_client, port_id, device_owner):
465     json_body = {'port': {
466                  'device_owner': device_owner,
467                  }}
468     try:
469         port = neutron_client.update_port(port=port_id,
470                                           body=json_body)
471         return port['port']['id']
472     except Exception, e:
473         print ("Error [update_neutron_port(neutron_client, '%s', '%s')]:" %
474                (port_id, device_owner)), e
475         return False
476
477
478 def add_interface_router(neutron_client, router_id, subnet_id):
479     json_body = {"subnet_id": subnet_id}
480     try:
481         neutron_client.add_interface_router(router=router_id, body=json_body)
482         return True
483     except Exception, e:
484         print ("Error [add_interface_router(neutron_client, '%s', '%s')]:" %
485                (router_id, subnet_id)), e
486         return False
487
488
489 def add_gateway_router(neutron_client, router_id):
490     ext_net_id = get_external_net_id(neutron_client)
491     router_dict = {'network_id': ext_net_id}
492     try:
493         neutron_client.add_gateway_router(router_id, router_dict)
494         return True
495     except Exception, e:
496         print ("Error [add_gateway_router(neutron_client, '%s')]:" %
497                router_id), e
498         return False
499
500
501 def delete_neutron_net(neutron_client, network_id):
502     try:
503         neutron_client.delete_network(network_id)
504         return True
505     except Exception, e:
506         print ("Error [delete_neutron_net(neutron_client, '%s')]:" %
507                network_id), e
508         return False
509
510
511 def delete_neutron_subnet(neutron_client, subnet_id):
512     try:
513         neutron_client.delete_subnet(subnet_id)
514         return True
515     except Exception, e:
516         print ("Error [delete_neutron_subnet(neutron_client, '%s')]:" %
517                subnet_id), e
518         return False
519
520
521 def delete_neutron_router(neutron_client, router_id):
522     try:
523         neutron_client.delete_router(router=router_id)
524         return True
525     except Exception, e:
526         print ("Error [delete_neutron_router(neutron_client, '%s')]:" %
527                router_id), e
528         return False
529
530
531 def delete_neutron_port(neutron_client, port_id):
532     try:
533         neutron_client.delete_port(port_id)
534         return True
535     except Exception, e:
536         print "Error [delete_neutron_port(neutron_client, '%s')]:" % port_id, e
537         return False
538
539
540 def remove_interface_router(neutron_client, router_id, subnet_id):
541     json_body = {"subnet_id": subnet_id}
542     try:
543         neutron_client.remove_interface_router(router=router_id,
544                                                body=json_body)
545         return True
546     except Exception, e:
547         print ("Error [remove_interface_router(neutron_client, '%s', '%s')]:" %
548                (router_id, subnet_id)), e
549         return False
550
551
552 def remove_gateway_router(neutron_client, router_id):
553     try:
554         neutron_client.remove_gateway_router(router_id)
555         return True
556     except Exception, e:
557         print ("Error [remove_gateway_router(neutron_client, '%s')]:" %
558                router_id), e
559         return False
560
561
562 def create_network_full(logger,
563                         neutron_client,
564                         net_name,
565                         subnet_name,
566                         router_name,
567                         cidr):
568
569     # Check if the network already exists
570     network_id = get_network_id(neutron_client, net_name)
571     subnet_id = get_subnet_id(neutron_client, subnet_name)
572     router_id = get_router_id(neutron_client, router_name)
573
574     if network_id != '' and subnet_id != '' and router_id != '':
575         logger.info("A network with name '%s' already exists..." % net_name)
576     else:
577         neutron_client.format = 'json'
578         logger.info('Creating neutron network %s...' % net_name)
579         network_id = create_neutron_net(neutron_client, net_name)
580
581         if not network_id:
582             return False
583
584         logger.debug("Network '%s' created successfully" % network_id)
585         logger.debug('Creating Subnet....')
586         subnet_id = create_neutron_subnet(neutron_client, subnet_name,
587                                           cidr, network_id)
588         if not subnet_id:
589             return False
590
591         logger.debug("Subnet '%s' created successfully" % subnet_id)
592         logger.debug('Creating Router...')
593         router_id = create_neutron_router(neutron_client, router_name)
594
595         if not router_id:
596             return False
597
598         logger.debug("Router '%s' created successfully" % router_id)
599         logger.debug('Adding router to subnet...')
600
601         if not add_interface_router(neutron_client, router_id, subnet_id):
602             return False
603
604         logger.debug("Interface added successfully.")
605
606         logger.debug('Adding gateway to router...')
607         if not add_gateway_router(neutron_client, router_id):
608             return False
609
610         logger.debug("Gateway added successfully.")
611
612     network_dic = {'net_id': network_id,
613                    'subnet_id': subnet_id,
614                    'router_id': router_id}
615     return network_dic
616
617
618 def create_bgpvpn(neutron_client, **kwargs):
619     # route_distinguishers
620     # route_targets
621     json_body = {"bgpvpn": kwargs}
622     return neutron_client.create_bgpvpn(json_body)
623
624
625 def create_network_association(neutron_client, bgpvpn_id, neutron_network_id):
626     json_body = {"network_association": {"network_id": neutron_network_id}}
627     return neutron_client.create_network_association(bgpvpn_id, json_body)
628
629
630 def update_bgpvpn(neutron_client, bgpvpn_id, **kwargs):
631     json_body = {"bgpvpn": kwargs}
632     return neutron_client.update_bgpvpn(bgpvpn_id, json_body)
633
634 # *********************************************
635 #   SEC GROUPS
636 # *********************************************
637
638
639 def get_security_groups(neutron_client):
640     try:
641         security_groups = neutron_client.list_security_groups()[
642             'security_groups']
643         return security_groups
644     except Exception, e:
645         print "Error [get_security_groups(neutron_client)]:", e
646         return None
647
648
649 def get_security_group_id(neutron_client, sg_name):
650     security_groups = get_security_groups(neutron_client)
651     id = ''
652     for sg in security_groups:
653         if sg['name'] == sg_name:
654             id = sg['id']
655             break
656     return id
657
658
659 def create_security_group(neutron_client, sg_name, sg_description):
660     json_body = {'security_group': {'name': sg_name,
661                                     'description': sg_description}}
662     try:
663         secgroup = neutron_client.create_security_group(json_body)
664         return secgroup['security_group']
665     except Exception, e:
666         print ("Error [create_security_group(neutron_client, '%s', '%s')]:" %
667                (sg_name, sg_description)), e
668         return False
669
670
671 def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
672                          port_range_min=None, port_range_max=None):
673     if port_range_min is None and port_range_max is None:
674         json_body = {'security_group_rule': {'direction': direction,
675                                              'security_group_id': sg_id,
676                                              'protocol': protocol}}
677     elif port_range_min is not None and port_range_max is not None:
678         json_body = {'security_group_rule': {'direction': direction,
679                                              'security_group_id': sg_id,
680                                              'port_range_min': port_range_min,
681                                              'port_range_max': port_range_max,
682                                              'protocol': protocol}}
683     else:
684         print ("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
685                "'%s', '%s', '%s', '%s')]:" % (neutron_client, sg_id, direction,
686                                               port_range_min, port_range_max,
687                                               protocol),
688                " Invalid values for port_range_min, port_range_max")
689         return False
690     try:
691         neutron_client.create_security_group_rule(json_body)
692         return True
693     except Exception, e:
694         print ("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
695                "'%s', '%s', '%s', '%s')]:" % (neutron_client, sg_id, direction,
696                                               port_range_min, port_range_max,
697                                               protocol)), e
698         return False
699
700
701 def create_security_group_full(logger, neutron_client,
702                                sg_name, sg_description):
703     sg_id = get_security_group_id(neutron_client, sg_name)
704     if sg_id != '':
705         logger.info("Using existing security group '%s'..." % sg_name)
706     else:
707         logger.info("Creating security group  '%s'..." % sg_name)
708         SECGROUP = create_security_group(neutron_client,
709                                          sg_name,
710                                          sg_description)
711         if not SECGROUP:
712             logger.error("Failed to create the security group...")
713             return False
714
715         sg_id = SECGROUP['id']
716
717         logger.debug("Security group '%s' with ID=%s created successfully."
718                      % (SECGROUP['name'], sg_id))
719
720         logger.debug("Adding ICMP rules in security group '%s'..."
721                      % sg_name)
722         if not create_secgroup_rule(neutron_client, sg_id,
723                                     'ingress', 'icmp'):
724             logger.error("Failed to create the security group rule...")
725             return False
726
727         logger.debug("Adding SSH rules in security group '%s'..."
728                      % sg_name)
729         if not create_secgroup_rule(
730                 neutron_client, sg_id, 'ingress', 'tcp', '22', '22'):
731             logger.error("Failed to create the security group rule...")
732             return False
733
734         if not create_secgroup_rule(
735                 neutron_client, sg_id, 'egress', 'tcp', '22', '22'):
736             logger.error("Failed to create the security group rule...")
737             return False
738     return sg_id
739
740
741 def add_secgroup_to_instance(nova_client, instance_id, secgroup_id):
742     try:
743         nova_client.servers.add_security_group(instance_id, secgroup_id)
744         return True
745     except Exception, e:
746         print ("Error [add_secgroup_to_instance(nova_client, '%s', '%s')]: " %
747                (instance_id, secgroup_id)), e
748         return False
749
750
751 def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
752     json_body = {"quota": {
753         "security_group": sg_quota,
754         "security_group_rule": sg_rule_quota
755     }}
756
757     try:
758         neutron_client.update_quota(tenant_id=tenant_id,
759                                     body=json_body)
760         return True
761     except Exception, e:
762         print ("Error [update_sg_quota(neutron_client, '%s', '%s', "
763                "'%s')]:" % (tenant_id, sg_quota, sg_rule_quota)), e
764         return False
765
766
767 def delete_security_group(neutron_client, secgroup_id):
768     try:
769         neutron_client.delete_security_group(secgroup_id)
770         return True
771     except Exception, e:
772         print ("Error [delete_security_group(neutron_client, '%s')]:" %
773                secgroup_id), e
774         return False
775
776
777 # *********************************************
778 #   GLANCE
779 # *********************************************
780 def get_images(nova_client):
781     try:
782         images = nova_client.images.list()
783         return images
784     except Exception, e:
785         print "Error [get_images]:", e
786         return None
787
788
789 def get_image_id(glance_client, image_name):
790     images = glance_client.images.list()
791     id = ''
792     for i in images:
793         if i.name == image_name:
794             id = i.id
795             break
796     return id
797
798
799 def create_glance_image(glance_client, image_name, file_path, disk="qcow2",
800                         container="bare", public=True, logger=None):
801     if not os.path.isfile(file_path):
802         print "Error: file " + file_path + " does not exist."
803         return False
804     try:
805         image_id = get_image_id(glance_client, image_name)
806         if image_id != '':
807             if logger:
808                 logger.info("Image %s already exists." % image_name)
809         else:
810             if logger:
811                 logger.info("Creating image '%s' from '%s'..." % (image_name,
812                                                                   file_path))
813             with open(file_path) as fimage:
814                 image = glance_client.images.create(name=image_name,
815                                                     is_public=public,
816                                                     disk_format=disk,
817                                                     container_format=container,
818                                                     data=fimage)
819             image_id = image.id
820         return image_id
821     except Exception, e:
822         print ("Error [create_glance_image(glance_client, '%s', '%s', "
823                "'%s')]:" % (image_name, file_path, str(public))), e
824         return False
825
826
827 def delete_glance_image(nova_client, image_id):
828     try:
829         nova_client.images.delete(image_id)
830         return True
831     except Exception, e:
832         print ("Error [delete_glance_image(nova_client, '%s')]:" % image_id), e
833         return False
834
835
836 # *********************************************
837 #   CINDER
838 # *********************************************
839 def get_volumes(cinder_client):
840     try:
841         volumes = cinder_client.volumes.list(search_opts={'all_tenants': 1})
842         return volumes
843     except Exception, e:
844         print "Error [get_volumes(cinder_client)]:", e
845         return None
846
847
848 def list_volume_types(cinder_client, public=True, private=True):
849     try:
850         volume_types = cinder_client.volume_types.list()
851         if not public:
852             volume_types = [vt for vt in volume_types if not vt.is_public]
853         if not private:
854             volume_types = [vt for vt in volume_types if vt.is_public]
855         return volume_types
856     except Exception, e:
857         print "Error [list_volume_types(cinder_client)]:", e
858         return None
859
860
861 def create_volume_type(cinder_client, name):
862     try:
863         volume_type = cinder_client.volume_types.create(name)
864         return volume_type
865     except Exception, e:
866         print "Error [create_volume_type(cinder_client, '%s')]:" % name, e
867         return None
868
869
870 def update_cinder_quota(cinder_client, tenant_id, vols_quota,
871                         snapshots_quota, gigabytes_quota):
872     quotas_values = {"volumes": vols_quota,
873                      "snapshots": snapshots_quota,
874                      "gigabytes": gigabytes_quota}
875
876     try:
877         cinder_client.quotas.update(tenant_id, **quotas_values)
878         return True
879     except Exception, e:
880         print ("Error [update_cinder_quota(cinder_client, '%s', '%s', '%s'"
881                "'%s')]:" % (tenant_id, vols_quota,
882                             snapshots_quota, gigabytes_quota)), e
883         return False
884
885
886 def delete_volume(cinder_client, volume_id, forced=False):
887     try:
888         if forced:
889             try:
890                 cinder_client.volumes.detach(volume_id)
891             except:
892                 print "Error:", sys.exc_info()[0]
893             cinder_client.volumes.force_delete(volume_id)
894         else:
895             cinder_client.volumes.delete(volume_id)
896         return True
897     except Exception, e:
898         print ("Error [delete_volume(cinder_client, '%s', '%s')]:" %
899                (volume_id, str(forced))), e
900         return False
901
902
903 def delete_volume_type(cinder_client, volume_type):
904     try:
905         cinder_client.volume_types.delete(volume_type)
906         return True
907     except Exception, e:
908         print ("Error [delete_volume_type(cinder_client, '%s')]:" %
909                volume_type), e
910         return False
911
912
913 # *********************************************
914 #   KEYSTONE
915 # *********************************************
916 def get_tenants(keystone_client):
917     try:
918         tenants = keystone_client.tenants.list()
919         return tenants
920     except Exception, e:
921         print "Error [get_tenants(keystone_client)]:", e
922         return None
923
924
925 def get_users(keystone_client):
926     try:
927         users = keystone_client.users.list()
928         return users
929     except Exception, e:
930         print "Error [get_users(keystone_client)]:", e
931         return None
932
933
934 def get_tenant_id(keystone_client, tenant_name):
935     tenants = keystone_client.tenants.list()
936     id = ''
937     for t in tenants:
938         if t.name == tenant_name:
939             id = t.id
940             break
941     return id
942
943
944 def get_user_id(keystone_client, user_name):
945     users = keystone_client.users.list()
946     id = ''
947     for u in users:
948         if u.name == user_name:
949             id = u.id
950             break
951     return id
952
953
954 def get_role_id(keystone_client, role_name):
955     roles = keystone_client.roles.list()
956     id = ''
957     for r in roles:
958         if r.name == role_name:
959             id = r.id
960             break
961     return id
962
963
964 def create_tenant(keystone_client, tenant_name, tenant_description):
965     try:
966         tenant = keystone_client.tenants.create(tenant_name,
967                                                 tenant_description,
968                                                 enabled=True)
969         return tenant.id
970     except Exception, e:
971         print ("Error [create_tenant(cinder_client, '%s', '%s')]:" %
972                (tenant_name, tenant_description)), e
973         return False
974
975
976 def create_user(keystone_client, user_name, user_password,
977                 user_email, tenant_id):
978     try:
979         user = keystone_client.users.create(user_name, user_password,
980                                             user_email, tenant_id,
981                                             enabled=True)
982         return user.id
983     except Exception, e:
984         print ("Error [create_user(keystone_client, '%s', '%s', '%s'"
985                "'%s')]:" % (user_name, user_password, user_email, tenant_id),
986                e)
987         return False
988
989
990 def add_role_user(keystone_client, user_id, role_id, tenant_id):
991     try:
992         keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
993         return True
994     except Exception, e:
995         print ("Error [add_role_user(keystone_client, '%s', '%s'"
996                "'%s')]:" % (user_id, role_id, tenant_id)), e
997         return False
998
999
1000 def delete_tenant(keystone_client, tenant_id):
1001     try:
1002         keystone_client.tenants.delete(tenant_id)
1003         return True
1004     except Exception, e:
1005         print "Error [delete_tenant(keystone_client, '%s')]:" % tenant_id, e
1006         return False
1007
1008
1009 def delete_user(keystone_client, user_id):
1010     try:
1011         keystone_client.users.delete(user_id)
1012         return True
1013     except Exception, e:
1014         print "Error [delete_user(keystone_client, '%s')]:" % user_id, e
1015         return False