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 # for multi-region, we need to specify region
89 # when finding the endpoint
90 return get_session().get_endpoint(auth=auth,
91 service_type=service_type,
92 endpoint_type=endpoint_type,
93 region_name=os.environ.get(
97 # *********************************************
99 # *********************************************
100 def get_heat_api_version(): # pragma: no cover
102 api_version = os.environ['HEAT_API_VERSION']
104 return DEFAULT_HEAT_API_VERSION
106 log.info("HEAT_API_VERSION is set in env as '%s'", api_version)
110 def get_nova_client_version(): # pragma: no cover
112 api_version = os.environ['OS_COMPUTE_API_VERSION']
114 return DEFAULT_API_VERSION
116 log.info("OS_COMPUTE_API_VERSION is set in env as '%s'", api_version)
120 def get_nova_client(): # pragma: no cover
122 return novaclient.Client(get_nova_client_version(), session=sess)
125 def get_neutron_client_version(): # pragma: no cover
127 api_version = os.environ['OS_NETWORK_API_VERSION']
129 return DEFAULT_API_VERSION
131 log.info("OS_NETWORK_API_VERSION is set in env as '%s'", api_version)
135 def get_neutron_client(): # pragma: no cover
137 return neutronclient.Client(get_neutron_client_version(), session=sess)
140 def get_glance_client_version(): # pragma: no cover
142 api_version = os.environ['OS_IMAGE_API_VERSION']
144 return DEFAULT_API_VERSION
146 log.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
150 def get_glance_client(): # pragma: no cover
152 return glanceclient.Client(get_glance_client_version(), session=sess)
155 # *********************************************
157 # *********************************************
158 def get_instances(nova_client): # pragma: no cover
160 return nova_client.servers.list(search_opts={'all_tenants': 1})
162 log.exception("Error [get_instances(nova_client)]")
165 def get_instance_status(nova_client, instance): # pragma: no cover
167 return nova_client.servers.get(instance.id).status
169 log.exception("Error [get_instance_status(nova_client)]")
172 def get_instance_by_name(nova_client, instance_name): # pragma: no cover
174 return nova_client.servers.find(name=instance_name)
176 log.exception("Error [get_instance_by_name(nova_client, '%s')]",
180 def get_aggregates(nova_client): # pragma: no cover
182 return nova_client.aggregates.list()
184 log.exception("Error [get_aggregates(nova_client)]")
187 def get_availability_zones(nova_client): # pragma: no cover
189 return nova_client.availability_zones.list()
191 log.exception("Error [get_availability_zones(nova_client)]")
194 def get_availability_zone_names(nova_client): # pragma: no cover
196 return [az.zoneName for az in get_availability_zones(nova_client)]
198 log.exception("Error [get_availability_zone_names(nova_client)]")
201 def create_aggregate(nova_client, aggregate_name, av_zone): # pragma: no cover
203 nova_client.aggregates.create(aggregate_name, av_zone)
205 log.exception("Error [create_aggregate(nova_client, %s, %s)]",
206 aggregate_name, av_zone)
212 def get_aggregate_id(nova_client, aggregate_name): # pragma: no cover
214 aggregates = get_aggregates(nova_client)
215 _id = next((ag.id for ag in aggregates if ag.name == aggregate_name))
217 log.exception("Error [get_aggregate_id(nova_client, %s)]",
223 def add_host_to_aggregate(nova_client, aggregate_name,
224 compute_host): # pragma: no cover
226 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
227 nova_client.aggregates.add_host(aggregate_id, compute_host)
229 log.exception("Error [add_host_to_aggregate(nova_client, %s, %s)]",
230 aggregate_name, compute_host)
236 def create_aggregate_with_host(nova_client, aggregate_name, av_zone,
237 compute_host): # pragma: no cover
239 create_aggregate(nova_client, aggregate_name, av_zone)
240 add_host_to_aggregate(nova_client, aggregate_name, compute_host)
242 log.exception("Error [create_aggregate_with_host("
243 "nova_client, %s, %s, %s)]",
244 aggregate_name, av_zone, compute_host)
250 def create_instance(flavor_name,
253 instance_name="instance-vm",
258 files=None): # pragma: no cover
259 nova_client = get_nova_client()
261 flavor = nova_client.flavors.find(name=flavor_name)
263 flavors = nova_client.flavors.list()
264 log.exception("Error: Flavor '%s' not found. Available flavors are: "
265 "\n%s", flavor_name, flavors)
267 if fixed_ip is not None:
268 nics = {"net-id": network_id, "v4-fixed-ip": fixed_ip}
270 nics = {"net-id": network_id}
272 instance = nova_client.servers.create(
277 availability_zone=av_zone,
281 instance = nova_client.servers.create(
286 config_drive=confdrive,
288 availability_zone=av_zone,
294 def create_instance_and_wait_for_active(flavor_name,
297 instance_name="instance-vm",
302 files=None): # pragma: no cover
304 VM_BOOT_TIMEOUT = 180
305 nova_client = get_nova_client()
306 instance = create_instance(flavor_name,
315 count = VM_BOOT_TIMEOUT / SLEEP
316 for n in range(count, -1, -1):
317 status = get_instance_status(nova_client, instance)
318 if status.lower() == "active":
320 elif status.lower() == "error":
321 log.error("The instance %s went to ERROR status.", instance_name)
324 log.error("Timeout booting the instance %s.", instance_name)
328 def delete_instance(nova_client, instance_id): # pragma: no cover
330 nova_client.servers.force_delete(instance_id)
332 log.exception("Error [delete_instance(nova_client, '%s')]",
339 def remove_host_from_aggregate(nova_client, aggregate_name,
340 compute_host): # pragma: no cover
342 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
343 nova_client.aggregates.remove_host(aggregate_id, compute_host)
345 log.exception("Error remove_host_from_aggregate(nova_client, %s, %s)",
346 aggregate_name, compute_host)
352 def remove_hosts_from_aggregate(nova_client,
353 aggregate_name): # pragma: no cover
354 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
355 hosts = nova_client.aggregates.get(aggregate_id).hosts
357 all(remove_host_from_aggregate(nova_client, aggregate_name, host)
361 def delete_aggregate(nova_client, aggregate_name): # pragma: no cover
363 remove_hosts_from_aggregate(nova_client, aggregate_name)
364 nova_client.aggregates.delete(aggregate_name)
366 log.exception("Error [delete_aggregate(nova_client, %s)]",
373 def get_server_by_name(name): # pragma: no cover
375 return get_nova_client().servers.list(search_opts={'name': name})[0]
377 log.exception('Failed to get nova client')
381 def get_image_by_name(name): # pragma: no cover
382 images = get_nova_client().images.list()
384 return next((a for a in images if a.name == name))
385 except StopIteration:
386 log.exception('No image matched')
389 def get_flavor_by_name(name): # pragma: no cover
390 flavors = get_nova_client().flavors.list()
392 return next((a for a in flavors if a.name == name))
393 except StopIteration:
394 log.exception('No flavor matched')
397 def check_status(status, name, iterations, interval): # pragma: no cover
398 for i in range(iterations):
400 server = get_server_by_name(name)
402 log.error('Cannot found %s server', name)
405 if server.status == status:
412 # *********************************************
414 # *********************************************
415 def get_network_id(neutron_client, network_name): # pragma: no cover
416 networks = neutron_client.list_networks()['networks']
417 return next((n['id'] for n in networks if n['name'] == network_name), None)
420 def get_port_id_by_ip(neutron_client, ip_address): # pragma: no cover
421 ports = neutron_client.list_ports()['ports']
422 return next((i['id'] for i in ports for j in i.get(
423 'fixed_ips') if j['ip_address'] == ip_address), None)
426 # *********************************************
428 # *********************************************
429 def get_image_id(glance_client, image_name): # pragma: no cover
430 images = glance_client.images.list()
431 return next((i.id for i in images if i.name == image_name), None)