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"]:
73 self
, name
, vim_access
, sdn_controller
=None, sdn_port_mapping
=None, wait
=False
78 vca
= self
._client
.vca
.get(vca
)
80 raise NotFound("cannot find vca '{}'".format(vca
))
83 self
._logger
.debug("")
84 self
._client
.get_token()
85 if "vca" in vim_access
:
86 vca_id
= get_vca_id(vim_access
["vca"])
87 if "vim-type" not in vim_access
:
88 # 'openstack' not in vim_access['vim-type']):
89 raise Exception("vim type not provided")
91 vim_account
["name"] = name
92 vim_account
= self
.update_vim_account_dict(vim_account
, vim_access
)
94 vim_account
["vca"] = vca_id
96 if "config" in vim_access
and vim_access
["config"] is not None:
97 vim_config
= yaml
.safe_load(vim_access
["config"])
99 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
100 vim_config
["sdn-controller"] = sdnc
["_id"]
102 with
open(sdn_port_mapping
, "r") as f
:
103 vim_config
["sdn-port-mapping"] = yaml
.safe_load(f
.read())
105 vim_account
["config"] = vim_config
106 # vim_account['config'] = json.dumps(vim_config)
108 http_code
, resp
= self
._http
.post_cmd(
109 endpoint
=self
._apiBase
, postfields_dict
=vim_account
111 # print('HTTP CODE: {}'.format(http_code))
112 # print('RESP: {}'.format(resp))
113 # if http_code in (200, 201, 202, 204):
115 resp
= json
.loads(resp
)
116 if not resp
or "id" not in resp
:
117 raise ClientException("unexpected response from server - {}".format(resp
))
119 # Wait for status for VIM instance creation
120 self
._wait
(resp
.get("id"), wait
)
126 # msg = json.loads(resp)
129 # raise ClientException("failed to create vim {} - {}".format(name, msg))
132 self
, vim_name
, vim_account
, sdn_controller
, sdn_port_mapping
, wait
=False
134 self
._logger
.debug("")
135 self
._client
.get_token()
136 vim
= self
.get(vim_name
)
137 vim_id_for_wait
= self
._get
_id
_for
_wait
(vim_name
)
139 if "config" in vim_account
:
140 if vim_account
.get("config") == "" and (sdn_controller
or sdn_port_mapping
):
141 raise ClientException(
142 "clearing config is incompatible with updating SDN info"
144 if vim_account
.get("config") == "":
147 vim_config
= yaml
.safe_load(vim_account
["config"])
148 if sdn_controller
== "":
149 vim_config
["sdn-controller"] = None
150 vim_config
["sdn-port-mapping"] = None
153 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
154 vim_config
["sdn-controller"] = sdnc
["_id"]
156 with
open(sdn_port_mapping
, "r") as f
:
157 vim_config
["sdn-port-mapping"] = yaml
.safe_load(f
.read())
158 vim_account
["config"] = vim_config
159 # vim_account['config'] = json.dumps(vim_config)
160 http_code
, resp
= self
._http
.patch_cmd(
161 endpoint
="{}/{}".format(self
._apiBase
, vim
["_id"]),
162 postfields_dict
=vim_account
,
164 # print('HTTP CODE: {}'.format(http_code))
165 # print('RESP: {}'.format(resp))
166 # if http_code in (200, 201, 202, 204):
168 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
169 # Use the previously obtained id instead.
170 wait_id
= vim_id_for_wait
171 # Wait for status for VI instance update
172 self
._wait
(wait_id
, wait
)
179 # msg = json.loads(resp)
182 # raise ClientException("failed to update vim {} - {}".format(vim_name, msg))
184 def update_vim_account_dict(self
, vim_account
, vim_access
):
185 self
._logger
.debug("")
186 vim_account
["vim_type"] = vim_access
["vim-type"]
187 vim_account
["description"] = vim_access
["description"]
188 vim_account
["vim_url"] = vim_access
["vim-url"]
189 vim_account
["vim_user"] = vim_access
["vim-username"]
190 vim_account
["vim_password"] = vim_access
["vim-password"]
191 vim_account
["vim_tenant_name"] = vim_access
["vim-tenant-name"]
194 def get_id(self
, name
):
195 """Returns a VIM id from a VIM name"""
196 self
._logger
.debug("")
197 for vim
in self
.list():
198 if name
== vim
["name"]:
200 raise NotFound("vim {} not found".format(name
))
202 def delete(self
, vim_name
, force
=False, wait
=False):
203 self
._logger
.debug("")
204 self
._client
.get_token()
206 if not utils
.validate_uuid4(vim_name
):
207 vim_id
= self
.get_id(vim_name
)
210 querystring
= "?FORCE=True"
211 http_code
, resp
= self
._http
.delete_cmd(
212 "{}/{}{}".format(self
._apiBase
, vim_id
, querystring
)
214 # print('HTTP CODE: {}'.format(http_code))
215 # print('RESP: {}'.format(resp))
218 # When deleting an account, 'resp' may be None.
219 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
222 resp
= json
.loads(resp
)
223 wait_id
= resp
.get("id")
224 # Wait for status for VIM account deletion
225 self
._wait
(wait_id
, wait
, deleteFlag
=True)
227 print("Deletion in progress")
228 elif http_code
== 204:
234 # msg = json.loads(resp)
237 raise ClientException("failed to delete vim {} - {}".format(vim_name
, msg
))
239 def list(self
, filter=None):
240 """Returns a list of VIM accounts"""
241 self
._logger
.debug("")
242 self
._client
.get_token()
245 filter_string
= "?{}".format(filter)
246 _
, resp
= self
._http
.get2_cmd("{}{}".format(self
._apiBase
, filter_string
))
249 vim_accounts
= json
.loads(resp
)
250 for datacenter
in vim_accounts
:
251 datacenter
["uuid"] = datacenter
.get("_id") # backward compatibility?
255 """Returns a VIM account based on name or id"""
256 self
._logger
.debug("")
257 self
._client
.get_token()
259 if not utils
.validate_uuid4(name
):
260 vim_id
= self
.get_id(name
)
262 _
, resp
= self
._http
.get2_cmd("{}/{}".format(self
._apiBase
, vim_id
))
264 resp
= json
.loads(resp
)
265 if not resp
or "_id" not in resp
:
266 raise ClientException("failed to get vim info: {}".format(resp
))
269 raise NotFound("vim '{}' not found".format(name
))