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 cacert = False if cacert.lower() == "false" else cacert
83 return session.Session(auth=auth, verify=cacert)
86 def get_endpoint(service_type, endpoint_type='publicURL'):
87 auth = get_session_auth()
88 return get_session().get_endpoint(auth=auth,
89 service_type=service_type,
90 endpoint_type=endpoint_type)
93 # *********************************************
95 # *********************************************
96 def get_heat_api_version(): # pragma: no cover
98 api_version = os.environ['HEAT_API_VERSION']
100 return DEFAULT_HEAT_API_VERSION
102 log.info("HEAT_API_VERSION is set in env as '%s'", api_version)
106 def get_nova_client_version(): # pragma: no cover
108 api_version = os.environ['OS_COMPUTE_API_VERSION']
110 return DEFAULT_API_VERSION
112 log.info("OS_COMPUTE_API_VERSION is set in env as '%s'", api_version)
116 def get_nova_client(): # pragma: no cover
118 return novaclient.Client(get_nova_client_version(), session=sess)
121 def get_neutron_client_version(): # pragma: no cover
123 api_version = os.environ['OS_NETWORK_API_VERSION']
125 return DEFAULT_API_VERSION
127 log.info("OS_NETWORK_API_VERSION is set in env as '%s'", api_version)
131 def get_neutron_client(): # pragma: no cover
133 return neutronclient.Client(get_neutron_client_version(), session=sess)
136 def get_glance_client_version(): # pragma: no cover
138 api_version = os.environ['OS_IMAGE_API_VERSION']
140 return DEFAULT_API_VERSION
142 log.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
146 def get_glance_client(): # pragma: no cover
148 return glanceclient.Client(get_glance_client_version(), session=sess)
151 # *********************************************
153 # *********************************************
154 def get_instances(nova_client): # pragma: no cover
156 return nova_client.servers.list(search_opts={'all_tenants': 1})
158 log.exception("Error [get_instances(nova_client)]")
161 def get_instance_status(nova_client, instance): # pragma: no cover
163 return nova_client.servers.get(instance.id).status
165 log.exception("Error [get_instance_status(nova_client)]")
168 def get_instance_by_name(nova_client, instance_name): # pragma: no cover
170 return nova_client.servers.find(name=instance_name)
172 log.exception("Error [get_instance_by_name(nova_client, '%s')]",
176 def get_aggregates(nova_client): # pragma: no cover
178 return nova_client.aggregates.list()
180 log.exception("Error [get_aggregates(nova_client)]")
183 def get_availability_zones(nova_client): # pragma: no cover
185 return nova_client.availability_zones.list()
187 log.exception("Error [get_availability_zones(nova_client)]")
190 def get_availability_zone_names(nova_client): # pragma: no cover
192 return [az.zoneName for az in get_availability_zones(nova_client)]
194 log.exception("Error [get_availability_zone_names(nova_client)]")
197 def create_aggregate(nova_client, aggregate_name, av_zone): # pragma: no cover
199 nova_client.aggregates.create(aggregate_name, av_zone)
201 log.exception("Error [create_aggregate(nova_client, %s, %s)]",
202 aggregate_name, av_zone)
208 def get_aggregate_id(nova_client, aggregate_name): # pragma: no cover
210 aggregates = get_aggregates(nova_client)
211 _id = next((ag.id for ag in aggregates if ag.name == aggregate_name))
213 log.exception("Error [get_aggregate_id(nova_client, %s)]",
219 def add_host_to_aggregate(nova_client, aggregate_name,
220 compute_host): # pragma: no cover
222 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
223 nova_client.aggregates.add_host(aggregate_id, compute_host)
225 log.exception("Error [add_host_to_aggregate(nova_client, %s, %s)]",
226 aggregate_name, compute_host)
232 def create_aggregate_with_host(nova_client, aggregate_name, av_zone,
233 compute_host): # pragma: no cover
235 create_aggregate(nova_client, aggregate_name, av_zone)
236 add_host_to_aggregate(nova_client, aggregate_name, compute_host)
238 log.exception("Error [create_aggregate_with_host("
239 "nova_client, %s, %s, %s)]",
240 aggregate_name, av_zone, compute_host)
246 def create_instance(flavor_name,
249 instance_name="instance-vm",
254 files=None): # pragma: no cover
255 nova_client = get_nova_client()
257 flavor = nova_client.flavors.find(name=flavor_name)
259 flavors = nova_client.flavors.list()
260 log.exception("Error: Flavor '%s' not found. Available flavors are: "
261 "\n%s", flavor_name, flavors)
263 if fixed_ip is not None:
264 nics = {"net-id": network_id, "v4-fixed-ip": fixed_ip}
266 nics = {"net-id": network_id}
268 instance = nova_client.servers.create(
273 availability_zone=av_zone,
277 instance = nova_client.servers.create(
282 config_drive=confdrive,
284 availability_zone=av_zone,
290 def create_instance_and_wait_for_active(flavor_name,
293 instance_name="instance-vm",
298 files=None): # pragma: no cover
300 VM_BOOT_TIMEOUT = 180
301 nova_client = get_nova_client()
302 instance = create_instance(flavor_name,
311 count = VM_BOOT_TIMEOUT / SLEEP
312 for n in range(count, -1, -1):
313 status = get_instance_status(nova_client, instance)
314 if status.lower() == "active":
316 elif status.lower() == "error":
317 log.error("The instance %s went to ERROR status.", instance_name)
320 log.error("Timeout booting the instance %s.", instance_name)
324 def delete_instance(nova_client, instance_id): # pragma: no cover
326 nova_client.servers.force_delete(instance_id)
328 log.exception("Error [delete_instance(nova_client, '%s')]",
335 def remove_host_from_aggregate(nova_client, aggregate_name,
336 compute_host): # pragma: no cover
338 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
339 nova_client.aggregates.remove_host(aggregate_id, compute_host)
341 log.exception("Error remove_host_from_aggregate(nova_client, %s, %s)",
342 aggregate_name, compute_host)
348 def remove_hosts_from_aggregate(nova_client,
349 aggregate_name): # pragma: no cover
350 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
351 hosts = nova_client.aggregates.get(aggregate_id).hosts
353 all(remove_host_from_aggregate(nova_client, aggregate_name, host)
357 def delete_aggregate(nova_client, aggregate_name): # pragma: no cover
359 remove_hosts_from_aggregate(nova_client, aggregate_name)
360 nova_client.aggregates.delete(aggregate_name)
362 log.exception("Error [delete_aggregate(nova_client, %s)]",
369 def get_server_by_name(name): # pragma: no cover
371 return get_nova_client().servers.list(search_opts={'name': name})[0]
373 log.exception('Failed to get nova client')
377 def get_image_by_name(name): # pragma: no cover
378 images = get_nova_client().images.list()
380 return next((a for a in images if a.name == name))
381 except StopIteration:
382 log.exception('No image matched')
385 def get_flavor_by_name(name): # pragma: no cover
386 flavors = get_nova_client().flavors.list()
388 return next((a for a in flavors if a.name == name))
389 except StopIteration:
390 log.exception('No flavor matched')
393 def check_status(status, name, iterations, interval): # pragma: no cover
394 for i in range(iterations):
396 server = get_server_by_name(name)
398 log.error('Cannot found %s server', name)
401 if server.status == status:
408 # *********************************************
410 # *********************************************
411 def get_network_id(neutron_client, network_name): # pragma: no cover
412 networks = neutron_client.list_networks()['networks']
413 return next((n['id'] for n in networks if n['name'] == network_name), None)
416 def get_port_id_by_ip(neutron_client, ip_address): # pragma: no cover
417 ports = neutron_client.list_ports()['ports']
418 return next((i['id'] for i in ports for j in i.get(
419 'fixed_ips') if j['ip_address'] == ip_address), None)
422 # *********************************************
424 # *********************************************
425 def get_image_id(glance_client, image_name): # pragma: no cover
426 images = glance_client.images.list()
427 return next((i.id for i in images if i.name == image_name), None)