nsi list, show, create, delete 18/7118/1
authorlombardofr <lombardo@everyup.it>
Mon, 21 Jan 2019 14:43:52 +0000 (15:43 +0100)
committerlombardofr <lombardo@everyup.it>
Mon, 21 Jan 2019 14:43:52 +0000 (15:43 +0100)
Change-Id: I0c7757cdb7a38712e8960806765a2508b0013ce6
Signed-off-by: lombardofr <lombardo@everyup.it>
instancehandler/template/instance_list.html
instancehandler/template/instance_list_nsi.html [new file with mode: 0644]
instancehandler/template/modal/instance_create_nsi.html [new file with mode: 0644]
instancehandler/template/modal/instance_show.html
instancehandler/urls.py
instancehandler/views.py
lib/osm/osmclient/clientv2.py
projecthandler/template/project/osm/osm_project_left_sidebar.html
static/src/instancehandler/instance_create.js
static/src/instancehandler/instance_list.js

index 067dcb5..9fddbc0 100644 (file)
@@ -42,6 +42,8 @@
                 {% include 'instance_list_vnf.html' %}
             {% elif type == 'pdu' %}
                 {% include 'instance_list_pdu.html' %}
+            {% elif type == 'nsi' %}
+                {% include 'instance_list_nsi.html' %}
             {% endif %}
 
         </div>
@@ -49,6 +51,7 @@
     </div>
     {% include 'modal/instance_create.html' %}
     {% include 'modal/instance_create_pdu.html' %}
+    {% include 'modal/instance_create_nsi.html' %}
     {% include 'modal/instance_show.html' %}
     {% include 'modal/instance_new_action.html' %}
     {% include 'modal/instance_new_alarm.html' %}
                     "targets": 5,
                     "orderable": false
                 }
+            ],
+            'nsi': [
+                {
+                    "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["nst-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": "20%",
+                    "render": function (data, type, row) {
+                          var template = '<div class="btn-group">' +
+                            ' <button type="button" class="btn btn-default"' +
+                            '         onclick="javascript:showInstanceDetails(\''+instance_type+'\', \''+row["_id"]+'\')"' +
+                            '         data-toggle="tooltip" data-placement="top" data-container="body" title="Show Info">' +
+                            '     <i class="fa fa-info"></i>';
+                            /* if (row["operational-status"] === "running") {
+                                template += ' <button type="button" class="btn btn-default"' +
+                                '         onclick="javascript:showTopology(\'' + instance_type + '\', \'' + row["_id"] + '\')"' +
+                                '         data-toggle="tooltip" data-placement="top" data-container="body" title="Show Graph">' +
+                                '     <i class="fa fa-sitemap"></i>' +
+                                ' </button>';
+                            }else{
+                                template += ' <button type="button" disabled class="btn btn-default"' +
+                                '         onclick="javascript:showTopology(\'' + instance_type + '\', \'' + row["_id"] + '\')"' +
+                                '         data-toggle="tooltip" data-placement="top" data-container="body" title="Show Graph">' +
+                                '     <i class="fa fa-sitemap"></i>' +
+                                ' </button>';
+                            } */
+                            template += ' <button type="button" class="btn btn-default"' +
+                            '         onclick="javascript:deleteNsi(\''+ row["name"] +'\', \''+row["_id"]+'\')"' +
+                            '         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="/instances/nsi/' +row["_id"] +'/operation">' +
+                            '             <i class="fa fa-list"></i> History of operations</a></li>' +
+                            '     <li class="divider"></li>' +
+
+                            '     <li>' +
+                            '         <a href="javascript:deleteNsi(\''+ row["name"] +'\', \''+row["_id"]+'\', true)">' +
+                            '             <i class="far fa-trash-alt" style="color:red" ></i> Force delete</a></li>' +
+                            ' </ul>' +
+                            '</div>';
+                          return template;
+                    },
+                    "targets": 5,
+                    "orderable": false
+                },
+
             ]
         };
         $(document).ready(function () {
diff --git a/instancehandler/template/instance_list_nsi.html b/instancehandler/template/instance_list_nsi.html
new file mode 100644 (file)
index 0000000..a90e04c
--- /dev/null
@@ -0,0 +1,41 @@
+{% load get %}
+<div class="box">
+    <div class="box-header with-border">
+        <h3 class="box-title">Network Slices Instances</h3>
+
+        <div class="box-tools">
+
+            <button type="button" class="btn btn-default" data-container="body"
+                    data-toggle="tooltip" data-placement="top" title="Instantiate NSI"
+                    onclick="javascript:openModalCreateNSI({ 'project_id':'{{ project_id }}','vim_list_url': '{% url "vims:list"  %}', 'nst_list_url': '{% url "netslices:list_templates" %}'})">
+                <i class="fa fa-paper-plane"></i> <span> Create NSI</span></button>
+
+        </div>
+
+    </div>
+    <div class="box-body">
+    {% if alert_error %}
+        <div class="alert alert-danger alert-dismissible fade in">
+            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
+            <h4><i class="icon fa fa-ban"></i> Error</h4>
+            {{alert_error}}
+        </div>
+    {% endif %}
+        <table id="instances_table" class="table table-bordered table-striped responsive" style="width:100%">
+            <thead>
+            <tr>
+                <th>Name</th>
+                <th>Identifier</th>
+                <th>Nst name</th>
+                <th style="width:5%">Operational Status</th>
+                <th style="width:5%">Config Status</th>
+                <th>Detailed Status</th>
+                <th>Actions</th>
+            </tr>
+            </thead>
+            <tbody>
+
+            </tbody>
+        </table>
+    </div>
+</div>
diff --git a/instancehandler/template/modal/instance_create_nsi.html b/instancehandler/template/modal/instance_create_nsi.html
new file mode 100644 (file)
index 0000000..bad979f
--- /dev/null
@@ -0,0 +1,71 @@
+<div class="modal" id="modal_new_nsi" xmlns="http://www.w3.org/1999/html">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span></button>
+                <h4 class="modal-title">New NSI</h4>
+            </div>
+            <form id="formCreateNS" action='{% url "instances:create" type='nsi' %}'
+                  class="form-horizontal"
+                  method="post" enctype="multipart/form-data">
+                {% csrf_token %}
+                <div class="modal-body" id="modal_new_instance_body">
+                    <div class="form-group">
+                        <label for="nsiName" class="col-sm-3 control-label">Name *</label>
+                        <div class="col-sm-6">
+                            <input class="form-control" id="nsiName" name="nsiName"
+                                   placeholder="Ns name" required>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="nsiDescription" class="col-sm-3 control-label">Description *</label>
+                        <div class="col-sm-6">
+                            <input class="form-control" id="nsiDescription" name="nsiDescription"
+                                   placeholder="Description" required>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="nstId" class="col-sm-3 control-label">Nst Id *</label>
+                        <div class="col-sm-6">
+                            <select required id="nstId" class="js-example-basic form-control" name="nstId">
+                            </select>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="vimAccountIdNSI" class="col-sm-3 control-label">Vim Account Id *</label>
+                        <div class="col-sm-6">
+                            <select required id="vimAccountIdNSI" class="js-example-basic form-control" name="vimAccountId">
+                            </select>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="ssh_key_nsi" class="col-sm-3 control-label">SSH Key </label>
+                        <div class="col-sm-6">
+                            <textarea class="form-control" id="ssh_key_nsi" name="ssh_key"
+                                      placeholder="Paste your key here..." rows="4"></textarea>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="config_nsi" class="col-sm-3 control-label">Config </label>
+                        <div class="col-sm-6">
+                            <textarea class="form-control" id="config_nsi" name="config" placeholder="Yaml config"
+                                      rows="4"></textarea>
+                        </div>
+                    </div> 
+
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default pull-left" data-dismiss="modal">Cancel</button>
+                    <button class="btn btn-primary"
+                            data-loading-text="<i class='fa fa-circle-o-notch fa-spin'></i> Creating..."
+                            id="create_new_instance_nsi">Create
+                    </button>
+
+                </div>
+            </form>
+        </div>
+        <!-- /.modal-content -->
+    </div>
+    <!-- /.modal-dialog -->
+</div>
index 6df8bc1..1263855 100644 (file)
@@ -1,5 +1,5 @@
 <div class="modal" id="modal_show_instance" xmlns="http://www.w3.org/1999/html">
-    <div   class="modal-dialog">
+    <div   class="modal-dialog modal-lg">
         <div class="modal-content">
             <div class="modal-header">
                 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
index 40e20fa..e68f5ce 100644 (file)
@@ -18,15 +18,15 @@ from django.conf.urls import url
 from instancehandler import views
 
 urlpatterns = [
-    url(r'^(?P<type>[ns|vnf|pdu]+)/list/', views.list, name='list'),
-    url(r'^(?P<type>[ns|pdu]+)/create/', views.create, name='create'),
-    url(r'^(?P<type>[ns|vnf|pdu]+)/(?P<instance_id>[0-9a-z-]+)/delete$', views.delete, name='delete'),
+    url(r'^(?P<type>[ns|vnf|pdu|nsi]+)/list/', views.list, name='list'),
+    url(r'^(?P<type>[ns|pdu|nsi]+)/create/', views.create, name='create'),
+    url(r'^(?P<type>[ns|pdu|nsi]+)/(?P<instance_id>[0-9a-z-]+)/delete$', views.delete, name='delete'),
     url(r'^(?P<type>[ns|vnf]+)/(?P<instance_id>[0-9a-z-]+)/topology', views.show_topology, name='show_topology'),
     url(r'^(?P<type>[ns|vnf]+)/(?P<instance_id>[0-9a-z-]+)/action$', views.action, name='action'),
-    url(r'^(?P<type>[ns|vnf]+)/(?P<instance_id>[0-9a-z-]+)/operation$', views.ns_operations, name='ns_operations'),
+    url(r'^(?P<type>[ns|vnf|nsi]+)/(?P<instance_id>[0-9a-z-]+)/operation$', views.ns_operations, name='ns_operations'),
     url(r'^(?P<type>[ns|vnf]+)/(?P<instance_id>[0-9a-z-]+)/operation/(?P<op_id>[0-9a-z-]+)', views.ns_operation, name='ns_operation'),
     url(r'^(?P<type>[ns|vnf]+)/(?P<instance_id>[0-9a-z-]+)/monitoring/alarm$', views.create_alarm, name='ns_create_alarm'),
     url(r'^(?P<type>[ns|vnf]+)/(?P<instance_id>[0-9a-z-]+)/monitoring/metric$', views.export_metric, name='ns_export_metric'),
-    url(r'^(?P<type>[ns|vnf|pdu]+)/(?P<instance_id>[0-9a-z-]+)', views.show, name='show'),
+    url(r'^(?P<type>[ns|vnf|pdu|nsi]+)/(?P<instance_id>[0-9a-z-]+)', views.show, name='show'),
 
 ]
index ad7ead7..53dfb22 100644 (file)
@@ -15,7 +15,6 @@
 #
 
 from django.shortcuts import render, redirect
-#from django.contrib.auth.decorators import login_required
 from django.http import HttpResponse, JsonResponse
 import yaml
 import json
@@ -48,6 +47,8 @@ def list(request, type=None):
         instance_list = client.vnf_list(user.get_token())
     elif type == 'pdu':
         instance_list = client.pdu_list(user.get_token())
+    elif type == 'nsi':
+        instance_list = client.nsi_list(user.get_token())
 
     result['instances'] = instance_list['data'] if instance_list and instance_list['error'] is False else []
 
@@ -56,8 +57,10 @@ def list(request, type=None):
 @login_required
 def create(request, type=None):
     result = {}
+    config_vim_account_id = {}
     user = osmutils.get_user(request)
     client = Client()
+
     if type == 'ns':
         try:
 
@@ -96,6 +99,24 @@ def create(request, type=None):
             return __response_handler(request, {}, 'instances:list', to_redirect=True, type='ns', )
         result = client.ns_create(user.get_token(), ns_data)
         return __response_handler(request, result, 'instances:list', to_redirect=True, type='ns')
+
+    elif type == 'nsi':
+        try:
+            nsi_data = {
+                "nsiName": request.POST.get('nsiName', 'WithoutName'),
+                "nsiDescription": request.POST.get('nsiDescription', ''),
+                "nstId": request.POST.get('nstId', ''),
+                "vimAccountId": request.POST.get('vimAccountId', ''),
+            }
+            
+            if 'ssh_key' in request.POST and request.POST.get('ssh_key') != '':
+                nsi_data["ssh_keys"] = [request.POST.get('ssh_key')]
+        except Exception as e:
+            request.session["OSM_ERROR"] = "Error creating the NSI; Invalid parameters provided."
+            return __response_handler(request, {}, 'instances:list', to_redirect=True, type=type)
+        result = client.nsi_create(user.get_token(), nsi_data)
+        return __response_handler(request, result, 'instances:list', to_redirect=True, type=type)
+
     elif type == 'pdu':
         interface_param_name = request.POST.getlist('interfaces_name')
         interface_param_ip = request.POST.getlist('interfaces_ip')
@@ -128,12 +149,15 @@ 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}
+    result = {'type': type, '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)
+    if type == 'ns':
+        op_list = client.ns_op_list(user.get_token(), instance_id)
+    elif type == 'nsi':
+        op_list = client.nsi_op_list(user.get_token(), instance_id)
     result['operations'] = op_list['data'] if op_list and op_list['error'] is False else []
 
     return __response_handler(request, result, 'instance_operations_list.html')
@@ -164,7 +188,6 @@ def action(request, instance_id=None, type=None):
     if result['error']:
         return __response_handler(request, result['data'], url=None,
                                   status=result['data']['status'] if 'status' in result['data'] else 500)
-
     else:
         return __response_handler(request, {}, url=None, status=200)
 
@@ -179,8 +202,14 @@ def delete(request, instance_id=None, type=None):
         result = client.ns_delete(user.get_token(), instance_id, force)
     elif type == 'pdu':
         result = client.pdu_delete(user.get_token(), instance_id)
-    print result
-    return __response_handler(request, result, 'instances:list', to_redirect=True, type='ns')
+    elif type == 'nsi':
+        result = client.nsi_delete(user.get_token(), instance_id, force)
+
+    if result['error']:
+        return __response_handler(request, result['data'], url=None,
+                                  status=result['data']['status'] if 'status' in result['data'] else 500)
+    else:
+        return __response_handler(request, {}, url=None, status=200)
 
 @login_required
 def show_topology(request, instance_id=None, type=None):
@@ -224,6 +253,8 @@ def show(request, instance_id=None, type=None):
         result = client.vnf_get(user.get_token(), instance_id)
     elif type == 'pdu':
         result = client.pdu_get(user.get_token(), instance_id)
+    elif type == 'nsi':
+        result = client.nsi_get(user.get_token(), instance_id)
     print result
     return __response_handler(request, result)
 
index 191385e..f82bf4d 100644 (file)
@@ -343,6 +343,23 @@ class Client(object):
 
         return result
 
+    def nsi_list(self, token):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/yaml", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+        _url = "{0}/nsilcm/v1/netslice_instances".format(self._base_path)
+        try:
+            r = requests.get(_url, params=None, verify=False, stream=True, headers=headers)
+        except Exception as e:
+            log.exception(e)
+            result['data'] = str(e)
+            return result
+        if r.status_code == requests.codes.ok:
+            result['error'] = False
+        result['data'] = Util.json_loads_byteified(r.text)
+
+        return result
+    
     def ns_list(self, token):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/yaml", "accept": "application/json",
@@ -908,6 +925,24 @@ class Client(object):
 
         return result
 
+    def nsi_create(self, token, nsi_data):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/yaml", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+
+        _url = "{0}/nsilcm/v1/netslice_instances_content".format(self._base_path)
+
+        try:
+            r = requests.post(_url, json=nsi_data, verify=False, headers=headers)
+        except Exception as e:
+            log.exception(e)
+            result['data'] = str(e)
+            return result
+        if r.status_code == requests.codes.ok:
+            result['error'] = False
+        result['data'] = Util.json_loads_byteified(r.text)
+        return result
+
     def ns_create(self, token, ns_data):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/yaml", "accept": "application/json",
@@ -962,6 +997,24 @@ class Client(object):
 
         return result
 
+    def nsi_op_list(self, token, id):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/json", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+        _url = "{0}/nsilcm/v1/nsi_lcm_op_occs/?nsInstanceId={1}".format(self._base_path, id)
+
+        try:
+            r = requests.get(_url, params=None, verify=False, stream=True, headers=headers)
+        except Exception as e:
+            log.exception(e)
+            result['data'] = str(e)
+            return result
+        if r.status_code == requests.codes.ok:
+            result['error'] = False
+        result['data'] = Util.json_loads_byteified(r.text)
+
+        return result
+
     def ns_op(self, token, id):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/json", "accept": "application/json",
@@ -998,6 +1051,26 @@ class Client(object):
         result['data'] = Util.json_loads_byteified(r.text)
         return result
 
+    def nsi_delete(self, token, id, force=None):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/yaml", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+        query_path = ''
+        if force:
+            query_path = '?FORCE=true'
+        _url = "{0}/nsilcm/v1/netslice_instances_content/{1}{2}".format(self._base_path, id, query_path)
+        try:
+            r = requests.delete(_url, params=None, verify=False, headers=headers)
+        except Exception as e:
+            log.exception(e)
+            result['data'] = str(e)
+            return result
+        if r:
+            result['error'] = False
+        if r.status_code != requests.codes.no_content:
+            result['data'] = Util.json_loads_byteified(r.text)
+        return result
+
     def ns_delete(self, token, id, force=None):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/yaml", "accept": "application/json",
@@ -1035,6 +1108,23 @@ class Client(object):
             result['data'] = Util.json_loads_byteified(r.text)
         return result
 
+    def nsi_get(self, token, id):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/json", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+        _url = "{0}/nsilcm/v1/netslice_instances/{1}".format(self._base_path, id)
+
+        try:
+            r = requests.get(_url, params=None, verify=False, stream=True, headers=headers)
+        except Exception as e:
+            log.exception(e)
+            result['data'] = str(e)
+            return result
+        if r.status_code == requests.codes.ok:
+            result['error'] = False
+        result['data'] = Util.json_loads_byteified(r.text)
+        return result
+
     def ns_get(self, token, id):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/json", "accept": "application/json",
index 1855827..d39a0c8 100644 (file)
@@ -46,8 +46,9 @@
             </li>
             {% url "instances:list"  type='ns' as  instance_ns_list_url %}
             {% url "instances:list"  type='vnf' as  instance_vnf_list_url %}
-            {% url "instances:list"  type='pdu' as  instance_vnf_list_url %}
-            <li {% if request.get_full_path == instance_ns_list_url or  request.get_full_path == instance_vnf_list_url %}
+            {% url "instances:list"  type='pdu' as  instance_pdu_list_url %}
+            {% url "instances:list"  type='nsi' as  instance_nsi_list_url %}
+            <li {% if request.get_full_path == instance_ns_list_url or  request.get_full_path == instance_vnf_list_url or request.get_full_path == instance_pdu_list_url or request.get_full_path == instance_nsi_list_url %}
                 class="active treeview menu-open" {% else %} class="treeview  menu-open" {% endif %} >
                 <a href="#">
                     <i class="fa fa-paper-plane fa-fw"></i> <span>Instances</span>
                             <i class="far fa-hdd fa-fw"></i> <span>VNF Instances</span>
                         </a>
                     </li>
-                    {% url "instances:list"  type='pdu' as  instance_vnf_list_url %}
-                    <li {% if request.get_full_path == instance_vnf_list_url %} class="active" {% endif %} >
+                    {% url "instances:list"  type='pdu' as  instance_pdu_list_url %}
+                    <li {% if request.get_full_path == instance_pdu_list_url %} class="active" {% endif %} >
                         <a href='{% url "instances:list"   type="pdu" %}'>
-                            <i class="far fa-hdd fa-fw"></i> <span>PDU</span>
+                            <i class="far fa-hdd fa-fw"></i> <span>PDU Instances</span>
+                        </a>
+                    </li>
+                    {% url "instances:list"  type='nsi' as  instance_nsi_list_url %}
+                    <li {% if request.get_full_path == instance_nsi_list_url %} class="active" {% endif %} >
+                        <a href='{% url "instances:list"   type="nsi" %}'>
+                            <i class="fas fa-layer-group fa-fw"></i> <span>NetSlice Instances</span>
                         </a>
                     </li>
                 </ul>
index 4273f90..3cce0c4 100644 (file)
@@ -100,4 +100,66 @@ function openModalCreateNS(args) {
     }
 
     $('#modal_new_instance').modal('show');
+}
+function openModalCreateNSI(args) {
+    // load vim account list
+    select2_groups = $('#vimAccountIdNSI').select2({
+        placeholder: 'Select VIM',
+        width: '100%',
+        ajax: {
+            url: args.vim_list_url,
+            dataType: 'json',
+            processResults: function (data) {
+                vims = [];
+                if (data['datacenters']) {
+                    for (d in data['datacenters']) {
+                        var datacenter = data['datacenters'][d];
+                        vims.push({ id: datacenter['_id'], text: datacenter['name'] })
+                    }
+                }
+
+                return {
+                    results: vims
+                };
+            }
+        }
+    });
+
+    // load nsd list
+    select2_groups = $('#nstId').select2({
+        placeholder: 'Select NST',
+        width: '100%',
+        ajax: {
+            url: args.nst_list_url,
+            dataType: 'json',
+            processResults: function (data) {
+                nst_list = [];
+
+                if (data['templates']) {
+                    for (d in data['templates']) {
+                        var nst = data['templates'][d];
+                        nst_list.push({ id: nst['_id'], text: nst['name'] })
+                    }
+                }
+
+                return {
+                    results: nst_list
+                };
+            }
+        }
+    });
+
+    if (args.descriptor_id) {
+        // Set the value, creating a new option if necessary
+        if ($('#nstId').find("option[value='" + args.descriptor_id + "']").length) {
+            $('#nstId').val(args.descriptor_id).trigger('change');
+        } else {
+            // Create a DOM Option and pre-select by default
+            var newOption = new Option(args.descriptor_name, args.descriptor_id, true, true);
+            // Append it to the select
+            $('#nstId').append(newOption).trigger('change');
+        }
+    }
+
+    $('#modal_new_nsi').modal('show');
 }
\ No newline at end of file
index 88a1f57..7fa6524 100644 (file)
@@ -57,9 +57,61 @@ function deleteNs(instance_name, instance_id, force) {
                         location.reload();
                     }
                 },
-                error: function (error) {
+                error: function (result) {
                     dialog.modal('hide');
-                    bootbox.alert("An error occurred.");
+                    var data = result.responseJSON;
+                        var title = "Error " + (data && data.code ? data.code : 'unknown');
+                        var message = data && data.detail ? data.detail : 'No detail available.';
+                        bootbox.alert({
+                            title: title,
+                            message: message
+                        });
+                }
+            });
+        }
+    })
+}
+function deleteNsi(instance_name, instance_id, force) {
+    var url = '/instances/nsi/'+instance_id+'/delete';
+    bootbox.confirm("Are you sure want to delete " + instance_name + "?", function (result) {
+        if (result) {
+            if (force)
+                url = url + '?force=true';
+            var dialog = bootbox.dialog({
+                message: '<div class="text-center"><i class="fa fa-spin fa-spinner"></i> Loading...</div>',
+                closeButton: true
+            });
+            $.ajax({
+                url: url,
+                type: 'GET',
+                dataType: "json",
+                contentType: "application/json;charset=utf-8",
+                success: function (result) {
+                    console.log(result)
+                    if (result['error'] == true){
+                        dialog.modal('hide');
+                        var data = result.responseJSON;
+                        var title = "Error " + (data && data.code ? data.code : 'unknown');
+                        var message = data && data.detail ? data.detail : 'No detail available.';
+                        bootbox.alert({
+                            title: title,
+                            message: message
+                        });
+                    }
+                    else {
+                        dialog.modal('hide');
+                        location.reload();
+                    }
+                },
+                error: function (result) {
+                    dialog.modal('hide');
+                    var data = result.responseJSON;
+                        var title = "Error " + (data && data.code ? data.code : 'unknown');
+                        var message = data && data.detail ? data.detail : 'No detail available.';
+                        bootbox.alert({
+                            title: title,
+                            message: message
+                        });
                 }
             });
         }