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
30 def __init__(self
, http
=None, client
=None):
33 self
._apiName
= '/admin'
34 self
._apiVersion
= '/v1'
35 self
._apiResource
= '/vim_accounts'
36 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
37 self
._apiVersion
, self
._apiResource
)
40 def _wait(self
, id, deleteFlag
=False):
41 self
._client
.get_token()
42 # Endpoint to get operation status
43 apiUrlStatus
= '{}{}{}'.format(self
._apiName
, self
._apiVersion
, '/vim_accounts')
44 # Wait for status for VIM instance creation/deletion
45 WaitForStatus
.wait_for_status(
48 WaitForStatus
.TIMEOUT_VIM_OPERATION
,
51 deleteFlag
=deleteFlag
)
53 def _get_id_for_wait(self
, name
):
54 # Returns id of name, or the id itself if given as argument
55 for vim
in self
.list():
56 if name
== vim
['uuid']:
58 for vim
in self
.list():
59 if name
== vim
['name']:
63 def create(self
, name
, vim_access
, sdn_controller
=None, sdn_port_mapping
=None, wait
=False):
64 self
._client
.get_token()
65 if 'vim-type' not in vim_access
:
66 #'openstack' not in vim_access['vim-type']):
67 raise Exception("vim type not provided")
70 vim_account
['name'] = name
71 vim_account
= self
.update_vim_account_dict(vim_account
, vim_access
)
74 if 'config' in vim_access
and vim_access
['config'] is not None:
75 vim_config
= yaml
.safe_load(vim_access
['config'])
77 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
78 vim_config
['sdn-controller'] = sdnc
['_id']
80 with
open(sdn_port_mapping
, 'r') as f
:
81 vim_config
['sdn-port-mapping'] = yaml
.safe_load(f
.read())
83 vim_account
['config'] = vim_config
84 #vim_account['config'] = json.dumps(vim_config)
86 http_code
, resp
= self
._http
.post_cmd(endpoint
=self
._apiBase
,
87 postfields_dict
=vim_account
)
88 #print('HTTP CODE: {}'.format(http_code))
89 #print('RESP: {}'.format(resp))
90 if http_code
in (200, 201, 202, 204):
92 resp
= json
.loads(resp
)
93 if not resp
or 'id' not in resp
:
94 raise ClientException('unexpected response from server - {}'.format(
97 # Wait for status for VIM instance creation
98 self
._wait
(resp
.get('id'))
104 msg
= json
.loads(resp
)
107 raise ClientException("failed to create vim {} - {}".format(name
, msg
))
109 def update(self
, vim_name
, vim_account
, sdn_controller
, sdn_port_mapping
, wait
=False):
110 self
._client
.get_token()
111 vim
= self
.get(vim_name
)
112 vim_id_for_wait
= self
._get
_id
_for
_wait
(vim_name
)
114 if 'config' in vim_account
:
115 if vim_account
.get('config')=="" and (sdn_controller
or sdn_port_mapping
):
116 raise ClientException("clearing config is incompatible with updating SDN info")
117 if vim_account
.get('config')=="":
120 vim_config
= yaml
.safe_load(vim_account
['config'])
122 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
123 vim_config
['sdn-controller'] = sdnc
['_id']
125 with
open(sdn_port_mapping
, 'r') as f
:
126 vim_config
['sdn-port-mapping'] = yaml
.safe_load(f
.read())
127 vim_account
['config'] = vim_config
128 #vim_account['config'] = json.dumps(vim_config)
129 http_code
, resp
= self
._http
.patch_cmd(endpoint
='{}/{}'.format(self
._apiBase
,vim
['_id']),
130 postfields_dict
=vim_account
)
131 # print('HTTP CODE: {}'.format(http_code))
132 # print('RESP: {}'.format(resp))
133 if http_code
in (200, 201, 202, 204):
135 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
136 # Use the previously obtained id instead.
137 wait_id
= vim_id_for_wait
138 # Wait for status for VI instance update
146 msg
= json
.loads(resp
)
149 raise ClientException("failed to update vim {} - {}".format(vim_name
, msg
))
151 def update_vim_account_dict(self
, vim_account
, vim_access
):
152 vim_account
['vim_type'] = vim_access
['vim-type']
153 vim_account
['description'] = vim_access
['description']
154 vim_account
['vim_url'] = vim_access
['vim-url']
155 vim_account
['vim_user'] = vim_access
['vim-username']
156 vim_account
['vim_password'] = vim_access
['vim-password']
157 vim_account
['vim_tenant_name'] = vim_access
['vim-tenant-name']
160 def get_id(self
, name
):
161 """Returns a VIM id from a VIM name
163 for vim
in self
.list():
164 if name
== vim
['name']:
166 raise NotFound("vim {} not found".format(name
))
168 def delete(self
, vim_name
, force
=False, wait
=False):
169 self
._client
.get_token()
171 if not utils
.validate_uuid4(vim_name
):
172 vim_id
= self
.get_id(vim_name
)
175 querystring
= '?FORCE=True'
176 http_code
, resp
= self
._http
.delete_cmd('{}/{}{}'.format(self
._apiBase
,
177 vim_id
, querystring
))
178 #print('HTTP CODE: {}'.format(http_code))
179 #print('RESP: {}'.format(resp))
182 # When deleting an account, 'resp' may be None.
183 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
186 resp
= json
.loads(resp
)
187 wait_id
= resp
.get('id')
188 # Wait for status for VIM account deletion
189 self
._wait
(wait_id
, deleteFlag
=True)
191 print('Deletion in progress')
192 elif http_code
== 204:
198 msg
= json
.loads(resp
)
201 raise ClientException("failed to delete vim {} - {}".format(vim_name
, msg
))
203 def list(self
, filter=None):
204 """Returns a list of VIM accounts
206 self
._client
.get_token()
209 filter_string
= '?{}'.format(filter)
210 resp
= self
._http
.get_cmd('{}{}'.format(self
._apiBase
,filter_string
))
214 for datacenter
in resp
:
215 vim_accounts
.append({"name": datacenter
['name'], "uuid": datacenter
['_id']
216 if '_id' in datacenter
else None})
220 """Returns a VIM account based on name or id
222 self
._client
.get_token()
224 if not utils
.validate_uuid4(name
):
225 vim_id
= self
.get_id(name
)
226 resp
= self
._http
.get_cmd('{}/{}'.format(self
._apiBase
,vim_id
))
227 if not resp
or '_id' not in resp
:
228 raise ClientException('failed to get vim info: '.format(
232 raise NotFound("vim {} not found".format(name
))