X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fweb%2Fflows%2Fsrc%2Fmain%2Fresources%2Fjs%2Fpage.js;h=6e7fd25e049a17fc997b30c5d2003227e1b9a61f;hp=8b8a0b45a7f5608418482e71803222af7ec1eaf6;hb=5dc63c9502b18d9060826c581c71f9237b45160b;hpb=6fda9993ad4fb9e0ac911543bbd87b7cd0eb1b0f diff --git a/opendaylight/web/flows/src/main/resources/js/page.js b/opendaylight/web/flows/src/main/resources/js/page.js index 8b8a0b45a7..6e7fd25e04 100644 --- a/opendaylight/web/flows/src/main/resources/js/page.js +++ b/opendaylight/web/flows/src/main/resources/js/page.js @@ -11,1410 +11,1723 @@ one.f = {}; // specify dashlets and layouts one.f.dashlet = { - flows : { - id : 'flows', - name : 'Flow Entries' - }, - nodes : { - id : 'nodes', - name : 'Nodes' - }, - detail : { - id : 'detail', - name : 'Flow Detail' - } + flows : { + id : 'flows', + name : 'Flow Entries' + }, + nodes : { + id : 'nodes', + name : 'Nodes' + }, + detail : { + id : 'detail', + name : 'Flow Detail' + } }; one.f.menu = { - left : { - top : [ - one.f.dashlet.flows - ], - bottom : [ - one.f.dashlet.nodes - ] - }, - right : { - top : [], - bottom : [ - one.f.dashlet.detail - ] - } + left : { + top : [ + one.f.dashlet.flows + ], + bottom : [ + one.f.dashlet.nodes + ] + }, + right : { + top : [], + bottom : [ + one.f.dashlet.detail + ] + } }; one.f.address = { - root : "/controller/web/flows", - flows : { - main : "/main", - flows : "/node-flows", - nodes : "/node-ports", - flow : "/flow", - deleteFlows:"/flow/deleteFlows" - } + root : "/controller/web/flows", + flows : { + main : "/main", + flows : "/node-flows", + nodes : "/node-ports", + flow : "/flow", + modifyFlow : "/modifyFlow", + deleteFlows:"/flow/deleteFlows" + } } /** NODES **/ one.f.nodes = { - id : { - dashlet: { - datagrid: "one_f_nodes_id_dashlet_datagrid" - } - }, - registry : {}, - dashlet : function($dashlet) { - var $h4 = one.lib.dashlet.header("Nodes"); - $dashlet.append($h4); - - one.f.nodes.ajax.dashlet(function(data) { - var $gridHTML = one.lib.dashlet.datagrid.init(one.f.nodes.id.dashlet.datagrid, { - searchable: true, - filterable: false, - pagination: true, - flexibleRowsPerPage: true - }, "table-striped table-condensed"); - $dashlet.append($gridHTML); - var dataSource = one.f.nodes.data.nodesDataGrid(data); - $("#" + one.f.nodes.id.dashlet.datagrid).datagrid({dataSource: dataSource}); - }); - }, - ajax : { - dashlet : function(callback) { - $.getJSON(one.f.address.root+one.f.address.flows.flows, function(data) { - callback(data); - }); - } - }, - data : { - nodesDataGrid: function(data) { - var gridData = []; - $.each(data, function(nodeName, flow) { - var nodeFlowObject = {}; - nodeFlowObject["nodeName"] = nodeName; - nodeFlowObject["flows"] = flow; - nodeFlowObject["rowData"] = nodeName + flow + "-foobar"; - gridData.push(nodeFlowObject); - }); + id : { + dashlet: { + datagrid: "one_f_nodes_id_dashlet_datagrid" + } + }, + registry : {}, + dashlet : function($dashlet) { + var $h4 = one.lib.dashlet.header("Nodes"); + $dashlet.append($h4); - var source = new StaticDataSource({ - columns: [ - { - property: 'nodeName', - label: 'Node', - sortable: true - }, - { - property: 'flows', - label: 'Flows', - sortable: true - } - ], - data: gridData, - delay: 0 - }); - return source; - } - }, - body : { - dashlet : function(body, callback) { - var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed']; - var $table = one.lib.dashlet.table.table(attributes); + one.f.nodes.ajax.dashlet(function(data) { + var $gridHTML = one.lib.dashlet.datagrid.init(one.f.nodes.id.dashlet.datagrid, { + searchable: true, + filterable: false, + pagination: true, + flexibleRowsPerPage: true + }, "table-striped table-condensed"); + $dashlet.append($gridHTML); + var dataSource = one.f.nodes.data.nodesDataGrid(data); + $("#" + one.f.nodes.id.dashlet.datagrid).datagrid({dataSource: dataSource}); + }); + }, + ajax : { + dashlet : function(callback) { + $.getJSON(one.f.address.root+one.f.address.flows.flows, function(data) { + callback(data); + }); + } + }, + data : { + nodesDataGrid: function(data) { + var gridData = []; + $.each(data, function(nodeName, flow) { + var nodeFlowObject = {}; + nodeFlowObject["nodeName"] = nodeName; + nodeFlowObject["flows"] = flow; + nodeFlowObject["rowData"] = nodeName + flow + "-foobar"; + gridData.push(nodeFlowObject); + }); + + var source = new StaticDataSource({ + columns: [ + { + property: 'nodeName', + label: 'Node', + sortable: true + }, + { + property: 'flows', + label: 'Flows', + sortable: true + } + ], + data: gridData, + delay: 0 + }); + return source; + } + }, + body : { + dashlet : function(body, callback) { + var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed']; + var $table = one.lib.dashlet.table.table(attributes); - var headers = ['Node', 'Flows']; - var $thead = one.lib.dashlet.table.header(headers); - $table.append($thead); + var headers = ['Node', 'Flows']; + var $thead = one.lib.dashlet.table.header(headers); + $table.append($thead); - var $tbody = one.lib.dashlet.table.body(body); - $table.append($tbody); + var $tbody = one.lib.dashlet.table.body(body); + $table.append($tbody); - return $table; - } + return $table; } + } } /** FLOW DETAIL **/ one.f.detail = { - id : {}, - registry : {}, - dashlet : function($dashlet, details) { - var $h4 = one.lib.dashlet.header("Flow Details"); - $dashlet.append($h4); - - // details - if (details == undefined) { - var $none = $(document.createElement('div')); - $none.addClass('none'); - var $p = $(document.createElement('p')); - $p.text('Please select a flow'); - $p.addClass('text-center').addClass('text-info'); + id : {}, + registry : {}, + dashlet : function($dashlet, details) { + var $h4 = one.lib.dashlet.header("Flow Details"); + $dashlet.append($h4); - $dashlet.append($none) - .append($p); - } - }, - data : { - dashlet : function(data) { - var body = []; - var tr = {}; - var entry = []; - - entry.push(data['name']); - entry.push(data['node']); - entry.push(data['flow']['priority']); - entry.push(data['flow']['hardTimeout']); - entry.push(data['flow']['idleTimeout']); - - tr.entry = entry; - body.push(tr); - return body; - }, - description : function(data) { - var body = []; - var tr = {}; - var entry = []; - entry.push(data['flow']['ingressPort']); - entry.push(data['flow']['etherType']); - entry.push(data['flow']['vlanId']); - entry.push(data['flow']['vlanPriority']); - entry.push(data['flow']['srcMac']); - entry.push(data['flow']['dstMac']); - entry.push(data['flow']['srcIp']); - entry.push(data['flow']['dstIp']); - entry.push(data['flow']['tosBits']); - entry.push(data['flow']['srcPort']); - entry.push(data['flow']['dstPort']); - entry.push(data['flow']['protocol']); - entry.push(data['flow']['cookie']); - - tr.entry = entry; - body.push(tr); - return body; - }, - actions : function(data) { - var body = []; - var tr = {}; - var entry = []; - - var actions = ''; - $(data['flow']['actions']).each(function(index, value) { - actions += value + ', '; - }); - actions = actions.slice(0,-2); - entry.push(actions); + // details + if (details == undefined) { + var $none = $(document.createElement('div')); + $none.addClass('none'); + var $p = $(document.createElement('p')); + $p.text('Please select a flow'); + $p.addClass('text-center').addClass('text-info'); - tr.entry = entry; - body.push(tr); - return body; + $dashlet.append($none) + .append($p); + } + }, + data : { + dashlet : function(data) { + var body = []; + var tr = {}; + var entry = []; + + entry.push(data['name']); + entry.push(data['node']); + entry.push(data['flow']['priority']); + entry.push(data['flow']['hardTimeout']); + entry.push(data['flow']['idleTimeout']); + + tr.entry = entry; + body.push(tr); + return body; + }, + description : function(data) { + var body = []; + var tr = {}; + var entry = []; + entry.push(data['flow']['ingressPort']); + entry.push(data['flow']['etherType']); + entry.push(data['flow']['vlanId']); + entry.push(data['flow']['vlanPriority']); + entry.push(data['flow']['srcMac']); + entry.push(data['flow']['dstMac']); + entry.push(data['flow']['srcIp']); + entry.push(data['flow']['dstIp']); + entry.push(data['flow']['tosBits']); + entry.push(data['flow']['srcPort']); + entry.push(data['flow']['dstPort']); + entry.push(data['flow']['protocol']); + entry.push(data['flow']['cookie']); + + tr.entry = entry; + body.push(tr); + return body; + }, + actions : function(data) { + var body = []; + var tr = {}; + var entry = []; + var actions = ''; + + $(data['flow']['actions']).each(function(index, value) { + var locEqualTo = value.indexOf("="); + if ( locEqualTo == -1 ) { + actions += value + ', '; + } else { + var action = value.substr(0,locEqualTo); + if( action == "OUTPUT") { + var portIds = value.substr(locEqualTo+1).split(","); + actions += action + "="; + var allPorts = one.f.flows.registry.nodeports[one.f.flows.registry.selectedNode]['ports']; + for(var i =0; i < portIds.length ; i++) { + var portName = allPorts[portIds[i]]; + actions += portName + ", "; + } + } else { + actions += value + ', '; + } } + }); + actions = actions.slice(0,-2); + entry.push(actions); + + tr.entry = entry; + body.push(tr); + return body; + } + }, + body : { + dashlet : function(body) { + // create table + var header = ['Flow Name', 'Node', 'Priority', 'Hard Timeout', 'Idle Timeout']; + var $thead = one.lib.dashlet.table.header(header); + var attributes = ['table-striped', 'table-bordered', 'table-condensed']; + var $table = one.lib.dashlet.table.table(attributes); + $table.append($thead); + + var $tbody = one.lib.dashlet.table.body(body); + $table.append($tbody); + + return $table; }, - body : { - dashlet : function(body) { - // create table - var header = ['Flow Name', 'Node', 'Priority', 'Hard Timeout', 'Idle Timeout']; - var $thead = one.lib.dashlet.table.header(header); - var attributes = ['table-striped', 'table-bordered', 'table-condensed']; - var $table = one.lib.dashlet.table.table(attributes); - $table.append($thead); - - var $tbody = one.lib.dashlet.table.body(body); - $table.append($tbody); - - return $table; - }, - description : function(body) { - var header = ['Input Port', 'Ethernet Type', 'VLAN ID', 'VLAN Priority', 'Source MAC', 'Dest MAC', 'Source IP', 'Dest IP', 'ToS', 'Source Port', 'Dest Port', 'Protocol', 'Cookie']; - var $thead = one.lib.dashlet.table.header(header); - var attributes = ['table-striped', 'table-bordered', 'table-condensed']; - var $table = one.lib.dashlet.table.table(attributes); - $table.append($thead); + description : function(body) { + var header = ['Input Port', 'Ethernet Type', 'VLAN ID', 'VLAN Priority', 'Source MAC', 'Dest MAC', 'Source IP', 'Dest IP', 'ToS', 'Source Port', 'Dest Port', 'Protocol', 'Cookie']; + var $thead = one.lib.dashlet.table.header(header); + var attributes = ['table-striped', 'table-bordered', 'table-condensed']; + var $table = one.lib.dashlet.table.table(attributes); + $table.append($thead); - var $tbody = one.lib.dashlet.table.body(body); - $table.append($tbody); + var $tbody = one.lib.dashlet.table.body(body); + $table.append($tbody); - return $table; - }, - actions : function(body) { - var header = ['Actions']; - var $thead = one.lib.dashlet.table.header(header); - var attributes = ['table-striped', 'table-bordered', 'table-condensed']; - var $table = one.lib.dashlet.table.table(attributes); - $table.append($thead); + return $table; + }, + actions : function(body) { + var header = ['Actions']; + var $thead = one.lib.dashlet.table.header(header); + var attributes = ['table-striped', 'table-bordered', 'table-condensed']; + var $table = one.lib.dashlet.table.table(attributes); + $table.append($thead); - var $tbody = one.lib.dashlet.table.body(body); - $table.append($tbody); + var $tbody = one.lib.dashlet.table.body(body); + $table.append($tbody); - return $table; - } + return $table; } + } } /** FLOW ENTRIES **/ one.f.flows = { - id : { - dashlet : { - add : "one_f_flows_id_dashlet_add", - removeMultiple : "one_f_flows_id_dashlet_removeMultiple", - remove : "one_f_flows_id_dashlet_remove", - toggle : "one_f_flows_id_dashlet_toggle", - datagrid : "one_f_flows_id_dashlet_datagrid", - selectAllFlows : "one_f_flows_id_dashlet_selectAllFlows" - }, + id : { + dashlet : { + add : "one_f_flows_id_dashlet_add", + removeMultiple : "one_f_flows_id_dashlet_removeMultiple", + remove : "one_f_flows_id_dashlet_remove", + toggle : "one_f_flows_id_dashlet_toggle", + edit : "one_f_flows_id_dashlet_edit", + datagrid : "one_f_flows_id_dashlet_datagrid", + selectAllFlows : "one_f_flows_id_dashlet_selectAllFlows" + }, + modal : { + install : "one_f_flows_id_modal_install", + edit : "one_f_flows_id_modal_edit", + add : "one_f_flows_id_modal_add", + close : "one_f_flows_id_modal_close", + modal : "one_f_flows_id_modal_modal", + dialog : { + modal : "one_f_flows_id_modal_dialog_modal", + remove : "one_f_flows_id_modal_dialog_remove", + close : "one_f_flows_id_modal_dialog_close" + }, + action : { + button : "one_f_flows_id_modal_action_button", + modal : "one_f_flows_id_modal_action_modal", + add : "one_f_flows_id_modal_action_add", + close : "one_f_flows_id_modal_action_close", + table : "one_f_flows_id_modal_action_table", + addOutputPorts : "one_f_flows_id_modal_action_addOutputPorts", + setVlanId : "one_f_flows_id_modal_action_setVlanId", + setVlanPriority : "one_f_flows_id_modal_action_setVlanPriority", + modifyDatalayerSourceAddress : "one_f_flows_id_modal_action_modifyDatalayerSourceAddress", + modifyDatalayerDestinationAddress : "one_f_flows_id_modal_action_modifyDatalayerDestinationAddress", + modifyNetworkSourceAddress : "one_f_flows_modal_action_modifyNetworkSourceAddress", + modifyNetworkDestinationAddress : "one_f_flows_modal_action_modifyNetworkDestinationAddress", + modifyTosBits : "one_f_flows_modal_action_modifyTosBits", + modifyTransportSourcePort : "one_f_flows_modal_action_modifyTransportSourcePort", + modifyTransportDestinationPort : "one_f_flows_modal_action_modifyTransportDestinationPort", + enqueue : 'one-f-flows-modal-action-enqueue', + queue : 'one-f-flows-modal-action-queue', + setEthertype : 'one-f-flows-modal-action-setEthertype', + pushVlan : 'one-f-flows-modal-action-pushVlan', + setVlanCfi : 'one-f-flows-modal-action-setVlanCfi', modal : { - install : "one_f_flows_id_modal_install", - add : "one_f_flows_id_modal_add", - close : "one_f_flows_id_modal_close", - modal : "one_f_flows_id_modal_modal", - dialog : { - modal : "one_f_flows_id_modal_dialog_modal", - remove : "one_f_flows_id_modal_dialog_remove", - close : "one_f_flows_id_modal_dialog_close" - }, - action : { - button : "one_f_flows_id_modal_action_button", - modal : "one_f_flows_id_modal_action_modal", - add : "one_f_flows_id_modal_action_add", - close : "one_f_flows_id_modal_action_close", - table : "one_f_flows_id_modal_action_table", - addOutputPorts : "one_f_flows_id_modal_action_addOutputPorts", - setVlanId : "one_f_flows_id_modal_action_setVlanId", - setVlanPriority : "one_f_flows_id_modal_action_setVlanPriority", - modifyDatalayerSourceAddress : "one_f_flows_id_modal_action_modifyDatalayerSourceAddress", - modifyDatalayerDestinationAddress : "one_f_flows_id_modal_action_modifyDatalayerDestinationAddress", - modifyNetworkSourceAddress : "one_f_flows_modal_action_modifyNetworkSourceAddress", - modifyNetworkDestinationAddress : "one_f_flows_modal_action_modifyNetworkDestinationAddress", - modifyTosBits : "one_f_flows_modal_action_modifyTosBits", - modifyTransportSourcePort : "one_f_flows_modal_action_modifyTransportSourcePort", - modifyTransportDestinationPort : "one_f_flows_modal_action_modifyTransportDestinationPort", - modal : { - modal : "one_f_flows_modal_action_modal_modal", - remove : "one_f_flows_modal_action_modal_remove", - cancel : "one_f_flows_modal_action_modal_cancel" - } - }, - form : { - name : "one_f_flows_id_modal_form_name", - nodes : "one_f_flows_id_modal_form_nodes", - port : "one_f_flows_id_modal_form_port", - priority : "one_f_flows_id_modal_form_priority", - hardTimeout : "one_f_flows_id_modal_form_hardTimeout", - idleTimeout : "one_f_flows_id_modal_form_idleTimeout", - cookie : "one_f_flows_id_modal_form_cookie", - etherType : "one_f_flows_id_modal_form_etherType", - vlanId : "one_f_flows_id_modal_form_vlanId", - vlanPriority : "one_f_flows_id_modal_form_vlanPriority", - srcMac : "one_f_flows_id_modal_form_srcMac", - dstMac : "one_f_flows_id_modal_form_dstMac", - srcIp : "one_f_flows_id_modal_form_srcIp", - dstIp : "one_f_flows_id_modal_form_dstIp", - tosBits : "one_f_flows_id_modal_form_tosBits", - srcPort : "one_f_flows_id_modal_form_srcPort", - dstPort : "one_f_flows_id_modal_form_dstPort", - protocol : "one_f_flows_id_modal_form_protocol" - } + modal : "one_f_flows_modal_action_modal_modal", + remove : "one_f_flows_modal_action_modal_remove", + cancel : "one_f_flows_modal_action_modal_cancel" } - }, - registry : {}, - dashlet : function($dashlet, callback) { - - // load body - one.f.flows.ajax.dashlet(function(data) { - - var $h4 = one.lib.dashlet.header("Flow Entries"); - - $dashlet.append($h4); - if (one.f.flows.registry.privilege === 'WRITE') { - var button = one.lib.dashlet.button.single("Add Flow Entry", one.f.flows.id.dashlet.add, "btn-primary", "btn-mini"); - var $button = one.lib.dashlet.button.button(button); - - $button.click(function() { - var $modal = one.f.flows.modal.initialize(); - $modal.modal(); - }); - $dashlet.append($button); - var button = one.lib.dashlet.button.single("Remove Flow Entry", one.f.flows.id.dashlet.removeMultiple, "btn-danger", "btn-mini"); - var $button = one.lib.dashlet.button.button(button); - - $button.click(function() { - var checkedCheckBoxes = $('.flowEntry[type=checkbox]:checked'); - if (checkedCheckBoxes.size() === 0) { - return false; - } - - var requestData = []; - - checkedCheckBoxes.each(function(index, value) { - var flowEntry = {}; - flowEntry['name'] = checkedCheckBoxes[index].name; - flowEntry['node'] = checkedCheckBoxes[index].getAttribute("node"); - requestData.push(flowEntry); - }); - one.f.flows.modal.removeMultiple.dialog(requestData); - }); - $dashlet.append($button); + }, + form : { + name : "one_f_flows_id_modal_form_name", + nodes : "one_f_flows_id_modal_form_nodes", + port : "one_f_flows_id_modal_form_port", + priority : "one_f_flows_id_modal_form_priority", + hardTimeout : "one_f_flows_id_modal_form_hardTimeout", + idleTimeout : "one_f_flows_id_modal_form_idleTimeout", + cookie : "one_f_flows_id_modal_form_cookie", + etherType : "one_f_flows_id_modal_form_etherType", + vlanId : "one_f_flows_id_modal_form_vlanId", + vlanPriority : "one_f_flows_id_modal_form_vlanPriority", + srcMac : "one_f_flows_id_modal_form_srcMac", + dstMac : "one_f_flows_id_modal_form_dstMac", + srcIp : "one_f_flows_id_modal_form_srcIp", + dstIp : "one_f_flows_id_modal_form_dstIp", + tosBits : "one_f_flows_id_modal_form_tosBits", + srcPort : "one_f_flows_id_modal_form_srcPort", + dstPort : "one_f_flows_id_modal_form_dstPort", + protocol : "one_f_flows_id_modal_form_protocol", + action : 'one-f-flows-id-modal-form-action' + } + } + }, + registry : {}, + dashlet : function($dashlet, callback) { + // load body + one.f.flows.ajax.dashlet(function(data) { + var $h4 = one.lib.dashlet.header("Flow Entries"); + $dashlet.append($h4); + if (one.f.flows.registry.privilege === 'WRITE') { + var button = one.lib.dashlet.button.single("Add Flow Entry", one.f.flows.id.dashlet.add, "btn-primary", "btn-mini"); + var $button = one.lib.dashlet.button.button(button); + + $button.click(function() { + var $modal = one.f.flows.modal.initialize(); + $modal.modal(); + }); + $dashlet.append($button); + var button = one.lib.dashlet.button.single("Remove Flow Entry", one.f.flows.id.dashlet.removeMultiple, "btn-danger", "btn-mini"); + var $button = one.lib.dashlet.button.button(button); + + $button.click(function() { + var checkedCheckBoxes = $('.flowEntry[type=checkbox]:checked'); + if (checkedCheckBoxes.size() === 0) { + return false; + } + var requestData = []; + + checkedCheckBoxes.each(function(index, value) { + var flowEntry = {}; + flowEntry['name'] = checkedCheckBoxes[index].name; + flowEntry['node'] = checkedCheckBoxes[index].getAttribute("node"); + requestData.push(flowEntry); + }); + one.f.flows.modal.removeMultiple.dialog(requestData); + }); + $dashlet.append($button); + + } + var $gridHTML = one.lib.dashlet.datagrid.init(one.f.flows.id.dashlet.datagrid, { + searchable: true, + filterable: false, + pagination: true, + flexibleRowsPerPage: true + }, "table-striped table-condensed"); + $dashlet.append($gridHTML); + var dataSource = one.f.flows.data.flowsDataGrid(data); + $("#" + one.f.flows.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() { + $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).click(function() { + $("#" + one.f.flows.id.dashlet.datagrid).find(':checkbox').prop('checked', + $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).is(':checked')); + }); + + $("#" + one.f.flows.id.dashlet.datagrid).find("tbody tr").each(function(index, tr) { + $tr = $(tr); + $span = $("td span", $tr); + var flowstatus = $span.data("flowstatus"); + if($span.data("installinhw") != null) { + var installInHw = $span.data("installinhw").toString(); + if(installInHw == "true" && flowstatus == "Success") { + $tr.addClass("success"); + } else { + $tr.addClass("warning"); } + } + // attach mouseover to show pointer cursor + $tr.mouseover(function() { + $(this).css("cursor", "pointer"); + }); + // attach click event + $tr.click(function() { + var $td = $($(this).find("td")[1]); + var id = $td.text(); + var node = $td.find("span").data("nodeid"); + one.f.flows.detail(id, node); + }); + $(".flowEntry").click(function(e){ + if (!$('.flowEntry[type=checkbox]:not(:checked)').length) { + $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows) + .prop("checked", + true); + } else { + $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows) + .prop("checked", + false); + } + e.stopPropagation(); + }); + }); + }); + + // details callback + if(callback != undefined) callback(); + }); + }, + detail : function(id, node) { + // clear flow details + var $detailDashlet = one.main.dashlet.right.bottom; + $detailDashlet.empty(); + var $h4 = one.lib.dashlet.header("Flow Overview"); + $detailDashlet.append($h4); + + // details + var flows = one.f.flows.registry.flows; + one.f.flows.registry['selectedId'] = id; + one.f.flows.registry['selectedNode'] = node; + var flow; + $(flows).each(function(index, value) { + if (value.name == id && value.nodeId == node) { + flow = value; + } + }); + if (one.f.flows.registry.privilege === 'WRITE') { + // remove button + var button = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.dashlet.remove, "btn-danger", "btn-mini"); + var $button = one.lib.dashlet.button.button(button); + $button.click(function() { + var $modal = one.f.flows.modal.dialog.initialize(id, node); + $modal.modal(); + }); + // edit button + var editButton = one.lib.dashlet.button.single("Edit Flow", one.f.flows.id.dashlet.edit, "btn-primary", "btn-mini"); + var $editButton = one.lib.dashlet.button.button(editButton); + $editButton.click(function() { + var install = flow['flow']['installInHw']; + var $modal = one.f.flows.modal.initialize(true,install); + $modal.modal().on('shown',function(){ + var $port = $('#'+one.f.flows.id.modal.form.port); + $('#'+one.f.flows.id.modal.form.nodes).trigger("change"); + }); + }); + // toggle button + var toggle; + if (flow['flow']['installInHw'] == 'true' && flow['flow']['status'] == 'Success') { + toggle = one.lib.dashlet.button.single("Uninstall Flow", one.f.flows.id.dashlet.toggle, "btn-warning", "btn-mini"); + } else { + toggle = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.dashlet.toggle, "btn-success", "btn-mini"); + } + var $toggle = one.lib.dashlet.button.button(toggle); + $toggle.click(function() { + one.f.flows.modal.ajax.toggleflow(id, node, function(data) { + if(data == "Success") { + one.main.dashlet.right.bottom.empty(); + one.f.detail.dashlet(one.main.dashlet.right.bottom); + one.main.dashlet.left.top.empty(); + one.f.flows.dashlet(one.main.dashlet.left.top, function() { + // checks are backwards due to stale registry + if(flow['flow']['installInHw'] == 'true') { + one.lib.alert('Uninstalled Flow'); + } else { + one.lib.alert('Installed Flow'); + } + one.f.flows.detail(id, node) + }); + } else { + one.lib.alert('Cannot toggle flow: '+data); + } + }); + }); + + $detailDashlet.append($button).append($editButton).append($toggle); + } + // append details + var body = one.f.detail.data.dashlet(flow); + var $body = one.f.detail.body.dashlet(body); + $detailDashlet.append($body); + var body = one.f.detail.data.description(flow); + var $body = one.f.detail.body.description(body); + $detailDashlet.append($body); + var body = one.f.detail.data.actions(flow); + var $body = one.f.detail.body.actions(body); + $detailDashlet.append($body); + }, + modal : { + dialog : { + initialize : function(id, node) { + var h3 = "Remove Flow"; + var $p = one.f.flows.modal.dialog.body(id); + var footer = one.f.flows.modal.dialog.footer(); + var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $p, footer); + $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() { + $modal.modal('hide'); + }); + $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(function() { + one.f.flows.modal.ajax.removeflow(id, node, function(data) { + if (data == "Success") { + $modal.modal('hide'); + one.main.dashlet.right.bottom.empty(); + one.f.detail.dashlet(one.main.dashlet.right.bottom); + one.main.dashlet.left.top.empty(); + one.f.flows.dashlet(one.main.dashlet.left.top); + one.lib.alert('Flow removed'); + } else { + one.lib.alert('Cannot remove flow: '+data); + } + }); + }); + return $modal; + }, + footer : function() { + var footer = []; + + var removeButton = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.modal.dialog.remove, "btn-danger", ""); + var $removeButton = one.lib.dashlet.button.button(removeButton); + footer.push($removeButton); + + var closeButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.dialog.close, "", ""); + var $closeButton = one.lib.dashlet.button.button(closeButton); + footer.push($closeButton); + + return footer; + }, + body : function(id) { + var $p = $(document.createElement('p')); + $p.append('Remove flow '+id+'?'); + return $p; + } + }, + initialize : function(edit,install) { + var h3; + if(edit) { + h3 = "Edit Flow Entry"; + var footer = one.f.flows.modal.footerEdit(); + + } else { + h3 = "Add Flow Entry"; + var footer = one.f.flows.modal.footer(); + } + + var $modal = one.lib.modal.spawn(one.f.flows.id.modal.modal, h3, "", footer); + + // bind close button + $('#'+one.f.flows.id.modal.close, $modal).click(function() { + $modal.modal('hide'); + }); + + if (edit) { + // bind edit flow button + $('#'+one.f.flows.id.modal.edit, $modal).click(function() { + one.f.flows.modal.save($modal, install, true); + }); + } else { + // bind add flow button + $('#'+one.f.flows.id.modal.add, $modal).click(function() { + one.f.flows.modal.save($modal, 'false'); + }); - var $gridHTML = one.lib.dashlet.datagrid.init(one.f.flows.id.dashlet.datagrid, { - searchable: true, - filterable: false, - pagination: true, - flexibleRowsPerPage: true - }, "table-striped table-condensed"); - $dashlet.append($gridHTML); - var dataSource = one.f.flows.data.flowsDataGrid(data); - $("#" + one.f.flows.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() { - $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).click(function() { - $("#" + one.f.flows.id.dashlet.datagrid).find(':checkbox').prop('checked', - $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).is(':checked')); - }); - - $("#" + one.f.flows.id.dashlet.datagrid).find("tbody tr").each(function(index, tr) { - $tr = $(tr); - $span = $("td span", $tr); - var flowstatus = $span.data("flowstatus"); - if($span.data("installinhw") != null) { - var installInHw = $span.data("installinhw").toString(); - if(installInHw == "true" && flowstatus == "Success") { - $tr.addClass("success"); - } else { - $tr.addClass("warning"); - } - } - // attach mouseover to show pointer cursor - $tr.mouseover(function() { - $(this).css("cursor", "pointer"); - }); - // attach click event - $tr.click(function() { - var $td = $($(this).find("td")[1]); - var id = $td.text(); - var node = $td.find("span").data("nodeid"); - one.f.flows.detail(id, node); - }); - $(".flowEntry").click(function(e){ - if (!$('.flowEntry[type=checkbox]:not(:checked)').length) { - $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows) - .prop("checked", - true); - } else { - $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows) - .prop("checked", - false); - } - e.stopPropagation(); - }); - }); + // bind install flow button + $('#'+one.f.flows.id.modal.install, $modal).click(function() { + one.f.flows.modal.save($modal, 'true'); + }); + } + + var nodes = one.f.flows.registry.nodes; + var nodeports = one.f.flows.registry.nodeports; + var $body = one.f.flows.modal.body(nodes, nodeports, edit); + one.lib.modal.inject.body($modal, $body,edit); + + return $modal; + }, + save : function($modal, install, edit) { + var result = {}; + + result['name'] = $('#'+one.f.flows.id.modal.form.name, $modal).val(); + result['ingressPort'] = $('#'+one.f.flows.id.modal.form.port, $modal).val(); + result['priority'] = $('#'+one.f.flows.id.modal.form.priority, $modal).val(); + result['hardTimeout'] = $('#'+one.f.flows.id.modal.form.hardTimeout, $modal).val(); + result['idleTimeout'] = $('#'+one.f.flows.id.modal.form.idleTimeout, $modal).val(); + result['cookie'] = $('#'+one.f.flows.id.modal.form.cookie, $modal).val(); + result['etherType'] = $('#'+one.f.flows.id.modal.form.etherType, $modal).val(); + result['vlanId'] = $('#'+one.f.flows.id.modal.form.vlanId, $modal).val(); + result['vlanPriority'] = $('#'+one.f.flows.id.modal.form.vlanPriority, $modal).val(); + result['dlSrc'] = $('#'+one.f.flows.id.modal.form.srcMac, $modal).val(); + result['dlDst'] = $('#'+one.f.flows.id.modal.form.dstMac, $modal).val(); + result['nwSrc'] = $('#'+one.f.flows.id.modal.form.srcIp, $modal).val(); + result['nwDst'] = $('#'+one.f.flows.id.modal.form.dstIp, $modal).val(); + result['tosBits'] = $('#'+one.f.flows.id.modal.form.tosBits, $modal).val(); + result['tpSrc'] = $('#'+one.f.flows.id.modal.form.srcPort, $modal).val(); + result['tpDst'] = $('#'+one.f.flows.id.modal.form.dstPort, $modal).val(); + result['protocol'] = $('#'+one.f.flows.id.modal.form.protocol, $modal).val(); + result['installInHw'] = install; + + var nodeId = $('#'+one.f.flows.id.modal.form.nodes, $modal).val(); + + $.each(result, function(key, value) { + if (value == "") delete result[key]; + }); + + var action = []; + var $table = $('#'+one.f.flows.id.modal.action.table, $modal); + $($table.find('tbody').find('tr')).each(function(index, value) { + if (!$(this).find('td').hasClass('empty')) { + action.push($(value).data('action')); + } + }); + result['actions'] = action; + + // frontend validation + if (result['name'] == undefined) { + alert('Need flow name'); + return; + } + if (nodeId == '') { + alert('Select node'); + return; + } + if (action.length == 0) { + alert('Please specify an action'); + return; + } + + // package for ajax call + var resource = {}; + resource['body'] = JSON.stringify(result); + if(edit){ + resource['action'] = 'edit'; + } else { + resource['action'] = 'add'; + } + + resource['nodeId'] = nodeId; + + if (edit) { + one.f.flows.modal.ajax.saveflow(resource, function(data) { + if (data == "Success") { + $modal.modal('hide').on('hidden', function () { + one.f.flows.detail(result['name'], nodeId); }); - - // details callback - if(callback != undefined) callback(); + one.lib.alert('Flow Entry edited'); + one.main.dashlet.left.top.empty(); + one.f.flows.dashlet(one.main.dashlet.left.top); + } else { + alert('Could not edit flow: '+data); + } + }); + } else { + one.f.flows.modal.ajax.saveflow(resource, function(data) { + if (data == "Success") { + $modal.modal('hide'); + one.lib.alert('Flow Entry added'); + one.main.dashlet.left.top.empty(); + one.f.flows.dashlet(one.main.dashlet.left.top); + } else { + alert('Could not add flow: '+data); + } + }); + } + }, + ajax : { + nodes : function(successCallback) { + $.getJSON(one.f.address.root+one.f.address.flows.nodes, function(data) { + var nodes = one.f.flows.modal.data.nodes(data); + var nodeports = data; + one.f.flows.registry['nodes'] = nodes; + one.f.flows.registry['nodeports'] = nodeports; + + successCallback(nodes, nodeports); + }); + }, + saveflow : function(resource, callback) { + $.post(one.f.address.root+one.f.address.flows.flow, resource, function(data) { + callback(data); + }); + }, + removeflow : function(id, node, callback) { + resource = {}; + resource['action'] = 'remove'; + $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) { + callback(data); + }); + }, + toggleflow : function(id, node, callback) { + resource = {}; + resource['action'] = 'toggle'; + $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) { + callback(data); }); + } }, - detail : function(id, node) { - // clear flow details - var $detailDashlet = one.main.dashlet.right.bottom; - $detailDashlet.empty(); - var $h4 = one.lib.dashlet.header("Flow Overview"); - $detailDashlet.append($h4); - - // details + data : { + nodes : function(data) { + result = {}; + $.each(data, function(key, value) { + result[key] = value['name']; + }); + return result; + } + }, + body : function(nodes, nodeports, edit) { + var $form = $(document.createElement('form')); + var $fieldset = $(document.createElement('fieldset')); + var existingFlow; + // flow description + var $legend = one.lib.form.legend(""); + $legend.css('visibility', 'hidden'); + $fieldset.append($legend); + // name + var $label = one.lib.form.label("Name"); + var $input = one.lib.form.input("Flow Name"); + $input.attr('id', one.f.flows.id.modal.form.name); + if(edit) { + $input.attr('disabled', 'disabled'); var flows = one.f.flows.registry.flows; - var flow; $(flows).each(function(index, value) { - if (value.name == id && value.nodeId == node) { - flow = value; + if (value.name == one.f.flows.registry.selectedId && value.nodeId == one.f.flows.registry.selectedNode) { + existingFlow = value.flow; } }); - if (one.f.flows.registry.privilege === 'WRITE') { - // remove button - var button = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.dashlet.remove, "btn-danger", "btn-mini"); - var $button = one.lib.dashlet.button.button(button); - $button.click(function() { - var $modal = one.f.flows.modal.dialog.initialize(id, node); - $modal.modal(); - }); - // toggle button - var toggle; - if (flow['flow']['installInHw'] == 'true' && flow['flow']['status'] == 'Success') { - toggle = one.lib.dashlet.button.single("Uninstall Flow", one.f.flows.id.dashlet.toggle, "btn-warning", "btn-mini"); + $input.val(existingFlow.name); + } + + $fieldset.append($label).append($input); + // node + var $label = one.lib.form.label("Node"); + var $select = one.lib.form.select.create(nodes); + one.lib.form.select.prepend($select, { '' : 'Please Select a Node' }); + $select.val($select.find("option:first").val()); + $select.attr('id', one.f.flows.id.modal.form.nodes); + if(edit) { + $select.attr('disabled', 'disabled'); + $select.val(existingFlow.node.type + "|"+ existingFlow.node.nodeIDString); + } + + // bind onchange + $select.change(function() { + // retrieve port value + var node = $(this).find('option:selected').attr('value'); + var $ports = $('#'+one.f.flows.id.modal.form.port); + if (node == '') { + one.lib.form.select.inject($ports, {}); + return; + } + one.f.flows.registry['currentNode'] = node; + var ports = nodeports[node]['ports']; + one.lib.form.select.inject($ports, ports); + one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' }); + $ports.val($ports.find("option:first").val()); + if(edit) { + $ports.val( existingFlow.ingressPort ); + } + $.getJSON(one.f.address.root+'/valid-flows/'+node, function(response) { + var $select = $('#'+one.f.flows.id.modal.form.action, $fieldset); + one.lib.form.select.inject($select, response); + one.lib.form.select.prepend($select, {'' : 'Please Select an Action'}); + // when selecting an action + $select.change(function() { + var action = $(this).find('option:selected'); + one.f.flows.modal.action.parse(action.attr('value')); + $select[0].selectedIndex = 0; + }); + }); + }); + + $fieldset.append($label).append($select); + // input port + var $label = one.lib.form.label("Input Port"); + var $select = one.lib.form.select.create(); + + $select.attr('id', one.f.flows.id.modal.form.port); + $fieldset.append($label).append($select); + // priority + var $label = one.lib.form.label("Priority"); + var $input = one.lib.form.input("Priority"); + $input.attr('id', one.f.flows.id.modal.form.priority); + $input.val('500'); + $fieldset.append($label).append($input); + if(edit) { + $input.val(existingFlow.priority); + } + // hardTimeout + var $label = one.lib.form.label("Hard Timeout"); + var $input = one.lib.form.input("Hard Timeout"); + $input.attr('id', one.f.flows.id.modal.form.hardTimeout); + if(edit) { + $input.val(existingFlow.hardTimeout); + } + $fieldset.append($label).append($input); + + // idleTimeout + var $label = one.lib.form.label("Idle Timeout"); + var $input = one.lib.form.input("Idle Timeout"); + $input.attr('id', one.f.flows.id.modal.form.idleTimeout); + $fieldset.append($label).append($input); + if(edit) { + $input.val(existingFlow.idleTimeout); + } + // cookie + var $label = one.lib.form.label("Cookie"); + var $input = one.lib.form.input("Cookie"); + $input.attr('id', one.f.flows.id.modal.form.cookie); + $fieldset.append($label).append($input); + if(edit) { + $input.val(existingFlow.cookie); + } + + // layer 2 + var $legend = one.lib.form.legend("Layer 2"); + $fieldset.append($legend); + // etherType + var $label = one.lib.form.label("Ethernet Type"); + var $input = one.lib.form.input("Ethernet Type"); + $input.attr('id', one.f.flows.id.modal.form.etherType); + $input.val('0x800'); + $fieldset.append($label).append($input); + if(edit) { + $input.val(existingFlow.etherType); + } + // vlanId + var $label = one.lib.form.label("VLAN Identification Number"); + var $input = one.lib.form.input("VLAN Identification Number"); + $input.attr('id', one.f.flows.id.modal.form.vlanId); + var $help = one.lib.form.help("Range: 0 - 4095"); + $fieldset.append($label).append($input).append($help); + if(edit) { + $input.val(existingFlow.vlanId); + } + + // vlanPriority + var $label = one.lib.form.label("VLAN Priority"); + var $input = one.lib.form.input("VLAN Priority"); + $input.attr('id', one.f.flows.id.modal.form.vlanPriority); + var $help = one.lib.form.help("Range: 0 - 7"); + $fieldset.append($label).append($input).append($help); + if(edit) { + $input.val(existingFlow.vlanPriority); + } + + // srcMac + var $label = one.lib.form.label("Source MAC Address"); + var $input = one.lib.form.input("3c:97:0e:75:c3:f7"); + $input.attr('id', one.f.flows.id.modal.form.srcMac); + $fieldset.append($label).append($input); + if(edit) { + $input.val(existingFlow.srcMac); + } + // dstMac + var $label = one.lib.form.label("Destination MAC Address"); + var $input = one.lib.form.input("7c:d1:c3:e8:e6:99"); + $input.attr('id', one.f.flows.id.modal.form.dstMac); + $fieldset.append($label).append($input); + if(edit) { + $input.val(existingFlow.dstMac); + } + // layer 3 + var $legend = one.lib.form.legend("Layer 3"); + $fieldset.append($legend); + + // srcIp + var $label = one.lib.form.label("Source IP Address"); + var $input = one.lib.form.input("192.168.3.128"); + $input.attr('id', one.f.flows.id.modal.form.srcIp); + $fieldset.append($label).append($input); + if(edit) { + $input.val(existingFlow.srcIp); + } + // dstIp + var $label = one.lib.form.label("Destination IP Address"); + var $input = one.lib.form.input("2001:2334::0/32"); + $input.attr('id', one.f.flows.id.modal.form.dstIp); + $fieldset.append($label).append($input); + if(edit) { + $input.val(existingFlow.dstIp); + } + // tosBits + var $label = one.lib.form.label("ToS Bits"); + var $input = one.lib.form.input("ToS Bits"); + $input.attr('id', one.f.flows.id.modal.form.tosBits); + var $help = one.lib.form.help("Range: 0 - 63"); + $fieldset.append($label).append($input).append($help); + if(edit) { + $input.val(existingFlow.tosBits); + } + + // layer 4 + var $legend = one.lib.form.legend("Layer 4"); + $fieldset.append($legend); + // srcPort + var $label = one.lib.form.label("Source Port"); + var $input = one.lib.form.input("Source Port"); + $input.attr('id', one.f.flows.id.modal.form.srcPort); + var $help = one.lib.form.help("Range: 0 - 65535"); + $fieldset.append($label).append($input).append($help); + if(edit) { + $input.val(existingFlow.srcPort); + } + // dstPort + var $label = one.lib.form.label("Destination Port"); + var $input = one.lib.form.input("Destination Port"); + $input.attr('id', one.f.flows.id.modal.form.dstPort); + var $help = one.lib.form.help("Range: 0 - 65535"); + $fieldset.append($label).append($input).append($help); + if(edit) { + $input.val(existingFlow.dstPort); + } + // protocol + var $label = one.lib.form.label("Protocol"); + var $input = one.lib.form.input("Protocol"); + $input.attr('id', one.f.flows.id.modal.form.protocol); + $fieldset.append($label).append($input); + if(edit) { + $input.val(existingFlow.protocol); + } + // actions + var $legend = one.lib.form.label("Actions"); + $fieldset.append($legend); + // actions table + var tableAttributes = ["table-striped", "table-bordered", "table-condensed", "table-hover", "table-cursor"]; + var $table = one.lib.dashlet.table.table(tableAttributes); + $table.attr('id', one.f.flows.id.modal.action.table); + var tableHeaders = ["Action", "Data"]; + var $thead = one.lib.dashlet.table.header(tableHeaders); + var $tbody = one.lib.dashlet.table.body("", tableHeaders); + $table.append($thead).append($tbody); + // actions + var actions = { + "" : "Please Select an Action", + "DROP" : "Drop", + "LOOPBACK" : "Loopback", + "FLOOD" : "Flood", + "FLOOD_ALL" : "Flood All", + "CONTROLLER" : "Controller", + "SW_PATH" : "Software Path", + "HW_PATH" : "Hardware Path", + "OUTPUT" : "Add Output Ports", + "ENQUEUE" : "Enqueue", + "SET_VLAN_ID" : "Set VLAN ID", + "SET_VLAN_PCP" : "Set VLAN Priority", + "SET_VLAN_CFI" : "Set VLAN CFI", + "POP_VLAN" : "Strip VLAN Header", + "PUSH_VLAN" : "Push VLAN", + "SET_DL_SRC" : "Modify Datalayer Source Address", + "SET_DL_DST" : "Modify Datalayer Destination Address", + "SET_DL_TYPE" : "Set Ethertype", + "SET_NW_SRC" : "Modify Network Source Address", + "SET_NW_DST" :"Modify Network Destination Address", + "SET_NW_TOS" : "Modify ToS Bits", + "SET_TP_SRC" : "Modify Transport Source Port", + "SET_TP_DST" : "Modify Transport Destination Port" + }; + var $select = one.lib.form.select.create(actions); + $select.attr('id', one.f.flows.id.modal.form.action); + // when selecting an action + $select.change(function() { + var action = $(this).find('option:selected'); + one.f.flows.modal.action.parse(action.attr('value')); + $select[0].selectedIndex = 0; + }); + + if(edit) { + $(existingFlow.actions).each(function(index, value){ + setTimeout(function(){ + var locEqualTo = value.indexOf("="); + if ( locEqualTo == -1 ) { + one.f.flows.modal.action.add.add(actions[value], value); } else { - toggle = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.dashlet.toggle, "btn-success", "btn-mini"); + var action = value.substr(0,locEqualTo); + if( action == "OUTPUT") { + var portIds = value.substr(locEqualTo+1).split(","); + var ports = []; + var allPorts = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports']; + for(var i =0; i < portIds.length ; i++) { + var portName = allPorts[portIds[i]]; + ports.push(portName); + } + one.f.flows.modal.action.add.addPortsToTable(ports.join(", "), portIds.join(",")); + } else { + var val = value.substr(locEqualTo+1); + one.f.flows.modal.action.add.addDataToTable(actions[action], val, action) + } } - var $toggle = one.lib.dashlet.button.button(toggle); - $toggle.click(function() { - one.f.flows.modal.ajax.toggleflow(id, node, function(data) { - if(data == "Success") { - one.main.dashlet.right.bottom.empty(); - one.f.detail.dashlet(one.main.dashlet.right.bottom); - one.main.dashlet.left.top.empty(); - one.f.flows.dashlet(one.main.dashlet.left.top, function() { - // checks are backwards due to stale registry - if(flow['flow']['installInHw'] == 'true') { - one.lib.alert('Uninstalled Flow'); - } else { - one.lib.alert('Installed Flow'); - } - one.f.flows.detail(id, node) - }); - } else { - one.lib.alert('Cannot toggle flow: '+data); - } - }); - }); + }, 1000) + }); + } + $fieldset.append($select).append($table); - $detailDashlet.append($button).append($toggle); - } - // append details - var body = one.f.detail.data.dashlet(flow); - var $body = one.f.detail.body.dashlet(body); - $detailDashlet.append($body); - var body = one.f.detail.data.description(flow); - var $body = one.f.detail.body.description(body); - $detailDashlet.append($body); - var body = one.f.detail.data.actions(flow); - var $body = one.f.detail.body.actions(body); - $detailDashlet.append($body); + // return + $form.append($fieldset); + return $form; }, - modal : { - dialog : { - initialize : function(id, node) { - var h3 = "Remove Flow"; - var $p = one.f.flows.modal.dialog.body(id); - var footer = one.f.flows.modal.dialog.footer(); - var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $p, footer); - $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() { - $modal.modal('hide'); - }); - $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(function() { - one.f.flows.modal.ajax.removeflow(id, node, function(data) { - if (data == "Success") { - $modal.modal('hide'); - one.main.dashlet.right.bottom.empty(); - one.f.detail.dashlet(one.main.dashlet.right.bottom); - one.main.dashlet.left.top.empty(); - one.f.flows.dashlet(one.main.dashlet.left.top); - one.lib.alert('Flow removed'); - } else { - one.lib.alert('Cannot remove flow: '+data); - } - }); - }); - return $modal; - }, - footer : function() { - var footer = []; - - var removeButton = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.modal.dialog.remove, "btn-danger", ""); - var $removeButton = one.lib.dashlet.button.button(removeButton); - footer.push($removeButton); - - var closeButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.dialog.close, "", ""); - var $closeButton = one.lib.dashlet.button.button(closeButton); - footer.push($closeButton); - - return footer; - }, - body : function(id) { - var $p = $(document.createElement('p')); - $p.append('Remove flow '+id+'?'); - return $p; - } + action : { + parse : function(option) { + switch (option) { + case "OUTPUT" : + var h3 = "Add Output Port"; + var $modal = one.f.flows.modal.action.initialize(h3, one.f.flows.modal.action.body.addOutputPorts, one.f.flows.modal.action.add.addOutputPorts); + $modal.modal(); + break; + case "SET_VLAN_ID" : + var h3 = "Set VLAN ID"; + var placeholder = "VLAN Identification Number"; + var id = one.f.flows.id.modal.action.setVlanId; + var help = "Range: 0 - 4095"; + var action = 'SET_VLAN_ID'; + var name = "VLAN ID"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "SET_VLAN_PCP" : + var h3 = "Set VLAN Priority"; + var placeholder = "VLAN Priority"; + var id = one.f.flows.id.modal.action.setVlanPriority; + var help = "Range: 0 - 7"; + var action = 'SET_VLAN_PCP'; + var name = "VLAN Priority"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "SET_VLAN_CFI" : + var h3 = "Set VLAN CFI"; + var placeholder = "VLAN CFI"; + var id = one.f.flows.id.modal.action.setVlanCfi; + var help = "Range: 0 - 1"; + var action = 'SET_VLAN_CFI'; + var name = "VLAN CFI"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "POP_VLAN" : + var name = "Strip VLAN Header"; + var action = 'POP_VLAN'; + one.f.flows.modal.action.add.add(name, action); + break; + case "PUSH_VLAN" : + var h3 = "Push VLAN"; + var placeholder = "VLAN"; + var id = one.f.flows.id.modal.action.pushVlan; + var help = "Range: 0 - 4095"; + var action = 'PUSH_VLAN'; + var name = "VLAN"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "SET_DL_SRC" : + var h3 = "Set Source MAC Address"; + var placeholder = "Source MAC Address"; + var id = one.f.flows.id.modal.action.modifyDatalayerSourceAddress; + var help = "Example: 00:11:22:aa:bb:cc"; + var action = 'SET_DL_SRC'; + var name = "Source MAC"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "SET_DL_DST" : + var h3 = "Set Destination MAC Address"; + var placeholder = "Destination MAC Address"; + var id = one.f.flows.id.modal.action.modifyDatalayerDestinationAddress; + var help = "Example: 00:11:22:aa:bb:cc"; + var action = 'SET_DL_DST'; + var name = "Destination MAC"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "SET_DL_TYPE" : + var h3 = "Set Ethertype"; + var placeholder = "Ethertype"; + var id = one.f.flows.id.modal.action.setEthertype; + var help = "Range: 0 - 65535"; + var action = 'SET_DL_TYPE'; + var name = "Ethertype"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "SET_NW_SRC" : + var h3 = "Set IP Source Address"; + var placeholder = "Source IP Address"; + var id = one.f.flows.id.modal.action.modifyNetworkSourceAddress; + var help = "Example: 127.0.0.1"; + var action = 'SET_NW_SRC'; + var name = "Source IP"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "SET_NW_DST" : + var h3 = "Set IP Destination Address"; + var placeholder = "Destination IP Address"; + var id = one.f.flows.id.modal.action.modifyNetworkDestinationAddress; + var help = "Example: 127.0.0.1"; + var action = 'SET_NW_DST'; + var name = "Destination IP"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "SET_NW_TOS" : + var h3 = "Set IPv4 ToS"; + var placeholder = "IPv4 ToS"; + var id = one.f.flows.id.modal.action.modifyTosBits; + var help = "Range: 0 - 63"; + var action = 'SET_NW_TOS'; + var name = "ToS Bits"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "SET_TP_SRC" : + var h3 = "Set Transport Source Port"; + var placeholder = "Transport Source Port"; + var id = one.f.flows.id.modal.action.modifyTransportSourcePort; + var help = "Range: 1 - 65535"; + var action = 'SET_TP_SRC'; + var name = "Source Port"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "SET_TP_DST" : + var h3 = "Set Transport Destination Port"; + var placeholder = "Transport Destination Port"; + var id = one.f.flows.id.modal.action.modifyTransportDestinationPort; + var help = "Range: 1 - 65535"; + var action = 'SET_TP_DST'; + var name = "Destination Port"; + var body = function() { + return one.f.flows.modal.action.body.set(h3, placeholder, id, help); + }; + var add = function($modal) { + one.f.flows.modal.action.add.set(name, id, action, $modal); + }; + var $modal = one.f.flows.modal.action.initialize(h3, body, add); + $modal.modal(); + break; + case "ENQUEUE" : + var h3 = "Enqueue"; + var placeholder = "Enqueue"; + var id = one.f.flows.id.modal.action.enqueue; + var $modal = one.f.flows.modal.action.initialize(h3, one.f.flows.modal.action.body.addEnqueue, one.f.flows.modal.action.add.addEnqueue); + $modal.modal(); + break; + case "DROP" : + var name = "Drop"; + var action = 'DROP'; + one.f.flows.modal.action.add.add(name, action); + break; + case "LOOPBACK" : + var name = "Loopback"; + var action = 'LOOPBACK'; + one.f.flows.modal.action.add.add(name, action); + break; + case "FLOOD" : + var name = "Flood"; + var action = 'FLOOD'; + one.f.flows.modal.action.add.add(name, action); + break; + case "FLOOD_ALL" : + var name = "Flood All"; + var action = 'FLOOD_ALL'; + one.f.flows.modal.action.add.add(name, action); + break; + case "SW_PATH" : + var name = "Software Path"; + var action = 'SW_PATH'; + one.f.flows.modal.action.add.add(name, action); + break; + case "HW_PATH" : + var name = "Hardware Path"; + var action = 'HW_PATH'; + one.f.flows.modal.action.add.add(name, action); + break; + case "CONTROLLER" : + var name = "Controller"; + var action = 'CONTROLLER'; + one.f.flows.modal.action.add.add(name, action); + break; + } + }, + initialize : function(h3, bodyCallback, addCallback) { + var footer = one.f.flows.modal.action.footer(); + var $body = bodyCallback(); + var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal, h3, $body, footer); + // bind close button + $('#'+one.f.flows.id.modal.action.close, $modal).click(function() { + $modal.modal('hide'); + }); + // bind add flow button + $('#'+one.f.flows.id.modal.action.add, $modal).click(function() { + addCallback($modal); + }); + return $modal; + }, + add : { + addOutputPorts : function($modal) { + var $options = $('#'+one.f.flows.id.modal.action.addOutputPorts).find('option:selected'); + var ports = ''; + var pid = ''; + $options.each(function(index, value) { + ports = ports+$(value).text()+", "; + pid = pid+$(value).attr('value')+","; + }); + ports = ports.slice(0,-2); + pid = pid.slice(0,-1); + one.f.flows.modal.action.add.addPortsToTable(ports, pid); + $modal.modal('hide'); }, - initialize : function() { - var h3 = "Add Flow Entry"; - var footer = one.f.flows.modal.footer(); - var $modal = one.lib.modal.spawn(one.f.flows.id.modal.modal, h3, "", footer); - - // bind close button - $('#'+one.f.flows.id.modal.close, $modal).click(function() { - $modal.modal('hide'); - }); - - // bind add flow button - $('#'+one.f.flows.id.modal.add, $modal).click(function() { - one.f.flows.modal.add($modal, 'false'); - }); - - // bind install flow button - $('#'+one.f.flows.id.modal.install, $modal).click(function() { - one.f.flows.modal.add($modal, 'true'); + addEnqueue : function($modal) { + var $options = $('#'+one.f.flows.id.modal.action.addOutputPorts).find('option:selected'); + var ports = ''; + var pid = ''; + $options.each(function(index, value) { + ports = ports+$(value).text()+", "; + pid = pid+$(value).attr('value')+","; + }); + var $input = $('#'+one.f.flows.id.modal.action.queue); + var queue = $input.val(); + ports = ports.slice(0,-2); + pid = pid.slice(0,-1); + one.f.flows.modal.action.add.addEnqueueToTable(ports, pid, queue); + $modal.modal('hide'); + }, + addEnqueueToTable : function(ports, pid, queue) { + if (queue !== '' && queue >= 0) { + ports += ':'+queue; + } + var $tr = one.f.flows.modal.action.table.add("Enqueue", ports); + $tr.attr('id', 'ENQUEUE'); + if (queue !== '' && queue >= 0) { + $tr.data('action', 'ENQUEUE='+pid+':'+queue); + } else { + $tr.data('action', 'ENQUEUE='+pid+':0'); // default queue to 0 + } + $tr.click(function() { + one.f.flows.modal.action.add.modal.initialize(this); + }); + one.f.flows.modal.action.table.append($tr); + }, + addPortsToTable : function(ports, pid){ + var $tr = one.f.flows.modal.action.table.add("Add Output Ports", ports); + $tr.attr('id', 'OUTPUT'); + $tr.data('action', 'OUTPUT='+pid); + $tr.click(function() { + one.f.flows.modal.action.add.modal.initialize(this); + }); + one.f.flows.modal.action.table.append($tr); + }, + add : function(name, action) { + var $tr = one.f.flows.modal.action.table.add(name); + $tr.attr('id', action); + $tr.data('action', action); + $tr.click(function() { + one.f.flows.modal.action.add.modal.initialize(this); + }); + one.f.flows.modal.action.table.append($tr); + }, + set : function(name, id, action, $modal) { + var $input = $('#'+id); + var value = $input.val(); + one.f.flows.modal.action.add.addDataToTable(name,value,action) + $modal.modal('hide'); + }, + addDataToTable : function(name,value,action) { + var $tr = one.f.flows.modal.action.table.add(name, value); + $tr.attr('id', action); + $tr.data('action', action+'='+value); + $tr.click(function() { + one.f.flows.modal.action.add.modal.initialize(this); + }); + one.f.flows.modal.action.table.append($tr); + }, + remove : function(that) { + $(that).remove(); + var $table = $('#'+one.f.flows.id.modal.action.table); + if ($table.find('tbody').find('tr').size() == 0) { + var $tr = $(document.createElement('tr')); + var $td = $(document.createElement('td')); + $td.attr('colspan', '3'); + $tr.addClass('empty'); + $td.text('No data available'); + $tr.append($td); + $table.find('tbody').append($tr); + } + }, + modal : { + initialize : function(that) { + var h3 = "Remove Action"; + var footer = one.f.flows.modal.action.add.modal.footer(); + var $body = one.f.flows.modal.action.add.modal.body(); + var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal.modal, h3, $body, footer); + + // bind cancel button + $('#'+one.f.flows.id.modal.action.modal.cancel, $modal).click(function() { + $modal.modal('hide'); }); - // inject body (nodePorts) - one.f.flows.modal.ajax.nodes(function(nodes, nodeports) { - var $body = one.f.flows.modal.body(nodes, nodeports); - one.lib.modal.inject.body($modal, $body); + // bind remove button + $('#'+one.f.flows.id.modal.action.modal.remove, $modal).click(function() { + one.f.flows.modal.action.add.remove(that); + $modal.modal('hide'); }); - return $modal; - }, - add : function($modal, install) { - var result = {}; - - result['name'] = $('#'+one.f.flows.id.modal.form.name, $modal).val(); - result['ingressPort'] = $('#'+one.f.flows.id.modal.form.port, $modal).val(); - result['priority'] = $('#'+one.f.flows.id.modal.form.priority, $modal).val(); - result['hardTimeout'] = $('#'+one.f.flows.id.modal.form.hardTimeout, $modal).val(); - result['idleTimeout'] = $('#'+one.f.flows.id.modal.form.idleTimeout, $modal).val(); - result['cookie'] = $('#'+one.f.flows.id.modal.form.cookie, $modal).val(); - result['etherType'] = $('#'+one.f.flows.id.modal.form.etherType, $modal).val(); - result['vlanId'] = $('#'+one.f.flows.id.modal.form.vlanId, $modal).val(); - result['vlanPriority'] = $('#'+one.f.flows.id.modal.form.vlanPriority, $modal).val(); - result['dlSrc'] = $('#'+one.f.flows.id.modal.form.srcMac, $modal).val(); - result['dlDst'] = $('#'+one.f.flows.id.modal.form.dstMac, $modal).val(); - result['nwSrc'] = $('#'+one.f.flows.id.modal.form.srcIp, $modal).val(); - result['nwDst'] = $('#'+one.f.flows.id.modal.form.dstIp, $modal).val(); - result['tosBits'] = $('#'+one.f.flows.id.modal.form.tosBits, $modal).val(); - result['tpSrc'] = $('#'+one.f.flows.id.modal.form.srcPort, $modal).val(); - result['tpDst'] = $('#'+one.f.flows.id.modal.form.dstPort, $modal).val(); - result['protocol'] = $('#'+one.f.flows.id.modal.form.protocol, $modal).val(); - - result['installInHw'] = install; - - var nodeId = $('#'+one.f.flows.id.modal.form.nodes, $modal).val(); - - $.each(result, function(key, value) { - if (value == "") delete result[key]; - }); + $modal.modal(); + }, + body : function() { + var $p = $(document.createElement('p')); + $p.append("Remove this action?"); + return $p; + }, + footer : function() { + var footer = []; - var action = []; - var $table = $('#'+one.f.flows.id.modal.action.table, $modal); - $($table.find('tbody').find('tr')).each(function(index, value) { - if (!$(this).find('td').hasClass('empty')) { - action.push($(value).data('action')); - } - }); - result['actions'] = action; + var removeButton = one.lib.dashlet.button.single("Remove Action", one.f.flows.id.modal.action.modal.remove, "btn-danger", ""); + var $removeButton = one.lib.dashlet.button.button(removeButton); + footer.push($removeButton); - // frontend validation - if (result['name'] == undefined) { - alert('Need flow name'); - return; - } - if (nodeId == '') { - alert('Select node'); - return; - } - if (action.length == 0) { - alert('Please specify an action'); - return; - } + var cancelButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.action.modal.cancel, "", ""); + var $cancelButton = one.lib.dashlet.button.button(cancelButton); + footer.push($cancelButton); - // package for ajax call - var resource = {}; - resource['body'] = JSON.stringify(result); - resource['action'] = 'add'; - resource['nodeId'] = nodeId; - - one.f.flows.modal.ajax.saveflow(resource, function(data) { - if (data == "Success") { - $modal.modal('hide'); - one.lib.alert('Flow Entry added'); - one.main.dashlet.left.top.empty(); - one.f.flows.dashlet(one.main.dashlet.left.top); - } else { - alert('Could not add flow: '+data); - } - }); + return footer; + } + } + }, + table : { + add : function(action, data) { + var $tr = $(document.createElement('tr')); + var $td = $(document.createElement('td')); + $td.append(action); + $tr.append($td); + var $td = $(document.createElement('td')); + if (data != undefined) $td.append(data); + $tr.append($td); + return $tr; }, - ajax : { - nodes : function(successCallback) { - $.getJSON(one.f.address.root+one.f.address.flows.nodes, function(data) { - var nodes = one.f.flows.modal.data.nodes(data); - var nodeports = data; - one.f.flows.registry['nodeports'] = nodeports; - - successCallback(nodes, nodeports); - }); - }, - saveflow : function(resource, callback) { - $.post(one.f.address.root+one.f.address.flows.flow, resource, function(data) { - callback(data); - }); - }, - removeflow : function(id, node, callback) { - resource = {}; - resource['action'] = 'remove'; - $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) { - callback(data); - }); - }, - toggleflow : function(id, node, callback) { - resource = {}; - resource['action'] = 'toggle'; - $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) { - callback(data); - }); - } + append : function($tr) { + var $table = $('#'+one.f.flows.id.modal.action.table); + var $empty = $table.find('.empty').parent(); + if ($empty.size() > 0) $empty.remove(); + $table.append($tr); + } + }, + body : { + common : function() { + var $form = $(document.createElement('form')); + var $fieldset = $(document.createElement('fieldset')); + return [$form, $fieldset]; }, - data : { - nodes : function(data) { - result = {}; - $.each(data, function(key, value) { - result[key] = value['name']; - }); - return result; - } + addOutputPorts : function() { + var common = one.f.flows.modal.action.body.common(); + var $form = common[0]; + var $fieldset = common[1]; + // output port + $label = one.lib.form.label("Select Output Ports"); + if (one.f.flows.registry.currentNode == undefined){ + return; //Selecting Output ports without selecting node throws an exception + } + var ports = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports']; + $select = one.lib.form.select.create(ports, true); + $select.attr('id', one.f.flows.id.modal.action.addOutputPorts); + $fieldset.append($label).append($select); + $form.append($fieldset); + return $form; }, - body : function(nodes, nodeports) { - var $form = $(document.createElement('form')); - var $fieldset = $(document.createElement('fieldset')); - // flow description - var $legend = one.lib.form.legend(""); - $legend.css('visibility', 'hidden'); - $fieldset.append($legend); - // name - var $label = one.lib.form.label("Name"); - var $input = one.lib.form.input("Flow Name"); - $input.attr('id', one.f.flows.id.modal.form.name); - $fieldset.append($label).append($input); - // node - var $label = one.lib.form.label("Node"); - var $select = one.lib.form.select.create(nodes); - one.lib.form.select.prepend($select, { '' : 'Please Select a Node' }); - $select.val($select.find("option:first").val()); - $select.attr('id', one.f.flows.id.modal.form.nodes); - - // bind onchange - $select.change(function() { - // retrieve port value - var node = $(this).find('option:selected').attr('value'); - var $ports = $('#'+one.f.flows.id.modal.form.port); - if (node == '') { - one.lib.form.select.inject($ports, {}); - return; - } - one.f.flows.registry['currentNode'] = node; - var ports = nodeports[node]['ports']; - one.lib.form.select.inject($ports, ports); - one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' }); - $ports.val($ports.find("option:first").val()); - }); + addEnqueue : function() { + var common = one.f.flows.modal.action.body.common(); + var $form = common[0]; + var $fieldset = common[1]; + // output port + $label = one.lib.form.label("Select Output Ports"); + if (one.f.flows.registry.currentNode == undefined){ + return; //Selecting Output ports without selecting node throws an exception + } + var ports = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports']; + $select = one.lib.form.select.create(ports); + $select.attr('id', one.f.flows.id.modal.action.addOutputPorts); + $fieldset.append($label).append($select); + $label = one.lib.form.label('Queue (Optional)'); + $input = one.lib.form.input('Queue') + .attr('id', one.f.flows.id.modal.action.queue); + $help = one.lib.form.help('Range: 1 - 2147483647'); + $fieldset.append($label).append($input).append($help); + $form.append($fieldset); + return $form; + }, + set : function(label, placeholder, id, help) { + var common = one.f.flows.modal.action.body.common(); + var $form = common[0]; + var $fieldset = common[1]; + // input + $label = one.lib.form.label(label); + $input = one.lib.form.input(placeholder); + $input.attr('id', id); + $help = one.lib.form.help(help); + // append + $fieldset.append($label).append($input).append($help); + $form.append($fieldset); + return $form; + } + }, + footer : function() { + var footer = []; + var addButton = one.lib.dashlet.button.single("Add Action", one.f.flows.id.modal.action.add, "btn-primary", ""); + var $addButton = one.lib.dashlet.button.button(addButton); + footer.push($addButton); + + var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.action.close, "", ""); + var $closeButton = one.lib.dashlet.button.button(closeButton); + footer.push($closeButton); + + return footer; + } + }, + footer : function() { + var footer = []; - $fieldset.append($label).append($select); - // input port - var $label = one.lib.form.label("Input Port"); - var $select = one.lib.form.select.create(); - $select.attr('id', one.f.flows.id.modal.form.port); - $fieldset.append($label).append($select); - // priority - var $label = one.lib.form.label("Priority"); - var $input = one.lib.form.input("Priority"); - $input.attr('id', one.f.flows.id.modal.form.priority); - $input.val('500'); - $fieldset.append($label).append($input); - // hardTimeout - var $label = one.lib.form.label("Hard Timeout"); - var $input = one.lib.form.input("Hard Timeout"); - $input.attr('id', one.f.flows.id.modal.form.hardTimeout); - $fieldset.append($label).append($input); - // idleTimeout - var $label = one.lib.form.label("Idle Timeout"); - var $input = one.lib.form.input("Idle Timeout"); - $input.attr('id', one.f.flows.id.modal.form.idleTimeout); - $fieldset.append($label).append($input); - // cookie - var $label = one.lib.form.label("Cookie"); - var $input = one.lib.form.input("Cookie"); - $input.attr('id', one.f.flows.id.modal.form.cookie); - $fieldset.append($label).append($input); - // layer 2 - var $legend = one.lib.form.legend("Layer 2"); - $fieldset.append($legend); - // etherType - var $label = one.lib.form.label("Ethernet Type"); - var $input = one.lib.form.input("Ethernet Type"); - $input.attr('id', one.f.flows.id.modal.form.etherType); - $input.val('0x800'); - $fieldset.append($label).append($input); - // vlanId - var $label = one.lib.form.label("VLAN Identification Number"); - var $input = one.lib.form.input("VLAN Identification Number"); - $input.attr('id', one.f.flows.id.modal.form.vlanId); - var $help = one.lib.form.help("Range: 0 - 4095"); - $fieldset.append($label).append($input).append($help); - // vlanPriority - var $label = one.lib.form.label("VLAN Priority"); - var $input = one.lib.form.input("VLAN Priority"); - $input.attr('id', one.f.flows.id.modal.form.vlanPriority); - var $help = one.lib.form.help("Range: 0 - 7"); - $fieldset.append($label).append($input).append($help); - // srcMac - var $label = one.lib.form.label("Source MAC Address"); - var $input = one.lib.form.input("3c:97:0e:75:c3:f7"); - $input.attr('id', one.f.flows.id.modal.form.srcMac); - $fieldset.append($label).append($input); - // dstMac - var $label = one.lib.form.label("Destination MAC Address"); - var $input = one.lib.form.input("7c:d1:c3:e8:e6:99"); - $input.attr('id', one.f.flows.id.modal.form.dstMac); - $fieldset.append($label).append($input); - // layer 3 - var $legend = one.lib.form.legend("Layer 3"); - $fieldset.append($legend); - // srcIp - var $label = one.lib.form.label("Source IP Address"); - var $input = one.lib.form.input("192.168.3.128"); - $input.attr('id', one.f.flows.id.modal.form.srcIp); - $fieldset.append($label).append($input); - // dstIp - var $label = one.lib.form.label("Destination IP Address"); - var $input = one.lib.form.input("2001:2334::0/32"); - $input.attr('id', one.f.flows.id.modal.form.dstIp); - $fieldset.append($label).append($input); - // tosBits - var $label = one.lib.form.label("ToS Bits"); - var $input = one.lib.form.input("ToS Bits"); - $input.attr('id', one.f.flows.id.modal.form.tosBits); - var $help = one.lib.form.help("Range: 0 - 63"); - $fieldset.append($label).append($input).append($help); - // layer 4 - var $legend = one.lib.form.legend("Layer 4"); - $fieldset.append($legend); - // srcPort - var $label = one.lib.form.label("Source Port"); - var $input = one.lib.form.input("Source Port"); - $input.attr('id', one.f.flows.id.modal.form.srcPort); - var $help = one.lib.form.help("Range: 0 - 65535"); - $fieldset.append($label).append($input).append($help); - // dstPort - var $label = one.lib.form.label("Destination Port"); - var $input = one.lib.form.input("Destination Port"); - $input.attr('id', one.f.flows.id.modal.form.dstPort); - var $help = one.lib.form.help("Range: 0 - 65535"); - $fieldset.append($label).append($input).append($help); - // protocol - var $label = one.lib.form.label("Protocol"); - var $input = one.lib.form.input("Protocol"); - $input.attr('id', one.f.flows.id.modal.form.protocol); - $fieldset.append($label).append($input); - // actions - var $legend = one.lib.form.label("Actions"); - $fieldset.append($legend); - // actions table - var tableAttributes = ["table-striped", "table-bordered", "table-condensed", "table-hover", "table-cursor"]; - var $table = one.lib.dashlet.table.table(tableAttributes); - $table.attr('id', one.f.flows.id.modal.action.table); - var tableHeaders = ["Action", "Data", "Type"]; - var $thead = one.lib.dashlet.table.header(tableHeaders); - var $tbody = one.lib.dashlet.table.body("", tableHeaders); - $table.append($thead).append($tbody); - // actions - var actions = { - "" : "Please Select an Action", - "drop" : "Drop", - "loopback" : "Loopback", - "flood" : "Flood", - "softwarePath" : "Software Path", - "hardwarePath" : "Hardware Path", - "controller" : "Controller", - "addOutputPorts" : "Add Output Ports", - "setVlanId" : "Set VLAN ID", - "setVlanPriority" : "Set VLAN Priority", - "stripVlanHeader" : "Strip VLAN Header", - "modifyDatalayerSourceAddress" : "Modify Datalayer Source Address", - "modifyDatalayerDestinationAddress" : "Modify Datalayer Destination Address", - "modifyNetworkSourceAddress" : "Modify Network Source Address", - "modifyNetworkDestinationAddress" :"Modify Network Destination Address", - "modifyTosBits" : "Modify ToS Bits", - "modifyTransportSourcePort" : "Modify Transport Source Port", - "modifyTransportDestinationPort" : "Modify Transport Destination Port" - }; - var $select = one.lib.form.select.create(actions); - // when selecting an action - $select.change(function() { - var action = $(this).find('option:selected'); - one.f.flows.modal.action.parse(action.attr('value')); - $select[0].selectedIndex = 0; - }); + var installButton = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.modal.install, "btn-success", ""); + var $installButton = one.lib.dashlet.button.button(installButton); + footer.push($installButton); - $fieldset.append($select).append($table); + var addButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.add, "btn-primary", ""); + var $addButton = one.lib.dashlet.button.button(addButton); + footer.push($addButton); - // return - $form.append($fieldset); - return $form; - }, - action : { - parse : function(option) { - switch (option) { - case "addOutputPorts" : - var h3 = "Add Output Port"; - var $modal = one.f.flows.modal.action.initialize(h3, one.f.flows.modal.action.body.addOutputPorts, one.f.flows.modal.action.add.addOutputPorts); - $modal.modal(); - break; - case "setVlanId" : - var h3 = "Set VLAN ID"; - var placeholder = "VLAN Identification Number"; - var id = one.f.flows.id.modal.action.setVlanId; - var help = "Range: 0 - 4095"; - var action = 'SET_VLAN_ID'; - var name = "VLAN ID"; - var body = function() { - return one.f.flows.modal.action.body.set(h3, placeholder, id, help); - }; - var add = function($modal) { - one.f.flows.modal.action.add.set(name, id, action, $modal); - }; - var $modal = one.f.flows.modal.action.initialize(h3, body, add); - $modal.modal(); - break; - case "setVlanPriority" : - var h3 = "Set VLAN Priority"; - var placeholder = "VLAN Priority"; - var id = one.f.flows.id.modal.action.setVlanPriority; - var help = "Range: 0 - 7"; - var action = 'SET_VLAN_PCP'; - var name = "VLAN Priority"; - var body = function() { - return one.f.flows.modal.action.body.set(h3, placeholder, id, help); - }; - var add = function($modal) { - one.f.flows.modal.action.add.set(name, id, action, $modal); - }; - var $modal = one.f.flows.modal.action.initialize(h3, body, add); - $modal.modal(); - break; - case "stripVlanHeader" : - var name = "Strip VLAN Header"; - var action = 'POP_VLAN'; - one.f.flows.modal.action.add.add(name, action); - break; - case "modifyDatalayerSourceAddress" : - var h3 = "Set Source MAC Address"; - var placeholder = "Source MAC Address"; - var id = one.f.flows.id.modal.action.modifyDatalayerSourceAddress; - var help = "Example: 00:11:22:aa:bb:cc"; - var action = 'SET_DL_SRC'; - var name = "Source MAC"; - var body = function() { - return one.f.flows.modal.action.body.set(h3, placeholder, id, help); - }; - var add = function($modal) { - one.f.flows.modal.action.add.set(name, id, action, $modal); - }; - var $modal = one.f.flows.modal.action.initialize(h3, body, add); - $modal.modal(); - break; - case "modifyDatalayerDestinationAddress" : - var h3 = "Set Destination MAC Address"; - var placeholder = "Destination MAC Address"; - var id = one.f.flows.id.modal.action.modifyDatalayerDestinationAddress; - var help = "Example: 00:11:22:aa:bb:cc"; - var action = 'SET_DL_DST'; - var name = "Destination MAC"; - var body = function() { - return one.f.flows.modal.action.body.set(h3, placeholder, id, help); - }; - var add = function($modal) { - one.f.flows.modal.action.add.set(name, id, action, $modal); - }; - var $modal = one.f.flows.modal.action.initialize(h3, body, add); - $modal.modal(); - break; - case "modifyNetworkSourceAddress" : - var h3 = "Set IP Source Address"; - var placeholder = "Source IP Address"; - var id = one.f.flows.id.modal.action.modifyNetworkSourceAddress; - var help = "Example: 127.0.0.1"; - var action = 'SET_NW_SRC'; - var name = "Source IP"; - var body = function() { - return one.f.flows.modal.action.body.set(h3, placeholder, id, help); - }; - var add = function($modal) { - one.f.flows.modal.action.add.set(name, id, action, $modal); - }; - var $modal = one.f.flows.modal.action.initialize(h3, body, add); - $modal.modal(); - break; - case "modifyNetworkDestinationAddress" : - var h3 = "Set IP Destination Address"; - var placeholder = "Destination IP Address"; - var id = one.f.flows.id.modal.action.modifyNetworkDestinationAddress; - var help = "Example: 127.0.0.1"; - var action = 'SET_NW_DST'; - var name = "Destination IP"; - var body = function() { - return one.f.flows.modal.action.body.set(h3, placeholder, id, help); - }; - var add = function($modal) { - one.f.flows.modal.action.add.set(name, id, action, $modal); - }; - var $modal = one.f.flows.modal.action.initialize(h3, body, add); - $modal.modal(); - break; - case "modifyTosBits" : - var h3 = "Set IPv4 ToS"; - var placeholder = "IPv4 ToS"; - var id = one.f.flows.id.modal.action.modifyTosBits; - var help = "Range: 0 - 63"; - var action = 'SET_NW_TOS'; - var name = "ToS Bits"; - var body = function() { - return one.f.flows.modal.action.body.set(h3, placeholder, id, help); - }; - var add = function($modal) { - one.f.flows.modal.action.add.set(name, id, action, $modal); - }; - var $modal = one.f.flows.modal.action.initialize(h3, body, add); - $modal.modal(); - break; - case "modifyTransportSourcePort" : - var h3 = "Set Transport Source Port"; - var placeholder = "Transport Source Port"; - var id = one.f.flows.id.modal.action.modifyTransportSourcePort; - var help = "Range: 1 - 65535"; - var action = 'SET_TP_SRC'; - var name = "Source Port"; - var body = function() { - return one.f.flows.modal.action.body.set(h3, placeholder, id, help); - }; - var add = function($modal) { - one.f.flows.modal.action.add.set(name, id, action, $modal); - }; - var $modal = one.f.flows.modal.action.initialize(h3, body, add); - $modal.modal(); - break; - case "modifyTransportDestinationPort" : - var h3 = "Set Transport Destination Port"; - var placeholder = "Transport Destination Port"; - var id = one.f.flows.id.modal.action.modifyTransportDestinationPort; - var help = "Range: 1 - 65535"; - var action = 'SET_TP_DST'; - var name = "Destination Port"; - var body = function() { - return one.f.flows.modal.action.body.set(h3, placeholder, id, help); - }; - var add = function($modal) { - one.f.flows.modal.action.add.set(name, id, action, $modal); - }; - var $modal = one.f.flows.modal.action.initialize(h3, body, add); - $modal.modal(); - break; - case "drop" : - var name = "Drop"; - var action = 'DROP'; - one.f.flows.modal.action.add.add(name, action); - break; - case "loopback" : - var name = "Loopback"; - var action = 'LOOPBACK'; - one.f.flows.modal.action.add.add(name, action); - break; - case "flood" : - var name = "Flood"; - var action = 'FLOOD'; - one.f.flows.modal.action.add.add(name, action); - break; - case "softwarePath" : - var name = "Software Path"; - var action = 'SW_PATH'; - one.f.flows.modal.action.add.add(name, action); - break; - case "hardwarePath" : - var name = "Hardware Path"; - var action = 'HW_PATH'; - one.f.flows.modal.action.add.add(name, action); - break; - case "controller" : - var name = "Controller"; - var action = 'CONTROLLER'; - one.f.flows.modal.action.add.add(name, action); - break; - } - }, - initialize : function(h3, bodyCallback, addCallback) { - var footer = one.f.flows.modal.action.footer(); - var $body = bodyCallback(); - var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal, h3, $body, footer); - // bind close button - $('#'+one.f.flows.id.modal.action.close, $modal).click(function() { - $modal.modal('hide'); - }); - // bind add flow button - $('#'+one.f.flows.id.modal.action.add, $modal).click(function() { - addCallback($modal); - }); - return $modal; - }, - add : { - addOutputPorts : function($modal) { - var $options = $('#'+one.f.flows.id.modal.action.addOutputPorts).find('option:selected'); - var ports = ''; - var pid = ''; - $options.each(function(index, value) { - ports = ports+$(value).text()+", "; - pid = pid+$(value).attr('value')+","; - }); - ports = ports.slice(0,-2); - pid = pid.slice(0,-1); - var $tr = one.f.flows.modal.action.table.add("Add Output Ports", ports); - $tr.attr('id', 'addOutputPorts'); - $tr.data('action', 'OUTPUT='+pid); - $tr.click(function() { - one.f.flows.modal.action.add.modal.initialize(this); - }); - one.f.flows.modal.action.table.append($tr); - $modal.modal('hide'); - }, - add : function(name, action) { - var $tr = one.f.flows.modal.action.table.add(name); - $tr.attr('id', action); - $tr.data('action', action); - $tr.click(function() { - one.f.flows.modal.action.add.modal.initialize(this); - }); - one.f.flows.modal.action.table.append($tr); - }, - set : function(name, id, action, $modal) { - var $input = $('#'+id); - var value = $input.val(); - var $tr = one.f.flows.modal.action.table.add(name, value); - $tr.attr('id', action); - $tr.data('action', action+'='+value); - $tr.click(function() { - one.f.flows.modal.action.add.modal.initialize(this); - }); - one.f.flows.modal.action.table.append($tr); - $modal.modal('hide'); - }, - remove : function(that) { - $(that).remove(); - var $table = $('#'+one.f.flows.id.modal.action.table); - if ($table.find('tbody').find('tr').size() == 0) { - var $tr = $(document.createElement('tr')); - var $td = $(document.createElement('td')); - $td.attr('colspan', '3'); - $tr.addClass('empty'); - $td.text('No data available'); - $tr.append($td); - $table.find('tbody').append($tr); - } - }, - modal : { - initialize : function(that) { - var h3 = "Remove Action"; - var footer = one.f.flows.modal.action.add.modal.footer(); - var $body = one.f.flows.modal.action.add.modal.body(); - var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal.modal, h3, $body, footer); - - // bind cancel button - $('#'+one.f.flows.id.modal.action.modal.cancel, $modal).click(function() { - $modal.modal('hide'); - }); - - // bind remove button - $('#'+one.f.flows.id.modal.action.modal.remove, $modal).click(function() { - one.f.flows.modal.action.add.remove(that); - $modal.modal('hide'); - }); - - $modal.modal(); - }, - body : function() { - var $p = $(document.createElement('p')); - $p.append("Remove this action?"); - return $p; - }, - footer : function() { - var footer = []; - - var removeButton = one.lib.dashlet.button.single("Remove Action", one.f.flows.id.modal.action.modal.remove, "btn-danger", ""); - var $removeButton = one.lib.dashlet.button.button(removeButton); - footer.push($removeButton); - - var cancelButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.action.modal.cancel, "", ""); - var $cancelButton = one.lib.dashlet.button.button(cancelButton); - footer.push($cancelButton); - - return footer; - } - } - }, - table : { - add : function(action, data, type) { - var $tr = $(document.createElement('tr')); - var $td = $(document.createElement('td')); - $td.append(action); - $tr.append($td); - var $td = $(document.createElement('td')); - if (data != undefined) $td.append(data); - $tr.append($td); - var $td = $(document.createElement('td')); - if (type != undefined) $td.append(type); - $tr.append($td); - return $tr; - }, - append : function($tr) { - var $table = $('#'+one.f.flows.id.modal.action.table); - var $empty = $table.find('.empty').parent(); - if ($empty.size() > 0) $empty.remove(); - $table.append($tr); - } - }, - body : { - common : function() { - var $form = $(document.createElement('form')); - var $fieldset = $(document.createElement('fieldset')); - return [$form, $fieldset]; - }, - addOutputPorts : function() { - var common = one.f.flows.modal.action.body.common(); - var $form = common[0]; - var $fieldset = common[1]; - // output port - $label = one.lib.form.label("Select Output Ports"); - var ports = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports']; - $select = one.lib.form.select.create(ports, true); - $select.attr('id', one.f.flows.id.modal.action.addOutputPorts); - one.lib.form.select.prepend($select, {'':'Select a Port'}); - $fieldset.append($label).append($select); - $form.append($fieldset); - return $form; - }, - set : function(label, placeholder, id, help) { - var common = one.f.flows.modal.action.body.common(); - var $form = common[0]; - var $fieldset = common[1]; - // input - $label = one.lib.form.label(label); - $input = one.lib.form.input(placeholder); - $input.attr('id', id); - $help = one.lib.form.help(help); - // append - $fieldset.append($label).append($input).append($help); - $form.append($fieldset); - return $form; - } - }, - footer : function() { - var footer = []; - var addButton = one.lib.dashlet.button.single("Add Action", one.f.flows.id.modal.action.add, "btn-primary", ""); - var $addButton = one.lib.dashlet.button.button(addButton); - footer.push($addButton); - - var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.action.close, "", ""); - var $closeButton = one.lib.dashlet.button.button(closeButton); - footer.push($closeButton); - - return footer; - } - }, - footer : function() { - var footer = []; + var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", ""); + var $closeButton = one.lib.dashlet.button.button(closeButton); + footer.push($closeButton); - var installButton = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.modal.install, "btn-success", ""); - var $installButton = one.lib.dashlet.button.button(installButton); - footer.push($installButton); + return footer; + }, + footerEdit : function() { + var footer = []; - var addButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.add, "btn-primary", ""); - var $addButton = one.lib.dashlet.button.button(addButton); - footer.push($addButton); + var editButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.edit, "btn-success", ""); + var $editButton = one.lib.dashlet.button.button(editButton); + footer.push($editButton); - var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", ""); - var $closeButton = one.lib.dashlet.button.button(closeButton); - footer.push($closeButton); + var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", ""); + var $closeButton = one.lib.dashlet.button.button(closeButton); + footer.push($closeButton); - return footer; - }, - removeMultiple: { - dialog: function(flows) { - var h3 = 'Remove Flow Entry'; - var flowList = []; - for (var i = 0; i < flows.length; i++) { - flowList.push(flows[i]["name"]); - } - var footer = one.f.flows.modal.removeMultiple.footer(); - var $body = one.f.flows.modal.removeMultiple.body(flowList); - var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $body, footer); - - // bind close button - $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() { - $modal.modal('hide'); - }); - - // bind remove rule button - $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(this, function(e) { - var resource = {}; - resource['body'] = JSON.stringify(flows); - - $.post(one.f.address.root+one.f.address.flows.deleteFlows, resource, function(response) { - $modal.modal('hide'); - if(response == "Success") { - one.lib.alert("Flow Entry(s) successfully removed"); - } else { - one.lib.alert(response); - } - one.main.dashlet.right.bottom.empty(); - one.f.detail.dashlet(one.main.dashlet.right.bottom); - one.main.dashlet.left.top.empty(); - one.f.flows.dashlet(one.main.dashlet.left.top); - }); - }); - $modal.modal(); - }, - footer : function() { - var footer = []; - var remove = one.lib.dashlet.button.single('Remove Flow Entry',one.f.flows.id.modal.dialog.remove, 'btn-danger', ''); - var $remove = one.lib.dashlet.button.button(remove); - footer.push($remove); - - var cancel = one.lib.dashlet.button.single('Cancel', one.f.flows.id.modal.dialog.close, '', ''); - var $cancel = one.lib.dashlet.button.button(cancel); - footer.push($cancel); - - return footer; - }, - body : function (flows) { - var $p = $(document.createElement('p')); - var p = 'Remove the following Flow Entry(s)?'; - //creata a BS label for each rule and append to list - $(flows).each(function(){ - var $span = $(document.createElement('span')); - $span.append(this); - p += '
' + $span[0].outerHTML; - }); - $p.append(p); - return $p; - } - } - }, - ajax : { - dashlet : function(callback) { - $.getJSON(one.f.address.root+one.f.address.flows.main, function(data) { - one.f.flows.registry['flows'] = data.flows; - one.f.flows.registry['privilege'] = data.privilege; - callback(data); - }); - } + return footer; }, - data : { - flowsDataGrid: function(data) { - var source = new StaticDataSource({ - columns: [ - { - property: 'selector', - label: "", - sortable: false - }, - { - property: 'name', - label: 'Flow Name', - sortable: true - }, - { - property: 'node', - label: 'Node', - sortable: true - } - ], - data: data.flows, - formatter: function(items) { - $.each(items, function(index, item) { - var $checkbox = document.createElement("input"); - $checkbox.setAttribute("type", "checkbox"); - $checkbox.setAttribute("name", item.name); - $checkbox.setAttribute("node", item.nodeId); - $checkbox.setAttribute('class','flowEntry') - item.selector = $checkbox.outerHTML; - item["name"] = '' + item["name"] + ''; - }); - - }, - delay: 0 - }); - return source; - }, - dashlet : function(data) { - var body = []; - $(data).each(function(index, value) { - var tr = {}; - var entry = []; - - - entry.push(value['name']); - entry.push(value['node']); - if (value['flow']['installInHw'] == 'true' && value['flow']['status'] == 'Success') - tr['type'] = ['success']; - else if (value['flow']['installInHw'] == 'false' && value['flow']['status'] == 'Success') - tr['type'] = ['warning']; - else - tr['type'] = ['warning']; - tr['entry'] = entry; - tr['id'] = value['nodeId']; - - body.push(tr); - }); - return body; + removeMultiple: { + dialog: function(flows) { + var h3 = 'Remove Flow Entry'; + var flowList = []; + for (var i = 0; i < flows.length; i++) { + flowList.push(flows[i]["name"]); } + var footer = one.f.flows.modal.removeMultiple.footer(); + var $body = one.f.flows.modal.removeMultiple.body(flowList); + var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $body, footer); + + // bind close button + $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() { + $modal.modal('hide'); + }); + + // bind remove rule button + $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(this, function(e) { + var resource = {}; + resource['body'] = JSON.stringify(flows); + + $.post(one.f.address.root+one.f.address.flows.deleteFlows, resource, function(response) { + $modal.modal('hide'); + if(response == "Success") { + one.lib.alert("Flow Entry(s) successfully removed"); + } else { + one.lib.alert(response); + } + one.main.dashlet.right.bottom.empty(); + one.f.detail.dashlet(one.main.dashlet.right.bottom); + one.main.dashlet.left.top.empty(); + one.f.flows.dashlet(one.main.dashlet.left.top); + }); + }); + $modal.modal(); + }, + footer : function() { + var footer = []; + var remove = one.lib.dashlet.button.single('Remove Flow Entry',one.f.flows.id.modal.dialog.remove, 'btn-danger', ''); + var $remove = one.lib.dashlet.button.button(remove); + footer.push($remove); + + var cancel = one.lib.dashlet.button.single('Cancel', one.f.flows.id.modal.dialog.close, '', ''); + var $cancel = one.lib.dashlet.button.button(cancel); + footer.push($cancel); + + return footer; + }, + body : function (flows) { + var $p = $(document.createElement('p')); + var p = 'Remove the following Flow Entry(s)?'; + //creata a BS label for each rule and append to list + $(flows).each(function(){ + var $span = $(document.createElement('span')); + $span.append(this); + p += '
' + $span[0].outerHTML; + }); + $p.append(p); + return $p; + } + } + }, + ajax : { + dashlet : function(callback) { + $.getJSON(one.f.address.root+one.f.address.flows.main, function(data) { + one.f.flows.registry['flows'] = data.flows; + one.f.flows.registry['privilege'] = data.privilege; + one.f.flows.modal.ajax.nodes(function(){/*Empty function. Do nothing. */}) + + callback(data); + }); + } + }, + data : { + flowsDataGrid: function(data) { + var source = new StaticDataSource({ + columns: [ + { + property: 'selector', + label: "", + sortable: false + }, + { + property: 'name', + label: 'Flow Name', + sortable: true + }, + { + property: 'node', + label: 'Node', + sortable: true + } + ], + data: data.flows, + formatter: function(items) { + $.each(items, function(index, item) { + var $checkbox = document.createElement("input"); + $checkbox.setAttribute("type", "checkbox"); + $checkbox.setAttribute("name", item.name); + $checkbox.setAttribute("node", item.nodeId); + $checkbox.setAttribute('class','flowEntry') + item.selector = $checkbox.outerHTML; + item["name"] = '' + item["name"] + ''; + }); + + }, + delay: 0 + }); + return source; }, - body : { - dashlet : function(body, callback) { - var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed', 'table-cursor']; - var $table = one.lib.dashlet.table.table(attributes); - - var headers = ['Flow Name', 'Node']; - - var $thead = one.lib.dashlet.table.header(headers); - $table.append($thead); - - var $tbody = one.lib.dashlet.table.body(body); - $table.append($tbody); - return $table; - } + dashlet : function(data) { + var body = []; + $(data).each(function(index, value) { + var tr = {}; + var entry = []; + + + entry.push(value['name']); + entry.push(value['node']); + if (value['flow']['installInHw'] == 'true' && value['flow']['status'] == 'Success') + tr['type'] = ['success']; + else if (value['flow']['installInHw'] == 'false' && value['flow']['status'] == 'Success') + tr['type'] = ['warning']; + else + tr['type'] = ['warning']; + tr['entry'] = entry; + tr['id'] = value['nodeId']; + + body.push(tr); + }); + return body; + } + }, + body : { + dashlet : function(body, callback) { + var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed', 'table-cursor']; + var $table = one.lib.dashlet.table.table(attributes); + + var headers = ['Flow Name', 'Node']; + + var $thead = one.lib.dashlet.table.header(headers); + $table.append($thead); + + var $tbody = one.lib.dashlet.table.body(body); + $table.append($tbody); + return $table; } + } } /** INIT **/ // populate nav tabs $(one.f.menu.left.top).each(function(index, value) { - var $nav = $(".nav", "#left-top"); - one.main.page.dashlet($nav, value); + var $nav = $(".nav", "#left-top"); + one.main.page.dashlet($nav, value); }); $(one.f.menu.left.bottom).each(function(index, value) { - var $nav = $(".nav", "#left-bottom"); - one.main.page.dashlet($nav, value); + var $nav = $(".nav", "#left-bottom"); + one.main.page.dashlet($nav, value); }); $(one.f.menu.right.bottom).each(function(index, value) { - var $nav = $(".nav", "#right-bottom"); - one.main.page.dashlet($nav, value); + var $nav = $(".nav", "#right-bottom"); + one.main.page.dashlet($nav, value); }); one.f.populate = function($dashlet, header) { - var $h4 = one.lib.dashlet.header(header); - $dashlet.append($h4); + var $h4 = one.lib.dashlet.header(header); + $dashlet.append($h4); }; // bind dashlet nav $('.dash .nav a', '#main').click(function() { - // de/activation - var $li = $(this).parent(); - var $ul = $li.parent(); - one.lib.nav.unfocus($ul); - $li.addClass('active'); - // clear respective dashlet - var $dashlet = $ul.parent().find('.dashlet'); - one.lib.dashlet.empty($dashlet); - // callback based on menu - var id = $(this).attr('id'); - var menu = one.f.dashlet; - switch (id) { - case menu.flows.id: - one.f.flows.dashlet($dashlet); - break; - case menu.nodes.id: - one.f.nodes.dashlet($dashlet); - break; - case menu.detail.id: - one.f.detail.dashlet($dashlet); - break; - }; + // de/activation + var $li = $(this).parent(); + var $ul = $li.parent(); + one.lib.nav.unfocus($ul); + $li.addClass('active'); + // clear respective dashlet + var $dashlet = $ul.parent().find('.dashlet'); + one.lib.dashlet.empty($dashlet); + // callback based on menu + var id = $(this).attr('id'); + var menu = one.f.dashlet; + switch (id) { + case menu.flows.id: + one.f.flows.dashlet($dashlet); + break; + case menu.nodes.id: + one.f.nodes.dashlet($dashlet); + break; + case menu.detail.id: + one.f.detail.dashlet($dashlet); + break; + }; }); // activate first tab on each dashlet $('.dash .nav').each(function(index, value) { - $($(value).find('li')[0]).find('a').click(); + $($(value).find('li')[0]).find('a').click(); });