Add get_field method
[osm/osmclient.git] / osmclient / sol005 / ns.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 ns API handling
19 """
20
21 from osmclient.common import utils
22 from osmclient.common.exceptions import ClientException
23 from osmclient.common.exceptions import NotFound
24 import yaml
25 import json
26
27
28 class Ns(object):
29
30 def __init__(self, http=None, client=None):
31 self._http = http
32 self._client = client
33 self._apiName = '/nslcm'
34 self._apiVersion = '/v1'
35 self._apiResource = '/ns_instances_content'
36 self._apiBase = '{}{}{}'.format(self._apiName,
37 self._apiVersion, self._apiResource)
38
39 def list(self, filter=None):
40 """Returns a list of NS
41 """
42 filter_string = ''
43 if filter:
44 filter_string = '?{}'.format(filter)
45 resp = self._http.get_cmd('{}{}'.format(self._apiBase,filter_string))
46 if resp:
47 return resp
48 return list()
49
50 def get(self, name):
51 """Returns an NS based on name or id
52 """
53 if utils.validate_uuid4(name):
54 for ns in self.list():
55 if name == ns['_id']:
56 return ns
57 else:
58 for ns in self.list():
59 if name == ns['name']:
60 return ns
61 raise NotFound("ns {} not found".format(name))
62
63 def get_individual(self, name):
64 ns_id = name
65 if not utils.validate_uuid4(name):
66 for ns in self.list():
67 if name == ns['name']:
68 ns_id = ns['_id']
69 break
70 resp = self._http.get_cmd('{}/{}'.format(self._apiBase, ns_id))
71 #resp = self._http.get_cmd('{}/{}/nsd_content'.format(self._apiBase, ns_id))
72 #print yaml.safe_dump(resp)
73 if resp:
74 return resp
75 raise NotFound("ns {} not found".format(name))
76
77 def delete(self, name, force=False):
78 ns = self.get(name)
79 querystring = ''
80 if force:
81 querystring = '?FORCE=True'
82 http_code, resp = self._http.delete_cmd('{}/{}{}'.format(self._apiBase,
83 ns['_id'], querystring))
84 #print 'HTTP CODE: {}'.format(http_code)
85 #print 'RESP: {}'.format(resp)
86 if http_code == 202:
87 print('Deletion in progress')
88 elif http_code == 204:
89 print('Deleted')
90 else:
91 msg = ""
92 if resp:
93 try:
94 msg = json.loads(resp)
95 except ValueError:
96 msg = resp
97 raise ClientException("failed to delete ns {} - {}".format(name, msg))
98
99 def create(self, nsd_name, nsr_name, account, config=None,
100 ssh_keys=None, description='default description',
101 admin_status='ENABLED'):
102
103 nsd = self._client.nsd.get(nsd_name)
104
105 vim_account_id = {}
106
107 def get_vim_account_id(vim_account):
108 if vim_account_id.get(vim_account):
109 return vim_account_id[vim_account]
110
111 vim = self._client.vim.get(vim_account)
112 if vim is None:
113 raise NotFound("cannot find vim account '{}'".format(vim_account))
114 vim_account_id[vim_account] = vim['_id']
115 return vim['_id']
116
117 ns = {}
118 ns['nsdId'] = nsd['_id']
119 ns['nsName'] = nsr_name
120 ns['nsDescription'] = description
121 ns['vimAccountId'] = get_vim_account_id(account)
122 #ns['userdata'] = {}
123 #ns['userdata']['key1']='value1'
124 #ns['userdata']['key2']='value2'
125
126 if ssh_keys is not None:
127 # ssh_keys is comma separate list
128 # ssh_keys_format = []
129 # for key in ssh_keys.split(','):
130 # ssh_keys_format.append({'key-pair-ref': key})
131 #
132 # ns['ssh-authorized-key'] = ssh_keys_format
133 ns['ssh-authorized-key'] = []
134 for pubkeyfile in ssh_keys.split(','):
135 with open(pubkeyfile, 'r') as f:
136 ns['ssh-authorized-key'].append(f.read())
137 if config:
138 ns_config = yaml.load(config)
139 if "vim-network-name" in ns_config:
140 ns_config["vld"] = ns_config.pop("vim-network-name")
141 if "vld" in ns_config:
142 for vld in ns_config["vld"]:
143 if vld.get("vim-network-name"):
144 if isinstance(vld["vim-network-name"], dict):
145 vim_network_name_dict = {}
146 for vim_account, vim_net in list(vld["vim-network-name"].items()):
147 vim_network_name_dict[get_vim_account_id(vim_account)] = vim_net
148 vld["vim-network-name"] = vim_network_name_dict
149 ns["vld"] = ns_config["vld"]
150 if "vnf" in ns_config:
151 for vnf in ns_config["vnf"]:
152 if vnf.get("vim_account"):
153 vnf["vimAccountId"] = get_vim_account_id(vnf.pop("vim_account"))
154
155 ns["vnf"] = ns_config["vnf"]
156
157 #print yaml.safe_dump(ns)
158 try:
159 self._apiResource = '/ns_instances_content'
160 self._apiBase = '{}{}{}'.format(self._apiName,
161 self._apiVersion, self._apiResource)
162 headers = self._client._headers
163 headers['Content-Type'] = 'application/yaml'
164 http_header = ['{}: {}'.format(key,val)
165 for (key,val) in list(headers.items())]
166 self._http.set_http_header(http_header)
167 http_code, resp = self._http.post_cmd(endpoint=self._apiBase,
168 postfields_dict=ns)
169 #print 'HTTP CODE: {}'.format(http_code)
170 #print 'RESP: {}'.format(resp)
171 if http_code in (200, 201, 202, 204):
172 if resp:
173 resp = json.loads(resp)
174 if not resp or 'id' not in resp:
175 raise ClientException('unexpected response from server - {} '.format(
176 resp))
177 return resp['id']
178 else:
179 msg = ""
180 if resp:
181 try:
182 msg = json.loads(resp)
183 except ValueError:
184 msg = resp
185 raise ClientException(msg)
186 except ClientException as exc:
187 message="failed to create ns: {} nsd: {}\nerror:\n{}".format(
188 nsr_name,
189 nsd_name,
190 exc.message)
191 raise ClientException(message)
192
193 def list_op(self, name, filter=None):
194 """Returns the list of operations of a NS
195 """
196 ns = self.get(name)
197 try:
198 self._apiResource = '/ns_lcm_op_occs'
199 self._apiBase = '{}{}{}'.format(self._apiName,
200 self._apiVersion, self._apiResource)
201 filter_string = ''
202 if filter:
203 filter_string = '&{}'.format(filter)
204 http_code, resp = self._http.get2_cmd('{}?nsInstanceId={}'.format(
205 self._apiBase, ns['_id'],
206 filter_string) )
207 #print 'HTTP CODE: {}'.format(http_code)
208 #print 'RESP: {}'.format(resp)
209 if http_code == 200:
210 if resp:
211 resp = json.loads(resp)
212 return resp
213 else:
214 raise ClientException('unexpected response from server')
215 else:
216 msg = ""
217 if resp:
218 try:
219 resp = json.loads(resp)
220 msg = resp['detail']
221 except ValueError:
222 msg = resp
223 raise ClientException(msg)
224 except ClientException as exc:
225 message="failed to get operation list of NS {}:\nerror:\n{}".format(
226 name,
227 exc.message)
228 raise ClientException(message)
229
230 def get_op(self, operationId):
231 """Returns the status of an operation
232 """
233 try:
234 self._apiResource = '/ns_lcm_op_occs'
235 self._apiBase = '{}{}{}'.format(self._apiName,
236 self._apiVersion, self._apiResource)
237 http_code, resp = self._http.get2_cmd('{}/{}'.format(self._apiBase, operationId))
238 #print 'HTTP CODE: {}'.format(http_code)
239 #print 'RESP: {}'.format(resp)
240 if http_code == 200:
241 if resp:
242 resp = json.loads(resp)
243 return resp
244 else:
245 raise ClientException('unexpected response from server')
246 else:
247 msg = ""
248 if resp:
249 try:
250 resp = json.loads(resp)
251 msg = resp['detail']
252 except ValueError:
253 msg = resp
254 raise ClientException(msg)
255 except ClientException as exc:
256 message="failed to get status of operation {}:\nerror:\n{}".format(
257 operationId,
258 exc.message)
259 raise ClientException(message)
260
261 def exec_op(self, name, op_name, op_data=None):
262 """Executes an operation on a NS
263 """
264 ns = self.get(name)
265 try:
266 self._apiResource = '/ns_instances'
267 self._apiBase = '{}{}{}'.format(self._apiName,
268 self._apiVersion, self._apiResource)
269 endpoint = '{}/{}/{}'.format(self._apiBase, ns['_id'], op_name)
270 #print 'OP_NAME: {}'.format(op_name)
271 #print 'OP_DATA: {}'.format(json.dumps(op_data))
272 http_code, resp = self._http.post_cmd(endpoint=endpoint, postfields_dict=op_data)
273 #print 'HTTP CODE: {}'.format(http_code)
274 #print 'RESP: {}'.format(resp)
275 if http_code in (200, 201, 202, 204):
276 if resp:
277 resp = json.loads(resp)
278 if not resp or 'id' not in resp:
279 raise ClientException('unexpected response from server - {}'.format(
280 resp))
281 print(resp['id'])
282 else:
283 msg = ""
284 if resp:
285 try:
286 msg = json.loads(resp)
287 except ValueError:
288 msg = resp
289 raise ClientException(msg)
290 except ClientException as exc:
291 message="failed to exec operation {}:\nerror:\n{}".format(
292 name,
293 exc.message)
294 raise ClientException(message)
295
296 def create_alarm(self, alarm):
297 data = {}
298 data["create_alarm_request"] = {}
299 data["create_alarm_request"]["alarm_create_request"] = alarm
300 try:
301 http_code, resp = self._http.post_cmd(endpoint='/test/message/alarm_request',
302 postfields_dict=data)
303 #print 'HTTP CODE: {}'.format(http_code)
304 #print 'RESP: {}'.format(resp)
305 if http_code in (200, 201, 202, 204):
306 #resp = json.loads(resp)
307 print('Alarm created')
308 else:
309 msg = ""
310 if resp:
311 try:
312 msg = json.loads(resp)
313 except ValueError:
314 msg = resp
315 raise ClientException('error: code: {}, resp: {}'.format(
316 http_code, msg))
317 except ClientException as exc:
318 message="failed to create alarm: alarm {}\n{}".format(
319 alarm,
320 exc.message)
321 raise ClientException(message)
322
323 def delete_alarm(self, name):
324 data = {}
325 data["delete_alarm_request"] = {}
326 data["delete_alarm_request"]["alarm_delete_request"] = {}
327 data["delete_alarm_request"]["alarm_delete_request"]["alarm_uuid"] = name
328 try:
329 http_code, resp = self._http.post_cmd(endpoint='/test/message/alarm_request',
330 postfields_dict=data)
331 #print 'HTTP CODE: {}'.format(http_code)
332 #print 'RESP: {}'.format(resp)
333 if http_code in (200, 201, 202, 204):
334 #resp = json.loads(resp)
335 print('Alarm deleted')
336 else:
337 msg = ""
338 if resp:
339 try:
340 msg = json.loads(resp)
341 except ValueError:
342 msg = resp
343 raise ClientException('error: code: {}, resp: {}'.format(
344 http_code, msg))
345 except ClientException as exc:
346 message="failed to delete alarm: alarm {}\n{}".format(
347 name,
348 exc.message)
349 raise ClientException(message)
350
351 def export_metric(self, metric):
352 data = {}
353 data["read_metric_data_request"] = metric
354 try:
355 http_code, resp = self._http.post_cmd(endpoint='/test/message/metric_request',
356 postfields_dict=data)
357 #print 'HTTP CODE: {}'.format(http_code)
358 #print 'RESP: {}'.format(resp)
359 if http_code in (200, 201, 202, 204):
360 #resp = json.loads(resp)
361 return 'Metric exported'
362 else:
363 msg = ""
364 if resp:
365 try:
366 msg = json.loads(resp)
367 except ValueError:
368 msg = resp
369 raise ClientException('error: code: {}, resp: {}'.format(
370 http_code, msg))
371 except ClientException as exc:
372 message="failed to export metric: metric {}\n{}".format(
373 metric,
374 exc.message)
375 raise ClientException(message)
376
377 def get_field(self, ns_name, field):
378 nsr = self.get(ns_name)
379 if nsr is None:
380 raise NotFound("failed to retrieve ns {}".format(ns_name))
381
382 if field in nsr:
383 return nsr[field]
384
385 raise NotFound("failed to find {} in ns {}".format(field, ns_name))