diff --git a/webroot/config/networking/port/ui/js/models/fatFlowModel.js b/webroot/config/networking/port/ui/js/models/fatFlowModel.js new file mode 100644 index 000000000..08acb23bf --- /dev/null +++ b/webroot/config/networking/port/ui/js/models/fatFlowModel.js @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved. + */ + +define([ + 'underscore', + 'contrail-model' +], function (_, ContrailModel) { + var fatFlowModel = ContrailModel.extend({ + + defaultConfig: { + 'protocol': 'tcp', + 'port':'' + }, + + validateAttr: function (attributePath, validation, data) { + var model = data.model().attributes.model(), + attr = cowu.getAttributeFromPath(attributePath), + errors = model.get(cowc.KEY_MODEL_ERRORS), + attrErrorObj = {}, isValid; + + isValid = model.isValid(attributePath, validation); + + attrErrorObj[attr + cowc.ERROR_SUFFIX_ID] = + (isValid == true) ? false : isValid; + errors.set(attrErrorObj); + }, + + + validations: { + fatFlowValidations: { + 'protocol': { + required: true, + msg: 'Select a protocol.' + }, + 'port': function(value, attr, finalObj) { + if(finalObj.protocol != "icmp") { + if(value.trim() == "") { + return "Enter valid port between 1 to 65535 for Fat Flow Record"; + } + if (!isNumber(value)) { + return "Fat Flow Protocol's Port has to be a number"; + } + if (value % 1 != 0) { + return "Fat Flow Protocol's Port has to be a number"; + } + if (Number(value) < 1 || Number(value) > 65535) { + return "Enter valid port between 1 to 65535 for Fat Flow Record"; + } + } else { + if(value.trim() != "0") { + return "ICMP can have only 0"; + } + } + } + } + } + }); + return fatFlowModel; +}); \ No newline at end of file diff --git a/webroot/config/networking/port/ui/js/models/portModel.js b/webroot/config/networking/port/ui/js/models/portModel.js index 7f37a9bb1..da0d5ca4f 100644 --- a/webroot/config/networking/port/ui/js/models/portModel.js +++ b/webroot/config/networking/port/ui/js/models/portModel.js @@ -10,9 +10,10 @@ define([ 'config/networking/port/ui/js/models/fixedIPModel', 'config/networking/port/ui/js/models/allowAddressPairModel', 'config/networking/port/ui/js/models/dhcpOptionModel', + 'config/networking/port/ui/js/models/fatFlowModel', 'config/networking/port/ui/js/models/staticRouteModel' ], function (_, ContrailModel, PortFormatters, FixedIPModel, - AllowAddressPairModel, DHCPOptionModel, StaticRouteModel) { + AllowAddressPairModel, DHCPOptionModel, FatFlowModel, StaticRouteModel) { var portFormatters = new PortFormatters(); var self; var subnetDataSource = []; @@ -51,10 +52,15 @@ define([ 'interface_route_table_refs':[], 'virtual_machine_interface_dhcp_option_list':{'dhcp_option':[]}, 'dhcpOptionCollection':[], + 'virtual_machine_interface_fat_flow_protocols': { + 'fat_flow_protocol':[] + }, + 'fatFlowCollection': [], 'virtual_machine_interface_properties':{'sub_interface_vlan_tag':''}, 'fixedIPCollection': [], 'display_name': '', 'virtual_machine_interface_refs': [], + 'disablePort':false, 'is_sub_interface':false, 'subInterfaceVMIValue':'', 'templateGeneratorData': 'rawData', @@ -219,7 +225,7 @@ define([ for(var i = 0; i < staticRouteLen; i++) { var staticRoute_obj = staticRouteList[i]; var staticRouteOptionModel = - new DHCPOptionModel(staticRoute_obj); + new StaticRouteModel(staticRoute_obj); staticRoute.push(staticRouteOptionModel); } @@ -229,6 +235,25 @@ define([ new Backbone.Collection(staticRoute); modelConfig['staticRouteCollection'] = staticRouteCollectionModel; + //Modal config default Fat Flow option formatting + var fatFlows = []; + var fatFlowList = + modelConfig["virtual_machine_interface_fat_flow_protocols"]["fat_flow_protocol"]; + if(fatFlowList != null && fatFlowList.length > 0) { + var fatFlowLen = fatFlowList.length; + for(var i = 0; i < fatFlowLen; i++) { + var fatFlow_obj = fatFlowList[i]; + var fatFlowModel = new FatFlowModel(fatFlow_obj); + this.enableDisablePort(fatFlowModel); + fatFlows.push(fatFlowModel); + } + } + var fatFlowCollectionModel = new Backbone.Collection(fatFlows); + modelConfig["virtual_machine_interface_fat_flow_protocols"]["fat_flow_protocol"] + = fatFlowCollectionModel; + modelConfig['fatFlowCollection'] = fatFlowCollectionModel; + + //Modal config default Device Owner formatting var deviceOwnerValue = "none"; var devOwner = modelConfig['virtual_machine_interface_device_owner']; @@ -411,6 +436,33 @@ define([ dhcpCollection.remove(delDHCP); }, + //Fat Flow Add + addFatFlow: function() { + var fatFlowList = this.model().attributes['fatFlowCollection'], + fatFlowModel = new FatFlowModel(); + this.enableDisablePort(fatFlowModel); + fatFlowList.add([fatFlowModel]); + }, + //Fat Flow Delete + deleteFatFlow: function(data, fatFlow) { + var fatFlowCollection = data.model().collection, + delFatFlow = fatFlow.model(); + fatFlowCollection.remove(delFatFlow); + }, + enableDisablePort: function(fatFlowModel) { + fatFlowModel.disablePort = ko.computed((function() { + if(this.protocol() == "icmp") { + this.port("0"); + return true; + } else { + if(this.port() == "0") { + this.port(""); + } + return false; + } + }), fatFlowModel); + }, + // Static Route Add addStaticRoute: function() { var staticRouteList = this.model().attributes['staticRouteCollection'], @@ -524,6 +576,19 @@ define([ = newPortData['macAddress']; delete(newPortData['macAddress']); } + //Fat Flow + var fatFlowCollection = + newPortData["fatFlowCollection"].toJSON(); + newPortData.virtual_machine_interface_fat_flow_protocols = {}; + if (fatFlowCollection && fatFlowCollection.length > 0) { + var fatFlowLocal = []; + for(i = 0 ; i< fatFlowCollection.length ; i++){ + fatFlowLocal[i] = {}; + fatFlowLocal[i]["protocol"] = fatFlowCollection[i].protocol(); + fatFlowLocal[i]["port"] = Number(fatFlowCollection[i].port()); + } + newPortData.virtual_machine_interface_fat_flow_protocols.fat_flow_protocol = fatFlowLocal; + } //DHCP var allDHCPValues = newPortData["dhcpOptionCollection"].toJSON(); newPortData.virtual_machine_interface_dhcp_option_list = {}; @@ -783,6 +848,7 @@ define([ delete(newPortData.securityGroupValue); delete(newPortData.floatingIpValue); delete(newPortData.allowedAddressPairCollection); + delete(newPortData.fatFlowCollection); delete(newPortData.staticRouteCollection); delete(newPortData.deviceOwnerValue); delete(newPortData.logicalRouterValue); diff --git a/webroot/config/networking/port/ui/js/views/portEditView.js b/webroot/config/networking/port/ui/js/views/portEditView.js index 3058c7d76..2fac3f534 100644 --- a/webroot/config/networking/port/ui/js/views/portEditView.js +++ b/webroot/config/networking/port/ui/js/views/portEditView.js @@ -110,6 +110,10 @@ define([ {collection: self.model.model().attributes.allowedAddressPairCollection} ); + kbValidation.bind(self, + {collection: + self.model.model().attributes.fatFlowCollection} + ); kbValidation.bind(self, {collection: self.model.model().attributes.staticRouteCollection} @@ -565,6 +569,64 @@ define([ }] } }] + },{ + columns: [{ + elementId: 'fatFlowCollection', + view: 'FormEditableGridView', + viewConfig: { + label:"Fat Flow", + path: "fatFlowCollection", + validation: 'fatFlowValidations', + collection: "fatFlowCollection", + columns: [{ + elementId: 'protocol', + name: "Protocol", + view: "FormDropdownView", + viewConfig: { + path: 'protocol', + templateId: cowc.TMPL_EDITABLE_GRID_DROPDOWN_VIEW, + dataBindValue: 'protocol()', + placeholder: 'Protocol', + class: "span6", + width:275, + label: 'Protocol', + elementConfig:{ + dataTextField: "text", + dataValueField: "value", + data : [ + {'text':'TCP','value':'tcp'}, + {'text':'UDP','value':'udp'}, + {'text':'SCTP','value':'sctp'}, + {'text':'ICMP','value':'icmp'} + ] + } + } + }, { + elementId: 'port', + name: "Value", + view: "FormInputView", + viewConfig: { + path: 'port', + placeholder: 'Port', + templateId: cowc.TMPL_EDITABLE_GRID_INPUT_VIEW, + dataBindValue: 'port()', + disabled: "disablePort()", + class: "span6", + width:275, + label: 'Value' + } + }], + rowActions: [{ + onClick: + "function() { $root.deleteFatFlow($data, this); }", + iconClass: 'icon-minus' + }], + gridActions: [{ + onClick: "function() { addFatFlow(); }", + buttonTitle: "Add Fat Flow" + }] + } + }] }, { columns: [{ elementId: 'deviceOwnerValue', diff --git a/webroot/config/networking/port/ui/js/views/portFormatters.js b/webroot/config/networking/port/ui/js/views/portFormatters.js index 782eed646..544fccb48 100644 --- a/webroot/config/networking/port/ui/js/views/portFormatters.js +++ b/webroot/config/networking/port/ui/js/views/portFormatters.js @@ -222,6 +222,29 @@ define([ } return staticRout; }; + //Grid column expand label: Fat Flow// + this.FatFlowFormatter = function(d, c, v, cd, dc) { + var fatFlow = ""; + var fatFlowData = getValueByJsonPath(dc, + "virtual_machine_interface_fat_flow_protocols;fat_flow_protocol", + []); + if(fatFlowData.length > 0) { + var fatFlow_length = fatFlowData.length; + fatFlow = "" + for(var i = 0; i < fatFlow_length;i++) { + var fatFlowVal = fatFlowData[i]; + fatFlow += ""; + } + fatFlow += "
ProtocolPort
"; + fatFlow += fatFlowVal["protocol"]; + fatFlow += ""; + fatFlow += fatFlowVal["port"]; + fatFlow += "
"; + } else { + fatFlow = "-"; + } + return fatFlow; + }; //Grid column expand label: Allowed address pairs// this.AAPFormatter = function(d, c, v, cd, dc) { var AAP = ""; @@ -462,7 +485,7 @@ define([ deviceVMIValue = uuid +" "+to; returnComputeUUID.push({"text":text,"value":deviceVMIValue}); } - if((!edit && returnComputeUUID.length > 0) || + if((returnComputeUUID.length > 0) && (edit && portModel.model.deviceOwnerValue() != "compute")) { portModel.model.virtualMachineValue(returnComputeUUID[0].value); } diff --git a/webroot/config/networking/port/ui/js/views/portGridView.js b/webroot/config/networking/port/ui/js/views/portGridView.js index a10678f47..a266df4c2 100644 --- a/webroot/config/networking/port/ui/js/views/portGridView.js +++ b/webroot/config/networking/port/ui/js/views/portGridView.js @@ -404,6 +404,14 @@ define([ templateGeneratorConfig:{ formatter: "staticRoutFormatter" } + }, { + key: 'virtual_machine_interface_fat_flow_protocols', + name:"virtual_machine_interface_fat_flow_protocols", + label:"FatFlow", + templateGenerator: 'TextGenerator', + templateGeneratorConfig:{ + formatter: "FatFlowFormatter" + } }, { key: 'virtual_machine_interface_allowed_address_pairs', name:"virtual_machine_interface_allowed_address_pairs", @@ -489,6 +497,9 @@ define([ this.AAPFormatter = function(v, dc) { return portFormatters.AAPFormatter("", "", v, "", dc); }; + this.FatFlowFormatter = function(v, dc) { + return portFormatters.FatFlowFormatter("", "", v, "", dc); + }; this.fixedIPFormaterExpand = function(v, dc) { return portFormatters.fixedIPFormaterExpand("", "", v, "", dc); };