2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
12 // specify dashlets and layouts
46 root : "/controller/web/flows",
49 flows : "/node-flows",
50 nodes : "/node-ports",
52 deleteFlows:"/flow/deleteFlows"
60 datagrid: "one_f_nodes_id_dashlet_datagrid"
64 dashlet : function($dashlet) {
65 var $h4 = one.lib.dashlet.header("Nodes");
68 one.f.nodes.ajax.dashlet(function(data) {
69 var $gridHTML = one.lib.dashlet.datagrid.init(one.f.nodes.id.dashlet.datagrid, {
73 flexibleRowsPerPage: true
74 }, "table-striped table-condensed");
75 $dashlet.append($gridHTML);
76 var dataSource = one.f.nodes.data.nodesDataGrid(data);
77 $("#" + one.f.nodes.id.dashlet.datagrid).datagrid({dataSource: dataSource});
81 dashlet : function(callback) {
82 $.getJSON(one.f.address.root+one.f.address.flows.flows, function(data) {
88 nodesDataGrid: function(data) {
90 $.each(data, function(nodeName, flow) {
91 var nodeFlowObject = {};
92 nodeFlowObject["nodeName"] = nodeName;
93 nodeFlowObject["flows"] = flow;
94 nodeFlowObject["rowData"] = nodeName + flow + "-foobar";
95 gridData.push(nodeFlowObject);
98 var source = new StaticDataSource({
101 property: 'nodeName',
118 dashlet : function(body, callback) {
119 var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed'];
120 var $table = one.lib.dashlet.table.table(attributes);
122 var headers = ['Node', 'Flows'];
123 var $thead = one.lib.dashlet.table.header(headers);
124 $table.append($thead);
126 var $tbody = one.lib.dashlet.table.body(body);
127 $table.append($tbody);
138 dashlet : function($dashlet, details) {
139 var $h4 = one.lib.dashlet.header("Flow Details");
140 $dashlet.append($h4);
143 if (details == undefined) {
144 var $none = $(document.createElement('div'));
145 $none.addClass('none');
146 var $p = $(document.createElement('p'));
147 $p.text('Please select a flow');
148 $p.addClass('text-center').addClass('text-info');
150 $dashlet.append($none)
155 dashlet : function(data) {
160 entry.push(data['name']);
161 entry.push(data['node']);
162 entry.push(data['flow']['priority']);
163 entry.push(data['flow']['hardTimeout']);
164 entry.push(data['flow']['idleTimeout']);
170 description : function(data) {
174 entry.push(data['flow']['ingressPort']);
175 entry.push(data['flow']['etherType']);
176 entry.push(data['flow']['vlanId']);
177 entry.push(data['flow']['vlanPriority']);
178 entry.push(data['flow']['srcMac']);
179 entry.push(data['flow']['dstMac']);
180 entry.push(data['flow']['srcIp']);
181 entry.push(data['flow']['dstIp']);
182 entry.push(data['flow']['tosBits']);
183 entry.push(data['flow']['srcPort']);
184 entry.push(data['flow']['dstPort']);
185 entry.push(data['flow']['protocol']);
186 entry.push(data['flow']['cookie']);
192 actions : function(data) {
198 $(data['flow']['actions']).each(function(index, value) {
199 actions += value + ', ';
201 actions = actions.slice(0,-2);
210 dashlet : function(body) {
212 var header = ['Flow Name', 'Node', 'Priority', 'Hard Timeout', 'Idle Timeout'];
213 var $thead = one.lib.dashlet.table.header(header);
214 var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
215 var $table = one.lib.dashlet.table.table(attributes);
216 $table.append($thead);
218 var $tbody = one.lib.dashlet.table.body(body);
219 $table.append($tbody);
223 description : function(body) {
224 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'];
225 var $thead = one.lib.dashlet.table.header(header);
226 var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
227 var $table = one.lib.dashlet.table.table(attributes);
228 $table.append($thead);
230 var $tbody = one.lib.dashlet.table.body(body);
231 $table.append($tbody);
235 actions : function(body) {
236 var header = ['Actions'];
237 var $thead = one.lib.dashlet.table.header(header);
238 var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
239 var $table = one.lib.dashlet.table.table(attributes);
240 $table.append($thead);
242 var $tbody = one.lib.dashlet.table.body(body);
243 $table.append($tbody);
254 add : "one_f_flows_id_dashlet_add",
255 removeMultiple : "one_f_flows_id_dashlet_removeMultiple",
256 remove : "one_f_flows_id_dashlet_remove",
257 toggle : "one_f_flows_id_dashlet_toggle",
258 datagrid : "one_f_flows_id_dashlet_datagrid",
259 selectAllFlows : "one_f_flows_id_dashlet_selectAllFlows"
262 install : "one_f_flows_id_modal_install",
263 add : "one_f_flows_id_modal_add",
264 close : "one_f_flows_id_modal_close",
265 modal : "one_f_flows_id_modal_modal",
267 modal : "one_f_flows_id_modal_dialog_modal",
268 remove : "one_f_flows_id_modal_dialog_remove",
269 close : "one_f_flows_id_modal_dialog_close"
272 button : "one_f_flows_id_modal_action_button",
273 modal : "one_f_flows_id_modal_action_modal",
274 add : "one_f_flows_id_modal_action_add",
275 close : "one_f_flows_id_modal_action_close",
276 table : "one_f_flows_id_modal_action_table",
277 addOutputPorts : "one_f_flows_id_modal_action_addOutputPorts",
278 setVlanId : "one_f_flows_id_modal_action_setVlanId",
279 setVlanPriority : "one_f_flows_id_modal_action_setVlanPriority",
280 modifyDatalayerSourceAddress : "one_f_flows_id_modal_action_modifyDatalayerSourceAddress",
281 modifyDatalayerDestinationAddress : "one_f_flows_id_modal_action_modifyDatalayerDestinationAddress",
282 modifyNetworkSourceAddress : "one_f_flows_modal_action_modifyNetworkSourceAddress",
283 modifyNetworkDestinationAddress : "one_f_flows_modal_action_modifyNetworkDestinationAddress",
284 modifyTosBits : "one_f_flows_modal_action_modifyTosBits",
285 modifyTransportSourcePort : "one_f_flows_modal_action_modifyTransportSourcePort",
286 modifyTransportDestinationPort : "one_f_flows_modal_action_modifyTransportDestinationPort",
288 modal : "one_f_flows_modal_action_modal_modal",
289 remove : "one_f_flows_modal_action_modal_remove",
290 cancel : "one_f_flows_modal_action_modal_cancel"
294 name : "one_f_flows_id_modal_form_name",
295 nodes : "one_f_flows_id_modal_form_nodes",
296 port : "one_f_flows_id_modal_form_port",
297 priority : "one_f_flows_id_modal_form_priority",
298 hardTimeout : "one_f_flows_id_modal_form_hardTimeout",
299 idleTimeout : "one_f_flows_id_modal_form_idleTimeout",
300 cookie : "one_f_flows_id_modal_form_cookie",
301 etherType : "one_f_flows_id_modal_form_etherType",
302 vlanId : "one_f_flows_id_modal_form_vlanId",
303 vlanPriority : "one_f_flows_id_modal_form_vlanPriority",
304 srcMac : "one_f_flows_id_modal_form_srcMac",
305 dstMac : "one_f_flows_id_modal_form_dstMac",
306 srcIp : "one_f_flows_id_modal_form_srcIp",
307 dstIp : "one_f_flows_id_modal_form_dstIp",
308 tosBits : "one_f_flows_id_modal_form_tosBits",
309 srcPort : "one_f_flows_id_modal_form_srcPort",
310 dstPort : "one_f_flows_id_modal_form_dstPort",
311 protocol : "one_f_flows_id_modal_form_protocol"
316 dashlet : function($dashlet, callback) {
319 one.f.flows.ajax.dashlet(function(data) {
321 var $h4 = one.lib.dashlet.header("Flow Entries");
323 $dashlet.append($h4);
324 if (one.f.flows.registry.privilege === 'WRITE') {
325 var button = one.lib.dashlet.button.single("Add Flow Entry", one.f.flows.id.dashlet.add, "btn-primary", "btn-mini");
326 var $button = one.lib.dashlet.button.button(button);
328 $button.click(function() {
329 var $modal = one.f.flows.modal.initialize();
332 $dashlet.append($button);
333 var button = one.lib.dashlet.button.single("Remove Flow Entry", one.f.flows.id.dashlet.removeMultiple, "btn-danger", "btn-mini");
334 var $button = one.lib.dashlet.button.button(button);
336 $button.click(function() {
337 var checkedCheckBoxes = $('.flowEntry[type=checkbox]:checked');
338 if (checkedCheckBoxes.size() === 0) {
342 var requestData = [];
344 checkedCheckBoxes.each(function(index, value) {
346 flowEntry['name'] = checkedCheckBoxes[index].name;
347 flowEntry['node'] = checkedCheckBoxes[index].getAttribute("node");
348 requestData.push(flowEntry);
350 one.f.flows.modal.removeMultiple.dialog(requestData);
352 $dashlet.append($button);
356 var $gridHTML = one.lib.dashlet.datagrid.init(one.f.flows.id.dashlet.datagrid, {
360 flexibleRowsPerPage: true
361 }, "table-striped table-condensed");
362 $dashlet.append($gridHTML);
363 var dataSource = one.f.flows.data.flowsDataGrid(data);
364 $("#" + one.f.flows.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
365 $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).click(function() {
366 $("#" + one.f.flows.id.dashlet.datagrid).find(':checkbox').prop('checked',
367 $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).is(':checked'));
370 $("#" + one.f.flows.id.dashlet.datagrid).find("tbody tr").each(function(index, tr) {
372 $span = $("td span", $tr);
373 var flowstatus = $span.data("flowstatus");
374 if($span.data("installinhw") != null) {
375 var installInHw = $span.data("installinhw").toString();
376 if(installInHw == "true" && flowstatus == "Success") {
377 $tr.addClass("success");
379 $tr.addClass("warning");
382 // attach mouseover to show pointer cursor
383 $tr.mouseover(function() {
384 $(this).css("cursor", "pointer");
386 // attach click event
387 $tr.click(function() {
388 var $td = $($(this).find("td")[1]);
390 var node = $td.find("span").data("nodeid");
391 one.f.flows.detail(id, node);
393 $(".flowEntry").click(function(e){
394 if (!$('.flowEntry[type=checkbox]:not(:checked)').length) {
395 $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows)
399 $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows)
409 if(callback != undefined) callback();
412 detail : function(id, node) {
413 // clear flow details
414 var $detailDashlet = one.main.dashlet.right.bottom;
415 $detailDashlet.empty();
416 var $h4 = one.lib.dashlet.header("Flow Overview");
417 $detailDashlet.append($h4);
420 var flows = one.f.flows.registry.flows;
422 $(flows).each(function(index, value) {
423 if (value.name == id && value.nodeId == node) {
427 if (one.f.flows.registry.privilege === 'WRITE') {
429 var button = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.dashlet.remove, "btn-danger", "btn-mini");
430 var $button = one.lib.dashlet.button.button(button);
431 $button.click(function() {
432 var $modal = one.f.flows.modal.dialog.initialize(id, node);
437 if (flow['flow']['installInHw'] == 'true' && flow['flow']['status'] == 'Success') {
438 toggle = one.lib.dashlet.button.single("Uninstall Flow", one.f.flows.id.dashlet.toggle, "btn-warning", "btn-mini");
440 toggle = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.dashlet.toggle, "btn-success", "btn-mini");
442 var $toggle = one.lib.dashlet.button.button(toggle);
443 $toggle.click(function() {
444 one.f.flows.modal.ajax.toggleflow(id, node, function(data) {
445 if(data == "Success") {
446 one.main.dashlet.right.bottom.empty();
447 one.f.detail.dashlet(one.main.dashlet.right.bottom);
448 one.main.dashlet.left.top.empty();
449 one.f.flows.dashlet(one.main.dashlet.left.top, function() {
450 // checks are backwards due to stale registry
451 if(flow['flow']['installInHw'] == 'true') {
452 one.lib.alert('Uninstalled Flow');
454 one.lib.alert('Installed Flow');
456 one.f.flows.detail(id, node)
459 one.lib.alert('Cannot toggle flow: '+data);
464 $detailDashlet.append($button).append($toggle);
467 var body = one.f.detail.data.dashlet(flow);
468 var $body = one.f.detail.body.dashlet(body);
469 $detailDashlet.append($body);
470 var body = one.f.detail.data.description(flow);
471 var $body = one.f.detail.body.description(body);
472 $detailDashlet.append($body);
473 var body = one.f.detail.data.actions(flow);
474 var $body = one.f.detail.body.actions(body);
475 $detailDashlet.append($body);
479 initialize : function(id, node) {
480 var h3 = "Remove Flow";
481 var $p = one.f.flows.modal.dialog.body(id);
482 var footer = one.f.flows.modal.dialog.footer();
483 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $p, footer);
484 $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() {
485 $modal.modal('hide');
487 $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(function() {
488 one.f.flows.modal.ajax.removeflow(id, node, function(data) {
489 if (data == "Success") {
490 $modal.modal('hide');
491 one.main.dashlet.right.bottom.empty();
492 one.f.detail.dashlet(one.main.dashlet.right.bottom);
493 one.main.dashlet.left.top.empty();
494 one.f.flows.dashlet(one.main.dashlet.left.top);
495 one.lib.alert('Flow removed');
497 one.lib.alert('Cannot remove flow: '+data);
503 footer : function() {
506 var removeButton = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.modal.dialog.remove, "btn-danger", "");
507 var $removeButton = one.lib.dashlet.button.button(removeButton);
508 footer.push($removeButton);
510 var closeButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.dialog.close, "", "");
511 var $closeButton = one.lib.dashlet.button.button(closeButton);
512 footer.push($closeButton);
516 body : function(id) {
517 var $p = $(document.createElement('p'));
518 $p.append('Remove flow '+id+'?');
522 initialize : function() {
523 var h3 = "Add Flow Entry";
524 var footer = one.f.flows.modal.footer();
525 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.modal, h3, "", footer);
528 $('#'+one.f.flows.id.modal.close, $modal).click(function() {
529 $modal.modal('hide');
532 // bind add flow button
533 $('#'+one.f.flows.id.modal.add, $modal).click(function() {
534 one.f.flows.modal.add($modal, 'false');
537 // bind install flow button
538 $('#'+one.f.flows.id.modal.install, $modal).click(function() {
539 one.f.flows.modal.add($modal, 'true');
542 // inject body (nodePorts)
543 one.f.flows.modal.ajax.nodes(function(nodes, nodeports) {
544 var $body = one.f.flows.modal.body(nodes, nodeports);
545 one.lib.modal.inject.body($modal, $body);
550 add : function($modal, install) {
553 result['name'] = $('#'+one.f.flows.id.modal.form.name, $modal).val();
554 result['ingressPort'] = $('#'+one.f.flows.id.modal.form.port, $modal).val();
555 result['priority'] = $('#'+one.f.flows.id.modal.form.priority, $modal).val();
556 result['hardTimeout'] = $('#'+one.f.flows.id.modal.form.hardTimeout, $modal).val();
557 result['idleTimeout'] = $('#'+one.f.flows.id.modal.form.idleTimeout, $modal).val();
558 result['cookie'] = $('#'+one.f.flows.id.modal.form.cookie, $modal).val();
559 result['etherType'] = $('#'+one.f.flows.id.modal.form.etherType, $modal).val();
560 result['vlanId'] = $('#'+one.f.flows.id.modal.form.vlanId, $modal).val();
561 result['vlanPriority'] = $('#'+one.f.flows.id.modal.form.vlanPriority, $modal).val();
562 result['dlSrc'] = $('#'+one.f.flows.id.modal.form.srcMac, $modal).val();
563 result['dlDst'] = $('#'+one.f.flows.id.modal.form.dstMac, $modal).val();
564 result['nwSrc'] = $('#'+one.f.flows.id.modal.form.srcIp, $modal).val();
565 result['nwDst'] = $('#'+one.f.flows.id.modal.form.dstIp, $modal).val();
566 result['tosBits'] = $('#'+one.f.flows.id.modal.form.tosBits, $modal).val();
567 result['tpSrc'] = $('#'+one.f.flows.id.modal.form.srcPort, $modal).val();
568 result['tpDst'] = $('#'+one.f.flows.id.modal.form.dstPort, $modal).val();
569 result['protocol'] = $('#'+one.f.flows.id.modal.form.protocol, $modal).val();
571 result['installInHw'] = install;
573 var nodeId = $('#'+one.f.flows.id.modal.form.nodes, $modal).val();
575 $.each(result, function(key, value) {
576 if (value == "") delete result[key];
580 var $table = $('#'+one.f.flows.id.modal.action.table, $modal);
581 $($table.find('tbody').find('tr')).each(function(index, value) {
582 if (!$(this).find('td').hasClass('empty')) {
583 action.push($(value).data('action'));
586 result['actions'] = action;
588 // frontend validation
589 if (result['name'] == undefined) {
590 alert('Need flow name');
594 alert('Select node');
597 if (action.length == 0) {
598 alert('Please specify an action');
602 // package for ajax call
604 resource['body'] = JSON.stringify(result);
605 resource['action'] = 'add';
606 resource['nodeId'] = nodeId;
608 one.f.flows.modal.ajax.saveflow(resource, function(data) {
609 if (data == "Success") {
610 $modal.modal('hide');
611 one.lib.alert('Flow Entry added');
612 one.main.dashlet.left.top.empty();
613 one.f.flows.dashlet(one.main.dashlet.left.top);
615 alert('Could not add flow: '+data);
620 nodes : function(successCallback) {
621 $.getJSON(one.f.address.root+one.f.address.flows.nodes, function(data) {
622 var nodes = one.f.flows.modal.data.nodes(data);
623 var nodeports = data;
624 one.f.flows.registry['nodeports'] = nodeports;
626 successCallback(nodes, nodeports);
629 saveflow : function(resource, callback) {
630 $.post(one.f.address.root+one.f.address.flows.flow, resource, function(data) {
634 removeflow : function(id, node, callback) {
636 resource['action'] = 'remove';
637 $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
641 toggleflow : function(id, node, callback) {
643 resource['action'] = 'toggle';
644 $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
650 nodes : function(data) {
652 $.each(data, function(key, value) {
653 result[key] = value['name'];
658 body : function(nodes, nodeports) {
659 var $form = $(document.createElement('form'));
660 var $fieldset = $(document.createElement('fieldset'));
662 var $legend = one.lib.form.legend("Flow Description");
663 $fieldset.append($legend);
665 var $label = one.lib.form.label("Name");
666 var $input = one.lib.form.input("Flow Name");
667 $input.attr('id', one.f.flows.id.modal.form.name);
668 $fieldset.append($label).append($input);
670 var $label = one.lib.form.label("Node");
671 var $select = one.lib.form.select.create(nodes);
672 one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
673 $select.val($select.find("option:first").val());
674 $select.attr('id', one.f.flows.id.modal.form.nodes);
677 $select.change(function() {
678 // retrieve port value
679 var node = $(this).find('option:selected').attr('value');
680 var $ports = $('#'+one.f.flows.id.modal.form.port);
682 one.lib.form.select.inject($ports, {});
685 one.f.flows.registry['currentNode'] = node;
686 var ports = nodeports[node]['ports'];
687 one.lib.form.select.inject($ports, ports);
688 one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
689 $ports.val($ports.find("option:first").val());
692 $fieldset.append($label).append($select);
694 var $label = one.lib.form.label("Input Port");
695 var $select = one.lib.form.select.create();
696 $select.attr('id', one.f.flows.id.modal.form.port);
697 $fieldset.append($label).append($select);
699 var $label = one.lib.form.label("Priority");
700 var $input = one.lib.form.input("Priority");
701 $input.attr('id', one.f.flows.id.modal.form.priority);
703 $fieldset.append($label).append($input);
705 var $label = one.lib.form.label("Hard Timeout");
706 var $input = one.lib.form.input("Hard Timeout");
707 $input.attr('id', one.f.flows.id.modal.form.hardTimeout);
708 $fieldset.append($label).append($input);
710 var $label = one.lib.form.label("Idle Timeout");
711 var $input = one.lib.form.input("Idle Timeout");
712 $input.attr('id', one.f.flows.id.modal.form.idleTimeout);
713 $fieldset.append($label).append($input);
715 var $label = one.lib.form.label("Cookie");
716 var $input = one.lib.form.input("Cookie");
717 $input.attr('id', one.f.flows.id.modal.form.cookie);
718 $fieldset.append($label).append($input);
720 var $legend = one.lib.form.legend("Layer 2");
721 $fieldset.append($legend);
723 var $label = one.lib.form.label("Ethernet Type");
724 var $input = one.lib.form.input("Ethernet Type");
725 $input.attr('id', one.f.flows.id.modal.form.etherType);
727 $fieldset.append($label).append($input);
729 var $label = one.lib.form.label("VLAN Identification Number");
730 var $input = one.lib.form.input("VLAN Identification Number");
731 $input.attr('id', one.f.flows.id.modal.form.vlanId);
732 var $help = one.lib.form.help("Range: 0 - 4095");
733 $fieldset.append($label).append($input).append($help);
735 var $label = one.lib.form.label("VLAN Priority");
736 var $input = one.lib.form.input("VLAN Priority");
737 $input.attr('id', one.f.flows.id.modal.form.vlanPriority);
738 var $help = one.lib.form.help("Range: 0 - 7");
739 $fieldset.append($label).append($input).append($help);
741 var $label = one.lib.form.label("Source MAC Address");
742 var $input = one.lib.form.input("Source MAC Address");
743 $input.attr('id', one.f.flows.id.modal.form.srcMac);
744 var $help = one.lib.form.help("Example: 00:11:22:aa:bb:cc");
745 $fieldset.append($label).append($input).append($help);
747 var $label = one.lib.form.label("Destination MAC Address");
748 var $input = one.lib.form.input("Destination MAC Address");
749 $input.attr('id', one.f.flows.id.modal.form.dstMac);
750 var $help = one.lib.form.help("Example: 00:11:22:aa:bb:cc");
751 $fieldset.append($label).append($input).append($help);
753 var $legend = one.lib.form.legend("Layer 3");
754 $fieldset.append($legend);
756 var $label = one.lib.form.label("Source IP Address");
757 var $input = one.lib.form.input("Source IP Address");
758 $input.attr('id', one.f.flows.id.modal.form.srcIp);
759 var $help = one.lib.form.help("Example: 127.0.0.1");
760 $fieldset.append($label).append($input).append($help);
762 var $label = one.lib.form.label("Destination IP Address");
763 var $input = one.lib.form.input("Destination IP Address");
764 $input.attr('id', one.f.flows.id.modal.form.dstIp);
765 var $help = one.lib.form.help("Example: 127.0.0.1");
766 $fieldset.append($label).append($input).append($help);
768 var $label = one.lib.form.label("TOS Bits");
769 var $input = one.lib.form.input("TOS Bits");
770 $input.attr('id', one.f.flows.id.modal.form.tosBits);
771 var $help = one.lib.form.help("Range: 0 - 63");
772 $fieldset.append($label).append($input).append($help);
774 var $legend = one.lib.form.legend("Layer 4");
775 $fieldset.append($legend);
777 var $label = one.lib.form.label("Source Port");
778 var $input = one.lib.form.input("Source Port");
779 $input.attr('id', one.f.flows.id.modal.form.srcPort);
780 var $help = one.lib.form.help("Range: 0 - 65535");
781 $fieldset.append($label).append($input).append($help);
783 var $label = one.lib.form.label("Destination Port");
784 var $input = one.lib.form.input("Destination Port");
785 $input.attr('id', one.f.flows.id.modal.form.dstPort);
786 var $help = one.lib.form.help("Range: 0 - 65535");
787 $fieldset.append($label).append($input).append($help);
789 var $label = one.lib.form.label("Protocol");
790 var $input = one.lib.form.input("Protocol");
791 $input.attr('id', one.f.flows.id.modal.form.protocol);
792 $fieldset.append($label).append($input);
794 var $legend = one.lib.form.label("Actions");
795 $fieldset.append($legend);
797 var tableAttributes = ["table-striped", "table-bordered", "table-condensed", "table-hover", "table-cursor"];
798 var $table = one.lib.dashlet.table.table(tableAttributes);
799 $table.attr('id', one.f.flows.id.modal.action.table);
800 var tableHeaders = ["Action", "Data", "Type"];
801 var $thead = one.lib.dashlet.table.header(tableHeaders);
802 var $tbody = one.lib.dashlet.table.body("", tableHeaders);
803 $table.append($thead).append($tbody);
806 "" : "Please Select an Action",
808 "loopback" : "Loopback",
810 "softwarePath" : "Software Path",
811 "hardwarePath" : "Hardware Path",
812 "controller" : "Controller",
813 "addOutputPorts" : "Add Output Ports",
814 "setVlanId" : "Set VLAN ID",
815 "setVlanPriority" : "Set VLAN Priority",
816 "stripVlanHeader" : "Strip VLAN Header",
817 "modifyDatalayerSourceAddress" : "Modify Datalayer Source Address",
818 "modifyDatalayerDestinationAddress" : "Modify Datalayer Destination Address",
819 "modifyNetworkSourceAddress" : "Modify Network Source Address",
820 "modifyNetworkDestinationAddress" :"Modify Network Destination Address",
821 "modifyTosBits" : "Modify TOS Bits",
822 "modifyTransportSourcePort" : "Modify Transport Source Port",
823 "modifyTransportDestinationPort" : "Modify Transport Destination Port"
825 var $select = one.lib.form.select.create(actions);
826 // when selecting an action
827 $select.change(function() {
828 var action = $(this).find('option:selected');
829 one.f.flows.modal.action.parse(action.attr('value'));
830 $select[0].selectedIndex = 0;
833 $fieldset.append($select).append($table);
836 $form.append($fieldset);
840 parse : function(option) {
842 case "addOutputPorts" :
843 var h3 = "Add Output Port";
844 var $modal = one.f.flows.modal.action.initialize(h3, one.f.flows.modal.action.body.addOutputPorts, one.f.flows.modal.action.add.addOutputPorts);
848 var h3 = "Set VLAN ID";
849 var placeholder = "VLAN Identification Number";
850 var id = one.f.flows.id.modal.action.setVlanId;
851 var help = "Range: 0 - 4095";
852 var action = 'SET_VLAN_ID';
853 var name = "VLAN ID";
854 var body = function() {
855 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
857 var add = function($modal) {
858 one.f.flows.modal.action.add.set(name, id, action, $modal);
860 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
863 case "setVlanPriority" :
864 var h3 = "Set VLAN Priority";
865 var placeholder = "VLAN Priority";
866 var id = one.f.flows.id.modal.action.setVlanPriority;
867 var help = "Range: 0 - 7";
868 var action = 'SET_VLAN_PCP';
869 var name = "VLAN Priority";
870 var body = function() {
871 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
873 var add = function($modal) {
874 one.f.flows.modal.action.add.set(name, id, action, $modal);
876 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
879 case "stripVlanHeader" :
880 var name = "Strip VLAN Header";
881 var action = 'POP_VLAN';
882 one.f.flows.modal.action.add.add(name, action);
884 case "modifyDatalayerSourceAddress" :
885 var h3 = "Set Source MAC Address";
886 var placeholder = "Source MAC Address";
887 var id = one.f.flows.id.modal.action.modifyDatalayerSourceAddress;
888 var help = "Example: 00:11:22:aa:bb:cc";
889 var action = 'SET_DL_SRC';
890 var name = "Source MAC";
891 var body = function() {
892 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
894 var add = function($modal) {
895 one.f.flows.modal.action.add.set(name, id, action, $modal);
897 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
900 case "modifyDatalayerDestinationAddress" :
901 var h3 = "Set Destination MAC Address";
902 var placeholder = "Destination MAC Address";
903 var id = one.f.flows.id.modal.action.modifyDatalayerDestinationAddress;
904 var help = "Example: 00:11:22:aa:bb:cc";
905 var action = 'SET_DL_DST';
906 var name = "Destination MAC";
907 var body = function() {
908 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
910 var add = function($modal) {
911 one.f.flows.modal.action.add.set(name, id, action, $modal);
913 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
916 case "modifyNetworkSourceAddress" :
917 var h3 = "Set IP Source Address";
918 var placeholder = "Source IP Address";
919 var id = one.f.flows.id.modal.action.modifyNetworkSourceAddress;
920 var help = "Example: 127.0.0.1";
921 var action = 'SET_NW_SRC';
922 var name = "Source IP";
923 var body = function() {
924 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
926 var add = function($modal) {
927 one.f.flows.modal.action.add.set(name, id, action, $modal);
929 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
932 case "modifyNetworkDestinationAddress" :
933 var h3 = "Set IP Destination Address";
934 var placeholder = "Destination IP Address";
935 var id = one.f.flows.id.modal.action.modifyNetworkDestinationAddress;
936 var help = "Example: 127.0.0.1";
937 var action = 'SET_NW_DST';
938 var name = "Destination IP";
939 var body = function() {
940 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
942 var add = function($modal) {
943 one.f.flows.modal.action.add.set(name, id, action, $modal);
945 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
948 case "modifyTosBits" :
949 var h3 = "Set IPv4 ToS";
950 var placeholder = "IPv4 ToS";
951 var id = one.f.flows.id.modal.action.modifyTosBits;
952 var help = "Range: 0 - 63";
953 var action = 'SET_NW_TOS';
954 var name = "TOS Bits";
955 var body = function() {
956 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
958 var add = function($modal) {
959 one.f.flows.modal.action.add.set(name, id, action, $modal);
961 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
964 case "modifyTransportSourcePort" :
965 var h3 = "Set Transport Source Port";
966 var placeholder = "Transport Source Port";
967 var id = one.f.flows.id.modal.action.modifyTransportSourcePort;
968 var help = "Range: 1 - 65535";
969 var action = 'SET_TP_SRC';
970 var name = "Source Port";
971 var body = function() {
972 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
974 var add = function($modal) {
975 one.f.flows.modal.action.add.set(name, id, action, $modal);
977 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
980 case "modifyTransportDestinationPort" :
981 var h3 = "Set Transport Destination Port";
982 var placeholder = "Transport Destination Port";
983 var id = one.f.flows.id.modal.action.modifyTransportDestinationPort;
984 var help = "Range: 1 - 65535";
985 var action = 'SET_TP_DST';
986 var name = "Destination Port";
987 var body = function() {
988 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
990 var add = function($modal) {
991 one.f.flows.modal.action.add.set(name, id, action, $modal);
993 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
999 one.f.flows.modal.action.add.add(name, action);
1002 var name = "Loopback";
1003 var action = 'LOOPBACK';
1004 one.f.flows.modal.action.add.add(name, action);
1008 var action = 'FLOOD';
1009 one.f.flows.modal.action.add.add(name, action);
1011 case "softwarePath" :
1012 var name = "Software Path";
1013 var action = 'SW_PATH';
1014 one.f.flows.modal.action.add.add(name, action);
1016 case "hardwarePath" :
1017 var name = "Hardware Path";
1018 var action = 'HW_PATH';
1019 one.f.flows.modal.action.add.add(name, action);
1022 var name = "Controller";
1023 var action = 'CONTROLLER';
1024 one.f.flows.modal.action.add.add(name, action);
1028 initialize : function(h3, bodyCallback, addCallback) {
1029 var footer = one.f.flows.modal.action.footer();
1030 var $body = bodyCallback();
1031 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal, h3, $body, footer);
1032 // bind close button
1033 $('#'+one.f.flows.id.modal.action.close, $modal).click(function() {
1034 $modal.modal('hide');
1036 // bind add flow button
1037 $('#'+one.f.flows.id.modal.action.add, $modal).click(function() {
1038 addCallback($modal);
1043 addOutputPorts : function($modal) {
1044 var $options = $('#'+one.f.flows.id.modal.action.addOutputPorts).find('option:selected');
1047 $options.each(function(index, value) {
1048 ports = ports+$(value).text()+", ";
1049 pid = pid+$(value).attr('value')+",";
1051 ports = ports.slice(0,-2);
1052 pid = pid.slice(0,-1);
1053 var $tr = one.f.flows.modal.action.table.add("Add Output Ports", ports);
1054 $tr.attr('id', 'addOutputPorts');
1055 $tr.data('action', 'OUTPUT='+pid);
1056 $tr.click(function() {
1057 one.f.flows.modal.action.add.modal.initialize(this);
1059 one.f.flows.modal.action.table.append($tr);
1060 $modal.modal('hide');
1062 add : function(name, action) {
1063 var $tr = one.f.flows.modal.action.table.add(name);
1064 $tr.attr('id', action);
1065 $tr.data('action', action);
1066 $tr.click(function() {
1067 one.f.flows.modal.action.add.modal.initialize(this);
1069 one.f.flows.modal.action.table.append($tr);
1071 set : function(name, id, action, $modal) {
1072 var $input = $('#'+id);
1073 var value = $input.val();
1074 var $tr = one.f.flows.modal.action.table.add(name, value);
1075 $tr.attr('id', action);
1076 $tr.data('action', action+'='+value);
1077 $tr.click(function() {
1078 one.f.flows.modal.action.add.modal.initialize(this);
1080 one.f.flows.modal.action.table.append($tr);
1081 $modal.modal('hide');
1083 remove : function(that) {
1085 var $table = $('#'+one.f.flows.id.modal.action.table);
1086 if ($table.find('tbody').find('tr').size() == 0) {
1087 var $tr = $(document.createElement('tr'));
1088 var $td = $(document.createElement('td'));
1089 $td.attr('colspan', '3');
1090 $tr.addClass('empty');
1091 $td.text('No data available');
1093 $table.find('tbody').append($tr);
1097 initialize : function(that) {
1098 var h3 = "Remove Action";
1099 var footer = one.f.flows.modal.action.add.modal.footer();
1100 var $body = one.f.flows.modal.action.add.modal.body();
1101 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal.modal, h3, $body, footer);
1103 // bind cancel button
1104 $('#'+one.f.flows.id.modal.action.modal.cancel, $modal).click(function() {
1105 $modal.modal('hide');
1108 // bind remove button
1109 $('#'+one.f.flows.id.modal.action.modal.remove, $modal).click(function() {
1110 one.f.flows.modal.action.add.remove(that);
1111 $modal.modal('hide');
1117 var $p = $(document.createElement('p'));
1118 $p.append("Remove this action?");
1121 footer : function() {
1124 var removeButton = one.lib.dashlet.button.single("Remove Action", one.f.flows.id.modal.action.modal.remove, "btn-danger", "");
1125 var $removeButton = one.lib.dashlet.button.button(removeButton);
1126 footer.push($removeButton);
1128 var cancelButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.action.modal.cancel, "", "");
1129 var $cancelButton = one.lib.dashlet.button.button(cancelButton);
1130 footer.push($cancelButton);
1137 add : function(action, data, type) {
1138 var $tr = $(document.createElement('tr'));
1139 var $td = $(document.createElement('td'));
1142 var $td = $(document.createElement('td'));
1143 if (data != undefined) $td.append(data);
1145 var $td = $(document.createElement('td'));
1146 if (type != undefined) $td.append(type);
1150 append : function($tr) {
1151 var $table = $('#'+one.f.flows.id.modal.action.table);
1152 var $empty = $table.find('.empty').parent();
1153 if ($empty.size() > 0) $empty.remove();
1158 common : function() {
1159 var $form = $(document.createElement('form'));
1160 var $fieldset = $(document.createElement('fieldset'));
1161 return [$form, $fieldset];
1163 addOutputPorts : function() {
1164 var common = one.f.flows.modal.action.body.common();
1165 var $form = common[0];
1166 var $fieldset = common[1];
1168 $label = one.lib.form.label("Select Output Ports");
1169 var ports = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports'];
1170 $select = one.lib.form.select.create(ports, true);
1171 $select.attr('id', one.f.flows.id.modal.action.addOutputPorts);
1172 one.lib.form.select.prepend($select, {'':'Select a Port'});
1173 $fieldset.append($label).append($select);
1174 $form.append($fieldset);
1177 set : function(label, placeholder, id, help) {
1178 var common = one.f.flows.modal.action.body.common();
1179 var $form = common[0];
1180 var $fieldset = common[1];
1182 $label = one.lib.form.label(label);
1183 $input = one.lib.form.input(placeholder);
1184 $input.attr('id', id);
1185 $help = one.lib.form.help(help);
1187 $fieldset.append($label).append($input).append($help);
1188 $form.append($fieldset);
1192 footer : function() {
1194 var addButton = one.lib.dashlet.button.single("Add Action", one.f.flows.id.modal.action.add, "btn-primary", "");
1195 var $addButton = one.lib.dashlet.button.button(addButton);
1196 footer.push($addButton);
1198 var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.action.close, "", "");
1199 var $closeButton = one.lib.dashlet.button.button(closeButton);
1200 footer.push($closeButton);
1205 footer : function() {
1208 var installButton = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.modal.install, "btn-success", "");
1209 var $installButton = one.lib.dashlet.button.button(installButton);
1210 footer.push($installButton);
1212 var addButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.add, "btn-primary", "");
1213 var $addButton = one.lib.dashlet.button.button(addButton);
1214 footer.push($addButton);
1216 var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", "");
1217 var $closeButton = one.lib.dashlet.button.button(closeButton);
1218 footer.push($closeButton);
1223 dialog: function(flows) {
1224 var h3 = 'Remove Flow Entry';
1226 for (var i = 0; i < flows.length; i++) {
1227 flowList.push(flows[i]["name"]);
1229 var footer = one.f.flows.modal.removeMultiple.footer();
1230 var $body = one.f.flows.modal.removeMultiple.body(flowList);
1231 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $body, footer);
1233 // bind close button
1234 $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() {
1235 $modal.modal('hide');
1238 // bind remove rule button
1239 $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(this, function(e) {
1241 resource['body'] = JSON.stringify(flows);
1243 $.post(one.f.address.root+one.f.address.flows.deleteFlows, resource, function(response) {
1244 $modal.modal('hide');
1245 if(response == "Success") {
1246 one.lib.alert("Flow Entry(s) successfully removed");
1248 one.lib.alert(response);
1250 one.main.dashlet.right.bottom.empty();
1251 one.f.detail.dashlet(one.main.dashlet.right.bottom);
1252 one.main.dashlet.left.top.empty();
1253 one.f.flows.dashlet(one.main.dashlet.left.top);
1258 footer : function() {
1260 var remove = one.lib.dashlet.button.single('Remove Flow Entry',one.f.flows.id.modal.dialog.remove, 'btn-danger', '');
1261 var $remove = one.lib.dashlet.button.button(remove);
1262 footer.push($remove);
1264 var cancel = one.lib.dashlet.button.single('Cancel', one.f.flows.id.modal.dialog.close, '', '');
1265 var $cancel = one.lib.dashlet.button.button(cancel);
1266 footer.push($cancel);
1270 body : function (flows) {
1271 var $p = $(document.createElement('p'));
1272 var p = 'Remove the following Flow Entry(s)?';
1273 //creata a BS label for each rule and append to list
1274 $(flows).each(function(){
1275 var $span = $(document.createElement('span'));
1277 p += '<br/>' + $span[0].outerHTML;
1285 dashlet : function(callback) {
1286 $.getJSON(one.f.address.root+one.f.address.flows.main, function(data) {
1287 one.f.flows.registry['flows'] = data.flows;
1288 one.f.flows.registry['privilege'] = data.privilege;
1294 flowsDataGrid: function(data) {
1295 var source = new StaticDataSource({
1298 property: 'selector',
1299 label: "<input type='checkbox' id='"+one.f.flows.id.dashlet.datagrid.selectAllFlows+"'/>",
1314 formatter: function(items) {
1315 $.each(items, function(index, item) {
1316 var $checkbox = document.createElement("input");
1317 $checkbox.setAttribute("type", "checkbox");
1318 $checkbox.setAttribute("name", item.name);
1319 $checkbox.setAttribute("node", item.nodeId);
1320 $checkbox.setAttribute('class','flowEntry')
1321 item.selector = $checkbox.outerHTML;
1322 item["name"] = '<span data-installInHw=' + item["flow"]["installInHw"] +
1323 ' data-flowstatus=' + item["flow"]["status"] +
1324 ' data-nodeId=' + item["nodeId"] + '>' + item["name"] + '</span>';
1332 dashlet : function(data) {
1334 $(data).each(function(index, value) {
1339 entry.push(value['name']);
1340 entry.push(value['node']);
1341 if (value['flow']['installInHw'] == 'true' && value['flow']['status'] == 'Success')
1342 tr['type'] = ['success'];
1343 else if (value['flow']['installInHw'] == 'false' && value['flow']['status'] == 'Success')
1344 tr['type'] = ['warning'];
1346 tr['type'] = ['warning'];
1347 tr['entry'] = entry;
1348 tr['id'] = value['nodeId'];
1356 dashlet : function(body, callback) {
1357 var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed', 'table-cursor'];
1358 var $table = one.lib.dashlet.table.table(attributes);
1360 var headers = ['Flow Name', 'Node'];
1362 var $thead = one.lib.dashlet.table.header(headers);
1363 $table.append($thead);
1365 var $tbody = one.lib.dashlet.table.body(body);
1366 $table.append($tbody);
1373 // populate nav tabs
1374 $(one.f.menu.left.top).each(function(index, value) {
1375 var $nav = $(".nav", "#left-top");
1376 one.main.page.dashlet($nav, value);
1379 $(one.f.menu.left.bottom).each(function(index, value) {
1380 var $nav = $(".nav", "#left-bottom");
1381 one.main.page.dashlet($nav, value);
1384 $(one.f.menu.right.bottom).each(function(index, value) {
1385 var $nav = $(".nav", "#right-bottom");
1386 one.main.page.dashlet($nav, value);
1389 one.f.populate = function($dashlet, header) {
1390 var $h4 = one.lib.dashlet.header(header);
1391 $dashlet.append($h4);
1395 $('.dash .nav a', '#main').click(function() {
1397 var $li = $(this).parent();
1398 var $ul = $li.parent();
1399 one.lib.nav.unfocus($ul);
1400 $li.addClass('active');
1401 // clear respective dashlet
1402 var $dashlet = $ul.parent().find('.dashlet');
1403 one.lib.dashlet.empty($dashlet);
1404 // callback based on menu
1405 var id = $(this).attr('id');
1406 var menu = one.f.dashlet;
1409 one.f.flows.dashlet($dashlet);
1412 one.f.nodes.dashlet($dashlet);
1414 case menu.detail.id:
1415 one.f.detail.dashlet($dashlet);
1420 // activate first tab on each dashlet
1421 $('.dash .nav').each(function(index, value) {
1422 $($(value).find('li')[0]).find('a').click();