2 # Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
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
29 from projecthandler
.osm_model
import OsmProject
30 from projecthandler
.models
import Project
33 Project
.add_project_type('osm', OsmProject
)
37 from projecthandler
.models
import Repository
41 return render(request
, 'home.html', {})
45 def create_new_project(request
):
46 if request
.method
== 'POST':
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')
54 project_types
= Project
.get_project_types()
55 if type in project_types
:
56 project_class
= project_types
[type]
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.'})
66 if start_from
== 'scratch':
70 elif start_from
== 'files':
72 data_project
= project_class
.data_project_from_files(request
)
74 elif start_from
== 'example':
76 data_project
= project_class
.data_project_from_example(request
)
78 project
= project_class
.create_project(name
, user
, False, info
, data_project
)
79 # print project.get_dataproject()
82 except Exception as e
:
83 print 'Error creating ' + type + ' project! Please retry.'
85 return render(request
, 'error.html', {'error_msg': 'Error creating ' + type + ' project! Please retry.'})
86 return redirect('projects:open_project', project_id
=project
.id)
88 elif request
.method
== 'GET':
89 csrf_token_value
= get_token(request
)
91 data_type_selector
= [{
93 'text': 'Select an option'
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({
107 type_container_template
+= render_to_string(type + '/' + type + '_new_project.html')
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
)
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()
122 return render(request
, 'projectlist.html', {
123 'projects': list(projects
),
124 'csrf_token': csrf_token_value
129 def open_project(request
, project_id
=None):
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
})
138 except Exception as e
:
140 return render(request
, 'error.html', {'error_msg': 'Error open project! Please retry.'})
144 def delete_project(request
, project_id
=None):
145 if request
.method
== 'POST':
148 Project
.objects
.filter(id=project_id
).delete()
149 return redirect('projects:projects_list')
150 except Exception as e
:
152 return render(request
, 'error.html', {'error_msg': 'Error deleting Project.'})
154 elif request
.method
== 'GET':
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']})
164 except Exception as e
:
166 return render(request
, 'error.html', {'error_msg': 'Project not found.'})
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']
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
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
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']
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"] = "*"
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'
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
,
234 # 'message': "Delete succeeded!" if result else 'Error in delete'}
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'
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
,
256 'message': "Cloned!" if result
else 'Error in cloning'}
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', '')
269 json_template
= projects
[0].get_new_descriptor(descriptor_type
, request_id
)
270 print 'new descriptor GET', json_template
272 descriptor_string_yaml
= Util
.json2yaml(json_template
)
273 descriptor_string_json
= json
.dumps(json_template
)
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
}
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
)
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
)
300 'project_id': project_id
,
301 'descriptor_type': descriptor_type
,
302 'project_overview_data': projects
[0].get_overview_data(),
303 'descriptor_id': result
,
305 'success': True if result
!= False else False,
306 'message': "Descriptor created" if result
else 'Error in creation'}
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"] = "*"
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'))
322 'project_id': project_id
,
323 'descriptor_type': descriptor_type
,
324 #'project_overview_data': projects[0].get_overview_data(),
326 'success': True if result
else False,
327 'message': "Descriptor modified." if result
else 'Error during descriptor editing.'}
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"] = "*"
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'
342 descriptor
= projects
[0].get_descriptor(descriptor_id
, descriptor_type
)
344 descriptor_string_json
= json
.dumps(descriptor
)
345 descriptor_string_yaml
= Util
.json2yaml(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
}})
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"] = "*"
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
)
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"] = "*"
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
)
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"] = "*"
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
)
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"] = "*"
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
)
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"] = "*"
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"] = "*"
428 def overviewelement(request
, project_id
=None):
429 if request
.method
== 'GET':
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
:
441 if error_msg
is not None:
442 return JsonResponse({'error': {'error_msg': str(error_msg
)}})
444 return JsonResponse({'node_overview': result
})
446 # ETSI specific method #
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
)
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"] = "*"
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"] = "*"
471 # end ETSI specific method #
474 # OSM specific method #
475 def get_package_files_list(request
, project_id
, project
, descriptor_id
, descriptor_type
):
478 files_list
= project
.get_package_files_list(descriptor_type
, descriptor_id
)
479 result
= {'files': files_list
}
480 except Exception as e
:
483 result
= {'error_msg': 'Unknown error.'}
484 return __response_handler(request
, result
)
487 def download_pkg(request
, project_id
, project
, descriptor_id
, descriptor_type
):
488 tar_pkg
= project
.download_pkg(project
, descriptor_id
, descriptor_type
)
490 response
= HttpResponse(content_type
="application/tgz")
491 response
["Content-Disposition"] = "attachment; filename=osm_export.tar.gz"
492 response
.write(tar_pkg
.getvalue())
496 def create_ns(request
, project_id
, project
, descriptor_id
, descriptor_type
):
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": [
506 request
.POST
.get('key-pair-ref', ''): request
.POST
.get('keyValue', '')
510 #result = project.create_ns(descriptor_type, descriptor_id, ns_data)
512 except Exception as e
:
515 result
= {'error_msg': 'Unknown error.'}
516 return __response_handler(request
, result
)
518 # end OSM specific method #
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
)
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
)
533 return redirect(url
, *args
, **kwargs
)
535 return render(request
, url
, data_res
)