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) {
305 var $h4 = one.lib.dashlet.header("Flow Entries");
308 var button = one.lib.dashlet.button.single("Add Flow Entry", one.f.flows.id.dashlet.add, "btn-primary", "btn-mini");
309 var $button = one.lib.dashlet.button.button(button);
311 $button.click(function() {
312 var $modal = one.f.flows.modal.initialize();
317 $dashlet.append($h4);
318 if (one.role < 2) $dashlet.append($button);
321 one.f.flows.ajax.dashlet(function($table) {
323 var flowCount = $table.find('tbody').find('tr').size();
325 var flowText = "flow";
327 if (flowCount != 1) {
331 var out = "There "+verb+" "+flowCount+" "+flowText;
332 $p = $(document.createElement('p'));
336 $table.find('tbody').find('tr').click(function() {
337 var id = $($(this).find('td')[0]).text();
338 var node = $(this).data('id');
339 one.f.flows.detail(id, node);
342 $dashlet.append($table);
344 if(callback != undefined) callback();
347 detail : function(id, node) {
348 // clear flow details
349 var $detailDashlet = one.main.dashlet.right.bottom;
350 $detailDashlet.empty();
351 var $h4 = one.lib.dashlet.header("Flow Overview");
352 $detailDashlet.append($h4);
355 var flows = one.f.flows.registry.flows;
357 $(flows).each(function(index, value) {
358 if (value['name'] == id) {
364 var button = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.dashlet.remove, "btn-danger", "btn-mini");
365 var $button = one.lib.dashlet.button.button(button);
366 $button.click(function() {
367 var $modal = one.f.flows.modal.dialog.initialize(id, node);
372 if (flow['flow']['installInHw'] == 'true') {
373 toggle = one.lib.dashlet.button.single("Uninstall Flow", one.f.flows.id.dashlet.toggle, "btn-warning", "btn-mini");
375 toggle = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.dashlet.toggle, "btn-success", "btn-mini");
377 var $toggle = one.lib.dashlet.button.button(toggle);
378 $toggle.click(function() {
379 one.f.flows.modal.ajax.toggleflow(id, node, function(data) {
380 if(data == "Success") {
381 one.main.dashlet.right.bottom.empty();
382 one.f.detail.dashlet(one.main.dashlet.right.bottom);
383 one.main.dashlet.left.top.empty();
384 one.f.flows.dashlet(one.main.dashlet.left.top, function() {
385 // checks are backwards due to stale registry
386 if(flow['flow']['installInHw'] == 'true') {
387 one.lib.alert('Uninstalled Flow');
389 one.lib.alert('Installed Flow');
391 one.f.flows.detail(id, node)
394 one.lib.alert('Cannot toggle flow: '+data);
400 var body = one.f.detail.data.dashlet(flow);
401 var $body = one.f.detail.body.dashlet(body);
402 if (one.role < 2) $detailDashlet.append($button).append($toggle);
403 $detailDashlet.append($body);
404 var body = one.f.detail.data.description(flow);
405 var $body = one.f.detail.body.description(body);
406 $detailDashlet.append($body);
407 var body = one.f.detail.data.actions(flow);
408 var $body = one.f.detail.body.actions(body);
409 $detailDashlet.append($body);
413 initialize : function(id, node) {
414 var h3 = "Remove Flow?";
415 var $p = one.f.flows.modal.dialog.body(id);
416 var footer = one.f.flows.modal.dialog.footer();
417 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $p, footer);
418 $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() {
419 $modal.modal('hide');
421 $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(function() {
422 one.f.flows.modal.ajax.removeflow(id, node, function(data) {
423 if (data == "Success") {
424 $modal.modal('hide');
425 one.main.dashlet.right.bottom.empty();
426 one.f.detail.dashlet(one.main.dashlet.right.bottom);
427 one.main.dashlet.left.top.empty();
428 one.f.flows.dashlet(one.main.dashlet.left.top);
429 one.lib.alert('Flow removed');
431 one.lib.alert('Cannot remove flow: '+data);
437 footer : function() {
440 var removeButton = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.modal.dialog.remove, "btn-danger", "");
441 var $removeButton = one.lib.dashlet.button.button(removeButton);
442 footer.push($removeButton);
444 var closeButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.dialog.close, "", "");
445 var $closeButton = one.lib.dashlet.button.button(closeButton);
446 footer.push($closeButton);
450 body : function(id) {
451 var $p = $(document.createElement('p'));
452 $p.append('Remove flow '+id+'?');
456 initialize : function() {
457 var h3 = "Add Flow Entry";
458 var footer = one.f.flows.modal.footer();
459 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.modal, h3, "", footer);
462 $('#'+one.f.flows.id.modal.close, $modal).click(function() {
463 $modal.modal('hide');
466 // bind add flow button
467 $('#'+one.f.flows.id.modal.add, $modal).click(function() {
468 one.f.flows.modal.add($modal, 'false');
471 // bind install flow button
472 $('#'+one.f.flows.id.modal.install, $modal).click(function() {
473 one.f.flows.modal.add($modal, 'true');
476 // inject body (nodePorts)
477 one.f.flows.modal.ajax.nodes(function(nodes, nodeports) {
478 var $body = one.f.flows.modal.body(nodes, nodeports);
479 one.lib.modal.inject.body($modal, $body);
484 add : function($modal, install) {
487 result['name'] = $('#'+one.f.flows.id.modal.form.name, $modal).val();
488 result['ingressPort'] = $('#'+one.f.flows.id.modal.form.port, $modal).val();
489 result['priority'] = $('#'+one.f.flows.id.modal.form.priority, $modal).val();
490 result['hardTimeout'] = $('#'+one.f.flows.id.modal.form.hardTimeout, $modal).val();
491 result['idleTimeout'] = $('#'+one.f.flows.id.modal.form.idleTimeout, $modal).val();
492 result['cookie'] = $('#'+one.f.flows.id.modal.form.cookie, $modal).val();
493 result['etherType'] = $('#'+one.f.flows.id.modal.form.etherType, $modal).val();
494 result['vlanId'] = $('#'+one.f.flows.id.modal.form.vlanId, $modal).val();
495 result['vlanPriority'] = $('#'+one.f.flows.id.modal.form.vlanPriority, $modal).val();
496 result['dlSrc'] = $('#'+one.f.flows.id.modal.form.srcMac, $modal).val();
497 result['dlDst'] = $('#'+one.f.flows.id.modal.form.dstMac, $modal).val();
498 result['nwSrc'] = $('#'+one.f.flows.id.modal.form.srcIp, $modal).val();
499 result['nwDst'] = $('#'+one.f.flows.id.modal.form.dstIp, $modal).val();
500 result['tosBits'] = $('#'+one.f.flows.id.modal.form.tosBits, $modal).val();
501 result['tpSrc'] = $('#'+one.f.flows.id.modal.form.srcPort, $modal).val();
502 result['tpDst'] = $('#'+one.f.flows.id.modal.form.dstPort, $modal).val();
503 result['protocol'] = $('#'+one.f.flows.id.modal.form.protocol, $modal).val();
505 result['installInHw'] = install;
507 var nodeId = $('#'+one.f.flows.id.modal.form.nodes, $modal).val();
509 $.each(result, function(key, value) {
510 if (value == "") delete result[key];
514 var $table = $('#'+one.f.flows.id.modal.action.table, $modal);
515 $($table.find('tbody').find('tr')).each(function(index, value) {
516 if (!$(this).find('td').hasClass('empty')) {
517 action.push($(value).data('action'));
520 result['actions'] = action;
522 // frontend validation
523 if (result['name'] == undefined) {
524 alert('Need flow name');
528 alert('Select node');
531 if (action.length == 0) {
532 alert('Please specify an action');
536 // package for ajax call
538 resource['body'] = JSON.stringify(result);
539 resource['action'] = 'add';
540 resource['nodeId'] = nodeId;
542 one.f.flows.modal.ajax.saveflow(resource, function(data) {
543 if (data == "Success") {
544 $modal.modal('hide');
545 one.lib.alert('Flow added');
546 one.main.dashlet.left.top.empty();
547 one.f.flows.dashlet(one.main.dashlet.left.top);
549 alert('Could not add flow: '+data);
554 nodes : function(successCallback) {
555 $.getJSON(one.f.address.root+one.f.address.flows.nodes, function(data) {
556 var nodes = one.f.flows.modal.data.nodes(data);
557 var nodeports = data;
558 one.f.flows.registry['nodeports'] = nodeports;
560 successCallback(nodes, nodeports);
563 saveflow : function(resource, callback) {
564 $.post(one.f.address.root+one.f.address.flows.flow, resource, function(data) {
568 removeflow : function(id, node, callback) {
570 resource['action'] = 'remove';
571 $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
575 toggleflow : function(id, node, callback) {
577 resource['action'] = 'toggle';
578 $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
584 nodes : function(data) {
586 $.each(data, function(key, value) {
587 result[key] = value['name'];
592 body : function(nodes, nodeports) {
593 var $form = $(document.createElement('form'));
594 var $fieldset = $(document.createElement('fieldset'));
596 var $legend = one.lib.form.legend("Flow Description");
597 $fieldset.append($legend);
599 var $label = one.lib.form.label("Name");
600 var $input = one.lib.form.input("Flow Name");
601 $input.attr('id', one.f.flows.id.modal.form.name);
602 $fieldset.append($label).append($input);
604 var $label = one.lib.form.label("Node");
605 var $select = one.lib.form.select.create(nodes);
606 one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
607 $select.val($select.find("option:first").val());
608 $select.attr('id', one.f.flows.id.modal.form.nodes);
611 $select.change(function() {
612 // retrieve port value
613 var node = $(this).find('option:selected').attr('value');
614 var $ports = $('#'+one.f.flows.id.modal.form.port);
616 one.lib.form.select.inject($ports, {});
619 one.f.flows.registry['currentNode'] = node;
620 var ports = nodeports[node]['ports'];
621 one.lib.form.select.inject($ports, ports);
622 one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
623 $ports.val($ports.find("option:first").val());
626 $fieldset.append($label).append($select);
628 var $label = one.lib.form.label("Input Port");
629 var $select = one.lib.form.select.create();
630 $select.attr('id', one.f.flows.id.modal.form.port);
631 $fieldset.append($label).append($select);
633 var $label = one.lib.form.label("Priority");
634 var $input = one.lib.form.input("Priority");
635 $input.attr('id', one.f.flows.id.modal.form.priority);
637 $fieldset.append($label).append($input);
639 var $label = one.lib.form.label("Hard Timeout");
640 var $input = one.lib.form.input("Hard Timeout");
641 $input.attr('id', one.f.flows.id.modal.form.hardTimeout);
642 $fieldset.append($label).append($input);
644 var $label = one.lib.form.label("Idle Timeout");
645 var $input = one.lib.form.input("Idle Timeout");
646 $input.attr('id', one.f.flows.id.modal.form.idleTimeout);
647 $fieldset.append($label).append($input);
649 var $label = one.lib.form.label("Cookie");
650 var $input = one.lib.form.input("Cookie");
651 $input.attr('id', one.f.flows.id.modal.form.cookie);
652 $fieldset.append($label).append($input);
654 var $legend = one.lib.form.legend("Layer 2");
655 $fieldset.append($legend);
657 var $label = one.lib.form.label("Ethernet Type");
658 var $input = one.lib.form.input("Ethernet Type");
659 $input.attr('id', one.f.flows.id.modal.form.etherType);
661 $fieldset.append($label).append($input);
663 var $label = one.lib.form.label("VLAN Identification Number");
664 var $input = one.lib.form.input("VLAN Identification Number");
665 $input.attr('id', one.f.flows.id.modal.form.vlanId);
666 var $help = one.lib.form.help("Range: 0 - 4095");
667 $fieldset.append($label).append($input).append($help);
669 var $label = one.lib.form.label("VLAN Priority");
670 var $input = one.lib.form.input("VLAN Priority");
671 $input.attr('id', one.f.flows.id.modal.form.vlanPriority);
672 var $help = one.lib.form.help("Range: 0 - 7");
673 $fieldset.append($label).append($input).append($help);
675 var $label = one.lib.form.label("Source MAC Address");
676 var $input = one.lib.form.input("Source MAC Address");
677 $input.attr('id', one.f.flows.id.modal.form.srcMac);
678 var $help = one.lib.form.help("Example: 00:11:22:aa:bb:cc");
679 $fieldset.append($label).append($input).append($help);
681 var $label = one.lib.form.label("Destination MAC Address");
682 var $input = one.lib.form.input("Destination MAC Address");
683 $input.attr('id', one.f.flows.id.modal.form.dstMac);
684 var $help = one.lib.form.help("Example: 00:11:22:aa:bb:cc");
685 $fieldset.append($label).append($input).append($help);
687 var $legend = one.lib.form.legend("Layer 3");
688 $fieldset.append($legend);
690 var $label = one.lib.form.label("Source IP Address");
691 var $input = one.lib.form.input("Source IP Address");
692 $input.attr('id', one.f.flows.id.modal.form.srcIp);
693 var $help = one.lib.form.help("Example: 127.0.0.1");
694 $fieldset.append($label).append($input).append($help);
696 var $label = one.lib.form.label("Destination IP Address");
697 var $input = one.lib.form.input("Destination IP Address");
698 $input.attr('id', one.f.flows.id.modal.form.dstIp);
699 var $help = one.lib.form.help("Example: 127.0.0.1");
700 $fieldset.append($label).append($input).append($help);
702 var $label = one.lib.form.label("TOS Bits");
703 var $input = one.lib.form.input("TOS Bits");
704 $input.attr('id', one.f.flows.id.modal.form.tosBits);
705 var $help = one.lib.form.help("Range: 0 - 63");
706 $fieldset.append($label).append($input).append($help);
708 var $legend = one.lib.form.legend("Layer 4");
709 $fieldset.append($legend);
711 var $label = one.lib.form.label("Source Port");
712 var $input = one.lib.form.input("Source Port");
713 $input.attr('id', one.f.flows.id.modal.form.srcPort);
714 var $help = one.lib.form.help("Range: 1 - 65535");
715 $fieldset.append($label).append($input).append($help);
717 var $label = one.lib.form.label("Destination Port");
718 var $input = one.lib.form.input("Destination Port");
719 $input.attr('id', one.f.flows.id.modal.form.dstPort);
720 var $help = one.lib.form.help("Range: 1 - 65535");
721 $fieldset.append($label).append($input).append($help);
723 var $label = one.lib.form.label("Protocol");
724 var $input = one.lib.form.input("Protocol");
725 $input.attr('id', one.f.flows.id.modal.form.protocol);
726 $fieldset.append($label).append($input);
728 var $legend = one.lib.form.label("Actions");
729 $fieldset.append($legend);
731 var tableAttributes = ["table-striped", "table-bordered", "table-condensed", "table-hover", "table-cursor"];
732 var $table = one.lib.dashlet.table.table(tableAttributes);
733 $table.attr('id', one.f.flows.id.modal.action.table);
734 var tableHeaders = ["Action", "Data", "Type"];
735 var $thead = one.lib.dashlet.table.header(tableHeaders);
736 var $tbody = one.lib.dashlet.table.body("", tableHeaders);
737 $table.append($thead).append($tbody);
740 "" : "Please Select an Action",
742 "loopback" : "Loopback",
744 "softwarePath" : "Software Path",
745 "hardwarePath" : "Hardware Path",
746 "controller" : "Controller",
747 "addOutputPorts" : "Add Output Ports",
748 "setVlanId" : "Set VLAN ID",
749 "setVlanPriority" : "Set VLAN Priority",
750 "stripVlanHeader" : "Strip VLAN Header",
751 "modifyDatalayerSourceAddress" : "Modify Datalayer Source Address",
752 "modifyDatalayerDestinationAddress" : "Modify Datalayer Destination Address",
753 "modifyNetworkSourceAddress" : "Modify Network Source Address",
754 "modifyNetworkDestinationAddress" :"Modify Network Destination Address",
755 "modifyTosBits" : "Modify TOS Bits",
756 "modifyTransportSourcePort" : "Modify Transport Source Port",
757 "modifyTransportDestinationPort" : "Modify Transport Destination Port"
759 var $select = one.lib.form.select.create(actions);
760 // when selecting an action
761 $select.change(function() {
762 var action = $(this).find('option:selected');
763 one.f.flows.modal.action.parse(action.attr('value'));
764 $select[0].selectedIndex = 0;
767 $fieldset.append($select).append($table);
770 $form.append($fieldset);
774 parse : function(option) {
776 case "addOutputPorts" :
777 var h3 = "Add Output Port";
778 var $modal = one.f.flows.modal.action.initialize(h3, one.f.flows.modal.action.body.addOutputPorts, one.f.flows.modal.action.add.addOutputPorts);
782 var h3 = "Set VLAN ID";
783 var placeholder = "VLAN Identification Number";
784 var id = one.f.flows.id.modal.action.setVlanId;
785 var help = "Range: 0 - 4095";
786 var action = 'SET_VLAN_ID';
787 var name = "VLAN ID";
788 var body = function() {
789 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
791 var add = function($modal) {
792 one.f.flows.modal.action.add.set(name, id, action, $modal);
794 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
797 case "setVlanPriority" :
798 var h3 = "Set VLAN Priority";
799 var placeholder = "VLAN Priority";
800 var id = one.f.flows.id.modal.action.setVlanPriority;
801 var help = "Range: 0 - 7";
802 var action = 'SET_VLAN_PCP';
803 var name = "VLAN Priority";
804 var body = function() {
805 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
807 var add = function($modal) {
808 one.f.flows.modal.action.add.set(name, id, action, $modal);
810 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
813 case "stripVlanHeader" :
814 var name = "Strip VLAN Header";
815 var action = 'POP_VLAN';
816 one.f.flows.modal.action.add.add(name, action);
818 case "modifyDatalayerSourceAddress" :
819 var h3 = "Set Source MAC Address";
820 var placeholder = "Source MAC Address";
821 var id = one.f.flows.id.modal.action.modifyDatalayerSourceAddress;
822 var help = "Example: 00:11:22:aa:bb:cc";
823 var action = 'SET_DL_SRC';
824 var name = "Source MAC";
825 var body = function() {
826 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
828 var add = function($modal) {
829 one.f.flows.modal.action.add.set(name, id, action, $modal);
831 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
834 case "modifyDatalayerDestinationAddress" :
835 var h3 = "Set Destination MAC Address";
836 var placeholder = "Destination MAC Address";
837 var id = one.f.flows.id.modal.action.modifyDatalayerDestinationAddress;
838 var help = "Example: 00:11:22:aa:bb:cc";
839 var action = 'SET_DL_DST';
840 var name = "Destination MAC";
841 var body = function() {
842 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
844 var add = function($modal) {
845 one.f.flows.modal.action.add.set(name, id, action, $modal);
847 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
850 case "modifyNetworkSourceAddress" :
851 var h3 = "Set IP Source Address";
852 var placeholder = "Source IP Address";
853 var id = one.f.flows.id.modal.action.modifyNetworkSourceAddress;
854 var help = "Example: 127.0.0.1";
855 var action = 'SET_NW_SRC';
856 var name = "Source IP";
857 var body = function() {
858 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
860 var add = function($modal) {
861 one.f.flows.modal.action.add.set(name, id, action, $modal);
863 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
866 case "modifyNetworkDestinationAddress" :
867 var h3 = "Set IP Destination Address";
868 var placeholder = "Destination IP Address";
869 var id = one.f.flows.id.modal.action.modifyNetworkDestinationAddress;
870 var help = "Example: 127.0.0.1";
871 var action = 'SET_NW_DST';
872 var name = "Destination IP";
873 var body = function() {
874 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
876 var add = function($modal) {
877 one.f.flows.modal.action.add.set(name, id, action, $modal);
879 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
882 case "modifyTosBits" :
883 var h3 = "Set IPv4 ToS";
884 var placeholder = "IPv4 ToS";
885 var id = one.f.flows.id.modal.action.modifyTosBits;
886 var help = "Range: 0 - 63";
887 var action = 'SET_NW_TOS';
888 var name = "TOS Bits";
889 var body = function() {
890 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
892 var add = function($modal) {
893 one.f.flows.modal.action.add.set(name, id, action, $modal);
895 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
898 case "modifyTransportSourcePort" :
899 var h3 = "Set Transport Source Port";
900 var placeholder = "Transport Source Port";
901 var id = one.f.flows.id.modal.action.modifyTransportSourcePort;
902 var help = "Range: 1 - 65535";
903 var action = 'SET_TP_SRC';
904 var name = "Source Port";
905 var body = function() {
906 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
908 var add = function($modal) {
909 one.f.flows.modal.action.add.set(name, id, action, $modal);
911 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
914 case "modifyTransportDestinationPort" :
915 var h3 = "Set Transport Destination Port";
916 var placeholder = "Transport Destination Port";
917 var id = one.f.flows.id.modal.action.modifyTransportDestinationPort;
918 var help = "Range: 1 - 65535";
919 var action = 'SET_TP_DST';
920 var name = "Destination Port";
921 var body = function() {
922 return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
924 var add = function($modal) {
925 one.f.flows.modal.action.add.set(name, id, action, $modal);
927 var $modal = one.f.flows.modal.action.initialize(h3, body, add);
933 one.f.flows.modal.action.add.add(name, action);
936 var name = "Loopback";
937 var action = 'LOOPBACK';
938 one.f.flows.modal.action.add.add(name, action);
942 var action = 'FLOOD';
943 one.f.flows.modal.action.add.add(name, action);
945 case "softwarePath" :
946 var name = "Software Path";
947 var action = 'SW_PATH';
948 one.f.flows.modal.action.add.add(name, action);
950 case "hardwarePath" :
951 var name = "Hardware Path";
952 var action = 'HW_PATH';
953 one.f.flows.modal.action.add.add(name, action);
956 var name = "Controller";
957 var action = 'CONTROLLER';
958 one.f.flows.modal.action.add.add(name, action);
962 initialize : function(h3, bodyCallback, addCallback) {
963 var footer = one.f.flows.modal.action.footer();
964 var $body = bodyCallback();
965 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal, h3, $body, footer);
967 $('#'+one.f.flows.id.modal.action.close, $modal).click(function() {
968 $modal.modal('hide');
970 // bind add flow button
971 $('#'+one.f.flows.id.modal.action.add, $modal).click(function() {
977 addOutputPorts : function($modal) {
978 var $options = $('#'+one.f.flows.id.modal.action.addOutputPorts).find('option:selected');
981 $options.each(function(index, value) {
982 ports = ports+$(value).text()+", ";
983 pid = pid+$(value).attr('value')+",";
985 ports = ports.slice(0,-2);
986 pid = pid.slice(0,-1);
987 var $tr = one.f.flows.modal.action.table.add("Add Output Ports", ports);
988 $tr.attr('id', 'addOutputPorts');
989 $tr.data('action', 'OUTPUT='+pid);
990 $tr.click(function() {
991 one.f.flows.modal.action.add.modal.initialize(this);
993 one.f.flows.modal.action.table.append($tr);
994 $modal.modal('hide');
996 add : function(name, action) {
997 var $tr = one.f.flows.modal.action.table.add(name);
998 $tr.attr('id', action);
999 $tr.data('action', action);
1000 $tr.click(function() {
1001 one.f.flows.modal.action.add.modal.initialize(this);
1003 one.f.flows.modal.action.table.append($tr);
1005 set : function(name, id, action, $modal) {
1006 var $input = $('#'+id);
1007 var value = $input.val();
1008 var $tr = one.f.flows.modal.action.table.add(name, value);
1009 $tr.attr('id', action);
1010 $tr.data('action', action+'='+value);
1011 $tr.click(function() {
1012 one.f.flows.modal.action.add.modal.initialize(this);
1014 one.f.flows.modal.action.table.append($tr);
1015 $modal.modal('hide');
1017 remove : function(that) {
1019 var $table = $('#'+one.f.flows.id.modal.action.table);
1020 if ($table.find('tbody').find('tr').size() == 0) {
1021 var $tr = $(document.createElement('tr'));
1022 var $td = $(document.createElement('td'));
1023 $td.attr('colspan', '3');
1024 $tr.addClass('empty');
1025 $td.text('No data available');
1027 $table.find('tbody').append($tr);
1031 initialize : function(that) {
1032 var h3 = "Remove Action";
1033 var footer = one.f.flows.modal.action.add.modal.footer();
1034 var $body = one.f.flows.modal.action.add.modal.body();
1035 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal.modal, h3, $body, footer);
1037 // bind cancel button
1038 $('#'+one.f.flows.id.modal.action.modal.cancel, $modal).click(function() {
1039 $modal.modal('hide');
1042 // bind remove button
1043 $('#'+one.f.flows.id.modal.action.modal.remove, $modal).click(function() {
1044 one.f.flows.modal.action.add.remove(that);
1045 $modal.modal('hide');
1051 var $p = $(document.createElement('p'));
1052 $p.append("Remove this action?");
1055 footer : function() {
1058 var removeButton = one.lib.dashlet.button.single("Remove Action", one.f.flows.id.modal.action.modal.remove, "btn-danger", "");
1059 var $removeButton = one.lib.dashlet.button.button(removeButton);
1060 footer.push($removeButton);
1062 var cancelButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.action.modal.cancel, "", "");
1063 var $cancelButton = one.lib.dashlet.button.button(cancelButton);
1064 footer.push($cancelButton);
1071 add : function(action, data, type) {
1072 var $tr = $(document.createElement('tr'));
1073 var $td = $(document.createElement('td'));
1076 var $td = $(document.createElement('td'));
1077 if (data != undefined) $td.append(data);
1079 var $td = $(document.createElement('td'));
1080 if (type != undefined) $td.append(type);
1084 append : function($tr) {
1085 var $table = $('#'+one.f.flows.id.modal.action.table);
1086 var $empty = $table.find('.empty').parent();
1087 if ($empty.size() > 0) $empty.remove();
1092 common : function() {
1093 var $form = $(document.createElement('form'));
1094 var $fieldset = $(document.createElement('fieldset'));
1095 return [$form, $fieldset];
1097 addOutputPorts : function() {
1098 var common = one.f.flows.modal.action.body.common();
1099 var $form = common[0];
1100 var $fieldset = common[1];
1102 $label = one.lib.form.label("Select Output Ports");
1103 var ports = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports'];
1104 $select = one.lib.form.select.create(ports, true);
1105 $select.attr('id', one.f.flows.id.modal.action.addOutputPorts);
1106 one.lib.form.select.prepend($select, {'':'Select a Port'});
1107 $fieldset.append($label).append($select);
1108 $form.append($fieldset);
1111 set : function(label, placeholder, id, help) {
1112 var common = one.f.flows.modal.action.body.common();
1113 var $form = common[0];
1114 var $fieldset = common[1];
1116 $label = one.lib.form.label(label);
1117 $input = one.lib.form.input(placeholder);
1118 $input.attr('id', id);
1119 $help = one.lib.form.help(help);
1121 $fieldset.append($label).append($input).append($help);
1122 $form.append($fieldset);
1126 footer : function() {
1128 var addButton = one.lib.dashlet.button.single("Add Action", one.f.flows.id.modal.action.add, "btn-primary", "");
1129 var $addButton = one.lib.dashlet.button.button(addButton);
1130 footer.push($addButton);
1132 var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.action.close, "", "");
1133 var $closeButton = one.lib.dashlet.button.button(closeButton);
1134 footer.push($closeButton);
1139 footer : function() {
1142 var installButton = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.modal.install, "btn-success", "");
1143 var $installButton = one.lib.dashlet.button.button(installButton);
1144 footer.push($installButton);
1146 var addButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.add, "btn-primary", "");
1147 var $addButton = one.lib.dashlet.button.button(addButton);
1148 footer.push($addButton);
1150 var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", "");
1151 var $closeButton = one.lib.dashlet.button.button(closeButton);
1152 footer.push($closeButton);
1158 dashlet : function(callback) {
1159 $.getJSON(one.f.address.root+one.f.address.flows.main, function(data) {
1160 one.f.flows.registry['flows'] = data;
1161 var body = one.f.flows.data.dashlet(data);
1162 var $body = one.f.flows.body.dashlet(body, callback);
1168 dashlet : function(data) {
1170 $(data).each(function(index, value) {
1173 entry.push(value['name']);
1174 entry.push(value['node']);
1175 if (value['flow']['installInHw'] == 'true')
1176 tr['type'] = ['success'];
1177 else if (value['flow']['installInHw'] == 'false')
1178 tr['type'] = ['warning'];
1179 tr['entry'] = entry;
1180 tr['id'] = value['nodeId'];
1188 dashlet : function(body, callback) {
1189 var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed', 'table-cursor'];
1190 var $table = one.lib.dashlet.table.table(attributes);
1192 var headers = ['Flow Name', 'Node'];
1193 var $thead = one.lib.dashlet.table.header(headers);
1194 $table.append($thead);
1196 var $tbody = one.lib.dashlet.table.body(body);
1197 $table.append($tbody);
1205 // populate nav tabs
1206 $(one.f.menu.left.top).each(function(index, value) {
1207 var $nav = $(".nav", "#left-top");
1208 one.main.page.dashlet($nav, value);
1211 $(one.f.menu.left.bottom).each(function(index, value) {
1212 var $nav = $(".nav", "#left-bottom");
1213 one.main.page.dashlet($nav, value);
1216 $(one.f.menu.right.bottom).each(function(index, value) {
1217 var $nav = $(".nav", "#right-bottom");
1218 one.main.page.dashlet($nav, value);
1221 one.f.populate = function($dashlet, header) {
1222 var $h4 = one.lib.dashlet.header(header);
1223 $dashlet.append($h4);
1227 $('.dash .nav a', '#main').click(function() {
1229 var $li = $(this).parent();
1230 var $ul = $li.parent();
1231 one.lib.nav.unfocus($ul);
1232 $li.addClass('active');
1233 // clear respective dashlet
1234 var $dashlet = $ul.parent().find('.dashlet');
1235 one.lib.dashlet.empty($dashlet);
1236 // callback based on menu
1237 var id = $(this).attr('id');
1238 var menu = one.f.dashlet;
1241 one.f.flows.dashlet($dashlet);
1244 one.f.nodes.dashlet($dashlet);
1246 case menu.detail.id:
1247 one.f.detail.dashlet($dashlet);
1252 // activate first tab on each dashlet
1253 $('.dash .nav').each(function(index, value) {
1254 $($(value).find('li')[0]).find('a').click();