blob: a7e62209d8e275e26d30f9367939ccf9c998838d [file] [log] [blame]
kairat_kushaev5c8626d2018-06-09 18:15:15 +04001import six
2import logging
3import uuid
4
5import os_client_config
6from salt import exceptions
7
8
9log = logging.getLogger(__name__)
10
11SERVICE_KEY = 'volumev3'
12
13
14def get_raw_client(cloud_name):
15 config = os_client_config.OpenStackConfig()
16 cloud = config.get_one_cloud(cloud_name)
17 adapter = cloud.get_session_client(SERVICE_KEY)
kairat_kushaev5c8626d2018-06-09 18:15:15 +040018 try:
19 access_info = adapter.session.auth.get_access(adapter.session)
20 endpoints = access_info.service_catalog.get_endpoints()
21 except (AttributeError, ValueError) as exc:
22 six.raise_from(exc, exceptions.SaltInvocationError(
23 "Cannot load keystoneauth plugin. Please check your environment "
24 "configuration."))
25 if SERVICE_KEY not in endpoints:
26 raise exceptions.SaltInvocationError("Cannot find cinder endpoint in "
27 "environment endpoint list.")
28 return adapter
29
30
31def send(method):
32 def wrap(func):
33 @six.wraps(func)
34 def wrapped_f(*args, **kwargs):
35 cloud_name = kwargs.pop('cloud_name', None)
36 if not cloud_name:
37 raise exceptions.SaltInvocationError(
38 "No cloud_name specified. Please provide cloud_name "
39 "parameter")
40 adapter = get_raw_client(cloud_name)
41 kwarg_keys = list(kwargs.keys())
42 for k in kwarg_keys:
43 if k.startswith('__'):
44 kwargs.pop(k)
45 url, request_kwargs = func(*args, **kwargs)
46 try:
47 response = getattr(adapter, method.lower())(url,
48 **request_kwargs)
49 except Exception as e:
50 log.exception("Error occured when executing request")
51 return {"result": False,
52 "comment": str(e),
53 "status_code": getattr(e, "http_status", 500)}
54 return {"result": True,
55 "body": response.json() if response.content else {},
56 "status_code": response.status_code}
57 return wrapped_f
58 return wrap
59
60
61def _check_uuid(val):
62 try:
63 return str(uuid.UUID(val)) == val
64 except (TypeError, ValueError, AttributeError):
65 return False
66
67
68def get_by_name_or_uuid(resource_list, resp_key):
69 def wrap(func):
70 @six.wraps(func)
71 def wrapped_f(*args, **kwargs):
72 if 'name' in kwargs:
73 ref = kwargs.pop('name', None)
74 start_arg = 0
75 else:
76 start_arg = 1
77 ref = args[0]
78 item_id = None
79 if _check_uuid(ref):
80 item_id = ref
81 else:
82 cloud_name = kwargs['cloud_name']
83 # seems no filtering on volume type name in cinder
84 resp = resource_list(cloud_name=cloud_name)["body"][resp_key]
85 # so need to search in list directly
86 for item in resp:
87 if item["name"] == ref:
88 if item_id is not None:
89 msg = ("Multiple resource: {resource} "
90 "with name: {name} found ").format(
91 resource=resp_key, name=ref)
92 return {"result": False,
93 "body": msg,
94 "status_code": 400}
95 item_id = item["id"]
96 if not item_id:
97 msg = ("Uniq {resource} resource "
98 "with name={name} not found.").format(
99 resource=resp_key, name=ref)
100 return {"result": False,
101 "body": msg,
102 "status_code": 404}
103 return func(item_id, *args[start_arg:], **kwargs)
104 return wrapped_f
105 return wrap