blob: 3859ca7e47191563593badeea68e7e8ee7b23d06 [file] [log] [blame]
kairat_kushaev66852622018-06-07 17:27:35 +04001import logging
2import six
3import uuid
4
Pavlo Shchelokovskyye2542a52019-01-30 10:46:52 +02005try:
6 import os_client_config
7except ImportError:
8 os_client_config = None
kairat_kushaev66852622018-06-07 17:27:35 +04009from salt import exceptions
10
11
12log = logging.getLogger(__name__)
13
14SERVICE_KEY = 'orchestration'
15
16
17def get_raw_client(cloud_name):
Pavlo Shchelokovskyye2542a52019-01-30 10:46:52 +020018 if not os_client_config:
19 raise exceptions.SaltInvocationError(
20 "Cannot load os-client-config. Please check your environment "
21 "configuration.")
kairat_kushaev66852622018-06-07 17:27:35 +040022 config = os_client_config.OpenStackConfig()
23 cloud = config.get_one_cloud(cloud_name)
24 adapter = cloud.get_session_client(SERVICE_KEY)
25 adapter.version = '1'
26 try:
27 access_info = adapter.session.auth.get_access(adapter.session)
28 endpoints = access_info.service_catalog.get_endpoints()
29 except (AttributeError, ValueError) as exc:
30 six.raise_from(exc, exceptions.SaltInvocationError(
31 "Cannot load keystoneauth plugin. Please check your environment "
32 "configuration."))
33 if SERVICE_KEY not in endpoints:
34 raise exceptions.SaltInvocationError("Cannot find heat endpoint in "
35 "environment endpoint list.")
36 return adapter
37
38
39def send(method):
40 def wrap(func):
41 @six.wraps(func)
42 def wrapped_f(*args, **kwargs):
43 cloud_name = kwargs.get('cloud_name', None)
44 if not cloud_name:
45 raise exceptions.SaltInvocationError(
46 "No cloud_name specified. Please provide cloud_name "
47 "parameter")
48 adapter = get_raw_client(cloud_name)
49 # Remove salt internal kwargs
50 kwarg_keys = list(kwargs.keys())
51 for k in kwarg_keys:
52 if k.startswith('__'):
53 kwargs.pop(k)
54 url, request_kwargs = func(*args, **kwargs)
55 try:
56 response = getattr(adapter, method.lower())(url,
57 **request_kwargs)
58 except Exception as e:
59 log.exception("Error occured when executing request")
60 return {"result": False,
61 "comment": str(e),
62 "status_code": getattr(e, "http_status", 500)}
63 try:
64 resp_body = response.json() if response.content else {}
65 except:
66 resp_body = str(response.content)
67 return {"result": True,
68 "body": resp_body,
69 "status_code": response.status_code}
70 return wrapped_f
71 return wrap
72
73
74def _check_uuid(val):
75 try:
76 return str(uuid.UUID(val)) == val
77 except (TypeError, ValueError, AttributeError):
78 return False
79
80
81def get_by_name_or_uuid(resource_list, resp_key):
82 def wrap(func):
83 @six.wraps(func)
84 def wrapped_f(*args, **kwargs):
85 if 'name' in kwargs:
86 ref = kwargs.get('name', None)
87 start_arg = 0
88 else:
89 start_arg = 1
90 ref = args[0]
91 kwargs["name"] = ref
92 if _check_uuid(ref):
93 uuid = ref
94 else:
95 # Then we have name not uuid
96 cloud_name = kwargs['cloud_name']
97 resp = resource_list(
98 name=ref, cloud_name=cloud_name)["body"][resp_key]
99 if len(resp) == 0:
100 msg = ("Uniq {resource} resource "
101 "with name={name} not found.").format(
102 resource=resp_key, name=ref)
103 return {"result": False,
104 "body": msg,
105 "status_code": 404}
106 elif len(resp) > 1:
107 msg = ("Multiple resource: {resource} "
108 "with name: {name} found ").format(
109 resource=resp_key, name=ref)
110 return {"result": False,
111 "body": msg,
112 "status_code": 400}
113 uuid = resp[0]['id']
114 return func(uuid, *args[start_arg:], **kwargs)
115 return wrapped_f
Pavlo Shchelokovskyye2542a52019-01-30 10:46:52 +0200116 return wrap