1 ##############################################################################
2 # Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
10 from __future__ import absolute_import
16 from keystoneauth1 import loading
17 from keystoneauth1 import session
18 from novaclient import client as novaclient
19 from glanceclient import client as glanceclient
20 from neutronclient.neutron import client as neutronclient
22 log = logging.getLogger(__name__)
24 DEFAULT_HEAT_API_VERSION = '1'
25 DEFAULT_API_VERSION = '2'
28 # *********************************************
30 # *********************************************
31 def get_credentials():
32 """Returns a creds dictionary filled with parsed from env"""
35 keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
37 if keystone_api_version is None or keystone_api_version == '2':
39 tenant_env = 'OS_TENANT_NAME'
40 tenant = 'tenant_name'
43 tenant_env = 'OS_PROJECT_NAME'
44 tenant = 'project_name'
46 # The most common way to pass these info to the script is to do it
47 # through environment variables.
49 "username": os.environ.get("OS_USERNAME"),
50 "password": os.environ.get("OS_PASSWORD"),
51 "auth_url": os.environ.get("OS_AUTH_URL"),
52 tenant: os.environ.get(tenant_env)
56 if os.getenv('OS_USER_DOMAIN_NAME') is not None:
58 "user_domain_name": os.getenv('OS_USER_DOMAIN_NAME')
60 if os.getenv('OS_PROJECT_DOMAIN_NAME') is not None:
62 "project_domain_name": os.getenv('OS_PROJECT_DOMAIN_NAME')
68 def get_session_auth():
69 loader = loading.get_plugin_loader('password')
70 creds = get_credentials()
71 auth = loader.load_from_options(**creds)
76 auth = get_session_auth()
78 cacert = os.environ['OS_CACERT']
80 return session.Session(auth=auth)
82 return session.Session(auth=auth, verify=cacert)
85 def get_endpoint(service_type, endpoint_type='publicURL'):
86 auth = get_session_auth()
87 return get_session().get_endpoint(auth=auth,
88 service_type=service_type,
89 endpoint_type=endpoint_type)
92 # *********************************************
94 # *********************************************
95 def get_heat_api_version(): # pragma: no cover
97 api_version = os.environ['HEAT_API_VERSION']
99 return DEFAULT_HEAT_API_VERSION
101 log.info("HEAT_API_VERSION is set in env as '%s'", api_version)
105 def get_nova_client_version(): # pragma: no cover
107 api_version = os.environ['OS_COMPUTE_API_VERSION']
109 return DEFAULT_API_VERSION
111 log.info("OS_COMPUTE_API_VERSION is set in env as '%s'", api_version)
115 def get_nova_client(): # pragma: no cover
117 return novaclient.Client(get_nova_client_version(), session=sess)
120 def get_neutron_client_version(): # pragma: no cover
122 api_version = os.environ['OS_NETWORK_API_VERSION']
124 return DEFAULT_API_VERSION
126 log.info("OS_NETWORK_API_VERSION is set in env as '%s'", api_version)
130 def get_neutron_client(): # pragma: no cover
132 return neutronclient.Client(get_neutron_client_version(), session=sess)
135 def get_glance_client_version(): # pragma: no cover
137 api_version = os.environ['OS_IMAGE_API_VERSION']
139 return DEFAULT_API_VERSION
141 log.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
145 def get_glance_client(): # pragma: no cover
147 return glanceclient.Client(get_glance_client_version(), session=sess)
150 # *********************************************
152 # *********************************************
153 def get_instances(nova_client): # pragma: no cover
155 return nova_client.servers.list(search_opts={'all_tenants': 1})
157 log.exception("Error [get_instances(nova_client)]")
160 def get_instance_status(nova_client, instance): # pragma: no cover
162 return nova_client.servers.get(instance.id).status
164 log.exception("Error [get_instance_status(nova_client)]")
167 def get_instance_by_name(nova_client, instance_name): # pragma: no cover
169 return nova_client.servers.find(name=instance_name)
171 log.exception("Error [get_instance_by_name(nova_client, '%s')]",
175 def get_aggregates(nova_client): # pragma: no cover
177 return nova_client.aggregates.list()
179 log.exception("Error [get_aggregates(nova_client)]")
182 def get_availability_zones(nova_client): # pragma: no cover
184 return nova_client.availability_zones.list()
186 log.exception("Error [get_availability_zones(nova_client)]")
189 def get_availability_zone_names(nova_client): # pragma: no cover
191 return [az.zoneName for az in get_availability_zones(nova_client)]
193 log.exception("Error [get_availability_zone_names(nova_client)]")
196 def create_aggregate(nova_client, aggregate_name, av_zone): # pragma: no cover
198 nova_client.aggregates.create(aggregate_name, av_zone)
200 log.exception("Error [create_aggregate(nova_client, %s, %s)]",
201 aggregate_name, av_zone)
207 def get_aggregate_id(nova_client, aggregate_name): # pragma: no cover
209 aggregates = get_aggregates(nova_client)
210 _id = next((ag.id for ag in aggregates if ag.name == aggregate_name))
212 log.exception("Error [get_aggregate_id(nova_client, %s)]",
218 def add_host_to_aggregate(nova_client, aggregate_name,
219 compute_host): # pragma: no cover
221 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
222 nova_client.aggregates.add_host(aggregate_id, compute_host)
224 log.exception("Error [add_host_to_aggregate(nova_client, %s, %s)]",
225 aggregate_name, compute_host)
231 def create_aggregate_with_host(nova_client, aggregate_name, av_zone,
232 compute_host): # pragma: no cover
234 create_aggregate(nova_client, aggregate_name, av_zone)
235 add_host_to_aggregate(nova_client, aggregate_name, compute_host)
237 log.exception("Error [create_aggregate_with_host("
238 "nova_client, %s, %s, %s)]",
239 aggregate_name, av_zone, compute_host)
245 def create_instance(flavor_name,
248 instance_name="instance-vm",
253 files=None): # pragma: no cover
254 nova_client = get_nova_client()
256 flavor = nova_client.flavors.find(name=flavor_name)
258 flavors = nova_client.flavors.list()
259 log.exception("Error: Flavor '%s' not found. Available flavors are: "
260 "\n%s", flavor_name, flavors)
262 if fixed_ip is not None:
263 nics = {"net-id": network_id, "v4-fixed-ip": fixed_ip}
265 nics = {"net-id": network_id}
267 instance = nova_client.servers.create(
272 availability_zone=av_zone,
276 instance = nova_client.servers.create(
281 config_drive=confdrive,
283 availability_zone=av_zone,
289 def create_instance_and_wait_for_active(flavor_name,
292 instance_name="instance-vm",
297 files=None): # pragma: no cover
299 VM_BOOT_TIMEOUT = 180
300 nova_client = get_nova_client()
301 instance = create_instance(flavor_name,
310 count = VM_BOOT_TIMEOUT / SLEEP
311 for n in range(count, -1, -1):
312 status = get_instance_status(nova_client, instance)
313 if status.lower() == "active":
315 elif status.lower() == "error":
316 log.error("The instance %s went to ERROR status.", instance_name)
319 log.error("Timeout booting the instance %s.", instance_name)
323 def delete_instance(nova_client, instance_id): # pragma: no cover
325 nova_client.servers.force_delete(instance_id)
327 log.exception("Error [delete_instance(nova_client, '%s')]",
334 def remove_host_from_aggregate(nova_client, aggregate_name,
335 compute_host): # pragma: no cover
337 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
338 nova_client.aggregates.remove_host(aggregate_id, compute_host)
340 log.exception("Error remove_host_from_aggregate(nova_client, %s, %s)",
341 aggregate_name, compute_host)
347 def remove_hosts_from_aggregate(nova_client,
348 aggregate_name): # pragma: no cover
349 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
350 hosts = nova_client.aggregates.get(aggregate_id).hosts
352 all(remove_host_from_aggregate(nova_client, aggregate_name, host)
356 def delete_aggregate(nova_client, aggregate_name): # pragma: no cover
358 remove_hosts_from_aggregate(nova_client, aggregate_name)
359 nova_client.aggregates.delete(aggregate_name)
361 log.exception("Error [delete_aggregate(nova_client, %s)]",
368 def get_server_by_name(name): # pragma: no cover
370 return get_nova_client().servers.list(search_opts={'name': name})[0]
372 log.exception('Failed to get nova client')
376 def get_image_by_name(name): # pragma: no cover
377 images = get_nova_client().images.list()
379 return next((a for a in images if a.name == name))
380 except StopIteration:
381 log.exception('No image matched')
384 def get_flavor_by_name(name): # pragma: no cover
385 flavors = get_nova_client().flavors.list()
387 return next((a for a in flavors if a.name == name))
388 except StopIteration:
389 log.exception('No flavor matched')
392 def check_status(status, name, iterations, interval): # pragma: no cover
393 for i in range(iterations):
395 server = get_server_by_name(name)
397 log.error('Cannot found %s server', name)
400 if server.status == status:
407 # *********************************************
409 # *********************************************
410 def get_network_id(neutron_client, network_name): # pragma: no cover
411 networks = neutron_client.list_networks()['networks']
412 return next((n['id'] for n in networks if n['name'] == network_name), None)
415 def get_port_id_by_ip(neutron_client, ip_address): # pragma: no cover
416 ports = neutron_client.list_ports()['ports']
417 return next((i['id'] for i in ports for j in i.get(
418 'fixed_ips') if j['ip_address'] == ip_address), None)
421 # *********************************************
423 # *********************************************
424 def get_image_id(glance_client, image_name): # pragma: no cover
425 images = glance_client.images.list()
426 return next((i.id for i in images if i.name == image_name), None)