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
17 from keystoneauth1 import loading
18 from keystoneauth1 import session
19 from cinderclient import client as cinderclient
20 from glanceclient import client as glanceclient
21 from novaclient import client as novaclient
22 from keystoneclient import client as keystoneclient
23 from neutronclient.neutron import client as neutronclient
25 import functest.utils.functest_logger as ft_logger
26 import functest.utils.functest_utils as ft_utils
28 logger = ft_logger.Logger("openstack_utils").getLogger()
30 DEFAULT_API_VERSION = '2'
33 # *********************************************
35 # *********************************************
36 class MissingEnvVar(Exception):
38 def __init__(self, var):
42 return str.format("Please set the mandatory env var: {}", self.var)
46 keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
47 if (keystone_api_version is None or
48 keystone_api_version == '2'):
54 def get_rc_env_vars():
55 env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD']
57 env_vars.extend(['OS_PROJECT_NAME',
58 'OS_USER_DOMAIN_NAME',
59 'OS_PROJECT_DOMAIN_NAME'])
61 env_vars.extend(['OS_TENANT_NAME'])
65 def check_credentials():
67 Check if the OpenStack credentials (openrc) are sourced
69 env_vars = get_rc_env_vars()
70 return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
73 def get_env_cred_dict():
75 'OS_USERNAME': 'username',
76 'OS_PASSWORD': 'password',
77 'OS_AUTH_URL': 'auth_url',
78 'OS_TENANT_NAME': 'tenant_name',
79 'OS_USER_DOMAIN_NAME': 'user_domain_name',
80 'OS_PROJECT_DOMAIN_NAME': 'project_domain_name',
81 'OS_PROJECT_NAME': 'project_name',
82 'OS_ENDPOINT_TYPE': 'endpoint_type',
83 'OS_REGION_NAME': 'region_name'
88 def get_credentials(other_creds={}):
89 """Returns a creds dictionary filled with parsed from env
92 env_vars = get_rc_env_vars()
93 env_cred_dict = get_env_cred_dict()
95 for envvar in env_vars:
96 if os.getenv(envvar) is None:
97 raise MissingEnvVar(envvar)
99 creds_key = env_cred_dict.get(envvar)
100 creds.update({creds_key: os.getenv(envvar)})
102 if 'tenant' in other_creds.keys():
104 tenant = 'project_name'
106 tenant = 'tenant_name'
107 other_creds[tenant] = other_creds.pop('tenant')
109 creds.update(other_creds)
114 def source_credentials(rc_file):
115 with open(rc_file, "r") as f:
117 var = line.rstrip('"\n').replace(
118 'export ', '').replace("'", "").split("=")
119 key = re.sub(r'^ *| *$', '', var[0])
120 value = re.sub(r'^[" ]*|[ "]*$', '', "".join(var[1:]))
121 os.environ[key] = value
124 def get_credentials_for_rally():
125 creds = get_credentials()
126 env_cred_dict = get_env_cred_dict()
127 rally_conf = {"type": "ExistingCloud", "admin": {}}
129 if key == 'auth_url':
130 rally_conf[key] = creds[key]
132 rally_conf['admin'][key] = creds[key]
134 endpoint_types = [('internalURL', 'internal'),
135 ('publicURL', 'public'), ('adminURL', 'admin')]
137 endpoint_type = os.getenv('OS_ENDPOINT_TYPE')
138 if endpoint_type is not None:
139 cred_key = env_cred_dict.get('OS_ENDPOINT_TYPE')
140 for k, v in endpoint_types:
141 if endpoint_type == k:
142 rally_conf[cred_key] = v
144 region_name = os.getenv('OS_REGION_NAME')
145 if region_name is not None:
146 cred_key = env_cred_dict.get('OS_REGION_NAME')
147 rally_conf[cred_key] = region_name
151 def get_session_auth(other_creds={}):
152 loader = loading.get_plugin_loader('password')
153 creds = get_credentials(other_creds)
154 auth = loader.load_from_options(**creds)
158 def get_endpoint(service_type, endpoint_type='publicURL'):
159 auth = get_session_auth()
160 return get_session().get_endpoint(auth=auth,
161 service_type=service_type,
162 endpoint_type=endpoint_type)
165 def get_session(other_creds={}):
166 auth = get_session_auth(other_creds)
167 return session.Session(auth=auth)
170 # *********************************************
172 # *********************************************
173 def get_keystone_client_version():
174 api_version = os.getenv('OS_IDENTITY_API_VERSION')
175 if api_version is not None:
176 logger.info("OS_IDENTITY_API_VERSION is set in env as '%s'",
179 return DEFAULT_API_VERSION
182 def get_keystone_client(other_creds={}):
183 sess = get_session(other_creds)
184 return keystoneclient.Client(get_keystone_client_version(), session=sess)
187 def get_nova_client_version():
188 api_version = os.getenv('OS_COMPUTE_API_VERSION')
189 if api_version is not None:
190 logger.info("OS_COMPUTE_API_VERSION is set in env as '%s'",
193 return DEFAULT_API_VERSION
196 def get_nova_client(other_creds={}):
197 sess = get_session(other_creds)
198 return novaclient.Client(get_nova_client_version(), session=sess)
201 def get_cinder_client_version():
202 api_version = os.getenv('OS_VOLUME_API_VERSION')
203 if api_version is not None:
204 logger.info("OS_VOLUME_API_VERSION is set in env as '%s'",
207 return DEFAULT_API_VERSION
210 def get_cinder_client(other_creds={}):
211 sess = get_session(other_creds)
212 return cinderclient.Client(get_cinder_client_version(), session=sess)
215 def get_neutron_client_version():
216 api_version = os.getenv('OS_NETWORK_API_VERSION')
217 if api_version is not None:
218 logger.info("OS_NETWORK_API_VERSION is set in env as '%s'",
221 return DEFAULT_API_VERSION
224 def get_neutron_client(other_creds={}):
225 sess = get_session(other_creds)
226 return neutronclient.Client(get_neutron_client_version(), session=sess)
229 def get_glance_client_version():
230 api_version = os.getenv('OS_IMAGE_API_VERSION')
231 if api_version is not None:
232 logger.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
234 return DEFAULT_API_VERSION
237 def get_glance_client(other_creds={}):
238 sess = get_session(other_creds)
239 return glanceclient.Client(get_glance_client_version(), session=sess)
242 # *********************************************
244 # *********************************************
245 def get_instances(nova_client):
247 instances = nova_client.servers.list(search_opts={'all_tenants': 1})
250 logger.error("Error [get_instances(nova_client)]: %s" % e)
254 def get_instance_status(nova_client, instance):
256 instance = nova_client.servers.get(instance.id)
257 return instance.status
259 logger.error("Error [get_instance_status(nova_client)]: %s" % e)
263 def get_instance_by_name(nova_client, instance_name):
265 instance = nova_client.servers.find(name=instance_name)
268 logger.error("Error [get_instance_by_name(nova_client, '%s')]: %s"
269 % (instance_name, e))
273 def get_flavor_id(nova_client, flavor_name):
274 flavors = nova_client.flavors.list(detailed=True)
277 if f.name == flavor_name:
283 def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram):
284 flavors = nova_client.flavors.list(detailed=True)
287 if min_ram <= f.ram and f.ram <= max_ram:
293 def get_aggregates(nova_client):
295 aggregates = nova_client.aggregates.list()
298 logger.error("Error [get_aggregates(nova_client)]: %s" % e)
302 def get_aggregate_id(nova_client, aggregate_name):
304 aggregates = get_aggregates(nova_client)
305 _id = [ag.id for ag in aggregates if ag.name == aggregate_name][0]
308 logger.error("Error [get_aggregate_id(nova_client, %s)]:"
309 " %s" % (aggregate_name, e))
313 def get_availability_zones(nova_client):
315 availability_zones = nova_client.availability_zones.list()
316 return availability_zones
318 logger.error("Error [get_availability_zones(nova_client)]: %s" % e)
322 def get_availability_zone_names(nova_client):
324 az_names = [az.zoneName for az in get_availability_zones(nova_client)]
327 logger.error("Error [get_availability_zone_names(nova_client)]:"
332 def create_flavor(nova_client, flavor_name, ram, disk, vcpus, public=True):
334 flavor = nova_client.flavors.create(
335 flavor_name, ram, vcpus, disk, is_public=public)
337 extra_specs = ft_utils.get_functest_config(
338 'general.flavor_extra_specs')
339 flavor.set_keys(extra_specs)
341 # flavor extra specs are not configured, therefore skip the update
345 logger.error("Error [create_flavor(nova_client, '%s', '%s', '%s', "
346 "'%s')]: %s" % (flavor_name, ram, disk, vcpus, e))
351 def get_or_create_flavor(flavor_name, ram, disk, vcpus, public=True):
352 flavor_exists = False
353 nova_client = get_nova_client()
355 flavor_id = get_flavor_id(nova_client, flavor_name)
357 logger.info("Using existing flavor '%s'..." % flavor_name)
360 logger.info("Creating flavor '%s' with '%s' RAM, '%s' disk size, "
361 "'%s' vcpus..." % (flavor_name, ram, disk, vcpus))
362 flavor_id = create_flavor(
363 nova_client, flavor_name, ram, disk, vcpus, public=public)
365 logger.error("Failed to create flavor '%s'..." % (flavor_name))
367 logger.debug("Flavor '%s' with ID=%s created successfully."
368 % (flavor_name, flavor_id))
370 return flavor_exists, flavor_id
373 def get_floating_ips(nova_client):
375 floating_ips = nova_client.floating_ips.list()
378 logger.error("Error [get_floating_ips(nova_client)]: %s" % e)
382 def get_hypervisors(nova_client):
385 hypervisors = nova_client.hypervisors.list()
386 for hypervisor in hypervisors:
387 if hypervisor.state == "up":
388 nodes.append(hypervisor.hypervisor_hostname)
391 logger.error("Error [get_hypervisors(nova_client)]: %s" % e)
395 def create_aggregate(nova_client, aggregate_name, av_zone):
397 nova_client.aggregates.create(aggregate_name, av_zone)
400 logger.error("Error [create_aggregate(nova_client, %s, %s)]: %s"
401 % (aggregate_name, av_zone, e))
405 def add_host_to_aggregate(nova_client, aggregate_name, compute_host):
407 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
408 nova_client.aggregates.add_host(aggregate_id, compute_host)
411 logger.error("Error [add_host_to_aggregate(nova_client, %s, %s)]: %s"
412 % (aggregate_name, compute_host, e))
416 def create_aggregate_with_host(
417 nova_client, aggregate_name, av_zone, compute_host):
419 create_aggregate(nova_client, aggregate_name, av_zone)
420 add_host_to_aggregate(nova_client, aggregate_name, compute_host)
423 logger.error("Error [create_aggregate_with_host("
424 "nova_client, %s, %s, %s)]: %s"
425 % (aggregate_name, av_zone, compute_host, e))
429 def create_instance(flavor_name,
432 instance_name="functest-vm",
438 nova_client = get_nova_client()
440 flavor = nova_client.flavors.find(name=flavor_name)
442 flavors = nova_client.flavors.list()
443 logger.error("Error: Flavor '%s' not found. Available flavors are: "
444 "\n%s" % (flavor_name, flavors))
446 if fixed_ip is not None:
447 nics = {"net-id": network_id, "v4-fixed-ip": fixed_ip}
449 nics = {"net-id": network_id}
451 instance = nova_client.servers.create(
456 availability_zone=av_zone,
460 instance = nova_client.servers.create(
465 config_drive=confdrive,
467 availability_zone=av_zone,
473 def create_instance_and_wait_for_active(flavor_name,
483 VM_BOOT_TIMEOUT = 180
484 nova_client = get_nova_client()
485 instance = create_instance(flavor_name,
494 count = VM_BOOT_TIMEOUT / SLEEP
495 for n in range(count, -1, -1):
496 status = get_instance_status(nova_client, instance)
497 if status.lower() == "active":
499 elif status.lower() == "error":
500 logger.error("The instance %s went to ERROR status."
504 logger.error("Timeout booting the instance %s." % instance_name)
508 def create_floating_ip(neutron_client):
509 extnet_id = get_external_net_id(neutron_client)
510 props = {'floating_network_id': extnet_id}
512 ip_json = neutron_client.create_floatingip({'floatingip': props})
513 fip_addr = ip_json['floatingip']['floating_ip_address']
514 fip_id = ip_json['floatingip']['id']
516 logger.error("Error [create_floating_ip(neutron_client)]: %s" % e)
518 return {'fip_addr': fip_addr, 'fip_id': fip_id}
521 def add_floating_ip(nova_client, server_id, floatingip_addr):
523 nova_client.servers.add_floating_ip(server_id, floatingip_addr)
526 logger.error("Error [add_floating_ip(nova_client, '%s', '%s')]: %s"
527 % (server_id, floatingip_addr, e))
531 def delete_instance(nova_client, instance_id):
533 nova_client.servers.force_delete(instance_id)
536 logger.error("Error [delete_instance(nova_client, '%s')]: %s"
541 def delete_floating_ip(nova_client, floatingip_id):
543 nova_client.floating_ips.delete(floatingip_id)
546 logger.error("Error [delete_floating_ip(nova_client, '%s')]: %s"
547 % (floatingip_id, e))
551 def remove_host_from_aggregate(nova_client, aggregate_name, compute_host):
553 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
554 nova_client.aggregates.remove_host(aggregate_id, compute_host)
557 logger.error("Error [remove_host_from_aggregate(nova_client, %s, %s)]:"
558 " %s" % (aggregate_name, compute_host, e))
562 def remove_hosts_from_aggregate(nova_client, aggregate_name):
563 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
564 hosts = nova_client.aggregates.get(aggregate_id).hosts
566 all(remove_host_from_aggregate(nova_client, aggregate_name, host)
570 def delete_aggregate(nova_client, aggregate_name):
572 remove_hosts_from_aggregate(nova_client, aggregate_name)
573 nova_client.aggregates.delete(aggregate_name)
576 logger.error("Error [delete_aggregate(nova_client, %s)]: %s"
577 % (aggregate_name, e))
581 # *********************************************
583 # *********************************************
584 def get_network_list(neutron_client):
585 network_list = neutron_client.list_networks()['networks']
586 if len(network_list) == 0:
592 def get_router_list(neutron_client):
593 router_list = neutron_client.list_routers()['routers']
594 if len(router_list) == 0:
600 def get_port_list(neutron_client):
601 port_list = neutron_client.list_ports()['ports']
602 if len(port_list) == 0:
608 def get_network_id(neutron_client, network_name):
609 networks = neutron_client.list_networks()['networks']
612 if n['name'] == network_name:
618 def get_subnet_id(neutron_client, subnet_name):
619 subnets = neutron_client.list_subnets()['subnets']
622 if s['name'] == subnet_name:
628 def get_router_id(neutron_client, router_name):
629 routers = neutron_client.list_routers()['routers']
632 if r['name'] == router_name:
638 def get_private_net(neutron_client):
639 # Checks if there is an existing shared private network
640 networks = neutron_client.list_networks()['networks']
641 if len(networks) == 0:
644 if (net['router:external'] is False) and (net['shared'] is True):
649 def get_external_net(neutron_client):
650 for network in neutron_client.list_networks()['networks']:
651 if network['router:external']:
652 return network['name']
656 def get_external_net_id(neutron_client):
657 for network in neutron_client.list_networks()['networks']:
658 if network['router:external']:
663 def check_neutron_net(neutron_client, net_name):
664 for network in neutron_client.list_networks()['networks']:
665 if network['name'] == net_name:
666 for subnet in network['subnets']:
671 def create_neutron_net(neutron_client, name):
672 json_body = {'network': {'name': name,
673 'admin_state_up': True}}
675 network = neutron_client.create_network(body=json_body)
676 network_dict = network['network']
677 return network_dict['id']
679 logger.error("Error [create_neutron_net(neutron_client, '%s')]: %s"
684 def create_neutron_subnet(neutron_client, name, cidr, net_id):
685 json_body = {'subnets': [{'name': name, 'cidr': cidr,
686 'ip_version': 4, 'network_id': net_id}]}
688 subnet = neutron_client.create_subnet(body=json_body)
689 return subnet['subnets'][0]['id']
691 logger.error("Error [create_neutron_subnet(neutron_client, '%s', "
692 "'%s', '%s')]: %s" % (name, cidr, net_id, e))
696 def create_neutron_router(neutron_client, name):
697 json_body = {'router': {'name': name, 'admin_state_up': True}}
699 router = neutron_client.create_router(json_body)
700 return router['router']['id']
702 logger.error("Error [create_neutron_router(neutron_client, '%s')]: %s"
707 def create_neutron_port(neutron_client, name, network_id, ip):
708 json_body = {'port': {
709 'admin_state_up': True,
711 'network_id': network_id,
712 'fixed_ips': [{"ip_address": ip}]
715 port = neutron_client.create_port(body=json_body)
716 return port['port']['id']
718 logger.error("Error [create_neutron_port(neutron_client, '%s', '%s', "
719 "'%s')]: %s" % (name, network_id, ip, e))
723 def update_neutron_net(neutron_client, network_id, shared=False):
724 json_body = {'network': {'shared': shared}}
726 neutron_client.update_network(network_id, body=json_body)
729 logger.error("Error [update_neutron_net(neutron_client, '%s', '%s')]: "
730 "%s" % (network_id, str(shared), e))
734 def update_neutron_port(neutron_client, port_id, device_owner):
735 json_body = {'port': {
736 'device_owner': device_owner,
739 port = neutron_client.update_port(port=port_id,
741 return port['port']['id']
743 logger.error("Error [update_neutron_port(neutron_client, '%s', '%s')]:"
744 " %s" % (port_id, device_owner, e))
748 def add_interface_router(neutron_client, router_id, subnet_id):
749 json_body = {"subnet_id": subnet_id}
751 neutron_client.add_interface_router(router=router_id, body=json_body)
754 logger.error("Error [add_interface_router(neutron_client, '%s', "
755 "'%s')]: %s" % (router_id, subnet_id, e))
759 def add_gateway_router(neutron_client, router_id):
760 ext_net_id = get_external_net_id(neutron_client)
761 router_dict = {'network_id': ext_net_id}
763 neutron_client.add_gateway_router(router_id, router_dict)
766 logger.error("Error [add_gateway_router(neutron_client, '%s')]: %s"
771 def delete_neutron_net(neutron_client, network_id):
773 neutron_client.delete_network(network_id)
776 logger.error("Error [delete_neutron_net(neutron_client, '%s')]: %s"
781 def delete_neutron_subnet(neutron_client, subnet_id):
783 neutron_client.delete_subnet(subnet_id)
786 logger.error("Error [delete_neutron_subnet(neutron_client, '%s')]: %s"
791 def delete_neutron_router(neutron_client, router_id):
793 neutron_client.delete_router(router=router_id)
796 logger.error("Error [delete_neutron_router(neutron_client, '%s')]: %s"
801 def delete_neutron_port(neutron_client, port_id):
803 neutron_client.delete_port(port_id)
806 logger.error("Error [delete_neutron_port(neutron_client, '%s')]: %s"
811 def remove_interface_router(neutron_client, router_id, subnet_id):
812 json_body = {"subnet_id": subnet_id}
814 neutron_client.remove_interface_router(router=router_id,
818 logger.error("Error [remove_interface_router(neutron_client, '%s', "
819 "'%s')]: %s" % (router_id, subnet_id, e))
823 def remove_gateway_router(neutron_client, router_id):
825 neutron_client.remove_gateway_router(router_id)
828 logger.error("Error [remove_gateway_router(neutron_client, '%s')]: %s"
833 def create_network_full(neutron_client,
839 # Check if the network already exists
840 network_id = get_network_id(neutron_client, net_name)
841 subnet_id = get_subnet_id(neutron_client, subnet_name)
842 router_id = get_router_id(neutron_client, router_name)
844 if network_id != '' and subnet_id != '' and router_id != '':
845 logger.info("A network with name '%s' already exists..." % net_name)
847 neutron_client.format = 'json'
848 logger.info('Creating neutron network %s...' % net_name)
849 network_id = create_neutron_net(neutron_client, net_name)
854 logger.debug("Network '%s' created successfully" % network_id)
855 logger.debug('Creating Subnet....')
856 subnet_id = create_neutron_subnet(neutron_client, subnet_name,
861 logger.debug("Subnet '%s' created successfully" % subnet_id)
862 logger.debug('Creating Router...')
863 router_id = create_neutron_router(neutron_client, router_name)
868 logger.debug("Router '%s' created successfully" % router_id)
869 logger.debug('Adding router to subnet...')
871 if not add_interface_router(neutron_client, router_id, subnet_id):
874 logger.debug("Interface added successfully.")
876 logger.debug('Adding gateway to router...')
877 if not add_gateway_router(neutron_client, router_id):
880 logger.debug("Gateway added successfully.")
882 network_dic = {'net_id': network_id,
883 'subnet_id': subnet_id,
884 'router_id': router_id}
888 def create_shared_network_full(net_name, subnt_name, router_name, subnet_cidr):
889 neutron_client = get_neutron_client()
891 network_dic = create_network_full(neutron_client,
897 if not update_neutron_net(neutron_client,
898 network_dic['net_id'],
900 logger.error("Failed to update network %s..." % net_name)
903 logger.debug("Network '%s' is available..." % net_name)
905 logger.error("Network %s creation failed" % net_name)
910 def create_bgpvpn(neutron_client, **kwargs):
911 # route_distinguishers
913 json_body = {"bgpvpn": kwargs}
914 return neutron_client.create_bgpvpn(json_body)
917 def create_network_association(neutron_client, bgpvpn_id, neutron_network_id):
918 json_body = {"network_association": {"network_id": neutron_network_id}}
919 return neutron_client.create_network_association(bgpvpn_id, json_body)
922 def create_router_association(neutron_client, bgpvpn_id, router_id):
923 json_body = {"router_association": {"router_id": router_id}}
924 return neutron_client.create_router_association(bgpvpn_id, json_body)
927 def update_bgpvpn(neutron_client, bgpvpn_id, **kwargs):
928 json_body = {"bgpvpn": kwargs}
929 return neutron_client.update_bgpvpn(bgpvpn_id, json_body)
932 def delete_bgpvpn(neutron_client, bgpvpn_id):
933 return neutron_client.delete_bgpvpn(bgpvpn_id)
936 def get_bgpvpn(neutron_client, bgpvpn_id):
937 return neutron_client.show_bgpvpn(bgpvpn_id)
940 def get_bgpvpn_routers(neutron_client, bgpvpn_id):
941 return get_bgpvpn(neutron_client, bgpvpn_id)['bgpvpn']['routers']
944 def get_bgpvpn_networks(neutron_client, bgpvpn_id):
945 return get_bgpvpn(neutron_client, bgpvpn_id)['bgpvpn']['networks']
947 # *********************************************
949 # *********************************************
952 def get_security_groups(neutron_client):
954 security_groups = neutron_client.list_security_groups()[
956 return security_groups
958 logger.error("Error [get_security_groups(neutron_client)]: %s" % e)
962 def get_security_group_id(neutron_client, sg_name):
963 security_groups = get_security_groups(neutron_client)
965 for sg in security_groups:
966 if sg['name'] == sg_name:
972 def create_security_group(neutron_client, sg_name, sg_description):
973 json_body = {'security_group': {'name': sg_name,
974 'description': sg_description}}
976 secgroup = neutron_client.create_security_group(json_body)
977 return secgroup['security_group']
979 logger.error("Error [create_security_group(neutron_client, '%s', "
980 "'%s')]: %s" % (sg_name, sg_description, e))
984 def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
985 port_range_min=None, port_range_max=None):
986 if port_range_min is None and port_range_max is None:
987 json_body = {'security_group_rule': {'direction': direction,
988 'security_group_id': sg_id,
989 'protocol': protocol}}
990 elif port_range_min is not None and port_range_max is not None:
991 json_body = {'security_group_rule': {'direction': direction,
992 'security_group_id': sg_id,
993 'port_range_min': port_range_min,
994 'port_range_max': port_range_max,
995 'protocol': protocol}}
997 logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
998 "'%s', '%s', '%s', '%s')]:" % (neutron_client,
1003 " Invalid values for port_range_min, port_range_max")
1006 neutron_client.create_security_group_rule(json_body)
1008 except Exception, e:
1009 logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
1010 "'%s', '%s', '%s', '%s')]: %s" % (neutron_client,
1019 def create_security_group_full(neutron_client,
1020 sg_name, sg_description):
1021 sg_id = get_security_group_id(neutron_client, sg_name)
1023 logger.info("Using existing security group '%s'..." % sg_name)
1025 logger.info("Creating security group '%s'..." % sg_name)
1026 SECGROUP = create_security_group(neutron_client,
1030 logger.error("Failed to create the security group...")
1033 sg_id = SECGROUP['id']
1035 logger.debug("Security group '%s' with ID=%s created successfully."
1036 % (SECGROUP['name'], sg_id))
1038 logger.debug("Adding ICMP rules in security group '%s'..."
1040 if not create_secgroup_rule(neutron_client, sg_id,
1042 logger.error("Failed to create the security group rule...")
1045 logger.debug("Adding SSH rules in security group '%s'..."
1047 if not create_secgroup_rule(
1048 neutron_client, sg_id, 'ingress', 'tcp', '22', '22'):
1049 logger.error("Failed to create the security group rule...")
1052 if not create_secgroup_rule(
1053 neutron_client, sg_id, 'egress', 'tcp', '22', '22'):
1054 logger.error("Failed to create the security group rule...")
1059 def add_secgroup_to_instance(nova_client, instance_id, secgroup_id):
1061 nova_client.servers.add_security_group(instance_id, secgroup_id)
1063 except Exception, e:
1064 logger.error("Error [add_secgroup_to_instance(nova_client, '%s', "
1065 "'%s')]: %s" % (instance_id, secgroup_id, e))
1069 def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
1070 json_body = {"quota": {
1071 "security_group": sg_quota,
1072 "security_group_rule": sg_rule_quota
1076 neutron_client.update_quota(tenant_id=tenant_id,
1079 except Exception, e:
1080 logger.error("Error [update_sg_quota(neutron_client, '%s', '%s', "
1081 "'%s')]: %s" % (tenant_id, sg_quota, sg_rule_quota, e))
1085 def delete_security_group(neutron_client, secgroup_id):
1087 neutron_client.delete_security_group(secgroup_id)
1089 except Exception, e:
1090 logger.error("Error [delete_security_group(neutron_client, '%s')]: %s"
1095 # *********************************************
1097 # *********************************************
1098 def get_images(nova_client):
1100 images = nova_client.images.list()
1102 except Exception, e:
1103 logger.error("Error [get_images]: %s" % e)
1107 def get_image_id(glance_client, image_name):
1108 images = glance_client.images.list()
1111 if i.name == image_name:
1117 def create_glance_image(glance_client, image_name, file_path, disk="qcow2",
1118 container="bare", public="public"):
1119 if not os.path.isfile(file_path):
1120 logger.error("Error: file %s does not exist." % file_path)
1123 image_id = get_image_id(glance_client, image_name)
1125 logger.info("Image %s already exists." % image_name)
1127 logger.info("Creating image '%s' from '%s'..." % (image_name,
1130 image = glance_client.images.create(name=image_name,
1133 container_format=container)
1135 with open(file_path) as image_data:
1136 glance_client.images.upload(image_id, image_data)
1138 except Exception, e:
1139 logger.error("Error [create_glance_image(glance_client, '%s', '%s', "
1140 "'%s')]: %s" % (image_name, file_path, public, e))
1144 def get_or_create_image(name, path, format):
1145 image_exists = False
1146 glance_client = get_glance_client()
1148 image_id = get_image_id(glance_client, name)
1150 logger.info("Using existing image '%s'..." % name)
1153 logger.info("Creating image '%s' from '%s'..." % (name, path))
1154 image_id = create_glance_image(glance_client, name, path, format)
1156 logger.error("Failed to create a Glance image...")
1158 logger.debug("Image '%s' with ID=%s created successfully."
1161 return image_exists, image_id
1164 def delete_glance_image(nova_client, image_id):
1166 nova_client.images.delete(image_id)
1168 except Exception, e:
1169 logger.error("Error [delete_glance_image(nova_client, '%s')]: %s"
1174 # *********************************************
1176 # *********************************************
1177 def get_volumes(cinder_client):
1179 volumes = cinder_client.volumes.list(search_opts={'all_tenants': 1})
1181 except Exception, e:
1182 logger.error("Error [get_volumes(cinder_client)]: %s" % e)
1186 def list_volume_types(cinder_client, public=True, private=True):
1188 volume_types = cinder_client.volume_types.list()
1190 volume_types = [vt for vt in volume_types if not vt.is_public]
1192 volume_types = [vt for vt in volume_types if vt.is_public]
1194 except Exception, e:
1195 logger.error("Error [list_volume_types(cinder_client)]: %s" % e)
1199 def create_volume_type(cinder_client, name):
1201 volume_type = cinder_client.volume_types.create(name)
1203 except Exception, e:
1204 logger.error("Error [create_volume_type(cinder_client, '%s')]: %s"
1209 def update_cinder_quota(cinder_client, tenant_id, vols_quota,
1210 snapshots_quota, gigabytes_quota):
1211 quotas_values = {"volumes": vols_quota,
1212 "snapshots": snapshots_quota,
1213 "gigabytes": gigabytes_quota}
1216 cinder_client.quotas.update(tenant_id, **quotas_values)
1218 except Exception, e:
1219 logger.error("Error [update_cinder_quota(cinder_client, '%s', '%s', "
1220 "'%s' '%s')]: %s" % (tenant_id, vols_quota,
1221 snapshots_quota, gigabytes_quota, e))
1225 def delete_volume(cinder_client, volume_id, forced=False):
1229 cinder_client.volumes.detach(volume_id)
1231 logger.error(sys.exc_info()[0])
1232 cinder_client.volumes.force_delete(volume_id)
1234 cinder_client.volumes.delete(volume_id)
1236 except Exception, e:
1237 logger.error("Error [delete_volume(cinder_client, '%s', '%s')]: %s"
1238 % (volume_id, str(forced), e))
1242 def delete_volume_type(cinder_client, volume_type):
1244 cinder_client.volume_types.delete(volume_type)
1246 except Exception, e:
1247 logger.error("Error [delete_volume_type(cinder_client, '%s')]: %s"
1252 # *********************************************
1254 # *********************************************
1255 def get_tenants(keystone_client):
1257 if is_keystone_v3():
1258 tenants = keystone_client.projects.list()
1260 tenants = keystone_client.tenants.list()
1262 except Exception, e:
1263 logger.error("Error [get_tenants(keystone_client)]: %s" % e)
1267 def get_users(keystone_client):
1269 users = keystone_client.users.list()
1271 except Exception, e:
1272 logger.error("Error [get_users(keystone_client)]: %s" % e)
1276 def get_tenant_id(keystone_client, tenant_name):
1277 tenants = get_tenants(keystone_client)
1280 if t.name == tenant_name:
1286 def get_user_id(keystone_client, user_name):
1287 users = get_users(keystone_client)
1290 if u.name == user_name:
1296 def get_role_id(keystone_client, role_name):
1297 roles = keystone_client.roles.list()
1300 if r.name == role_name:
1306 def create_tenant(keystone_client, tenant_name, tenant_description):
1308 if is_keystone_v3():
1309 tenant = keystone_client.projects.create(
1311 description=tenant_description,
1315 tenant = keystone_client.tenants.create(tenant_name,
1319 except Exception, e:
1320 logger.error("Error [create_tenant(keystone_client, '%s', '%s')]: %s"
1321 % (tenant_name, tenant_description, e))
1325 def create_user(keystone_client, user_name, user_password,
1326 user_email, tenant_id):
1328 if is_keystone_v3():
1329 user = keystone_client.users.create(name=user_name,
1330 password=user_password,
1332 project_id=tenant_id,
1335 user = keystone_client.users.create(user_name,
1341 except Exception, e:
1342 logger.error("Error [create_user(keystone_client, '%s', '%s', '%s'"
1343 "'%s')]: %s" % (user_name, user_password,
1344 user_email, tenant_id, e))
1348 def add_role_user(keystone_client, user_id, role_id, tenant_id):
1350 if is_keystone_v3():
1351 keystone_client.roles.grant(role=role_id,
1355 keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
1357 except Exception, e:
1358 logger.error("Error [add_role_user(keystone_client, '%s', '%s'"
1359 "'%s')]: %s " % (user_id, role_id, tenant_id, e))
1363 def delete_tenant(keystone_client, tenant_id):
1365 if is_keystone_v3():
1366 keystone_client.projects.delete(tenant_id)
1368 keystone_client.tenants.delete(tenant_id)
1370 except Exception, e:
1371 logger.error("Error [delete_tenant(keystone_client, '%s')]: %s"
1376 def delete_user(keystone_client, user_id):
1378 keystone_client.users.delete(user_id)
1380 except Exception, e:
1381 logger.error("Error [delete_user(keystone_client, '%s')]: %s"