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 keystone_v3 = is_keystone_v3()
56 env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD']
57 if keystone_v3 is False:
58 env_vars.extend(['OS_TENANT_NAME'])
60 env_vars.extend(['OS_PROJECT_NAME',
61 'OS_USER_DOMAIN_NAME',
62 'OS_PROJECT_DOMAIN_NAME'])
66 def check_credentials():
68 Check if the OpenStack credentials (openrc) are sourced
70 env_vars = get_rc_env_vars()
71 return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
74 def get_env_cred_dict():
76 'OS_USERNAME': 'username',
77 'OS_PASSWORD': 'password',
78 'OS_AUTH_URL': 'auth_url',
79 'OS_TENANT_NAME': 'tenant_name',
80 'OS_USER_DOMAIN_NAME': 'user_domain_name',
81 'OS_PROJECT_DOMAIN_NAME': 'project_domain_name',
82 'OS_PROJECT_NAME': 'project_name',
83 'OS_ENDPOINT_TYPE': 'endpoint_type',
84 'OS_REGION_NAME': 'region_name'
89 def get_credentials():
90 """Returns a creds dictionary filled with parsed from env
93 env_vars = get_rc_env_vars()
94 env_cred_dict = get_env_cred_dict()
96 for envvar in env_vars:
97 if os.getenv(envvar) is None:
98 raise MissingEnvVar(envvar)
100 creds_key = env_cred_dict.get(envvar)
101 creds.update({creds_key: os.getenv(envvar)})
105 def source_credentials(rc_file):
106 pipe = subprocess.Popen(". %s; env" % rc_file, stdout=subprocess.PIPE,
108 output = pipe.communicate()[0]
109 env = dict((line.split("=", 1) for line in output.splitlines()))
110 os.environ.update(env)
114 def get_credentials_for_rally():
115 creds = get_credentials()
116 env_cred_dict = get_env_cred_dict()
117 rally_conf = {"type": "ExistingCloud", "admin": {}}
119 if key == 'auth_url':
120 rally_conf[key] = creds[key]
122 rally_conf['admin'][key] = creds[key]
124 endpoint_types = [('internalURL', 'internal'),
125 ('publicURL', 'public'), ('adminURL', 'admin')]
127 endpoint_type = os.getenv('OS_ENDPOINT_TYPE')
128 if endpoint_type is not None:
129 cred_key = env_cred_dict.get('OS_ENDPOINT_TYPE')
130 for k, v in endpoint_types:
131 if endpoint_type == k:
132 rally_conf[cred_key] = v
134 region_name = os.getenv('OS_REGION_NAME')
135 if region_name is not None:
136 cred_key = env_cred_dict.get('OS_REGION_NAME')
137 rally_conf[cred_key] = region_name
141 def get_session_auth():
142 loader = loading.get_plugin_loader('password')
143 creds = get_credentials()
144 auth = loader.load_from_options(**creds)
148 def get_endpoint(service_type, endpoint_type='publicURL'):
149 auth = get_session_auth()
150 return get_session().get_endpoint(auth=auth,
151 service_type=service_type,
152 endpoint_type=endpoint_type)
156 auth = get_session_auth()
157 return session.Session(auth=auth)
160 # *********************************************
162 # *********************************************
163 def get_keystone_client_version():
164 api_version = os.getenv('OS_IDENTITY_API_VERSION')
165 if api_version is not None:
166 logger.info("OS_IDENTITY_API_VERSION is set in env as '%s'",
169 return DEFAULT_API_VERSION
172 def get_keystone_client():
174 return keystoneclient.Client(get_keystone_client_version(), session=sess)
177 def get_nova_client_version():
178 api_version = os.getenv('OS_COMPUTE_API_VERSION')
179 if api_version is not None:
180 logger.info("OS_COMPUTE_API_VERSION is set in env as '%s'",
183 return DEFAULT_API_VERSION
186 def get_nova_client():
188 return novaclient.Client(get_nova_client_version(), session=sess)
191 def get_cinder_client_version():
192 api_version = os.getenv('OS_VOLUME_API_VERSION')
193 if api_version is not None:
194 logger.info("OS_VOLUME_API_VERSION is set in env as '%s'",
197 return DEFAULT_API_VERSION
200 def get_cinder_client():
202 return cinderclient.Client(get_cinder_client_version(), session=sess)
205 def get_neutron_client_version():
206 api_version = os.getenv('OS_NETWORK_API_VERSION')
207 if api_version is not None:
208 logger.info("OS_NETWORK_API_VERSION is set in env as '%s'",
211 return DEFAULT_API_VERSION
214 def get_neutron_client():
216 return neutronclient.Client(get_neutron_client_version(), session=sess)
219 def get_glance_client_version():
220 api_version = os.getenv('OS_IMAGE_API_VERSION')
221 if api_version is not None:
222 logger.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
224 return DEFAULT_API_VERSION
227 def get_glance_client():
229 return glanceclient.Client(get_glance_client_version(), session=sess)
232 # *********************************************
234 # *********************************************
235 def get_instances(nova_client):
237 instances = nova_client.servers.list(search_opts={'all_tenants': 1})
240 logger.error("Error [get_instances(nova_client)]: %s" % e)
244 def get_instance_status(nova_client, instance):
246 instance = nova_client.servers.get(instance.id)
247 return instance.status
249 logger.error("Error [get_instance_status(nova_client)]: %s" % e)
253 def get_instance_by_name(nova_client, instance_name):
255 instance = nova_client.servers.find(name=instance_name)
258 logger.error("Error [get_instance_by_name(nova_client, '%s')]: %s"
259 % (instance_name, e))
263 def get_flavor_id(nova_client, flavor_name):
264 flavors = nova_client.flavors.list(detailed=True)
267 if f.name == flavor_name:
273 def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram):
274 flavors = nova_client.flavors.list(detailed=True)
277 if min_ram <= f.ram and f.ram <= max_ram:
283 def get_aggregates(nova_client):
285 aggregates = nova_client.aggregates.list()
288 logger.error("Error [get_aggregates(nova_client)]: %s" % e)
292 def get_aggregate_id(nova_client, aggregate_name):
294 aggregates = get_aggregates(nova_client)
295 _id = [ag.id for ag in aggregates if ag.name == aggregate_name][0]
298 logger.error("Error [get_aggregate_id(nova_client, %s)]:"
299 " %s" % (aggregate_name, e))
303 def get_availability_zones(nova_client):
305 availability_zones = nova_client.availability_zones.list()
306 return availability_zones
308 logger.error("Error [get_availability_zones(nova_client)]: %s" % e)
312 def get_availability_zone_names(nova_client):
314 az_names = [az.zoneName for az in get_availability_zones(nova_client)]
317 logger.error("Error [get_availability_zone_names(nova_client)]:"
322 def create_flavor(nova_client, flavor_name, ram, disk, vcpus, public=True):
324 flavor = nova_client.flavors.create(
325 flavor_name, ram, vcpus, disk, is_public=public)
327 extra_specs = ft_utils.get_functest_config(
328 'general.flavor_extra_specs')
329 flavor.set_keys(extra_specs)
331 # flavor extra specs are not configured, therefore skip the update
335 logger.error("Error [create_flavor(nova_client, '%s', '%s', '%s', "
336 "'%s')]: %s" % (flavor_name, ram, disk, vcpus, e))
341 def get_or_create_flavor(flavor_name, ram, disk, vcpus, public=True):
342 flavor_exists = False
343 nova_client = get_nova_client()
345 flavor_id = get_flavor_id(nova_client, flavor_name)
347 logger.info("Using existing flavor '%s'..." % flavor_name)
350 logger.info("Creating flavor '%s' with '%s' RAM, '%s' disk size, "
351 "'%s' vcpus..." % (flavor_name, ram, disk, vcpus))
352 flavor_id = create_flavor(
353 nova_client, flavor_name, ram, disk, vcpus, public=public)
355 logger.error("Failed to create flavor '%s'..." % (flavor_name))
357 logger.debug("Flavor '%s' with ID=%s created successfully."
358 % (flavor_name, flavor_id))
360 return flavor_exists, flavor_id
363 def get_floating_ips(nova_client):
365 floating_ips = nova_client.floating_ips.list()
368 logger.error("Error [get_floating_ips(nova_client)]: %s" % e)
372 def get_hypervisors(nova_client):
375 hypervisors = nova_client.hypervisors.list()
376 for hypervisor in hypervisors:
377 if hypervisor.state == "up":
378 nodes.append(hypervisor.hypervisor_hostname)
381 logger.error("Error [get_hypervisors(nova_client)]: %s" % e)
385 def create_aggregate(nova_client, aggregate_name, av_zone):
387 nova_client.aggregates.create(aggregate_name, av_zone)
390 logger.error("Error [create_aggregate(nova_client, %s, %s)]: %s"
391 % (aggregate_name, av_zone, e))
395 def add_host_to_aggregate(nova_client, aggregate_name, compute_host):
397 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
398 nova_client.aggregates.add_host(aggregate_id, compute_host)
401 logger.error("Error [add_host_to_aggregate(nova_client, %s, %s)]: %s"
402 % (aggregate_name, compute_host, e))
406 def create_aggregate_with_host(
407 nova_client, aggregate_name, av_zone, compute_host):
409 create_aggregate(nova_client, aggregate_name, av_zone)
410 add_host_to_aggregate(nova_client, aggregate_name, compute_host)
413 logger.error("Error [create_aggregate_with_host("
414 "nova_client, %s, %s, %s)]: %s"
415 % (aggregate_name, av_zone, compute_host, e))
419 def create_instance(flavor_name,
422 instance_name="functest-vm",
428 nova_client = get_nova_client()
430 flavor = nova_client.flavors.find(name=flavor_name)
432 flavors = nova_client.flavors.list()
433 logger.error("Error: Flavor '%s' not found. Available flavors are: "
434 "\n%s" % (flavor_name, flavors))
436 if fixed_ip is not None:
437 nics = {"net-id": network_id, "v4-fixed-ip": fixed_ip}
439 nics = {"net-id": network_id}
441 instance = nova_client.servers.create(
446 availability_zone=av_zone,
450 instance = nova_client.servers.create(
455 config_drive=confdrive,
457 availability_zone=av_zone,
463 def create_instance_and_wait_for_active(flavor_name,
473 VM_BOOT_TIMEOUT = 180
474 nova_client = get_nova_client()
475 instance = create_instance(flavor_name,
484 count = VM_BOOT_TIMEOUT / SLEEP
485 for n in range(count, -1, -1):
486 status = get_instance_status(nova_client, instance)
487 if status.lower() == "active":
489 elif status.lower() == "error":
490 logger.error("The instance %s went to ERROR status."
494 logger.error("Timeout booting the instance %s." % instance_name)
498 def create_floating_ip(neutron_client):
499 extnet_id = get_external_net_id(neutron_client)
500 props = {'floating_network_id': extnet_id}
502 ip_json = neutron_client.create_floatingip({'floatingip': props})
503 fip_addr = ip_json['floatingip']['floating_ip_address']
504 fip_id = ip_json['floatingip']['id']
506 logger.error("Error [create_floating_ip(neutron_client)]: %s" % e)
508 return {'fip_addr': fip_addr, 'fip_id': fip_id}
511 def add_floating_ip(nova_client, server_id, floatingip_addr):
513 nova_client.servers.add_floating_ip(server_id, floatingip_addr)
516 logger.error("Error [add_floating_ip(nova_client, '%s', '%s')]: %s"
517 % (server_id, floatingip_addr, e))
521 def delete_instance(nova_client, instance_id):
523 nova_client.servers.force_delete(instance_id)
526 logger.error("Error [delete_instance(nova_client, '%s')]: %s"
531 def delete_floating_ip(nova_client, floatingip_id):
533 nova_client.floating_ips.delete(floatingip_id)
536 logger.error("Error [delete_floating_ip(nova_client, '%s')]: %s"
537 % (floatingip_id, e))
541 def remove_host_from_aggregate(nova_client, aggregate_name, compute_host):
543 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
544 nova_client.aggregates.remove_host(aggregate_id, compute_host)
547 logger.error("Error [remove_host_from_aggregate(nova_client, %s, %s)]:"
548 " %s" % (aggregate_name, compute_host, e))
552 def remove_hosts_from_aggregate(nova_client, aggregate_name):
553 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
554 hosts = nova_client.aggregates.get(aggregate_id).hosts
556 all(remove_host_from_aggregate(nova_client, aggregate_name, host)
560 def delete_aggregate(nova_client, aggregate_name):
562 remove_hosts_from_aggregate(nova_client, aggregate_name)
563 nova_client.aggregates.delete(aggregate_name)
566 logger.error("Error [delete_aggregate(nova_client, %s)]: %s"
567 % (aggregate_name, e))
571 # *********************************************
573 # *********************************************
574 def get_network_list(neutron_client):
575 network_list = neutron_client.list_networks()['networks']
576 if len(network_list) == 0:
582 def get_router_list(neutron_client):
583 router_list = neutron_client.list_routers()['routers']
584 if len(router_list) == 0:
590 def get_port_list(neutron_client):
591 port_list = neutron_client.list_ports()['ports']
592 if len(port_list) == 0:
598 def get_network_id(neutron_client, network_name):
599 networks = neutron_client.list_networks()['networks']
602 if n['name'] == network_name:
608 def get_subnet_id(neutron_client, subnet_name):
609 subnets = neutron_client.list_subnets()['subnets']
612 if s['name'] == subnet_name:
618 def get_router_id(neutron_client, router_name):
619 routers = neutron_client.list_routers()['routers']
622 if r['name'] == router_name:
628 def get_private_net(neutron_client):
629 # Checks if there is an existing shared private network
630 networks = neutron_client.list_networks()['networks']
631 if len(networks) == 0:
634 if (net['router:external'] is False) and (net['shared'] is True):
639 def get_external_net(neutron_client):
640 for network in neutron_client.list_networks()['networks']:
641 if network['router:external']:
642 return network['name']
646 def get_external_net_id(neutron_client):
647 for network in neutron_client.list_networks()['networks']:
648 if network['router:external']:
653 def check_neutron_net(neutron_client, net_name):
654 for network in neutron_client.list_networks()['networks']:
655 if network['name'] == net_name:
656 for subnet in network['subnets']:
661 def create_neutron_net(neutron_client, name):
662 json_body = {'network': {'name': name,
663 'admin_state_up': True}}
665 network = neutron_client.create_network(body=json_body)
666 network_dict = network['network']
667 return network_dict['id']
669 logger.error("Error [create_neutron_net(neutron_client, '%s')]: %s"
674 def create_neutron_subnet(neutron_client, name, cidr, net_id):
675 json_body = {'subnets': [{'name': name, 'cidr': cidr,
676 'ip_version': 4, 'network_id': net_id}]}
678 subnet = neutron_client.create_subnet(body=json_body)
679 return subnet['subnets'][0]['id']
681 logger.error("Error [create_neutron_subnet(neutron_client, '%s', "
682 "'%s', '%s')]: %s" % (name, cidr, net_id, e))
686 def create_neutron_router(neutron_client, name):
687 json_body = {'router': {'name': name, 'admin_state_up': True}}
689 router = neutron_client.create_router(json_body)
690 return router['router']['id']
692 logger.error("Error [create_neutron_router(neutron_client, '%s')]: %s"
697 def create_neutron_port(neutron_client, name, network_id, ip):
698 json_body = {'port': {
699 'admin_state_up': True,
701 'network_id': network_id,
702 'fixed_ips': [{"ip_address": ip}]
705 port = neutron_client.create_port(body=json_body)
706 return port['port']['id']
708 logger.error("Error [create_neutron_port(neutron_client, '%s', '%s', "
709 "'%s')]: %s" % (name, network_id, ip, e))
713 def update_neutron_net(neutron_client, network_id, shared=False):
714 json_body = {'network': {'shared': shared}}
716 neutron_client.update_network(network_id, body=json_body)
719 logger.error("Error [update_neutron_net(neutron_client, '%s', '%s')]: "
720 "%s" % (network_id, str(shared), e))
724 def update_neutron_port(neutron_client, port_id, device_owner):
725 json_body = {'port': {
726 'device_owner': device_owner,
729 port = neutron_client.update_port(port=port_id,
731 return port['port']['id']
733 logger.error("Error [update_neutron_port(neutron_client, '%s', '%s')]:"
734 " %s" % (port_id, device_owner, e))
738 def add_interface_router(neutron_client, router_id, subnet_id):
739 json_body = {"subnet_id": subnet_id}
741 neutron_client.add_interface_router(router=router_id, body=json_body)
744 logger.error("Error [add_interface_router(neutron_client, '%s', "
745 "'%s')]: %s" % (router_id, subnet_id, e))
749 def add_gateway_router(neutron_client, router_id):
750 ext_net_id = get_external_net_id(neutron_client)
751 router_dict = {'network_id': ext_net_id}
753 neutron_client.add_gateway_router(router_id, router_dict)
756 logger.error("Error [add_gateway_router(neutron_client, '%s')]: %s"
761 def delete_neutron_net(neutron_client, network_id):
763 neutron_client.delete_network(network_id)
766 logger.error("Error [delete_neutron_net(neutron_client, '%s')]: %s"
771 def delete_neutron_subnet(neutron_client, subnet_id):
773 neutron_client.delete_subnet(subnet_id)
776 logger.error("Error [delete_neutron_subnet(neutron_client, '%s')]: %s"
781 def delete_neutron_router(neutron_client, router_id):
783 neutron_client.delete_router(router=router_id)
786 logger.error("Error [delete_neutron_router(neutron_client, '%s')]: %s"
791 def delete_neutron_port(neutron_client, port_id):
793 neutron_client.delete_port(port_id)
796 logger.error("Error [delete_neutron_port(neutron_client, '%s')]: %s"
801 def remove_interface_router(neutron_client, router_id, subnet_id):
802 json_body = {"subnet_id": subnet_id}
804 neutron_client.remove_interface_router(router=router_id,
808 logger.error("Error [remove_interface_router(neutron_client, '%s', "
809 "'%s')]: %s" % (router_id, subnet_id, e))
813 def remove_gateway_router(neutron_client, router_id):
815 neutron_client.remove_gateway_router(router_id)
818 logger.error("Error [remove_gateway_router(neutron_client, '%s')]: %s"
823 def create_network_full(neutron_client,
829 # Check if the network already exists
830 network_id = get_network_id(neutron_client, net_name)
831 subnet_id = get_subnet_id(neutron_client, subnet_name)
832 router_id = get_router_id(neutron_client, router_name)
834 if network_id != '' and subnet_id != '' and router_id != '':
835 logger.info("A network with name '%s' already exists..." % net_name)
837 neutron_client.format = 'json'
838 logger.info('Creating neutron network %s...' % net_name)
839 network_id = create_neutron_net(neutron_client, net_name)
844 logger.debug("Network '%s' created successfully" % network_id)
845 logger.debug('Creating Subnet....')
846 subnet_id = create_neutron_subnet(neutron_client, subnet_name,
851 logger.debug("Subnet '%s' created successfully" % subnet_id)
852 logger.debug('Creating Router...')
853 router_id = create_neutron_router(neutron_client, router_name)
858 logger.debug("Router '%s' created successfully" % router_id)
859 logger.debug('Adding router to subnet...')
861 if not add_interface_router(neutron_client, router_id, subnet_id):
864 logger.debug("Interface added successfully.")
866 logger.debug('Adding gateway to router...')
867 if not add_gateway_router(neutron_client, router_id):
870 logger.debug("Gateway added successfully.")
872 network_dic = {'net_id': network_id,
873 'subnet_id': subnet_id,
874 'router_id': router_id}
878 def create_shared_network_full(net_name, subnt_name, router_name, subnet_cidr):
879 neutron_client = get_neutron_client()
881 network_dic = create_network_full(neutron_client,
887 if not update_neutron_net(neutron_client,
888 network_dic['net_id'],
890 logger.error("Failed to update network %s..." % net_name)
893 logger.debug("Network '%s' is available..." % net_name)
895 logger.error("Network %s creation failed" % net_name)
900 def create_bgpvpn(neutron_client, **kwargs):
901 # route_distinguishers
903 json_body = {"bgpvpn": kwargs}
904 return neutron_client.create_bgpvpn(json_body)
907 def create_network_association(neutron_client, bgpvpn_id, neutron_network_id):
908 json_body = {"network_association": {"network_id": neutron_network_id}}
909 return neutron_client.create_network_association(bgpvpn_id, json_body)
912 def create_router_association(neutron_client, bgpvpn_id, router_id):
913 json_body = {"router_association": {"router_id": router_id}}
914 return neutron_client.create_router_association(bgpvpn_id, json_body)
917 def update_bgpvpn(neutron_client, bgpvpn_id, **kwargs):
918 json_body = {"bgpvpn": kwargs}
919 return neutron_client.update_bgpvpn(bgpvpn_id, json_body)
922 def delete_bgpvpn(neutron_client, bgpvpn_id):
923 return neutron_client.delete_bgpvpn(bgpvpn_id)
926 def get_bgpvpn(neutron_client, bgpvpn_id):
927 return neutron_client.show_bgpvpn(bgpvpn_id)
930 def get_bgpvpn_routers(neutron_client, bgpvpn_id):
931 return get_bgpvpn(neutron_client, bgpvpn_id)['bgpvpn']['routers']
934 def get_bgpvpn_networks(neutron_client, bgpvpn_id):
935 return get_bgpvpn(neutron_client, bgpvpn_id)['bgpvpn']['networks']
937 # *********************************************
939 # *********************************************
942 def get_security_groups(neutron_client):
944 security_groups = neutron_client.list_security_groups()[
946 return security_groups
948 logger.error("Error [get_security_groups(neutron_client)]: %s" % e)
952 def get_security_group_id(neutron_client, sg_name):
953 security_groups = get_security_groups(neutron_client)
955 for sg in security_groups:
956 if sg['name'] == sg_name:
962 def create_security_group(neutron_client, sg_name, sg_description):
963 json_body = {'security_group': {'name': sg_name,
964 'description': sg_description}}
966 secgroup = neutron_client.create_security_group(json_body)
967 return secgroup['security_group']
969 logger.error("Error [create_security_group(neutron_client, '%s', "
970 "'%s')]: %s" % (sg_name, sg_description, e))
974 def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
975 port_range_min=None, port_range_max=None):
976 if port_range_min is None and port_range_max is None:
977 json_body = {'security_group_rule': {'direction': direction,
978 'security_group_id': sg_id,
979 'protocol': protocol}}
980 elif port_range_min is not None and port_range_max is not None:
981 json_body = {'security_group_rule': {'direction': direction,
982 'security_group_id': sg_id,
983 'port_range_min': port_range_min,
984 'port_range_max': port_range_max,
985 'protocol': protocol}}
987 logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
988 "'%s', '%s', '%s', '%s')]:" % (neutron_client,
993 " Invalid values for port_range_min, port_range_max")
996 neutron_client.create_security_group_rule(json_body)
999 logger.error("Error [create_secgroup_rule(neutron_client, '%s', '%s', "
1000 "'%s', '%s', '%s', '%s')]: %s" % (neutron_client,
1009 def create_security_group_full(neutron_client,
1010 sg_name, sg_description):
1011 sg_id = get_security_group_id(neutron_client, sg_name)
1013 logger.info("Using existing security group '%s'..." % sg_name)
1015 logger.info("Creating security group '%s'..." % sg_name)
1016 SECGROUP = create_security_group(neutron_client,
1020 logger.error("Failed to create the security group...")
1023 sg_id = SECGROUP['id']
1025 logger.debug("Security group '%s' with ID=%s created successfully."
1026 % (SECGROUP['name'], sg_id))
1028 logger.debug("Adding ICMP rules in security group '%s'..."
1030 if not create_secgroup_rule(neutron_client, sg_id,
1032 logger.error("Failed to create the security group rule...")
1035 logger.debug("Adding SSH rules in security group '%s'..."
1037 if not create_secgroup_rule(
1038 neutron_client, sg_id, 'ingress', 'tcp', '22', '22'):
1039 logger.error("Failed to create the security group rule...")
1042 if not create_secgroup_rule(
1043 neutron_client, sg_id, 'egress', 'tcp', '22', '22'):
1044 logger.error("Failed to create the security group rule...")
1049 def add_secgroup_to_instance(nova_client, instance_id, secgroup_id):
1051 nova_client.servers.add_security_group(instance_id, secgroup_id)
1053 except Exception, e:
1054 logger.error("Error [add_secgroup_to_instance(nova_client, '%s', "
1055 "'%s')]: %s" % (instance_id, secgroup_id, e))
1059 def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
1060 json_body = {"quota": {
1061 "security_group": sg_quota,
1062 "security_group_rule": sg_rule_quota
1066 neutron_client.update_quota(tenant_id=tenant_id,
1069 except Exception, e:
1070 logger.error("Error [update_sg_quota(neutron_client, '%s', '%s', "
1071 "'%s')]: %s" % (tenant_id, sg_quota, sg_rule_quota, e))
1075 def delete_security_group(neutron_client, secgroup_id):
1077 neutron_client.delete_security_group(secgroup_id)
1079 except Exception, e:
1080 logger.error("Error [delete_security_group(neutron_client, '%s')]: %s"
1085 # *********************************************
1087 # *********************************************
1088 def get_images(nova_client):
1090 images = nova_client.images.list()
1092 except Exception, e:
1093 logger.error("Error [get_images]: %s" % e)
1097 def get_image_id(glance_client, image_name):
1098 images = glance_client.images.list()
1101 if i.name == image_name:
1107 def create_glance_image(glance_client, image_name, file_path, disk="qcow2",
1108 container="bare", public="public"):
1109 if not os.path.isfile(file_path):
1110 logger.error("Error: file %s does not exist." % file_path)
1113 image_id = get_image_id(glance_client, image_name)
1115 logger.info("Image %s already exists." % image_name)
1117 logger.info("Creating image '%s' from '%s'..." % (image_name,
1120 image = glance_client.images.create(name=image_name,
1123 container_format=container)
1125 with open(file_path) as image_data:
1126 glance_client.images.upload(image_id, image_data)
1128 except Exception, e:
1129 logger.error("Error [create_glance_image(glance_client, '%s', '%s', "
1130 "'%s')]: %s" % (image_name, file_path, public, e))
1134 def get_or_create_image(name, path, format):
1135 image_exists = False
1136 glance_client = get_glance_client()
1138 image_id = get_image_id(glance_client, name)
1140 logger.info("Using existing image '%s'..." % name)
1143 logger.info("Creating image '%s' from '%s'..." % (name, path))
1144 image_id = create_glance_image(glance_client, name, path, format)
1146 logger.error("Failed to create a Glance image...")
1148 logger.debug("Image '%s' with ID=%s created successfully."
1151 return image_exists, image_id
1154 def delete_glance_image(nova_client, image_id):
1156 nova_client.images.delete(image_id)
1158 except Exception, e:
1159 logger.error("Error [delete_glance_image(nova_client, '%s')]: %s"
1164 # *********************************************
1166 # *********************************************
1167 def get_volumes(cinder_client):
1169 volumes = cinder_client.volumes.list(search_opts={'all_tenants': 1})
1171 except Exception, e:
1172 logger.error("Error [get_volumes(cinder_client)]: %s" % e)
1176 def list_volume_types(cinder_client, public=True, private=True):
1178 volume_types = cinder_client.volume_types.list()
1180 volume_types = [vt for vt in volume_types if not vt.is_public]
1182 volume_types = [vt for vt in volume_types if vt.is_public]
1184 except Exception, e:
1185 logger.error("Error [list_volume_types(cinder_client)]: %s" % e)
1189 def create_volume_type(cinder_client, name):
1191 volume_type = cinder_client.volume_types.create(name)
1193 except Exception, e:
1194 logger.error("Error [create_volume_type(cinder_client, '%s')]: %s"
1199 def update_cinder_quota(cinder_client, tenant_id, vols_quota,
1200 snapshots_quota, gigabytes_quota):
1201 quotas_values = {"volumes": vols_quota,
1202 "snapshots": snapshots_quota,
1203 "gigabytes": gigabytes_quota}
1206 cinder_client.quotas.update(tenant_id, **quotas_values)
1208 except Exception, e:
1209 logger.error("Error [update_cinder_quota(cinder_client, '%s', '%s', "
1210 "'%s' '%s')]: %s" % (tenant_id, vols_quota,
1211 snapshots_quota, gigabytes_quota, e))
1215 def delete_volume(cinder_client, volume_id, forced=False):
1219 cinder_client.volumes.detach(volume_id)
1221 logger.error(sys.exc_info()[0])
1222 cinder_client.volumes.force_delete(volume_id)
1224 cinder_client.volumes.delete(volume_id)
1226 except Exception, e:
1227 logger.error("Error [delete_volume(cinder_client, '%s', '%s')]: %s"
1228 % (volume_id, str(forced), e))
1232 def delete_volume_type(cinder_client, volume_type):
1234 cinder_client.volume_types.delete(volume_type)
1236 except Exception, e:
1237 logger.error("Error [delete_volume_type(cinder_client, '%s')]: %s"
1242 # *********************************************
1244 # *********************************************
1245 def get_tenants(keystone_client):
1247 tenants = keystone_client.tenants.list()
1249 except Exception, e:
1250 logger.error("Error [get_tenants(keystone_client)]: %s" % e)
1254 def get_users(keystone_client):
1256 users = keystone_client.users.list()
1258 except Exception, e:
1259 logger.error("Error [get_users(keystone_client)]: %s" % e)
1263 def get_tenant_id(keystone_client, tenant_name):
1264 tenants = keystone_client.tenants.list()
1267 if t.name == tenant_name:
1273 def get_user_id(keystone_client, user_name):
1274 users = keystone_client.users.list()
1277 if u.name == user_name:
1283 def get_role_id(keystone_client, role_name):
1284 roles = keystone_client.roles.list()
1287 if r.name == role_name:
1293 def create_tenant(keystone_client, tenant_name, tenant_description):
1295 tenant = keystone_client.tenants.create(tenant_name,
1299 except Exception, e:
1300 logger.error("Error [create_tenant(keystone_client, '%s', '%s')]: %s"
1301 % (tenant_name, tenant_description, e))
1305 def create_user(keystone_client, user_name, user_password,
1306 user_email, tenant_id):
1308 user = keystone_client.users.create(user_name, user_password,
1309 user_email, tenant_id,
1312 except Exception, e:
1313 logger.error("Error [create_user(keystone_client, '%s', '%s', '%s'"
1314 "'%s')]: %s" % (user_name, user_password,
1315 user_email, tenant_id, e))
1319 def add_role_user(keystone_client, user_id, role_id, tenant_id):
1321 keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
1323 except Exception, e:
1324 logger.error("Error [add_role_user(keystone_client, '%s', '%s'"
1325 "'%s')]: %s " % (user_id, role_id, tenant_id, e))
1329 def delete_tenant(keystone_client, tenant_id):
1331 keystone_client.tenants.delete(tenant_id)
1333 except Exception, e:
1334 logger.error("Error [delete_tenant(keystone_client, '%s')]: %s"
1339 def delete_user(keystone_client, user_id):
1341 keystone_client.users.delete(user_id)
1343 except Exception, e:
1344 logger.error("Error [delete_user(keystone_client, '%s')]: %s"