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