blob: df18df9126c36d7947fbc7074fdd7d7fc9bd691a [file] [log] [blame]
Oleksiy Petrenko95664c02018-04-19 17:05:16 +03001import logging
Oleksiy Petrenko95664c02018-04-19 17:05:16 +03002from uuid import UUID
Oleksiy Petrenko7cd57572019-02-06 12:50:15 +02003
4
5try:
6 import os_client_config
7except ImportError:
8 os_client_config = None
9from salt import exceptions
10
11
Oleksiy Petrenko95664c02018-04-19 17:05:16 +030012try:
13 from urllib.parse import urlsplit
14except ImportError:
15 from urlparse import urlsplit
16
17log = logging.getLogger(__name__)
18
19
20class BarbicanException(Exception):
21
22 _msg = "Barbican module exception occured."
23
24 def __init__(self, message=None, **kwargs):
25 super(BarbicanException, self).__init__(message or self._msg)
26
27
28class NoBarbicanEndpoint(BarbicanException):
29 _msg = "Barbican endpoint not found in keystone catalog."
30
31
32class NoAuthPluginConfigured(BarbicanException):
33 _msg = ("You are using keystoneauth auth plugin that does not support "
34 "fetching endpoint list from token (noauth or admin_token).")
35
36
37class NoCredentials(BarbicanException):
38 _msg = "Please provide cloud name present in clouds.yaml."
39
40
41class ResourceNotFound(BarbicanException):
42 _msg = "Uniq resource: {resource} with name: {name} not found."
43
44 def __init__(self, resource, name, **kwargs):
45 super(BarbicanException, self).__init__(
46 self._msg.format(resource=resource, name=name))
47
48
49class MultipleResourcesFound(BarbicanException):
50 _msg = "Multiple resource: {resource} with name: {name} found."
51
52 def __init__(self, resource, name, **kwargs):
53 super(BarbicanException, self).__init__(
54 self._msg.format(resource=resource, name=name))
55
56
57def _get_raw_client(cloud_name):
Oleksiy Petrenko7cd57572019-02-06 12:50:15 +020058 if not os_client_config:
59 raise exceptions.SaltInvocationError(
60 "Cannot load os-client-config. Please check your environment "
61 "configuration.")
Oleksiy Petrenko95664c02018-04-19 17:05:16 +030062 service_type = 'key-manager'
Vasyl Saienko1e36a462018-06-01 12:46:18 +030063 config = os_client_config.OpenStackConfig()
64 cloud = config.get_one_cloud(cloud_name)
65 adapter = cloud.get_session_client(service_type)
66 adapter.version = '1'
Oleksiy Petrenko95664c02018-04-19 17:05:16 +030067 try:
68 access_info = adapter.session.auth.get_access(adapter.session)
69 endpoints = access_info.service_catalog.get_endpoints()
Vasyl Saienko1e36a462018-06-01 12:46:18 +030070 except (AttributeError, ValueError) as exc:
71 log.exception('%s' % exc)
Oleksiy Petrenko95664c02018-04-19 17:05:16 +030072 e = NoAuthPluginConfigured()
73 log.exception('%s' % e)
74 raise e
75 if service_type not in endpoints:
76 if not service_type:
77 e = NoBarbicanEndpoint()
78 log.error('%s' % e)
79 raise e
80 return adapter
81
82
83def send(method):
84 def wrap(func):
85 def wrapped_f(*args, **kwargs):
86 cloud_name = kwargs.pop('cloud_name')
87 if not cloud_name:
88 e = NoCredentials()
89 log.error('%s' % e)
90 raise e
91 adapter = _get_raw_client(cloud_name)
92 # Remove salt internal kwargs
93 kwarg_keys = list(kwargs.keys())
94 for k in kwarg_keys:
95 if k.startswith('__'):
96 kwargs.pop(k)
97 url, request_kwargs = func(*args, **kwargs)
98 response = getattr(adapter, method)(url, **request_kwargs)
99 if not response.content:
100 return {}
101 try:
102 resp = response.json()
103 except:
104 resp = response.content
105 return resp
106 return wrapped_f
107 return wrap
108
109
110def _check_uuid(val):
111 try:
112 return str(UUID(val)).replace('-', '') == val
113 except (TypeError, ValueError, AttributeError):
114 return False
115
116
117def _parse_secret_href(href):
118 return urlsplit(href).path.split('/')[-1]
119
120
121def get_by_name_or_uuid(resource_list, resp_key):
122 def wrap(func):
123 def wrapped_f(*args, **kwargs):
124 if 'name' in kwargs:
125 ref = kwargs.pop('name', None)
126 start_arg = 0
127 else:
128 start_arg = 1
129 ref = args[0]
130 cloud_name = kwargs['cloud_name']
131 if _check_uuid(ref):
132 uuid = ref
133 else:
134 # Then we have name not uuid
135 resp = resource_list(
136 name=ref, cloud_name=cloud_name)[resp_key]
137 if len(resp) == 0:
138 raise ResourceNotFound(resp_key, ref)
139 elif len(resp) > 1:
140 raise MultipleResourcesFound(resp_key, ref)
141 href = resp[0]['secret_ref']
142 uuid = _parse_secret_href(href)
143 return func(uuid, *args[start_arg:], **kwargs)
144 return wrapped_f
145 return wrap