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
19 from keystoneauth1 import loading
20 from keystoneauth1 import session
21 from cinderclient import client as cinderclient
22 from heatclient import client as heatclient
23 from keystoneclient import client as keystoneclient
24 from neutronclient.neutron import client as neutronclient
25 from openstack import connection
26 from openstack import cloud as os_cloud
28 from functest.utils import env
30 logger = logging.getLogger(__name__)
32 DEFAULT_API_VERSION = '2'
33 DEFAULT_HEAT_API_VERSION = '1'
36 # *********************************************
38 # *********************************************
39 class MissingEnvVar(Exception):
41 def __init__(self, var):
45 return str.format("Please set the mandatory env var: {}", self.var)
48 def get_os_connection():
49 return connection.from_config()
53 return os_cloud.openstack_cloud()
57 keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
58 if (keystone_api_version is None or
59 keystone_api_version == '2'):
65 def get_rc_env_vars():
66 env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD']
68 env_vars.extend(['OS_PROJECT_NAME',
69 'OS_USER_DOMAIN_NAME',
70 'OS_PROJECT_DOMAIN_NAME'])
72 env_vars.extend(['OS_TENANT_NAME'])
76 def check_credentials():
78 Check if the OpenStack credentials (openrc) are sourced
80 env_vars = get_rc_env_vars()
81 return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
84 def get_env_cred_dict():
86 'OS_USERNAME': 'username',
87 'OS_PASSWORD': 'password',
88 'OS_AUTH_URL': 'auth_url',
89 'OS_TENANT_NAME': 'tenant_name',
90 'OS_USER_DOMAIN_NAME': 'user_domain_name',
91 'OS_PROJECT_DOMAIN_NAME': 'project_domain_name',
92 'OS_PROJECT_NAME': 'project_name',
93 'OS_ENDPOINT_TYPE': 'endpoint_type',
94 'OS_REGION_NAME': 'region_name',
95 'OS_CACERT': 'https_cacert',
96 'OS_INSECURE': 'https_insecure'
101 def get_credentials(other_creds={}):
102 """Returns a creds dictionary filled with parsed from env
105 env_vars = get_rc_env_vars()
106 env_cred_dict = get_env_cred_dict()
108 for envvar in env_vars:
109 if os.getenv(envvar) is None:
110 raise MissingEnvVar(envvar)
112 creds_key = env_cred_dict.get(envvar)
113 creds.update({creds_key: os.getenv(envvar)})
115 if 'tenant' in other_creds.keys():
117 tenant = 'project_name'
119 tenant = 'tenant_name'
120 other_creds[tenant] = other_creds.pop('tenant')
122 creds.update(other_creds)
127 def get_session_auth(other_creds={}):
128 loader = loading.get_plugin_loader('password')
129 creds = get_credentials(other_creds)
130 auth = loader.load_from_options(**creds)
134 def get_endpoint(service_type, interface='public'):
135 auth = get_session_auth()
136 return get_session().get_endpoint(auth=auth,
137 service_type=service_type,
141 def get_session(other_creds={}):
142 auth = get_session_auth(other_creds)
143 https_cacert = os.getenv('OS_CACERT', '')
144 https_insecure = os.getenv('OS_INSECURE', '').lower() == 'true'
145 return session.Session(auth=auth,
146 verify=(https_cacert or not https_insecure))
149 # *********************************************
151 # *********************************************
152 def get_keystone_client_version():
153 api_version = os.getenv('OS_IDENTITY_API_VERSION')
154 if api_version is not None:
155 logger.info("OS_IDENTITY_API_VERSION is set in env as '%s'",
158 return DEFAULT_API_VERSION
161 def get_keystone_client(other_creds={}):
162 sess = get_session(other_creds)
163 return keystoneclient.Client(get_keystone_client_version(),
165 interface=os.getenv('OS_INTERFACE', 'admin'))
168 def get_cinder_client_version():
169 api_version = os.getenv('OS_VOLUME_API_VERSION')
170 if api_version is not None:
171 logger.info("OS_VOLUME_API_VERSION is set in env as '%s'",
174 return DEFAULT_API_VERSION
177 def get_cinder_client(other_creds={}):
178 sess = get_session(other_creds)
179 return cinderclient.Client(get_cinder_client_version(), session=sess)
182 def get_neutron_client_version():
183 api_version = os.getenv('OS_NETWORK_API_VERSION')
184 if api_version is not None:
185 logger.info("OS_NETWORK_API_VERSION is set in env as '%s'",
188 return DEFAULT_API_VERSION
191 def get_neutron_client(other_creds={}):
192 sess = get_session(other_creds)
193 return neutronclient.Client(get_neutron_client_version(), session=sess)
196 def get_heat_client_version():
197 api_version = os.getenv('OS_ORCHESTRATION_API_VERSION')
198 if api_version is not None:
199 logger.info("OS_ORCHESTRATION_API_VERSION is set in env as '%s'",
202 return DEFAULT_HEAT_API_VERSION
205 def get_heat_client(other_creds={}):
206 sess = get_session(other_creds)
207 return heatclient.Client(get_heat_client_version(), session=sess)
210 def download_url(url, dest_path):
212 Download a file to a destination path given a URL
214 name = url.rsplit('/')[-1]
215 dest = dest_path + "/" + name
217 response = urllib.urlopen(url)
221 with open(dest, 'wb') as lfile:
222 shutil.copyfileobj(response, lfile)
226 def download_and_add_image_on_glance(conn, image_name, image_url, data_dir):
229 if not os.path.exists(dest_path):
230 os.makedirs(dest_path)
231 file_name = image_url.rsplit('/')[-1]
232 if not download_url(image_url, dest_path):
235 raise Exception("Impossible to download image from {}".format(
239 image = create_glance_image(
240 conn, image_name, dest_path + file_name)
246 raise Exception("Impossible to put image {} in glance".format(
250 # *********************************************
252 # *********************************************
253 def get_instances(conn):
255 instances = conn.compute.servers(all_tenants=1)
257 except Exception as e:
258 logger.error("Error [get_instances(compute)]: %s" % e)
262 def get_instance_status(conn, instance):
264 instance = conn.compute.get_server(instance.id)
265 return instance.status
266 except Exception as e:
267 logger.error("Error [get_instance_status(compute)]: %s" % e)
271 def get_instance_by_name(conn, instance_name):
273 instance = conn.compute.find_server(instance_name,
274 ignore_missing=False)
276 except Exception as e:
277 logger.error("Error [get_instance_by_name(compute, '%s')]: %s"
278 % (instance_name, e))
282 def get_flavor_id(conn, flavor_name):
283 flavors = conn.compute.flavors()
286 if f.name == flavor_name:
292 def get_flavor_id_by_ram_range(conn, min_ram, max_ram):
293 flavors = conn.compute.flavors()
296 if min_ram <= f.ram and f.ram <= max_ram:
302 def get_aggregates(cloud):
304 aggregates = cloud.list_aggregates()
306 except Exception as e:
307 logger.error("Error [get_aggregates(compute)]: %s" % e)
311 def get_aggregate_id(cloud, aggregate_name):
313 aggregates = get_aggregates(cloud)
314 _id = [ag.id for ag in aggregates if ag.name == aggregate_name][0]
316 except Exception as e:
317 logger.error("Error [get_aggregate_id(compute, %s)]:"
318 " %s" % (aggregate_name, e))
322 def get_availability_zones(conn):
324 availability_zones = conn.compute.availability_zones()
325 return availability_zones
326 except Exception as e:
327 logger.error("Error [get_availability_zones(compute)]: %s" % e)
331 def get_availability_zone_names(conn):
333 az_names = [az.zoneName for az in get_availability_zones(conn)]
335 except Exception as e:
336 logger.error("Error [get_availability_zone_names(compute)]:"
341 def create_flavor(conn, flavor_name, ram, disk, vcpus, public=True):
343 flavor = conn.compute.create_flavor(
344 name=flavor_name, ram=ram, disk=disk, vcpus=vcpus,
346 except Exception as e:
347 logger.error("Error [create_flavor(compute, '%s', '%s', '%s', "
348 "'%s')]: %s" % (flavor_name, ram, disk, vcpus, e))
353 def get_or_create_flavor(flavor_name, ram, disk, vcpus, public=True):
354 flavor_exists = False
355 conn = get_os_connection()
357 flavor_id = get_flavor_id(conn, flavor_name)
359 logger.info("Using existing flavor '%s'..." % flavor_name)
362 logger.info("Creating flavor '%s' with '%s' RAM, '%s' disk size, "
363 "'%s' vcpus..." % (flavor_name, ram, disk, vcpus))
364 flavor_id = create_flavor(
365 conn, flavor_name, ram, disk, vcpus, public=public)
367 raise Exception("Failed to create flavor '%s'..." % (flavor_name))
369 logger.debug("Flavor '%s' with ID=%s created successfully."
370 % (flavor_name, flavor_id))
372 return flavor_exists, flavor_id
375 def get_floating_ips(conn):
377 floating_ips = conn.network.ips()
379 except Exception as e:
380 logger.error("Error [get_floating_ips(network)]: %s" % e)
384 def get_hypervisors(conn):
387 hypervisors = conn.compute.hypervisors()
388 for hypervisor in hypervisors:
389 if hypervisor.state == "up":
390 nodes.append(hypervisor.name)
392 except Exception as e:
393 logger.error("Error [get_hypervisors(compute)]: %s" % e)
397 def create_aggregate(cloud, aggregate_name, av_zone):
399 cloud.create_aggregate(aggregate_name, av_zone)
401 except Exception as e:
402 logger.error("Error [create_aggregate(compute, %s, %s)]: %s"
403 % (aggregate_name, av_zone, e))
407 def add_host_to_aggregate(cloud, aggregate_name, compute_host):
409 aggregate_id = get_aggregate_id(cloud, aggregate_name)
410 cloud.add_host_to_aggregate(aggregate_id, compute_host)
412 except Exception as e:
413 logger.error("Error [add_host_to_aggregate(compute, %s, %s)]: %s"
414 % (aggregate_name, compute_host, e))
418 def create_aggregate_with_host(
419 cloud, aggregate_name, av_zone, compute_host):
421 create_aggregate(cloud, aggregate_name, av_zone)
422 add_host_to_aggregate(cloud, aggregate_name, compute_host)
424 except Exception as e:
425 logger.error("Error [create_aggregate_with_host("
426 "compute, %s, %s, %s)]: %s"
427 % (aggregate_name, av_zone, compute_host, e))
431 def create_instance(flavor_name,
434 instance_name="functest-vm",
440 conn = get_os_connection()
442 flavor = conn.compute.find_flavor(flavor_name, ignore_missing=False)
444 flavors = [flavor.name for flavor in conn.compute.flavors()]
445 logger.error("Error: Flavor '%s' not found. Available flavors are: "
446 "\n%s" % (flavor_name, flavors))
448 if fixed_ip is not None:
449 networks = {"uuid": network_id, "fixed_ip": fixed_ip}
451 networks = {"uuid": network_id}
454 'name': instance_name,
455 'flavor_id': flavor.id,
456 'image_id': image_id,
457 'networks': [networks],
460 if userdata is not None:
461 server_attrs['config_drive'] = confdrive
462 server_attrs['user_data'] = base64.b64encode(userdata.encode())
463 if av_zone is not None:
464 server_attrs['availability_zone'] = av_zone
466 instance = conn.compute.create_server(**server_attrs)
470 def create_instance_and_wait_for_active(flavor_name,
480 VM_BOOT_TIMEOUT = 180
481 conn = get_os_connection()
482 instance = create_instance(flavor_name,
491 count = VM_BOOT_TIMEOUT / SLEEP
492 for n in range(count, -1, -1):
493 status = get_instance_status(conn, instance)
497 elif 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(conn):
509 extnet_id = get_external_net_id(conn)
511 fip = conn.network.create_ip(floating_network_id=extnet_id)
512 fip_addr = fip.floating_ip_address
514 except Exception as e:
515 logger.error("Error [create_floating_ip(network)]: %s" % e)
517 return {'fip_addr': fip_addr, 'fip_id': fip_id}
520 def attach_floating_ip(conn, port_id):
521 extnet_id = get_external_net_id(conn)
523 return conn.network.create_ip(floating_network_id=extnet_id,
525 except Exception as e:
526 logger.error("Error [Attach_floating_ip(network), %s]: %s"
531 def add_floating_ip(conn, server_id, floatingip_addr):
533 conn.compute.add_floating_ip_to_server(server_id, floatingip_addr)
535 except Exception as e:
536 logger.error("Error [add_floating_ip(compute, '%s', '%s')]: %s"
537 % (server_id, floatingip_addr, e))
541 def delete_instance(conn, instance_id):
543 conn.compute.delete_server(instance_id, force=True)
545 except Exception as e:
546 logger.error("Error [delete_instance(compute, '%s')]: %s"
551 def delete_floating_ip(conn, floatingip_id):
553 conn.network.delete_ip(floatingip_id)
555 except Exception as e:
556 logger.error("Error [delete_floating_ip(network, '%s')]: %s"
557 % (floatingip_id, e))
561 def remove_host_from_aggregate(cloud, aggregate_name, compute_host):
563 aggregate_id = get_aggregate_id(cloud, aggregate_name)
564 cloud.remove_host_from_aggregate(aggregate_id, compute_host)
566 except Exception as e:
567 logger.error("Error [remove_host_from_aggregate(compute, %s, %s)]:"
568 " %s" % (aggregate_name, compute_host, e))
572 def remove_hosts_from_aggregate(cloud, aggregate_name):
573 aggregate_id = get_aggregate_id(cloud, aggregate_name)
574 hosts = cloud.get_aggregate(aggregate_id).hosts
576 all(remove_host_from_aggregate(cloud, aggregate_name, host)
580 def delete_aggregate(cloud, aggregate_name):
582 remove_hosts_from_aggregate(cloud, aggregate_name)
583 cloud.delete_aggregate(aggregate_name)
585 except Exception as e:
586 logger.error("Error [delete_aggregate(compute, %s)]: %s"
587 % (aggregate_name, e))
591 # *********************************************
593 # *********************************************
594 def get_network_list(conn):
595 return conn.network.networks()
598 def get_router_list(conn):
599 return conn.network.routers()
602 def get_port_list(conn):
603 return conn.network.ports()
606 def get_network_id(conn, network_name):
607 networks = conn.network.networks()
610 if n.name == network_name:
616 def get_subnet_id(conn, subnet_name):
617 subnets = conn.network.subnets()
620 if s.name == subnet_name:
626 def get_router_id(conn, router_name):
627 routers = conn.network.routers()
630 if r.name == router_name:
636 def get_private_net(conn):
637 # Checks if there is an existing shared private network
638 networks = conn.network.networks()
640 if (net.is_router_external is False) and (net.is_shared is True):
645 def get_external_net(conn):
646 if (env.get('EXTERNAL_NETWORK')):
647 return env.get('EXTERNAL_NETWORK')
648 for network in conn.network.networks():
649 if network.is_router_external:
654 def get_external_net_id(conn):
655 if (env.get('EXTERNAL_NETWORK')):
656 networks = conn.network.networks(name=env.get('EXTERNAL_NETWORK'))
657 net_id = networks.next().id
659 for network in conn.network.networks():
660 if network.is_router_external:
665 def check_neutron_net(conn, net_name):
666 for network in conn.network.networks():
667 if network.name == net_name:
668 for subnet in network.subnet_ids:
673 def create_neutron_net(conn, name):
675 network = conn.network.create_network(name=name)
677 except Exception as e:
678 logger.error("Error [create_neutron_net(network, '%s')]: %s"
683 def create_neutron_subnet(conn, name, cidr, net_id,
684 dns=['8.8.8.8', '8.8.4.4']):
686 subnet = conn.network.create_subnet(name=name,
692 except Exception as e:
693 logger.error("Error [create_neutron_subnet(network, '%s', "
694 "'%s', '%s')]: %s" % (name, cidr, net_id, e))
698 def create_neutron_router(conn, name):
700 router = conn.network.create_router(name=name)
702 except Exception as e:
703 logger.error("Error [create_neutron_router(network, '%s')]: %s"
708 def create_neutron_port(conn, name, network_id, ip):
710 port = conn.network.create_port(name=name,
711 network_id=network_id,
712 fixed_ips=[{'ip_address': ip}])
714 except Exception as e:
715 logger.error("Error [create_neutron_port(network, '%s', '%s', "
716 "'%s')]: %s" % (name, network_id, ip, e))
720 def update_neutron_net(conn, network_id, shared=False):
722 conn.network.update_network(network_id, is_shared=shared)
724 except Exception as e:
725 logger.error("Error [update_neutron_net(network, '%s', '%s')]: "
726 "%s" % (network_id, str(shared), e))
730 def update_neutron_port(conn, port_id, device_owner):
732 port = conn.network.update_port(port_id, device_owner=device_owner)
734 except Exception as e:
735 logger.error("Error [update_neutron_port(network, '%s', '%s')]:"
736 " %s" % (port_id, device_owner, e))
740 def add_interface_router(conn, router_id, subnet_id):
742 conn.network.add_interface_to_router(router_id, subnet_id=subnet_id)
744 except Exception as e:
745 logger.error("Error [add_interface_router(network, '%s', "
746 "'%s')]: %s" % (router_id, subnet_id, e))
750 def add_gateway_router(conn, router_id):
751 ext_net_id = get_external_net_id(conn)
752 router_dict = {'network_id': ext_net_id}
754 conn.network.update_router(router_id,
755 external_gateway_info=router_dict)
757 except Exception as e:
758 logger.error("Error [add_gateway_router(network, '%s')]: %s"
763 def delete_neutron_net(conn, network_id):
765 conn.network.delete_network(network_id, ignore_missing=False)
767 except Exception as e:
768 logger.error("Error [delete_neutron_net(network, '%s')]: %s"
773 def delete_neutron_subnet(conn, subnet_id):
775 conn.network.delete_subnet(subnet_id, ignore_missing=False)
777 except Exception as e:
778 logger.error("Error [delete_neutron_subnet(network, '%s')]: %s"
783 def delete_neutron_router(conn, router_id):
785 conn.network.delete_router(router_id, ignore_missing=False)
787 except Exception as e:
788 logger.error("Error [delete_neutron_router(network, '%s')]: %s"
793 def delete_neutron_port(conn, port_id):
795 conn.network.delete_port(port_id, ignore_missing=False)
797 except Exception as e:
798 logger.error("Error [delete_neutron_port(network, '%s')]: %s"
803 def remove_interface_router(conn, router_id, subnet_id):
805 conn.network.remove_interface_from_router(router_id,
808 except Exception as e:
809 logger.error("Error [remove_interface_router(network, '%s', "
810 "'%s')]: %s" % (router_id, subnet_id, e))
814 def remove_gateway_router(conn, router_id):
816 conn.network.update_router(router_id, external_gateway_info=None)
818 except Exception as e:
819 logger.error("Error [remove_gateway_router(network, '%s')]: %s"
824 def create_network_full(conn,
829 dns=['8.8.8.8', '8.8.4.4']):
831 # Check if the network already exists
832 network_id = get_network_id(conn, net_name)
833 subnet_id = get_subnet_id(conn, subnet_name)
834 router_id = get_router_id(conn, router_name)
836 if network_id != '' and subnet_id != '' and router_id != '':
837 logger.info("A network with name '%s' already exists..." % net_name)
839 logger.info('Creating neutron network %s...' % net_name)
841 network_id = create_neutron_net(conn, net_name)
844 logger.debug("Network '%s' created successfully" % network_id)
846 logger.debug('Creating Subnet....')
848 subnet_id = create_neutron_subnet(conn, subnet_name, cidr,
852 logger.debug("Subnet '%s' created successfully" % subnet_id)
854 logger.debug('Creating Router...')
856 router_id = create_neutron_router(conn, router_name)
859 logger.debug("Router '%s' created successfully" % router_id)
861 logger.debug('Adding router to subnet...')
863 if not add_interface_router(conn, router_id, subnet_id):
865 logger.debug("Interface added successfully.")
867 logger.debug('Adding gateway to router...')
868 if not add_gateway_router(conn, 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 conn = get_os_connection()
881 network_dic = create_network_full(conn,
887 if not update_neutron_net(conn,
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 # *********************************************
902 # *********************************************
905 def get_security_groups(conn):
906 return conn.network.security_groups()
909 def get_security_group_id(conn, sg_name):
910 security_groups = get_security_groups(conn)
912 for sg in security_groups:
913 if sg.name == sg_name:
919 def create_security_group(conn, sg_name, sg_description):
921 secgroup = conn.network.\
922 create_security_group(name=sg_name, description=sg_description)
924 except Exception as e:
925 logger.error("Error [create_security_group(network, '%s', "
926 "'%s')]: %s" % (sg_name, sg_description, e))
930 def create_secgroup_rule(conn, sg_id, direction, protocol,
931 port_range_min=None, port_range_max=None):
932 # We create a security group in 2 steps
933 # 1 - we check the format and set the secgroup rule attributes accordingly
934 # 2 - we call openstacksdk to create the security group
937 secgroup_rule_attrs = {'direction': direction,
938 'security_group_id': sg_id,
939 'protocol': protocol}
941 # - both None => we do nothing
942 # - both Not None => we add them to the secgroup rule attributes
943 # but one cannot be None is the other is not None
944 if (port_range_min is not None and port_range_max is not None):
945 # add port_range in secgroup rule attributes
946 secgroup_rule_attrs['port_range_min'] = port_range_min
947 secgroup_rule_attrs['port_range_max'] = port_range_max
948 logger.debug("Security_group format set (port range included)")
950 # either both port range are set to None => do nothing
951 # or one is set but not the other => log it and return False
952 if port_range_min is None and port_range_max is None:
953 logger.debug("Security_group format set (no port range mentioned)")
955 logger.error("Bad security group format."
956 "One of the port range is not properly set:"
958 "range max: {}".format(port_range_min,
962 # Create security group using neutron client
964 conn.network.create_security_group_rule(**secgroup_rule_attrs)
967 logger.exception("Impossible to create_security_group_rule,"
968 "security group rule probably already exists")
972 def get_security_group_rules(conn, sg_id):
974 security_rules = conn.network.security_group_rules()
975 security_rules = [rule for rule in security_rules
976 if rule.security_group_id == sg_id]
977 return security_rules
978 except Exception as e:
979 logger.error("Error [get_security_group_rules(network, sg_id)]:"
984 def check_security_group_rules(conn, sg_id, direction, protocol,
985 port_min=None, port_max=None):
987 security_rules = get_security_group_rules(conn, sg_id)
988 security_rules = [rule for rule in security_rules
989 if (rule.direction.lower() == direction and
990 rule.protocol.lower() == protocol and
991 rule.port_range_min == port_min and
992 rule.port_range_max == port_max)]
993 if len(security_rules) == 0:
997 except Exception as e:
998 logger.error("Error [check_security_group_rules("
999 " network, sg_id, direction,"
1000 " protocol, port_min=None, port_max=None)]: "
1005 def create_security_group_full(conn,
1006 sg_name, sg_description):
1007 sg_id = get_security_group_id(conn, sg_name)
1009 logger.info("Using existing security group '%s'..." % sg_name)
1011 logger.info("Creating security group '%s'..." % sg_name)
1012 SECGROUP = create_security_group(conn,
1016 logger.error("Failed to create the security group...")
1021 logger.debug("Security group '%s' with ID=%s created successfully."
1022 % (SECGROUP.name, sg_id))
1024 logger.debug("Adding ICMP rules in security group '%s'..."
1026 if not create_secgroup_rule(conn, sg_id,
1028 logger.error("Failed to create the security group rule...")
1031 logger.debug("Adding SSH rules in security group '%s'..."
1033 if not create_secgroup_rule(
1034 conn, sg_id, 'ingress', 'tcp', '22', '22'):
1035 logger.error("Failed to create the security group rule...")
1038 if not create_secgroup_rule(
1039 conn, sg_id, 'egress', 'tcp', '22', '22'):
1040 logger.error("Failed to create the security group rule...")
1045 def add_secgroup_to_instance(conn, instance_id, secgroup_id):
1047 conn.compute.add_security_group_to_server(instance_id, secgroup_id)
1049 except Exception as e:
1050 logger.error("Error [add_secgroup_to_instance(compute, '%s', "
1051 "'%s')]: %s" % (instance_id, secgroup_id, e))
1055 def update_sg_quota(conn, tenant_id, sg_quota, sg_rule_quota):
1057 conn.network.update_quota(tenant_id,
1058 security_group_rules=sg_rule_quota,
1059 security_groups=sg_quota)
1061 except Exception as e:
1062 logger.error("Error [update_sg_quota(network, '%s', '%s', "
1063 "'%s')]: %s" % (tenant_id, sg_quota, sg_rule_quota, e))
1067 def delete_security_group(conn, secgroup_id):
1069 conn.network.delete_security_group(secgroup_id, ignore_missing=False)
1071 except Exception as e:
1072 logger.error("Error [delete_security_group(network, '%s')]: %s"
1077 # *********************************************
1079 # *********************************************
1080 def get_images(conn):
1082 images = conn.image.images()
1084 except Exception as e:
1085 logger.error("Error [get_images]: %s" % e)
1089 def get_image_id(conn, image_name):
1090 images = conn.image.images()
1093 if i.name == image_name:
1099 def create_glance_image(conn,
1103 extra_properties={},
1106 if not os.path.isfile(file_path):
1107 logger.error("Error: file %s does not exist." % file_path)
1110 image_id = get_image_id(conn, image_name)
1112 logger.info("Image %s already exists." % image_name)
1114 logger.info("Creating image '%s' from '%s'..." % (image_name,
1116 with open(file_path) as image_data:
1117 image = conn.image.upload_image(name=image_name,
1120 container_format=container,
1125 except Exception as e:
1126 logger.error("Error [create_glance_image(image, '%s', '%s', "
1127 "'%s')]: %s" % (image_name, file_path, public, e))
1131 def get_or_create_image(name, path, format, extra_properties):
1132 image_exists = False
1133 conn = get_os_connection()
1135 image_id = get_image_id(conn, name)
1137 logger.info("Using existing image '%s'..." % name)
1140 logger.info("Creating image '%s' from '%s'..." % (name, path))
1141 image_id = create_glance_image(conn,
1147 logger.error("Failed to create a Glance image...")
1149 logger.debug("Image '%s' with ID=%s created successfully."
1152 return image_exists, image_id
1155 def delete_glance_image(conn, image_id):
1157 conn.image.delete_image(image_id)
1159 except Exception as e:
1160 logger.error("Error [delete_glance_image(image, '%s')]: %s"
1165 # *********************************************
1167 # *********************************************
1168 def get_volumes(conn):
1170 volumes = conn.block_store.volumes(all_tenants=1)
1172 except Exception as e:
1173 logger.error("Error [get_volumes(volume)]: %s" % e)
1177 def update_cinder_quota(cloud, tenant_id, vols_quota,
1178 snapshots_quota, gigabytes_quota):
1179 quotas_values = {"volumes": vols_quota,
1180 "snapshots": snapshots_quota,
1181 "gigabytes": gigabytes_quota}
1184 cloud.set_volume_quotas(tenant_id, **quotas_values)
1186 except Exception as e:
1187 logger.error("Error [update_cinder_quota(volume, '%s', '%s', "
1188 "'%s' '%s')]: %s" % (tenant_id, vols_quota,
1189 snapshots_quota, gigabytes_quota, e))
1193 def delete_volume(cloud, volume_id, forced=False):
1197 volume = cloud.get_volume(volume_id)
1198 for attachment in volume.attachments:
1199 server = cloud.get_server(attachment.server_id)
1200 cloud.detach_volume(server, volume)
1202 logger.error(sys.exc_info()[0])
1203 cloud.delete_volume(volume_id, force=True)
1205 cloud.delete_volume(volume_id)
1207 except Exception as e:
1208 logger.error("Error [delete_volume(volume, '%s', '%s')]: %s"
1209 % (volume_id, str(forced), e))
1213 # *********************************************
1215 # *********************************************
1216 def get_tenants(keystone_client):
1218 if is_keystone_v3():
1219 tenants = keystone_client.projects.list()
1221 tenants = keystone_client.tenants.list()
1223 except Exception as e:
1224 logger.error("Error [get_tenants(keystone_client)]: %s" % e)
1228 def get_users(keystone_client):
1230 users = keystone_client.users.list()
1232 except Exception as e:
1233 logger.error("Error [get_users(keystone_client)]: %s" % e)
1237 def get_tenant_id(keystone_client, tenant_name):
1238 tenants = get_tenants(keystone_client)
1241 if t.name == tenant_name:
1247 def get_user_id(keystone_client, user_name):
1248 users = get_users(keystone_client)
1251 if u.name == user_name:
1257 def get_role_id(keystone_client, role_name):
1258 roles = keystone_client.roles.list()
1261 if r.name == role_name:
1267 def get_domain_id(keystone_client, domain_name):
1268 domains = keystone_client.domains.list()
1271 if d.name == domain_name:
1277 def create_tenant(keystone_client, tenant_name, tenant_description):
1279 if is_keystone_v3():
1280 domain_name = os.environ['OS_PROJECT_DOMAIN_NAME']
1281 domain_id = get_domain_id(keystone_client, domain_name)
1282 tenant = keystone_client.projects.create(
1284 description=tenant_description,
1288 tenant = keystone_client.tenants.create(tenant_name,
1292 except Exception as e:
1293 logger.error("Error [create_tenant(keystone_client, '%s', '%s')]: %s"
1294 % (tenant_name, tenant_description, e))
1298 def get_or_create_tenant(keystone_client, tenant_name, tenant_description):
1299 tenant_id = get_tenant_id(keystone_client, tenant_name)
1301 tenant_id = create_tenant(keystone_client, tenant_name,
1307 def get_or_create_tenant_for_vnf(keystone_client, tenant_name,
1308 tenant_description):
1309 """Get or Create a Tenant
1312 keystone_client: keystone client reference
1313 tenant_name: the name of the tenant
1314 tenant_description: the description of the tenant
1316 return False if tenant retrieved though get
1317 return True if tenant created
1318 raise Exception if error during processing
1321 tenant_id = get_tenant_id(keystone_client, tenant_name)
1323 tenant_id = create_tenant(keystone_client, tenant_name,
1329 raise Exception("Impossible to create a Tenant for the VNF {}".format(
1333 def create_user(keystone_client, user_name, user_password,
1334 user_email, tenant_id):
1336 if is_keystone_v3():
1337 user = keystone_client.users.create(name=user_name,
1338 password=user_password,
1340 project_id=tenant_id,
1343 user = keystone_client.users.create(user_name,
1349 except Exception as e:
1350 logger.error("Error [create_user(keystone_client, '%s', '%s', '%s'"
1351 "'%s')]: %s" % (user_name, user_password,
1352 user_email, tenant_id, e))
1356 def get_or_create_user(keystone_client, user_name, user_password,
1357 tenant_id, user_email=None):
1358 user_id = get_user_id(keystone_client, user_name)
1360 user_id = create_user(keystone_client, user_name, user_password,
1361 user_email, tenant_id)
1365 def get_or_create_user_for_vnf(keystone_client, vnf_ref):
1366 """Get or Create user for VNF
1369 keystone_client: keystone client reference
1370 vnf_ref: VNF reference used as user name & password, tenant name
1372 return False if user retrieved through get
1373 return True if user created
1374 raise Exception if error during processing
1377 user_id = get_user_id(keystone_client, vnf_ref)
1378 tenant_id = get_tenant_id(keystone_client, vnf_ref)
1381 user_id = create_user(keystone_client, vnf_ref, vnf_ref,
1385 role_id = get_role_id(keystone_client, 'admin')
1386 tenant_id = get_tenant_id(keystone_client, vnf_ref)
1387 add_role_user(keystone_client, user_id, role_id, tenant_id)
1389 logger.warn("Cannot associate user to role admin on tenant")
1392 raise Exception("Impossible to create a user for the VNF {}".format(
1396 def add_role_user(keystone_client, user_id, role_id, tenant_id):
1398 if is_keystone_v3():
1399 keystone_client.roles.grant(role=role_id,
1403 keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
1405 except Exception as e:
1406 logger.error("Error [add_role_user(keystone_client, '%s', '%s'"
1407 "'%s')]: %s " % (user_id, role_id, tenant_id, e))
1411 def delete_tenant(keystone_client, tenant_id):
1413 if is_keystone_v3():
1414 keystone_client.projects.delete(tenant_id)
1416 keystone_client.tenants.delete(tenant_id)
1418 except Exception as e:
1419 logger.error("Error [delete_tenant(keystone_client, '%s')]: %s"
1424 def delete_user(keystone_client, user_id):
1426 keystone_client.users.delete(user_id)
1428 except Exception as e:
1429 logger.error("Error [delete_user(keystone_client, '%s')]: %s"
1434 # *********************************************
1436 # *********************************************
1437 def get_resource(heat_client, stack_id, resource):
1439 resources = heat_client.resources.get(stack_id, resource)
1441 except Exception as e:
1442 logger.error("Error [get_resource]: %s" % e)
1446 def create_stack(heat_client, **kwargs):
1448 stack = heat_client.stacks.create(**kwargs)
1449 stack_id = stack['stack']['id']
1450 if stack_id is None:
1451 logger.error("Stack create start failed")
1452 raise SystemError("Stack create start failed")
1454 except Exception as e:
1455 logger.error("Error [create_stack]: %s" % e)
1459 def delete_stack(heat_client, stack_id):
1461 heat_client.stacks.delete(stack_id)
1463 except Exception as e:
1464 logger.error("Error [delete_stack]: %s" % e)
1468 def list_stack(heat_client, **kwargs):
1470 result = heat_client.stacks.list(**kwargs)
1472 except Exception as e:
1473 logger.error("Error [list_stack]: %s" % e)
1477 def get_output(heat_client, stack_id, output_key):
1479 output = heat_client.stacks.output_show(stack_id, output_key)
1481 except Exception as e:
1482 logger.error("Error [get_output]: %s" % e)