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