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')
65 cacert = os.environ.get("OS_CACERT")
67 if cacert is not None:
68 # each openstack client uses differnt kwargs for this
69 creds.update({"cacert": cacert,
71 "https_ca_cert": cacert,
72 "https_cacert": cacert,
74 creds.update({"insecure": "True", "https_insecure": "True"})
75 if not os.path.isfile(cacert):
76 log.info("WARNING: The 'OS_CACERT' environment variable is set \
77 to %s but the file does not exist.", cacert)
82 def get_session_auth():
83 loader = loading.get_plugin_loader('password')
84 creds = get_credentials()
85 auth = loader.load_from_options(**creds)
90 auth = get_session_auth()
91 return session.Session(auth=auth)
94 def get_endpoint(service_type, endpoint_type='publicURL'):
95 auth = get_session_auth()
96 return get_session().get_endpoint(auth=auth,
97 service_type=service_type,
98 endpoint_type=endpoint_type)
101 # *********************************************
103 # *********************************************
104 def get_heat_api_version(): # pragma: no cover
106 api_version = os.environ['HEAT_API_VERSION']
108 return DEFAULT_HEAT_API_VERSION
110 log.info("HEAT_API_VERSION is set in env as '%s'", api_version)
114 def get_nova_client_version(): # pragma: no cover
116 api_version = os.environ['OS_COMPUTE_API_VERSION']
118 return DEFAULT_API_VERSION
120 log.info("OS_COMPUTE_API_VERSION is set in env as '%s'", api_version)
124 def get_nova_client(): # pragma: no cover
126 return novaclient.Client(get_nova_client_version(), session=sess)
129 def get_neutron_client_version(): # pragma: no cover
131 api_version = os.environ['OS_NETWORK_API_VERSION']
133 return DEFAULT_API_VERSION
135 log.info("OS_NETWORK_API_VERSION is set in env as '%s'", api_version)
139 def get_neutron_client(): # pragma: no cover
141 return neutronclient.Client(get_neutron_client_version(), session=sess)
144 def get_glance_client_version(): # pragma: no cover
146 api_version = os.environ['OS_IMAGE_API_VERSION']
148 return DEFAULT_API_VERSION
150 log.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
154 def get_glance_client(): # pragma: no cover
156 return glanceclient.Client(get_glance_client_version(), session=sess)
159 # *********************************************
161 # *********************************************
162 def get_instances(nova_client): # pragma: no cover
164 return nova_client.servers.list(search_opts={'all_tenants': 1})
166 log.exception("Error [get_instances(nova_client)]")
169 def get_instance_status(nova_client, instance): # pragma: no cover
171 return nova_client.servers.get(instance.id).status
173 log.exception("Error [get_instance_status(nova_client)]")
176 def get_instance_by_name(nova_client, instance_name): # pragma: no cover
178 return nova_client.servers.find(name=instance_name)
180 log.exception("Error [get_instance_by_name(nova_client, '%s')]",
184 def get_aggregates(nova_client): # pragma: no cover
186 return nova_client.aggregates.list()
188 log.exception("Error [get_aggregates(nova_client)]")
191 def get_availability_zones(nova_client): # pragma: no cover
193 return nova_client.availability_zones.list()
195 log.exception("Error [get_availability_zones(nova_client)]")
198 def get_availability_zone_names(nova_client): # pragma: no cover
200 return [az.zoneName for az in get_availability_zones(nova_client)]
202 log.exception("Error [get_availability_zone_names(nova_client)]")
205 def create_aggregate(nova_client, aggregate_name, av_zone): # pragma: no cover
207 nova_client.aggregates.create(aggregate_name, av_zone)
209 log.exception("Error [create_aggregate(nova_client, %s, %s)]",
210 aggregate_name, av_zone)
216 def get_aggregate_id(nova_client, aggregate_name): # pragma: no cover
218 aggregates = get_aggregates(nova_client)
219 _id = next((ag.id for ag in aggregates if ag.name == aggregate_name))
221 log.exception("Error [get_aggregate_id(nova_client, %s)]",
227 def add_host_to_aggregate(nova_client, aggregate_name,
228 compute_host): # pragma: no cover
230 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
231 nova_client.aggregates.add_host(aggregate_id, compute_host)
233 log.exception("Error [add_host_to_aggregate(nova_client, %s, %s)]",
234 aggregate_name, compute_host)
240 def create_aggregate_with_host(nova_client, aggregate_name, av_zone,
241 compute_host): # pragma: no cover
243 create_aggregate(nova_client, aggregate_name, av_zone)
244 add_host_to_aggregate(nova_client, aggregate_name, compute_host)
246 log.exception("Error [create_aggregate_with_host("
247 "nova_client, %s, %s, %s)]",
248 aggregate_name, av_zone, compute_host)
254 def create_instance(flavor_name,
257 instance_name="instance-vm",
262 files=None): # pragma: no cover
263 nova_client = get_nova_client()
265 flavor = nova_client.flavors.find(name=flavor_name)
267 flavors = nova_client.flavors.list()
268 log.exception("Error: Flavor '%s' not found. Available flavors are: "
269 "\n%s", flavor_name, flavors)
271 if fixed_ip is not None:
272 nics = {"net-id": network_id, "v4-fixed-ip": fixed_ip}
274 nics = {"net-id": network_id}
276 instance = nova_client.servers.create(
281 availability_zone=av_zone,
285 instance = nova_client.servers.create(
290 config_drive=confdrive,
292 availability_zone=av_zone,
298 def create_instance_and_wait_for_active(flavor_name,
301 instance_name="instance-vm",
306 files=None): # pragma: no cover
308 VM_BOOT_TIMEOUT = 180
309 nova_client = get_nova_client()
310 instance = create_instance(flavor_name,
319 count = VM_BOOT_TIMEOUT / SLEEP
320 for n in range(count, -1, -1):
321 status = get_instance_status(nova_client, instance)
322 if status.lower() == "active":
324 elif status.lower() == "error":
325 log.error("The instance %s went to ERROR status.", instance_name)
328 log.error("Timeout booting the instance %s.", instance_name)
332 def delete_instance(nova_client, instance_id): # pragma: no cover
334 nova_client.servers.force_delete(instance_id)
336 log.exception("Error [delete_instance(nova_client, '%s')]",
343 def remove_host_from_aggregate(nova_client, aggregate_name,
344 compute_host): # pragma: no cover
346 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
347 nova_client.aggregates.remove_host(aggregate_id, compute_host)
349 log.exception("Error remove_host_from_aggregate(nova_client, %s, %s)",
350 aggregate_name, compute_host)
356 def remove_hosts_from_aggregate(nova_client,
357 aggregate_name): # pragma: no cover
358 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
359 hosts = nova_client.aggregates.get(aggregate_id).hosts
361 all(remove_host_from_aggregate(nova_client, aggregate_name, host)
365 def delete_aggregate(nova_client, aggregate_name): # pragma: no cover
367 remove_hosts_from_aggregate(nova_client, aggregate_name)
368 nova_client.aggregates.delete(aggregate_name)
370 log.exception("Error [delete_aggregate(nova_client, %s)]",
377 def get_server_by_name(name): # pragma: no cover
379 return get_nova_client().servers.list(search_opts={'name': name})[0]
381 log.exception('Failed to get nova client')
385 def get_image_by_name(name): # pragma: no cover
386 images = get_nova_client().images.list()
388 return next((a for a in images if a.name == name))
389 except StopIteration:
390 log.exception('No image matched')
393 def get_flavor_by_name(name): # pragma: no cover
394 flavors = get_nova_client().flavors.list()
396 return next((a for a in flavors if a.name == name))
397 except StopIteration:
398 log.exception('No flavor matched')
401 def check_status(status, name, iterations, interval): # pragma: no cover
402 for i in range(iterations):
404 server = get_server_by_name(name)
406 log.error('Cannot found %s server', name)
409 if server.status == status:
416 # *********************************************
418 # *********************************************
419 def get_network_id(neutron_client, network_name): # pragma: no cover
420 networks = neutron_client.list_networks()['networks']
421 return next((n['id'] for n in networks if n['name'] == network_name), None)
424 def get_port_id_by_ip(neutron_client, ip_address): # pragma: no cover
425 ports = neutron_client.list_ports()['ports']
426 return next((i['id'] for i in ports for j in i.get(
427 'fixed_ips') if j['ip_address'] == ip_address), None)
430 # *********************************************
432 # *********************************************
433 def get_image_id(glance_client, image_name): # pragma: no cover
434 images = glance_client.images.list()
435 return next((i.id for i in images if i.name == image_name), None)