blob: 829b916463175f01d6b6afc0ae3f32cb43a9e14e [file] [log] [blame]
Moshe0bb532c2018-02-26 13:39:57 +02001##############################################################################
2# Copyright 2018 EuropeanSoftwareMarketingLtd.
3# ===================================================================
4# Licensed under the ApacheLicense, Version2.0 (the"License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# software distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and limitations under
12# the License
13##############################################################################
14# vnftest comment: this is a modified copy of
15# yardstick/common/openstack_utils.py
16
17from __future__ import absolute_import
18
19import os
20import time
21import sys
22import logging
23
24from keystoneauth1 import loading
25from keystoneauth1 import session
26from cinderclient import client as cinderclient
27from novaclient import client as novaclient
28from glanceclient import client as glanceclient
29from neutronclient.neutron import client as neutronclient
Moshec7c4cc22018-06-20 10:23:28 +030030from heatclient.client import Client as heatclient
Moshe0bb532c2018-02-26 13:39:57 +020031
32log = logging.getLogger(__name__)
33
34DEFAULT_HEAT_API_VERSION = '1'
35DEFAULT_API_VERSION = '2'
36
Moshe05acf082018-03-20 10:51:42 +020037creds = {}
38
Moshe0bb532c2018-02-26 13:39:57 +020039
40# *********************************************
41# CREDENTIALS
42# *********************************************
43def get_credentials():
44 """Returns a creds dictionary filled with parsed from env"""
Moshe05acf082018-03-20 10:51:42 +020045 if len(creds) == 0:
46 # The most common way to pass these info to the script is to do it
47 # through environment variables.
48 keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
Moshe0bb532c2018-02-26 13:39:57 +020049
Moshe05acf082018-03-20 10:51:42 +020050 if keystone_api_version is None or keystone_api_version == '2':
51 keystone_v3 = False
52 creds['tenant_name'] = os.environ.get('OS_TENANT_NAME')
53 else:
54 keystone_v3 = True
55 creds['tenant_name'] = os.environ.get('OS_PROJECT_NAME')
56 creds['project_name'] = os.environ.get('OS_PROJECT_NAME')
Moshe0bb532c2018-02-26 13:39:57 +020057
Moshe05acf082018-03-20 10:51:42 +020058 creds["username"] = os.environ.get("OS_USERNAME")
59 creds["password"] = os.environ.get("OS_PASSWORD")
60 creds["auth_url"] = os.environ.get("OS_AUTH_URL")
61 creds["tenant_id"] = os.environ.get("OS_TENANT_ID")
Moshe0bb532c2018-02-26 13:39:57 +020062
Moshe05acf082018-03-20 10:51:42 +020063 if keystone_v3:
64 if os.getenv('OS_USER_DOMAIN_NAME') is not None:
65 creds.update({
66 "user_domain_name": os.getenv('OS_USER_DOMAIN_NAME')
67 })
68 if os.getenv('OS_PROJECT_DOMAIN_NAME') is not None:
69 creds.update({
70 "project_domain_name": os.getenv('OS_PROJECT_DOMAIN_NAME')
71 })
Moshe0bb532c2018-02-26 13:39:57 +020072 return creds
73
74
75def get_session_auth():
76 loader = loading.get_plugin_loader('password')
77 creds = get_credentials()
78 auth = loader.load_from_options(**creds)
79 return auth
80
81
82def get_session():
83 auth = get_session_auth()
84 try:
85 cacert = os.environ['OS_CACERT']
86 except KeyError:
87 return session.Session(auth=auth)
88 else:
89 insecure = os.getenv('OS_INSECURE', '').lower() == 'true'
90 cacert = False if insecure else cacert
91 return session.Session(auth=auth, verify=cacert)
92
93
94def get_endpoint(service_type, endpoint_type='publicURL'):
95 auth = get_session_auth()
96 # for multi-region, we need to specify region
97 # when finding the endpoint
98 return get_session().get_endpoint(auth=auth,
99 service_type=service_type,
100 endpoint_type=endpoint_type,
101 region_name=os.environ.get(
102 "OS_REGION_NAME"))
103
104
105# *********************************************
106# CLIENTS
107# *********************************************
108def get_heat_api_version(): # pragma: no cover
109 try:
110 api_version = os.environ['HEAT_API_VERSION']
111 except KeyError:
112 return DEFAULT_HEAT_API_VERSION
113 else:
114 log.info("HEAT_API_VERSION is set in env as '%s'", api_version)
115 return api_version
116
117
118def get_cinder_client_version(): # pragma: no cover
119 try:
120 api_version = os.environ['OS_VOLUME_API_VERSION']
121 except KeyError:
122 return DEFAULT_API_VERSION
123 else:
124 log.info("OS_VOLUME_API_VERSION is set in env as '%s'", api_version)
125 return api_version
126
127
128def get_cinder_client(): # pragma: no cover
129 sess = get_session()
130 return cinderclient.Client(get_cinder_client_version(), session=sess)
131
132
133def get_nova_client_version(): # pragma: no cover
134 try:
135 api_version = os.environ['OS_COMPUTE_API_VERSION']
136 except KeyError:
137 return DEFAULT_API_VERSION
138 else:
139 log.info("OS_COMPUTE_API_VERSION is set in env as '%s'", api_version)
140 return api_version
141
142
143def get_nova_client(): # pragma: no cover
144 sess = get_session()
145 return novaclient.Client(get_nova_client_version(), session=sess)
146
147
148def get_neutron_client_version(): # pragma: no cover
149 try:
150 api_version = os.environ['OS_NETWORK_API_VERSION']
151 except KeyError:
152 return DEFAULT_API_VERSION
153 else:
154 log.info("OS_NETWORK_API_VERSION is set in env as '%s'", api_version)
155 return api_version
156
157
158def get_neutron_client(): # pragma: no cover
159 sess = get_session()
160 return neutronclient.Client(get_neutron_client_version(), session=sess)
161
162
Moshec7c4cc22018-06-20 10:23:28 +0300163def get_heat_client(): # pragma: no cover
164 sess = get_session()
165 return heatclient(get_heat_api_version(), session=sess)
166
167
Moshe0bb532c2018-02-26 13:39:57 +0200168def get_glance_client_version(): # pragma: no cover
169 try:
170 api_version = os.environ['OS_IMAGE_API_VERSION']
171 except KeyError:
172 return DEFAULT_API_VERSION
173 else:
174 log.info("OS_IMAGE_API_VERSION is set in env as '%s'", api_version)
175 return api_version
176
177
178def get_glance_client(): # pragma: no cover
179 sess = get_session()
180 return glanceclient.Client(get_glance_client_version(), session=sess)
181
182
183# *********************************************
184# NOVA
185# *********************************************
186def get_instances(nova_client): # pragma: no cover
187 try:
188 return nova_client.servers.list(search_opts={'all_tenants': 1})
189 except Exception:
190 log.exception("Error [get_instances(nova_client)]")
191
192
193def get_instance_status(nova_client, instance): # pragma: no cover
194 try:
195 return nova_client.servers.get(instance.id).status
196 except Exception:
197 log.exception("Error [get_instance_status(nova_client)]")
198
199
200def get_instance_by_name(nova_client, instance_name): # pragma: no cover
201 try:
202 return nova_client.servers.find(name=instance_name)
203 except Exception:
204 log.exception("Error [get_instance_by_name(nova_client, '%s')]",
205 instance_name)
206
207
Moshec7c4cc22018-06-20 10:23:28 +0300208def get_instance_by_id(instance_id): # pragma: no cover
209 try:
210 return get_nova_client().servers.find(id=instance_id)
211 except Exception:
212 log.exception("Error [get_instance_by_id(nova_client, '%s')]",
213 instance_id)
214
215
Moshe0bb532c2018-02-26 13:39:57 +0200216def get_aggregates(nova_client): # pragma: no cover
217 try:
218 return nova_client.aggregates.list()
219 except Exception:
220 log.exception("Error [get_aggregates(nova_client)]")
221
222
223def get_availability_zones(nova_client): # pragma: no cover
224 try:
225 return nova_client.availability_zones.list()
226 except Exception:
227 log.exception("Error [get_availability_zones(nova_client)]")
228
229
230def get_availability_zone_names(nova_client): # pragma: no cover
231 try:
232 return [az.zoneName for az in get_availability_zones(nova_client)]
233 except Exception:
234 log.exception("Error [get_availability_zone_names(nova_client)]")
235
236
237def create_aggregate(nova_client, aggregate_name, av_zone): # pragma: no cover
238 try:
239 nova_client.aggregates.create(aggregate_name, av_zone)
240 except Exception:
241 log.exception("Error [create_aggregate(nova_client, %s, %s)]",
242 aggregate_name, av_zone)
243 return False
244 else:
245 return True
246
247
248def get_aggregate_id(nova_client, aggregate_name): # pragma: no cover
249 try:
250 aggregates = get_aggregates(nova_client)
251 _id = next((ag.id for ag in aggregates if ag.name == aggregate_name))
252 except Exception:
253 log.exception("Error [get_aggregate_id(nova_client, %s)]",
254 aggregate_name)
255 else:
256 return _id
257
258
259def add_host_to_aggregate(nova_client, aggregate_name,
260 compute_host): # pragma: no cover
261 try:
262 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
263 nova_client.aggregates.add_host(aggregate_id, compute_host)
264 except Exception:
265 log.exception("Error [add_host_to_aggregate(nova_client, %s, %s)]",
266 aggregate_name, compute_host)
267 return False
268 else:
269 return True
270
271
272def create_aggregate_with_host(nova_client, aggregate_name, av_zone,
273 compute_host): # pragma: no cover
274 try:
275 create_aggregate(nova_client, aggregate_name, av_zone)
276 add_host_to_aggregate(nova_client, aggregate_name, compute_host)
277 except Exception:
278 log.exception("Error [create_aggregate_with_host("
279 "nova_client, %s, %s, %s)]",
280 aggregate_name, av_zone, compute_host)
281 return False
282 else:
283 return True
284
285
286def create_keypair(nova_client, name, key_path=None): # pragma: no cover
287 try:
288 with open(key_path) as fpubkey:
289 keypair = get_nova_client().keypairs.create(name=name, public_key=fpubkey.read())
290 return keypair
291 except Exception:
292 log.exception("Error [create_keypair(nova_client)]")
293
294
295def create_instance(json_body): # pragma: no cover
296 try:
297 return get_nova_client().servers.create(**json_body)
298 except Exception:
299 log.exception("Error create instance failed")
300 return None
301
302
303def create_instance_and_wait_for_active(json_body): # pragma: no cover
304 SLEEP = 3
305 VM_BOOT_TIMEOUT = 180
306 nova_client = get_nova_client()
307 instance = create_instance(json_body)
308 count = VM_BOOT_TIMEOUT / SLEEP
309 for n in range(count, -1, -1):
310 status = get_instance_status(nova_client, instance)
311 if status.lower() == "active":
312 return instance
313 elif status.lower() == "error":
314 log.error("The instance went to ERROR status.")
315 return None
316 time.sleep(SLEEP)
317 log.error("Timeout booting the instance.")
318 return None
319
320
321def attach_server_volume(server_id, volume_id, device=None): # pragma: no cover
322 try:
323 get_nova_client().volumes.create_server_volume(server_id, volume_id, device)
324 except Exception:
325 log.exception("Error [attach_server_volume(nova_client, '%s', '%s')]",
326 server_id, volume_id)
327 return False
328 else:
329 return True
330
331
332def delete_instance(nova_client, instance_id): # pragma: no cover
333 try:
334 nova_client.servers.force_delete(instance_id)
335 except Exception:
336 log.exception("Error [delete_instance(nova_client, '%s')]",
337 instance_id)
338 return False
339 else:
340 return True
341
342
343def remove_host_from_aggregate(nova_client, aggregate_name,
344 compute_host): # pragma: no cover
345 try:
346 aggregate_id = get_aggregate_id(nova_client, aggregate_name)
347 nova_client.aggregates.remove_host(aggregate_id, compute_host)
348 except Exception:
349 log.exception("Error remove_host_from_aggregate(nova_client, %s, %s)",
350 aggregate_name, compute_host)
351 return False
352 else:
353 return True
354
355
356def 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
360 assert(
361 all(remove_host_from_aggregate(nova_client, aggregate_name, host)
362 for host in hosts))
363
364
365def delete_aggregate(nova_client, aggregate_name): # pragma: no cover
366 try:
367 remove_hosts_from_aggregate(nova_client, aggregate_name)
368 nova_client.aggregates.delete(aggregate_name)
369 except Exception:
370 log.exception("Error [delete_aggregate(nova_client, %s)]",
371 aggregate_name)
372 return False
373 else:
374 return True
375
376
377def get_server_by_name(name): # pragma: no cover
378 try:
379 return get_nova_client().servers.list(search_opts={'name': name})[0]
380 except IndexError:
381 log.exception('Failed to get nova client')
382 raise
383
384
385def create_flavor(name, ram, vcpus, disk, **kwargs): # pragma: no cover
386 try:
387 return get_nova_client().flavors.create(name, ram, vcpus, disk, **kwargs)
388 except Exception:
389 log.exception("Error [create_flavor(nova_client, %s, %s, %s, %s, %s)]",
390 name, ram, disk, vcpus, kwargs['is_public'])
391 return None
392
393
394def get_image_by_name(name): # pragma: no cover
395 images = get_nova_client().images.list()
396 try:
397 return next((a for a in images if a.name == name))
398 except StopIteration:
399 log.exception('No image matched')
400
401
402def get_flavor_id(nova_client, flavor_name): # pragma: no cover
403 flavors = nova_client.flavors.list(detailed=True)
404 flavor_id = ''
405 for f in flavors:
406 if f.name == flavor_name:
407 flavor_id = f.id
408 break
409 return flavor_id
410
411
412def get_flavor_by_name(name): # pragma: no cover
413 flavors = get_nova_client().flavors.list()
414 try:
415 return next((a for a in flavors if a.name == name))
416 except StopIteration:
417 log.exception('No flavor matched')
418
419
420def check_status(status, name, iterations, interval): # pragma: no cover
421 for i in range(iterations):
422 try:
423 server = get_server_by_name(name)
424 except IndexError:
425 log.error('Cannot found %s server', name)
426 raise
427
428 if server.status == status:
429 return True
430
431 time.sleep(interval)
432 return False
433
434
435def delete_flavor(flavor_id): # pragma: no cover
436 try:
437 get_nova_client().flavors.delete(flavor_id)
438 except Exception:
439 log.exception("Error [delete_flavor(nova_client, %s)]", flavor_id)
440 return False
441 else:
442 return True
443
444
445def delete_keypair(nova_client, key): # pragma: no cover
446 try:
447 nova_client.keypairs.delete(key=key)
448 return True
449 except Exception:
450 log.exception("Error [delete_keypair(nova_client)]")
451 return False
452
453
454# *********************************************
455# NEUTRON
456# *********************************************
Moshec7c4cc22018-06-20 10:23:28 +0300457def get_network_by_name(network_name): # pragma: no cover
458 try:
459 networks = get_neutron_client().list_networks()['networks']
460 return next((n for n in networks if n['name'] == network_name), None)
461 except Exception:
462 log.exception("Error [get_instance_by_id(nova_client, '%s')]",
463 network_name)
464
465
Moshe0bb532c2018-02-26 13:39:57 +0200466def get_network_id(neutron_client, network_name): # pragma: no cover
467 networks = neutron_client.list_networks()['networks']
468 return next((n['id'] for n in networks if n['name'] == network_name), None)
469
470
471def get_port_id_by_ip(neutron_client, ip_address): # pragma: no cover
472 ports = neutron_client.list_ports()['ports']
473 return next((i['id'] for i in ports for j in i.get(
474 'fixed_ips') if j['ip_address'] == ip_address), None)
475
476
477def create_neutron_net(neutron_client, json_body): # pragma: no cover
478 try:
479 network = neutron_client.create_network(body=json_body)
480 return network['network']['id']
481 except Exception:
482 log.error("Error [create_neutron_net(neutron_client)]")
483 raise Exception("operation error")
484 return None
485
486
487def delete_neutron_net(neutron_client, network_id): # pragma: no cover
488 try:
489 neutron_client.delete_network(network_id)
490 return True
491 except Exception:
492 log.error("Error [delete_neutron_net(neutron_client, '%s')]" % network_id)
493 return False
494
495
496def create_neutron_subnet(neutron_client, json_body): # pragma: no cover
497 try:
498 subnet = neutron_client.create_subnet(body=json_body)
499 return subnet['subnets'][0]['id']
500 except Exception:
501 log.error("Error [create_neutron_subnet")
502 raise Exception("operation error")
503 return None
504
505
506def create_neutron_router(neutron_client, json_body): # pragma: no cover
507 try:
508 router = neutron_client.create_router(json_body)
509 return router['router']['id']
510 except Exception:
511 log.error("Error [create_neutron_router(neutron_client)]")
512 raise Exception("operation error")
513 return None
514
515
516def delete_neutron_router(neutron_client, router_id): # pragma: no cover
517 try:
518 neutron_client.delete_router(router=router_id)
519 return True
520 except Exception:
521 log.error("Error [delete_neutron_router(neutron_client, '%s')]" % router_id)
522 return False
523
524
525def remove_gateway_router(neutron_client, router_id): # pragma: no cover
526 try:
527 neutron_client.remove_gateway_router(router_id)
528 return True
529 except Exception:
530 log.error("Error [remove_gateway_router(neutron_client, '%s')]" % router_id)
531 return False
532
533
534def remove_interface_router(neutron_client, router_id, subnet_id,
535 **json_body): # pragma: no cover
536 json_body.update({"subnet_id": subnet_id})
537 try:
538 neutron_client.remove_interface_router(router=router_id,
539 body=json_body)
540 return True
541 except Exception:
542 log.error("Error [remove_interface_router(neutron_client, '%s', "
543 "'%s')]" % (router_id, subnet_id))
544 return False
545
546
547def create_floating_ip(neutron_client, extnet_id): # pragma: no cover
548 props = {'floating_network_id': extnet_id}
549 try:
550 ip_json = neutron_client.create_floatingip({'floatingip': props})
551 fip_addr = ip_json['floatingip']['floating_ip_address']
552 fip_id = ip_json['floatingip']['id']
553 except Exception:
554 log.error("Error [create_floating_ip(neutron_client)]")
555 return None
556 return {'fip_addr': fip_addr, 'fip_id': fip_id}
557
558
559def delete_floating_ip(nova_client, floatingip_id): # pragma: no cover
560 try:
561 nova_client.floating_ips.delete(floatingip_id)
562 return True
563 except Exception:
564 log.error("Error [delete_floating_ip(nova_client, '%s')]" % floatingip_id)
565 return False
566
567
568def get_security_groups(neutron_client): # pragma: no cover
569 try:
570 security_groups = neutron_client.list_security_groups()[
571 'security_groups']
572 return security_groups
573 except Exception:
574 log.error("Error [get_security_groups(neutron_client)]")
575 return None
576
577
578def get_security_group_id(neutron_client, sg_name): # pragma: no cover
579 security_groups = get_security_groups(neutron_client)
580 id = ''
581 for sg in security_groups:
582 if sg['name'] == sg_name:
583 id = sg['id']
584 break
585 return id
586
587
588def create_security_group(neutron_client, sg_name, sg_description): # pragma: no cover
589 json_body = {'security_group': {'name': sg_name,
590 'description': sg_description}}
591 try:
592 secgroup = neutron_client.create_security_group(json_body)
593 return secgroup['security_group']
594 except Exception:
595 log.error("Error [create_security_group(neutron_client, '%s', "
596 "'%s')]" % (sg_name, sg_description))
597 return None
598
599
600def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
601 port_range_min=None, port_range_max=None,
602 **json_body): # pragma: no cover
603 # We create a security group in 2 steps
604 # 1 - we check the format and set the json body accordingly
605 # 2 - we call neturon client to create the security group
606
607 # Format check
608 json_body.update({'security_group_rule': {'direction': direction,
609 'security_group_id': sg_id, 'protocol': protocol}})
610 # parameters may be
611 # - both None => we do nothing
612 # - both Not None => we add them to the json description
613 # but one cannot be None is the other is not None
614 if (port_range_min is not None and port_range_max is not None):
615 # add port_range in json description
616 json_body['security_group_rule']['port_range_min'] = port_range_min
617 json_body['security_group_rule']['port_range_max'] = port_range_max
618 log.debug("Security_group format set (port range included)")
619 else:
620 # either both port range are set to None => do nothing
621 # or one is set but not the other => log it and return False
622 if port_range_min is None and port_range_max is None:
623 log.debug("Security_group format set (no port range mentioned)")
624 else:
625 log.error("Bad security group format."
626 "One of the port range is not properly set:"
627 "range min: {},"
628 "range max: {}".format(port_range_min,
629 port_range_max))
630 return False
631
632 # Create security group using neutron client
633 try:
634 neutron_client.create_security_group_rule(json_body)
635 return True
636 except Exception:
637 log.exception("Impossible to create_security_group_rule,"
638 "security group rule probably already exists")
639 return False
640
641
642def create_security_group_full(neutron_client,
643 sg_name, sg_description): # pragma: no cover
644 sg_id = get_security_group_id(neutron_client, sg_name)
645 if sg_id != '':
646 log.info("Using existing security group '%s'..." % sg_name)
647 else:
648 log.info("Creating security group '%s'..." % sg_name)
649 SECGROUP = create_security_group(neutron_client,
650 sg_name,
651 sg_description)
652 if not SECGROUP:
653 log.error("Failed to create the security group...")
654 return None
655
656 sg_id = SECGROUP['id']
657
658 log.debug("Security group '%s' with ID=%s created successfully."
659 % (SECGROUP['name'], sg_id))
660
661 log.debug("Adding ICMP rules in security group '%s'..."
662 % sg_name)
663 if not create_secgroup_rule(neutron_client, sg_id,
664 'ingress', 'icmp'):
665 log.error("Failed to create the security group rule...")
666 return None
667
668 log.debug("Adding SSH rules in security group '%s'..."
669 % sg_name)
670 if not create_secgroup_rule(
671 neutron_client, sg_id, 'ingress', 'tcp', '22', '22'):
672 log.error("Failed to create the security group rule...")
673 return None
674
675 if not create_secgroup_rule(
676 neutron_client, sg_id, 'egress', 'tcp', '22', '22'):
677 log.error("Failed to create the security group rule...")
678 return None
679 return sg_id
680
681
682# *********************************************
683# GLANCE
684# *********************************************
685def get_image_id(glance_client, image_name): # pragma: no cover
686 images = glance_client.images.list()
687 return next((i.id for i in images if i.name == image_name), None)
688
689
690def create_image(glance_client, image_name, file_path, disk_format,
691 container_format, min_disk, min_ram, protected, tag,
692 public, **kwargs): # pragma: no cover
693 if not os.path.isfile(file_path):
694 log.error("Error: file %s does not exist." % file_path)
695 return None
696 try:
697 image_id = get_image_id(glance_client, image_name)
698 if image_id is not None:
699 log.info("Image %s already exists." % image_name)
700 else:
701 log.info("Creating image '%s' from '%s'...", image_name, file_path)
702
703 image = glance_client.images.create(name=image_name,
704 visibility=public,
705 disk_format=disk_format,
706 container_format=container_format,
707 min_disk=min_disk,
708 min_ram=min_ram,
709 tags=tag,
710 protected=protected,
711 **kwargs)
712 image_id = image.id
713 with open(file_path) as image_data:
714 glance_client.images.upload(image_id, image_data)
715 return image_id
716 except Exception:
717 log.error("Error [create_glance_image(glance_client, '%s', '%s', '%s')]",
718 image_name, file_path, public)
719 return None
720
721
722def delete_image(glance_client, image_id): # pragma: no cover
723 try:
724 glance_client.images.delete(image_id)
725
726 except Exception:
727 log.exception("Error [delete_flavor(glance_client, %s)]", image_id)
728 return False
729 else:
730 return True
731
732
733# *********************************************
734# CINDER
735# *********************************************
736def get_volume_id(volume_name): # pragma: no cover
737 volumes = get_cinder_client().volumes.list()
738 return next((v.id for v in volumes if v.name == volume_name), None)
739
740
741def create_volume(cinder_client, volume_name, volume_size,
742 volume_image=False): # pragma: no cover
743 try:
744 if volume_image:
745 volume = cinder_client.volumes.create(name=volume_name,
746 size=volume_size,
747 imageRef=volume_image)
748 else:
749 volume = cinder_client.volumes.create(name=volume_name,
750 size=volume_size)
751 return volume
752 except Exception:
753 log.exception("Error [create_volume(cinder_client, %s)]",
754 (volume_name, volume_size))
755 return None
756
757
758def delete_volume(cinder_client, volume_id, forced=False): # pragma: no cover
759 try:
760 if forced:
761 try:
762 cinder_client.volumes.detach(volume_id)
763 except:
764 log.error(sys.exc_info()[0])
765 cinder_client.volumes.force_delete(volume_id)
766 else:
767 while True:
768 volume = get_cinder_client().volumes.get(volume_id)
769 if volume.status.lower() == 'available':
770 break
771 cinder_client.volumes.delete(volume_id)
772 return True
773 except Exception:
774 log.exception("Error [delete_volume(cinder_client, '%s')]" % volume_id)
775 return False
776
777
778def detach_volume(server_id, volume_id): # pragma: no cover
779 try:
780 get_nova_client().volumes.delete_server_volume(server_id, volume_id)
781 return True
782 except Exception:
783 log.exception("Error [detach_server_volume(nova_client, '%s', '%s')]",
784 server_id, volume_id)
785 return False
Moshec7c4cc22018-06-20 10:23:28 +0300786# *********************************************
787# HEAT
788# *********************************************
789
790
791def get_stack(heat_stack_id): # pragma: no cover
792 try:
793 client = get_heat_client()
794 return client.stacks.get(heat_stack_id)
795 except Exception as e:
796 log.exception("Error [get_stack(heat_stack_id)]", e)
797
798
799def get_stack_resources(heat_stack_id): # pragma: no cover
800 try:
801 client = get_heat_client()
802 return client.resources.list(heat_stack_id)
803 except Exception as e:
804 log.exception("Error [get_stack_resources(heat_stack_id)]", e)
805
806
807def get_stack_vms(heat_stack_id): # pragma: no cover
808 resources = get_stack_resources(heat_stack_id)
809 ret_vms = []
810 for resource in resources:
811 if resource.resource_type == "OS::Nova::Server":
812 ret_vms.append(resource)
813 return ret_vms