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