pdu: list, create, show, delete 86/7086/1
authorlombardofr <lombardo@everyup.it>
Fri, 4 Jan 2019 14:25:45 +0000 (15:25 +0100)
committerlombardofr <lombardo@everyup.it>
Fri, 4 Jan 2019 14:25:45 +0000 (15:25 +0100)
Change-Id: I1d184eba4fef6cd55719ef5b0e51a29b05c34b96
Signed-off-by: lombardofr <lombardo@everyup.it>
12 files changed:
instancehandler/template/instance_list.html
instancehandler/template/instance_list_pdu.html [new file with mode: 0644]
instancehandler/template/instance_list_vnf.html
instancehandler/template/modal/instance_create.html
instancehandler/template/modal/instance_create_pdu.html [new file with mode: 0644]
instancehandler/template/modal/instance_new_action.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 bc94e5f..39d9b3c 100644 (file)
                 {% include 'instance_list_ns.html' %}
             {% elif type == 'vnf' %}
                 {% include 'instance_list_vnf.html' %}
                 {% include 'instance_list_ns.html' %}
             {% elif type == 'vnf' %}
                 {% include 'instance_list_vnf.html' %}
+            {% elif type == 'pdu' %}
+                {% include 'instance_list_pdu.html' %}
             {% endif %}
 
         </div>
 
     </div>
     {% include 'modal/instance_create.html' %}
             {% endif %}
 
         </div>
 
     </div>
     {% include 'modal/instance_create.html' %}
+    {% include 'modal/instance_create_pdu.html' %}
     {% include 'modal/instance_show.html' %}
     {% include 'modal/instance_new_action.html' %}
     {% include 'modal/instance_new_alarm.html' %}
     {% include 'modal/instance_show.html' %}
     {% include 'modal/instance_new_action.html' %}
     {% include 'modal/instance_new_alarm.html' %}
@@ -75,6 +78,7 @@
     <script src="/static/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
 
     <script>
     <script src="/static/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
 
     <script>
+        var table;
         var instance_type = '{{ type }}';
         var row_builder = {
             'ns': [
         var instance_type = '{{ type }}';
         var row_builder = {
             'ns': [
                 },
 
             ],
                 },
 
             ],
-            'vnf': [ {
+            'vnf': [ 
+                {
                     "render": function (data, type, row) {
                         return row["_id"];
                     },
                     "render": function (data, type, row) {
                         return row["_id"];
                     },
                     },
                     "targets": 5
                 },
                     },
                     "targets": 5
                 },
+            ],
+            'pdu': [
+            {
+                    "render": function (data, type, row) {
+                        return row["_id"];
+                    },
+                    "targets": 0
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["name"];
+                    },
+                    "targets": 1
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row["type"];
+                    },
+                    "targets": 2
+                },
+                {
+                    "render": function (data, type, row) {
+                        return row['_admin']['usageState'];
+                    },
+                    "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"' +
+                            '             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>' +
+                            '     </button>' +
+                            '<button type="button" class="btn btn-default"' +
+                            '         onclick="javascript:deletePDU(\''+ row["name"] +'\', \''+row["_id"]+'\')"' +
+                            '         data-toggle="tooltip" data-placement="top" data-container="body" title="Delete"><i' +
+                            '         class="far fa-trash-alt"></i></button>'+
+                            ' </div>';
+                    },
+                    "targets": 5
+                }
             ]
         };
         $(document).ready(function () {
             ]
         };
         $(document).ready(function () {
-            var table = $('#instances_table').DataTable({
+            table = $('#instances_table').DataTable({
                 responsive: true,
                 "ajax": {
                     "url": "/instances/" + instance_type + "/list/",
                 responsive: true,
                 "ajax": {
                     "url": "/instances/" + instance_type + "/list/",
             setInterval(function () {
                 table.ajax.reload();
             }, 10000);
             setInterval(function () {
                 table.ajax.reload();
             }, 10000);
+
+
         });
 
     </script>
         });
 
     </script>
diff --git a/instancehandler/template/instance_list_pdu.html b/instancehandler/template/instance_list_pdu.html
new file mode 100644 (file)
index 0000000..3eab3fc
--- /dev/null
@@ -0,0 +1,33 @@
+{% load get %}
+{% load date_tag %}
+<div class="box">
+    <div class="box-header with-border">
+        <h3 class="box-title">{{ type|upper }}</h3>
+
+        <div class="box-tools">
+            <button type="button" class="btn btn-default" data-container="body"
+                data-toggle="tooltip" data-placement="top" title="New PDU"
+                onclick="javascript:openModalCreatePDU({ 'project_id':'{{ project_id }}','vim_list_url': '{% url "vims:list"  %}'})">
+            <i class="fa fa-plus"></i> <span> New PDU</span>
+            </button>
+        </div>
+
+    </div>
+    <div class="box-body">
+        <table id="instances_table" class="table table-bordered table-striped responsive" style="width:100%">
+            <thead>
+            <tr>
+                <th>Identifier</th>
+                <th>Name</th>
+                <th>Type</th>
+                <th>Usage State</th>
+                <th>Created At</th>
+                <th>Actions</th>
+            </tr>
+            </thead>
+            <tbody>
+
+            </tbody>
+        </table>
+    </div>
+</div>
\ No newline at end of file
index d290ad1..ae82675 100644 (file)
@@ -1,14 +1,11 @@
 {% load get %}
 {% load date_tag %}
 {% load get %}
 {% load date_tag %}
-
 <div class="box">
     <div class="box-header with-border">
         <h3 class="box-title">{{ type|upper }} Instances</h3>
 
         <div class="box-tools">
 
 <div class="box">
     <div class="box-header with-border">
         <h3 class="box-title">{{ type|upper }} Instances</h3>
 
         <div class="box-tools">
 
-
-
         </div>
 
     </div>
         </div>
 
     </div>
index 7544919..8b4d40c 100644 (file)
@@ -6,7 +6,7 @@
                     <span aria-hidden="true">×</span></button>
                 <h4 class="modal-title">New Instance</h4>
             </div>
                     <span aria-hidden="true">×</span></button>
                 <h4 class="modal-title">New Instance</h4>
             </div>
-            <form id="formCreateNS" action='{% url "instances:create" %}'
+            <form id="formCreateNS" action='{% url "instances:create" type='ns' %}'
                   class="form-horizontal"
                   method="post" enctype="multipart/form-data">
                 {% csrf_token %}
                   class="form-horizontal"
                   method="post" enctype="multipart/form-data">
                 {% csrf_token %}
diff --git a/instancehandler/template/modal/instance_create_pdu.html b/instancehandler/template/modal/instance_create_pdu.html
new file mode 100644 (file)
index 0000000..444bd7e
--- /dev/null
@@ -0,0 +1,87 @@
+<div class="modal" id="modal_new_pdu" xmlns="http://www.w3.org/1999/html">
+    <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">
+                    <span aria-hidden="true">×</span></button>
+                <h4 class="modal-title">New PDU</h4>
+            </div>
+            <form id="formCreatePDU" action='{% url "instances:create" type='pdu' %}'
+                  class="form-horizontal"
+                  method="post" enctype="multipart/form-data">
+                {% csrf_token %}
+                <div class="modal-body" id="modal_new_pdu_body">
+                        <div id="pdu_base_div">
+
+                                <div class="form-group">
+        
+                                    <label for="pdu_name" class="col-sm-2">Name *</label>
+                                    <div class="col-sm-3">
+                                        <input class="form-control" id="pdu_name" name="name" placeholder="Name" required>
+                                    </div>
+        
+                                    <label for="pdu_type" class="col-sm-2">PDU type *</label>
+                                    <div class="col-sm-3">
+                                        <input class="form-control" id="pdu_type" name="pdu_type" placeholder="Type" required>
+                                    </div>
+                                </div>
+                                <div class="form-group">
+                                    <label for="pdu_vim_accounts" class="col-sm-2">Vim Accounts *</label>
+                                    <div class="col-sm-6">
+                                            <select required id="pdu_vim_accounts" class="js-example-basic-multiple form-control" name="pdu_vim_accounts"
+                                            multiple="multiple">
+                                            </select>
+                                    </div>
+                                </div>
+        
+                            </div>
+                            <div class="row">
+                                    <h4 class="col-sm-4">Interfaces:</h4>
+                                </div>
+                            <div id="interfaces_div">
+                                
+                                <div class="interface-group">
+                                    <button type="button" class="btn btn-success btn-add btn-sm pull-right">+</button>
+                                    <div class="form-group">
+                                        <label for="interfaces_name" class="col-sm-2">Name</label>
+                                        <div class="col-sm-3">
+                                            <input name="interfaces_name" class="form-control input-sm" required>
+                                        </div>
+                                        <label for="interfaces_name" class="col-sm-2">IP</label>
+                                        <div class="col-sm-3">
+                                            <input name="interfaces_ip" class="form-control input-sm" required>
+                                        </div>
+                                    </div>
+                                    <div class="form-group">
+                                        <label for="interfaces_mgmt" class="col-sm-2">Mgmt</label>
+                                        <div class="col-sm-3">
+                                                <select name="interfaces_mgmt" id="interfaces_mgmt" class="form-control">
+                                                    <option value="false">False</option>
+                                                    <option value="true">True</option>
+                                                </select>
+                                        </div>
+                                        <label for="interfaces_vimnetname" class="col-sm-2">Net name</label>
+                                        <div class="col-sm-3">
+                                            <input id="interfaces_vimnetname" name="interfaces_vimnetname" class="form-control input-sm" required>
+                                        </div>
+                                    </div>
+                                </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_pdu">Create
+                    </button>
+
+                </div>
+            </form>
+        </div>
+        <!-- /.modal-content -->
+    </div>
+    <!-- /.modal-dialog -->
+</div>
+
+
+
index 6cf3059..1aa1c24 100644 (file)
 
                 <div class="row">
                     <h5 class="col-sm-4">Primitive parameters :</h5>
 
                 <div class="row">
                     <h5 class="col-sm-4">Primitive parameters :</h5>
-
                 </div>
 
                 </div>
 
-                <div id="primitive_params_div">
-
+                <div id="primitive_params_div" class="primitive-group">
                     <div class="form-group">
                         <label  class="col-sm-2">Name: </label>
                             <div class="col-sm-3">
                     <div class="form-group">
                         <label  class="col-sm-2">Name: </label>
                             <div class="col-sm-3">
@@ -42,7 +40,6 @@
                     </div>
                 </div>
 
                     </div>
                 </div>
 
-
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-default pull-left" data-dismiss="modal">Cancel</button>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-default pull-left" data-dismiss="modal">Cancel</button>
index d097b60..40e20fa 100644 (file)
@@ -18,15 +18,15 @@ from django.conf.urls import url
 from instancehandler import views
 
 urlpatterns = [
 from instancehandler import views
 
 urlpatterns = [
-    url(r'^(?P<type>[ns|vnf]+)/list/', views.list, name='list'),
-    url(r'^create/', views.create, name='create'),
-    url(r'^(?P<type>[ns|vnf]+)/(?P<instance_id>[0-9a-z-]+)/delete$', views.delete, name='delete'),
+    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]+)/(?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]+)/(?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]+)/(?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]+)/(?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]+)/(?P<instance_id>[0-9a-z-]+)', views.show, name='show'),
+    url(r'^(?P<type>[ns|vnf|pdu]+)/(?P<instance_id>[0-9a-z-]+)', views.show, name='show'),
 
 ]
 
 ]
index d71cd32..ad7ead7 100644 (file)
@@ -31,7 +31,6 @@ log = logging.getLogger('instancehandler/view.py')
 
 @login_required
 def list(request, type=None):
 
 @login_required
 def list(request, type=None):
-
     user = osmutils.get_user(request)
     project_id = user.project_id
     client = Client()
     user = osmutils.get_user(request)
     project_id = user.project_id
     client = Client()
@@ -47,57 +46,82 @@ def list(request, type=None):
         instance_list = client.ns_list(user.get_token())
     elif type == 'vnf':
         instance_list = client.vnf_list(user.get_token())
         instance_list = client.ns_list(user.get_token())
     elif type == 'vnf':
         instance_list = client.vnf_list(user.get_token())
+    elif type == 'pdu':
+        instance_list = client.pdu_list(user.get_token())
 
     result['instances'] = instance_list['data'] if instance_list and instance_list['error'] is False else []
 
     return __response_handler(request, result, 'instance_list.html')
 
 
     result['instances'] = instance_list['data'] if instance_list and instance_list['error'] is False else []
 
     return __response_handler(request, result, 'instance_list.html')
 
-
 @login_required
 @login_required
-def create(request):
+def create(request, type=None):
     result = {}
     result = {}
-    try:
-
-        ns_data = {
-            "nsName": request.POST.get('nsName', 'WithoutName'),
-            "nsDescription": request.POST.get('nsDescription', ''),
-            "nsdId": request.POST.get('nsdId', ''),
-            "vimAccountId": request.POST.get('vimAccountId', ''),
-        }
-        if 'ssh_key' in request.POST and request.POST.get('ssh_key') != '':
-            ns_data["ssh_keys"] = [request.POST.get('ssh_key')]
-
-        if 'config' in request.POST:
-            ns_config = yaml.load(request.POST.get('config'))
-            if isinstance(ns_config, dict):
-                if "vim-network-name" in ns_config:
-                    ns_config["vld"] = ns_config.pop("vim-network-name")
-                if "vld" in ns_config:
-                    print ns_config
-                    for vld in ns_config["vld"]:
-                        if vld.get("vim-network-name"):
-                            if isinstance(vld["vim-network-name"], dict):
-                                vim_network_name_dict = {}
-                                for vim_account, vim_net in vld["vim-network-name"].items():
-                                    vim_network_name_dict[ns_data["vimAccountId"]] = vim_net
-                                vld["vim-network-name"] = vim_network_name_dict
-                    ns_data["vld"] = ns_config["vld"]
-                if "vnf" in ns_config:
-                    for vnf in ns_config["vnf"]:
-                        if vnf.get("vim_account"):
-                            vnf["vimAccountId"] = ns_data["vimAccountId"]
-
-                    ns_data["vnf"] = ns_config["vnf"]
-    except Exception as e:
-        request.session["OSM_ERROR"] = "Error creating the NS; Invalid parameters provided."
-        return __response_handler(request, {}, 'instances:list', to_redirect=True, type='ns', )
-
-    print ns_data
     user = osmutils.get_user(request)
     client = Client()
     user = osmutils.get_user(request)
     client = Client()
-    result = client.ns_create(user.get_token(), ns_data)
-    return __response_handler(request, result, 'instances:list', to_redirect=True, type='ns',)
-
+    if type == 'ns':
+        try:
+
+            ns_data = {
+                "nsName": request.POST.get('nsName', 'WithoutName'),
+                "nsDescription": request.POST.get('nsDescription', ''),
+                "nsdId": request.POST.get('nsdId', ''),
+                "vimAccountId": request.POST.get('vimAccountId', ''),
+            }
+            if 'ssh_key' in request.POST and request.POST.get('ssh_key') != '':
+                ns_data["ssh_keys"] = [request.POST.get('ssh_key')]
+
+            if 'config' in request.POST:
+                ns_config = yaml.load(request.POST.get('config'))
+                if isinstance(ns_config, dict):
+                    if "vim-network-name" in ns_config:
+                        ns_config["vld"] = ns_config.pop("vim-network-name")
+                    if "vld" in ns_config:
+                        print ns_config
+                        for vld in ns_config["vld"]:
+                            if vld.get("vim-network-name"):
+                                if isinstance(vld["vim-network-name"], dict):
+                                    vim_network_name_dict = {}
+                                    for vim_account, vim_net in vld["vim-network-name"].items():
+                                        vim_network_name_dict[ns_data["vimAccountId"]] = vim_net
+                                    vld["vim-network-name"] = vim_network_name_dict
+                        ns_data["vld"] = ns_config["vld"]
+                    if "vnf" in ns_config:
+                        for vnf in ns_config["vnf"]:
+                            if vnf.get("vim_account"):
+                                vnf["vimAccountId"] = ns_data["vimAccountId"]
+
+                        ns_data["vnf"] = ns_config["vnf"]
+        except Exception as e:
+            request.session["OSM_ERROR"] = "Error creating the NS; Invalid parameters provided."
+            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 == 'pdu':
+        interface_param_name = request.POST.getlist('interfaces_name')
+        interface_param_ip = request.POST.getlist('interfaces_ip')
+        interface_param_mgmt = request.POST.getlist('interfaces_mgmt')
+        interface_param_netname = request.POST.getlist('interfaces_vimnetname')
+
+        pdu_payload = {
+            "name": request.POST.get('name'),
+            "type": request.POST.get('pdu_type'),
+            "vim_accounts": request.POST.getlist('pdu_vim_accounts'),
+            "description": request.POST.get('description'),
+            "interfaces": []
+        }
+        for i in (0,len(interface_param_name)-1):
+            pdu_payload['interfaces'].append({
+                'name': interface_param_name[i],
+                'mgmt': True if interface_param_mgmt[i] == 'true' else False,
+                'ip-address': interface_param_ip[i],
+                'vim-network-name': interface_param_netname[i]
+            })
+        result = client.pdu_create(user.get_token(), pdu_payload)
+        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 ns_operations(request, instance_id=None, type=None):
 
 @login_required
 def ns_operations(request, instance_id=None, type=None):
@@ -151,7 +175,10 @@ def delete(request, instance_id=None, type=None):
     result = {}
     user = osmutils.get_user(request)
     client = Client()
     result = {}
     user = osmutils.get_user(request)
     client = Client()
-    result = client.ns_delete(user.get_token(), instance_id, force)
+    if type == 'ns':
+        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')
 
     print result
     return __response_handler(request, result, 'instances:list', to_redirect=True, type='ns')
 
@@ -176,10 +203,7 @@ def show_topology(request, instance_id=None, type=None):
                         vnfd_resp = client.vnfd_get(user.get_token(), vnfr['vnfd-id'])
                         nsr_object['vnfd'][vnfr['vnfd-id']] = vnfd_resp['vnfd:vnfd-catalog']['vnfd'][0]
 
                         vnfd_resp = client.vnfd_get(user.get_token(), vnfr['vnfd-id'])
                         nsr_object['vnfd'][vnfr['vnfd-id']] = vnfd_resp['vnfd:vnfd-catalog']['vnfd'][0]
 
-
-
         test = OsmParser()
         test = OsmParser()
-        #print nsr_object
 
         result = test.nsr_to_graph(nsr_object)
         return __response_handler(request, result)
 
         result = test.nsr_to_graph(nsr_object)
         return __response_handler(request, result)
@@ -198,6 +222,8 @@ def show(request, instance_id=None, type=None):
         result = client.ns_get(user.get_token(), instance_id)
     elif type == 'vnf':
         result = client.vnf_get(user.get_token(), instance_id)
         result = client.ns_get(user.get_token(), instance_id)
     elif type == 'vnf':
         result = client.vnf_get(user.get_token(), instance_id)
+    elif type == 'pdu':
+        result = client.pdu_get(user.get_token(), instance_id)
     print result
     return __response_handler(request, result)
 
     print result
     return __response_handler(request, result)
 
@@ -256,8 +282,8 @@ def create_alarm(request, instance_id=None, type=None):
 
 def __response_handler(request, data_res, url=None, to_redirect=None, *args, **kwargs):
     raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
 
 def __response_handler(request, data_res, url=None, to_redirect=None, *args, **kwargs):
     raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
-    if 'application/json' in raw_content_types or url is None:
-        return HttpResponse(json.dumps(data_res), content_type="application/json")
+    if not to_redirect and ('application/json' in raw_content_types or url is None):
+        return HttpResponse(json.dumps(data_res), content_type="application/json", *args, **kwargs)
     elif to_redirect:
         return redirect(url, *args, **kwargs)
     else:
     elif to_redirect:
         return redirect(url, *args, **kwargs)
     else:
index 6307198..d900af6 100644 (file)
@@ -325,6 +325,23 @@ class Client(object):
 
         return result
 
 
         return result
 
+    def pdu_list(self, token):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/yaml", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+        _url = "{0}/pdu/v1/pdu_descriptors".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 nsd_delete(self, token, id):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/yaml", "accept": "application/json",
     def nsd_delete(self, token, id):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/yaml", "accept": "application/json",
@@ -804,6 +821,24 @@ class Client(object):
         result['data'] = Util.json_loads_byteified(r.text)
         return result
 
         result['data'] = Util.json_loads_byteified(r.text)
         return result
 
+    def pdu_create(self, token, pdu_data):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/yaml", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+
+        _url = "{0}/pdu/v1/pdu_descriptors".format(self._base_path)
+
+        try:
+            r = requests.post(_url, json=pdu_data, verify=False, headers=headers)
+        except Exception as e:
+            log.exception(e)
+            result['data'] = str(e)
+            return result
+        if r.status_code == requests.codes.created:
+            result['error'] = False
+        result['data'] = Util.json_loads_byteified(r.text)
+        return result
+
     def ns_op_list(self, token, id):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/json", "accept": "application/json",
     def ns_op_list(self, token, id):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/json", "accept": "application/json",
@@ -878,6 +913,23 @@ class Client(object):
             result['data'] = Util.json_loads_byteified(r.text)
         return result
 
             result['data'] = Util.json_loads_byteified(r.text)
         return result
 
+    def pdu_delete(self, token, id):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/yaml", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+        _url = "{0}/pdu/v1/pdu_descriptors/{1}".format(self._base_path, id)
+        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_get(self, token, id):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/json", "accept": "application/json",
     def ns_get(self, token, id):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/json", "accept": "application/json",
@@ -912,6 +964,23 @@ class Client(object):
         result['data'] = Util.json_loads_byteified(r.text)
         return result
 
         result['data'] = Util.json_loads_byteified(r.text)
         return result
 
+    def pdu_get(self, token, id):
+        result = {'error': True, 'data': ''}
+        headers = {"Content-Type": "application/json", "accept": "application/json",
+                   'Authorization': 'Bearer {}'.format(token['id'])}
+        _url = "{0}/pdu/v1/pdu_descriptors/{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_alarm_create(self, token, id, alarm_payload):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/json",
     def ns_alarm_create(self, token, id, alarm_payload):
         result = {'error': True, 'data': ''}
         headers = {"Content-Type": "application/json",
index 85bedfe..ba649a9 100644 (file)
@@ -40,6 +40,7 @@
             </li>
             {% url "instances:list"  type='ns' as  instance_ns_list_url %}
             {% url "instances:list"  type='vnf' as  instance_vnf_list_url %}
             </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 %}
                 class="active treeview menu-open" {% else %} class="treeview  menu-open" {% endif %} >
                 <a href="#">
             <li {% if request.get_full_path == instance_ns_list_url or  request.get_full_path == instance_vnf_list_url %}
                 class="active treeview menu-open" {% else %} class="treeview  menu-open" {% endif %} >
                 <a href="#">
                             <i class="far fa-hdd fa-fw"></i> <span>VNF Instances</span>
                         </a>
                     </li>
                             <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 %} >
+                        <a href='{% url "instances:list"   type="pdu" %}'>
+                            <i class="far fa-hdd fa-fw"></i> <span>PDU</span>
+                        </a>
+                    </li>
                 </ul>
             </li>
 
                 </ul>
             </li>
 
index 47cba12..4273f90 100644 (file)
    limitations under the License.
 */
 
    limitations under the License.
 */
 
+function openModalCreatePDU(args) {
+    var select2_groups = $('#pdu_vim_accounts').select2({
+        placeholder: 'Select Vims',
+        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
+                };
+            }
+        }
+    });
+
+    $('#modal_new_pdu').modal('show');
+}
+
 function openModalCreateNS(args) {
     // load vim account list
     select2_groups = $('#vimAccountId').select2({
 function openModalCreateNS(args) {
     // load vim account list
     select2_groups = $('#vimAccountId').select2({
@@ -27,7 +52,7 @@ function openModalCreateNS(args) {
                 if (data['datacenters']) {
                     for (d in data['datacenters']) {
                         var datacenter = data['datacenters'][d];
                 if (data['datacenters']) {
                     for (d in data['datacenters']) {
                         var datacenter = data['datacenters'][d];
-                        vims.push({id: datacenter['_id'], text: datacenter['name']})
+                        vims.push({ id: datacenter['_id'], text: datacenter['name'] })
                     }
                 }
 
                     }
                 }
 
@@ -51,7 +76,7 @@ function openModalCreateNS(args) {
                 if (data['descriptors']) {
                     for (d in data['descriptors']) {
                         var nsd = data['descriptors'][d];
                 if (data['descriptors']) {
                     for (d in data['descriptors']) {
                         var nsd = data['descriptors'][d];
-                        nsd_list.push({id: nsd['_id'], text: nsd['name']})
+                        nsd_list.push({ id: nsd['_id'], text: nsd['name'] })
                     }
                 }
 
                     }
                 }
 
index a2c2003..88a1f57 100644 (file)
@@ -66,6 +66,38 @@ function deleteNs(instance_name, instance_id, force) {
     })
 }
 
     })
 }
 
+function deletePDU(instance_name, instance_id) {
+    var url = '/instances/pdu/'+instance_id+'/delete';
+    bootbox.confirm("Are you sure want to delete " + instance_name + "?", 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: url,
+                type: 'GET',
+                dataType: "json",
+                contentType: "application/json;charset=utf-8",
+                success: function (result) {
+                    if (result['error'] == true){
+                        dialog.modal('hide');
+                        bootbox.alert("An error occurred.");
+                    }
+                    else {
+                        dialog.modal('hide');
+                        location.reload();
+                    }
+                },
+                error: function (error) {
+                    dialog.modal('hide');
+                    bootbox.alert("An error occurred.");
+                }
+            });
+        }
+    })
+}
+
 var addFormGroup = function (event) {
     event.preventDefault();
 
 var addFormGroup = function (event) {
     event.preventDefault();
 
@@ -87,6 +119,27 @@ var removeFormGroup = function (event) {
     $formGroup.remove();
 };
 
     $formGroup.remove();
 };
 
+var addInterfaceGroup = function (event) {
+    event.preventDefault();
+
+    var $formGroup = $(this).closest('.interface-group');
+    var $formGroupClone = $formGroup.clone();
+
+    $(this)
+        .toggleClass('btn-success btn-add btn-danger btn-remove')
+        .html('–');
+
+    $formGroupClone.find('input').val('');
+    $formGroupClone.insertAfter($formGroup);
+
+};
+
+var removeInterfaceGroup = function (event) {
+    event.preventDefault();
+    var $formGroup = $(this).closest('.interface-group');
+    $formGroup.remove();
+};
+
 function showTopology(type, instance_id) {
     var url = '/instances/'+type+'/'+instance_id+'/topology';
     window.location = url;
 function showTopology(type, instance_id) {
     var url = '/instances/'+type+'/'+instance_id+'/topology';
     window.location = url;
@@ -156,8 +209,39 @@ $(document).ready(function () {
     }, json_editor_settings);
 
 
     }, json_editor_settings);
 
 
-    $(document).on('click', '.btn-add', addFormGroup);
-    $(document).on('click', '.btn-remove', removeFormGroup);
+    $(document).on('click', '.primitive-group .btn-add', addFormGroup);
+    $(document).on('click', '.primitive-group .btn-remove', removeFormGroup);
+
+    $(document).on('click', '.interface-group .btn-add', addInterfaceGroup);
+    $(document).on('click', '.interface-group .btn-remove', removeInterfaceGroup);
+
+    $("#formCreatePDU").submit(function (event) {
+        event.preventDefault(); //prevent default action
+        var post_url = $(this).attr("action"); //get form action url
+        var request_method = $(this).attr("method"); //get form GET/POST method
+        var form_data = new FormData(this); //Encode form elements for submission
+        $.ajax({
+            url: post_url,
+            type: request_method,
+            data: form_data,
+            headers: {
+                "Accept": 'application/json'
+            },
+            contentType: false,
+            processData: false
+        }).done(function (response, textStatus, jqXHR) {
+            table.ajax.reload();
+            $('#modal_new_pdu').modal('hide');
+        }).fail(function (result) {
+            var data = result.responseJSON;
+            var title = "Error " + (data.code ? data.code : 'unknown');
+            var message = data.detail ? data.detail : 'No detail available.';
+            bootbox.alert({
+                title: title,
+                message: message
+            });
+        });
+    });
 
     $("#formActionNS").submit(function (event) {
         event.preventDefault(); //prevent default action
 
     $("#formActionNS").submit(function (event) {
         event.preventDefault(); //prevent default action