blob: a75c26fb77176c0aec0b45afa435d652e85ca32a [file] [log] [blame]
Mykyta Karpinfa53b302018-06-13 14:52:16 +03001import logging
Mykyta Karpinfa53b302018-06-13 14:52:16 +03002from uuid import UUID
3
Oleksiy Petrenko24394b32019-02-06 12:58:52 +02004try:
5 import os_client_config
6except ImportError:
7 os_client_config = None
8from salt import exceptions
9
Mykyta Karpinfa53b302018-06-13 14:52:16 +030010log = logging.getLogger(__name__)
11
12
13class GnocchiException(Exception):
14
15 _msg = "Gnocchi module exception occured."
16
17 def __init__(self, message=None, **kwargs):
18 super(GnocchiException, self).__init__(message or self._msg)
19
20
21class NoGnocchiEndpoint(GnocchiException):
22 _msg = "Gnocchi endpoint not found in keystone catalog."
23
24
25class NoAuthPluginConfigured(GnocchiException):
26 _msg = ("You are using keystoneauth auth plugin that does not support "
27 "fetching endpoint list from token (noauth or admin_token).")
28
29
30class NoCredentials(GnocchiException):
31 _msg = "Please provide cloud name present in clouds.yaml."
32
33
34class ResourceNotFound(GnocchiException):
35 _msg = "Uniq resource: {resource} with name: {name} not found."
36
37 def __init__(self, resource, name, **kwargs):
38 super(GnocchiException, self).__init__(
39 self._msg.format(resource=resource, name=name))
40
41
42class MultipleResourcesFound(GnocchiException):
43 _msg = "Multiple resource: {resource} with name: {name} found."
44
45 def __init__(self, resource, name, **kwargs):
46 super(GnocchiException, self).__init__(
47 self._msg.format(resource=resource, name=name))
48
49
50def get_raw_client(cloud_name):
Oleksiy Petrenko24394b32019-02-06 12:58:52 +020051 if not os_client_config:
52 raise exceptions.SaltInvocationError(
53 "Cannot load os-client-config. Please check your environment "
54 "configuration.")
Mykyta Karpinfa53b302018-06-13 14:52:16 +030055 service_type = 'metric'
56 config = os_client_config.OpenStackConfig()
57 cloud = config.get_one_cloud(cloud_name)
Mykyta Karpinfbefb702018-07-10 16:28:22 +030058 api_version = '1'
59 try:
60 # NOTE(pas-ha) for Queens and later,
61 # 'version' kwarg in absent for Pike and older
62 adapter = cloud.get_session_client(service_type, version=api_version)
63 except TypeError:
64 adapter = cloud.get_session_client(service_type)
65 adapter.version = api_version
Mykyta Karpinfa53b302018-06-13 14:52:16 +030066 try:
67 access_info = adapter.session.auth.get_access(adapter.session)
68 endpoints = access_info.service_catalog.get_endpoints()
69 except (AttributeError, ValueError) as exc:
70 log.exception('%s' % exc)
71 e = NoAuthPluginConfigured()
72 log.exception('%s' % e)
73 raise e
74 if service_type not in endpoints:
75 if not service_type:
76 e = NoGnocchiEndpoint()
77 log.error('%s' % e)
78 raise e
79 return adapter
80
81
82def send(method):
83 def wrap(func):
84 def wrapped_f(*args, **kwargs):
85 cloud_name = kwargs.pop('cloud_name')
86 if not cloud_name:
87 e = NoCredentials()
88 log.error('%s' % e)
89 raise e
90 adapter = get_raw_client(cloud_name)
91 # Remove salt internal kwargs
92 kwarg_keys = list(kwargs.keys())
93 for k in kwarg_keys:
94 if k.startswith('__'):
95 kwargs.pop(k)
96 url, request_kwargs = func(*args, **kwargs)
97 response = getattr(adapter, method)(url, **request_kwargs)
98 if not response.content:
99 return {}
100 return response.json()
101 return wrapped_f
102 return wrap
103
104
105def _check_uuid(val):
106 try:
107 return str(UUID(val)).replace('-', '') == val.replace('-', '')
108 except (TypeError, ValueError, AttributeError):
109 return False
110
111
112def get_by_name_or_uuid(resource_list, resp_key):
113 def wrap(func):
114 def wrapped_f(*args, **kwargs):
115 if 'name' in kwargs:
116 ref = kwargs.pop('name', None)
117 start_arg = 0
118 else:
119 start_arg = 1
120 ref = args[0]
121 if _check_uuid(ref):
122 uuid = ref
123 else:
124 # Then we have name not uuid
125 cloud_name = kwargs['cloud_name']
126 resp = resource_list(
127 name=ref, cloud_name=cloud_name)[resp_key]
128 if len(resp) == 0:
129 raise ResourceNotFound(resp_key, ref)
130 elif len(resp) > 1:
131 raise MultipleResourcesFound(resp_key, ref)
132 uuid = resp[0]['id']
133 return func(uuid, *args[start_arg:], **kwargs)
134 return wrapped_f
135 return wrap