create ns instance from ns list; minor fix
[osm/LW-UI.git] / projecthandler / views.py
1 #
2 # Copyright 2017 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 import json
18
19 from django.contrib.auth.decorators import login_required
20 from django.http import HttpResponse, JsonResponse
21 from django.middleware.csrf import get_token
22 from django.shortcuts import render, redirect
23 from django.template.loader import render_to_string
24 from lib.util import Util
25 from sf_user.models import CustomUser
26 import tarfile
27
28
29 from projecthandler.osm_model import OsmProject
30 from projecthandler.models import Project
31
32
33 Project.add_project_type('osm', OsmProject)
34
35
36
37 from projecthandler.models import Repository
38
39 @login_required
40 def home(request):
41 return render(request, 'home.html', {})
42
43
44 @login_required
45 def create_new_project(request):
46 if request.method == 'POST':
47 error_msgs = []
48 user = CustomUser.objects.get(id=request.user.id)
49 name = request.POST.get('name', 'WithoutName')
50 info = request.POST.get('info', ' ')
51 type = request.POST.get('type', '')
52 start_from = request.POST.get('startfrom', 'scratch')
53
54 project_types = Project.get_project_types()
55 if type in project_types:
56 project_class = project_types[type]
57
58 else:
59 # FIXME this error is not handled
60 error_msgs.append('Project type undefined.')
61 return render(request, 'error.html',
62 {'error_msg': 'Error creating new project, project type undefined. Please retry.'})
63
64 try:
65
66 if start_from == 'scratch':
67 print 'from scratch'
68 data_project = {}
69
70 elif start_from == 'files':
71 print 'from files'
72 data_project = project_class.data_project_from_files(request)
73
74 elif start_from == 'example':
75 print 'from example'
76 data_project = project_class.data_project_from_example(request)
77
78 project = project_class.create_project(name, user, False, info, data_project)
79 # print project.get_dataproject()
80
81
82 except Exception as e:
83 print 'Error creating ' + type + ' project! Please retry.'
84 print e
85 return render(request, 'error.html', {'error_msg': 'Error creating ' + type + ' project! Please retry.'})
86 return redirect('projects:open_project', project_id=project.id)
87
88 elif request.method == 'GET':
89 csrf_token_value = get_token(request)
90 result = {}
91 data_type_selector = [{
92 'id': '-1',
93 'text': 'Select an option'
94 }]
95 type_example_files = {}
96 type_container_template = ''
97 project_types = Project.get_project_types()
98 print "project_types", project_types.keys()
99 for type in project_types:
100 project_class = project_types[type]
101 type_example_files.update(project_class.get_example_list())
102 data_type_selector.append({
103 'id': type,
104 'text': type,
105 'value': type
106 })
107 type_container_template += render_to_string(type + '/' + type + '_new_project.html')
108
109 result.update({'type_example_files': json.dumps(type_example_files)})
110 result.update({'data_type_selector': json.dumps(data_type_selector)})
111 result.update({'type_container_template': type_container_template})
112 result.update({'csrf_token': csrf_token_value})
113 return render(request, 'new_project.html', result)
114
115
116 @login_required
117 def user_projects(request):
118 csrf_token_value = get_token(request)
119 user = CustomUser.objects.get(id=request.user.id)
120 projects = Project.objects.filter(owner=user).select_subclasses()
121
122 return render(request, 'projectlist.html', {
123 'projects': list(projects),
124 'csrf_token': csrf_token_value
125 })
126
127
128 @login_required
129 def open_project(request, project_id=None):
130 try:
131 projects = Project.objects.filter(id=project_id).select_subclasses()
132 project_overview = projects[0].get_overview_data()
133 prj_token = project_overview['type']
134 print request.COOKIES.keys()
135 return render(request, prj_token + '/' + prj_token + '_project_details.html',
136 {'project_overview': project_overview, 'project_id': project_id})
137
138 except Exception as e:
139 print e
140 return render(request, 'error.html', {'error_msg': 'Error open project! Please retry.'})
141
142
143 @login_required
144 def delete_project(request, project_id=None):
145 if request.method == 'POST':
146
147 try:
148 Project.objects.filter(id=project_id).delete()
149 return redirect('projects:projects_list')
150 except Exception as e:
151 print e
152 return render(request, 'error.html', {'error_msg': 'Error deleting Project.'})
153
154 elif request.method == 'GET':
155 try:
156 projects = Project.objects.filter(id=project_id).select_subclasses()
157 project_overview = projects[0].get_overview_data()
158 prj_token = project_overview['type']
159 # example: 'etsi/etsi_project_delete.html'
160 print prj_token + '/' + prj_token + '_project_delete.html', project_overview['name']
161 return render(request, prj_token + '/' + prj_token + '_project_delete.html',
162 {'project_id': project_id, 'project_name': project_overview['name']})
163
164 except Exception as e:
165 print e
166 return render(request, 'error.html', {'error_msg': 'Project not found.'})
167
168
169 @login_required
170 def show_descriptors(request, project_id=None, descriptor_type=None):
171 csrf_token_value = get_token(request)
172 projects = Project.objects.filter(id=project_id).select_subclasses()
173 project_overview = projects[0].get_overview_data()
174 prj_token = project_overview['type']
175
176 url = prj_token + '/' + prj_token + '_project_descriptors.html'
177 return __response_handler(request, {
178 'descriptors': projects[0].get_descriptors(descriptor_type),
179 'project_id': project_id,
180 'project_type': prj_token,
181 'project_overview_data': project_overview,
182 "csrf_token_value": csrf_token_value,
183 'descriptor_type': descriptor_type
184 },url)
185
186
187 @login_required
188 def graph(request, project_id=None):
189 if request.method == 'GET':
190 csrf_token_value = get_token(request)
191 projects = Project.objects.filter(id=project_id).select_subclasses()
192 project_overview = projects[0].get_overview_data()
193 prj_token = project_overview['type']
194 # example : 'etsi/project_graph.html'
195 return render(request, prj_token + '/project_graph.html', {
196 'project_id': project_id,
197 'project_overview_data': projects[0].get_overview_data(),
198 'collapsed_sidebar': False
199 })
200
201
202 @login_required
203 def graph_data(request, project_id=None, descriptor_id=None):
204 print 'graph_data', project_id, descriptor_id
205 projects = Project.objects.filter(id=project_id).select_subclasses()
206 project_overview = projects[0].get_overview_data()
207 # data = projects[0].get_overview_data()
208 prj_token = project_overview['type']
209
210 topology = projects[0].get_graph_data_json_topology(descriptor_id)
211 response = HttpResponse(topology, content_type="application/json")
212 response["Access-Control-Allow-Origin"] = "*"
213
214 return response
215
216
217 @login_required
218 def delete_descriptor(request, project_id=None, descriptor_type=None, descriptor_id=None):
219 csrf_token_value = get_token(request)
220 projects = Project.objects.filter(id=project_id).select_subclasses()
221 result = projects[0].delete_descriptor(descriptor_type, descriptor_id)
222 project_overview = projects[0].get_overview_data()
223 prj_token = project_overview['type']
224 page = prj_token + '/' + prj_token + '_project_descriptors.html'
225
226 return render(request, page, {
227 'descriptors': projects[0].get_descriptors(descriptor_type),
228 'project_id': project_id,
229 'project_overview_data': project_overview,
230 "csrf_token_value": csrf_token_value,
231 'descriptor_type': descriptor_type,
232 #'alert_message': {
233 # 'success': result,
234 # 'message': "Delete succeeded!" if result else 'Error in delete'}
235 })
236
237
238 @login_required
239 def clone_descriptor(request, project_id=None, descriptor_type=None, descriptor_id=None):
240 csrf_token_value = get_token(request)
241 projects = Project.objects.filter(id=project_id).select_subclasses()
242 new_id = request.GET.get('newid', '')
243 result = projects[0].clone_descriptor(descriptor_type, descriptor_id, new_id)
244 project_overview = projects[0].get_overview_data()
245 prj_token = project_overview['type']
246 page = prj_token + '/' + prj_token + '_project_descriptors.html'
247
248 return render(request, page, {
249 'descriptors': projects[0].get_descriptors(descriptor_type),
250 'project_id': project_id,
251 'project_overview_data': project_overview,
252 "csrf_token_value": csrf_token_value,
253 'descriptor_type': descriptor_type,
254 'alert_message': {
255 'success': result,
256 'message': "Cloned!" if result else 'Error in cloning'}
257 })
258
259
260 @login_required
261 def new_descriptor(request, project_id=None, descriptor_type=None):
262 projects = Project.objects.filter(id=project_id).select_subclasses()
263 project_overview = projects[0].get_overview_data()
264 prj_token = project_overview['type']
265 page = prj_token + '/descriptor/descriptor_new.html'
266 if request.method == 'GET':
267 request_id = request.GET.get('id', '')
268
269 json_template = projects[0].get_new_descriptor(descriptor_type, request_id)
270 print 'new descriptor GET', json_template
271
272 descriptor_string_yaml = Util.json2yaml(json_template)
273 descriptor_string_json = json.dumps(json_template)
274
275 return render(request, page, {
276 'project_id': project_id,
277 'descriptor_type': descriptor_type,
278 'descriptor_id': request_id,
279 'project_overview_data': project_overview,
280 'descriptor_strings': {'descriptor_string_yaml': descriptor_string_yaml,
281 'descriptor_string_json': descriptor_string_json}
282 })
283 elif request.method == 'POST':
284 csrf_token_value = get_token(request)
285 data_type = request.POST.get('type')
286 print "TYPE", data_type
287 if data_type == "file":
288 file_uploaded = request.FILES['file']
289 text = file_uploaded.read()
290 data_type = file_uploaded.name.split(".")[-1]
291 desc_name = file_uploaded.name.split(".")[0]
292 result = projects[0].create_descriptor(desc_name, descriptor_type, text, data_type, file_uploaded)
293 else:
294 text = request.POST.get('text')
295 desc_name = request.POST.get('id')
296 result = projects[0].create_descriptor(desc_name, descriptor_type, text, data_type)
297
298
299 response_data = {
300 'project_id': project_id,
301 'descriptor_type': descriptor_type,
302 'project_overview_data': projects[0].get_overview_data(),
303 'descriptor_id': result,
304 'alert_message': {
305 'success': True if result != False else False,
306 'message': "Descriptor created" if result else 'Error in creation'}
307 }
308 status_code = 200 if result != False else 500
309 response = HttpResponse(json.dumps(response_data), content_type="application/json", status=status_code)
310 response["Access-Control-Allow-Origin"] = "*"
311 return response
312
313
314 @login_required
315 def edit_descriptor(request, project_id=None, descriptor_id=None, descriptor_type=None):
316 if request.method == 'POST':
317 print "edit_descriptor"
318 projects = Project.objects.filter(id=project_id).select_subclasses()
319 result = projects[0].edit_descriptor(descriptor_type, descriptor_id, request.POST.get('text'),
320 request.POST.get('type'))
321 response_data = {
322 'project_id': project_id,
323 'descriptor_type': descriptor_type,
324 #'project_overview_data': projects[0].get_overview_data(),
325 'alert_message': {
326 'success': True if result else False,
327 'message': "Descriptor modified." if result else 'Error during descriptor editing.'}
328 }
329 status_code = 200 if result else 500
330 response = HttpResponse(json.dumps(response_data), content_type="application/json", status=status_code)
331 response["Access-Control-Allow-Origin"] = "*"
332 return response
333
334 elif request.method == 'GET':
335 csrf_token_value = get_token(request)
336 projects = Project.objects.filter(id=project_id).select_subclasses()
337 project_overview = projects[0].get_overview_data()
338 print project_overview
339 prj_token = project_overview['type']
340 page = prj_token + '/descriptor/descriptor_view.html'
341
342 descriptor = projects[0].get_descriptor(descriptor_id, descriptor_type)
343
344 descriptor_string_json = json.dumps(descriptor)
345 descriptor_string_yaml = Util.json2yaml(descriptor)
346 # print descriptor
347 return render(request, page, {
348 'project_id': project_id,
349 'descriptor_id': descriptor_id,
350 'project_overview_data': projects[0].get_overview_data(),
351 'descriptor_type': descriptor_type,
352 'descriptor_strings': {'descriptor_string_yaml': descriptor_string_yaml,
353 'descriptor_string_json': descriptor_string_json}})
354
355
356 @login_required
357 def graph_positions(request, project_id=None):
358 if request.method == 'POST':
359 projects = Project.objects.filter(id=project_id).select_subclasses()
360 result = projects[0].edit_graph_positions(json.loads(request.POST.get('positions')))
361 status_code = 200 if result else 500
362 response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
363 response["Access-Control-Allow-Origin"] = "*"
364 return response
365
366
367 @login_required
368 def add_element(request, project_id=None):
369 if request.method == 'POST':
370 projects = Project.objects.filter(id=project_id).select_subclasses()
371 result = projects[0].get_add_element(request)
372
373 status_code = 200 if result else 500
374 response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
375 response["Access-Control-Allow-Origin"] = "*"
376 return response
377
378
379 @login_required
380 def remove_element(request, project_id=None):
381 if request.method == 'POST':
382 projects = Project.objects.filter(id=project_id).select_subclasses()
383 result = projects[0].get_remove_element(request)
384
385 status_code = 200 if result else 500
386 response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
387 response["Access-Control-Allow-Origin"] = "*"
388 return response
389
390
391 @login_required
392 def add_link(request, project_id=None):
393 if request.method == 'POST':
394 projects = Project.objects.filter(id=project_id).select_subclasses()
395 result = projects[0].get_add_link(request)
396
397 status_code = 200 if result else 500
398 response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
399 response["Access-Control-Allow-Origin"] = "*"
400 return response
401
402
403 @login_required
404 def remove_link(request, project_id=None):
405 if request.method == 'POST':
406 projects = Project.objects.filter(id=project_id).select_subclasses()
407 result = projects[0].get_remove_link(request)
408
409 status_code = 200 if result else 500
410 response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
411 response["Access-Control-Allow-Origin"] = "*"
412 return response
413
414 @login_required
415 def get_available_nodes(request, project_id=None):
416 if request.method == 'GET':
417 csrf_token_value = get_token(request)
418 projects = Project.objects.filter(id=project_id).select_subclasses()
419 print "get_available_nodes", request.GET.dict()
420 result = projects[0].get_available_nodes(request.GET.dict())
421 status_code = 500 if result == None else 200
422 print json.dumps(result)
423 response = HttpResponse(json.dumps(result), content_type="application/json", status=status_code)
424 response["Access-Control-Allow-Origin"] = "*"
425 return response
426
427 @login_required
428 def overviewelement(request, project_id=None):
429 if request.method == 'GET':
430 result = {}
431 error_msg = None
432 try:
433 projects = Project.objects.filter(id=project_id).select_subclasses()
434 project = projects[0]
435 parameters = request.GET.dict()
436 print "parameters", parameters
437 result = project.get_node_overview(**parameters)
438 except Exception as e:
439 error_msg = str(e)
440
441 if error_msg is not None:
442 return JsonResponse({'error': {'error_msg': str(error_msg)}})
443
444 return JsonResponse({'node_overview': result})
445
446 # ETSI specific method #
447 @login_required
448 def add_node_to_vnffg(request, project_id=None):
449 print "add_node_to_vnffg" # TODO log
450 if request.method == 'POST':
451 projects = Project.objects.filter(id=project_id).select_subclasses()
452 result = projects[0].add_node_to_vnffg(request)
453
454 status_code = 200 if result else 500
455 response = HttpResponse(json.dumps({}), content_type="application/json", status=status_code)
456 response["Access-Control-Allow-Origin"] = "*"
457 return response
458
459
460 @login_required
461 def unused_vnf(request, project_id=None, nsd_id=None):
462 if request.method == 'GET':
463 print 'in method unused_vnf : ', project_id, nsd_id # TODO log
464 projects = Project.objects.filter(id=project_id).select_subclasses()
465 result = projects[0].get_unused_vnf(nsd_id)
466 status_code = 500 if result == None else 200
467 response = HttpResponse(json.dumps(result), content_type="application/json", status=status_code)
468 response["Access-Control-Allow-Origin"] = "*"
469 return response
470
471 # end ETSI specific method #
472
473
474 # OSM specific method #
475 def get_package_files_list(request, project_id, project, descriptor_id, descriptor_type):
476 files_list = []
477 try:
478 files_list = project.get_package_files_list(descriptor_type, descriptor_id)
479 result = {'files': files_list}
480 except Exception as e:
481 print e
482 url = 'error.html'
483 result = {'error_msg': 'Unknown error.'}
484 return __response_handler(request, result)
485
486
487 def download_pkg(request, project_id, project, descriptor_id, descriptor_type):
488 tar_pkg = project.download_pkg(project, descriptor_id, descriptor_type)
489
490 response = HttpResponse(content_type="application/tgz")
491 response["Content-Disposition"] = "attachment; filename=osm_export.tar.gz"
492 response.write(tar_pkg.getvalue())
493 return response
494
495
496 def create_ns(request, project_id, project, descriptor_id, descriptor_type):
497 files_list = []
498 try:
499 ns_data={
500 "nsName": request.POST.get('nsName', 'WithoutName'),
501 "nsDescription": request.POST.get('nsDescription', ''),
502 "nsdId": request.POST.get('nsdId', ''),
503 "vimAccountId": request.POST.get('vimAccountId', ''),
504 "ssh-authorized-key": [
505 {
506 request.POST.get('key-pair-ref', ''): request.POST.get('keyValue', '')
507 }
508 ]
509 }
510 #result = project.create_ns(descriptor_type, descriptor_id, ns_data)
511
512 except Exception as e:
513 print e
514 url = 'error.html'
515 result = {'error_msg': 'Unknown error.'}
516 return __response_handler(request, result)
517
518 # end OSM specific method #
519
520 @login_required
521 def custom_action(request, project_id=None, descriptor_id=None, descriptor_type=None, action_name=None):
522 if request.method == 'GET':
523 projects = Project.objects.filter(id=project_id).select_subclasses()
524 print "Custom action: " + action_name
525 return globals()[action_name](request, project_id, projects[0], descriptor_id, descriptor_type)
526
527
528 def __response_handler(request, data_res, url=None, to_redirect=None, *args, **kwargs):
529 raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
530 if 'application/json' in raw_content_types:
531 return JsonResponse(data_res)
532 elif to_redirect:
533 return redirect(url, *args, **kwargs)
534 else:
535 return render(request, url, data_res)