SFA Rest client: most of the functions are supported
authorLoic Baron <loic.baron@lip6.fr>
Tue, 5 May 2015 16:26:29 +0000 (18:26 +0200)
committerLoic Baron <loic.baron@lip6.fr>
Tue, 5 May 2015 16:26:29 +0000 (18:26 +0200)
myslice/urls.py
portal/resources.py [new file with mode: 0644]
portal/templates/resources.html [new file with mode: 0644]
rest/sfa_api.py

index 237c0ab..61f779f 100644 (file)
@@ -42,6 +42,9 @@ platforms_view=portal.platformsview.PlatformsView.as_view()
 import portal.sliceview
 import portal.sliceresourceview
 
+# Testing sfa rest
+import portal.resources
+
 import portal.slicetabexperiment
 import portal.slicetabinfo
 import portal.slicetabtestbeds
@@ -104,6 +107,9 @@ urls = [
     (r'^news/?$', portal.newsview.NewsView.as_view()),
     (r'^resources/(?P<slicename>[^/]+)/?$', portal.sliceresourceview.SliceResourceView.as_view()),
     (r'^users/(?P<slicename>[^/]+)/?$', portal.slicetabusers.SliceUserView.as_view()),
+
+    # Testing sfa rest
+    (r'^sfa_resources/(?P<slicename>[^/]+)/?$', portal.resources.ResourcesView.as_view()),
     
     (r'^slice/(?P<slicename>[^/]+)/?$', portal.sliceview.SliceView.as_view()),
     (r'^info/(?P<slicename>[^/]+)/?$', portal.slicetabinfo.SliceInfoView.as_view()),
diff --git a/portal/resources.py b/portal/resources.py
new file mode 100644 (file)
index 0000000..ca5f84d
--- /dev/null
@@ -0,0 +1,55 @@
+import json
+import time
+import re
+
+from django.shortcuts           import render
+from django.shortcuts           import render_to_response
+from django.template                    import RequestContext
+from django.contrib.sites.models import Site
+
+from unfold.page                import Page
+
+from manifold.core.query        import Query
+from manifoldapi.manifoldapi    import execute_admin_query, execute_query
+
+from portal.actions             import is_pi, create_slice, create_pending_slice, clear_user_creds, authority_check_pis
+#from portal.forms               import SliceRequestForm
+from unfold.loginrequired       import LoginRequiredAutoLogoutView
+from ui.topmenu                 import topmenu_items_live, the_user
+
+from myslice.theme import ThemeView
+from myslice.settings import logger
+
+import activity.user
+theme = ThemeView()
+
+class ResourcesView (LoginRequiredAutoLogoutView, ThemeView):
+    template_name = 'resources.html'
+    
+    # because we inherit LoginRequiredAutoLogoutView that is implemented by redefining 'dispatch'
+    # we cannot redefine dispatch here, or we'd lose LoginRequired and AutoLogout behaviours
+    def post (self, request, slicename):
+        return self.get_or_post (request, 'POST', slicename)
+
+    def get (self, request, slicename):
+        return self.get_or_post (request, 'GET', slicename)
+
+    def get_or_post  (self, request, method, slicename):
+        """
+        """
+        # Page rendering
+        page = Page(request)
+        page.add_js_files  ( [ "js/jquery-ui.js" ] )
+        page.add_css_files ( [ "css/jquery-ui.css" ] )
+
+        errors = []
+        slice_name =''
+        template_env = {
+            'theme': self.theme,
+            'section': "Slice request",
+            'slicename': slicename,
+            'request': request,
+        }
+        template_env.update(page.prelude_env())
+
+        return render_to_response(self.template,template_env, context_instance=RequestContext(request))
diff --git a/portal/templates/resources.html b/portal/templates/resources.html
new file mode 100644 (file)
index 0000000..b0e9a94
--- /dev/null
@@ -0,0 +1,63 @@
+{% extends "layout.html" %}
+{% load i18n %}
+
+{% block head %}
+<script type="text/javascript" src="//goessner.net/download/prj/jsonxml/json2xml.js"></script>
+<script type="text/javascript" src="//goessner.net/download/prj/jsonxml/xml2json.js"></script>
+{% endblock head %}
+{% block content %}
+       <div class="row">
+               <div class="col-md-12">
+                       <h1><img src="{{ STATIC_URL }}icons/slices-xs.png" alt="List of Resources" /> Resources List</h1>
+               </div>
+       </div>
+
+       {% if errors %}
+       <div class="row">
+               <div class="col-md-12">
+               <ul>
+                 {% for error in errors %}
+                 <li>{{ error }}</li>
+                 {% endfor %}
+               </ul>
+               </div>
+       </div>
+       {% endif %}
+       
+       <div class="row" id="table">
+       </div>
+               
+<script>
+jQuery(document).ready(function(){
+    /*
+    // sfa/Describe?hrn=onelab.upmc.projectx.slicex&type=slice
+    $.post("/sfa/Describe",{'hrn':'{{slicename}}','type':'slice','platform':['ple'],'display':'table'}, function( data ) {
+        console.log(data);
+        $('#table').html(data);
+    });
+    */
+    $.post("/sfa/ListResources",{'platform':['ple'],'display':'table'}, function( data ) {
+    //$.post("/sfa/ListResources",{'display':'table'}, function( data ) {
+        console.log(data);
+        $('#table').html(data);
+    });
+
+    /*
+    //$.post("/sfa/ListResources",{'platform':['ple'],'display':'table'}, function( data ) {
+    $.post("/sfa/ListResources",{}, function( data ) {
+        console.log(data);
+        $.each(data, function(key) {
+            if(key=='nitos'){
+                $('#table').html(data[key]['value']);
+            }
+        });
+    });
+    $.post("/sfa/Renew",{'hrn':'{{slicename}}','type':'slice'}, function( data ) {
+        console.log(data);
+    });
+    */
+
+});
+</script>
+{% endblock %}
+
index 62c883e..bad6773 100644 (file)
@@ -3,6 +3,7 @@ import json
 import ConfigParser 
 import datetime
 from time                       import mktime
+import xmltodict
 
 from django.shortcuts           import render_to_response
 from django.http                import HttpResponse
@@ -37,6 +38,7 @@ def dispatch(request, method):
     urn = ''
     hrn = ''
     object_type = ''
+    display = None
 
     if request.method == 'POST':
         req_items = request.POST
@@ -56,6 +58,8 @@ def dispatch(request, method):
             urn = el[1]
         elif el[0].startswith('type'):
             object_type = el[1]
+        elif el[0].startswith('display'):
+            display = el[1]
 
     if method not in ['GetVersion','ListResources']:
         try:
@@ -73,8 +77,12 @@ def dispatch(request, method):
     #results = {'method':method,'platforms':platforms,'rspec':rspec,'options':options}
 
     result = []
+    dict_result = {}
+    data = []
+    columns = []
     api_options = {}
     api_options['geni_rspec_version'] = {'type': 'GENI', 'version': '3'}
+    api_options['list_leases'] = 'all'
     server_am = False
     from manifoldapi.manifoldapi    import execute_admin_query
     for pf in platforms:
@@ -131,13 +139,39 @@ def dispatch(request, method):
                 if server_am:
                     if method == "ListResources":
                         result = server.ListResources([user_cred], api_options)
+                        logger.debug(result.keys())
+                        dict_result = xmltodict.parse(result['value'])
+                        result['json'] = json.dumps(dict_result)
+                        if isinstance(dict_result['rspec']['node'], list):
+                            columns.extend(dict_result['rspec']['node'][0].keys())
+                        else:
+                            columns.extend(dict_result['rspec']['node'].keys())
+
                     elif method == "Describe":
+                        version = server.GetVersion()
+                        logger.debug(version['geni_api'])
                         # if GetVersion = v2
-                        # ListResources(slice_hrn)
+                        if version['geni_api'] == 2:
+                            # ListResources(slice_hrn)
+                            api_options['geni_slice_urn'] = urn
+                            result = server.ListResources([object_cred], api_options)
+                            dict_result = xmltodict.parse(result['value'])
                         # else GetVersion = v3
-                        result = server.Describe([urn] ,[object_cred], api_options)
+                        else:
+                            result = server.Describe([urn] ,[object_cred], api_options)
+                            dict_result = xmltodict.parse(result['value']['geni_rspec'])
+
+                        result['json'] = json.dumps(dict_result)
+                        if isinstance(dict_result['rspec']['node'], list):
+                            columns.extend(dict_result['rspec']['node'][0].keys())
+                        else:
+                            columns.extend(dict_result['rspec']['node'].keys())
+
                     elif method == 'Renew':
-                        result = server.Renew([urn] ,[object_cred], api_options)
+                        # Renew till 1 month from now
+                        d = datetime.datetime.utcnow() + datetime.timedelta(365/12)
+                        date = d.isoformat("T") + "Z"
+                        result = server.Renew([urn] ,[object_cred], date, api_options)
                     elif method == 'Delete':
                         result = server.Delete([urn] ,[object_cred], api_options)
                     elif method == 'Allocate':
@@ -170,6 +204,7 @@ def dispatch(request, method):
                         logger.debug('method %s not handled by AM' % method)
                         result = []
                 else:
+                    record_dict = {'urn': urn, 'hrn': hrn, 'type': object_type}
                     if method == "List":
                         # hrn is required
                         result = server.List(hrn, user_cred, options)
@@ -200,13 +235,21 @@ def dispatch(request, method):
                         result = []
 
             results[pf] = result
+            if dict_result:
+                if isinstance(dict_result['rspec']['node'], list):
+                    data = data + dict_result['rspec']['node']
+                else:
+                    data.append(dict_result['rspec']['node'])
         except Exception,e:
             import traceback
             logger.error(traceback.format_exc())
             logger.error(e)
             results[pf] = {'error':'-3', 'error_msg': str(e)}
-
-    return HttpResponse(json.dumps(results, cls=MyEncoder), content_type="application/json")
+    if display == 'table':
+        return render_to_response('table-default.html', {'data' : data, 'fields' : columns, 'id' : '@component_id', 'options' : None})
+    else:
+        results['columns'] = columns
+        return HttpResponse(json.dumps(results, cls=MyEncoder), content_type="application/json")
 
 def get_user_account(user_email, platform_name):
     """
@@ -231,7 +274,7 @@ def get_user_config(user_email, platform_name):
 
 def get_platforms():
     ret = list()
-    platforms = db.query(Platform).all()
+    platforms = db.query(Platform).filter(Platform.gateway_type == 'sfa', Platform.disabled == 0).all()
     for p in platforms:
         ret.append(p.platform)
     return ret