blob: e039f87d207293857668e99761d65b169943bfa4 [file] [log] [blame]
Oleh Hryhorov1aeb0c82018-10-26 14:51:30 +00001import time
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +02002import logging
Oleksiy Petrenkob110da92019-02-06 12:52:56 +02003
4try:
5 import os_client_config
6except ImportError:
7 os_client_config = None
8from salt import exceptions
kairat_kushaev5c8626d2018-06-09 18:15:15 +04009
10log = logging.getLogger(__name__)
11
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +020012
13class CinderException(Exception):
14
15 _msg = "Cinder module exception occured."
16
17 def __init__(self, message=None, **kwargs):
18 super(CinderException, self).__init__(message or self._msg)
kairat_kushaev5c8626d2018-06-09 18:15:15 +040019
20
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +020021class NoCinderEndpoint(CinderException):
22 _msg = "Cinder endpoint not found in keystone catalog."
23
24
25class NoAuthPluginConfigured(CinderException):
26 _msg = ("You are using keystoneauth auth plugin that does not support "
27 "fetching endpoint list from token (noauth or admin_token).")
28
29
30class NoCredentials(CinderException):
31 _msg = "Please provide cloud name present in clouds.yaml."
32
33
34class ResourceNotFound(CinderException):
35 _msg = "Uniq resource: {resource} with name: {name} not found."
36
37 def __init__(self, resource, name, **kwargs):
38 super(CinderException, self).__init__(
39 self._msg.format(resource=resource, name=name))
40
41
42class MultipleResourcesFound(CinderException):
43 _msg = "Multiple resource: {resource} with name: {name} found."
44
45 def __init__(self, resource, name, **kwargs):
46 super(CinderException, self).__init__(
47 self._msg.format(resource=resource, name=name))
48
49
50def _get_raw_client(cloud_name):
Oleksiy Petrenkob110da92019-02-06 12:52:56 +020051 if not os_client_config:
52 raise exceptions.SaltInvocationError(
53 "Cannot load os-client-config. Please check your environment "
54 "configuration.")
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +020055 service_type = 'volumev3'
kairat_kushaev5c8626d2018-06-09 18:15:15 +040056 config = os_client_config.OpenStackConfig()
57 cloud = config.get_one_cloud(cloud_name)
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +020058 adapter = cloud.get_session_client(service_type)
kairat_kushaev5c8626d2018-06-09 18:15:15 +040059 try:
60 access_info = adapter.session.auth.get_access(adapter.session)
61 endpoints = access_info.service_catalog.get_endpoints()
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +020062 except (AttributeError, ValueError):
63 e = NoAuthPluginConfigured()
64 log.exception('%s' % e)
65 raise e
66 if service_type not in endpoints:
67 if not service_type:
68 e = NoCinderEndpoint()
69 log.error('%s' % e)
70 raise e
kairat_kushaev5c8626d2018-06-09 18:15:15 +040071 return adapter
72
73
74def send(method):
75 def wrap(func):
kairat_kushaev5c8626d2018-06-09 18:15:15 +040076 def wrapped_f(*args, **kwargs):
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +020077 cloud_name = kwargs.pop('cloud_name')
root08402652018-12-28 15:04:23 +000078 connection_params = kwargs.pop('connection_params', {}) or {}
79 connect_retries = connection_params.get('connect_retries', 60)
80 connect_retry_delay = connection_params.get('connect_retry_delay',
81 1)
kairat_kushaev5c8626d2018-06-09 18:15:15 +040082 if not cloud_name:
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +020083 e = NoCredentials()
84 log.error('%s' % e)
85 raise e
86 adapter = _get_raw_client(cloud_name)
87 # Remove salt internal kwargs
kairat_kushaev5c8626d2018-06-09 18:15:15 +040088 kwarg_keys = list(kwargs.keys())
89 for k in kwarg_keys:
90 if k.startswith('__'):
91 kwargs.pop(k)
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +020092 url, json = func(*args, **kwargs)
Oleh Hryhorov1aeb0c82018-10-26 14:51:30 +000093 response = None
94 for i in range(connect_retries):
95 try:
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +020096 if json:
97 response = getattr(adapter, method)(
98 url, json=json, connect_retries=connect_retries)
99 else:
100 response = getattr(adapter, method)(url)
Oleh Hryhorov1aeb0c82018-10-26 14:51:30 +0000101 except Exception as e:
Oleksiy Petrenko61a84ff2018-12-07 19:14:28 +0200102 if not hasattr(e, 'http_status') or (e.http_status >= 500
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +0200103 or e.http_status == 0):
Oleh Hryhorov1aeb0c82018-10-26 14:51:30 +0000104 msg = ("Got retriable exception when contacting "
105 "Cinder API. Sleeping for %ss. Attepmpts "
106 "%s of %s")
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +0200107 log.error(
108 msg % (connect_retry_delay, i, connect_retries))
Oleh Hryhorov1aeb0c82018-10-26 14:51:30 +0000109 time.sleep(connect_retry_delay)
110 continue
111 break
112 if not response or not response.content:
113 return {}
kairat_kushaev5c8626d2018-06-09 18:15:15 +0400114 try:
Oleh Hryhorov1aeb0c82018-10-26 14:51:30 +0000115 resp = response.json()
Oleksiy Petrenkoe38f5a62018-11-21 12:58:07 +0200116 except:
Oleh Hryhorov1aeb0c82018-10-26 14:51:30 +0000117 resp = response.content
118 return resp
kairat_kushaev5c8626d2018-06-09 18:15:15 +0400119 return wrapped_f
120 return wrap