automatic reload on lists; new django decorator for ajax request 64/6464/2
authorlombardofr <lombardo@everyup.it>
Mon, 10 Sep 2018 09:36:06 +0000 (11:36 +0200)
committerlombardofr <lombardo@everyup.it>
Tue, 11 Sep 2018 13:18:59 +0000 (15:18 +0200)
Change-Id: I3eb41de76217191268acb6053ad0c04aec0e8388
Signed-off-by: lombardofr <lombardo@everyup.it>
25 files changed:
authosm/backend.py
bower.json
instancehandler/template/instance_list.html
instancehandler/template/instance_list_ns.html
instancehandler/template/instance_list_vnf.html
instancehandler/template/instance_operations_list.html
instancehandler/views.py
projecthandler/middleware.py
projecthandler/template/project/osm/osm_project_descriptors.html
projecthandler/template/project/projectlist.html
projecthandler/views.py
sdnctrlhandler/template/sdn_list.html
sdnctrlhandler/views.py
sf_t3d/decorators.py [new file with mode: 0644]
static/src/instancehandler/instance_list.js
static/src/instancehandler/instance_operations_list.js
static/src/projecthandler/descriptorslist.js
static/src/sdnctrlhandler/sdn_list.js
static/src/userhandler/user_list.js
static/src/utils.js
template/base.html
userhandler/templates/user_list.html
userhandler/views.py
vimhandler/template/vim_list.html
vimhandler/views.py

index 9c316a9..628eb6a 100644 (file)
@@ -21,6 +21,7 @@ from .exceptions import OSMAuthException
 
 
 class OsmBackend(object):
+
     def authenticate(self, **kwargs):
         '''
         kwargs will receive the python dict that may contain
index 20c60cb..d8b5366 100644 (file)
@@ -23,6 +23,7 @@
     "codemirror": "^5.36.0",
     "d3": "^4",
     "bootbox.js": "bootbox#^4.4.0",
-    "components-font-awesome": "^5.0.6"
+    "components-font-awesome": "^5.0.6",
+    "moment": "^2.22.2"
   }
 }
index 3b8ffcf..de47e62 100644 (file)
     <script src="/static/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
 
     <script>
-    $(document).ready( function () {
-        $('#instances_table').DataTable();
-    } );
+        var instance_type = '{{ type }}';
+        var row_builder = {
+            'ns': [
+                {
+                    "render": function (data, type, row) {
+                        return row["short-name"];
+                    },
+                    "targets": 0
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["_id"];
+                    },
+                    "targets": 1
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["nsd-name-ref"];
+                    },
+                    "targets": 2
+                },
+                {
+                 //   "width": "5%",
+                    "render": function (data, type, row) {
+                        if(row["operational-status"] === 'failed')
+                           return '<span class="label label-danger">'+ row["operational-status"] +'</span>';
+                        if(row["operational-status"] === 'init')
+                           return '<span class="label label-warning">'+ row["operational-status"] +'</span>';
+                        if(row["operational-status"] === 'running')
+                           return '<span class="label label-success">'+ row["operational-status"] +'</span>';
+                        return  ''+row["operational-status"]+'';
+                    },
+                    "targets": 3
+                },
+                {
+                //    "width": "5%",
+                    "render": function (data, type, row) {
+                         if(row["config-status"] === 'failed')
+                           return '<span class="label label-danger">'+ row["config-status"] +'</span>';
+                        if(row["config-status"] === 'init')
+                           return '<span class="label label-warning">'+ row["config-status"] +'</span>';
+                        if(row["config-status"] === 'running')
+                           return '<span class="label label-success">'+ row["config-status"] +'</span>';
+                        if(row["config-status"] === 'configured')
+                           return '<span class="label label-success">'+ row["config-status"] +'</span>';
+                        return  ''+row["operational-status"]+'';
+                    },
+                    "targets": 4
+                },
+                {
+                   // "className": "ellipsis",
+                    "render": function (data, type, row) {
+                        return row["detailed-status"];
+                    },
+                    "targets": 5
+                },{
+                   //  "width": "10%",
+                    "render": function (data, type, row) {
+                        return '<div class="btn-group">\n' +
+                            ' <button type="button" class="btn btn-default"\n' +
+                            '         onclick="javascript:showInstanceDetails(\''+instance_type+'\', \''+row["_id"]+'\')"\n' +
+                            '         data-toggle="tooltip" data-placement="top" data-container="body" title="Show Info">\n' +
+                            '     <i class="fa fa-info"></i>\n' +
+                            ' </button>\n' +
+                            ' <button type="button" class="btn btn-default"\n' +
+                            '         onclick="javascript:deleteNs(\''+ row["short-name"] +'\', \''+row["_id"]+'\')"\n' +
+                            '         data-toggle="tooltip" data-placement="top" data-container="body" title="Delete"><i\n' +
+                            '         class="far fa-trash-alt"></i></button>\n' +
+                            ' <button type="button" class="btn btn-default dropdown-toggle"\n' +
+                            '         data-toggle="dropdown" aria-expanded="false">Actions\n' +
+                            '     <span class="fa fa-caret-down"></span></button>\n' +
+                            ' <ul class="dropdown-menu">\n' +
+                            '     <li><a href="#"\n' +
+                            '            onclick="javascript:performAction(\''+ row["short-name"] +'\', \''+row["_id"]+'\')">\n' +
+                            '         <i class="fa fa-magic"></i> Exec NS Primitive</a></li>\n' +
+                            '     <li>\n' +
+                            '         <a href="/instances/ns/' +row["_id"] +'/operation">\n' +
+                            '             <i class="fa fa-list"></i> Active operations</a></li>\n' +
+                            '     <li class="divider"></li>\n' +
+                            '     <li><a href="#"\n' +
+                            '            onclick="javascript:newAlarmNs(\''+ row["short-name"] +'\', \''+row["_id"]+'\')">\n' +
+                            '         <i class="far fa-bell"></i> New Alarm</a></li>\n' +
+                            '     <li><a href="#"\n' +
+                            '            onclick="javascript:exportMetricNs(\''+ row["short-name"] +'\', \''+row["_id"]+ '\')">\n' +
+                            '         <i class="far fa-chart-bar"></i> Export metric</a></li>\n' +
+                            '     <li class="divider"></li>\n' +
+                            '     <li>\n' +
+                            '         <a href="javascript:deleteNs(\''+ row["short-name"] +'\', \''+row["_id"]+'\', true)">\n' +
+                            '             <i class="far fa-trash-alt" style="color:red" ></i> Force delete</a></li>\n' +
+                            ' </ul>\n' +
+                            '</div>';
+                    },
+                    "targets": 5
+                },
+
+            ],
+            'vnf': [ {
+                    "render": function (data, type, row) {
+                        return row["_id"];
+                    },
+                    "targets": 0
+                },
+                {
+                    "render": function (data, type, row) {
+                        return '<a href="javascript:openDescriptorView(\'vnfd\', \'' + row["_id"]+'\')"> ' + row["vnfd-ref"] +' </a>';
+                    },
+                    "targets": 1
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["member-vnf-index-ref"];
+                    },
+                    "targets": 2
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["nsr-id-ref"];
+                    },
+                    "targets": 3
+                },
+                {
+                    "render": function (data, type, row) {
+                        return moment.unix(row['created-time']).format('YYYY-MM-DD hh:mm:ss a');
+                    },
+                    "targets": 4
+                }, 
+                {
+                    "render": function (data, type, row) {
+                        return '<div class="btn-group">\n' +
+                            '     <button type="button" class="btn btn-default"\n' +
+                            '             onclick="javascript:showInstanceDetails(\''+instance_type+'\', \''+row["_id"]+'\')"\n' +
+                            '             data-toggle="tooltip" data-placement="top" data-container="body" title="Show Info">\n' +
+                            '         <i class="fa fa-info"></i>\n' +
+                            '     </button>\n' +
+                            ' </div>';
+                    },
+                    "targets": 5
+                },
+            ]
+        };
+        $(document).ready(function () {
+            var table = $('#instances_table').DataTable({
+                responsive: true,
+                "ajax": {
+                    "url": "/instances/" + instance_type + "/list/",
+                    "dataSrc": function (json) {
+                        return json.instances;
+                    },
+                    statusCode: {
+                        401: function(){
+                            console.log("no auth");
+                            moveToLogin(window.location.pathname);
+                        }
+                    },
+                    "error": function(hxr, error, thrown){
+                        console.log(error);
+                    }
+
+                },
+                "columns": row_builder[instance_type]
+            });
+
+
+            setInterval(function () {
+                table.ajax.reload();
+            }, 10000);
+        });
+
     </script>
 
 {% endblock %}
index 01bdc10..9a50881 100644 (file)
@@ -21,7 +21,7 @@
             {{alert_error}}
         </div>
     {% endif %}
-        <table id="instances_table" class="table table-bordered table-striped">
+        <table id="instances_table" class="table table-bordered table-striped responsive" style="width:100%">
             <thead>
             <tr>
                 <th>Name</th>
             </tr>
             </thead>
             <tbody>
-            {% for i in instances %}
-                <tr>
-                    <td>{{ i|get:"short-name" }}</td>
-                    <td>{{ i|get:"_id" }}</td>
 
-                    <td>{{ i|get:"nsd-name-ref" }}</td>
-
-                    {% if i|get:"operational-status" == 'failed' %}
-                        <td><span class="label label-danger">{{ i|get:"operational-status" }}</span></td>
-                    {% elif i|get:"operational-status" == 'init' %}
-                        <td><span class="label label-warning">{{ i|get:"operational-status" }}</span></td>
-                    {% elif i|get:"operational-status" == 'running' %}
-                        <td><span class="label label-success">{{ i|get:"operational-status" }}</span></td>
-                    {% else %}
-                        <td>{{ i|get:"operational-status" }}</td>
-                    {% endif %}
-                    {% if i|get:"config-status" == 'failed' %}
-                        <td><span class="label label-danger">{{ i|get:"config-status" }}</span></td>
-                    {% elif i|get:"config-status" == 'init' %}
-                        <td><span class="label label-warning">{{ i|get:"config-status" }}</span></td>
-                    {% elif i|get:"config-status" == 'running' %}
-                        <td><span class="label label-success">{{ i|get:"config-status" }}</span></td>
-                    {% elif i|get:"config-status" == 'configured' %}
-                        <td><span class="label label-success">{{ i|get:"config-status" }}</span></td>
-                    {% else %}
-                        <td>{{ i|get:"config-status" }}</td>
-                    {% endif %}
-                    <td class="ellipsis" data-text="{{ i|get:"detailed-status" }}">{{ i|get:"detailed-status" }}</td>
-                    <td>
-                        <div class="btn-group">
-                            <button type="button" class="btn btn-default"
-                                    onclick="javascript:showInstanceDetails('{% url 'instances:show' instance_id=i|get:'_id'  type=type %}')"
-                                    data-toggle="tooltip" data-placement="top" data-container="body" title="Show Info">
-                                <i class="fa fa-info"></i>
-                            </button>
-                            <!--
-                            <button type="button" class="btn btn-default"
-                                    onclick="javascript:showInstanceTopology('{% url 'instances:show_topology' instance_id=i|get:'_id'  type=type %}')"
-                                    data-toggle="tooltip" data-placement="top" data-container="body" title="Show Topology">
-                                <i class="fa fa-sitemap"></i>
-                            </button>
-                            -->
-
-                            <button type="button" class="btn btn-default"
-                                    onclick="javascript:deleteNs('{% url 'instances:delete' instance_id=i|get:'_id'  type=type %}')"
-                                    data-toggle="tooltip" data-placement="top" data-container="body" title="Delete"><i
-                                    class="far fa-trash-alt"></i></button>
-
-                            <button type="button" class="btn btn-default dropdown-toggle"
-                                    data-toggle="dropdown" aria-expanded="false">Actions
-                                <span class="fa fa-caret-down"></span></button>
-                            <ul class="dropdown-menu">
-                                <li><a href="#"
-                                       onclick="javascript:performAction('{% url 'instances:action' instance_id=i|get:'_id'  type=type %}')">
-                                    <i class="fa fa-magic"></i> Exec NS Primitive</a></li>
-                                <li>
-                                    <a href="{% url 'instances:ns_operations'  type=type instance_id=i|get:'_id' %}">
-                                        <i class="fa fa-list"></i> Active operations</a></li>
-                                <li class="divider"></li>
-                                <li><a href="#"
-                                       onclick="javascript:newAlarmNs('{% url 'instances:ns_create_alarm' instance_id=i|get:'_id'  type=type %}')">
-                                    <i class="far fa-bell"></i> New Alarm</a></li>
-                                <li><a href="#"
-                                       onclick="javascript:exportMetricNs('{% url 'instances:ns_export_metric' instance_id=i|get:'_id'  type=type %}')">
-                                    <i class="far fa-chart-bar"></i> Export metric</a></li>
-                                <li class="divider"></li>
-                                <li>
-                                    <a href="javascript:deleteNs('{% url 'instances:delete' instance_id=i|get:'_id'  type=type %}', true)">
-                                        <i class="far fa-trash-alt" style="color:red" ></i> Force delete</a></li>
-                            </ul>
-
-
-                        </div>
-
-                    </td>
-
-
-                </tr>
-            {% endfor %}
             </tbody>
         </table>
     </div>
index 5f13f2b..d290ad1 100644 (file)
@@ -13,7 +13,7 @@
 
     </div>
     <div class="box-body">
-        <table id="instances_table" class="table table-bordered table-striped">
+        <table id="instances_table" class="table table-bordered table-striped responsive" style="width:100%">
             <thead>
             <tr>
                 <th>Identifier</th>
             </tr>
             </thead>
             <tbody>
-            {% for i in instances %}
-                <tr>
 
-                    <td>{{ i|get:"_id" }}</td>
-                    <td><a href="javascript:openDescriptorView('vnfd', '{{ i|get:"vnfd-id" }}')"> {{ i|get:"vnfd-ref" }}</a></td>
-                    <td>{{ i|get:"member-vnf-index-ref" }}</td>
-                    <td class="ellipsis" data-text="{{ i|get:"nsr-id-ref" }}">{{ i|get:"nsr-id-ref" }}</td>
-                    <td >{{ i|get:"created-time"|get_date }}</td>
-
-                    <td>
-                        <div class="btn-group">
-                            <button type="button" class="btn btn-default"
-                                    onclick="javascript:showInstanceDetails('{% url 'instances:show' instance_id=i|get:'_id'  type=type %}')"
-                                    data-toggle="tooltip" data-placement="top" data-container="body" title="Show Info">
-                                <i class="fa fa-info"></i>
-                            </button>
-
-
-                        </div>
-
-                    </td>
-
-
-                </tr>
-            {% endfor %}
             </tbody>
         </table>
     </div>
index 55c097b..7e84658 100644 (file)
@@ -14,6 +14,8 @@
     <link rel="stylesheet" href="/static/bower_components/codemirror/addon/dialog/dialog.css">
     <link rel="stylesheet" href="/static/bower_components/codemirror/addon/display/fullscreen.css">
     <link rel="stylesheet" href="/static/bower_components/select2/dist/css/select2.min.css">
+        <link rel="stylesheet" href="/static/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
+
 {% endblock %}
 {% block title_header_big %}
     {{ block.super }}
@@ -26,6 +28,7 @@
 {% block breadcrumb_body %}
     {{ block.super }}
     <li><a href="{% url 'instances:list'  type=type %}">Instances</a></li>
+    <li><a href="#">Operations</a></li>
 {% endblock %}
 
 {% block content_body %}
@@ -41,7 +44,7 @@
 
                 </div>
                 <div class="box-body">
-                    <table id="instances_table" class="table table-bordered table-striped">
+                    <table id="operations_table" class="table table-bordered table-striped">
                         <thead>
                         <tr>
                             <th>Id</th>
                         </tr>
                         </thead>
                         <tbody>
-                        {% for i in operations %}
-                            <tr>
-
-                                <td>{{ i|get:"_id" }}</td>
-                                <td>{{ i|get:"lcmOperationType" }}</td>
-
-                                {% if i|get:"operationState" == 'FAILED' %}
-                                    <td><span class="label label-danger">{{ i|get:"operationState"  }}</span> </td>
-                                {% elif i|get:"operationState" == 'PROCESSING' %}
-                                     <td><span class="label label-warning">{{ i|get:"operationState"  }}</span> </td>
-                                {% elif i|get:"operationState" == 'COMPLETED' %}
-                                     <td><span class="label label-success">{{ i|get:"operationState"  }}</span> </td>
-                                {% else  %}
-                                    <td>{{ i|get:"operationState"  }}</td>
-                                {% endif %}
-
-                                <td >{{ i.startTime|get_date }}</td>
-                                <td >{{ i.statusEnteredTime|get_date }}</td>
-                                <td>
-                                    <div class="btn-group">
-                                        <button type="button" class="btn btn-default"
-                                                onclick="javascript:showOperationDetails('{% url 'instances:ns_operation' op_id=i|get:'_id' instance_id=i|get:'nsInstanceId'  type=type %}')"
-                                                data-toggle="tooltip" data-placement="top" data-container="body" title="More Info"><i
-                                                class="fa fa-info"></i>
-                                        </button>
-
 
-                                    </div>
-
-                                </td>
-
-
-                            </tr>
-                        {% endfor %}
                         </tbody>
                     </table>
                 </div>
     <script src="/static/bower_components/codemirror/addon/edit/closebrackets.js"></script>
     <script src="/static/bower_components/codemirror/addon/display/fullscreen.js"></script>
     <script src="/static/bower_components/codemirror/keymap/sublime.js"></script>
+    <script src="/static/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
+    <script src="/static/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
     <script src="/static/src/instancehandler/instance_operations_list.js"></script>
 
+    <script>
+    var instance_type = '{{ type }}';
+    var instance_id = '{{ instance_id }}';
+    $(document).ready(function () {
+            var table = $('#operations_table').DataTable({
+                responsive: true,
+                "ajax": {
+                    "url": "/instances/" + instance_type + "/" +instance_id + "/operation",
+                    "dataSrc": function (json) {
+                        return json['operations'];
+                    },
+                    statusCode: {
+                        401: function(){
+                            console.log("no auth");
+                            moveToLogin(window.location.pathname);
+                        }
+                    },
+                    "error": function(hxr, error, thrown){
+                        console.log(error);
+                    }
+
+                },
+                "columns": [
+                    {
+                    "render": function (data, type, row) {
+                        return row["_id"];
+                    },
+                    "targets": 0
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row['lcmOperationType'];
+                    },
+                    "targets": 1
+                },
+                {
+                    "render": function (data, type, row) {
+
+                        if(row["operationState"] === 'FAILED')
+                           return '<span class="label label-danger">'+ row["operationState"] +'</span>';
+                        else if(row["operationState"] === 'PROCESSING')
+                           return '<span class="label label-warning">'+ row["operationState"] +'</span>';
+                        else if(row["operationState"] === 'COMPLETED')
+                           return '<span class="label label-success">'+ row["operationState"] +'</span>';
+                        else
+                         return row["operationState"];
+                    },
+                    "targets": 2
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["startTime"];
+                    },
+                    "targets": 3
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["statusEnteredTime"];
+                    },
+                    "targets": 4
+                },
+                {
+                    "render": function (data, type, row) {
+                        return '<div class="btn-group">\n' +
+                            '     <button type="button" class="btn btn-default"\n' +
+                            '             onclick="javascript:showOperationDetails(\''+row["nsInstanceId"]+'\', \''+row["_id"]+'\')"\n' +
+                            '             data-toggle="tooltip" data-placement="top" data-container="body" title="Show Info">\n' +
+                            '         <i class="fa fa-info"></i>\n' +
+                            '     </button>\n' +
+                            ' </div>';
+                    },
+                    "targets": 5
+                }
+                ]
+            });
+
+
+            setInterval(function () {
+                table.ajax.reload();
+            }, 10000);
+        });
+
+    </script>
+
 {% endblock %}
 
 {% block footer %}
     {% include "footer.html" %}
-{% endblock %}
+{% endblock %}
\ No newline at end of file
index 212fbbf..d80d18d 100644 (file)
 #
 
 from django.shortcuts import render, redirect
-from django.contrib.auth.decorators import login_required
+#from django.contrib.auth.decorators import login_required
 from django.http import HttpResponse, JsonResponse
 import yaml
 import json
 import logging
 from lib.osm.osmclient.clientv2 import Client
 import authosm.utils as osmutils
+from sf_t3d.decorators import login_required
 
 logging.basicConfig(level=logging.DEBUG)
 log = logging.getLogger('instancehandler/view.py')
 
+
 @login_required
 def list(request, type=None):
+
     user = osmutils.get_user(request)
     project_id = user.project_id
     client = Client()
+    result = {'type': type, 'project_id': project_id}
+    if "OSM_ERROR" in request.session:
+        result['alert_error'] = request.session["OSM_ERROR"]
+        del request.session["OSM_ERROR"]
+    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
+    if 'application/json' not in raw_content_types:
+        return __response_handler(request, result, 'instance_list.html')
+    instance_list = None
     if type == 'ns':
         instance_list = client.ns_list(user.get_token())
     elif type == 'vnf':
         instance_list = client.vnf_list(user.get_token())
 
-    result = {'instances': instance_list['data'] if instance_list and instance_list['error'] is False else [],
-              'type': type, 'project_id': project_id}
-
-    if "OSM_ERROR" in request.session:
-        result['alert_error'] = request.session["OSM_ERROR"]
-        del request.session["OSM_ERROR"]
+    result['instances'] = instance_list['data'] if instance_list and instance_list['error'] is False else []
 
     return __response_handler(request, result, 'instance_list.html')
 
@@ -96,12 +102,16 @@ def create(request):
 def ns_operations(request, instance_id=None, type=None):
     user = osmutils.get_user(request)
     project_id = user.project_id
+
+    result = {'type': 'ns', 'project_id': project_id, 'instance_id': instance_id}
+    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
+    if 'application/json' not in raw_content_types:
+        return __response_handler(request, result, 'instance_operations_list.html')
     client = Client()
     op_list = client.ns_op_list(user.get_token(), instance_id)
-    return __response_handler(request,
-                              {'operations': op_list['data'] if op_list and op_list['error'] is False else [],
-                               'type': 'ns', 'project_id': project_id}, 'instance_operations_list.html')
+    result['operations'] = op_list['data'] if op_list and op_list['error'] is False else []
 
+    return __response_handler(request, result, 'instance_operations_list.html')
 
 @login_required
 def ns_operation(request, op_id, instance_id=None, type=None):
index 4880ebe..89ae94d 100644 (file)
@@ -1,6 +1,4 @@
 
 class OsmProjectMiddleware(object):
     def process_view(self, request, view_func, view_args, view_kwargs):
-        print "OsmProjectMiddleware", view_func, view_args, view_kwargs
-
         return None
\ No newline at end of file
index f877ea8..182c8cc 100644 (file)
     <script>
     var csrf_token = '{{csrf_token}}';
     var descr_list_url = '{% url "projects:list_descriptors"   descriptor_type=descriptor_type%}';
-    var new_desc_url ="{% url 'projects:new_descriptor'  descriptor_type=descriptor_type %}"
+    var vim_list_url = '{% url "vims:list"  %}';
+    var new_desc_url ="{% url 'projects:new_descriptor'  descriptor_type=descriptor_type %}";
+    var descriptor_type = '{{ descriptor_type }}';
+    var project_id = '{{ project_id }}';
     $(document).ready( function () {
-        $('#descriptors_table').DataTable();
-    } );
+        var table = $('#descriptors_table').DataTable({
+            responsive: true,
+            "ajax": {
+                "url": "/projects/descriptors/" +descriptor_type+"/list",
+                "dataSrc": function (json) {
+                    return json['descriptors'];
+                },
+                statusCode: {
+                    401: function () {
+                        console.log("no auth");
+                        moveToLogin(window.location.pathname);
+                    }
+                },
+                "error": function (hxr, error, thrown) {
+                    console.log(hxr)
+                    console.log(thrown)
+                    console.log(error);
+                }
 
+            },
+            "columns": [
+                {
+                    "render": function (data, type, row) {
+                       return row['short-name'];
+                    },
+                    "targets": 0
+                },
+                {
+                    "render": function (data, type, row) {
+                       return row['_id'];
+                    },
+                    "targets": 1
+                },
+                {
+                    "render": function (data, type, row) {
+                       return row['description'] || '';
+                    },
+                    "targets": 2
+                },
+                {
+                    "render": function (data, type, row) {
+                       return row['vendor'] || '';
+                    },
+                    "targets": 3
+                },
+                {
+                    "render": function (data, type, row) {
+                       return row['version'] || '';
+                    },
+                    "targets": 4
+                },
+                {
+                    "render": function (data, type, row) {
+                       var result = '<div class="btn-group">\n' ;
+                       if(descriptor_type == "nsd")
+                           result += '    <button type="button" class="btn btn-default" data-container="body"\n' +
+                               'data-toggle="tooltip" data-placement="top" title="Instantiate NS"\n' +
+                               'onclick="javascript:openModalCreateNS({ \'project_id\':\'' + project_id +'\', \'descriptor_type\': \''+ descriptor_type +'\', \'descriptor_name\':\''+row["name"]+'\', \'descriptor_id\':\''+row["_id"]+'\',\'vim_list_url\': \''+vim_list_url+'\',  \'nsd_list_url\': \''+descr_list_url+'\' })">\n' +
+                               '<i class="fa fa-paper-plane"></i></button>\n';
+                        result += '<button type="button" class="btn btn-default" data-container="body"\n' +
+                           '        data-toggle="tooltip" data-placement="top" title="Edit"\n' +
+                           '        onclick="javascript:openDescriptorView(\''+descriptor_type+'\', \''+row["_id"]+'\')">\n' +
+                           '    <i class="fa fa-edit"></i></button>\n' +
+                           '<button type="button" class="btn btn-default" data-container="body"\n' +
+                           '        data-toggle="tooltip" data-placement="top" title="Show content"\n' +
+                           '        onclick="javascript:openPackageContentList(\''+ descriptor_type +'\', \''+row["_id"]+'\')">\n' +
+                           '    <i class="fa fa-folder-open"></i></button>\n' +
+                           '<button type="button" class="btn btn-default" data-container="body"\n' +
+                           '        data-toggle="tooltip" data-placement="top" title="Show Graph"\n' +
+                           '        onclick="location.href=\'/projects/graph?type='+descriptor_type+'&id='+row["_id"] +'\'"\n' +
+                           '        disabled><i class="fa fa-sitemap fa-fw"></i></button>\n' +
+                           '<button type="button" class="btn btn-default" data-container="body"\n' +
+                           '        data-toggle="tooltip" data-placement="top" title="Download package"\n' +
+                           '        onclick="location.href=\'/projects/descriptors/'+descriptor_type+'/'+ row["_id"] +'/action/download_pkg\'">\n' +
+                           '    <i class="fa fa-download fa-fw"></i></button>\n' +
+                           '<button type="button" class="btn btn-default" data-container="body"\n' +
+                           '        data-toggle="tooltip" data-placement="top" title="Delete"\n' +
+                           '        onclick="javascript:deletePackage( \'' + descriptor_type + '\', \''+row["_id"] + '\')">\n' +
+                           '    <i class="far fa-trash-alt"></i></button>\n' +
+                           '</div>';
+
+                               return result
+                    },
+                    "targets": 5
+                }]
+
+
+        });
+
+        setInterval(function () {
+                table.ajax.reload();
+            }, 10000);
+    });
     </script>
     <script src="/static/bower_components/select2/dist/js/select2.js"></script>
     <script src="/static/src/instancehandler/instance_create.js"></script>
index 213c5b0..a90fec8 100644 (file)
                                        </tr>
                                </thead>
                                <tbody>
-                               {% for p in projects %}
-                                       <tr>
 
-                                               <td>
-                                                       <a href="/projects/switch/{{ p.name }}" >{{ p.name }}</a>
-                                               </td>
-
-                                               <td>{{ p|get_sub:"_admin,modified"|get_date}}</td>
-                        <td>{{ p|get_sub:"_admin,created"|get_date}}</td>
-
-                        <td>
-                            <div class="btn-group">
-                            <button type="button" class="btn btn-default dropdown-toggle"
-                                    data-toggle="dropdown" aria-expanded="false">Actions
-                                <span class="fa fa-caret-down"></span></button>
-                            <ul class="dropdown-menu">
-                                <li><a href="#"
-                                       onclick="javascript:editProject('{% url 'projects:edit_project'  project_id=p.name %}')">
-                                    <i class="fa fa-edit"></i> Rename</a></li>
-                                <li>
-                                    <a href="#" onclick="javascript:deleteProject('{% url 'projects:delete_project'  project_id=p.name%}')" style="color:red">
-                                        <i class="fa fa-trash"  ></i> Delete</a>
-                                </li>
-                            </ul>
-                            </div>
-                        </td>
-                                       </tr>
-                               {% endfor %}
                                </tbody>
                        </table>
                </div>
     <script src="/static/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
 
     <script>
-    $(document).ready( function () {
-        $('#projects_table').DataTable();
-    } );
+   $(document).ready( function () {
+        var table = $('#projects_table').DataTable({
+            responsive: true,
+            "ajax": {
+                "url": "/projects/list",
+                "dataSrc": function (json) {
+                    return json['projects'];
+                },
+                statusCode: {
+                    401: function () {
+                        console.log("no auth");
+                        moveToLogin(window.location.pathname);
+                    }
+                },
+                "error": function (hxr, error, thrown) {
+                    console.log(hxr)
+                    console.log(thrown)
+                    console.log(error);
+                }
+
+            },
+            "columns": [
+                {
+                    "render": function (data, type, row) {
+                       return '<a href="/projects/switch/'+row['name']+'" >'+row['name']+'</a>'
+                    },
+                    "targets": 0
+                },
+                {
+                    "render": function (data, type, row) {
+                        return moment.unix(row["_admin"]['modified']).format('YYYY-MM-DD hh:mm:ss a');
+                    },
+                    "targets": 1
+                },
+                {
+                    "render": function (data, type, row) {
+                        return moment.unix(row["_admin"]['created']).format('YYYY-MM-DD hh:mm:ss a');
+                    },
+                    "targets": 2
+                },
+                {
+                    "render": function (data, type, row) {
+                        return '<div class="btn-group">\n' +
+                            ' <button type="button" class="btn btn-default dropdown-toggle"\n' +
+                            '         data-toggle="dropdown" aria-expanded="false">Actions\n' +
+                            '     <span class="fa fa-caret-down"></span></button>\n' +
+                            ' <ul class="dropdown-menu">\n' +
+                            '     <li><a href="#"\n' +
+                            '            onclick="javascript:editProject(\''+ row['name']+'\')">\n' +
+                            '         <i class="fa fa-edit"></i> Rename</a></li>\n' +
+                            '     <li>\n' +
+                            '         <a href="#" onclick="javascript:deleteProject(\''+ row['name']+'\')" style="color:red">\n' +
+                            '             <i class="fa fa-trash"  ></i> Delete</a>\n' +
+                            '     </li>\n' +
+                            ' </ul>\n' +
+                            ' </div>';
+                    },
+                    "targets": 3
+                }
+            ]
+        });
+
+        setInterval(function () {
+                table.ajax.reload();
+            }, 10000);
+    });
     </script>
     <script>
     function showModalNewProject(){
         $('#modal_new_project').modal('show');
     }
 
-    function editProject(url){
+    function editProject(project_id){
+        var url = "/projects/" + project_id+"/edit";
         $("#formEditProject").attr("action", url);
         $('#modal_edit_project').modal('show');
     }
 
-    function deleteProject(url) {
+    function deleteProject(project_id) {
+        var url = "/projects/" + project_id+"/delete";
     bootbox.confirm("Are you sure want to delete?", function (result) {
         if (result) {
             $.ajax({
index 0f4248a..06b4770 100644 (file)
@@ -18,7 +18,7 @@ import json
 import logging
 
 import yaml
-from django.contrib.auth.decorators import login_required
+from sf_t3d.decorators import login_required
 from django.http import HttpResponse, JsonResponse
 from django.shortcuts import render, redirect
 
@@ -64,7 +64,6 @@ def user_projects(request):
     },'projectlist.html')
 
 
-
 def open_composer(request):
     user = osmutils.get_user(request)
     project_id = user.project_id
index 423efcd..da5526f 100644 (file)
                         </tr>
                         </thead>
                         <tbody>
-                        {% for s in sdns %}
-                            <tr>
-                                <td>{{ s|get:"name" }}</td>
-                                <td>{{ s|get:"_id" }}</td>
-                                <td>{{ s|get:"type" }}</td>
-                                <td>{{ s|get_sub:"_admin,operationalState"}}</td>
-                                <td>{{ s|get:"ip" }}</td>
-                                <td>{{ s|get:"port" }}</td>
-                                <td>
-                                    <div class="btn-group">
-                                        <button type="button" class="btn btn-default"
-                                                onclick="javascript:showSDN( '{{ s|get:"_id" }}')" data-toggle="tooltip" data-placement="top" data-container="body" title="Show Info"><i
-                                                class="fa fa-info"></i></button>
-                                        <button type="button" class="btn btn-default"
-                                                onclick="javascript:deleteSDN('{{ s|get:"_id" }}')" data-toggle="tooltip" data-placement="top" data-container="body" title="Delete"><i
-                                                class="far fa-trash-alt" ></i></button>
-                                    </div>
-                                </td>
 
-                            </tr>
-                        {% endfor %}
                         </tbody>
                     </table>
                 </div>
 
      <script>
     $(document).ready( function () {
-        $('#sdns_table').DataTable();
-    } );
+        var table = $('#sdns_table').DataTable({
+            responsive: true,
+            "ajax": {
+                "url": "/sdn/list",
+                "dataSrc": function (json) {
+                    console.log(json)
+                    return json['sdns'];
+                },
+                statusCode: {
+                    401: function () {
+                        console.log("no auth");
+                        moveToLogin(window.location.pathname);
+                    }
+                },
+                "error": function (hxr, error, thrown) {
+                    console.log(hxr)
+                    console.log(thrown)
+                    console.log(error);
+                }
+
+            },
+            "columns": [
+                {
+                    "render": function (data, type, row) {
+                        return row["name"];
+                    },
+                    "targets": 0
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row['_id'];
+                    },
+                    "targets": 1
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["type"];
+                    },
+                    "targets": 2
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["_admin"]["operationalState"];
+                    },
+                    "targets": 3
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["ip"];
+                    },
+                    "targets": 4
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["port"];
+                    },
+                    "targets": 5
+                },
+                {
+                    "render": function (data, type, row) {
+                        return '<div class="btn-group">' +
+                            '<button type="button" class="btn btn-default" ' +
+                            'onclick="javascript:showSDN( \''+row['_id'] + '\', \''+row['name'] +'\')" data-toggle="tooltip" data-placement="top" data-container="body" title="Show Info"><i class="fa fa-info"></i>' +
+                        '</button>' +
+                        '<button type="button" class="btn btn-default"' +
+                        'onclick="javascript:deleteSDN(\''+row['_id']+'\', \''+ row["name"] +'\')" data-toggle="tooltip" data-placement="top" data-container="body" title="Delete">' +
+                        '<i class="far fa-trash-alt" ></i></button></div>';
+                    },
+                    "targets": 6
+                }
+            ]
+        });
+
+        setInterval(function () {
+                table.ajax.reload();
+            }, 10000);
+    });
     </script>
 {% endblock %}
 
index e015ded..52be0a4 100644 (file)
@@ -15,7 +15,7 @@
 #
 
 from django.shortcuts import render, redirect
-from django.contrib.auth.decorators import login_required
+from sf_t3d.decorators import login_required
 from django.http import HttpResponse
 import json
 import logging
@@ -30,13 +30,15 @@ log = logging.getLogger('sdnctrlhandler/view.py')
 def list(request):
     user = osmutils.get_user(request)
     project_id = user.project_id
+    result = {'project_id': project_id}
+    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
+    if 'application/json' not in raw_content_types:
+        return __response_handler(request, result, 'sdn_list.html')
     client = Client()
-    result = client.sdn_list(user.get_token())
+    result_client = client.sdn_list(user.get_token())
+
+    result['sdns'] = result_client['data'] if result_client and result_client['error'] is False else []
 
-    result = {
-        'project_id': project_id,
-        'sdns': result['data'] if result and result['error'] is False else []
-    }
     return __response_handler(request, result, 'sdn_list.html')
 
 
diff --git a/sf_t3d/decorators.py b/sf_t3d/decorators.py
new file mode 100644 (file)
index 0000000..9f4981b
--- /dev/null
@@ -0,0 +1,76 @@
+#
+#   Copyright 2018 EveryUP Srl
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+"""
+ This Decorator is a modified version of django.contrib.auth.decorators, in order to avoid retirect to login_url
+ with AJAX calls.
+"""
+
+from django.http import HttpResponse
+from django.conf import settings
+from django.contrib.auth import REDIRECT_FIELD_NAME
+from django.shortcuts import resolve_url
+from django.utils.decorators import available_attrs
+from django.utils.six.moves.urllib.parse import urlparse
+from six import wraps
+from django.contrib.auth.views import redirect_to_login
+
+
+def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
+    """
+    Decorator for views that checks that the user passes the given test,
+    redirecting to the log-in page if necessary. The test should be a callable
+    that takes the user object and returns True if the user passes.
+    """
+
+    def decorator(view_func):
+        @wraps(view_func, assigned=available_attrs(view_func))
+        def _wrapped_view(request, *args, **kwargs):
+            if test_func(request.user):
+                return view_func(request, *args, **kwargs)
+            path = request.build_absolute_uri()
+            resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
+            # If the login url is the same scheme and net location then just
+            # use the path as the "next" url.
+            login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
+            current_scheme, current_netloc = urlparse(path)[:2]
+            if ((not login_scheme or login_scheme == current_scheme) and
+                    (not login_netloc or login_netloc == current_netloc)):
+                path = request.get_full_path()
+            raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
+            # if Browser call
+            if 'application/json' not in raw_content_types:
+                return redirect_to_login(path, resolved_login_url, redirect_field_name)
+            # if AJAX call
+            else:
+                return HttpResponse(status=401)
+        return _wrapped_view
+    return decorator
+
+
+def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):
+    """
+    Decorator for views that checks that the user is logged in, redirecting
+    to the log-in page if necessary.
+    """
+    actual_decorator = user_passes_test(
+        lambda u: u.is_authenticated,
+        login_url=login_url,
+        redirect_field_name=redirect_field_name
+    )
+    if function:
+        return actual_decorator(function)
+    return actual_decorator
index c53c0b4..fa9bef4 100644 (file)
    limitations under the License.
 */
 
-function performAction(url) {
+function performAction(instance_name, instance_id) {
+    var url = '/instances/ns/'+instance_id+'/action';
     $("#formActionNS").attr("action", url);
     $('#modal_instance_new_action').modal('show');
 }
 
-function exportMetricNs(url) {
-    console.log(url)
+function exportMetricNs(instance_name, instance_id) {
+    var url = '/instances/ns/'+instance_id+'/monitoring/metric';
     $("#formExportMetricNS").attr("action", url);
     $('#modal_instance_export_metric').modal('show');
 }
 
-function showInstanceTopology(url) {
-    window.location.href = url;
-}
-
-function newAlarmNs(url) {
+function newAlarmNs(instance_name, instance_id) {
+    var url = '/instances/ns/'+instance_id+'/monitoring/alarm';
     $("#formAlarmNS").attr("action", url);
     $('#modal_instance_new_alarm').modal('show');
 }
 
-function deleteNs(url, force) {
-    bootbox.confirm("Are you sure want to delete?", function (result) {
+function deleteNs(instance_name, instance_id, force) {
+    var url = '/instances/ns/'+instance_id+'/delete';
+    bootbox.confirm("Are you sure want to delete " + instance_name + "?", function (result) {
         if (result) {
             if (force)
                 url = url + '?force=true';
@@ -88,7 +87,8 @@ var removeFormGroup = function (event) {
     $formGroup.remove();
 };
 
-function showInstanceDetails(url_info) {
+function showInstanceDetails(type, instance_id) {
+    var url_info = '/instances/'+type+'/'+instance_id;
     var dialog = bootbox.dialog({
         message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
         closeButton: true
index 705fce2..d85ebcf 100644 (file)
@@ -15,7 +15,8 @@
 */
 
 
-function showOperationDetails(url_info) {
+function showOperationDetails(instance_id, operation_id) {
+    var url_info = '/instances/ns/'+instance_id+'/operation/' + operation_id;
     var dialog = bootbox.dialog({
         message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
         closeButton: true
index d6ee937..c85603c 100644 (file)
@@ -1,11 +1,11 @@
 function deletePackage(descriptor_type, package_id) {
-    var dialog = bootbox.dialog({
-        message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
-        closeButton: true
-    });
+
     bootbox.confirm("Are you sure want to delete?", function (result) {
         if (result) {
-
+            var dialog = bootbox.dialog({
+                message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
+                closeButton: true
+            });
             $.ajax({
                 url: '/projects/descriptors/' + descriptor_type + '/' + package_id + '/delete',
                 type: 'GET',
index 013cb6f..5542825 100644 (file)
@@ -1,5 +1,5 @@
-function deleteSDN(sdn_uuid) {
-    bootbox.confirm("Are you sure want to delete?", function (result) {
+function deleteSDN(sdn_uuid, name) {
+    bootbox.confirm("Are you sure want to delete " + name +"?", function (result) {
         if (result) {
             var dialog = bootbox.dialog({
                 message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
index 282c314..88f4770 100644 (file)
@@ -26,8 +26,9 @@ function openModalCreateUser(args) {
     $('#modal_new_user').modal('show');
 }
 
-function deleteUser(delete_url) {
-    bootbox.confirm("Are you sure want to delete?", function (confirm) {
+function deleteUser(user_id, name) {
+    var delete_url = '/admin/users/'+user_id+'/delete';
+    bootbox.confirm("Are you sure want to delete "+name+"?", function (confirm) {
         if (confirm) {
             var dialog = bootbox.dialog({
                 message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
index 83b580c..6763f78 100644 (file)
@@ -2,8 +2,8 @@ function generateUID() {
     return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4)
 }
 
-function openProject(pId) {
-    window.location.href = '/projects/' + pId;
+function moveToLogin(next) {
+    window.location.href =  (next) ? "/auth/?next="+next : '/auth/';
 }
 
 
index bb56c29..ee790ff 100644 (file)
 <script src="/static/bower_components/admin-lte/plugins/iCheck/icheck.min.js"></script>
 <!-- pace -->
 <script src="/static/bower_components/admin-lte/plugins/pace/pace.min.js"></script>
+<!-- momentjs -->
+<script src="/static/bower_components/moment/moment.js"></script>
 <!-- bootbox -->
 <script src="/static/bower_components/bootbox.js/bootbox.js"></script>
 <!-- RDCL3D AdminLTE session storage handler -->
index 8d7e84a..621df92 100644 (file)
                         </tr>
                         </thead>
                         <tbody>
-                        {% for s in users %}
-                            <tr>
-
-                                <td>{{ s|get:"username" }}</td>
-                                <td>{{ s|get:"projects" }}</td>
-                                <td>{{ s|get:"_id" }}</td>
-                                <td>{{ s|get_sub:"_admin,modified"|get_date}}</td>
-                                <td>{{ s|get_sub:"_admin,created"|get_date}}</td>
-
-                                <td>
-
-                                    <div class="btn-group">
-                            <button type="button" class="btn btn-default dropdown-toggle"
-                                    data-toggle="dropdown" aria-expanded="false">Actions
-                                <span class="fa fa-caret-down"></span></button>
-                            <ul class="dropdown-menu">
-
-                                <li>
-                                    <a href="#" onclick="javascript:deleteUser('{% url "users:delete" user_id=s|get:"_id"  %}')" style="color:red">
-                                        <i class="fa fa-trash"  ></i> Delete</a>
-
-                                </li>
-                            </ul>
-                            </div>
-                                </td>
-
-                            </tr>
-                        {% endfor %}
+
                         </tbody>
                     </table>
                 </div>
     <script src="/static/src/userhandler/user_list.js"></script>
     <script>
     $(document).ready( function () {
-    $('#users_table').DataTable();
-    } );
+        var table = $('#users_table').DataTable({
+            responsive: true,
+            "ajax": {
+                "url": "/admin/users/list",
+                "dataSrc": function (json) {
+                    return json['users'];
+                },
+                statusCode: {
+                    401: function () {
+                        console.log("no auth");
+                        moveToLogin(window.location.pathname);
+                    }
+                },
+                "error": function (hxr, error, thrown) {
+                    console.log(hxr)
+                    console.log(thrown)
+                    console.log(error);
+                }
+
+            },
+            "columns": [
+                {
+                    "render": function (data, type, row) {
+                        return row["username"];
+                    },
+                    "targets": 0
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row['projects'];
+                    },
+                    "targets": 1
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row['_id'];
+                    },
+                    "targets": 2
+                },
+                {
+                    "render": function (data, type, row) {
+                        return moment.unix(row["_admin"]['modified']).format('YYYY-MM-DD hh:mm:ss a');
+                    },
+                    "targets": 3
+                },
+                {
+                    "render": function (data, type, row) {
+                        return moment.unix(row["_admin"]['created']).format('YYYY-MM-DD hh:mm:ss a');;
+                    },
+                    "targets": 4
+                },
+                {
+                    "render": function (data, type, row) {
+                        return '<div class="btn-group">' +
+                            '<button type="button" class="btn btn-default dropdown-toggle"' +
+                            'data-toggle="dropdown" aria-expanded="false">Actions ' +
+                            '<span class="fa fa-caret-down"></span></button> ' +
+                            '<ul class="dropdown-menu">' +
+                            '<li> <a href="#" onclick="javascript:deleteUser(\'' + row['_id'] + '\', \''+row['username']+'\')"' +
+                        'style="color:red"><i class="fa fa-trash"></i> Delete</a></li> </ul></div>';
+                    },
+                    "targets": 5
+                }
+            ]
+        });
+
+        setInterval(function () {
+                table.ajax.reload();
+            }, 10000);
+    });
     </script>
 
 
index 8e312fa..aa0d8d2 100644 (file)
@@ -1,5 +1,5 @@
 from django.shortcuts import render, redirect
-from django.contrib.auth.decorators import login_required
+from sf_t3d.decorators import login_required
 from django.http import HttpResponse
 import json
 import logging
index 07cb857..adc823a 100644 (file)
                         </tr>
                         </thead>
                         <tbody>
-                        {% for p in datacenters %}
 
-                            <tr>
-                                <td>{{ p|get:"name" }}</td>
-                                <td>{{ p|get:"_id" }}</td>
-                                <td>{{ p|get:"vim_type" }}</td>
-                                <td>{{ p|get_sub:"_admin,operationalState"}}</td>
-                                <td>{{ p|get_sub:"_admin,description" }}</td>
-
-
-                                <td>
-                                    <div class="btn-group">
-                                        <button type="button" class="btn btn-default"
-                                                onclick="location.href='{% url "vims:show"   vim_id=p|get:"_id" %}'" data-toggle="tooltip" data-placement="top" data-container="body" title="Show Info"><i
-                                                class="fa fa-info"></i></button>
-                                        <button type="button" class="btn btn-default"
-                                                onclick="javascript:deleteVim('{% url "vims:delete"   vim_id=p|get:"_id" %}')" data-toggle="tooltip" data-placement="top" data-container="body" title="Delete"><i
-                                                class="far fa-trash-alt" ></i></button>
-                                    </div>
-                                </td>
-
-                            </tr>
-                        {% endfor %}
                         </tbody>
                     </table>
                 </div>
     <script src="/static/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
     <script>
     $(document).ready( function () {
-        $('#vims_table').DataTable();
-    } );
+        var table = $('#vims_table').DataTable({
+            responsive: true,
+            "ajax": {
+                "url": "/vims/list/",
+                "dataSrc": function (json) {
+                    return json['datacenters'];
+                },
+                statusCode: {
+                    401: function () {
+                        console.log("no auth");
+                        moveToLogin(window.location.pathname);
+                    }
+                },
+                "error": function (hxr, error, thrown) {
+                    console.log(hxr)
+                    console.log(thrown)
+                    console.log(error);
+                }
+
+            },
+            "columns": [
+                {
+                    "render": function (data, type, row) {
+                        return row["name"];
+                    },
+                    "targets": 0
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row['_id'];
+                    },
+                    "targets": 1
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["vim_type"];
+                    },
+                    "targets": 2
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["_admin"]['operationalState'];
+                    },
+                    "targets": 3
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["_admin"]['description'] || '';
+                    },
+                    "targets": 4
+                },
+                {
+                    "render": function (data, type, row) {
+                        return '<div class="btn-group"><button type="button" class="btn btn-default" ' +
+                            'onclick="location.href=\'/vims/'+row['_id']+'\'" data-toggle="tooltip" data-placement="top" data-container="body" title="Show Info">' +
+                        '<i class="fa fa-info"></i>' +
+                        '</button> ' +
+                        '<button type="button" class="btn btn-default"' +
+                        'onclick="javascript:deleteVim(\''+row['_id']+'\', \''+ row["name"] +'\')" data-toggle="tooltip" data-placement="top" data-container="body" title="Delete">' +
+                        '<i class="far fa-trash-alt" ></i></button></div>';
+                    },
+                    "targets": 5
+                }
+            ]
+        });
+
+        setInterval(function () {
+                table.ajax.reload();
+            }, 10000);
+    });
     </script>
     <script>
 
-        function deleteVim(url) {
-            bootbox.confirm("Are you sure want to delete?", function (result) {
+        function deleteVim(vim_id, vim_name) {
+            var url = "/vims/"+vim_id+"/delete";
+            bootbox.confirm("Are you sure want to delete " + vim_name + "?", function (result) {
                 if (result) {
                     var dialog = bootbox.dialog({
                         message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
index c40e4e9..d16fb7e 100644 (file)
@@ -15,7 +15,7 @@
 #
 
 from django.shortcuts import render, redirect
-from django.contrib.auth.decorators import login_required
+from sf_t3d.decorators import login_required
 from django.http import HttpResponse
 import json
 from lib.osm.osmclient.clientv2 import Client
@@ -31,13 +31,13 @@ log = logging.getLogger('vimhandler.py')
 def list(request):
     user = osmutils.get_user(request)
     project_id = user.project_id
+    result = {'type': 'ns', 'project_id': project_id}
+    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
+    if 'application/json' not in raw_content_types:
+        return __response_handler(request, result, 'vim_list.html')
     client = Client()
-    result = client.vim_list(user.get_token())
-    print result
-    result = {
-        "project_id": project_id,
-        "datacenters": result['data'] if result and result['error'] is False else []
-    }
+    result_client = client.vim_list(user.get_token())
+    result["datacenters"] = result_client['data'] if result_client and result_client['error'] is False else []
     return __response_handler(request, result, 'vim_list.html')