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
, config
={}, 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
97 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
98 vim_config
["sdn-controller"] = sdnc
["_id"]
100 with
open(sdn_port_mapping
, "r") as f
:
101 vim_config
["sdn-port-mapping"] = yaml
.safe_load(f
.read())
103 vim_account
["config"] = vim_config
104 # vim_account['config'] = json.dumps(vim_config)
106 http_code
, resp
= self
._http
.post_cmd(
107 endpoint
=self
._apiBase
, postfields_dict
=vim_account
109 # print('HTTP CODE: {}'.format(http_code))
110 # print('RESP: {}'.format(resp))
111 # if http_code in (200, 201, 202, 204):
113 resp
= json
.loads(resp
)
114 if not resp
or "id" not in resp
:
115 raise ClientException("unexpected response from server - {}".format(resp
))
117 # Wait for status for VIM instance creation
118 self
._wait
(resp
.get("id"), wait
)
124 # msg = json.loads(resp)
127 # raise ClientException("failed to create vim {} - {}".format(name, msg))
130 self
, vim_name
, vim_account
, config
, sdn_controller
, sdn_port_mapping
, wait
=False
132 self
._logger
.debug("")
133 self
._client
.get_token()
134 vim
= self
.get(vim_name
)
135 vim_id_for_wait
= self
._get
_id
_for
_wait
(vim_name
)
137 if config
is not None:
138 if not config
and (sdn_controller
or sdn_port_mapping
):
139 # If config is empty (clearing config)
140 raise ClientException(
141 "clearing config is incompatible with updating SDN info"
144 if sdn_controller
== "":
145 vim_config
["sdn-controller"] = None
146 vim_config
["sdn-port-mapping"] = None
149 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
150 vim_config
["sdn-controller"] = sdnc
["_id"]
152 with
open(sdn_port_mapping
, "r") as f
:
153 vim_config
["sdn-port-mapping"] = yaml
.safe_load(f
.read())
154 vim_account
["config"] = vim_config
155 # vim_account['config'] = json.dumps(vim_config)
156 http_code
, resp
= self
._http
.patch_cmd(
157 endpoint
="{}/{}".format(self
._apiBase
, vim
["_id"]),
158 postfields_dict
=vim_account
,
160 # print('HTTP CODE: {}'.format(http_code))
161 # print('RESP: {}'.format(resp))
162 # if http_code in (200, 201, 202, 204):
164 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
165 # Use the previously obtained id instead.
166 wait_id
= vim_id_for_wait
167 # Wait for status for VI instance update
168 self
._wait
(wait_id
, wait
)
175 # msg = json.loads(resp)
178 # raise ClientException("failed to update vim {} - {}".format(vim_name, msg))
180 def update_vim_account_dict(self
, vim_account
, vim_access
):
181 self
._logger
.debug("")
182 vim_account
["vim_type"] = vim_access
["vim-type"]
183 vim_account
["description"] = vim_access
["description"]
184 vim_account
["vim_url"] = vim_access
["vim-url"] or "null"
185 vim_account
["vim_user"] = vim_access
["vim-username"] or "null"
186 vim_account
["vim_password"] = vim_access
["vim-password"] or "null"
187 vim_account
["vim_tenant_name"] = vim_access
["vim-tenant-name"] or "null"
190 def get_id(self
, name
):
191 """Returns a VIM id from a VIM name"""
192 self
._logger
.debug("")
193 for vim
in self
.list():
194 if name
== vim
["name"]:
196 raise NotFound("vim {} not found".format(name
))
198 def delete(self
, vim_name
, force
=False, wait
=False):
199 self
._logger
.debug("")
200 self
._client
.get_token()
202 if not utils
.validate_uuid4(vim_name
):
203 vim_id
= self
.get_id(vim_name
)
206 querystring
= "?FORCE=True"
207 http_code
, resp
= self
._http
.delete_cmd(
208 "{}/{}{}".format(self
._apiBase
, vim_id
, querystring
)
210 # print('HTTP CODE: {}'.format(http_code))
211 # print('RESP: {}'.format(resp))
214 # When deleting an account, 'resp' may be None.
215 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
218 resp
= json
.loads(resp
)
219 wait_id
= resp
.get("id")
220 # Wait for status for VIM account deletion
221 self
._wait
(wait_id
, wait
, deleteFlag
=True)
223 print("Deletion in progress")
224 elif http_code
== 204:
230 # msg = json.loads(resp)
233 raise ClientException("failed to delete vim {} - {}".format(vim_name
, msg
))
235 def list(self
, filter=None):
236 """Returns a list of VIM accounts"""
237 self
._logger
.debug("")
238 self
._client
.get_token()
241 filter_string
= "?{}".format(filter)
242 _
, resp
= self
._http
.get2_cmd("{}{}".format(self
._apiBase
, filter_string
))
245 vim_accounts
= json
.loads(resp
)
246 for datacenter
in vim_accounts
:
247 datacenter
["uuid"] = datacenter
.get("_id") # backward compatibility?
251 """Returns a VIM account based on name or id"""
252 self
._logger
.debug("")
253 self
._client
.get_token()
255 if not utils
.validate_uuid4(name
):
256 vim_id
= self
.get_id(name
)
258 _
, resp
= self
._http
.get2_cmd("{}/{}".format(self
._apiBase
, vim_id
))
260 resp
= json
.loads(resp
)
261 if not resp
or "_id" not in resp
:
262 raise ClientException("failed to get vim info: {}".format(resp
))
265 raise NotFound("vim '{}' not found".format(name
))