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
25 from osmclient
.common
.exceptions
import OsmHttpException
32 def __init__(self
, http
=None, client
=None):
35 self
._logger
= logging
.getLogger('osmclient')
36 self
._apiName
= '/admin'
37 self
._apiVersion
= '/v1'
38 self
._apiResource
= '/vim_accounts'
39 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
40 self
._apiVersion
, self
._apiResource
)
43 def _wait(self
, id, 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 WaitForStatus
.wait_for_status(
52 WaitForStatus
.TIMEOUT_VIM_OPERATION
,
55 deleteFlag
=deleteFlag
)
57 def _get_id_for_wait(self
, name
):
58 """ Returns id of name, or the id itself if given as argument
60 self
._logger
.debug("")
61 self
._client
.get_token()
62 for vim
in self
.list():
63 if name
== vim
['uuid']:
65 for vim
in self
.list():
66 if name
== vim
['name']:
70 def create(self
, name
, vim_access
, sdn_controller
=None, sdn_port_mapping
=None, wait
=False):
71 self
._logger
.debug("")
72 self
._client
.get_token()
73 if 'vim-type' not in vim_access
:
74 #'openstack' not in vim_access['vim-type']):
75 raise Exception("vim type not provided")
78 vim_account
['name'] = name
79 vim_account
= self
.update_vim_account_dict(vim_account
, vim_access
)
82 if 'config' in vim_access
and vim_access
['config'] is not None:
83 vim_config
= yaml
.safe_load(vim_access
['config'])
85 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
86 vim_config
['sdn-controller'] = sdnc
['_id']
88 with
open(sdn_port_mapping
, 'r') as f
:
89 vim_config
['sdn-port-mapping'] = yaml
.safe_load(f
.read())
91 vim_account
['config'] = vim_config
92 #vim_account['config'] = json.dumps(vim_config)
94 http_code
, resp
= self
._http
.post_cmd(endpoint
=self
._apiBase
,
95 postfields_dict
=vim_account
)
96 #print('HTTP CODE: {}'.format(http_code))
97 #print('RESP: {}'.format(resp))
98 #if http_code in (200, 201, 202, 204):
100 resp
= json
.loads(resp
)
101 if not resp
or 'id' not in resp
:
102 raise OsmHttpException('unexpected response from server - {}'.format(
105 # Wait for status for VIM instance creation
106 self
._wait
(resp
.get('id'))
112 # msg = json.loads(resp)
115 # raise ClientException("failed to create vim {} - {}".format(name, msg))
117 def update(self
, vim_name
, vim_account
, sdn_controller
, sdn_port_mapping
, wait
=False):
118 self
._logger
.debug("")
119 self
._client
.get_token()
120 vim
= self
.get(vim_name
)
121 vim_id_for_wait
= self
._get
_id
_for
_wait
(vim_name
)
123 if 'config' in vim_account
:
124 if vim_account
.get('config')=="" and (sdn_controller
or sdn_port_mapping
):
125 raise ClientException("clearing config is incompatible with updating SDN info")
126 if vim_account
.get('config')=="":
129 vim_config
= yaml
.safe_load(vim_account
['config'])
131 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
132 vim_config
['sdn-controller'] = sdnc
['_id']
134 with
open(sdn_port_mapping
, 'r') as f
:
135 vim_config
['sdn-port-mapping'] = yaml
.safe_load(f
.read())
136 vim_account
['config'] = vim_config
137 #vim_account['config'] = json.dumps(vim_config)
138 http_code
, resp
= self
._http
.patch_cmd(endpoint
='{}/{}'.format(self
._apiBase
,vim
['_id']),
139 postfields_dict
=vim_account
)
140 # print('HTTP CODE: {}'.format(http_code))
141 # print('RESP: {}'.format(resp))
142 #if http_code in (200, 201, 202, 204):
144 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
145 # Use the previously obtained id instead.
146 wait_id
= vim_id_for_wait
147 # Wait for status for VI instance update
155 # msg = json.loads(resp)
158 # raise ClientException("failed to update vim {} - {}".format(vim_name, msg))
160 def update_vim_account_dict(self
, vim_account
, vim_access
):
161 self
._logger
.debug("")
162 vim_account
['vim_type'] = vim_access
['vim-type']
163 vim_account
['description'] = vim_access
['description']
164 vim_account
['vim_url'] = vim_access
['vim-url']
165 vim_account
['vim_user'] = vim_access
['vim-username']
166 vim_account
['vim_password'] = vim_access
['vim-password']
167 vim_account
['vim_tenant_name'] = vim_access
['vim-tenant-name']
170 def get_id(self
, name
):
171 """Returns a VIM id from a VIM name
173 self
._logger
.debug("")
174 for vim
in self
.list():
175 if name
== vim
['name']:
177 raise NotFound("vim {} not found".format(name
))
179 def delete(self
, vim_name
, force
=False, wait
=False):
180 self
._logger
.debug("")
181 self
._client
.get_token()
183 if not utils
.validate_uuid4(vim_name
):
184 vim_id
= self
.get_id(vim_name
)
187 querystring
= '?FORCE=True'
188 http_code
, resp
= self
._http
.delete_cmd('{}/{}{}'.format(self
._apiBase
,
189 vim_id
, querystring
))
190 #print('HTTP CODE: {}'.format(http_code))
191 #print('RESP: {}'.format(resp))
194 # When deleting an account, 'resp' may be None.
195 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
198 resp
= json
.loads(resp
)
199 wait_id
= resp
.get('id')
200 # Wait for status for VIM account deletion
201 self
._wait
(wait_id
, deleteFlag
=True)
203 print('Deletion in progress')
204 elif http_code
== 204:
210 msg
= json
.loads(resp
)
213 raise OsmHttpException("failed to delete vim {} - {}".format(vim_name
, msg
))
215 def list(self
, filter=None):
216 """Returns a list of VIM accounts
218 self
._logger
.debug("")
219 self
._client
.get_token()
222 filter_string
= '?{}'.format(filter)
223 _
, resp
= self
._http
.get2_cmd('{}{}'.format(self
._apiBase
,filter_string
))
227 for datacenter
in json
.loads(resp
):
228 vim_accounts
.append({"name": datacenter
['name'], "uuid": datacenter
['_id']
229 if '_id' in datacenter
else None})
233 """Returns a VIM account based on name or id
235 self
._logger
.debug("")
236 self
._client
.get_token()
238 if not utils
.validate_uuid4(name
):
239 vim_id
= self
.get_id(name
)
240 _
, resp
= self
._http
.get2_cmd('{}/{}'.format(self
._apiBase
,vim_id
))
241 # if not resp or '_id' not in resp:
242 # raise ClientException('failed to get vim info: '.format(
246 return json
.loads(resp
)
247 raise NotFound("vim {} not found".format(name
))