3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
13 // specify dashlets and layouts
47 root : "/controller/web/flows",
50 flows : "/node-flows",
51 nodes : "/node-ports",
60 dashlet : function($dashlet) {
61 var $h4 = one.lib.dashlet.header("Nodes");
65 one.f.nodes.ajax.dashlet(function($table) {
67 var nodeCount = $table.find('tbody').find('tr').size();
69 var nodeText = "node";
75 var out = "There "+verb+" "+nodeCount+" "+nodeText;
76 $p = $(document.createElement('p'));
80 $dashlet.append($table);
84 dashlet : function(callback) {
85 $.getJSON(one.f.address.root+one.f.address.flows.flows, function(data) {
86 var body = one.f.nodes.data.dashlet(data);
87 var $body = one.f.nodes.body.dashlet(body, callback);
93 dashlet : function(data) {
95 $.each(data, function(key, value) {
109 dashlet : function(body, callback) {
110 var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed'];
111 var $table = one.lib.dashlet.table.table(attributes);
113 var headers = ['Node', 'Flows'];
114 var $thead = one.lib.dashlet.table.header(headers);
115 $table.append($thead);
117 var $tbody = one.lib.dashlet.table.body(body);
118 $table.append($tbody);
129 dashlet : function($dashlet, details) {
130 var $h4 = one.lib.dashlet.header("Flow Details");
131 $dashlet.append($h4);
134 if (details == undefined) {
135 var $none = $(document.createElement('div'));
136 $none.addClass('none');
137 var $p = $(document.createElement('p'));
138 $p.text('Please select a flow');
139 $p.addClass('text-center').addClass('text-info');
141 $dashlet.append($none)
146 dashlet : function(data) {
151 entry.push(data['name']);
152 entry.push(data['node']);
153 entry.push(data['flow']['priority']);
154 entry.push(data['flow']['hardTimeout']);
155 entry.push(data['flow']['idleTimeout']);
161 description : function(data) {
165 entry.push(data['flow']['ingressPort']);
166 entry.push(data['flow']['etherType']);
167 entry.push(data['flow']['vlanId']);
168 entry.push(data['flow']['vlanPriority']);
169 entry.push(data['flow']['srcMac']);
170 entry.push(data['flow']['dstMac']);
171 entry.push(data['flow']['srcIp']);
172 entry.push(data['flow']['dstIp']);
173 entry.push(data['flow']['tosBits']);
174 entry.push(data['flow']['srcPort']);
175 entry.push(data['flow']['dstPort']);
176 entry.push(data['flow']['protocol']);
177 entry.push(data['flow']['cookie']);
183 actions : function(data) {
189 $(data['flow']['actions']).each(function(index, value) {
190 actions += value + ', ';
192 actions = actions.slice(0,-2);
201 dashlet : function(body) {
203 var header = ['Flow Name', 'Node', 'Priority', 'Hard Timeout', 'Idle Timeout'];
204 var $thead = one.lib.dashlet.table.header(header);
205 var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
206 var $table = one.lib.dashlet.table.table(attributes);
207 $table.append($thead);
209 var $tbody = one.lib.dashlet.table.body(body);
210 $table.append($tbody);
214 description : function(body) {
215 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'];
216 var $thead = one.lib.dashlet.table.header(header);
217 var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
218 var $table = one.lib.dashlet.table.table(attributes);
219 $table.append($thead);
221 var $tbody = one.lib.dashlet.table.body(body);
222 $table.append($tbody);
226 actions : function(body) {
227 var header = ['Actions'];
228 var $thead = one.lib.dashlet.table.header(header);
229 var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
230 var $table = one.lib.dashlet.table.table(attributes);
231 $table.append($thead);
233 var $tbody = one.lib.dashlet.table.body(body);
234 $table.append($tbody);
245 add : "one_f_flows_id_dashlet_add",
246 remove : "one_f_flows_id_dashlet_remove",
247 toggle : "one_f_flows_id_dashlet_toggle"
250 install : "one_f_flows_id_modal_install",
251 add : "one_f_flows_id_modal_add",
252 close : "one_f_flows_id_modal_close",
253 modal : "one_f_flows_id_modal_modal",
255 modal : "one_f_flows_id_modal_dialog_modal",
256 remove : "one_f_flows_id_modal_dialog_remove",
257 close : "one_f_flows_id_modal_dialog_close"
260 button : "one_f_flows_id_modal_action_button",
261 modal : "one_f_flows_id_modal_action_modal",
262 add : "one_f_flows_id_modal_action_add",
263 close : "one_f_flows_id_modal_action_close",
264 table : "one_f_flows_id_modal_action_table",
265 addOutputPorts : "one_f_flows_id_modal_action_addOutputPorts",
266 setVlanId : "one_f_flows_id_modal_action_setVlanId",
267 setVlanPriority : "one_f_flows_id_modal_action_setVlanPriority",
268 modifyDatalayerSourceAddress : "one_f_flows_id_modal_action_modifyDatalayerSourceAddress",
269 modifyDatalayerDestinationAddress : "one_f_flows_id_modal_action_modifyDatalayerDestinationAddress",
270 modifyNetworkSourceAddress : "one_f_flows_modal_action_modifyNetworkSourceAddress",
271 modifyNetworkDestinationAddress : "one_f_flows_modal_action_modifyNetworkDestinationAddress",
272 modifyTosBits : "one_f_flows_modal_action_modifyTosBits",
273 modifyTransportSourcePort : "one_f_flows_modal_action_modifyTransportSourcePort",
274 modifyTransportDestinationPort : "one_f_flows_modal_action_modifyTransportDestinationPort",
276 modal : "one_f_flows_modal_action_modal_modal",
277 remove : "one_f_flows_modal_action_modal_remove",
278 cancel : "one_f_flows_modal_action_modal_cancel"
282 name : "one_f_flows_id_modal_form_name",
283 nodes : "one_f_flows_id_modal_form_nodes",
284 port : "one_f_flows_id_modal_form_port",
285 priority : "one_f_flows_id_modal_form_priority",
286 hardTimeout : "one_f_flows_id_modal_form_hardTimeout",
287 idleTimeout : "one_f_flows_id_modal_form_idleTimeout",
288 cookie : "one_f_flows_id_modal_form_cookie",
289 etherType : "one_f_flows_id_modal_form_etherType",
290 vlanId : "one_f_flows_id_modal_form_vlanId",
291 vlanPriority : "one_f_flows_id_modal_form_vlanPriority",
292 srcMac : "one_f_flows_id_modal_form_srcMac",
293 dstMac : "one_f_flows_id_modal_form_dstMac",
294 srcIp : "one_f_flows_id_modal_form_srcIp",
295 dstIp : "one_f_flows_id_modal_form_dstIp",
296 tosBits : "one_f_flows_id_modal_form_tosBits",
297 srcPort : "one_f_flows_id_modal_form_srcPort",
298 dstPort : "one_f_flows_id_modal_form_dstPort",
299 protocol : "one_f_flows_id_modal_form_protocol"
304 dashlet : function($dashlet, callback) {
307 one.f.flows.ajax.dashlet(function($table) {
309 var $h4 = one.lib.dashlet.header("Flow Entries");
311 $dashlet.append($h4);
312 if (one.f.flows.registry.privilege === 'WRITE') {
313 var button = one.lib.dashlet.button.single("Add Flow Entry", one.f.flows.id.dashlet.add, "btn-primary", "btn-mini");
314 var $button = one.lib.dashlet.button.button(button);
316 $button.click(function() {
317 var $modal = one.f.flows.modal.initialize();
320 $dashlet.append($button);
325 $table.find('tbody').find('tr').click(function() {
326 var id = $($(this).find('td')[0]).text();
327 var node = $(this).data('id');
328 one.f.flows.detail(id, node);
332 var flowCount = $table.find('tbody').find('tr').size();
334 var flowText = "flow";
336 if (flowCount != 1) {
340 var out = "There "+verb+" "+flowCount+" "+flowText;
341 $p = $(document.createElement('p'));
344 // add table to dashlet
345 $dashlet.append($table);
347 if(callback != undefined) callback();
350 detail : function(id, node) {
351 // clear flow details
352 var $detailDashlet = one.main.dashlet.right.bottom;
353 $detailDashlet.empty();
354 var $h4 = one.lib.dashlet.header("Flow Overview");
355 $detailDashlet.append($h4);
358 var flows = one.f.flows.registry.flows;
360 $(flows).each(function(index, value) {
361 if (value['name'] == id) {
365 if (one.f.flows.registry.privilege === 'WRITE') {
367 var button = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.dashlet.remove, "btn-danger", "btn-mini");
368 var $button = one.lib.dashlet.button.button(button);
369 $button.click(function() {
370 var $modal = one.f.flows.modal.dialog.initialize(id, node);
375 if (flow['flow']['installInHw'] == 'true' && flow['flow']['status'] == 'Success') {
376 toggle = one.lib.dashlet.button.single("Uninstall Flow", one.f.flows.id.dashlet.toggle, "btn-warning", "btn-mini");
378 toggle = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.dashlet.toggle, "btn-success", "btn-mini");
380 var $toggle = one.lib.dashlet.button.button(toggle);
381 $toggle.click(function() {
382 one.f.flows.modal.ajax.toggleflow(id, node, function(data) {
383 if(data == "Success") {
384 one.main.dashlet.right.bottom.empty();
385 one.f.detail.dashlet(one.main.dashlet.right.bottom);
386 one.main.dashlet.left.top.empty();
387 one.f.flows.dashlet(one.main.dashlet.left.top, function() {
388 // checks are backwards due to stale registry
389 if(flow['flow']['installInHw'] == 'true') {
390 one.lib.alert('Uninstalled Flow');
392 one.lib.alert('Installed Flow');
394 one.f.flows.detail(id, node)
397 one.lib.alert('Cannot toggle flow: '+data);
402 $detailDashlet.append($button).append($toggle);
405 var body = one.f.detail.data.dashlet(flow);
406 var $body = one.f.detail.body.dashlet(body);
407 $detailDashlet.append($body);
408 var body = one.f.detail.data.description(flow);
409 var $body = one.f.detail.body.description(body);
410 $detailDashlet.append($body);
411 var body = one.f.detail.data.actions(flow);
412 var $body = one.f.detail.body.actions(body);
413 $detailDashlet.append($body);
417 initialize : function(id, node) {
418 var h3 = "Remove Flow?";
419 var $p = one.f.flows.modal.dialog.body(id);
420 var footer = one.f.flows.modal.dialog.footer();
421 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $p, footer);
422 $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() {
423 $modal.modal('hide');
425 $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(function() {
426 one.f.flows.modal.ajax.removeflow(id, node, function(data) {
427 if (data == "Success") {
428 $modal.modal('hide');
429 one.main.dashlet.right.bottom.empty();
430 one.f.detail.dashlet(one.main.dashlet.right.bottom);
431 one.main.dashlet.left.top.empty();
432 one.f.flows.dashlet(one.main.dashlet.left.top);
433 one.lib.alert('Flow removed');
435 one.lib.alert('Cannot remove flow: '+data);
441 footer : function() {
444 var removeButton = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.modal.dialog.remove, "btn-danger", "");
445 var $removeButton = one.lib.dashlet.button.button(removeButton);
446 footer.push($removeButton);
448 var closeButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.dialog.close, "", "");
449 var $closeButton = one.lib.dashlet.button.button(closeButton);
450 footer.push($closeButton);
454 body : function(id) {
455 var $p = $(document.createElement('p'));
456 $p.append('Remove flow '+id+'?');
460 initialize : function() {
461 var h3 = "Add Flow Entry";
462 var footer = one.f.flows.modal.footer();
463 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.modal, h3, "", footer);
466 $('#'+one.f.flows.id.modal.close, $modal).click(function() {
467 $modal.modal('hide');
470 // bind add flow button
471 $('#'+one.f.flows.id.modal.add, $modal).click(function() {
472 one.f.flows.modal.add($modal, 'false');
475 // bind install flow button
476 $('#'+one.f.flows.id.modal.install, $modal).click(function() {
477 one.f.flows.modal.add($modal, 'true');
480 // inject body (nodePorts)
481 one.f.flows.modal.ajax.nodes(function(nodes, nodeports) {
482 var $body = one.f.flows.modal.body(nodes, nodeports);
483 one.lib.modal.inject.body($modal, $body);
488 add : function($modal, install) {
491 result['name'] = $('#'+one.f.flows.id.modal.form.name, $modal).val();
492 result['ingressPort'] = $('#'+one.f.flows.id.modal.form.port, $modal).val();
493 result['priority'] = $('#'+one.f.flows.id.modal.form.priority, $modal).val();
494 result['hardTimeout'] = $('#'+one.f.flows.id.modal.form.hardTimeout, $modal).val();
495 result['idleTimeout'] = $('#'+one.f.flows.id.modal.form.idleTimeout, $modal).val();
496 result['cookie'] = $('#'+one.f.flows.id.modal.form.cookie, $modal).val();
497 result['etherType'] = $('#'+one.f.flows.id.modal.form.etherType, $modal).val();
498 result['vlanId'] = $('#'+one.f.flows.id.modal.form.vlanId, $modal).val();
499 result['vlanPriority'] = $('#'+one.f.flows.id.modal.form.vlanPriority, $modal).val();
500 result['dlSrc'] = $('#'+one.f.flows.id.modal.form.srcMac, $modal).val();
501 result['dlDst'] = $('#'+one.f.flows.id.modal.form.dstMac, $modal).val();
502 result['nwSrc'] = $('#'+one.f.flows.id.modal.form.srcIp, $modal).val();
503 result['nwDst'] = $('#'+one.f.flows.id.modal.form.dstIp, $modal).val();
504 result['tosBits'] = $('#'+one.f.flows.id.modal.form.tosBits, $modal).val();
505 result['tpSrc'] = $('#'+one.f.flows.id.modal.form.srcPort, $modal).val();
506 result['tpDst'] = $('#'+one.f.flows.id.modal.form.dstPort, $modal).val();
507 result['protocol'] = $('#'+one.f.flows.id.modal.form.protocol, $modal).val();
509 result['installInHw'] = install;
511 var nodeId = $('#'+one.f.flows.id.modal.form.nodes, $modal).val();
513 $.each(result, function(key, value) {
514 if (value == "") delete result[key];
518 var $table = $('#'+one.f.flows.id.modal.action.table, $modal);
519 $($table.find('tbody').find('tr')).each(function(index, value) {
520 if (!$(this).find('td').hasClass('empty')) {
521 action.push($(value).data('action'));
524 result['actions'] = action;
526 // frontend validation
527 if (result['name'] == undefined) {
528 alert('Need flow name');
532 alert('Select node');
535 if (action.length == 0) {
536 alert('Please specify an action');
540 // package for ajax call
542 resource['body'] = JSON.stringify(result);
543 resource['action'] = 'add';
544 resource['nodeId'] = nodeId;
546 one.f.flows.modal.ajax.saveflow(resource, function(data) {
547 if (data == "Success") {
548 $modal.modal('hide');
549 one.lib.alert('Flow added');
550 one.main.dashlet.left.top.empty();
551 one.f.flows.dashlet(one.main.dashlet.left.top);
553 alert('Could not add flow: '+data);
558 nodes : function(successCallback) {
559 $.getJSON(one.f.address.root+one.f.address.flows.nodes, function(data) {
560 var nodes = one.f.flows.modal.data.nodes(data);
561 var nodeports = data;
562 one.f.flows.registry['nodeports'] = nodeports;
564 successCallback(nodes, nodeports);
567 saveflow : function(resource, callback) {
568 $.post(one.f.address.root+one.f.address.flows.flow, resource, function(data) {
572 removeflow : function(id, node, callback) {
574 resource['action'] = 'remove';
575 $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
579 toggleflow : function(id, node, callback) {
581 resource['action'] = 'toggle';
582 $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
588 nodes : function(data) {
590 $.each(data, function(key, value) {
591 result[key] = value['name'];
596 body : function(nodes, nodeports) {
597 var $form = $(document.createElement('form'));
598 var $fieldset = $(document.createElement('fieldset'));
600 var $legend = one.lib.form.legend("Flow Description");
601 $fieldset.append($legend);
603 var $label = one.lib.form.label("Name");
604 var $input = one.lib.form.input("Flow Name");
605 $input.attr('id', one.f.flows.id.modal.form.name);
606 $fieldset.append($label).append($input);
608 var $label = one.lib.form.label("Node");
609 var $select = one.lib.form.select.create(nodes);
610 one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
611 $select.val($select.find("option:first").val());
612 $select.attr('id', one.f.flows.id.modal.form.nodes);
615 $select.change(function() {
616 // retrieve port value
617 var node = $(this).find('option:selected').attr('value');
618 var $ports = $('#'+one.f.flows.id.modal.form.port);
620 one.lib.form.select.inject($ports, {});
623 one.f.flows.registry['currentNode'] = node;
624 var ports = nodeports[node]['ports'];
625 one.lib.form.select.inject($ports, ports);
626 one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
627 $ports.val($ports.find("option:first").val());
630 $fieldset.append($label).append($select);
632 var $label = one.lib.form.label("Input Port");
633 var $select = one.lib.form.select.create();
634 $select.attr('id', one.f.flows.id.modal.form.port);
635 $fieldset.append($label).append($select);
637 var $label = one.lib.form.label("Priority");
638 var $input = one.lib.form.input("Priority");
639 $input.attr('id', one.f.flows.id.modal.form.priority);
641 $fieldset.append($label).append($input);
643 var $label = one.lib.form.label("Hard Timeout");
644 var $input = one.lib.form.input("Hard Timeout");
645 $input.attr('id', one.f.flows.id.modal.form.hardTimeout);
646 $fieldset.append($label).append($input);
648 var $label = one.lib.form.label("Idle Timeout");
649 var $input = one.lib.form.input("Idle Timeout");
650 $input.attr('id', one.f.flows.id.modal.form.idleTimeout);
651 $fieldset.append($label).append($input);
653 var $label = one.lib.form.label("Cookie");
654 var $input = one.lib.form.input("Cookie");
655 $input.attr('id', one.f.flows.id.modal.form.cookie);
656 $fieldset.append($label).append($input);
658 var $legend = one.lib.form.legend("Layer 2");
659 $fieldset.append($legend);
661 var $label = one.lib.form.label("Ethernet Type");
662 var $input = one.lib.form.input("Ethernet Type");
663 $input.attr('id', one.f.flows.id.modal.form.etherType);
665 $fieldset.append($label).append($input);
667 var $label = one.lib.form.label("VLAN Identification Number");
668 var $input = one.lib.form.input("VLAN Identification Number");
669 $input.attr('id', one.f.flows.id.modal.form.vlanId);
670 var $help = one.lib.form.help("Range: 0 - 4095");
671 $fieldset.append($label).append($input).append($help);
673 var $label = one.lib.form.label("VLAN Priority");
674 var $input = one.lib.form.input("VLAN Priority");
675 $input.attr('id', one.f.flows.id.modal.form.vlanPriority);
676 var $help = one.lib.form.help("Range: 0 - 7");
677 $fieldset.append($label).append($input).append($help);
679 var $label = one.lib.form.label("Source MAC Address");
680 var $input = one.lib.form.input("Source MAC Address");
681 $input.attr('id', one.f.flows.id.modal.form.srcMac);
682 var $help = one.lib.form.help("Example: 00:11:22:aa:bb:cc");
683 $fieldset.append($label).append($input).append($help);
685 var $label = one.lib.form.label("Destination MAC Address");
686 var $input = one.lib.form.input("Destination MAC Address");
687 $input.attr('id', one.f.flows.id.modal.form.dstMac);
688 var $help = one.lib.form.help("Example: 00:11:22:aa:bb:cc");
689 $fieldset.append($label).append($input).append($help);
691 var $legend = one.lib.form.legend("Layer 3");
692 $fieldset.append($legend);
694 var $label = one.lib.form.label("Source IP Address");
695 var $input = one.lib.form.input("Source IP Address");
696 $input.attr('id', one.f.flows.id.modal.form.srcIp);
697 var $help = one.lib.form.help("Example: 127.0.0.1");
698 $fieldset.append($label).append($input).append($help);
700 var $label = one.lib.form.label("Destination IP Address");
701 var $input = one.lib.form.input("Destination IP Address");
702 $input.attr('id', one.f.flows.id.modal.form.dstIp);
703 var $help = one.lib.form.help("Example: 127.0.0.1");
704 $fieldset.append($label).append($input).append($help);
706 var $label = one.lib.form.label("TOS Bits");
707 var $input = one.lib.form.input("TOS Bits");
708 $input.attr('id', one.f.flows.id.modal.form.tosBits);
709 var $help = one.lib.form.help("Range: 0 - 63");
710 $fieldset.append($label).append($input).append($help);
712 var $legend = one.lib.form.legend("Layer 4");
713 $fieldset.append($legend);
715 var $label = one.lib.form.label("Source Port");
716 var $input = one.lib.form.input("Source Port");
717 $input.attr('id', one.f.flows.id.modal.form.srcPort);
718 var $help = one.lib.form.help("Range: 0 - 65535");
719 $fieldset.append($label).append($input).append($help);
721 var $label = one.lib.form.label("Destination Port");
722 var $input = one.lib.form.input("Destination Port");
723 $input.attr('id', one.f.flows.id.modal.form.dstPort);
724 var $help = one.lib.form.help("Range: 0 - 65535");
725 $fieldset.append($label).append($input).append($help);
727 var $label = one.lib.form.label("Protocol");
728 var $input = one.lib.form.input("Protocol");
729 $input.attr('id', one.f.flows.id.modal.form.protocol);
730 $fieldset.append($label).append($input);
732 var $legend = one.lib.form.label("Actions");
733 $fieldset.append($legend);
735 var tableAttributes = ["table-striped", "table-bordered", "table-condensed", "table-hover", "table-cursor"];
736 var $table = one.lib.dashlet.table.table(tableAttributes);
737 $table.attr('id', one.f.flows.id.modal.action.table);
738 var tableHeaders = ["Action", "Data", "Type"];
739 var $thead = one.lib.dashlet.table.header(tableHeaders);
740 var $tbody = one.lib.dashlet.table.body("", tableHeaders);
741 $table.append($thead).append($tbody);
744 "" : "Please Select an Action",
746 "loopback" : "Loopback",
748 "softwarePath" : "Software Path",
749 "hardwarePath" : "Hardware Path",
750 "controller" : "Controller",
751 "addOutputPorts" : "Add Output Ports",
752 "setVlanId" : "Set VLAN ID",
753 "setVlanPriority" : "Set VLAN Priority",
754 "stripVlanHeader" : "Strip VLAN Header",
755 "modifyDatalayerSourceAddress" : "Modify Datalayer Source Address",
756 "modifyDatalayerDestinationAddress" : "Modify Datalayer Destination Address",
757 "modifyNetworkSourceAddress" : "Modify Network Source Address",
758 "modifyNetworkDestinationAddress" :"Modify Network Destination Address",
759 "modifyTosBits" : "Modify TOS Bits",
760 "modifyTransportSourcePort" : "Modify Transport Source Port",
761 "modifyTransportDestinationPort" : "Modify Transport Destination Port"
763 var $select = one.lib.form.select.create(actions);
764 // when selecting an action
765 $select.change(function() {
766 var action = $(this).find('option:selected');
767 one.f.flows.modal.action.parse(action.attr('value'));
768 $select[0].selectedIndex = 0;
771 $fieldset.append($select).append($table);
774 $form.append($fieldset);
778 parse : function(option) {
780 case "addOutputPorts" :
781 var h3 = "Add Output Port";
782 var $modal = one.f.flows.modal.action.initialize(h3, one.f.flows.modal.action.body.addOutputPorts, one.f.flows.modal.action.add.addOutputPorts);
786 var h3 = "Set VLAN ID";
787 var placeholder = "VLAN Identification Number";
788 var id = one.f.flows.id.modal.action.setVlanId;
789 var help = "Range: 0 - 4095";
790 var action = 'SET_VLAN_ID';
791 var name = "VLAN ID";
792 var body = function() {
793 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
795 var add = function($modal) {
796 one.f.flows.modal.action.add.set(name, id, action, $modal);
798 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
801 case "setVlanPriority" :
802 var h3 = "Set VLAN Priority";
803 var placeholder = "VLAN Priority";
804 var id = one.f.flows.id.modal.action.setVlanPriority;
805 var help = "Range: 0 - 7";
806 var action = 'SET_VLAN_PCP';
807 var name = "VLAN Priority";
808 var body = function() {
809 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
811 var add = function($modal) {
812 one.f.flows.modal.action.add.set(name, id, action, $modal);
814 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
817 case "stripVlanHeader" :
818 var name = "Strip VLAN Header";
819 var action = 'POP_VLAN';
820 one.f.flows.modal.action.add.add(name, action);
822 case "modifyDatalayerSourceAddress" :
823 var h3 = "Set Source MAC Address";
824 var placeholder = "Source MAC Address";
825 var id = one.f.flows.id.modal.action.modifyDatalayerSourceAddress;
826 var help = "Example: 00:11:22:aa:bb:cc";
827 var action = 'SET_DL_SRC';
828 var name = "Source MAC";
829 var body = function() {
830 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
832 var add = function($modal) {
833 one.f.flows.modal.action.add.set(name, id, action, $modal);
835 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
838 case "modifyDatalayerDestinationAddress" :
839 var h3 = "Set Destination MAC Address";
840 var placeholder = "Destination MAC Address";
841 var id = one.f.flows.id.modal.action.modifyDatalayerDestinationAddress;
842 var help = "Example: 00:11:22:aa:bb:cc";
843 var action = 'SET_DL_DST';
844 var name = "Destination MAC";
845 var body = function() {
846 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
848 var add = function($modal) {
849 one.f.flows.modal.action.add.set(name, id, action, $modal);
851 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
854 case "modifyNetworkSourceAddress" :
855 var h3 = "Set IP Source Address";
856 var placeholder = "Source IP Address";
857 var id = one.f.flows.id.modal.action.modifyNetworkSourceAddress;
858 var help = "Example: 127.0.0.1";
859 var action = 'SET_NW_SRC';
860 var name = "Source IP";
861 var body = function() {
862 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
864 var add = function($modal) {
865 one.f.flows.modal.action.add.set(name, id, action, $modal);
867 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
870 case "modifyNetworkDestinationAddress" :
871 var h3 = "Set IP Destination Address";
872 var placeholder = "Destination IP Address";
873 var id = one.f.flows.id.modal.action.modifyNetworkDestinationAddress;
874 var help = "Example: 127.0.0.1";
875 var action = 'SET_NW_DST';
876 var name = "Destination IP";
877 var body = function() {
878 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
880 var add = function($modal) {
881 one.f.flows.modal.action.add.set(name, id, action, $modal);
883 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
886 case "modifyTosBits" :
887 var h3 = "Set IPv4 ToS";
888 var placeholder = "IPv4 ToS";
889 var id = one.f.flows.id.modal.action.modifyTosBits;
890 var help = "Range: 0 - 63";
891 var action = 'SET_NW_TOS';
892 var name = "TOS Bits";
893 var body = function() {
894 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
896 var add = function($modal) {
897 one.f.flows.modal.action.add.set(name, id, action, $modal);
899 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
902 case "modifyTransportSourcePort" :
903 var h3 = "Set Transport Source Port";
904 var placeholder = "Transport Source Port";
905 var id = one.f.flows.id.modal.action.modifyTransportSourcePort;
906 var help = "Range: 1 - 65535";
907 var action = 'SET_TP_SRC';
908 var name = "Source Port";
909 var body = function() {
910 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
912 var add = function($modal) {
913 one.f.flows.modal.action.add.set(name, id, action, $modal);
915 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
918 case "modifyTransportDestinationPort" :
919 var h3 = "Set Transport Destination Port";
920 var placeholder = "Transport Destination Port";
921 var id = one.f.flows.id.modal.action.modifyTransportDestinationPort;
922 var help = "Range: 1 - 65535";
923 var action = 'SET_TP_DST';
924 var name = "Destination Port";
925 var body = function() {
926 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
928 var add = function($modal) {
929 one.f.flows.modal.action.add.set(name, id, action, $modal);
931 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
937 one.f.flows.modal.action.add.add(name, action);
940 var name = "Loopback";
941 var action = 'LOOPBACK';
942 one.f.flows.modal.action.add.add(name, action);
946 var action = 'FLOOD';
947 one.f.flows.modal.action.add.add(name, action);
949 case "softwarePath" :
950 var name = "Software Path";
951 var action = 'SW_PATH';
952 one.f.flows.modal.action.add.add(name, action);
954 case "hardwarePath" :
955 var name = "Hardware Path";
956 var action = 'HW_PATH';
957 one.f.flows.modal.action.add.add(name, action);
960 var name = "Controller";
961 var action = 'CONTROLLER';
962 one.f.flows.modal.action.add.add(name, action);
966 initialize : function(h3, bodyCallback, addCallback) {
967 var footer = one.f.flows.modal.action.footer();
968 var $body = bodyCallback();
969 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal, h3, $body, footer);
971 $('#'+one.f.flows.id.modal.action.close, $modal).click(function() {
972 $modal.modal('hide');
974 // bind add flow button
975 $('#'+one.f.flows.id.modal.action.add, $modal).click(function() {
981 addOutputPorts : function($modal) {
982 var $options = $('#'+one.f.flows.id.modal.action.addOutputPorts).find('option:selected');
985 $options.each(function(index, value) {
986 ports = ports+$(value).text()+", ";
987 pid = pid+$(value).attr('value')+",";
989 ports = ports.slice(0,-2);
990 pid = pid.slice(0,-1);
991 var $tr = one.f.flows.modal.action.table.add("Add Output Ports", ports);
992 $tr.attr('id', 'addOutputPorts');
993 $tr.data('action', 'OUTPUT='+pid);
994 $tr.click(function() {
995 one.f.flows.modal.action.add.modal.initialize(this);
997 one.f.flows.modal.action.table.append($tr);
998 $modal.modal('hide');
1000 add : function(name, action) {
1001 var $tr = one.f.flows.modal.action.table.add(name);
1002 $tr.attr('id', action);
1003 $tr.data('action', action);
1004 $tr.click(function() {
1005 one.f.flows.modal.action.add.modal.initialize(this);
1007 one.f.flows.modal.action.table.append($tr);
1009 set : function(name, id, action, $modal) {
1010 var $input = $('#'+id);
1011 var value = $input.val();
1012 var $tr = one.f.flows.modal.action.table.add(name, value);
1013 $tr.attr('id', action);
1014 $tr.data('action', action+'='+value);
1015 $tr.click(function() {
1016 one.f.flows.modal.action.add.modal.initialize(this);
1018 one.f.flows.modal.action.table.append($tr);
1019 $modal.modal('hide');
1021 remove : function(that) {
1023 var $table = $('#'+one.f.flows.id.modal.action.table);
1024 if ($table.find('tbody').find('tr').size() == 0) {
1025 var $tr = $(document.createElement('tr'));
1026 var $td = $(document.createElement('td'));
1027 $td.attr('colspan', '3');
1028 $tr.addClass('empty');
1029 $td.text('No data available');
1031 $table.find('tbody').append($tr);
1035 initialize : function(that) {
1036 var h3 = "Remove Action";
1037 var footer = one.f.flows.modal.action.add.modal.footer();
1038 var $body = one.f.flows.modal.action.add.modal.body();
1039 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal.modal, h3, $body, footer);
1041 // bind cancel button
1042 $('#'+one.f.flows.id.modal.action.modal.cancel, $modal).click(function() {
1043 $modal.modal('hide');
1046 // bind remove button
1047 $('#'+one.f.flows.id.modal.action.modal.remove, $modal).click(function() {
1048 one.f.flows.modal.action.add.remove(that);
1049 $modal.modal('hide');
1055 var $p = $(document.createElement('p'));
1056 $p.append("Remove this action?");
1059 footer : function() {
1062 var removeButton = one.lib.dashlet.button.single("Remove Action", one.f.flows.id.modal.action.modal.remove, "btn-danger", "");
1063 var $removeButton = one.lib.dashlet.button.button(removeButton);
1064 footer.push($removeButton);
1066 var cancelButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.action.modal.cancel, "", "");
1067 var $cancelButton = one.lib.dashlet.button.button(cancelButton);
1068 footer.push($cancelButton);
1075 add : function(action, data, type) {
1076 var $tr = $(document.createElement('tr'));
1077 var $td = $(document.createElement('td'));
1080 var $td = $(document.createElement('td'));
1081 if (data != undefined) $td.append(data);
1083 var $td = $(document.createElement('td'));
1084 if (type != undefined) $td.append(type);
1088 append : function($tr) {
1089 var $table = $('#'+one.f.flows.id.modal.action.table);
1090 var $empty = $table.find('.empty').parent();
1091 if ($empty.size() > 0) $empty.remove();
1096 common : function() {
1097 var $form = $(document.createElement('form'));
1098 var $fieldset = $(document.createElement('fieldset'));
1099 return [$form, $fieldset];
1101 addOutputPorts : function() {
1102 var common = one.f.flows.modal.action.body.common();
1103 var $form = common[0];
1104 var $fieldset = common[1];
1106 $label = one.lib.form.label("Select Output Ports");
1107 var ports = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports'];
1108 $select = one.lib.form.select.create(ports, true);
1109 $select.attr('id', one.f.flows.id.modal.action.addOutputPorts);
1110 one.lib.form.select.prepend($select, {'':'Select a Port'});
1111 $fieldset.append($label).append($select);
1112 $form.append($fieldset);
1115 set : function(label, placeholder, id, help) {
1116 var common = one.f.flows.modal.action.body.common();
1117 var $form = common[0];
1118 var $fieldset = common[1];
1120 $label = one.lib.form.label(label);
1121 $input = one.lib.form.input(placeholder);
1122 $input.attr('id', id);
1123 $help = one.lib.form.help(help);
1125 $fieldset.append($label).append($input).append($help);
1126 $form.append($fieldset);
1130 footer : function() {
1132 var addButton = one.lib.dashlet.button.single("Add Action", one.f.flows.id.modal.action.add, "btn-primary", "");
1133 var $addButton = one.lib.dashlet.button.button(addButton);
1134 footer.push($addButton);
1136 var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.action.close, "", "");
1137 var $closeButton = one.lib.dashlet.button.button(closeButton);
1138 footer.push($closeButton);
1143 footer : function() {
1146 var installButton = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.modal.install, "btn-success", "");
1147 var $installButton = one.lib.dashlet.button.button(installButton);
1148 footer.push($installButton);
1150 var addButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.add, "btn-primary", "");
1151 var $addButton = one.lib.dashlet.button.button(addButton);
1152 footer.push($addButton);
1154 var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", "");
1155 var $closeButton = one.lib.dashlet.button.button(closeButton);
1156 footer.push($closeButton);
1162 dashlet : function(callback) {
1163 $.getJSON(one.f.address.root+one.f.address.flows.main, function(data) {
1164 one.f.flows.registry['flows'] = data.flows;
1165 one.f.flows.registry['privilege'] = data.privilege;
1166 var body = one.f.flows.data.dashlet(data.flows);
1167 var $body = one.f.flows.body.dashlet(body, callback);
1173 dashlet : function(data) {
1175 $(data).each(function(index, value) {
1178 entry.push(value['name']);
1179 entry.push(value['node']);
1180 if (value['flow']['installInHw'] == 'true' && value['flow']['status'] == 'Success')
1181 tr['type'] = ['success'];
1182 else if (value['flow']['installInHw'] == 'false' && value['flow']['status'] == 'Success')
1183 tr['type'] = ['warning'];
1185 tr['type'] = ['warning'];
1186 tr['entry'] = entry;
1187 tr['id'] = value['nodeId'];
1195 dashlet : function(body, callback) {
1196 var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed', 'table-cursor'];
1197 var $table = one.lib.dashlet.table.table(attributes);
1199 var headers = ['Flow Name', 'Node'];
1200 var $thead = one.lib.dashlet.table.header(headers);
1201 $table.append($thead);
1203 var $tbody = one.lib.dashlet.table.body(body);
1204 $table.append($tbody);
1212 // populate nav tabs
1213 $(one.f.menu.left.top).each(function(index, value) {
1214 var $nav = $(".nav", "#left-top");
1215 one.main.page.dashlet($nav, value);
1218 $(one.f.menu.left.bottom).each(function(index, value) {
1219 var $nav = $(".nav", "#left-bottom");
1220 one.main.page.dashlet($nav, value);
1223 $(one.f.menu.right.bottom).each(function(index, value) {
1224 var $nav = $(".nav", "#right-bottom");
1225 one.main.page.dashlet($nav, value);
1228 one.f.populate = function($dashlet, header) {
1229 var $h4 = one.lib.dashlet.header(header);
1230 $dashlet.append($h4);
1234 $('.dash .nav a', '#main').click(function() {
1236 var $li = $(this).parent();
1237 var $ul = $li.parent();
1238 one.lib.nav.unfocus($ul);
1239 $li.addClass('active');
1240 // clear respective dashlet
1241 var $dashlet = $ul.parent().find('.dashlet');
1242 one.lib.dashlet.empty($dashlet);
1243 // callback based on menu
1244 var id = $(this).attr('id');
1245 var menu = one.f.dashlet;
1248 one.f.flows.dashlet($dashlet);
1251 one.f.nodes.dashlet($dashlet);
1253 case menu.detail.id:
1254 one.f.detail.dashlet($dashlet);
1259 // activate first tab on each dashlet
1260 $('.dash .nav').each(function(index, value) {
1261 $($(value).find('li')[0]).find('a').click();