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"] or name
== wim
["name"]:
68 def create(self
, name
, wim_input
, wim_port_mapping
=None, wait
=False):
69 self
._logger
.debug("")
70 self
._client
.get_token()
71 if "wim_type" not in wim_input
:
72 raise Exception("wim type not provided")
74 wim_account
= wim_input
75 wim_account
["name"] = name
78 if "config" in wim_input
and wim_input
["config"] is not None:
79 wim_config
= yaml
.safe_load(wim_input
["config"])
81 with
open(wim_port_mapping
, "r") as f
:
82 wim_config
["wim_port_mapping"] = yaml
.safe_load(f
.read())
84 wim_account
["config"] = wim_config
85 # wim_account['config'] = json.dumps(wim_config)
87 http_code
, resp
= self
._http
.post_cmd(
88 endpoint
=self
._apiBase
, postfields_dict
=wim_account
90 # print('HTTP CODE: {}'.format(http_code))
91 # print('RESP: {}'.format(resp))
92 # if http_code in (200, 201, 202, 204):
94 resp
= json
.loads(resp
)
95 if not resp
or "id" not in resp
:
96 raise ClientException("unexpected response from server - {}".format(resp
))
98 # Wait for status for WIM instance creation
99 self
._wait
(resp
.get("id"), wait
)
105 # msg = json.loads(resp)
108 # raise ClientException("failed to create wim {} - {}".format(name, msg))
110 def update(self
, wim_name
, wim_account
, wim_port_mapping
=None, wait
=False):
111 self
._logger
.debug("")
112 self
._client
.get_token()
113 wim
= self
.get(wim_name
)
114 wim_id_for_wait
= self
._get
_id
_for
_wait
(wim_name
)
116 if "config" in wim_account
:
117 if wim_account
.get("config") == "" and (wim_port_mapping
):
118 raise ClientException(
119 "clearing config is incompatible with updating SDN info"
121 if wim_account
.get("config") == "":
124 wim_config
= yaml
.safe_load(wim_account
["config"])
126 with
open(wim_port_mapping
, "r") as f
:
127 wim_config
["wim_port_mapping"] = yaml
.safe_load(f
.read())
128 wim_account
["config"] = wim_config
129 # wim_account['config'] = json.dumps(wim_config)
130 http_code
, resp
= self
._http
.patch_cmd(
131 endpoint
="{}/{}".format(self
._apiBase
, wim
["_id"]),
132 postfields_dict
=wim_account
,
134 # print('HTTP CODE: {}'.format(http_code))
135 # print('RESP: {}'.format(resp))
136 # if http_code in (200, 201, 202, 204):
138 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
139 # Use the previously obtained id instead.
140 wait_id
= wim_id_for_wait
141 # Wait for status for WIM instance update
142 self
._wait
(wait_id
, wait
)
149 # msg = json.loads(resp)
152 # raise ClientException("failed to update wim {} - {}".format(wim_name, msg))
154 def update_wim_account_dict(self
, wim_account
, wim_input
):
155 self
._logger
.debug("")
156 self
._logger
.debug(str(wim_input
))
157 wim_account
["wim_type"] = wim_input
["wim_type"]
158 wim_account
["description"] = wim_input
["description"]
159 wim_account
["wim_url"] = wim_input
["url"]
160 wim_account
["user"] = wim_input
.get("wim-username")
161 wim_account
["password"] = wim_input
.get("wim-password")
164 def get_id(self
, name
):
165 """Returns a WIM id from a WIM name"""
166 self
._logger
.debug("")
167 for wim
in self
.list():
168 if name
== wim
["name"]:
170 raise NotFound("wim {} not found".format(name
))
172 def delete(self
, wim_name
, force
=False, wait
=False):
173 self
._logger
.debug("")
174 self
._client
.get_token()
176 wim_id_for_wait
= self
._get
_id
_for
_wait
(wim_name
)
177 if not utils
.validate_uuid4(wim_name
):
178 wim_id
= self
.get_id(wim_name
)
181 querystring
= "?FORCE=True"
182 http_code
, resp
= self
._http
.delete_cmd(
183 "{}/{}{}".format(self
._apiBase
, wim_id
, querystring
)
185 # print('HTTP CODE: {}'.format(http_code))
186 # print('RESP: {}'.format(resp))
187 # print('WIM_ID: {}'.format(wim_id))
190 # 'resp' may be None.
191 # In that case, 'resp['id']' cannot be used, so use the previously obtained id instead
192 wait_id
= wim_id_for_wait
194 resp
= json
.loads(resp
)
195 wait_id
= resp
.get("id")
196 # Wait for status for WIM account deletion
197 self
._wait
(wait_id
, wait
, deleteFlag
=True)
199 print("Deletion in progress")
200 elif http_code
== 204:
206 # msg = json.loads(resp)
209 raise ClientException("failed to delete wim {} - {}".format(wim_name
, msg
))
211 def list(self
, filter=None):
212 """Returns a list of VIM accounts"""
213 self
._logger
.debug("")
214 self
._client
.get_token()
217 filter_string
= "?{}".format(filter)
218 _
, resp
= self
._http
.get2_cmd("{}{}".format(self
._apiBase
, filter_string
))
222 for datacenter
in json
.loads(resp
):
225 "name": datacenter
["name"],
226 "uuid": datacenter
["_id"] if "_id" in datacenter
else None,
232 """Returns a VIM account based on name or id"""
233 self
._logger
.debug("")
234 self
._client
.get_token()
236 if not utils
.validate_uuid4(name
):
237 wim_id
= self
.get_id(name
)
239 _
, resp
= self
._http
.get2_cmd("{}/{}".format(self
._apiBase
, wim_id
))
241 resp
= json
.loads(resp
)
242 if not resp
or "_id" not in resp
:
243 raise ClientException("failed to get wim info: {}".format(resp
))
246 raise NotFound("wim '{}' not found".format(name
))