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 OsmHttpException
25 from osmclient
.common
.exceptions
import NotFound
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
= '/wim_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
, '/wim_accounts')
48 # Wait for status for WIM instance creation/deletion
49 WaitForStatus
.wait_for_status(
52 WaitForStatus
.TIMEOUT_WIM_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 for wim
in self
.list():
62 if name
== wim
['uuid']:
64 for wim
in self
.list():
65 if name
== wim
['name']:
69 def create(self
, name
, wim_input
, wim_port_mapping
=None, wait
=False):
70 self
._logger
.debug("")
71 self
._client
.get_token()
72 if 'wim_type' not in wim_input
:
73 raise Exception("wim type not provided")
75 wim_account
= wim_input
76 wim_account
["name"] = name
79 if 'config' in wim_input
and wim_input
['config'] is not None:
80 wim_config
= yaml
.safe_load(wim_input
['config'])
82 with
open(wim_port_mapping
, 'r') as f
:
83 wim_config
['wim_port_mapping'] = yaml
.safe_load(f
.read())
85 wim_account
['config'] = wim_config
86 #wim_account['config'] = json.dumps(wim_config)
88 http_code
, resp
= self
._http
.post_cmd(endpoint
=self
._apiBase
,
89 postfields_dict
=wim_account
)
90 #print('HTTP CODE: {}'.format(http_code))
91 #print('RESP: {}'.format(resp))
92 #if http_code in (200, 201, 202, 204):
94 resp
= json
.loads(resp
)
95 if not resp
or 'id' not in resp
:
96 raise OsmHttpException('unexpected response from server - {}'.format(
99 # Wait for status for WIM instance creation
100 self
._wait
(resp
.get('id'))
106 # msg = json.loads(resp)
109 # raise ClientException("failed to create wim {} - {}".format(name, msg))
111 def update(self
, wim_name
, wim_account
, wim_port_mapping
=None, wait
=False):
112 self
._logger
.debug("")
113 self
._client
.get_token()
114 wim
= self
.get(wim_name
)
115 wim_id_for_wait
= self
._get
_id
_for
_wait
(wim_name
)
117 if 'config' in wim_account
:
118 if wim_account
.get('config')=="" and (wim_port_mapping
):
119 raise ClientException("clearing config is incompatible with updating SDN info")
120 if wim_account
.get('config')=="":
123 wim_config
= yaml
.safe_load(wim_account
['config'])
125 with
open(wim_port_mapping
, 'r') as f
:
126 wim_config
['wim_port_mapping'] = yaml
.safe_load(f
.read())
127 wim_account
['config'] = wim_config
128 #wim_account['config'] = json.dumps(wim_config)
129 http_code
, resp
= self
._http
.patch_cmd(endpoint
='{}/{}'.format(self
._apiBase
,wim
['_id']),
130 postfields_dict
=wim_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
= wim_id_for_wait
138 # Wait for status for WIM instance update
146 # msg = json.loads(resp)
149 # raise ClientException("failed to update wim {} - {}".format(wim_name, msg))
151 def update_wim_account_dict(self
, wim_account
, wim_input
):
152 self
._logger
.debug("")
153 self
._logger
.debug(str(wim_input
))
154 wim_account
['wim_type'] = wim_input
['wim_type']
155 wim_account
['description'] = wim_input
['description']
156 wim_account
['wim_url'] = wim_input
['url']
157 wim_account
['user'] = wim_input
.get('wim-username')
158 wim_account
['password'] = wim_input
.get('wim-password')
161 def get_id(self
, name
):
162 """Returns a WIM id from a WIM name
164 self
._logger
.debug("")
165 for wim
in self
.list():
166 if name
== wim
['name']:
168 raise NotFound("wim {} not found".format(name
))
170 def delete(self
, wim_name
, force
=False, wait
=False):
171 self
._logger
.debug("")
172 self
._client
.get_token()
174 wim_id_for_wait
= self
._get
_id
_for
_wait
(wim_name
)
175 if not utils
.validate_uuid4(wim_name
):
176 wim_id
= self
.get_id(wim_name
)
179 querystring
= '?FORCE=True'
180 http_code
, resp
= self
._http
.delete_cmd('{}/{}{}'.format(self
._apiBase
,
181 wim_id
, querystring
))
182 # print('HTTP CODE: {}'.format(http_code))
183 # print('RESP: {}'.format(resp))
184 # print('WIM_ID: {}'.format(wim_id))
187 # 'resp' may be None.
188 # In that case, 'resp['id']' cannot be used, so use the previously obtained id instead
189 wait_id
= wim_id_for_wait
191 resp
= json
.loads(resp
)
192 wait_id
= resp
.get('id')
193 # Wait for status for WIM account deletion
194 self
._wait
(wait_id
, deleteFlag
=True)
196 print('Deletion in progress')
197 elif http_code
== 204:
203 msg
= json
.loads(resp
)
206 raise OsmHttpException("failed to delete wim {} - {}".format(wim_name
, msg
))
208 def list(self
, filter=None):
209 """Returns a list of VIM accounts
211 self
._logger
.debug("")
212 self
._client
.get_token()
215 filter_string
= '?{}'.format(filter)
216 _
, resp
= self
._http
.get2_cmd('{}{}'.format(self
._apiBase
,filter_string
))
220 for datacenter
in json
.loads(resp
):
221 wim_accounts
.append({"name": datacenter
['name'], "uuid": datacenter
['_id']
222 if '_id' in datacenter
else None})
226 """Returns a VIM account based on name or id
228 self
._logger
.debug("")
229 self
._client
.get_token()
231 if not utils
.validate_uuid4(name
):
232 wim_id
= self
.get_id(name
)
233 _
, resp
= self
._http
.get2_cmd('{}/{}'.format(self
._apiBase
,wim_id
))
234 # if not resp or '_id' not in resp:
235 # raise ClientException('failed to get wim info: '.format(
239 return json
.loads(resp
)
240 raise NotFound("wim {} not found".format(name
))