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
= "/vim_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
, "/vim_accounts")
48 # Wait for status for VIM instance creation/deletion
49 if isinstance(wait_time
, bool):
50 wait_time
= WaitForStatus
.TIMEOUT_VIM_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 self
._client
.get_token()
64 for vim
in self
.list():
65 if name
== vim
["uuid"] or name
== vim
["name"]:
75 sdn_port_mapping
=None,
81 vca
= self
._client
.vca
.get(vca
)
83 raise NotFound("cannot find vca '{}'".format(vca
))
86 self
._logger
.debug("")
87 self
._client
.get_token()
88 if "vca" in vim_access
:
89 vca_id
= get_vca_id(vim_access
["vca"])
90 if "vim-type" not in vim_access
:
91 # 'openstack' not in vim_access['vim-type']):
92 raise Exception("vim type not provided")
94 vim_account
["name"] = name
95 vim_account
= self
.update_vim_account_dict(vim_account
, vim_access
)
97 vim_account
["vca"] = vca_id
100 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
101 vim_config
["sdn-controller"] = sdnc
["_id"]
103 with
open(sdn_port_mapping
, "r") as f
:
104 vim_config
["sdn-port-mapping"] = yaml
.safe_load(f
.read())
106 vim_account
["config"] = vim_config
107 # vim_account['config'] = json.dumps(vim_config)
109 http_code
, resp
= self
._http
.post_cmd(
110 endpoint
=self
._apiBase
, postfields_dict
=vim_account
112 # print('HTTP CODE: {}'.format(http_code))
113 # print('RESP: {}'.format(resp))
114 # if http_code in (200, 201, 202, 204):
116 resp
= json
.loads(resp
)
117 if not resp
or "id" not in resp
:
118 raise ClientException("unexpected response from server - {}".format(resp
))
120 # Wait for status for VIM instance creation
121 self
._wait
(resp
.get("id"), wait
)
127 # msg = json.loads(resp)
130 # raise ClientException("failed to create vim {} - {}".format(name, msg))
141 self
._logger
.debug("")
142 self
._client
.get_token()
143 vim
= self
.get(vim_name
)
144 vim_id_for_wait
= self
._get
_id
_for
_wait
(vim_name
)
146 if config
is not None:
147 if not config
and (sdn_controller
or sdn_port_mapping
):
148 # If config is empty (clearing config)
149 raise ClientException(
150 "clearing config is incompatible with updating SDN info"
153 if sdn_controller
== "":
154 vim_config
["sdn-controller"] = None
155 vim_config
["sdn-port-mapping"] = None
158 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
159 vim_config
["sdn-controller"] = sdnc
["_id"]
161 with
open(sdn_port_mapping
, "r") as f
:
162 vim_config
["sdn-port-mapping"] = yaml
.safe_load(f
.read())
163 vim_account
["config"] = vim_config
164 # vim_account['config'] = json.dumps(vim_config)
165 http_code
, resp
= self
._http
.patch_cmd(
166 endpoint
="{}/{}".format(self
._apiBase
, vim
["_id"]),
167 postfields_dict
=vim_account
,
169 # print('HTTP CODE: {}'.format(http_code))
170 # print('RESP: {}'.format(resp))
171 # if http_code in (200, 201, 202, 204):
173 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
174 # Use the previously obtained id instead.
175 wait_id
= vim_id_for_wait
176 # Wait for status for VI instance update
177 self
._wait
(wait_id
, wait
)
184 # msg = json.loads(resp)
187 # raise ClientException("failed to update vim {} - {}".format(vim_name, msg))
189 def update_vim_account_dict(self
, vim_account
, vim_access
):
190 self
._logger
.debug("")
191 vim_account
["vim_type"] = vim_access
["vim-type"]
192 vim_account
["description"] = vim_access
["description"]
193 vim_account
["vim_url"] = vim_access
["vim-url"] or "null"
194 vim_account
["vim_user"] = vim_access
["vim-username"] or "null"
195 vim_account
["vim_password"] = vim_access
["vim-password"] or "null"
196 vim_account
["vim_tenant_name"] = vim_access
["vim-tenant-name"] or "null"
197 if "prometheus-config" in vim_access
:
198 vim_account
["prometheus-config"] = vim_access
["prometheus-config"]
201 def get_id(self
, name
):
202 """Returns a VIM id from a VIM name"""
203 self
._logger
.debug("")
204 for vim
in self
.list():
205 if name
== vim
["name"]:
207 raise NotFound("vim {} not found".format(name
))
209 def delete(self
, vim_name
, force
=False, wait
=False):
210 self
._logger
.debug("")
211 self
._client
.get_token()
213 if not utils
.validate_uuid4(vim_name
):
214 vim_id
= self
.get_id(vim_name
)
217 querystring
= "?FORCE=True"
218 http_code
, resp
= self
._http
.delete_cmd(
219 "{}/{}{}".format(self
._apiBase
, vim_id
, querystring
)
221 # print('HTTP CODE: {}'.format(http_code))
222 # print('RESP: {}'.format(resp))
225 # When deleting an account, 'resp' may be None.
226 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
229 resp
= json
.loads(resp
)
230 wait_id
= resp
.get("id")
231 # Wait for status for VIM account deletion
232 self
._wait
(wait_id
, wait
, deleteFlag
=True)
234 print("Deletion in progress")
235 elif http_code
== 204:
241 # msg = json.loads(resp)
244 raise ClientException("failed to delete vim {} - {}".format(vim_name
, msg
))
246 def list(self
, filter=None):
247 """Returns a list of VIM accounts"""
248 self
._logger
.debug("")
249 self
._client
.get_token()
252 filter_string
= "?{}".format(filter)
253 _
, resp
= self
._http
.get2_cmd("{}{}".format(self
._apiBase
, filter_string
))
256 vim_accounts
= json
.loads(resp
)
257 for datacenter
in vim_accounts
:
258 datacenter
["uuid"] = datacenter
.get("_id") # backward compatibility?
262 """Returns a VIM account based on name or id"""
263 self
._logger
.debug("")
264 self
._client
.get_token()
266 if not utils
.validate_uuid4(name
):
267 vim_id
= self
.get_id(name
)
269 _
, resp
= self
._http
.get2_cmd("{}/{}".format(self
._apiBase
, vim_id
))
271 resp
= json
.loads(resp
)
272 if not resp
or "_id" not in resp
:
273 raise ClientException("failed to get vim info: {}".format(resp
))
276 raise NotFound("vim '{}' not found".format(name
))