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