blob: 83fd6ff7f05135a3e18dad858e826d0bb30cfa3a [file] [log] [blame]
Oleksiy Petrenko95664c02018-04-19 17:05:16 +03001import logging
2import os_client_config
3from uuid import UUID
4try:
5 from urllib.parse import urlsplit
6except ImportError:
7 from urlparse import urlsplit
8
9log = logging.getLogger(__name__)
10
11
12class BarbicanException(Exception):
13
14 _msg = "Barbican module exception occured."
15
16 def __init__(self, message=None, **kwargs):
17 super(BarbicanException, self).__init__(message or self._msg)
18
19
20class NoBarbicanEndpoint(BarbicanException):
21 _msg = "Barbican endpoint not found in keystone catalog."
22
23
24class NoAuthPluginConfigured(BarbicanException):
25 _msg = ("You are using keystoneauth auth plugin that does not support "
26 "fetching endpoint list from token (noauth or admin_token).")
27
28
29class NoCredentials(BarbicanException):
30 _msg = "Please provide cloud name present in clouds.yaml."
31
32
33class ResourceNotFound(BarbicanException):
34 _msg = "Uniq resource: {resource} with name: {name} not found."
35
36 def __init__(self, resource, name, **kwargs):
37 super(BarbicanException, self).__init__(
38 self._msg.format(resource=resource, name=name))
39
40
41class MultipleResourcesFound(BarbicanException):
42 _msg = "Multiple resource: {resource} with name: {name} found."
43
44 def __init__(self, resource, name, **kwargs):
45 super(BarbicanException, self).__init__(
46 self._msg.format(resource=resource, name=name))
47
48
49def _get_raw_client(cloud_name):
50 service_type = 'key-manager'
Vasyl Saienko1e36a462018-06-01 12:46:18 +030051 config = os_client_config.OpenStackConfig()
52 cloud = config.get_one_cloud(cloud_name)
53 adapter = cloud.get_session_client(service_type)
54 adapter.version = '1'
Oleksiy Petrenko95664c02018-04-19 17:05:16 +030055 try:
56 access_info = adapter.session.auth.get_access(adapter.session)
57 endpoints = access_info.service_catalog.get_endpoints()
Vasyl Saienko1e36a462018-06-01 12:46:18 +030058 except (AttributeError, ValueError) as exc:
59 log.exception('%s' % exc)
Oleksiy Petrenko95664c02018-04-19 17:05:16 +030060 e = NoAuthPluginConfigured()
61 log.exception('%s' % e)
62 raise e
63 if service_type not in endpoints:
64 if not service_type:
65 e = NoBarbicanEndpoint()
66 log.error('%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 try:
90 resp = response.json()
91 except:
92 resp = response.content
93 return resp
94 return wrapped_f
95 return wrap
96
97
98def _check_uuid(val):
99 try:
100 return str(UUID(val)).replace('-', '') == val
101 except (TypeError, ValueError, AttributeError):
102 return False
103
104
105def _parse_secret_href(href):
106 return urlsplit(href).path.split('/')[-1]
107
108
109def get_by_name_or_uuid(resource_list, resp_key):
110 def wrap(func):
111 def wrapped_f(*args, **kwargs):
112 if 'name' in kwargs:
113 ref = kwargs.pop('name', None)
114 start_arg = 0
115 else:
116 start_arg = 1
117 ref = args[0]
118 cloud_name = kwargs['cloud_name']
119 if _check_uuid(ref):
120 uuid = ref
121 else:
122 # Then we have name not uuid
123 resp = resource_list(
124 name=ref, cloud_name=cloud_name)[resp_key]
125 if len(resp) == 0:
126 raise ResourceNotFound(resp_key, ref)
127 elif len(resp) > 1:
128 raise MultipleResourcesFound(resp_key, ref)
129 href = resp[0]['secret_ref']
130 uuid = _parse_secret_href(href)
131 return func(uuid, *args[start_arg:], **kwargs)
132 return wrapped_f
133 return wrap