blob: ddc8138c187214225293aab21d5ba82794894e60 [file] [log] [blame]
Oleg Bondarev9250e612018-09-24 18:59:40 +04001import logging
Oleg Bondarev9250e612018-09-24 18:59:40 +04002from uuid import UUID
3
Oleksiy Petrenkoce6159b2019-02-06 13:13:52 +02004try:
5 import os_client_config
6except ImportError:
7 os_client_config = None
8from salt import exceptions
9
10
Oleg Bondarev9250e612018-09-24 18:59:40 +040011log = logging.getLogger(__name__)
12
13
14class OctaviaException(Exception):
15
16 _msg = "Octavia module exception occured."
17
18 def __init__(self, message=None, **kwargs):
19 super(OctaviaException, self).__init__(message or self._msg)
20
21
22class NoAuthPluginConfigured(OctaviaException):
23 _msg = ("You are using keystoneauth auth plugin that does not support "
24 "fetching endpoint list from token (noauth or admin_token).")
25
26
27class NoCredentials(OctaviaException):
28 _msg = "Please provide cloud name present in clouds.yaml."
29
30
31class ResourceNotFound(OctaviaException):
32 _msg = "Uniq resource: {resource} with name: {name} not found."
33
34 def __init__(self, resource, name, **kwargs):
35 super(ResourceNotFound, self).__init__(
36 self._msg.format(resource=resource, name=name))
37
38
39class MultipleResourcesFound(OctaviaException):
40 _msg = "Multiple resource: {resource} with name: {name} found."
41
42 def __init__(self, resource, name, **kwargs):
43 super(MultipleResourcesFound, self).__init__(
44 self._msg.format(resource=resource, name=name))
45
46
47def _get_raw_client(cloud_name):
Oleksiy Petrenkoce6159b2019-02-06 13:13:52 +020048 if not os_client_config:
49 raise exceptions.SaltInvocationError(
50 "Cannot load os-client-config. Please check your environment "
51 "configuration.")
Oleg Bondarev9250e612018-09-24 18:59:40 +040052 service_type = 'load-balancer'
53 config = os_client_config.OpenStackConfig()
54 cloud = config.get_one_cloud(cloud_name)
55 adapter = cloud.get_session_client(service_type)
56 # workaround for IndexError as Octavia doen's have a version discovery
57 # document till Rocky (https://review.openstack.org/#/c/559460/)
58 adapter.min_version = None
59 adapter.max_version = None
60 adapter.version = None
61 try:
62 access_info = adapter.session.auth.get_access(adapter.session)
63 access_info.service_catalog.get_endpoints()
64 except (AttributeError, ValueError):
65 e = NoAuthPluginConfigured()
66 log.exception('%s' % e)
67 raise e
68 return adapter
69
70
71def send(method):
72 def wrap(func):
73 def wrapped_f(*args, **kwargs):
74 cloud_name = kwargs.pop('cloud_name')
75 if not cloud_name:
76 e = NoCredentials()
77 log.error('%s' % e)
78 raise e
79 adapter = _get_raw_client(cloud_name)
80 # Remove salt internal kwargs
81 kwarg_keys = list(kwargs.keys())
82 for k in kwarg_keys:
83 if k.startswith('__'):
84 kwargs.pop(k)
85 url, request_kwargs = func(*args, **kwargs)
86 response = getattr(adapter, method)(url, **request_kwargs)
87 if not response.content:
88 return {}
89 return response.json()
90 return wrapped_f
91 return wrap
92
93
94def _check_uuid(val):
95 try:
96 return str(UUID(val)).replace('-', '') == val.replace('-', '')
97 except (TypeError, ValueError, AttributeError):
98 return False
99
100
101def get_by_name_or_uuid(resource_list, resp_key, resp_id_key='id'):
102 def wrap(func):
103 def wrapped_f(*args, **kwargs):
104 if 'name' in kwargs:
105 ref = kwargs.pop('name', None)
106 start_arg = 0
107 else:
108 start_arg = 1
109 ref = args[0]
110 if _check_uuid(ref):
111 uuid = ref
112 else:
113 # Then we have name not uuid
114 cloud_name = kwargs['cloud_name']
115 resp = resource_list(
116 name=ref, cloud_name=cloud_name)[resp_key]
117 if len(resp) == 0:
118 raise ResourceNotFound(resp_key, ref)
119 elif len(resp) > 1:
120 raise MultipleResourcesFound(resp_key, ref)
121 uuid = resp[0][resp_id_key]
122 return func(uuid, *args[start_arg:], **kwargs)
123 return wrapped_f
124 return wrap