mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-05-19 17:54:13 +00:00

IPv6 address shown in cidr notation in the IP address column, the subnet column only includes the ipv4 subnet mask, the gateway includes both.
314 lines
7.0 KiB
JavaScript
314 lines
7.0 KiB
JavaScript
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 === '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: '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: 'numberfield',
|
|
deleteEmpty: !me.create,
|
|
fieldLabel: gettext('Prefix length'),
|
|
name: 'netmask6',
|
|
value: '',
|
|
minValue: 0,
|
|
maxValue: 128,
|
|
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
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|