a5bc20da5736110daaf907df1eb3e74954b2101e
[myslice.git] / manifoldapi / manifoldproxy.py
1 import json
2 import os.path
3
4 # this is for django objects only
5 #from django.core import serializers
6 from django.http                import HttpResponse, HttpResponseForbidden
7
8 #from manifoldapi.manifoldquery import ManifoldQuery
9 from manifold.core.query        import Query
10 from manifold.core.result_value import ResultValue
11 from manifoldapi                import ManifoldAPI
12 from manifoldresult             import ManifoldException
13 from manifold.util.log          import Log
14
15 from unfold.sessioncache import SessionCache
16
17 from myslice.settings import config, logger
18
19 # register activity
20 import activity.slice
21
22 debug=False
23 #debug=True
24
25 # pretend the server only returns - empty lists to 'get' requests - this is to mimick 
26 # misconfigurations or expired credentials or similar corner case situations
27 debug_empty=False
28 #debug_empty=True
29
30 # this view is what the javascript talks to when it sends a query
31 # see also
32 # myslice/urls.py
33 # as well as 
34 # static/js/manifold.js
35 def proxy (request,format):
36     """the view associated with /manifold/proxy/ with the query passed using POST"""
37     
38     # expecting a POST
39     if request.method != 'POST':
40         logger.error("MANIFOLDPROXY unexpected method {} -- exiting".format(request.method))
41         return HttpResponse ({"ret":0}, content_type="application/json")
42     # we only support json for now
43     # if needed in the future we should probably cater for
44     # format_in : how is the query encoded in POST
45     # format_out: how to serve the results
46     if format != 'json':
47         logger.error("MANIFOLDPROXY unexpected format {} -- exiting".format(format))
48         return HttpResponse ({"ret":0}, content_type="application/json")
49     try:
50         # translate incoming POST request into a query object
51         #logger.debug("MANIFOLDPROXY request.POST {}".format(request.POST))
52
53         manifold_query = Query()
54         #manifold_query = ManifoldQuery()
55         manifold_query.fill_from_POST(request.POST)
56         # retrieve session for request
57
58         # We allow some requests to use the ADMIN user account
59         if (manifold_query.get_from() == 'local:user' and manifold_query.get_action() == 'create') \
60                 or (manifold_query.get_from() == 'local:platform' and manifold_query.get_action() == 'get'):
61             admin_user, admin_password = config.manifold_admin_user_password()
62             manifold_api_session_auth = {'AuthMethod': 'password', 'Username': admin_user, 'AuthString': admin_password}
63         else:
64             manifold_api_session_auth = SessionCache().get_auth(request)
65             if not manifold_api_session_auth:
66                 return HttpResponse (json.dumps({'code':0,'value':[]}), content_type="application/json")
67                 
68         if debug_empty and manifold_query.action.lower()=='get':
69             return HttpResponse (json.dumps({'code':0,'value':[]}), content_type="application/json")
70                 
71         # actually forward
72         manifold_api= ManifoldAPI(auth=manifold_api_session_auth)
73
74         # for the benefit of the python code, manifoldAPI raises an exception if something is wrong
75         # however in this case we want to propagate the complete manifold result to the js world
76
77         result = manifold_api.forward(manifold_query.to_dict())
78
79         # XXX TEMP HACK
80         if 'description' in result and result['description'] \
81                 and isinstance(result['description'], (tuple, list, set, frozenset)):
82             result [ 'description' ] = [ ResultValue.to_html (x) for x in result['description'] ]
83         
84         #
85         # register activity
86         #
87         # resource reservation
88         if (manifold_query.action.lower() == 'update') :
89             logger.debug(result['value'][0])
90             if 'resource' in result['value'][0] :
91                 for resource in result['value'][0]['resource'] :
92                     activity.slice.resource(request, 
93                             { 
94                                 'slice' :           result['value'][0]['slice_hrn'], 
95                                 'resource' :        resource['hostname'], 
96                                 'resource_type' :   resource['type'],
97                                 'facility' :        resource['facility_name'],
98                                 'testbed' :         resource['testbed_name']
99                             }
100                     )
101         
102         json_answer=json.dumps(result)
103
104         return HttpResponse (json_answer, content_type="application/json")
105
106     except Exception as e:
107         logger.error("MANIFOLDPROXY {}".format(e))
108         import traceback
109         logger.error(traceback.format_exc())
110         return HttpResponse ({"ret":0}, content_type="application/json")
111
112 #################### 
113 # see CSRF_FAILURE_VIEW in settings.py
114 # the purpose of redefining this was to display the failure reason somehow
115 # this however turns out disappointing/not very informative
116 failure_answer=[ "csrf_failure" ]
117 def csrf_failure(request, reason=""):
118     logger.error("CSRF failure with reason '{}'".format(reason))
119     return HttpResponseForbidden (json.dumps (failure_answer), content_type="application/json")