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(self
._apiName
,
39 self
._apiVersion
, self
._apiResource
)
42 def _wait(self
, id, deleteFlag
=False):
43 self
._logger
.debug("")
44 self
._client
.get_token()
45 # Endpoint to get operation status
46 apiUrlStatus
= '{}{}{}'.format(self
._apiName
, self
._apiVersion
, '/vim_accounts')
47 # Wait for status for VIM instance creation/deletion
48 WaitForStatus
.wait_for_status(
51 WaitForStatus
.TIMEOUT_VIM_OPERATION
,
54 deleteFlag
=deleteFlag
)
56 def _get_id_for_wait(self
, name
):
57 """ Returns id of name, or the id itself if given as argument
59 self
._logger
.debug("")
60 self
._client
.get_token()
61 for vim
in self
.list():
62 if name
== vim
['uuid']:
64 for vim
in self
.list():
65 if name
== vim
['name']:
69 def create(self
, name
, vim_access
, sdn_controller
=None, sdn_port_mapping
=None, wait
=False):
70 self
._logger
.debug("")
71 self
._client
.get_token()
72 if 'vim-type' not in vim_access
:
73 #'openstack' not in vim_access['vim-type']):
74 raise Exception("vim type not provided")
77 vim_account
['name'] = name
78 vim_account
= self
.update_vim_account_dict(vim_account
, vim_access
)
81 if 'config' in vim_access
and vim_access
['config'] is not None:
82 vim_config
= yaml
.safe_load(vim_access
['config'])
84 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
85 vim_config
['sdn-controller'] = sdnc
['_id']
87 with
open(sdn_port_mapping
, 'r') as f
:
88 vim_config
['sdn-port-mapping'] = yaml
.safe_load(f
.read())
90 vim_account
['config'] = vim_config
91 #vim_account['config'] = json.dumps(vim_config)
93 http_code
, resp
= self
._http
.post_cmd(endpoint
=self
._apiBase
,
94 postfields_dict
=vim_account
)
95 #print('HTTP CODE: {}'.format(http_code))
96 #print('RESP: {}'.format(resp))
97 if http_code
in (200, 201, 202, 204):
99 resp
= json
.loads(resp
)
100 if not resp
or 'id' not in resp
:
101 raise ClientException('unexpected response from server - {}'.format(
104 # Wait for status for VIM instance creation
105 self
._wait
(resp
.get('id'))
111 msg
= json
.loads(resp
)
114 raise ClientException("failed to create vim {} - {}".format(name
, msg
))
116 def update(self
, vim_name
, vim_account
, sdn_controller
, sdn_port_mapping
, wait
=False):
117 self
._logger
.debug("")
118 self
._client
.get_token()
119 vim
= self
.get(vim_name
)
120 vim_id_for_wait
= self
._get
_id
_for
_wait
(vim_name
)
122 if 'config' in vim_account
:
123 if vim_account
.get('config')=="" and (sdn_controller
or sdn_port_mapping
):
124 raise ClientException("clearing config is incompatible with updating SDN info")
125 if vim_account
.get('config')=="":
128 vim_config
= yaml
.safe_load(vim_account
['config'])
130 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
131 vim_config
['sdn-controller'] = sdnc
['_id']
133 with
open(sdn_port_mapping
, 'r') as f
:
134 vim_config
['sdn-port-mapping'] = yaml
.safe_load(f
.read())
135 vim_account
['config'] = vim_config
136 #vim_account['config'] = json.dumps(vim_config)
137 http_code
, resp
= self
._http
.patch_cmd(endpoint
='{}/{}'.format(self
._apiBase
,vim
['_id']),
138 postfields_dict
=vim_account
)
139 # print('HTTP CODE: {}'.format(http_code))
140 # print('RESP: {}'.format(resp))
141 if http_code
in (200, 201, 202, 204):
143 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
144 # Use the previously obtained id instead.
145 wait_id
= vim_id_for_wait
146 # Wait for status for VI instance update
154 msg
= json
.loads(resp
)
157 raise ClientException("failed to update vim {} - {}".format(vim_name
, msg
))
159 def update_vim_account_dict(self
, vim_account
, vim_access
):
160 self
._logger
.debug("")
161 vim_account
['vim_type'] = vim_access
['vim-type']
162 vim_account
['description'] = vim_access
['description']
163 vim_account
['vim_url'] = vim_access
['vim-url']
164 vim_account
['vim_user'] = vim_access
['vim-username']
165 vim_account
['vim_password'] = vim_access
['vim-password']
166 vim_account
['vim_tenant_name'] = vim_access
['vim-tenant-name']
169 def get_id(self
, name
):
170 """Returns a VIM id from a VIM name
172 self
._logger
.debug("")
173 for vim
in self
.list():
174 if name
== vim
['name']:
176 raise NotFound("vim {} not found".format(name
))
178 def delete(self
, vim_name
, force
=False, wait
=False):
179 self
._logger
.debug("")
180 self
._client
.get_token()
182 if not utils
.validate_uuid4(vim_name
):
183 vim_id
= self
.get_id(vim_name
)
186 querystring
= '?FORCE=True'
187 http_code
, resp
= self
._http
.delete_cmd('{}/{}{}'.format(self
._apiBase
,
188 vim_id
, querystring
))
189 #print('HTTP CODE: {}'.format(http_code))
190 #print('RESP: {}'.format(resp))
193 # When deleting an account, 'resp' may be None.
194 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
197 resp
= json
.loads(resp
)
198 wait_id
= resp
.get('id')
199 # Wait for status for VIM account deletion
200 self
._wait
(wait_id
, deleteFlag
=True)
202 print('Deletion in progress')
203 elif http_code
== 204:
209 msg
= json
.loads(resp
)
212 raise ClientException("failed to delete vim {} - {}".format(vim_name
, msg
))
214 def list(self
, filter=None):
215 """Returns a list of VIM accounts
217 self
._logger
.debug("")
218 self
._client
.get_token()
221 filter_string
= '?{}'.format(filter)
222 resp
= self
._http
.get_cmd('{}{}'.format(self
._apiBase
,filter_string
))
226 for datacenter
in resp
:
227 vim_accounts
.append({"name": datacenter
['name'], "uuid": datacenter
['_id']
228 if '_id' in datacenter
else None})
232 """Returns a VIM account based on name or id
234 self
._logger
.debug("")
235 self
._client
.get_token()
237 if not utils
.validate_uuid4(name
):
238 vim_id
= self
.get_id(name
)
239 resp
= self
._http
.get_cmd('{}/{}'.format(self
._apiBase
,vim_id
))
240 if not resp
or '_id' not in resp
:
241 raise ClientException('failed to get vim info: '.format(
245 raise NotFound("vim {} not found".format(name
))