defc536a5d1c39c786370b921854dc99526c53dc
[osm/osmclient.git] / osmclient / sol005 / wim.py
1 # Copyright 2018 Telefonica
2 #
3 # All Rights Reserved.
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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
15 # under the License.
16
17 """
18 OSM wim API handling
19 """
20
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
25 import yaml
26 import json
27
28
29 class Wim(object):
30 def __init__(self, http=None, client=None):
31 self._http = http
32 self._client = client
33 self._apiName = '/admin'
34 self._apiVersion = '/v1'
35 self._apiResource = '/wim_accounts'
36 self._apiBase = '{}{}{}'.format(self._apiName,
37 self._apiVersion, self._apiResource)
38 # WIM '--wait' option
39 def _wait(self, id, deleteFlag=False):
40 # Endpoint to get operation status
41 apiUrlStatus = '{}{}{}'.format(self._apiName, self._apiVersion, '/wim_accounts')
42 # Wait for status for WIM instance creation/deletion
43 WaitForStatus.wait_for_status(
44 'WIM',
45 str(id),
46 WaitForStatus.TIMEOUT_WIM_OPERATION,
47 apiUrlStatus,
48 self._http.get2_cmd,
49 deleteFlag=deleteFlag)
50
51 def _get_id_for_wait(self, name):
52 # Returns id of name, or the id itself if given as argument
53 for wim in self.list():
54 if name == wim['name']:
55 return wim['uuid']
56 for wim in self.list():
57 if name == wim['uuid']:
58 return wim['uuid']
59 return ''
60
61 def create(self, name, wim_input, wim_port_mapping=None, wait=False):
62 if 'wim_type' not in wim_input:
63 raise Exception("wim type not provided")
64
65 wim_account = wim_input
66 wim_account["name"] = name
67
68 wim_config = {}
69 if 'config' in wim_input and wim_input['config'] is not None:
70 wim_config = yaml.safe_load(wim_input['config'])
71 if wim_port_mapping:
72 with open(wim_port_mapping, 'r') as f:
73 wim_config['wim_port_mapping'] = yaml.safe_load(f.read())
74 if wim_config:
75 wim_account['config'] = wim_config
76 #wim_account['config'] = json.dumps(wim_config)
77
78 http_code, resp = self._http.post_cmd(endpoint=self._apiBase,
79 postfields_dict=wim_account)
80 #print 'HTTP CODE: {}'.format(http_code)
81 #print 'RESP: {}'.format(resp)
82 if http_code in (200, 201, 202, 204):
83 if resp:
84 resp = json.loads(resp)
85 if not resp or 'id' not in resp:
86 raise ClientException('unexpected response from server - {}'.format(
87 resp))
88 if wait:
89 # Wait for status for WIM instance creation
90 self._wait(resp.get('id'))
91 print(resp['id'])
92 else:
93 msg = ""
94 if resp:
95 try:
96 msg = json.loads(resp)
97 except ValueError:
98 msg = resp
99 raise ClientException("failed to create wim {} - {}".format(name, msg))
100
101 def update(self, wim_name, wim_account, wim_port_mapping=None, wait=False):
102 wim = self.get(wim_name)
103 wim_id_for_wait = self._get_id_for_wait(wim_name)
104 wim_config = {}
105 if 'config' in wim_account:
106 if wim_account.get('config')=="" and (wim_port_mapping):
107 raise ClientException("clearing config is incompatible with updating SDN info")
108 if wim_account.get('config')=="":
109 wim_config = None
110 else:
111 wim_config = yaml.safe_load(wim_account['config'])
112 if wim_port_mapping:
113 with open(wim_port_mapping, 'r') as f:
114 wim_config['wim_port_mapping'] = yaml.safe_load(f.read())
115 wim_account['config'] = wim_config
116 #wim_account['config'] = json.dumps(wim_config)
117 http_code, resp = self._http.put_cmd(endpoint='{}/{}'.format(self._apiBase,wim['_id']),
118 postfields_dict=wim_account)
119 #print 'HTTP CODE: {}'.format(http_code)
120 #print 'RESP: {}'.format(resp)
121 if http_code in (200, 201, 202, 204):
122 if wait:
123 # 'resp' may be None.
124 # In that case, 'resp['id']' cannot be used.
125 # In that case, 'resp['id']' cannot be used, so use the previously obtained id instead
126 wait_id = wim_id_for_wait
127 if resp:
128 resp = json.loads(resp)
129 wait_id = resp.get('id')
130 # Wait for status for WIM instance update
131 self._wait(wait_id)
132 else:
133 pass
134 else:
135 msg = ""
136 if resp:
137 try:
138 msg = json.loads(resp)
139 except ValueError:
140 msg = resp
141 raise ClientException("failed to update wim {} - {}".format(wim_name, msg))
142
143 def update_wim_account_dict(self, wim_account, wim_input):
144 print (wim_input)
145 wim_account['wim_type'] = wim_input['wim_type']
146 wim_account['description'] = wim_input['description']
147 wim_account['wim_url'] = wim_input['url']
148 wim_account['user'] = wim_input.get('wim-username')
149 wim_account['password'] = wim_input.get('wim-password')
150 return wim_account
151
152 def get_id(self, name):
153 """Returns a WIM id from a WIM name
154 """
155 for wim in self.list():
156 if name == wim['name']:
157 return wim['uuid']
158 raise NotFound("wim {} not found".format(name))
159
160 def delete(self, wim_name, force=False, wait=False):
161 wim_id = wim_name
162 wim_id_for_wait = self._get_id_for_wait(wim_name)
163 if not utils.validate_uuid4(wim_name):
164 wim_id = self.get_id(wim_name)
165 querystring = ''
166 if force:
167 querystring = '?FORCE=True'
168 http_code, resp = self._http.delete_cmd('{}/{}{}'.format(self._apiBase,
169 wim_id, querystring))
170 # print 'HTTP CODE: {}'.format(http_code)
171 # print 'RESP: {}'.format(resp)
172 # print 'WIM_ID: {}'.format(wim_id)
173 if http_code == 202:
174 if wait:
175 # 'resp' may be None.
176 # In that case, 'resp['id']' cannot be used, so use the previously obtained id instead
177 wait_id = wim_id_for_wait
178 if resp:
179 resp = json.loads(resp)
180 wait_id = resp.get('id')
181 # Wait for status for WIM account deletion
182 self._wait(wait_id, deleteFlag=True)
183 else:
184 print('Deletion in progress')
185 elif http_code == 204:
186 print('Deleted')
187 else:
188 msg = ""
189 if resp:
190 try:
191 msg = json.loads(resp)
192 except ValueError:
193 msg = resp
194 raise ClientException("failed to delete wim {} - {}".format(wim_name, msg))
195
196 def list(self, filter=None):
197 """Returns a list of VIM accounts
198 """
199 filter_string = ''
200 if filter:
201 filter_string = '?{}'.format(filter)
202 resp = self._http.get_cmd('{}{}'.format(self._apiBase,filter_string))
203 if not resp:
204 return list()
205 wim_accounts = []
206 for datacenter in resp:
207 wim_accounts.append({"name": datacenter['name'], "uuid": datacenter['_id']
208 if '_id' in datacenter else None})
209 return wim_accounts
210
211 def get(self, name):
212 """Returns a VIM account based on name or id
213 """
214 wim_id = name
215 if not utils.validate_uuid4(name):
216 wim_id = self.get_id(name)
217 resp = self._http.get_cmd('{}/{}'.format(self._apiBase,wim_id))
218 if not resp or '_id' not in resp:
219 raise ClientException('failed to get wim info: '.format(
220 resp))
221 else:
222 return resp
223 raise NotFound("wim {} not found".format(name))