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
)
39 def _wait(self
, id, deleteFlag
=False):
40 # Endpoint to get operation status
41 apiUrlStatus
= '{}{}{}'.format(self
._apiName
, self
._apiVersion
, '/vim_accounts')
42 # Wait for status for VIM instance creation/deletion
43 WaitForStatus
.wait_for_status(
46 WaitForStatus
.TIMEOUT_VIM_OPERATION
,
49 deleteFlag
=deleteFlag
)
51 def _get_id_for_wait(self
, name
):
52 # Returns id of name, or the id itself if given as argument
53 for vim
in self
.list():
54 if name
== vim
['uuid']:
56 for vim
in self
.list():
57 if name
== vim
['name']:
61 def create(self
, name
, vim_access
, sdn_controller
=None, sdn_port_mapping
=None, wait
=False):
62 if 'vim-type' not in vim_access
:
63 #'openstack' not in vim_access['vim-type']):
64 raise Exception("vim type not provided")
67 vim_account
['name'] = name
68 vim_account
= self
.update_vim_account_dict(vim_account
, vim_access
)
71 if 'config' in vim_access
and vim_access
['config'] is not None:
72 vim_config
= yaml
.safe_load(vim_access
['config'])
74 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
75 vim_config
['sdn-controller'] = sdnc
['_id']
77 with
open(sdn_port_mapping
, 'r') as f
:
78 vim_config
['sdn-port-mapping'] = yaml
.safe_load(f
.read())
80 vim_account
['config'] = vim_config
81 #vim_account['config'] = json.dumps(vim_config)
83 http_code
, resp
= self
._http
.post_cmd(endpoint
=self
._apiBase
,
84 postfields_dict
=vim_account
)
85 #print 'HTTP CODE: {}'.format(http_code)
86 #print 'RESP: {}'.format(resp)
87 if http_code
in (200, 201, 202, 204):
89 resp
= json
.loads(resp
)
90 if not resp
or 'id' not in resp
:
91 raise ClientException('unexpected response from server - {}'.format(
94 # Wait for status for VIM instance creation
95 self
._wait
(resp
.get('id'))
101 msg
= json
.loads(resp
)
104 raise ClientException("failed to create vim {} - {}".format(name
, msg
))
106 def update(self
, vim_name
, vim_account
, sdn_controller
, sdn_port_mapping
, wait
=False):
107 vim
= self
.get(vim_name
)
108 vim_id_for_wait
= self
._get
_id
_for
_wait
(vim_name
)
110 if 'config' in vim_account
:
111 if vim_account
.get('config')=="" and (sdn_controller
or sdn_port_mapping
):
112 raise ClientException("clearing config is incompatible with updating SDN info")
113 if vim_account
.get('config')=="":
116 vim_config
= yaml
.safe_load(vim_account
['config'])
118 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
119 vim_config
['sdn-controller'] = sdnc
['_id']
121 with
open(sdn_port_mapping
, 'r') as f
:
122 vim_config
['sdn-port-mapping'] = yaml
.safe_load(f
.read())
123 vim_account
['config'] = vim_config
124 #vim_account['config'] = json.dumps(vim_config)
125 http_code
, resp
= self
._http
.put_cmd(endpoint
='{}/{}'.format(self
._apiBase
,vim
['_id']),
126 postfields_dict
=vim_account
)
127 # print 'HTTP CODE: {}'.format(http_code)
128 # print 'RESP: {}'.format(resp)
129 if http_code
in (200, 201, 202, 204):
131 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
132 # Use the previously obtained id instead.
133 wait_id
= vim_id_for_wait
134 # Wait for status for VI instance update
142 msg
= json
.loads(resp
)
145 raise ClientException("failed to update vim {} - {}".format(vim_name
, msg
))
147 def update_vim_account_dict(self
, vim_account
, vim_access
):
148 vim_account
['vim_type'] = vim_access
['vim-type']
149 vim_account
['description'] = vim_access
['description']
150 vim_account
['vim_url'] = vim_access
['vim-url']
151 vim_account
['vim_user'] = vim_access
['vim-username']
152 vim_account
['vim_password'] = vim_access
['vim-password']
153 vim_account
['vim_tenant_name'] = vim_access
['vim-tenant-name']
156 def get_id(self
, name
):
157 """Returns a VIM id from a VIM name
159 for vim
in self
.list():
160 if name
== vim
['name']:
162 raise NotFound("vim {} not found".format(name
))
164 def delete(self
, vim_name
, force
=False, wait
=False):
166 if not utils
.validate_uuid4(vim_name
):
167 vim_id
= self
.get_id(vim_name
)
170 querystring
= '?FORCE=True'
171 http_code
, resp
= self
._http
.delete_cmd('{}/{}{}'.format(self
._apiBase
,
172 vim_id
, querystring
))
173 #print 'HTTP CODE: {}'.format(http_code)
174 #print 'RESP: {}'.format(resp)
177 # When deleting an account, 'resp' may be None.
178 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
181 resp
= json
.loads(resp
)
182 wait_id
= resp
.get('id')
183 # Wait for status for VIM account deletion
184 self
._wait
(wait_id
, deleteFlag
=True)
186 print('Deletion in progress')
187 elif http_code
== 204:
193 msg
= json
.loads(resp
)
196 raise ClientException("failed to delete vim {} - {}".format(vim_name
, msg
))
198 def list(self
, filter=None):
199 """Returns a list of VIM accounts
203 filter_string
= '?{}'.format(filter)
204 resp
= self
._http
.get_cmd('{}{}'.format(self
._apiBase
,filter_string
))
208 for datacenter
in resp
:
209 vim_accounts
.append({"name": datacenter
['name'], "uuid": datacenter
['_id']
210 if '_id' in datacenter
else None})
214 """Returns a VIM account based on name or id
217 if not utils
.validate_uuid4(name
):
218 vim_id
= self
.get_id(name
)
219 resp
= self
._http
.get_cmd('{}/{}'.format(self
._apiBase
,vim_id
))
220 if not resp
or '_id' not in resp
:
221 raise ClientException('failed to get vim info: '.format(
225 raise NotFound("vim {} not found".format(name
))