--- /dev/null
+Ext.define('PVE.node.NetworkEdit', {
+ extend: 'PVE.window.Edit',
+ alias: ['widget.pveNodeNetworkEdit'],
+
+ initComponent : function() {
+ var me = this;
+
+ var nodename = me.pveSelNode.data.node;
+ if (!nodename) {
+ throw "no node name specified";
+ }
+
+ if (!me.iftype) {
+ throw "no network device type specified";
+ }
+
+ me.create = !me.iface;
+
+ var iface_vtype;
+
+ if (me.iftype === 'bridge') {
+ iface_vtype = 'BridgeName';
+ } else if (me.iftype === 'bond') {
+ iface_vtype = 'BondName';
+ } else if (me.iftype === 'eth' && !me.create) {
+ iface_vtype = 'InterfaceName';
+ } else if (me.iftype === 'vlan' && !me.create) {
+ iface_vtype = 'InterfaceName';
+ } else if (me.iftype === 'OVSBridge') {
+ iface_vtype = 'BridgeName';
+ } else if (me.iftype === 'OVSBond') {
+ iface_vtype = 'BondName';
+ } else if (me.iftype === 'OVSIntPort') {
+ iface_vtype = 'InterfaceName';
+ } else if (me.iftype === 'OVSPort') {
+ iface_vtype = 'InterfaceName';
+ } else {
+ console.log(me.iftype);
+ throw "unknown network device type specified";
+ }
+
+ me.subject = PVE.Utils.render_network_iface_type(me.iftype);
+
+ var column2 = [];
+
+ if (!(me.iftype === 'OVSIntPort' || me.iftype === 'OVSPort' ||
+ me.iftype === 'OVSBond')) {
+ column2.push({
+ xtype: 'pvecheckbox',
+ fieldLabel: gettext('Autostart'),
+ name: 'autostart',
+ uncheckedValue: 0,
+ checked: me.create ? true : undefined
+ });
+ }
+
+ if (me.iftype === 'bridge') {
+ column2.push({
+ xtype: 'pvecheckbox',
+ fieldLabel: gettext('Vlan Aware'),
+ name: 'bridge_vlan_aware',
+ deleteEmpty: !me.create,
+ });
+ column2.push({
+ xtype: 'textfield',
+ fieldLabel: gettext('Bridge ports'),
+ name: 'bridge_ports'
+ });
+ } else if (me.iftype === 'OVSBridge') {
+ column2.push({
+ xtype: 'textfield',
+ fieldLabel: gettext('Bridge ports'),
+ name: 'ovs_ports'
+ });
+ column2.push({
+ xtype: 'textfield',
+ fieldLabel: gettext('OVS options'),
+ name: 'ovs_options'
+ });
+ } else if (me.iftype === 'OVSPort' || me.iftype === 'OVSIntPort') {
+ column2.push({
+ xtype: me.create ? 'PVE.form.BridgeSelector' : 'displayfield',
+ height: 22, // hack: set same height as text fields
+ fieldLabel: PVE.Utils.render_network_iface_type('OVSBridge'),
+ allowBlank: false,
+ nodename: nodename,
+ bridgeType: 'OVSBridge',
+ name: 'ovs_bridge'
+ });
+ column2.push({
+ xtype: 'pveVlanField',
+ deleteEmpty: !me.create,
+ name: 'ovs_tag',
+ value: ''
+ });
+ column2.push({
+ xtype: 'textfield',
+ fieldLabel: gettext('OVS options'),
+ name: 'ovs_options'
+ });
+ } else if (me.iftype === 'bond') {
+ column2.push({
+ xtype: 'textfield',
+ fieldLabel: gettext('Slaves'),
+ name: 'slaves'
+ });
+
+ var policySelector = Ext.createWidget('bondPolicySelector', {
+ fieldLabel: gettext('Hash policy'),
+ name: 'bond_xmit_hash_policy',
+ deleteEmpty: !me.create,
+ disabled: true
+ });
+
+ column2.push({
+ xtype: 'bondModeSelector',
+ fieldLabel: gettext('Mode'),
+ name: 'bond_mode',
+ value: me.create ? 'balance-rr' : undefined,
+ listeners: {
+ change: function(f, value) {
+ if (value === 'balance-xor' ||
+ value === '802.3ad') {
+ policySelector.setDisabled(false);
+ } else {
+ policySelector.setDisabled(true);
+ policySelector.setValue('');
+ }
+ }
+ },
+ allowBlank: false
+ });
+
+ column2.push(policySelector);
+
+ } else if (me.iftype === 'OVSBond') {
+ column2.push({
+ xtype: me.create ? 'PVE.form.BridgeSelector' : 'displayfield',
+ height: 22, // hack: set same height as text fields
+ fieldLabel: PVE.Utils.render_network_iface_type('OVSBridge'),
+ allowBlank: false,
+ nodename: nodename,
+ bridgeType: 'OVSBridge',
+ name: 'ovs_bridge'
+ });
+ column2.push({
+ xtype: 'pveVlanField',
+ deleteEmpty: !me.create,
+ name: 'ovs_tag',
+ value: ''
+ });
+ column2.push({
+ xtype: 'textfield',
+ fieldLabel: gettext('OVS options'),
+ name: 'ovs_options'
+ });
+ }
+
+ var url;
+ var method;
+
+ if (me.create) {
+ url = "/api2/extjs/nodes/" + nodename + "/network";
+ method = 'POST';
+ } else {
+ url = "/api2/extjs/nodes/" + nodename + "/network/" + me.iface;
+ method = 'PUT';
+ }
+
+ var column1 = [
+ {
+ xtype: 'hiddenfield',
+ name: 'type',
+ value: me.iftype
+ },
+ {
+ xtype: me.create ? 'textfield' : 'displayfield',
+ fieldLabel: gettext('Name'),
+ height: 22, // hack: set same height as text fields
+ name: 'iface',
+ value: me.iface,
+ vtype: iface_vtype,
+ allowBlank: false
+ }
+ ];
+
+ if (me.iftype === 'OVSBond') {
+ column1.push([
+ {
+ xtype: 'bondModeSelector',
+ fieldLabel: gettext('Mode'),
+ name: 'bond_mode',
+ openvswitch: true,
+ value: me.create ? 'active-backup' : undefined,
+ allowBlank: false
+ },
+ {
+ xtype: 'textfield',
+ fieldLabel: gettext('Slaves'),
+ name: 'ovs_bonds'
+ }
+ ]);
+ } else {
+
+ column1.push([
+ {
+ xtype: 'pvetextfield',
+ deleteEmpty: !me.create,
+ fieldLabel: gettext('IP address'),
+ vtype: 'IPAddress',
+ name: 'address'
+ },
+ {
+ xtype: 'pvetextfield',
+ deleteEmpty: !me.create,
+ fieldLabel: gettext('Subnet mask'),
+ vtype: 'IPAddress',
+ name: 'netmask',
+ validator: function(value) {
+ /*jslint confusion: true */
+ if (!me.items) {
+ return true;
+ }
+ var address = me.down('field[name=address]').getValue();
+ if (value !== '') {
+ if (address === '') {
+ return "Subnet mask requires option 'IP address'";
+ }
+ } else {
+ if (address !== '') {
+ return "Option 'IP address' requires a subnet mask";
+ }
+ }
+
+ return true;
+ }
+ },
+ {
+ xtype: 'pvetextfield',
+ deleteEmpty: !me.create,
+ fieldLabel: gettext('Gateway'),
+ vtype: 'IPAddress',
+ name: 'gateway'
+ },
+ {
+ xtype: 'pvetextfield',
+ deleteEmpty: !me.create,
+ fieldLabel: gettext('IPv6 address'),
+ vtype: 'IP6Address',
+ name: 'address6'
+ },
+ {
+ xtype: 'pvetextfield',
+ deleteEmpty: !me.create,
+ fieldLabel: gettext('Prefix length'),
+ vtype: 'IP6PrefixLength',
+ name: 'netmask6',
+ value: '',
+ allowBlank: true,
+ validator: function(value) {
+ /*jslint confusion: true */
+ if (!me.items) {
+ return true;
+ }
+ var address = me.down('field[name=address6]').getValue();
+ if (value !== '') {
+ if (address === '') {
+ return "IPv6 prefix length requires option 'IPv6 address'";
+ }
+ } else {
+ if (address !== '') {
+ return "Option 'IPv6 address' requires an IPv6 prefix length";
+ }
+ }
+
+ return true;
+ }
+ },
+ {
+ xtype: 'pvetextfield',
+ deleteEmpty: !me.create,
+ fieldLabel: gettext('Gateway'),
+ vtype: 'IP6Address',
+ name: 'gateway6'
+ }
+ ]);
+ }
+
+ Ext.applyIf(me, {
+ url: url,
+ method: method,
+ items: {
+ xtype: 'inputpanel',
+ column1: column1,
+ column2: column2
+ }
+ });
+
+ me.callParent();
+
+ if (me.create) {
+ me.down('field[name=iface]').setValue(me.iface_default);
+ } else {
+ me.load({
+ success: function(response, options) {
+ var data = response.result.data;
+ if (data.type !== me.iftype) {
+ var msg = "Got unexpected device type";
+ Ext.Msg.alert(gettext('Error'), msg, function() {
+ me.close();
+ });
+ return;
+ }
+ me.setValues(data);
+ me.isValid(); // trigger validation
+ }
+ });
+ }
+ }
+});