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 insecure = os.getenv('OS_INSECURE', '').lower() == 'true'
83 cacert = False if insecure else cacert
84 return session.Session(auth=auth, verify=cacert)
87 def get_endpoint(service_type, endpoint_type='publicURL'):
88 auth = get_session_auth()
89 # for multi-region, we need to specify region
90 # when finding the endpoint
91 return get_session().get_endpoint(auth=auth,
92 service_type=service_type,
93 endpoint_type=endpoint_type,
94 region_name=os.environ.get(
98 # *********************************************
100 # *********************************************
101 def get_heat_api_version(): # pragma: no cover
103 api_version = os.environ['HEAT_API_VERSION']
105 return DEFAULT_HEAT_API_VERSION
107 log.info("HEAT_API_VERSION is set in env as '%s'", api_version)
111 def get_nova_client_version(): # pragma: no cover
113 api_version = os.environ['OS_COMPUTE_API_VERSION']
115 return DEFAULT_API_VERSION
117 log.info("OS_COMPUTE_API_VERSION is set in env as '%s'", api_version)
121 def get_nova_client(): # pragma: no cover
123 return novaclient.Client(get_nova_client_version(), session=sess)
126 def get_neutron_client_version(): # pragma: no cover
128 api_version = os.environ['OS_NETWORK_API_VERSION']
130 return DEFAULT_API_VERSION
132 log.info("OS_NETWORK_API_VERSION is set in env as '%s'", api_version)
136 def get_neutron_client(): # pragma: no cover
138 return neutronclient.Client(get_neutron_client_version(), session=sess)
141 def get_glance_client_version(): # pragma: no cover
143 api_version = os.environ['OS_IMAGE_API_VERSION']
145 return DEFAULT_API_VERSION
147 log.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
151 def get_glance_client(): # pragma: no cover
153 return glanceclient.Client(get_glance_client_version(), session=sess)
156 # *********************************************
158 # *********************************************
159 def get_instances(nova_client): # pragma: no cover
161 return nova_client.servers.list(search_opts={'all_tenants': 1})
163 log.exception("Error [get_instances(nova_client)]")
166 def get_instance_status(nova_client, instance): # pragma: no cover
168 return nova_client.servers.get(instance.id).status
170 log.exception("Error [get_instance_status(nova_client)]")
173 def get_instance_by_name(nova_client, instance_name): # pragma: no cover
175 return nova_client.servers.find(name=instance_name)
177 log.exception("Error [get_instance_by_name(nova_client, '%s')]",
181 def get_aggregates(nova_client): # pragma: no cover
183 return nova_client.aggregates.list()
185 log.exception("Error [get_aggregates(nova_client)]")
188 def get_availability_zones(nova_client): # pragma: no cover
190 return nova_client.availability_zones.list()
192 log.exception("Error [get_availability_zones(nova_client)]")
195 def get_availability_zone_names(nova_client): # pragma: no cover
197 return [az.zoneName for az in get_availability_zones(nova_client)]
199 log.exception("Error [get_availability_zone_names(nova_client)]")
202 def create_aggregate(nova_client, aggregate_name, av_zone): # pragma: no cover
204 nova_client.aggregates.create(aggregate_name, av_zone)
206 log.exception("Error [create_aggregate(nova_client, %s, %s)]",
207 aggregate_name, av_zone)
213 def get_aggregate_id(nova_client, aggregate_name): # pragma: no cover
215 aggregates = get_aggregates(nova_client)
216 _id = next((ag.id for ag in aggregates if ag.name == aggregate_name))
218 log.exception("Error [get_aggregate_id(nova_client, %s)]",
224 def add_host_to_aggregate(nova_client, aggregate_name,
225 compute_host): # pragma: no cover
227 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
228 nova_client.aggregates.add_host(aggregate_id, compute_host)
230 log.exception("Error [add_host_to_aggregate(nova_client, %s, %s)]",
231 aggregate_name, compute_host)
237 def create_aggregate_with_host(nova_client, aggregate_name, av_zone,
238 compute_host): # pragma: no cover
240 create_aggregate(nova_client, aggregate_name, av_zone)
241 add_host_to_aggregate(nova_client, aggregate_name, compute_host)
243 log.exception("Error [create_aggregate_with_host("
244 "nova_client, %s, %s, %s)]",
245 aggregate_name, av_zone, compute_host)
251 def create_instance(flavor_name,
254 instance_name="instance-vm",
259 files=None): # pragma: no cover
260 nova_client = get_nova_client()
262 flavor = nova_client.flavors.find(name=flavor_name)
264 flavors = nova_client.flavors.list()
265 log.exception("Error: Flavor '%s' not found. Available flavors are: "
266 "\n%s", flavor_name, flavors)
268 if fixed_ip is not None:
269 nics = {"net-id": network_id, "v4-fixed-ip": fixed_ip}
271 nics = {"net-id": network_id}
273 instance = nova_client.servers.create(
278 availability_zone=av_zone,
282 instance = nova_client.servers.create(
287 config_drive=confdrive,
289 availability_zone=av_zone,
295 def create_instance_and_wait_for_active(flavor_name,
298 instance_name="instance-vm",
303 files=None): # pragma: no cover
305 VM_BOOT_TIMEOUT = 180
306 nova_client = get_nova_client()
307 instance = create_instance(flavor_name,
316 count = VM_BOOT_TIMEOUT / SLEEP
317 for n in range(count, -1, -1):
318 status = get_instance_status(nova_client, instance)
319 if status.lower() == "active":
321 elif status.lower() == "error":
322 log.error("The instance %s went to ERROR status.", instance_name)
325 log.error("Timeout booting the instance %s.", instance_name)
329 def delete_instance(nova_client, instance_id): # pragma: no cover
331 nova_client.servers.force_delete(instance_id)
333 log.exception("Error [delete_instance(nova_client, '%s')]",
340 def remove_host_from_aggregate(nova_client, aggregate_name,
341 compute_host): # pragma: no cover
343 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
344 nova_client.aggregates.remove_host(aggregate_id, compute_host)
346 log.exception("Error remove_host_from_aggregate(nova_client, %s, %s)",
347 aggregate_name, compute_host)
353 def remove_hosts_from_aggregate(nova_client,
354 aggregate_name): # pragma: no cover
355 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
356 hosts = nova_client.aggregates.get(aggregate_id).hosts
358 all(remove_host_from_aggregate(nova_client, aggregate_name, host)
362 def delete_aggregate(nova_client, aggregate_name): # pragma: no cover
364 remove_hosts_from_aggregate(nova_client, aggregate_name)
365 nova_client.aggregates.delete(aggregate_name)
367 log.exception("Error [delete_aggregate(nova_client, %s)]",
374 def get_server_by_name(name): # pragma: no cover
376 return get_nova_client().servers.list(search_opts={'name': name})[0]
378 log.exception('Failed to get nova client')
382 def get_image_by_name(name): # pragma: no cover
383 images = get_nova_client().images.list()
385 return next((a for a in images if a.name == name))
386 except StopIteration:
387 log.exception('No image matched')
390 def get_flavor_by_name(name): # pragma: no cover
391 flavors = get_nova_client().flavors.list()
393 return next((a for a in flavors if a.name == name))
394 except StopIteration:
395 log.exception('No flavor matched')
398 def check_status(status, name, iterations, interval): # pragma: no cover
399 for i in range(iterations):
401 server = get_server_by_name(name)
403 log.error('Cannot found %s server', name)
406 if server.status == status:
413 # *********************************************
415 # *********************************************
416 def get_network_id(neutron_client, network_name): # pragma: no cover
417 networks = neutron_client.list_networks()['networks']
418 return next((n['id'] for n in networks if n['name'] == network_name), None)
421 def get_port_id_by_ip(neutron_client, ip_address): # pragma: no cover
422 ports = neutron_client.list_ports()['ports']
423 return next((i['id'] for i in ports for j in i.get(
424 'fixed_ips') if j['ip_address'] == ip_address), None)
427 # *********************************************
429 # *********************************************
430 def get_image_id(glance_client, image_name): # pragma: no cover
431 images = glance_client.images.list()
432 return next((i.id for i in images if i.name == image_name), None)