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",
59 datagrid: "one_f_nodes_id_dashlet_datagrid"
63 dashlet : function($dashlet) {
64 var $h4 = one.lib.dashlet.header("Nodes");
67 one.f.nodes.ajax.dashlet(function(data) {
68 var $gridHTML = one.lib.dashlet.datagrid.init(one.f.nodes.id.dashlet.datagrid, {
72 flexibleRowsPerPage: true
73 }, "table-striped table-condensed");
74 $dashlet.append($gridHTML);
75 var dataSource = one.f.nodes.data.nodesDataGrid(data);
76 $("#" + one.f.nodes.id.dashlet.datagrid).datagrid({dataSource: dataSource});
80 dashlet : function(callback) {
81 $.getJSON(one.f.address.root+one.f.address.flows.flows, function(data) {
87 nodesDataGrid: function(data) {
89 $.each(data, function(nodeName, flow) {
90 var nodeFlowObject = {};
91 nodeFlowObject["nodeName"] = nodeName;
92 nodeFlowObject["flows"] = flow;
93 nodeFlowObject["rowData"] = nodeName + flow + "-foobar";
94 gridData.push(nodeFlowObject);
97 var source = new StaticDataSource({
100 property: 'nodeName',
117 dashlet : function(body, callback) {
118 var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed'];
119 var $table = one.lib.dashlet.table.table(attributes);
121 var headers = ['Node', 'Flows'];
122 var $thead = one.lib.dashlet.table.header(headers);
123 $table.append($thead);
125 var $tbody = one.lib.dashlet.table.body(body);
126 $table.append($tbody);
137 dashlet : function($dashlet, details) {
138 var $h4 = one.lib.dashlet.header("Flow Details");
139 $dashlet.append($h4);
142 if (details == undefined) {
143 var $none = $(document.createElement('div'));
144 $none.addClass('none');
145 var $p = $(document.createElement('p'));
146 $p.text('Please select a flow');
147 $p.addClass('text-center').addClass('text-info');
149 $dashlet.append($none)
154 dashlet : function(data) {
159 entry.push(data['name']);
160 entry.push(data['node']);
161 entry.push(data['flow']['priority']);
162 entry.push(data['flow']['hardTimeout']);
163 entry.push(data['flow']['idleTimeout']);
169 description : function(data) {
173 entry.push(data['flow']['ingressPort']);
174 entry.push(data['flow']['etherType']);
175 entry.push(data['flow']['vlanId']);
176 entry.push(data['flow']['vlanPriority']);
177 entry.push(data['flow']['srcMac']);
178 entry.push(data['flow']['dstMac']);
179 entry.push(data['flow']['srcIp']);
180 entry.push(data['flow']['dstIp']);
181 entry.push(data['flow']['tosBits']);
182 entry.push(data['flow']['srcPort']);
183 entry.push(data['flow']['dstPort']);
184 entry.push(data['flow']['protocol']);
185 entry.push(data['flow']['cookie']);
191 actions : function(data) {
197 $(data['flow']['actions']).each(function(index, value) {
198 actions += value + ', ';
200 actions = actions.slice(0,-2);
209 dashlet : function(body) {
211 var header = ['Flow Name', 'Node', 'Priority', 'Hard Timeout', 'Idle Timeout'];
212 var $thead = one.lib.dashlet.table.header(header);
213 var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
214 var $table = one.lib.dashlet.table.table(attributes);
215 $table.append($thead);
217 var $tbody = one.lib.dashlet.table.body(body);
218 $table.append($tbody);
222 description : function(body) {
223 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'];
224 var $thead = one.lib.dashlet.table.header(header);
225 var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
226 var $table = one.lib.dashlet.table.table(attributes);
227 $table.append($thead);
229 var $tbody = one.lib.dashlet.table.body(body);
230 $table.append($tbody);
234 actions : function(body) {
235 var header = ['Actions'];
236 var $thead = one.lib.dashlet.table.header(header);
237 var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
238 var $table = one.lib.dashlet.table.table(attributes);
239 $table.append($thead);
241 var $tbody = one.lib.dashlet.table.body(body);
242 $table.append($tbody);
253 add : "one_f_flows_id_dashlet_add",
254 remove : "one_f_flows_id_dashlet_remove",
255 toggle : "one_f_flows_id_dashlet_toggle",
256 datagrid: "one_f_flows_id_dashlet_datagrid"
259 install : "one_f_flows_id_modal_install",
260 add : "one_f_flows_id_modal_add",
261 close : "one_f_flows_id_modal_close",
262 modal : "one_f_flows_id_modal_modal",
264 modal : "one_f_flows_id_modal_dialog_modal",
265 remove : "one_f_flows_id_modal_dialog_remove",
266 close : "one_f_flows_id_modal_dialog_close"
269 button : "one_f_flows_id_modal_action_button",
270 modal : "one_f_flows_id_modal_action_modal",
271 add : "one_f_flows_id_modal_action_add",
272 close : "one_f_flows_id_modal_action_close",
273 table : "one_f_flows_id_modal_action_table",
274 addOutputPorts : "one_f_flows_id_modal_action_addOutputPorts",
275 setVlanId : "one_f_flows_id_modal_action_setVlanId",
276 setVlanPriority : "one_f_flows_id_modal_action_setVlanPriority",
277 modifyDatalayerSourceAddress : "one_f_flows_id_modal_action_modifyDatalayerSourceAddress",
278 modifyDatalayerDestinationAddress : "one_f_flows_id_modal_action_modifyDatalayerDestinationAddress",
279 modifyNetworkSourceAddress : "one_f_flows_modal_action_modifyNetworkSourceAddress",
280 modifyNetworkDestinationAddress : "one_f_flows_modal_action_modifyNetworkDestinationAddress",
281 modifyTosBits : "one_f_flows_modal_action_modifyTosBits",
282 modifyTransportSourcePort : "one_f_flows_modal_action_modifyTransportSourcePort",
283 modifyTransportDestinationPort : "one_f_flows_modal_action_modifyTransportDestinationPort",
285 modal : "one_f_flows_modal_action_modal_modal",
286 remove : "one_f_flows_modal_action_modal_remove",
287 cancel : "one_f_flows_modal_action_modal_cancel"
291 name : "one_f_flows_id_modal_form_name",
292 nodes : "one_f_flows_id_modal_form_nodes",
293 port : "one_f_flows_id_modal_form_port",
294 priority : "one_f_flows_id_modal_form_priority",
295 hardTimeout : "one_f_flows_id_modal_form_hardTimeout",
296 idleTimeout : "one_f_flows_id_modal_form_idleTimeout",
297 cookie : "one_f_flows_id_modal_form_cookie",
298 etherType : "one_f_flows_id_modal_form_etherType",
299 vlanId : "one_f_flows_id_modal_form_vlanId",
300 vlanPriority : "one_f_flows_id_modal_form_vlanPriority",
301 srcMac : "one_f_flows_id_modal_form_srcMac",
302 dstMac : "one_f_flows_id_modal_form_dstMac",
303 srcIp : "one_f_flows_id_modal_form_srcIp",
304 dstIp : "one_f_flows_id_modal_form_dstIp",
305 tosBits : "one_f_flows_id_modal_form_tosBits",
306 srcPort : "one_f_flows_id_modal_form_srcPort",
307 dstPort : "one_f_flows_id_modal_form_dstPort",
308 protocol : "one_f_flows_id_modal_form_protocol"
313 dashlet : function($dashlet, callback) {
316 one.f.flows.ajax.dashlet(function(data) {
318 var $h4 = one.lib.dashlet.header("Flow Entries");
320 $dashlet.append($h4);
321 if (one.f.flows.registry.privilege === 'WRITE') {
322 var button = one.lib.dashlet.button.single("Add Flow Entry", one.f.flows.id.dashlet.add, "btn-primary", "btn-mini");
323 var $button = one.lib.dashlet.button.button(button);
325 $button.click(function() {
326 var $modal = one.f.flows.modal.initialize();
329 $dashlet.append($button);
333 var $gridHTML = one.lib.dashlet.datagrid.init(one.f.flows.id.dashlet.datagrid, {
337 flexibleRowsPerPage: true
338 }, "table-striped table-condensed");
339 $dashlet.append($gridHTML);
340 var dataSource = one.f.flows.data.flowsDataGrid(data);
341 $("#" + one.f.flows.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
342 $("#" + one.f.flows.id.dashlet.datagrid).find("tbody tr").each(function(index, tr) {
344 $span = $("td span", $tr);
345 var flowstatus = $span.data("flowstatus");
346 if($span.data("installinhw") != null) {
347 var installInHw = $span.data("installinhw").toString();
348 if(installInHw == "true" && flowstatus == "Success") {
349 $tr.addClass("success");
351 $tr.addClass("warning");
354 // attach mouseover to show pointer cursor
355 $tr.mouseover(function() {
356 $(this).css("cursor", "pointer");
358 // attach click event
359 $tr.click(function() {
360 var $td = $($(this).find("td")[0]);
362 var node = $td.find("span").data("nodeid");
363 one.f.flows.detail(id, node);
369 if(callback != undefined) callback();
372 detail : function(id, node) {
373 // clear flow details
374 var $detailDashlet = one.main.dashlet.right.bottom;
375 $detailDashlet.empty();
376 var $h4 = one.lib.dashlet.header("Flow Overview");
377 $detailDashlet.append($h4);
380 var flows = one.f.flows.registry.flows;
382 $(flows).each(function(index, value) {
383 if (value['name'] == id) {
387 if (one.f.flows.registry.privilege === 'WRITE') {
389 var button = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.dashlet.remove, "btn-danger", "btn-mini");
390 var $button = one.lib.dashlet.button.button(button);
391 $button.click(function() {
392 var $modal = one.f.flows.modal.dialog.initialize(id, node);
397 if (flow['flow']['installInHw'] == 'true' && flow['flow']['status'] == 'Success') {
398 toggle = one.lib.dashlet.button.single("Uninstall Flow", one.f.flows.id.dashlet.toggle, "btn-warning", "btn-mini");
400 toggle = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.dashlet.toggle, "btn-success", "btn-mini");
402 var $toggle = one.lib.dashlet.button.button(toggle);
403 $toggle.click(function() {
404 one.f.flows.modal.ajax.toggleflow(id, node, function(data) {
405 if(data == "Success") {
406 one.main.dashlet.right.bottom.empty();
407 one.f.detail.dashlet(one.main.dashlet.right.bottom);
408 one.main.dashlet.left.top.empty();
409 one.f.flows.dashlet(one.main.dashlet.left.top, function() {
410 // checks are backwards due to stale registry
411 if(flow['flow']['installInHw'] == 'true') {
412 one.lib.alert('Uninstalled Flow');
414 one.lib.alert('Installed Flow');
416 one.f.flows.detail(id, node)
419 one.lib.alert('Cannot toggle flow: '+data);
424 $detailDashlet.append($button).append($toggle);
427 var body = one.f.detail.data.dashlet(flow);
428 var $body = one.f.detail.body.dashlet(body);
429 $detailDashlet.append($body);
430 var body = one.f.detail.data.description(flow);
431 var $body = one.f.detail.body.description(body);
432 $detailDashlet.append($body);
433 var body = one.f.detail.data.actions(flow);
434 var $body = one.f.detail.body.actions(body);
435 $detailDashlet.append($body);
439 initialize : function(id, node) {
440 var h3 = "Remove Flow?";
441 var $p = one.f.flows.modal.dialog.body(id);
442 var footer = one.f.flows.modal.dialog.footer();
443 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $p, footer);
444 $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() {
445 $modal.modal('hide');
447 $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(function() {
448 one.f.flows.modal.ajax.removeflow(id, node, function(data) {
449 if (data == "Success") {
450 $modal.modal('hide');
451 one.main.dashlet.right.bottom.empty();
452 one.f.detail.dashlet(one.main.dashlet.right.bottom);
453 one.main.dashlet.left.top.empty();
454 one.f.flows.dashlet(one.main.dashlet.left.top);
455 one.lib.alert('Flow removed');
457 one.lib.alert('Cannot remove flow: '+data);
463 footer : function() {
466 var removeButton = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.modal.dialog.remove, "btn-danger", "");
467 var $removeButton = one.lib.dashlet.button.button(removeButton);
468 footer.push($removeButton);
470 var closeButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.dialog.close, "", "");
471 var $closeButton = one.lib.dashlet.button.button(closeButton);
472 footer.push($closeButton);
476 body : function(id) {
477 var $p = $(document.createElement('p'));
478 $p.append('Remove flow '+id+'?');
482 initialize : function() {
483 var h3 = "Add Flow Entry";
484 var footer = one.f.flows.modal.footer();
485 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.modal, h3, "", footer);
488 $('#'+one.f.flows.id.modal.close, $modal).click(function() {
489 $modal.modal('hide');
492 // bind add flow button
493 $('#'+one.f.flows.id.modal.add, $modal).click(function() {
494 one.f.flows.modal.add($modal, 'false');
497 // bind install flow button
498 $('#'+one.f.flows.id.modal.install, $modal).click(function() {
499 one.f.flows.modal.add($modal, 'true');
502 // inject body (nodePorts)
503 one.f.flows.modal.ajax.nodes(function(nodes, nodeports) {
504 var $body = one.f.flows.modal.body(nodes, nodeports);
505 one.lib.modal.inject.body($modal, $body);
510 add : function($modal, install) {
513 result['name'] = $('#'+one.f.flows.id.modal.form.name, $modal).val();
514 result['ingressPort'] = $('#'+one.f.flows.id.modal.form.port, $modal).val();
515 result['priority'] = $('#'+one.f.flows.id.modal.form.priority, $modal).val();
516 result['hardTimeout'] = $('#'+one.f.flows.id.modal.form.hardTimeout, $modal).val();
517 result['idleTimeout'] = $('#'+one.f.flows.id.modal.form.idleTimeout, $modal).val();
518 result['cookie'] = $('#'+one.f.flows.id.modal.form.cookie, $modal).val();
519 result['etherType'] = $('#'+one.f.flows.id.modal.form.etherType, $modal).val();
520 result['vlanId'] = $('#'+one.f.flows.id.modal.form.vlanId, $modal).val();
521 result['vlanPriority'] = $('#'+one.f.flows.id.modal.form.vlanPriority, $modal).val();
522 result['dlSrc'] = $('#'+one.f.flows.id.modal.form.srcMac, $modal).val();
523 result['dlDst'] = $('#'+one.f.flows.id.modal.form.dstMac, $modal).val();
524 result['nwSrc'] = $('#'+one.f.flows.id.modal.form.srcIp, $modal).val();
525 result['nwDst'] = $('#'+one.f.flows.id.modal.form.dstIp, $modal).val();
526 result['tosBits'] = $('#'+one.f.flows.id.modal.form.tosBits, $modal).val();
527 result['tpSrc'] = $('#'+one.f.flows.id.modal.form.srcPort, $modal).val();
528 result['tpDst'] = $('#'+one.f.flows.id.modal.form.dstPort, $modal).val();
529 result['protocol'] = $('#'+one.f.flows.id.modal.form.protocol, $modal).val();
531 result['installInHw'] = install;
533 var nodeId = $('#'+one.f.flows.id.modal.form.nodes, $modal).val();
535 $.each(result, function(key, value) {
536 if (value == "") delete result[key];
540 var $table = $('#'+one.f.flows.id.modal.action.table, $modal);
541 $($table.find('tbody').find('tr')).each(function(index, value) {
542 if (!$(this).find('td').hasClass('empty')) {
543 action.push($(value).data('action'));
546 result['actions'] = action;
548 // frontend validation
549 if (result['name'] == undefined) {
550 alert('Need flow name');
554 alert('Select node');
557 if (action.length == 0) {
558 alert('Please specify an action');
562 // package for ajax call
564 resource['body'] = JSON.stringify(result);
565 resource['action'] = 'add';
566 resource['nodeId'] = nodeId;
568 one.f.flows.modal.ajax.saveflow(resource, function(data) {
569 if (data == "Success") {
570 $modal.modal('hide');
571 one.lib.alert('Flow added');
572 one.main.dashlet.left.top.empty();
573 one.f.flows.dashlet(one.main.dashlet.left.top);
575 alert('Could not add flow: '+data);
580 nodes : function(successCallback) {
581 $.getJSON(one.f.address.root+one.f.address.flows.nodes, function(data) {
582 var nodes = one.f.flows.modal.data.nodes(data);
583 var nodeports = data;
584 one.f.flows.registry['nodeports'] = nodeports;
586 successCallback(nodes, nodeports);
589 saveflow : function(resource, callback) {
590 $.post(one.f.address.root+one.f.address.flows.flow, resource, function(data) {
594 removeflow : function(id, node, callback) {
596 resource['action'] = 'remove';
597 $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
601 toggleflow : function(id, node, callback) {
603 resource['action'] = 'toggle';
604 $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
610 nodes : function(data) {
612 $.each(data, function(key, value) {
613 result[key] = value['name'];
618 body : function(nodes, nodeports) {
619 var $form = $(document.createElement('form'));
620 var $fieldset = $(document.createElement('fieldset'));
622 var $legend = one.lib.form.legend("Flow Description");
623 $fieldset.append($legend);
625 var $label = one.lib.form.label("Name");
626 var $input = one.lib.form.input("Flow Name");
627 $input.attr('id', one.f.flows.id.modal.form.name);
628 $fieldset.append($label).append($input);
630 var $label = one.lib.form.label("Node");
631 var $select = one.lib.form.select.create(nodes);
632 one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
633 $select.val($select.find("option:first").val());
634 $select.attr('id', one.f.flows.id.modal.form.nodes);
637 $select.change(function() {
638 // retrieve port value
639 var node = $(this).find('option:selected').attr('value');
640 var $ports = $('#'+one.f.flows.id.modal.form.port);
642 one.lib.form.select.inject($ports, {});
645 one.f.flows.registry['currentNode'] = node;
646 var ports = nodeports[node]['ports'];
647 one.lib.form.select.inject($ports, ports);
648 one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
649 $ports.val($ports.find("option:first").val());
652 $fieldset.append($label).append($select);
654 var $label = one.lib.form.label("Input Port");
655 var $select = one.lib.form.select.create();
656 $select.attr('id', one.f.flows.id.modal.form.port);
657 $fieldset.append($label).append($select);
659 var $label = one.lib.form.label("Priority");
660 var $input = one.lib.form.input("Priority");
661 $input.attr('id', one.f.flows.id.modal.form.priority);
663 $fieldset.append($label).append($input);
665 var $label = one.lib.form.label("Hard Timeout");
666 var $input = one.lib.form.input("Hard Timeout");
667 $input.attr('id', one.f.flows.id.modal.form.hardTimeout);
668 $fieldset.append($label).append($input);
670 var $label = one.lib.form.label("Idle Timeout");
671 var $input = one.lib.form.input("Idle Timeout");
672 $input.attr('id', one.f.flows.id.modal.form.idleTimeout);
673 $fieldset.append($label).append($input);
675 var $label = one.lib.form.label("Cookie");
676 var $input = one.lib.form.input("Cookie");
677 $input.attr('id', one.f.flows.id.modal.form.cookie);
678 $fieldset.append($label).append($input);
680 var $legend = one.lib.form.legend("Layer 2");
681 $fieldset.append($legend);
683 var $label = one.lib.form.label("Ethernet Type");
684 var $input = one.lib.form.input("Ethernet Type");
685 $input.attr('id', one.f.flows.id.modal.form.etherType);
687 $fieldset.append($label).append($input);
689 var $label = one.lib.form.label("VLAN Identification Number");
690 var $input = one.lib.form.input("VLAN Identification Number");
691 $input.attr('id', one.f.flows.id.modal.form.vlanId);
692 var $help = one.lib.form.help("Range: 0 - 4095");
693 $fieldset.append($label).append($input).append($help);
695 var $label = one.lib.form.label("VLAN Priority");
696 var $input = one.lib.form.input("VLAN Priority");
697 $input.attr('id', one.f.flows.id.modal.form.vlanPriority);
698 var $help = one.lib.form.help("Range: 0 - 7");
699 $fieldset.append($label).append($input).append($help);
701 var $label = one.lib.form.label("Source MAC Address");
702 var $input = one.lib.form.input("Source MAC Address");
703 $input.attr('id', one.f.flows.id.modal.form.srcMac);
704 var $help = one.lib.form.help("Example: 00:11:22:aa:bb:cc");
705 $fieldset.append($label).append($input).append($help);
707 var $label = one.lib.form.label("Destination MAC Address");
708 var $input = one.lib.form.input("Destination MAC Address");
709 $input.attr('id', one.f.flows.id.modal.form.dstMac);
710 var $help = one.lib.form.help("Example: 00:11:22:aa:bb:cc");
711 $fieldset.append($label).append($input).append($help);
713 var $legend = one.lib.form.legend("Layer 3");
714 $fieldset.append($legend);
716 var $label = one.lib.form.label("Source IP Address");
717 var $input = one.lib.form.input("Source IP Address");
718 $input.attr('id', one.f.flows.id.modal.form.srcIp);
719 var $help = one.lib.form.help("Example: 127.0.0.1");
720 $fieldset.append($label).append($input).append($help);
722 var $label = one.lib.form.label("Destination IP Address");
723 var $input = one.lib.form.input("Destination IP Address");
724 $input.attr('id', one.f.flows.id.modal.form.dstIp);
725 var $help = one.lib.form.help("Example: 127.0.0.1");
726 $fieldset.append($label).append($input).append($help);
728 var $label = one.lib.form.label("TOS Bits");
729 var $input = one.lib.form.input("TOS Bits");
730 $input.attr('id', one.f.flows.id.modal.form.tosBits);
731 var $help = one.lib.form.help("Range: 0 - 63");
732 $fieldset.append($label).append($input).append($help);
734 var $legend = one.lib.form.legend("Layer 4");
735 $fieldset.append($legend);
737 var $label = one.lib.form.label("Source Port");
738 var $input = one.lib.form.input("Source Port");
739 $input.attr('id', one.f.flows.id.modal.form.srcPort);
740 var $help = one.lib.form.help("Range: 0 - 65535");
741 $fieldset.append($label).append($input).append($help);
743 var $label = one.lib.form.label("Destination Port");
744 var $input = one.lib.form.input("Destination Port");
745 $input.attr('id', one.f.flows.id.modal.form.dstPort);
746 var $help = one.lib.form.help("Range: 0 - 65535");
747 $fieldset.append($label).append($input).append($help);
749 var $label = one.lib.form.label("Protocol");
750 var $input = one.lib.form.input("Protocol");
751 $input.attr('id', one.f.flows.id.modal.form.protocol);
752 $fieldset.append($label).append($input);
754 var $legend = one.lib.form.label("Actions");
755 $fieldset.append($legend);
757 var tableAttributes = ["table-striped", "table-bordered", "table-condensed", "table-hover", "table-cursor"];
758 var $table = one.lib.dashlet.table.table(tableAttributes);
759 $table.attr('id', one.f.flows.id.modal.action.table);
760 var tableHeaders = ["Action", "Data", "Type"];
761 var $thead = one.lib.dashlet.table.header(tableHeaders);
762 var $tbody = one.lib.dashlet.table.body("", tableHeaders);
763 $table.append($thead).append($tbody);
766 "" : "Please Select an Action",
768 "loopback" : "Loopback",
770 "softwarePath" : "Software Path",
771 "hardwarePath" : "Hardware Path",
772 "controller" : "Controller",
773 "addOutputPorts" : "Add Output Ports",
774 "setVlanId" : "Set VLAN ID",
775 "setVlanPriority" : "Set VLAN Priority",
776 "stripVlanHeader" : "Strip VLAN Header",
777 "modifyDatalayerSourceAddress" : "Modify Datalayer Source Address",
778 "modifyDatalayerDestinationAddress" : "Modify Datalayer Destination Address",
779 "modifyNetworkSourceAddress" : "Modify Network Source Address",
780 "modifyNetworkDestinationAddress" :"Modify Network Destination Address",
781 "modifyTosBits" : "Modify TOS Bits",
782 "modifyTransportSourcePort" : "Modify Transport Source Port",
783 "modifyTransportDestinationPort" : "Modify Transport Destination Port"
785 var $select = one.lib.form.select.create(actions);
786 // when selecting an action
787 $select.change(function() {
788 var action = $(this).find('option:selected');
789 one.f.flows.modal.action.parse(action.attr('value'));
790 $select[0].selectedIndex = 0;
793 $fieldset.append($select).append($table);
796 $form.append($fieldset);
800 parse : function(option) {
802 case "addOutputPorts" :
803 var h3 = "Add Output Port";
804 var $modal = one.f.flows.modal.action.initialize(h3, one.f.flows.modal.action.body.addOutputPorts, one.f.flows.modal.action.add.addOutputPorts);
808 var h3 = "Set VLAN ID";
809 var placeholder = "VLAN Identification Number";
810 var id = one.f.flows.id.modal.action.setVlanId;
811 var help = "Range: 0 - 4095";
812 var action = 'SET_VLAN_ID';
813 var name = "VLAN ID";
814 var body = function() {
815 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
817 var add = function($modal) {
818 one.f.flows.modal.action.add.set(name, id, action, $modal);
820 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
823 case "setVlanPriority" :
824 var h3 = "Set VLAN Priority";
825 var placeholder = "VLAN Priority";
826 var id = one.f.flows.id.modal.action.setVlanPriority;
827 var help = "Range: 0 - 7";
828 var action = 'SET_VLAN_PCP';
829 var name = "VLAN Priority";
830 var body = function() {
831 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
833 var add = function($modal) {
834 one.f.flows.modal.action.add.set(name, id, action, $modal);
836 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
839 case "stripVlanHeader" :
840 var name = "Strip VLAN Header";
841 var action = 'POP_VLAN';
842 one.f.flows.modal.action.add.add(name, action);
844 case "modifyDatalayerSourceAddress" :
845 var h3 = "Set Source MAC Address";
846 var placeholder = "Source MAC Address";
847 var id = one.f.flows.id.modal.action.modifyDatalayerSourceAddress;
848 var help = "Example: 00:11:22:aa:bb:cc";
849 var action = 'SET_DL_SRC';
850 var name = "Source MAC";
851 var body = function() {
852 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
854 var add = function($modal) {
855 one.f.flows.modal.action.add.set(name, id, action, $modal);
857 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
860 case "modifyDatalayerDestinationAddress" :
861 var h3 = "Set Destination MAC Address";
862 var placeholder = "Destination MAC Address";
863 var id = one.f.flows.id.modal.action.modifyDatalayerDestinationAddress;
864 var help = "Example: 00:11:22:aa:bb:cc";
865 var action = 'SET_DL_DST';
866 var name = "Destination MAC";
867 var body = function() {
868 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
870 var add = function($modal) {
871 one.f.flows.modal.action.add.set(name, id, action, $modal);
873 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
876 case "modifyNetworkSourceAddress" :
877 var h3 = "Set IP Source Address";
878 var placeholder = "Source IP Address";
879 var id = one.f.flows.id.modal.action.modifyNetworkSourceAddress;
880 var help = "Example: 127.0.0.1";
881 var action = 'SET_NW_SRC';
882 var name = "Source IP";
883 var body = function() {
884 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
886 var add = function($modal) {
887 one.f.flows.modal.action.add.set(name, id, action, $modal);
889 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
892 case "modifyNetworkDestinationAddress" :
893 var h3 = "Set IP Destination Address";
894 var placeholder = "Destination IP Address";
895 var id = one.f.flows.id.modal.action.modifyNetworkDestinationAddress;
896 var help = "Example: 127.0.0.1";
897 var action = 'SET_NW_DST';
898 var name = "Destination IP";
899 var body = function() {
900 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
902 var add = function($modal) {
903 one.f.flows.modal.action.add.set(name, id, action, $modal);
905 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
908 case "modifyTosBits" :
909 var h3 = "Set IPv4 ToS";
910 var placeholder = "IPv4 ToS";
911 var id = one.f.flows.id.modal.action.modifyTosBits;
912 var help = "Range: 0 - 63";
913 var action = 'SET_NW_TOS';
914 var name = "TOS Bits";
915 var body = function() {
916 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
918 var add = function($modal) {
919 one.f.flows.modal.action.add.set(name, id, action, $modal);
921 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
924 case "modifyTransportSourcePort" :
925 var h3 = "Set Transport Source Port";
926 var placeholder = "Transport Source Port";
927 var id = one.f.flows.id.modal.action.modifyTransportSourcePort;
928 var help = "Range: 1 - 65535";
929 var action = 'SET_TP_SRC';
930 var name = "Source Port";
931 var body = function() {
932 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
934 var add = function($modal) {
935 one.f.flows.modal.action.add.set(name, id, action, $modal);
937 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
940 case "modifyTransportDestinationPort" :
941 var h3 = "Set Transport Destination Port";
942 var placeholder = "Transport Destination Port";
943 var id = one.f.flows.id.modal.action.modifyTransportDestinationPort;
944 var help = "Range: 1 - 65535";
945 var action = 'SET_TP_DST';
946 var name = "Destination Port";
947 var body = function() {
948 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
950 var add = function($modal) {
951 one.f.flows.modal.action.add.set(name, id, action, $modal);
953 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
959 one.f.flows.modal.action.add.add(name, action);
962 var name = "Loopback";
963 var action = 'LOOPBACK';
964 one.f.flows.modal.action.add.add(name, action);
968 var action = 'FLOOD';
969 one.f.flows.modal.action.add.add(name, action);
971 case "softwarePath" :
972 var name = "Software Path";
973 var action = 'SW_PATH';
974 one.f.flows.modal.action.add.add(name, action);
976 case "hardwarePath" :
977 var name = "Hardware Path";
978 var action = 'HW_PATH';
979 one.f.flows.modal.action.add.add(name, action);
982 var name = "Controller";
983 var action = 'CONTROLLER';
984 one.f.flows.modal.action.add.add(name, action);
988 initialize : function(h3, bodyCallback, addCallback) {
989 var footer = one.f.flows.modal.action.footer();
990 var $body = bodyCallback();
991 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal, h3, $body, footer);
993 $('#'+one.f.flows.id.modal.action.close, $modal).click(function() {
994 $modal.modal('hide');
996 // bind add flow button
997 $('#'+one.f.flows.id.modal.action.add, $modal).click(function() {
1003 addOutputPorts : function($modal) {
1004 var $options = $('#'+one.f.flows.id.modal.action.addOutputPorts).find('option:selected');
1007 $options.each(function(index, value) {
1008 ports = ports+$(value).text()+", ";
1009 pid = pid+$(value).attr('value')+",";
1011 ports = ports.slice(0,-2);
1012 pid = pid.slice(0,-1);
1013 var $tr = one.f.flows.modal.action.table.add("Add Output Ports", ports);
1014 $tr.attr('id', 'addOutputPorts');
1015 $tr.data('action', 'OUTPUT='+pid);
1016 $tr.click(function() {
1017 one.f.flows.modal.action.add.modal.initialize(this);
1019 one.f.flows.modal.action.table.append($tr);
1020 $modal.modal('hide');
1022 add : function(name, action) {
1023 var $tr = one.f.flows.modal.action.table.add(name);
1024 $tr.attr('id', action);
1025 $tr.data('action', action);
1026 $tr.click(function() {
1027 one.f.flows.modal.action.add.modal.initialize(this);
1029 one.f.flows.modal.action.table.append($tr);
1031 set : function(name, id, action, $modal) {
1032 var $input = $('#'+id);
1033 var value = $input.val();
1034 var $tr = one.f.flows.modal.action.table.add(name, value);
1035 $tr.attr('id', action);
1036 $tr.data('action', action+'='+value);
1037 $tr.click(function() {
1038 one.f.flows.modal.action.add.modal.initialize(this);
1040 one.f.flows.modal.action.table.append($tr);
1041 $modal.modal('hide');
1043 remove : function(that) {
1045 var $table = $('#'+one.f.flows.id.modal.action.table);
1046 if ($table.find('tbody').find('tr').size() == 0) {
1047 var $tr = $(document.createElement('tr'));
1048 var $td = $(document.createElement('td'));
1049 $td.attr('colspan', '3');
1050 $tr.addClass('empty');
1051 $td.text('No data available');
1053 $table.find('tbody').append($tr);
1057 initialize : function(that) {
1058 var h3 = "Remove Action";
1059 var footer = one.f.flows.modal.action.add.modal.footer();
1060 var $body = one.f.flows.modal.action.add.modal.body();
1061 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal.modal, h3, $body, footer);
1063 // bind cancel button
1064 $('#'+one.f.flows.id.modal.action.modal.cancel, $modal).click(function() {
1065 $modal.modal('hide');
1068 // bind remove button
1069 $('#'+one.f.flows.id.modal.action.modal.remove, $modal).click(function() {
1070 one.f.flows.modal.action.add.remove(that);
1071 $modal.modal('hide');
1077 var $p = $(document.createElement('p'));
1078 $p.append("Remove this action?");
1081 footer : function() {
1084 var removeButton = one.lib.dashlet.button.single("Remove Action", one.f.flows.id.modal.action.modal.remove, "btn-danger", "");
1085 var $removeButton = one.lib.dashlet.button.button(removeButton);
1086 footer.push($removeButton);
1088 var cancelButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.action.modal.cancel, "", "");
1089 var $cancelButton = one.lib.dashlet.button.button(cancelButton);
1090 footer.push($cancelButton);
1097 add : function(action, data, type) {
1098 var $tr = $(document.createElement('tr'));
1099 var $td = $(document.createElement('td'));
1102 var $td = $(document.createElement('td'));
1103 if (data != undefined) $td.append(data);
1105 var $td = $(document.createElement('td'));
1106 if (type != undefined) $td.append(type);
1110 append : function($tr) {
1111 var $table = $('#'+one.f.flows.id.modal.action.table);
1112 var $empty = $table.find('.empty').parent();
1113 if ($empty.size() > 0) $empty.remove();
1118 common : function() {
1119 var $form = $(document.createElement('form'));
1120 var $fieldset = $(document.createElement('fieldset'));
1121 return [$form, $fieldset];
1123 addOutputPorts : function() {
1124 var common = one.f.flows.modal.action.body.common();
1125 var $form = common[0];
1126 var $fieldset = common[1];
1128 $label = one.lib.form.label("Select Output Ports");
1129 var ports = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports'];
1130 $select = one.lib.form.select.create(ports, true);
1131 $select.attr('id', one.f.flows.id.modal.action.addOutputPorts);
1132 one.lib.form.select.prepend($select, {'':'Select a Port'});
1133 $fieldset.append($label).append($select);
1134 $form.append($fieldset);
1137 set : function(label, placeholder, id, help) {
1138 var common = one.f.flows.modal.action.body.common();
1139 var $form = common[0];
1140 var $fieldset = common[1];
1142 $label = one.lib.form.label(label);
1143 $input = one.lib.form.input(placeholder);
1144 $input.attr('id', id);
1145 $help = one.lib.form.help(help);
1147 $fieldset.append($label).append($input).append($help);
1148 $form.append($fieldset);
1152 footer : function() {
1154 var addButton = one.lib.dashlet.button.single("Add Action", one.f.flows.id.modal.action.add, "btn-primary", "");
1155 var $addButton = one.lib.dashlet.button.button(addButton);
1156 footer.push($addButton);
1158 var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.action.close, "", "");
1159 var $closeButton = one.lib.dashlet.button.button(closeButton);
1160 footer.push($closeButton);
1165 footer : function() {
1168 var installButton = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.modal.install, "btn-success", "");
1169 var $installButton = one.lib.dashlet.button.button(installButton);
1170 footer.push($installButton);
1172 var addButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.add, "btn-primary", "");
1173 var $addButton = one.lib.dashlet.button.button(addButton);
1174 footer.push($addButton);
1176 var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", "");
1177 var $closeButton = one.lib.dashlet.button.button(closeButton);
1178 footer.push($closeButton);
1184 dashlet : function(callback) {
1185 $.getJSON(one.f.address.root+one.f.address.flows.main, function(data) {
1186 one.f.flows.registry['flows'] = data.flows;
1187 one.f.flows.registry['privilege'] = data.privilege;
1193 flowsDataGrid: function(data) {
1194 var source = new StaticDataSource({
1208 formatter: function(items) {
1209 $.each(items, function(index, item) {
1210 item["name"] = '<span data-installInHw=' + item["flow"]["installInHw"] +
1211 ' data-flowstatus=' + item["flow"]["status"] +
1212 ' data-nodeId=' + item["nodeId"] + '>' + item["name"] + '</span>';
1220 dashlet : function(data) {
1222 $(data).each(function(index, value) {
1225 entry.push(value['name']);
1226 entry.push(value['node']);
1227 if (value['flow']['installInHw'] == 'true' && value['flow']['status'] == 'Success')
1228 tr['type'] = ['success'];
1229 else if (value['flow']['installInHw'] == 'false' && value['flow']['status'] == 'Success')
1230 tr['type'] = ['warning'];
1232 tr['type'] = ['warning'];
1233 tr['entry'] = entry;
1234 tr['id'] = value['nodeId'];
1242 dashlet : function(body, callback) {
1243 var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed', 'table-cursor'];
1244 var $table = one.lib.dashlet.table.table(attributes);
1246 var headers = ['Flow Name', 'Node'];
1247 var $thead = one.lib.dashlet.table.header(headers);
1248 $table.append($thead);
1250 var $tbody = one.lib.dashlet.table.body(body);
1251 $table.append($tbody);
1259 // populate nav tabs
1260 $(one.f.menu.left.top).each(function(index, value) {
1261 var $nav = $(".nav", "#left-top");
1262 one.main.page.dashlet($nav, value);
1265 $(one.f.menu.left.bottom).each(function(index, value) {
1266 var $nav = $(".nav", "#left-bottom");
1267 one.main.page.dashlet($nav, value);
1270 $(one.f.menu.right.bottom).each(function(index, value) {
1271 var $nav = $(".nav", "#right-bottom");
1272 one.main.page.dashlet($nav, value);
1275 one.f.populate = function($dashlet, header) {
1276 var $h4 = one.lib.dashlet.header(header);
1277 $dashlet.append($h4);
1281 $('.dash .nav a', '#main').click(function() {
1283 var $li = $(this).parent();
1284 var $ul = $li.parent();
1285 one.lib.nav.unfocus($ul);
1286 $li.addClass('active');
1287 // clear respective dashlet
1288 var $dashlet = $ul.parent().find('.dashlet');
1289 one.lib.dashlet.empty($dashlet);
1290 // callback based on menu
1291 var id = $(this).attr('id');
1292 var menu = one.f.dashlet;
1295 one.f.flows.dashlet($dashlet);
1298 one.f.nodes.dashlet($dashlet);
1300 case menu.detail.id:
1301 one.f.detail.dashlet($dashlet);
1306 // activate first tab on each dashlet
1307 $('.dash .nav').each(function(index, value) {
1308 $($(value).find('li')[0]).find('a').click();