bdc85a7fe8b01a69c30f65a48dff035e6383f0f2
[osm/LW-UI.git] / instancehandler / views.py
1 #
2 # Copyright 2018 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16
17 from django.shortcuts import render, redirect
18 from django.http import HttpResponse, JsonResponse
19 import yaml
20 import json
21 import logging
22 from lib.osm.osmclient.clientv2 import Client
23 from lib.osm.osm_rdcl_parser import OsmParser
24 import authosm.utils as osmutils
25 from sf_t3d.decorators import login_required
26
27 logging.basicConfig(level=logging.DEBUG)
28 log = logging.getLogger('instancehandler/view.py')
29
30
31 @login_required
32 def list(request, type=None):
33 user = osmutils.get_user(request)
34 project_id = user.project_id
35 client = Client()
36 result = {'type': type, 'project_id': project_id}
37 if "OSM_ERROR" in request.session:
38 result['alert_error'] = request.session["OSM_ERROR"]
39 del request.session["OSM_ERROR"]
40 raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
41 if 'application/json' not in raw_content_types:
42 return __response_handler(request, result, 'instance_list.html')
43 instance_list = None
44 if type == 'ns':
45 instance_list = client.ns_list(user.get_token())
46 elif type == 'vnf':
47 instance_list = client.vnf_list(user.get_token())
48 elif type == 'pdu':
49 instance_list = client.pdu_list(user.get_token())
50 elif type == 'nsi':
51 instance_list = client.nsi_list(user.get_token())
52
53 result['instances'] = instance_list['data'] if instance_list and instance_list['error'] is False else []
54
55 return __response_handler(request, result, 'instance_list.html')
56
57 @login_required
58 def create(request, type=None):
59 result = {}
60 config_vim_account_id = {}
61 config_wim_account_id = {}
62 user = osmutils.get_user(request)
63 client = Client()
64
65 def get_vim_account_id(vim_account):
66 if config_vim_account_id.get(vim_account):
67 return config_vim_account_id[vim_account]
68 result_client = client.vim_list(user.get_token())
69 vim_list = result_client['data'] if result_client and result_client['error'] is False else []
70 if vim_list is None or len(vim_list) == 0:
71 raise ValueError("cannot find vim account '{}'".format(vim_account))
72 for vim in vim_list:
73 if vim_account == vim['name']:
74 config_vim_account_id[vim_account] = vim['uuid']
75 return vim['uuid']
76
77 def get_wim_account_id(wim_account):
78
79 if config_wim_account_id.get(wim_account):
80 return config_wim_account_id[wim_account]
81 result_client = client.wim_list(user.get_token())
82 wim_list = result_client['data'] if result_client and result_client['error'] is False else []
83 if wim_list is None or len(wim_list) == 0:
84 raise ValueError("cannot find wim account '{}'".format(wim_account))
85 for wim in wim_list:
86 if wim_account == wim['name']:
87 config_wim_account_id[wim_account] = wim['uuid']
88 return wim['uuid']
89
90
91 if type == 'ns':
92 try:
93
94 ns_data = {
95 "nsName": request.POST.get('nsName', 'WithoutName'),
96 "nsDescription": request.POST.get('nsDescription', ''),
97 "nsdId": request.POST.get('nsdId', ''),
98 "vimAccountId": request.POST.get('vimAccountId', ''),
99 }
100 ns_data["ssh_keys"] = []
101 if 'ssh_key' in request.POST and request.POST.get('ssh_key') != '':
102 ns_data["ssh_keys"].append(request.POST.get('ssh_key'))
103 ssh_key_files = request.FILES.getlist('ssh_key_files')
104 for ssh_key_file in ssh_key_files:
105 ssh_key = ''
106 for line in ssh_key_file:
107 ssh_key = ssh_key + line.decode()
108 ns_data["ssh_keys"].append(ssh_key)
109
110
111 config_file = request.FILES.get('config_file')
112
113 if config_file is not None:
114 config = ''
115 for line in config_file:
116 config = config + line.decode()
117 ns_config = yaml.load(config)
118 elif 'config' in request.POST and request.POST.get('config') != '':
119 ns_config = yaml.load(request.POST.get('config'))
120 else:
121 ns_config = None
122
123
124 if ns_config is not None:
125 if isinstance(ns_config, dict):
126 if "vim-network-name" in ns_config:
127 ns_config["vld"] = ns_config.pop("vim-network-name")
128 if "vld" in ns_config:
129 for vld in ns_config["vld"]:
130 if vld.get("vim-network-name"):
131 if isinstance(vld["vim-network-name"], dict):
132 vim_network_name_dict = {}
133 for vim_account, vim_net in list(vld["vim-network-name"].items()):
134 vim_network_name_dict[get_vim_account_id(vim_account)] = vim_net
135 vld["vim-network-name"] = vim_network_name_dict
136 if "wim_account" in vld and vld["wim_account"] is not None:
137 vld["wimAccountId"] = get_wim_account_id(vld.pop("wim_account"))
138 ns_data["vld"] = ns_config["vld"]
139 if "vnf" in ns_config:
140 for vnf in ns_config["vnf"]:
141 if vnf.get("vim_account"):
142 vnf["vimAccountId"] = get_vim_account_id(vnf.pop("vim_account"))
143 ns_data["vnf"] = ns_config["vnf"]
144
145 if "additionalParamsForNs" in ns_config:
146 ns_data["additionalParamsForNs"] = ns_config.pop("additionalParamsForNs")
147 if not isinstance(ns_data["additionalParamsForNs"], dict):
148 raise ValueError("Error 'additionalParamsForNs' must be a dictionary")
149 if "additionalParamsForVnf" in ns_config:
150 ns_data["additionalParamsForVnf"] = ns_config.pop("additionalParamsForVnf")
151 if not isinstance(ns_data["additionalParamsForVnf"], list):
152 raise ValueError("Error 'additionalParamsForVnf' must be a list")
153 for additional_param_vnf in ns_data["additionalParamsForVnf"]:
154 if not isinstance(additional_param_vnf, dict):
155 raise ValueError("Error 'additionalParamsForVnf' items must be dictionaries")
156 if not additional_param_vnf.get("member-vnf-index"):
157 raise ValueError("Error 'additionalParamsForVnf' items must contain "
158 "'member-vnf-index'")
159 if not additional_param_vnf.get("additionalParams"):
160 raise ValueError("Error 'additionalParamsForVnf' items must contain "
161 "'additionalParams'")
162 if "wim_account" in ns_config:
163 wim_account = ns_config.pop("wim_account")
164 if wim_account is not None:
165 ns_data['wimAccountId'] = get_wim_account_id(wim_account)
166
167 except Exception as e:
168 request.session["OSM_ERROR"] = "Error creating the NS; Invalid parameters provided."
169 return __response_handler(request, {}, 'instances:list', to_redirect=True, type='ns', )
170 result = client.ns_create(user.get_token(), ns_data)
171 return __response_handler(request, result, 'instances:list', to_redirect=True, type='ns')
172
173 elif type == 'nsi':
174 try:
175 nsi_data = {
176 "nsiName": request.POST.get('nsiName', 'WithoutName'),
177 "nsiDescription": request.POST.get('nsiDescription', ''),
178 "nstId": request.POST.get('nstId', ''),
179 "vimAccountId": request.POST.get('vimAccountId', ''),
180 }
181
182 nsi_data["ssh_keys"] = []
183 if 'ssh_key' in request.POST and request.POST.get('ssh_key') != '':
184 nsi_data["ssh_keys"].append(request.POST.get('ssh_key'))
185 ssh_key_files = request.FILES.getlist('ssh_key_files')
186 for ssh_key_file in ssh_key_files:
187 ssh_key = ''
188 for line in ssh_key_file:
189 ssh_key = ssh_key + line.decode()
190 nsi_data["ssh_keys"].append(ssh_key)
191 nsi_data["ssh_keys"] = ','.join(nsi_data["ssh_keys"])
192
193 config_file = request.FILES.get('config_file')
194
195 if config_file is not None:
196 config = ''
197 for line in config_file:
198 config = config + line.decode()
199 nsi_config = yaml.load(config)
200 elif 'config' in request.POST and request.POST.get('config') != '':
201 nsi_config = yaml.load(request.POST.get('config'))
202 else:
203 nsi_config = None
204
205 if nsi_config is not None:
206 if "netslice-vld" in nsi_config:
207 for vld in nsi_config["netslice-vld"]:
208 if vld.get("vim-network-name"):
209 if isinstance(vld["vim-network-name"], dict):
210 vim_network_name_dict = {}
211 for vim_account, vim_net in list(vld["vim-network-name"].items()):
212 vim_network_name_dict[get_vim_account_id(vim_account)] = vim_net
213 vld["vim-network-name"] = vim_network_name_dict
214 nsi_data["netslice-vld"] = nsi_config["netslice-vld"]
215 if "netslice-subnet" in nsi_config:
216 for nssubnet in nsi_config["netslice-subnet"]:
217 if "vld" in nssubnet:
218 for vld in nssubnet["vld"]:
219 if vld.get("vim-network-name"):
220 if isinstance(vld["vim-network-name"], dict):
221 vim_network_name_dict = {}
222 for vim_account, vim_net in list(vld["vim-network-name"].items()):
223 vim_network_name_dict[get_vim_account_id(vim_account)] = vim_net
224 vld["vim-network-name"] = vim_network_name_dict
225 if "vnf" in nssubnet:
226 for vnf in nsi_config["vnf"]:
227 if vnf.get("vim_account"):
228 vnf["vimAccountId"] = get_vim_account_id(vnf.pop("vim_account"))
229 nsi_data["netslice-subnet"] = nsi_config["netslice-subnet"]
230 if "additionalParamsForNsi" in nsi_config:
231 nsi_data["additionalParamsForNsi"] = nsi_config.pop("additionalParamsForNsi")
232 if not isinstance(nsi_data["additionalParamsForNsi"], dict):
233 raise ValueError("Error at 'additionalParamsForNsi' must be a dictionary")
234 if "additionalParamsForSubnet" in nsi_config:
235 nsi_data["additionalParamsForSubnet"] = nsi_config.pop("additionalParamsForSubnet")
236 if not isinstance(nsi_data["additionalParamsForSubnet"], list):
237 raise ValueError("Error 'additionalParamsForSubnet' must be a list")
238 for additional_param_subnet in nsi_data["additionalParamsForSubnet"]:
239 if not isinstance(additional_param_subnet, dict):
240 raise ValueError("Error 'additionalParamsForSubnet' items must be dictionaries")
241 if not additional_param_subnet.get("id"):
242 raise ValueError("Error 'additionalParamsForSubnet' items must contain subnet 'id'")
243 if not additional_param_subnet.get("additionalParamsForNs") and\
244 not additional_param_subnet.get("additionalParamsForVnf"):
245 raise ValueError("Error 'additionalParamsForSubnet' items must contain "
246 "'additionalParamsForNs' and/or 'additionalParamsForVnf'")
247 except Exception as e:
248 request.session["OSM_ERROR"] = "Error creating the NSI; Invalid parameters provided."
249 return __response_handler(request, {}, 'instances:list', to_redirect=True, type=type)
250
251 result = client.nsi_create(user.get_token(), nsi_data)
252 return __response_handler(request, result, 'instances:list', to_redirect=True, type=type)
253
254 elif type == 'pdu':
255 interface_param_name = request.POST.getlist('interfaces_name')
256 interface_param_ip = request.POST.getlist('interfaces_ip')
257 interface_param_mgmt = request.POST.getlist('interfaces_mgmt')
258 interface_param_netname = request.POST.getlist('interfaces_vimnetname')
259
260 pdu_payload = {
261 "name": request.POST.get('name'),
262 "type": request.POST.get('pdu_type'),
263 "vim_accounts": request.POST.getlist('pdu_vim_accounts'),
264 "description": request.POST.get('description'),
265 "interfaces": []
266 }
267 for i in (0,len(interface_param_name)-1):
268 pdu_payload['interfaces'].append({
269 'name': interface_param_name[i],
270 'mgmt': True if interface_param_mgmt[i] == 'true' else False,
271 'ip-address': interface_param_ip[i],
272 'vim-network-name': interface_param_netname[i]
273 })
274 result = client.pdu_create(user.get_token(), pdu_payload)
275 if result['error']:
276 return __response_handler(request, result['data'], url=None,
277 status=result['data']['status'] if 'status' in result['data'] else 500)
278 else:
279 return __response_handler(request, {}, url=None, status=200)
280
281 @login_required
282 def ns_operations(request, instance_id=None, type=None):
283 user = osmutils.get_user(request)
284 project_id = user.project_id
285
286 result = {'type': type, 'project_id': project_id, 'instance_id': instance_id}
287 raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
288 if 'application/json' not in raw_content_types:
289 return __response_handler(request, result, 'instance_operations_list.html')
290 client = Client()
291 if type == 'ns':
292 op_list = client.ns_op_list(user.get_token(), instance_id)
293 elif type == 'nsi':
294 op_list = client.nsi_op_list(user.get_token(), instance_id)
295 result['operations'] = op_list['data'] if op_list and op_list['error'] is False else []
296
297 return __response_handler(request, result, 'instance_operations_list.html')
298
299 @login_required
300 def ns_operation(request, op_id, instance_id=None, type=None):
301 user = osmutils.get_user(request)
302 client = Client()
303 result = client.ns_op(user.get_token(), op_id)
304 return __response_handler(request, result['data'])
305
306
307 @login_required
308 def action(request, instance_id=None, type=None):
309 user = osmutils.get_user(request)
310 client = Client()
311 # result = client.ns_action(instance_id, action_payload)
312 primitive_param_keys = request.POST.getlist('primitive_params_name')
313 primitive_param_value = request.POST.getlist('primitive_params_value')
314 action_payload = {
315 "vnf_member_index": request.POST.get('vnf_member_index'),
316 "primitive": request.POST.get('primitive'),
317 "primitive_params": {k: v for k, v in zip(primitive_param_keys, primitive_param_value) if len(k) > 0}
318 }
319
320 result = client.ns_action(user.get_token(), instance_id, action_payload)
321 if result['error']:
322 return __response_handler(request, result['data'], url=None,
323 status=result['data']['status'] if 'status' in result['data'] else 500)
324 else:
325 return __response_handler(request, {}, url=None, status=200)
326
327
328 @login_required
329 def delete(request, instance_id=None, type=None):
330 force = bool(request.GET.get('force', False))
331 result = {}
332 user = osmutils.get_user(request)
333 client = Client()
334 if type == 'ns':
335 result = client.ns_delete(user.get_token(), instance_id, force)
336 elif type == 'pdu':
337 result = client.pdu_delete(user.get_token(), instance_id)
338 elif type == 'nsi':
339 result = client.nsi_delete(user.get_token(), instance_id, force)
340
341 if result['error']:
342 return __response_handler(request, result['data'], url=None,
343 status=result['data']['status'] if 'status' in result['data'] else 500)
344 else:
345 return __response_handler(request, {}, url=None, status=200)
346
347 @login_required
348 def show_topology(request, instance_id=None, type=None):
349 user = osmutils.get_user(request)
350 project_id = user.project_id
351 raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
352 if 'application/json' in raw_content_types:
353 client = Client()
354 nsr_object = {'nsr': {}, 'vnfr': {}, 'vnfd': {}}
355 if type == 'ns':
356
357 nsr_resp = client.ns_get(user.get_token(), instance_id)
358 nsr_object['nsr'] = nsr_resp['data']
359 if 'constituent-vnfr-ref' in nsr_object['nsr'] :
360 for vnfr_id in nsr_object['nsr']['constituent-vnfr-ref']:
361 vnfr_resp = client.vnf_get(user.get_token(), vnfr_id)
362 vnfr = vnfr_resp['data']
363 nsr_object['vnfr'][vnfr['id']] = vnfr
364 if vnfr['vnfd-id'] not in nsr_object['vnfd']:
365 vnfd_resp = client.vnfd_get(user.get_token(), vnfr['vnfd-id'])
366 nsr_object['vnfd'][vnfr['vnfd-id']] = vnfd_resp['vnfd:vnfd-catalog']['vnfd'][0]
367
368 test = OsmParser()
369
370 result = test.nsr_to_graph(nsr_object)
371 return __response_handler(request, result)
372 else:
373 result = {'type': type, 'project_id': project_id, 'instance_id': instance_id}
374 return __response_handler(request, result, 'instance_topology_view.html')
375
376
377 @login_required
378 def show(request, instance_id=None, type=None):
379 # result = {}
380 user = osmutils.get_user(request)
381 project_id = user.project_id
382 client = Client()
383 if type == 'ns':
384 result = client.ns_get(user.get_token(), instance_id)
385 elif type == 'vnf':
386 result = client.vnf_get(user.get_token(), instance_id)
387 elif type == 'pdu':
388 result = client.pdu_get(user.get_token(), instance_id)
389 elif type == 'nsi':
390 result = client.nsi_get(user.get_token(), instance_id)
391
392 return __response_handler(request, result)
393
394
395 @login_required
396 def export_metric(request, instance_id=None, type=None):
397 metric_data = request.POST.dict()
398 user = osmutils.get_user(request)
399 project_id = user.project_id
400 client = Client()
401 keys = ["collection_period",
402 "vnf_member_index",
403 "metric_name",
404 "correlation_id",
405 "vdu_name",
406 "collection_unit"]
407 metric_data = dict(filter(lambda i: i[0] in keys and len(i[1]) > 0, metric_data.items()))
408
409 result = client.ns_metric_export(user.get_token(), instance_id, metric_data)
410
411 if result['error']:
412 return __response_handler(request, result['data'], url=None,
413 status=result['data']['status'] if 'status' in result['data'] else 500)
414 else:
415 return __response_handler(request, {}, url=None, status=200)
416
417
418 @login_required
419 def create_alarm(request, instance_id=None, type=None):
420 metric_data = request.POST.dict()
421 user = osmutils.get_user(request)
422 project_id = user.project_id
423 client = Client()
424
425 keys = ["threshold_value",
426 "vnf_member_index",
427 "metric_name",
428 "vdu_name",
429 "alarm_name",
430 "correlation_id",
431 "statistic",
432 "operation",
433 "severity"]
434 metric_data = dict(filter(lambda i: i[0] in keys and len(i[1]) > 0, metric_data.items()))
435
436 result = client.ns_alarm_create(user.get_token(), instance_id, metric_data)
437 if result['error']:
438 return __response_handler(request, result['data'], url=None,
439 status=result['data']['status'] if 'status' in result['data'] else 500)
440 else:
441 return __response_handler(request, {}, url=None, status=200)
442
443
444 def __response_handler(request, data_res, url=None, to_redirect=None, *args, **kwargs):
445 raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
446 if not to_redirect and ('application/json' in raw_content_types or url is None):
447 return HttpResponse(json.dumps(data_res), content_type="application/json", *args, **kwargs)
448 elif to_redirect:
449 return redirect(url, *args, **kwargs)
450 else:
451 return render(request, url, data_res)