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"]:
67 for vim
in self
.list():
68 if name
== vim
["name"]:
78 sdn_port_mapping
=None,
84 vca
= self
._client
.vca
.get(vca
)
86 raise NotFound("cannot find vca '{}'".format(vca
))
89 self
._logger
.debug("")
90 self
._client
.get_token()
91 if "vca" in vim_access
:
92 vca_id
= get_vca_id(vim_access
["vca"])
93 if "vim-type" not in vim_access
:
94 # 'openstack' not in vim_access['vim-type']):
95 raise Exception("vim type not provided")
97 vim_account
["name"] = name
98 vim_account
= self
.update_vim_account_dict(vim_account
, vim_access
)
100 vim_account
["vca"] = vca_id
103 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
104 vim_config
["sdn-controller"] = sdnc
["_id"]
106 with
open(sdn_port_mapping
, "r") as f
:
107 vim_config
["sdn-port-mapping"] = yaml
.safe_load(f
.read())
109 vim_account
["config"] = vim_config
110 # vim_account['config'] = json.dumps(vim_config)
112 http_code
, resp
= self
._http
.post_cmd(
113 endpoint
=self
._apiBase
, postfields_dict
=vim_account
115 # print('HTTP CODE: {}'.format(http_code))
116 # print('RESP: {}'.format(resp))
117 # if http_code in (200, 201, 202, 204):
119 resp
= json
.loads(resp
)
120 if not resp
or "id" not in resp
:
121 raise ClientException("unexpected response from server - {}".format(resp
))
123 # Wait for status for VIM instance creation
124 self
._wait
(resp
.get("id"), wait
)
130 # msg = json.loads(resp)
133 # raise ClientException("failed to create vim {} - {}".format(name, msg))
144 self
._logger
.debug("")
145 self
._client
.get_token()
146 vim
= self
.get(vim_name
)
147 vim_id_for_wait
= self
._get
_id
_for
_wait
(vim_name
)
149 if config
is not None:
150 if not config
and (sdn_controller
or sdn_port_mapping
):
151 # If config is empty (clearing config)
152 raise ClientException(
153 "clearing config is incompatible with updating SDN info"
156 if sdn_controller
== "":
157 vim_config
["sdn-controller"] = None
158 vim_config
["sdn-port-mapping"] = None
161 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
162 vim_config
["sdn-controller"] = sdnc
["_id"]
164 with
open(sdn_port_mapping
, "r") as f
:
165 vim_config
["sdn-port-mapping"] = yaml
.safe_load(f
.read())
166 vim_account
["config"] = vim_config
167 # vim_account['config'] = json.dumps(vim_config)
168 http_code
, resp
= self
._http
.patch_cmd(
169 endpoint
="{}/{}".format(self
._apiBase
, vim
["_id"]),
170 postfields_dict
=vim_account
,
172 # print('HTTP CODE: {}'.format(http_code))
173 # print('RESP: {}'.format(resp))
174 # if http_code in (200, 201, 202, 204):
176 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
177 # Use the previously obtained id instead.
178 wait_id
= vim_id_for_wait
179 # Wait for status for VI instance update
180 self
._wait
(wait_id
, wait
)
187 # msg = json.loads(resp)
190 # raise ClientException("failed to update vim {} - {}".format(vim_name, msg))
192 def update_vim_account_dict(self
, vim_account
, vim_access
):
193 self
._logger
.debug("")
194 vim_account
["vim_type"] = vim_access
["vim-type"]
195 vim_account
["description"] = vim_access
["description"]
196 vim_account
["vim_url"] = vim_access
["vim-url"] or "null"
197 vim_account
["vim_user"] = vim_access
["vim-username"] or "null"
198 vim_account
["vim_password"] = vim_access
["vim-password"] or "null"
199 vim_account
["vim_tenant_name"] = vim_access
["vim-tenant-name"] or "null"
200 if "prometheus-config" in vim_access
:
201 vim_account
["prometheus-config"] = vim_access
["prometheus-config"]
204 def get_id(self
, name
):
205 """Returns a VIM id from a VIM name"""
206 self
._logger
.debug("")
207 for vim
in self
.list():
208 if name
== vim
["name"]:
210 raise NotFound("vim {} not found".format(name
))
212 def delete(self
, vim_name
, force
=False, wait
=False):
213 self
._logger
.debug("")
214 self
._client
.get_token()
216 if not utils
.validate_uuid4(vim_name
):
217 vim_id
= self
.get_id(vim_name
)
220 querystring
= "?FORCE=True"
221 http_code
, resp
= self
._http
.delete_cmd(
222 "{}/{}{}".format(self
._apiBase
, vim_id
, querystring
)
224 # print('HTTP CODE: {}'.format(http_code))
225 # print('RESP: {}'.format(resp))
228 # When deleting an account, 'resp' may be None.
229 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
232 resp
= json
.loads(resp
)
233 wait_id
= resp
.get("id")
234 # Wait for status for VIM account deletion
235 self
._wait
(wait_id
, wait
, deleteFlag
=True)
237 print("Deletion in progress")
238 elif http_code
== 204:
244 # msg = json.loads(resp)
247 raise ClientException("failed to delete vim {} - {}".format(vim_name
, msg
))
249 def list(self
, filter=None):
250 """Returns a list of VIM accounts"""
251 self
._logger
.debug("")
252 self
._client
.get_token()
255 filter_string
= "?{}".format(filter)
256 _
, resp
= self
._http
.get2_cmd("{}{}".format(self
._apiBase
, filter_string
))
259 vim_accounts
= json
.loads(resp
)
260 for datacenter
in vim_accounts
:
261 datacenter
["uuid"] = datacenter
.get("_id") # backward compatibility?
265 """Returns a VIM account based on name or id"""
266 self
._logger
.debug("")
267 self
._client
.get_token()
269 if not utils
.validate_uuid4(name
):
270 vim_id
= self
.get_id(name
)
272 _
, resp
= self
._http
.get2_cmd("{}/{}".format(self
._apiBase
, vim_id
))
274 resp
= json
.loads(resp
)
275 if not resp
or "_id" not in resp
:
276 raise ClientException("failed to get vim info: {}".format(resp
))
279 raise NotFound("vim '{}' not found".format(name
))