1 # Copyright 2018 Telefonica
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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
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
31 def __init__(self
, http
=None, client
=None):
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
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(
57 deleteFlag
=deleteFlag
,
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"]:
66 for wim
in self
.list():
67 if name
== wim
["name"]:
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")
77 wim_account
= wim_input
78 wim_account
["name"] = name
81 if "config" in wim_input
and wim_input
["config"] is not None:
82 wim_config
= yaml
.safe_load(wim_input
["config"])
84 with
open(wim_port_mapping
, "r") as f
:
85 wim_config
["wim_port_mapping"] = yaml
.safe_load(f
.read())
87 wim_account
["config"] = wim_config
88 # wim_account['config'] = json.dumps(wim_config)
90 http_code
, resp
= self
._http
.post_cmd(
91 endpoint
=self
._apiBase
, postfields_dict
=wim_account
93 # print('HTTP CODE: {}'.format(http_code))
94 # print('RESP: {}'.format(resp))
95 # if http_code in (200, 201, 202, 204):
97 resp
= json
.loads(resp
)
98 if not resp
or "id" not in resp
:
99 raise ClientException("unexpected response from server - {}".format(resp
))
101 # Wait for status for WIM instance creation
102 self
._wait
(resp
.get("id"), wait
)
108 # msg = json.loads(resp)
111 # raise ClientException("failed to create wim {} - {}".format(name, msg))
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
)
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"
124 if wim_account
.get("config") == "":
127 wim_config
= yaml
.safe_load(wim_account
["config"])
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
,
137 # print('HTTP CODE: {}'.format(http_code))
138 # print('RESP: {}'.format(resp))
139 # if http_code in (200, 201, 202, 204):
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
)
152 # msg = json.loads(resp)
155 # raise ClientException("failed to update wim {} - {}".format(wim_name, msg))
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")
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"]:
173 raise NotFound("wim {} not found".format(name
))
175 def delete(self
, wim_name
, force
=False, wait
=False):
176 self
._logger
.debug("")
177 self
._client
.get_token()
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
)
184 querystring
= "?FORCE=True"
185 http_code
, resp
= self
._http
.delete_cmd(
186 "{}/{}{}".format(self
._apiBase
, wim_id
, querystring
)
188 # print('HTTP CODE: {}'.format(http_code))
189 # print('RESP: {}'.format(resp))
190 # print('WIM_ID: {}'.format(wim_id))
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
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)
202 print("Deletion in progress")
203 elif http_code
== 204:
209 # msg = json.loads(resp)
212 raise ClientException("failed to delete wim {} - {}".format(wim_name
, msg
))
214 def list(self
, filter=None):
215 """Returns a list of VIM accounts"""
216 self
._logger
.debug("")
217 self
._client
.get_token()
220 filter_string
= "?{}".format(filter)
221 _
, resp
= self
._http
.get2_cmd("{}{}".format(self
._apiBase
, filter_string
))
225 for datacenter
in json
.loads(resp
):
228 "name": datacenter
["name"],
229 "uuid": datacenter
["_id"] if "_id" in datacenter
else None,
235 """Returns a VIM account based on name or id"""
236 self
._logger
.debug("")
237 self
._client
.get_token()
239 if not utils
.validate_uuid4(name
):
240 wim_id
= self
.get_id(name
)
242 _
, resp
= self
._http
.get2_cmd("{}/{}".format(self
._apiBase
, wim_id
))
244 resp
= json
.loads(resp
)
245 if not resp
or "_id" not in resp
:
246 raise ClientException("failed to get wim info: {}".format(resp
))
249 raise NotFound("wim '{}' not found".format(name
))