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 create(self
, name
, vim_access
, sdn_controller
=None, sdn_port_mapping
=None, wait
=False):
52 if 'vim-type' not in vim_access
:
53 #'openstack' not in vim_access['vim-type']):
54 raise Exception("vim type not provided")
57 vim_account
['name'] = name
58 vim_account
= self
.update_vim_account_dict(vim_account
, vim_access
)
61 if 'config' in vim_access
and vim_access
['config'] is not None:
62 vim_config
= yaml
.safe_load(vim_access
['config'])
64 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
65 vim_config
['sdn-controller'] = sdnc
['_id']
67 with
open(sdn_port_mapping
, 'r') as f
:
68 vim_config
['sdn-port-mapping'] = yaml
.safe_load(f
.read())
70 vim_account
['config'] = vim_config
71 #vim_account['config'] = json.dumps(vim_config)
73 http_code
, resp
= self
._http
.post_cmd(endpoint
=self
._apiBase
,
74 postfields_dict
=vim_account
)
75 #print 'HTTP CODE: {}'.format(http_code)
76 #print 'RESP: {}'.format(resp)
77 if http_code
in (200, 201, 202, 204):
79 resp
= json
.loads(resp
)
80 if not resp
or 'id' not in resp
:
81 raise ClientException('unexpected response from server - {}'.format(
84 # Wait for status for VIM instance creation
85 self
._wait
(resp
.get('id'))
91 msg
= json
.loads(resp
)
94 raise ClientException("failed to create vim {} - {}".format(name
, msg
))
96 def update(self
, vim_name
, vim_account
, sdn_controller
, sdn_port_mapping
, wait
=False):
97 vim
= self
.get(vim_name
)
100 if 'config' in vim_account
:
101 if vim_account
.get('config')=="" and (sdn_controller
or sdn_port_mapping
):
102 raise ClientException("clearing config is incompatible with updating SDN info")
103 if vim_account
.get('config')=="":
106 vim_config
= yaml
.safe_load(vim_account
['config'])
108 sdnc
= self
._client
.sdnc
.get(sdn_controller
)
109 vim_config
['sdn-controller'] = sdnc
['_id']
111 with
open(sdn_port_mapping
, 'r') as f
:
112 vim_config
['sdn-port-mapping'] = yaml
.safe_load(f
.read())
113 vim_account
['config'] = vim_config
114 #vim_account['config'] = json.dumps(vim_config)
115 http_code
, resp
= self
._http
.put_cmd(endpoint
='{}/{}'.format(self
._apiBase
,vim
['_id']),
116 postfields_dict
=vim_account
)
117 #print 'HTTP CODE: {}'.format(http_code)
118 #print 'RESP: {}'.format(resp)
119 if http_code
in (200, 201, 202, 204):
121 resp
= json
.loads(resp
)
122 if not resp
or 'id' not in resp
:
123 raise ClientException('unexpected response from server - {}'.format(
126 # Wait for status for VIM instance update
127 self
._wait
(resp
.get('id'))
133 msg
= json
.loads(resp
)
136 raise ClientException("failed to update vim {} - {}".format(vim_name
, msg
))
138 def update_vim_account_dict(self
, vim_account
, vim_access
):
139 vim_account
['vim_type'] = vim_access
['vim-type']
140 vim_account
['description'] = vim_access
['description']
141 vim_account
['vim_url'] = vim_access
['vim-url']
142 vim_account
['vim_user'] = vim_access
['vim-username']
143 vim_account
['vim_password'] = vim_access
['vim-password']
144 vim_account
['vim_tenant_name'] = vim_access
['vim-tenant-name']
147 def get_id(self
, name
):
148 """Returns a VIM id from a VIM name
150 for vim
in self
.list():
151 if name
== vim
['name']:
153 raise NotFound("vim {} not found".format(name
))
155 def delete(self
, vim_name
, force
=False, wait
=False):
157 if not utils
.validate_uuid4(vim_name
):
158 vim_id
= self
.get_id(vim_name
)
161 querystring
= '?FORCE=True'
162 http_code
, resp
= self
._http
.delete_cmd('{}/{}{}'.format(self
._apiBase
,
163 vim_id
, querystring
))
164 #print 'HTTP CODE: {}'.format(http_code)
165 #print 'RESP: {}'.format(resp)
168 # When deleting an account, 'resp' may be None.
169 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
172 resp
= json
.loads(resp
)
173 wait_id
= resp
.get('id')
174 # Wait for status for VIM account deletion
175 self
._wait
(wait_id
, deleteFlag
=True)
177 print('Deletion in progress')
178 elif http_code
== 204:
184 msg
= json
.loads(resp
)
187 raise ClientException("failed to delete vim {} - {}".format(vim_name
, msg
))
189 def list(self
, filter=None):
190 """Returns a list of VIM accounts
194 filter_string
= '?{}'.format(filter)
195 resp
= self
._http
.get_cmd('{}{}'.format(self
._apiBase
,filter_string
))
199 for datacenter
in resp
:
200 vim_accounts
.append({"name": datacenter
['name'], "uuid": datacenter
['_id']
201 if '_id' in datacenter
else None})
205 """Returns a VIM account based on name or id
208 if not utils
.validate_uuid4(name
):
209 vim_id
= self
.get_id(name
)
210 resp
= self
._http
.get_cmd('{}/{}'.format(self
._apiBase
,vim_id
))
211 if not resp
or '_id' not in resp
:
212 raise ClientException('failed to get vim info: '.format(
216 raise NotFound("vim {} not found".format(name
))