Merge "Store packetsize in influxdb"
[yardstick.git] / yardstick / common / openstack_utils.py
1 ##############################################################################
2 # Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
3 #
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 ##############################################################################
9
10 from __future__ import absolute_import
11
12 import os
13 import time
14 import logging
15
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
21
22 log = logging.getLogger(__name__)
23
24 DEFAULT_HEAT_API_VERSION = '1'
25 DEFAULT_API_VERSION = '2'
26
27
28 # *********************************************
29 #   CREDENTIALS
30 # *********************************************
31 def get_credentials():
32     """Returns a creds dictionary filled with parsed from env"""
33     creds = {}
34
35     keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
36
37     if keystone_api_version is None or keystone_api_version == '2':
38         keystone_v3 = False
39         tenant_env = 'OS_TENANT_NAME'
40         tenant = 'tenant_name'
41     else:
42         keystone_v3 = True
43         tenant_env = 'OS_PROJECT_NAME'
44         tenant = 'project_name'
45
46     # The most common way to pass these info to the script is to do it
47     # through environment variables.
48     creds.update({
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)
53     })
54
55     if keystone_v3:
56         if os.getenv('OS_USER_DOMAIN_NAME') is not None:
57             creds.update({
58                 "user_domain_name": os.getenv('OS_USER_DOMAIN_NAME')
59             })
60         if os.getenv('OS_PROJECT_DOMAIN_NAME') is not None:
61             creds.update({
62                 "project_domain_name": os.getenv('OS_PROJECT_DOMAIN_NAME')
63             })
64
65     return creds
66
67
68 def get_session_auth():
69     loader = loading.get_plugin_loader('password')
70     creds = get_credentials()
71     auth = loader.load_from_options(**creds)
72     return auth
73
74
75 def get_session():
76     auth = get_session_auth()
77     try:
78         cacert = os.environ['OS_CACERT']
79     except KeyError:
80         return session.Session(auth=auth)
81     else:
82         cacert = False if cacert.lower() == "false" else cacert
83         return session.Session(auth=auth, verify=cacert)
84
85
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)
91
92
93 # *********************************************
94 #   CLIENTS
95 # *********************************************
96 def get_heat_api_version():     # pragma: no cover
97     try:
98         api_version = os.environ['HEAT_API_VERSION']
99     except KeyError:
100         return DEFAULT_HEAT_API_VERSION
101     else:
102         log.info("HEAT_API_VERSION is set in env as '%s'", api_version)
103         return api_version
104
105
106 def get_nova_client_version():      # pragma: no cover
107     try:
108         api_version = os.environ['OS_COMPUTE_API_VERSION']
109     except KeyError:
110         return DEFAULT_API_VERSION
111     else:
112         log.info("OS_COMPUTE_API_VERSION is set in env as '%s'", api_version)
113         return api_version
114
115
116 def get_nova_client():      # pragma: no cover
117     sess = get_session()
118     return novaclient.Client(get_nova_client_version(), session=sess)
119
120
121 def get_neutron_client_version():   # pragma: no cover
122     try:
123         api_version = os.environ['OS_NETWORK_API_VERSION']
124     except KeyError:
125         return DEFAULT_API_VERSION
126     else:
127         log.info("OS_NETWORK_API_VERSION is set in env as '%s'", api_version)
128         return api_version
129
130
131 def get_neutron_client():   # pragma: no cover
132     sess = get_session()
133     return neutronclient.Client(get_neutron_client_version(), session=sess)
134
135
136 def get_glance_client_version():    # pragma: no cover
137     try:
138         api_version = os.environ['OS_IMAGE_API_VERSION']
139     except KeyError:
140         return DEFAULT_API_VERSION
141     else:
142         log.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
143         return api_version
144
145
146 def get_glance_client():    # pragma: no cover
147     sess = get_session()
148     return glanceclient.Client(get_glance_client_version(), session=sess)
149
150
151 # *********************************************
152 #   NOVA
153 # *********************************************
154 def get_instances(nova_client):     # pragma: no cover
155     try:
156         return nova_client.servers.list(search_opts={'all_tenants': 1})
157     except Exception:
158         log.exception("Error [get_instances(nova_client)]")
159
160
161 def get_instance_status(nova_client, instance):     # pragma: no cover
162     try:
163         return nova_client.servers.get(instance.id).status
164     except Exception:
165         log.exception("Error [get_instance_status(nova_client)]")
166
167
168 def get_instance_by_name(nova_client, instance_name):   # pragma: no cover
169     try:
170         return nova_client.servers.find(name=instance_name)
171     except Exception:
172         log.exception("Error [get_instance_by_name(nova_client, '%s')]",
173                       instance_name)
174
175
176 def get_aggregates(nova_client):    # pragma: no cover
177     try:
178         return nova_client.aggregates.list()
179     except Exception:
180         log.exception("Error [get_aggregates(nova_client)]")
181
182
183 def get_availability_zones(nova_client):    # pragma: no cover
184     try:
185         return nova_client.availability_zones.list()
186     except Exception:
187         log.exception("Error [get_availability_zones(nova_client)]")
188
189
190 def get_availability_zone_names(nova_client):   # pragma: no cover
191     try:
192         return [az.zoneName for az in get_availability_zones(nova_client)]
193     except Exception:
194         log.exception("Error [get_availability_zone_names(nova_client)]")
195
196
197 def create_aggregate(nova_client, aggregate_name, av_zone):  # pragma: no cover
198     try:
199         nova_client.aggregates.create(aggregate_name, av_zone)
200     except Exception:
201         log.exception("Error [create_aggregate(nova_client, %s, %s)]",
202                       aggregate_name, av_zone)
203         return False
204     else:
205         return True
206
207
208 def get_aggregate_id(nova_client, aggregate_name):      # pragma: no cover
209     try:
210         aggregates = get_aggregates(nova_client)
211         _id = next((ag.id for ag in aggregates if ag.name == aggregate_name))
212     except Exception:
213         log.exception("Error [get_aggregate_id(nova_client, %s)]",
214                       aggregate_name)
215     else:
216         return _id
217
218
219 def add_host_to_aggregate(nova_client, aggregate_name,
220                           compute_host):    # pragma: no cover
221     try:
222         aggregate_id = get_aggregate_id(nova_client, aggregate_name)
223         nova_client.aggregates.add_host(aggregate_id, compute_host)
224     except Exception:
225         log.exception("Error [add_host_to_aggregate(nova_client, %s, %s)]",
226                       aggregate_name, compute_host)
227         return False
228     else:
229         return True
230
231
232 def create_aggregate_with_host(nova_client, aggregate_name, av_zone,
233                                compute_host):    # pragma: no cover
234     try:
235         create_aggregate(nova_client, aggregate_name, av_zone)
236         add_host_to_aggregate(nova_client, aggregate_name, compute_host)
237     except Exception:
238         log.exception("Error [create_aggregate_with_host("
239                       "nova_client, %s, %s, %s)]",
240                       aggregate_name, av_zone, compute_host)
241         return False
242     else:
243         return True
244
245
246 def create_instance(flavor_name,
247                     image_id,
248                     network_id,
249                     instance_name="instance-vm",
250                     confdrive=True,
251                     userdata=None,
252                     av_zone='',
253                     fixed_ip=None,
254                     files=None):    # pragma: no cover
255     nova_client = get_nova_client()
256     try:
257         flavor = nova_client.flavors.find(name=flavor_name)
258     except:
259         flavors = nova_client.flavors.list()
260         log.exception("Error: Flavor '%s' not found. Available flavors are: "
261                       "\n%s", flavor_name, flavors)
262         return None
263     if fixed_ip is not None:
264         nics = {"net-id": network_id, "v4-fixed-ip": fixed_ip}
265     else:
266         nics = {"net-id": network_id}
267     if userdata is None:
268         instance = nova_client.servers.create(
269             name=instance_name,
270             flavor=flavor,
271             image=image_id,
272             nics=[nics],
273             availability_zone=av_zone,
274             files=files
275         )
276     else:
277         instance = nova_client.servers.create(
278             name=instance_name,
279             flavor=flavor,
280             image=image_id,
281             nics=[nics],
282             config_drive=confdrive,
283             userdata=userdata,
284             availability_zone=av_zone,
285             files=files
286         )
287     return instance
288
289
290 def create_instance_and_wait_for_active(flavor_name,
291                                         image_id,
292                                         network_id,
293                                         instance_name="instance-vm",
294                                         config_drive=False,
295                                         userdata="",
296                                         av_zone='',
297                                         fixed_ip=None,
298                                         files=None):    # pragma: no cover
299     SLEEP = 3
300     VM_BOOT_TIMEOUT = 180
301     nova_client = get_nova_client()
302     instance = create_instance(flavor_name,
303                                image_id,
304                                network_id,
305                                instance_name,
306                                config_drive,
307                                userdata,
308                                av_zone=av_zone,
309                                fixed_ip=fixed_ip,
310                                files=files)
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":
315             return instance
316         elif status.lower() == "error":
317             log.error("The instance %s went to ERROR status.", instance_name)
318             return None
319         time.sleep(SLEEP)
320     log.error("Timeout booting the instance %s.", instance_name)
321     return None
322
323
324 def delete_instance(nova_client, instance_id):      # pragma: no cover
325     try:
326         nova_client.servers.force_delete(instance_id)
327     except Exception:
328         log.exception("Error [delete_instance(nova_client, '%s')]",
329                       instance_id)
330         return False
331     else:
332         return True
333
334
335 def remove_host_from_aggregate(nova_client, aggregate_name,
336                                compute_host):  # pragma: no cover
337     try:
338         aggregate_id = get_aggregate_id(nova_client, aggregate_name)
339         nova_client.aggregates.remove_host(aggregate_id, compute_host)
340     except Exception:
341         log.exception("Error remove_host_from_aggregate(nova_client, %s, %s)",
342                       aggregate_name, compute_host)
343         return False
344     else:
345         return True
346
347
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
352     assert(
353         all(remove_host_from_aggregate(nova_client, aggregate_name, host)
354             for host in hosts))
355
356
357 def delete_aggregate(nova_client, aggregate_name):  # pragma: no cover
358     try:
359         remove_hosts_from_aggregate(nova_client, aggregate_name)
360         nova_client.aggregates.delete(aggregate_name)
361     except Exception:
362         log.exception("Error [delete_aggregate(nova_client, %s)]",
363                       aggregate_name)
364         return False
365     else:
366         return True
367
368
369 def get_server_by_name(name):   # pragma: no cover
370     try:
371         return get_nova_client().servers.list(search_opts={'name': name})[0]
372     except IndexError:
373         log.exception('Failed to get nova client')
374         raise
375
376
377 def get_image_by_name(name):    # pragma: no cover
378     images = get_nova_client().images.list()
379     try:
380         return next((a for a in images if a.name == name))
381     except StopIteration:
382         log.exception('No image matched')
383
384
385 def get_flavor_by_name(name):   # pragma: no cover
386     flavors = get_nova_client().flavors.list()
387     try:
388         return next((a for a in flavors if a.name == name))
389     except StopIteration:
390         log.exception('No flavor matched')
391
392
393 def check_status(status, name, iterations, interval):   # pragma: no cover
394     for i in range(iterations):
395         try:
396             server = get_server_by_name(name)
397         except IndexError:
398             log.error('Cannot found %s server', name)
399             raise
400
401         if server.status == status:
402             return True
403
404         time.sleep(interval)
405     return False
406
407
408 # *********************************************
409 #   NEUTRON
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)
414
415
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)
420
421
422 # *********************************************
423 #   GLANCE
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)