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
= '/wim_accounts'
38 self
._apiBase
= '{}{}{}'.format(self
._apiName
,
39 self
._apiVersion
, self
._apiResource
)
42 def _wait(self
, id, wait_time
, deleteFlag
=False):
43 self
._logger
.debug("")
44 self
._client
.get_token()
45 # Endpoint to get operation status
46 apiUrlStatus
= '{}{}{}'.format(self
._apiName
, self
._apiVersion
, '/wim_accounts')
47 # Wait for status for WIM instance creation/deletion
48 if isinstance(wait_time
, bool):
49 wait_time
= WaitForStatus
.TIMEOUT_WIM_OPERATION
50 WaitForStatus
.wait_for_status(
56 deleteFlag
=deleteFlag
)
58 def _get_id_for_wait(self
, name
):
59 """Returns id of name, or the id itself if given as argument
61 self
._logger
.debug("")
62 for wim
in self
.list():
63 if name
== wim
['uuid']:
65 for wim
in self
.list():
66 if name
== wim
['name']:
70 def create(self
, name
, wim_input
, wim_port_mapping
=None, wait
=False):
71 self
._logger
.debug("")
72 self
._client
.get_token()
73 if 'wim_type' not in wim_input
:
74 raise Exception("wim type not provided")
76 wim_account
= wim_input
77 wim_account
["name"] = name
80 if 'config' in wim_input
and wim_input
['config'] is not None:
81 wim_config
= yaml
.safe_load(wim_input
['config'])
83 with
open(wim_port_mapping
, 'r') as f
:
84 wim_config
['wim_port_mapping'] = yaml
.safe_load(f
.read())
86 wim_account
['config'] = wim_config
87 #wim_account['config'] = json.dumps(wim_config)
89 http_code
, resp
= self
._http
.post_cmd(endpoint
=self
._apiBase
,
90 postfields_dict
=wim_account
)
91 #print('HTTP CODE: {}'.format(http_code))
92 #print('RESP: {}'.format(resp))
93 #if http_code in (200, 201, 202, 204):
95 resp
= json
.loads(resp
)
96 if not resp
or 'id' not in resp
:
97 raise ClientException('unexpected response from server - {}'.format(
100 # Wait for status for WIM instance creation
101 self
._wait
(resp
.get('id'), wait
)
107 # msg = json.loads(resp)
110 # raise ClientException("failed to create wim {} - {}".format(name, msg))
112 def update(self
, wim_name
, wim_account
, wim_port_mapping
=None, wait
=False):
113 self
._logger
.debug("")
114 self
._client
.get_token()
115 wim
= self
.get(wim_name
)
116 wim_id_for_wait
= self
._get
_id
_for
_wait
(wim_name
)
118 if 'config' in wim_account
:
119 if wim_account
.get('config')=="" and (wim_port_mapping
):
120 raise ClientException("clearing config is incompatible with updating SDN info")
121 if wim_account
.get('config')=="":
124 wim_config
= yaml
.safe_load(wim_account
['config'])
126 with
open(wim_port_mapping
, 'r') as f
:
127 wim_config
['wim_port_mapping'] = yaml
.safe_load(f
.read())
128 wim_account
['config'] = wim_config
129 #wim_account['config'] = json.dumps(wim_config)
130 http_code
, resp
= self
._http
.patch_cmd(endpoint
='{}/{}'.format(self
._apiBase
,wim
['_id']),
131 postfields_dict
=wim_account
)
132 #print('HTTP CODE: {}'.format(http_code))
133 #print('RESP: {}'.format(resp))
134 #if http_code in (200, 201, 202, 204):
136 # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
137 # Use the previously obtained id instead.
138 wait_id
= wim_id_for_wait
139 # Wait for status for WIM instance update
140 self
._wait
(wait_id
, wait
)
147 # msg = json.loads(resp)
150 # raise ClientException("failed to update wim {} - {}".format(wim_name, msg))
152 def update_wim_account_dict(self
, wim_account
, wim_input
):
153 self
._logger
.debug("")
154 self
._logger
.debug(str(wim_input
))
155 wim_account
['wim_type'] = wim_input
['wim_type']
156 wim_account
['description'] = wim_input
['description']
157 wim_account
['wim_url'] = wim_input
['url']
158 wim_account
['user'] = wim_input
.get('wim-username')
159 wim_account
['password'] = wim_input
.get('wim-password')
162 def get_id(self
, name
):
163 """Returns a WIM id from a WIM name
165 self
._logger
.debug("")
166 for wim
in self
.list():
167 if name
== wim
['name']:
169 raise NotFound("wim {} not found".format(name
))
171 def delete(self
, wim_name
, force
=False, wait
=False):
172 self
._logger
.debug("")
173 self
._client
.get_token()
175 wim_id_for_wait
= self
._get
_id
_for
_wait
(wim_name
)
176 if not utils
.validate_uuid4(wim_name
):
177 wim_id
= self
.get_id(wim_name
)
180 querystring
= '?FORCE=True'
181 http_code
, resp
= self
._http
.delete_cmd('{}/{}{}'.format(self
._apiBase
,
182 wim_id
, querystring
))
183 # print('HTTP CODE: {}'.format(http_code))
184 # print('RESP: {}'.format(resp))
185 # print('WIM_ID: {}'.format(wim_id))
188 # 'resp' may be None.
189 # In that case, 'resp['id']' cannot be used, so use the previously obtained id instead
190 wait_id
= wim_id_for_wait
192 resp
= json
.loads(resp
)
193 wait_id
= resp
.get('id')
194 # Wait for status for WIM account deletion
195 self
._wait
(wait_id
, wait
, deleteFlag
=True)
197 print('Deletion in progress')
198 elif http_code
== 204:
204 # msg = json.loads(resp)
207 raise ClientException("failed to delete wim {} - {}".format(wim_name
, msg
))
209 def list(self
, filter=None):
210 """Returns a list of VIM accounts
212 self
._logger
.debug("")
213 self
._client
.get_token()
216 filter_string
= '?{}'.format(filter)
217 _
, resp
= self
._http
.get2_cmd('{}{}'.format(self
._apiBase
,filter_string
))
221 for datacenter
in json
.loads(resp
):
222 wim_accounts
.append({"name": datacenter
['name'], "uuid": datacenter
['_id']
223 if '_id' in datacenter
else None})
227 """Returns a VIM account based on name or id
229 self
._logger
.debug("")
230 self
._client
.get_token()
232 if not utils
.validate_uuid4(name
):
233 wim_id
= self
.get_id(name
)
235 _
, resp
= self
._http
.get2_cmd('{}/{}'.format(self
._apiBase
,wim_id
))
237 resp
= json
.loads(resp
)
238 if not resp
or '_id' not in resp
:
239 raise ClientException('failed to get wim info: {}'.format(resp
))
242 raise NotFound("wim '{}' not found".format(name
))