Standardize Formatting
[osm/osmclient.git] / osmclient / sol005 / wim.py
1 # Copyright 2018 Telefonica
2 #
3 # All Rights Reserved.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
15 # under the License.
16
17 """
18 OSM wim API handling
19 """
20
21 from osmclient.common import utils
22 from osmclient.common import wait as WaitForStatus
23 from osmclient.common.exceptions import ClientException
24 from osmclient.common.exceptions import NotFound
25 import yaml
26 import json
27 import logging
28
29
30 class Wim(object):
31 def __init__(self, http=None, client=None):
32 self._http = http
33 self._client = client
34 self._logger = logging.getLogger("osmclient")
35 self._apiName = "/admin"
36 self._apiVersion = "/v1"
37 self._apiResource = "/wim_accounts"
38 self._apiBase = "{}{}{}".format(
39 self._apiName, self._apiVersion, self._apiResource
40 )
41
42 # WIM '--wait' option
43 def _wait(self, id, wait_time, deleteFlag=False):
44 self._logger.debug("")
45 self._client.get_token()
46 # Endpoint to get operation status
47 apiUrlStatus = "{}{}{}".format(self._apiName, self._apiVersion, "/wim_accounts")
48 # Wait for status for WIM instance creation/deletion
49 if isinstance(wait_time, bool):
50 wait_time = WaitForStatus.TIMEOUT_WIM_OPERATION
51 WaitForStatus.wait_for_status(
52 "WIM",
53 str(id),
54 wait_time,
55 apiUrlStatus,
56 self._http.get2_cmd,
57 deleteFlag=deleteFlag,
58 )
59
60 def _get_id_for_wait(self, name):
61 """Returns id of name, or the id itself if given as argument"""
62 self._logger.debug("")
63 for wim in self.list():
64 if name == wim["uuid"]:
65 return wim["uuid"]
66 for wim in self.list():
67 if name == wim["name"]:
68 return wim["uuid"]
69 return ""
70
71 def create(self, name, wim_input, wim_port_mapping=None, wait=False):
72 self._logger.debug("")
73 self._client.get_token()
74 if "wim_type" not in wim_input:
75 raise Exception("wim type not provided")
76
77 wim_account = wim_input
78 wim_account["name"] = name
79
80 wim_config = {}
81 if "config" in wim_input and wim_input["config"] is not None:
82 wim_config = yaml.safe_load(wim_input["config"])
83 if wim_port_mapping:
84 with open(wim_port_mapping, "r") as f:
85 wim_config["wim_port_mapping"] = yaml.safe_load(f.read())
86 if wim_config:
87 wim_account["config"] = wim_config
88 # wim_account['config'] = json.dumps(wim_config)
89
90 http_code, resp = self._http.post_cmd(
91 endpoint=self._apiBase, postfields_dict=wim_account
92 )
93 # print('HTTP CODE: {}'.format(http_code))
94 # print('RESP: {}'.format(resp))
95 # if http_code in (200, 201, 202, 204):
96 if resp:
97 resp = json.loads(resp)
98 if not resp or "id" not in resp:
99 raise ClientException("unexpected response from server - {}".format(resp))
100 if wait:
101 # Wait for status for WIM instance creation
102 self._wait(resp.get("id"), wait)
103 print(resp["id"])
104 # else:
105 # msg = ""
106 # if resp:
107 # try:
108 # msg = json.loads(resp)
109 # except ValueError:
110 # msg = resp
111 # raise ClientException("failed to create wim {} - {}".format(name, msg))
112
113 def update(self, wim_name, wim_account, wim_port_mapping=None, wait=False):
114 self._logger.debug("")
115 self._client.get_token()
116 wim = self.get(wim_name)
117 wim_id_for_wait = self._get_id_for_wait(wim_name)
118 wim_config = {}
119 if "config" in wim_account:
120 if wim_account.get("config") == "" and (wim_port_mapping):
121 raise ClientException(
122 "clearing config is incompatible with updating SDN info"
123 )
124 if wim_account.get("config") == "":
125 wim_config = None
126 else:
127 wim_config = yaml.safe_load(wim_account["config"])
128 if wim_port_mapping:
129 with open(wim_port_mapping, "r") as f:
130 wim_config["wim_port_mapping"] = yaml.safe_load(f.read())
131 wim_account["config"] = wim_config
132 # wim_account['config'] = json.dumps(wim_config)
133 http_code, resp = self._http.patch_cmd(
134 endpoint="{}/{}".format(self._apiBase, wim["_id"]),
135 postfields_dict=wim_account,
136 )
137 # print('HTTP CODE: {}'.format(http_code))
138 # print('RESP: {}'.format(resp))
139 # if http_code in (200, 201, 202, 204):
140 if wait:
141 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
142 # Use the previously obtained id instead.
143 wait_id = wim_id_for_wait
144 # Wait for status for WIM instance update
145 self._wait(wait_id, wait)
146 # else:
147 # pass
148 # else:
149 # msg = ""
150 # if resp:
151 # try:
152 # msg = json.loads(resp)
153 # except ValueError:
154 # msg = resp
155 # raise ClientException("failed to update wim {} - {}".format(wim_name, msg))
156
157 def update_wim_account_dict(self, wim_account, wim_input):
158 self._logger.debug("")
159 self._logger.debug(str(wim_input))
160 wim_account["wim_type"] = wim_input["wim_type"]
161 wim_account["description"] = wim_input["description"]
162 wim_account["wim_url"] = wim_input["url"]
163 wim_account["user"] = wim_input.get("wim-username")
164 wim_account["password"] = wim_input.get("wim-password")
165 return wim_account
166
167 def get_id(self, name):
168 """Returns a WIM id from a WIM name"""
169 self._logger.debug("")
170 for wim in self.list():
171 if name == wim["name"]:
172 return wim["uuid"]
173 raise NotFound("wim {} not found".format(name))
174
175 def delete(self, wim_name, force=False, wait=False):
176 self._logger.debug("")
177 self._client.get_token()
178 wim_id = wim_name
179 wim_id_for_wait = self._get_id_for_wait(wim_name)
180 if not utils.validate_uuid4(wim_name):
181 wim_id = self.get_id(wim_name)
182 querystring = ""
183 if force:
184 querystring = "?FORCE=True"
185 http_code, resp = self._http.delete_cmd(
186 "{}/{}{}".format(self._apiBase, wim_id, querystring)
187 )
188 # print('HTTP CODE: {}'.format(http_code))
189 # print('RESP: {}'.format(resp))
190 # print('WIM_ID: {}'.format(wim_id))
191 if http_code == 202:
192 if wait:
193 # 'resp' may be None.
194 # In that case, 'resp['id']' cannot be used, so use the previously obtained id instead
195 wait_id = wim_id_for_wait
196 if resp:
197 resp = json.loads(resp)
198 wait_id = resp.get("id")
199 # Wait for status for WIM account deletion
200 self._wait(wait_id, wait, deleteFlag=True)
201 else:
202 print("Deletion in progress")
203 elif http_code == 204:
204 print("Deleted")
205 else:
206 msg = resp or ""
207 # if resp:
208 # try:
209 # msg = json.loads(resp)
210 # except ValueError:
211 # msg = resp
212 raise ClientException("failed to delete wim {} - {}".format(wim_name, msg))
213
214 def list(self, filter=None):
215 """Returns a list of VIM accounts"""
216 self._logger.debug("")
217 self._client.get_token()
218 filter_string = ""
219 if filter:
220 filter_string = "?{}".format(filter)
221 _, resp = self._http.get2_cmd("{}{}".format(self._apiBase, filter_string))
222 if not resp:
223 return list()
224 wim_accounts = []
225 for datacenter in json.loads(resp):
226 wim_accounts.append(
227 {
228 "name": datacenter["name"],
229 "uuid": datacenter["_id"] if "_id" in datacenter else None,
230 }
231 )
232 return wim_accounts
233
234 def get(self, name):
235 """Returns a VIM account based on name or id"""
236 self._logger.debug("")
237 self._client.get_token()
238 wim_id = name
239 if not utils.validate_uuid4(name):
240 wim_id = self.get_id(name)
241 try:
242 _, resp = self._http.get2_cmd("{}/{}".format(self._apiBase, wim_id))
243 if resp:
244 resp = json.loads(resp)
245 if not resp or "_id" not in resp:
246 raise ClientException("failed to get wim info: {}".format(resp))
247 return resp
248 except NotFound:
249 raise NotFound("wim '{}' not found".format(name))