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 heatclient import client as heatclient
22 from novaclient import client as novaclient
23 from keystoneclient import client as keystoneclient
24 from neutronclient.neutron import client as neutronclient
26 import functest.utils.functest_logger as ft_logger
27 import functest.utils.functest_utils as ft_utils
29 logger = ft_logger.Logger("openstack_utils").getLogger()
31 DEFAULT_API_VERSION = '2'
32 DEFAULT_HEAT_API_VERSION = '1'
35 # *********************************************
37 # *********************************************
38 class MissingEnvVar(Exception):
40 def __init__(self, var):
44 return str.format("Please set the mandatory env var: {}", self.var)
48 keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
49 if (keystone_api_version is None or
50 keystone_api_version == '2'):
56 def get_rc_env_vars():
57 env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD']
59 env_vars.extend(['OS_PROJECT_NAME',
60 'OS_USER_DOMAIN_NAME',
61 'OS_PROJECT_DOMAIN_NAME'])
63 env_vars.extend(['OS_TENANT_NAME'])
67 def check_credentials():
69 Check if the OpenStack credentials (openrc) are sourced
71 env_vars = get_rc_env_vars()
72 return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
75 def get_env_cred_dict():
77 'OS_USERNAME': 'username',
78 'OS_PASSWORD': 'password',
79 'OS_AUTH_URL': 'auth_url',
80 'OS_TENANT_NAME': 'tenant_name',
81 'OS_USER_DOMAIN_NAME': 'user_domain_name',
82 'OS_PROJECT_DOMAIN_NAME': 'project_domain_name',
83 'OS_PROJECT_NAME': 'project_name',
84 'OS_ENDPOINT_TYPE': 'endpoint_type',
85 'OS_REGION_NAME': 'region_name'
90 def get_credentials(other_creds={}):
91 """Returns a creds dictionary filled with parsed from env
94 env_vars = get_rc_env_vars()
95 env_cred_dict = get_env_cred_dict()
97 for envvar in env_vars:
98 if os.getenv(envvar) is None:
99 raise MissingEnvVar(envvar)
101 creds_key = env_cred_dict.get(envvar)
102 creds.update({creds_key: os.getenv(envvar)})
104 if 'tenant' in other_creds.keys():
106 tenant = 'project_name'
108 tenant = 'tenant_name'
109 other_creds[tenant] = other_creds.pop('tenant')
111 creds.update(other_creds)
116 def source_credentials(rc_file):
117 with open(rc_file, "r") as f:
119 var = line.rstrip('"\n').replace('export ', '').split("=")
120 # The two next lines should be modified as soon as rc_file
121 # conforms with common rules. Be aware that it could induce
122 # issues if value starts with '
123 key = re.sub(r'^["\' ]*|[ \'"]*$', '', var[0])
124 value = re.sub(r'^["\' ]*|[ \'"]*$', '', "".join(var[1:]))
125 os.environ[key] = value
128 def get_credentials_for_rally():
129 creds = get_credentials()
130 env_cred_dict = get_env_cred_dict()
131 rally_conf = {"type": "ExistingCloud", "admin": {}}
133 if key == 'auth_url':
134 rally_conf[key] = creds[key]
136 rally_conf['admin'][key] = creds[key]
138 endpoint_types = [('internalURL', 'internal'),
139 ('publicURL', 'public'), ('adminURL', 'admin')]
141 endpoint_type = os.getenv('OS_ENDPOINT_TYPE')
142 if endpoint_type is not None:
143 cred_key = env_cred_dict.get('OS_ENDPOINT_TYPE')
144 for k, v in endpoint_types:
145 if endpoint_type == k:
146 rally_conf[cred_key] = v
148 region_name = os.getenv('OS_REGION_NAME')
149 if region_name is not None:
150 cred_key = env_cred_dict.get('OS_REGION_NAME')
151 rally_conf[cred_key] = region_name
155 def get_session_auth(other_creds={}):
156 loader = loading.get_plugin_loader('password')
157 creds = get_credentials(other_creds)
158 auth = loader.load_from_options(**creds)
162 def get_endpoint(service_type, endpoint_type='publicURL'):
163 auth = get_session_auth()
164 return get_session().get_endpoint(auth=auth,
165 service_type=service_type,
166 endpoint_type=endpoint_type)
169 def get_session(other_creds={}):
170 auth = get_session_auth(other_creds)
171 return session.Session(auth=auth)
174 # *********************************************
176 # *********************************************
177 def get_keystone_client_version():
178 api_version = os.getenv('OS_IDENTITY_API_VERSION')
179 if api_version is not None:
180 logger.info("OS_IDENTITY_API_VERSION is set in env as '%s'",
183 return DEFAULT_API_VERSION
186 def get_keystone_client(other_creds={}):
187 sess = get_session(other_creds)
188 return keystoneclient.Client(get_keystone_client_version(), session=sess)
191 def get_nova_client_version():
192 api_version = os.getenv('OS_COMPUTE_API_VERSION')
193 if api_version is not None:
194 logger.info("OS_COMPUTE_API_VERSION is set in env as '%s'",
197 return DEFAULT_API_VERSION
200 def get_nova_client(other_creds={}):
201 sess = get_session(other_creds)
202 return novaclient.Client(get_nova_client_version(), session=sess)
205 def get_cinder_client_version():
206 api_version = os.getenv('OS_VOLUME_API_VERSION')
207 if api_version is not None:
208 logger.info("OS_VOLUME_API_VERSION is set in env as '%s'",
211 return DEFAULT_API_VERSION
214 def get_cinder_client(other_creds={}):
215 sess = get_session(other_creds)
216 return cinderclient.Client(get_cinder_client_version(), session=sess)
219 def get_neutron_client_version():
220 api_version = os.getenv('OS_NETWORK_API_VERSION')
221 if api_version is not None:
222 logger.info("OS_NETWORK_API_VERSION is set in env as '%s'",
225 return DEFAULT_API_VERSION
228 def get_neutron_client(other_creds={}):
229 sess = get_session(other_creds)
230 return neutronclient.Client(get_neutron_client_version(), session=sess)
233 def get_glance_client_version():
234 api_version = os.getenv('OS_IMAGE_API_VERSION')
235 if api_version is not None:
236 logger.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
238 return DEFAULT_API_VERSION
241 def get_glance_client(other_creds={}):
242 sess = get_session(other_creds)
243 return glanceclient.Client(get_glance_client_version(), session=sess)
246 def get_heat_client_version():
247 api_version = os.getenv('OS_ORCHESTRATION_API_VERSION')
248 if api_version is not None:
249 logger.info("OS_ORCHESTRATION_API_VERSION is set in env as '%s'",
252 return DEFAULT_HEAT_API_VERSION
255 def get_heat_client(other_creds={}):
256 sess = get_session(other_creds)
257 return heatclient.Client(get_heat_client_version(), session=sess)
260 # *********************************************
262 # *********************************************
263 def get_instances(nova_client):
265 instances = nova_client.servers.list(search_opts={'all_tenants': 1})
268 logger.error("Error [get_instances(nova_client)]: %s" % e)
272 def get_instance_status(nova_client, instance):
274 instance = nova_client.servers.get(instance.id)
275 return instance.status
277 logger.error("Error [get_instance_status(nova_client)]: %s" % e)
281 def get_instance_by_name(nova_client, instance_name):
283 instance = nova_client.servers.find(name=instance_name)
286 logger.error("Error [get_instance_by_name(nova_client, '%s')]: %s"
287 % (instance_name, e))
291 def get_flavor_id(nova_client, flavor_name):
292 flavors = nova_client.flavors.list(detailed=True)
295 if f.name == flavor_name:
301 def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram):
302 flavors = nova_client.flavors.list(detailed=True)
305 if min_ram <= f.ram and f.ram <= max_ram:
311 def get_aggregates(nova_client):
313 aggregates = nova_client.aggregates.list()
316 logger.error("Error [get_aggregates(nova_client)]: %s" % e)
320 def get_aggregate_id(nova_client, aggregate_name):
322 aggregates = get_aggregates(nova_client)
323 _id = [ag.id for ag in aggregates if ag.name == aggregate_name][0]
326 logger.error("Error [get_aggregate_id(nova_client, %s)]:"
327 " %s" % (aggregate_name, e))
331 def get_availability_zones(nova_client):
333 availability_zones = nova_client.availability_zones.list()
334 return availability_zones
336 logger.error("Error [get_availability_zones(nova_client)]: %s" % e)
340 def get_availability_zone_names(nova_client):
342 az_names = [az.zoneName for az in get_availability_zones(nova_client)]
345 logger.error("Error [get_availability_zone_names(nova_client)]:"
350 def create_flavor(nova_client, flavor_name, ram, disk, vcpus, public=True):
352 flavor = nova_client.flavors.create(
353 flavor_name, ram, vcpus, disk, is_public=public)
355 extra_specs = ft_utils.get_functest_config(
356 'general.flavor_extra_specs')
357 flavor.set_keys(extra_specs)
359 # flavor extra specs are not configured, therefore skip the update
363 logger.error("Error [create_flavor(nova_client, '%s', '%s', '%s', "
364 "'%s')]: %s" % (flavor_name, ram, disk, vcpus, e))
369 def get_or_create_flavor(flavor_name, ram, disk, vcpus, public=True):
370 flavor_exists = False
371 nova_client = get_nova_client()
373 flavor_id = get_flavor_id(nova_client, flavor_name)
375 logger.info("Using existing flavor '%s'..." % flavor_name)
378 logger.info("Creating flavor '%s' with '%s' RAM, '%s' disk size, "
379 "'%s' vcpus..." % (flavor_name, ram, disk, vcpus))
380 flavor_id = create_flavor(
381 nova_client, flavor_name, ram, disk, vcpus, public=public)
383 logger.error("Failed to create flavor '%s'..." % (flavor_name))
385 logger.debug("Flavor '%s' with ID=%s created successfully."
386 % (flavor_name, flavor_id))
388 return flavor_exists, flavor_id
391 def get_floating_ips(nova_client):
393 floating_ips = nova_client.floating_ips.list()
396 logger.error("Error [get_floating_ips(nova_client)]: %s" % e)
400 def get_hypervisors(nova_client):
403 hypervisors = nova_client.hypervisors.list()
404 for hypervisor in hypervisors:
405 if hypervisor.state == "up":
406 nodes.append(hypervisor.hypervisor_hostname)
409 logger.error("Error [get_hypervisors(nova_client)]: %s" % e)
413 def create_aggregate(nova_client, aggregate_name, av_zone):
415 nova_client.aggregates.create(aggregate_name, av_zone)
418 logger.error("Error [create_aggregate(nova_client, %s, %s)]: %s"
419 % (aggregate_name, av_zone, e))
423 def add_host_to_aggregate(nova_client, aggregate_name, compute_host):
425 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
426 nova_client.aggregates.add_host(aggregate_id, compute_host)
429 logger.error("Error [add_host_to_aggregate(nova_client, %s, %s)]: %s"
430 % (aggregate_name, compute_host, e))
434 def create_aggregate_with_host(
435 nova_client, aggregate_name, av_zone, compute_host):
437 create_aggregate(nova_client, aggregate_name, av_zone)
438 add_host_to_aggregate(nova_client, aggregate_name, compute_host)
441 logger.error("Error [create_aggregate_with_host("
442 "nova_client, %s, %s, %s)]: %s"
443 % (aggregate_name, av_zone, compute_host, e))
447 def create_instance(flavor_name,
450 instance_name="functest-vm",
456 nova_client = get_nova_client()
458 flavor = nova_client.flavors.find(name=flavor_name)
460 flavors = nova_client.flavors.list()
461 logger.error("Error: Flavor '%s' not found. Available flavors are: "
462 "\n%s" % (flavor_name, flavors))
464 if fixed_ip is not None:
465 nics = {"net-id": network_id, "v4-fixed-ip": fixed_ip}
467 nics = {"net-id": network_id}
469 instance = nova_client.servers.create(
474 availability_zone=av_zone,
478 instance = nova_client.servers.create(
483 config_drive=confdrive,
485 availability_zone=av_zone,
491 def create_instance_and_wait_for_active(flavor_name,
501 VM_BOOT_TIMEOUT = 180
502 nova_client = get_nova_client()
503 instance = create_instance(flavor_name,
512 count = VM_BOOT_TIMEOUT / SLEEP
513 for n in range(count, -1, -1):
514 status = get_instance_status(nova_client, instance)
515 if status.lower() == "active":
517 elif status.lower() == "error":
518 logger.error("The instance %s went to ERROR status."
522 logger.error("Timeout booting the instance %s." % instance_name)
526 def create_floating_ip(neutron_client):
527 extnet_id = get_external_net_id(neutron_client)
528 props = {'floating_network_id': extnet_id}
530 ip_json = neutron_client.create_floatingip({'floatingip': props})
531 fip_addr = ip_json['floatingip']['floating_ip_address']
532 fip_id = ip_json['floatingip']['id']
534 logger.error("Error [create_floating_ip(neutron_client)]: %s" % e)
536 return {'fip_addr': fip_addr, 'fip_id': fip_id}
539 def add_floating_ip(nova_client, server_id, floatingip_addr):
541 nova_client.servers.add_floating_ip(server_id, floatingip_addr)
544 logger.error("Error [add_floating_ip(nova_client, '%s', '%s')]: %s"
545 % (server_id, floatingip_addr, e))
549 def delete_instance(nova_client, instance_id):
551 nova_client.servers.force_delete(instance_id)
554 logger.error("Error [delete_instance(nova_client, '%s')]: %s"
559 def delete_floating_ip(nova_client, floatingip_id):
561 nova_client.floating_ips.delete(floatingip_id)
564 logger.error("Error [delete_floating_ip(nova_client, '%s')]: %s"
565 % (floatingip_id, e))
569 def remove_host_from_aggregate(nova_client, aggregate_name, compute_host):
571 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
572 nova_client.aggregates.remove_host(aggregate_id, compute_host)
575 logger.error("Error [remove_host_from_aggregate(nova_client, %s, %s)]:"
576 " %s" % (aggregate_name, compute_host, e))
580 def remove_hosts_from_aggregate(nova_client, aggregate_name):
581 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
582 hosts = nova_client.aggregates.get(aggregate_id).hosts
584 all(remove_host_from_aggregate(nova_client, aggregate_name, host)
588 def delete_aggregate(nova_client, aggregate_name):
590 remove_hosts_from_aggregate(nova_client, aggregate_name)
591 nova_client.aggregates.delete(aggregate_name)
594 logger.error("Error [delete_aggregate(nova_client, %s)]: %s"
595 % (aggregate_name, e))
599 # *********************************************
601 # *********************************************
602 def get_network_list(neutron_client):
603 network_list = neutron_client.list_networks()['networks']
604 if len(network_list) == 0:
610 def get_router_list(neutron_client):
611 router_list = neutron_client.list_routers()['routers']
612 if len(router_list) == 0:
618 def get_port_list(neutron_client):
619 port_list = neutron_client.list_ports()['ports']
620 if len(port_list) == 0:
626 def get_network_id(neutron_client, network_name):
627 networks = neutron_client.list_networks()['networks']
630 if n['name'] == network_name:
636 def get_subnet_id(neutron_client, subnet_name):
637 subnets = neutron_client.list_subnets()['subnets']
640 if s['name'] == subnet_name:
646 def get_router_id(neutron_client, router_name):
647 routers = neutron_client.list_routers()['routers']
650 if r['name'] == router_name:
656 def get_private_net(neutron_client):
657 # Checks if there is an existing shared private network
658 networks = neutron_client.list_networks()['networks']
659 if len(networks) == 0:
662 if (net['router:external'] is False) and (net['shared'] is True):
667 def get_external_net(neutron_client):
668 for network in neutron_client.list_networks()['networks']:
669 if network['router:external']:
670 return network['name']
674 def get_external_net_id(neutron_client):
675 for network in neutron_client.list_networks()['networks']:
676 if network['router:external']:
681 def check_neutron_net(neutron_client, net_name):
682 for network in neutron_client.list_networks()['networks']:
683 if network['name'] == net_name:
684 for subnet in network['subnets']:
689 def create_neutron_net(neutron_client, name):
690 json_body = {'network': {'name': name,
691 'admin_state_up': True}}
693 network = neutron_client.create_network(body=json_body)
694 network_dict = network['network']
695 return network_dict['id']
697 logger.error("Error [create_neutron_net(neutron_client, '%s')]: %s"
702 def create_neutron_subnet(neutron_client, name, cidr, net_id):
703 json_body = {'subnets': [{'name': name, 'cidr': cidr,
704 'ip_version': 4, 'network_id': net_id}]}
706 subnet = neutron_client.create_subnet(body=json_body)
707 return subnet['subnets'][0]['id']
709 logger.error("Error [create_neutron_subnet(neutron_client, '%s', "
710 "'%s', '%s')]: %s" % (name, cidr, net_id, e))
714 def create_neutron_router(neutron_client, name):
715 json_body = {'router': {'name': name, 'admin_state_up': True}}
717 router = neutron_client.create_router(json_body)
718 return router['router']['id']
720 logger.error("Error [create_neutron_router(neutron_client, '%s')]: %s"
725 def create_neutron_port(neutron_client, name, network_id, ip):
726 json_body = {'port': {
727 'admin_state_up': True,
729 'network_id': network_id,
730 'fixed_ips': [{"ip_address": ip}]
733 port = neutron_client.create_port(body=json_body)
734 return port['port']['id']
736 logger.error("Error [create_neutron_port(neutron_client, '%s', '%s', "
737 "'%s')]: %s" % (name, network_id, ip, e))
741 def update_neutron_net(neutron_client, network_id, shared=False):
742 json_body = {'network': {'shared': shared}}
744 neutron_client.update_network(network_id, body=json_body)
747 logger.error("Error [update_neutron_net(neutron_client, '%s', '%s')]: "
748 "%s" % (network_id, str(shared), e))
752 def update_neutron_port(neutron_client, port_id, device_owner):
753 json_body = {'port': {
754 'device_owner': device_owner,
757 port = neutron_client.update_port(port=port_id,
759 return port['port']['id']
761 logger.error("Error [update_neutron_port(neutron_client, '%s', '%s')]:"
762 " %s" % (port_id, device_owner, e))
766 def add_interface_router(neutron_client, router_id, subnet_id):
767 json_body = {"subnet_id": subnet_id}
769 neutron_client.add_interface_router(router=router_id, body=json_body)
772 logger.error("Error [add_interface_router(neutron_client, '%s', "
773 "'%s')]: %s" % (router_id, subnet_id, e))
777 def add_gateway_router(neutron_client, router_id):
778 ext_net_id = get_external_net_id(neutron_client)
779 router_dict = {'network_id': ext_net_id}
781 neutron_client.add_gateway_router(router_id, router_dict)
784 logger.error("Error [add_gateway_router(neutron_client, '%s')]: %s"
789 def delete_neutron_net(neutron_client, network_id):
791 neutron_client.delete_network(network_id)
794 logger.error("Error [delete_neutron_net(neutron_client, '%s')]: %s"
799 def delete_neutron_subnet(neutron_client, subnet_id):
801 neutron_client.delete_subnet(subnet_id)
804 logger.error("Error [delete_neutron_subnet(neutron_client, '%s')]: %s"
809 def delete_neutron_router(neutron_client, router_id):
811 neutron_client.delete_router(router=router_id)
814 logger.error("Error [delete_neutron_router(neutron_client, '%s')]: %s"
819 def delete_neutron_port(neutron_client, port_id):
821 neutron_client.delete_port(port_id)
824 logger.error("Error [delete_neutron_port(neutron_client, '%s')]: %s"
829 def remove_interface_router(neutron_client, router_id, subnet_id):
830 json_body = {"subnet_id": subnet_id}
832 neutron_client.remove_interface_router(router=router_id,
836 logger.error("Error [remove_interface_router(neutron_client, '%s', "
837 "'%s')]: %s" % (router_id, subnet_id, e))
841 def remove_gateway_router(neutron_client, router_id):
843 neutron_client.remove_gateway_router(router_id)
846 logger.error("Error [remove_gateway_router(neutron_client, '%s')]: %s"
851 def create_network_full(neutron_client,
857 # Check if the network already exists
858 network_id = get_network_id(neutron_client, net_name)
859 subnet_id = get_subnet_id(neutron_client, subnet_name)
860 router_id = get_router_id(neutron_client, router_name)
862 if network_id != '' and subnet_id != '' and router_id != '':
863 logger.info("A network with name '%s' already exists..." % net_name)
865 neutron_client.format = 'json'
866 logger.info('Creating neutron network %s...' % net_name)
867 network_id = create_neutron_net(neutron_client, net_name)
872 logger.debug("Network '%s' created successfully" % network_id)
873 logger.debug('Creating Subnet....')
874 subnet_id = create_neutron_subnet(neutron_client, subnet_name,
879 logger.debug("Subnet '%s' created successfully" % subnet_id)
880 logger.debug('Creating Router...')
881 router_id = create_neutron_router(neutron_client, router_name)
886 logger.debug("Router '%s' created successfully" % router_id)
887 logger.debug('Adding router to subnet...')
889 if not add_interface_router(neutron_client, router_id, subnet_id):
892 logger.debug("Interface added successfully.")
894 logger.debug('Adding gateway to router...')
895 if not add_gateway_router(neutron_client, router_id):
898 logger.debug("Gateway added successfully.")
900 network_dic = {'net_id': network_id,
901 'subnet_id': subnet_id,
902 'router_id': router_id}
906 def create_shared_network_full(net_name, subnt_name, router_name, subnet_cidr):
907 neutron_client = get_neutron_client()
909 network_dic = create_network_full(neutron_client,
915 if not update_neutron_net(neutron_client,
916 network_dic['net_id'],
918 logger.error("Failed to update network %s..." % net_name)
921 logger.debug("Network '%s' is available..." % net_name)
923 logger.error("Network %s creation failed" % net_name)
928 def create_bgpvpn(neutron_client, **kwargs):
929 # route_distinguishers
931 json_body = {"bgpvpn": kwargs}
932 return neutron_client.create_bgpvpn(json_body)
935 def create_network_association(neutron_client, bgpvpn_id, neutron_network_id):
936 json_body = {"network_association": {"network_id": neutron_network_id}}
937 return neutron_client.create_network_association(bgpvpn_id, json_body)
940 def create_router_association(neutron_client, bgpvpn_id, router_id):
941 json_body = {"router_association": {"router_id": router_id}}
942 return neutron_client.create_router_association(bgpvpn_id, json_body)
945 def update_bgpvpn(neutron_client, bgpvpn_id, **kwargs):
946 json_body = {"bgpvpn": kwargs}
947 return neutron_client.update_bgpvpn(bgpvpn_id, json_body)
950 def delete_bgpvpn(neutron_client, bgpvpn_id):
951 return neutron_client.delete_bgpvpn(bgpvpn_id)
954 def get_bgpvpn(neutron_client, bgpvpn_id):
955 return neutron_client.show_bgpvpn(bgpvpn_id)
958 def get_bgpvpn_routers(neutron_client, bgpvpn_id):
959 return get_bgpvpn(neutron_client, bgpvpn_id)['bgpvpn']['routers']
962 def get_bgpvpn_networks(neutron_client, bgpvpn_id):
963 return get_bgpvpn(neutron_client, bgpvpn_id)['bgpvpn']['networks']
965 # *********************************************
967 # *********************************************
970 def get_security_groups(neutron_client):
972 security_groups = neutron_client.list_security_groups()[
974 return security_groups
976 logger.error("Error [get_security_groups(neutron_client)]: %s" % e)
980 def get_security_group_id(neutron_client, sg_name):
981 security_groups = get_security_groups(neutron_client)
983 for sg in security_groups:
984 if sg['name'] == sg_name:
990 def create_security_group(neutron_client, sg_name, sg_description):
991 json_body = {'security_group': {'name': sg_name,
992 'description': sg_description}}
994 secgroup = neutron_client.create_security_group(json_body)
995 return secgroup['security_group']
997 logger.error("Error [create_security_group(neutron_client, '%s', "
998 "'%s')]: %s" % (sg_name, sg_description, e))
1002 def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
1003 port_range_min=None, port_range_max=None):
1004 if port_range_min is None and port_range_max is None:
1005 json_body = {'security_group_rule': {'direction': direction,
1006 'security_group_id': sg_id,
1007 'protocol': protocol}}
1008 elif port_range_min is not None and port_range_max is not None:
1009 json_body = {'security_group_rule': {'direction': direction,
1010 'security_group_id': sg_id,
1011 'port_range_min': port_range_min,
1012 'port_range_max': port_range_max,
1013 'protocol': protocol}}
1015 logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
1016 "'%s', '%s', '%s', '%s')]:" % (neutron_client,
1021 " Invalid values for port_range_min, port_range_max")
1024 neutron_client.create_security_group_rule(json_body)
1026 except Exception, e:
1027 logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
1028 "'%s', '%s', '%s', '%s')]: %s" % (neutron_client,
1037 def create_security_group_full(neutron_client,
1038 sg_name, sg_description):
1039 sg_id = get_security_group_id(neutron_client, sg_name)
1041 logger.info("Using existing security group '%s'..." % sg_name)
1043 logger.info("Creating security group '%s'..." % sg_name)
1044 SECGROUP = create_security_group(neutron_client,
1048 logger.error("Failed to create the security group...")
1051 sg_id = SECGROUP['id']
1053 logger.debug("Security group '%s' with ID=%s created successfully."
1054 % (SECGROUP['name'], sg_id))
1056 logger.debug("Adding ICMP rules in security group '%s'..."
1058 if not create_secgroup_rule(neutron_client, sg_id,
1060 logger.error("Failed to create the security group rule...")
1063 logger.debug("Adding SSH rules in security group '%s'..."
1065 if not create_secgroup_rule(
1066 neutron_client, sg_id, 'ingress', 'tcp', '22', '22'):
1067 logger.error("Failed to create the security group rule...")
1070 if not create_secgroup_rule(
1071 neutron_client, sg_id, 'egress', 'tcp', '22', '22'):
1072 logger.error("Failed to create the security group rule...")
1077 def add_secgroup_to_instance(nova_client, instance_id, secgroup_id):
1079 nova_client.servers.add_security_group(instance_id, secgroup_id)
1081 except Exception, e:
1082 logger.error("Error [add_secgroup_to_instance(nova_client, '%s', "
1083 "'%s')]: %s" % (instance_id, secgroup_id, e))
1087 def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
1088 json_body = {"quota": {
1089 "security_group": sg_quota,
1090 "security_group_rule": sg_rule_quota
1094 neutron_client.update_quota(tenant_id=tenant_id,
1097 except Exception, e:
1098 logger.error("Error [update_sg_quota(neutron_client, '%s', '%s', "
1099 "'%s')]: %s" % (tenant_id, sg_quota, sg_rule_quota, e))
1103 def delete_security_group(neutron_client, secgroup_id):
1105 neutron_client.delete_security_group(secgroup_id)
1107 except Exception, e:
1108 logger.error("Error [delete_security_group(neutron_client, '%s')]: %s"
1113 # *********************************************
1115 # *********************************************
1116 def get_images(nova_client):
1118 images = nova_client.images.list()
1120 except Exception, e:
1121 logger.error("Error [get_images]: %s" % e)
1125 def get_image_id(glance_client, image_name):
1126 images = glance_client.images.list()
1129 if i.name == image_name:
1135 def create_glance_image(glance_client, image_name, file_path, disk="qcow2",
1136 container="bare", public="public"):
1137 if not os.path.isfile(file_path):
1138 logger.error("Error: file %s does not exist." % file_path)
1141 image_id = get_image_id(glance_client, image_name)
1143 logger.info("Image %s already exists." % image_name)
1145 logger.info("Creating image '%s' from '%s'..." % (image_name,
1148 image = glance_client.images.create(name=image_name,
1151 container_format=container)
1153 with open(file_path) as image_data:
1154 glance_client.images.upload(image_id, image_data)
1156 except Exception, e:
1157 logger.error("Error [create_glance_image(glance_client, '%s', '%s', "
1158 "'%s')]: %s" % (image_name, file_path, public, e))
1162 def get_or_create_image(name, path, format):
1163 image_exists = False
1164 glance_client = get_glance_client()
1166 image_id = get_image_id(glance_client, name)
1168 logger.info("Using existing image '%s'..." % name)
1171 logger.info("Creating image '%s' from '%s'..." % (name, path))
1172 image_id = create_glance_image(glance_client, name, path, format)
1174 logger.error("Failed to create a Glance image...")
1176 logger.debug("Image '%s' with ID=%s created successfully."
1179 return image_exists, image_id
1182 def delete_glance_image(nova_client, image_id):
1184 nova_client.images.delete(image_id)
1186 except Exception, e:
1187 logger.error("Error [delete_glance_image(nova_client, '%s')]: %s"
1192 # *********************************************
1194 # *********************************************
1195 def get_volumes(cinder_client):
1197 volumes = cinder_client.volumes.list(search_opts={'all_tenants': 1})
1199 except Exception, e:
1200 logger.error("Error [get_volumes(cinder_client)]: %s" % e)
1204 def list_volume_types(cinder_client, public=True, private=True):
1206 volume_types = cinder_client.volume_types.list()
1208 volume_types = [vt for vt in volume_types if not vt.is_public]
1210 volume_types = [vt for vt in volume_types if vt.is_public]
1212 except Exception, e:
1213 logger.error("Error [list_volume_types(cinder_client)]: %s" % e)
1217 def create_volume_type(cinder_client, name):
1219 volume_type = cinder_client.volume_types.create(name)
1221 except Exception, e:
1222 logger.error("Error [create_volume_type(cinder_client, '%s')]: %s"
1227 def update_cinder_quota(cinder_client, tenant_id, vols_quota,
1228 snapshots_quota, gigabytes_quota):
1229 quotas_values = {"volumes": vols_quota,
1230 "snapshots": snapshots_quota,
1231 "gigabytes": gigabytes_quota}
1234 cinder_client.quotas.update(tenant_id, **quotas_values)
1236 except Exception, e:
1237 logger.error("Error [update_cinder_quota(cinder_client, '%s', '%s', "
1238 "'%s' '%s')]: %s" % (tenant_id, vols_quota,
1239 snapshots_quota, gigabytes_quota, e))
1243 def delete_volume(cinder_client, volume_id, forced=False):
1247 cinder_client.volumes.detach(volume_id)
1249 logger.error(sys.exc_info()[0])
1250 cinder_client.volumes.force_delete(volume_id)
1252 cinder_client.volumes.delete(volume_id)
1254 except Exception, e:
1255 logger.error("Error [delete_volume(cinder_client, '%s', '%s')]: %s"
1256 % (volume_id, str(forced), e))
1260 def delete_volume_type(cinder_client, volume_type):
1262 cinder_client.volume_types.delete(volume_type)
1264 except Exception, e:
1265 logger.error("Error [delete_volume_type(cinder_client, '%s')]: %s"
1270 # *********************************************
1272 # *********************************************
1273 def get_tenants(keystone_client):
1275 if is_keystone_v3():
1276 tenants = keystone_client.projects.list()
1278 tenants = keystone_client.tenants.list()
1280 except Exception, e:
1281 logger.error("Error [get_tenants(keystone_client)]: %s" % e)
1285 def get_users(keystone_client):
1287 users = keystone_client.users.list()
1289 except Exception, e:
1290 logger.error("Error [get_users(keystone_client)]: %s" % e)
1294 def get_tenant_id(keystone_client, tenant_name):
1295 tenants = get_tenants(keystone_client)
1298 if t.name == tenant_name:
1304 def get_user_id(keystone_client, user_name):
1305 users = get_users(keystone_client)
1308 if u.name == user_name:
1314 def get_role_id(keystone_client, role_name):
1315 roles = keystone_client.roles.list()
1318 if r.name == role_name:
1324 def create_tenant(keystone_client, tenant_name, tenant_description):
1326 if is_keystone_v3():
1327 tenant = keystone_client.projects.create(
1329 description=tenant_description,
1333 tenant = keystone_client.tenants.create(tenant_name,
1337 except Exception, e:
1338 logger.error("Error [create_tenant(keystone_client, '%s', '%s')]: %s"
1339 % (tenant_name, tenant_description, e))
1343 def create_user(keystone_client, user_name, user_password,
1344 user_email, tenant_id):
1346 if is_keystone_v3():
1347 user = keystone_client.users.create(name=user_name,
1348 password=user_password,
1350 project_id=tenant_id,
1353 user = keystone_client.users.create(user_name,
1359 except Exception, e:
1360 logger.error("Error [create_user(keystone_client, '%s', '%s', '%s'"
1361 "'%s')]: %s" % (user_name, user_password,
1362 user_email, tenant_id, e))
1366 def add_role_user(keystone_client, user_id, role_id, tenant_id):
1368 if is_keystone_v3():
1369 keystone_client.roles.grant(role=role_id,
1373 keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
1375 except Exception, e:
1376 logger.error("Error [add_role_user(keystone_client, '%s', '%s'"
1377 "'%s')]: %s " % (user_id, role_id, tenant_id, e))
1381 def delete_tenant(keystone_client, tenant_id):
1383 if is_keystone_v3():
1384 keystone_client.projects.delete(tenant_id)
1386 keystone_client.tenants.delete(tenant_id)
1388 except Exception, e:
1389 logger.error("Error [delete_tenant(keystone_client, '%s')]: %s"
1394 def delete_user(keystone_client, user_id):
1396 keystone_client.users.delete(user_id)
1398 except Exception, e:
1399 logger.error("Error [delete_user(keystone_client, '%s')]: %s"
1404 # *********************************************
1406 # *********************************************
1407 def get_resource(heat_client, stack_id, resource):
1409 resources = heat_client.resources.get(stack_id, resource)
1411 except Exception, e:
1412 logger.error("Error [get_resource]: %s" % e)