]> git.proxmox.com Git - proxmox-widget-toolkit.git/blame - src/node/NetworkEdit.js
fix #2703: networkedit: limit custom interface name field to 15 characters.
[proxmox-widget-toolkit.git] / src / node / NetworkEdit.js
CommitLineData
a58001dd
DM
1Ext.define('Proxmox.node.NetworkEdit', {
2 extend: 'Proxmox.window.Edit',
3 alias: ['widget.proxmoxNodeNetworkEdit'],
4
01031528 5 initComponent: function() {
05a977a2 6 let me = this;
a58001dd
DM
7
8 if (!me.nodename) {
9 throw "no node name specified";
10 }
11
12 if (!me.iftype) {
13 throw "no network device type specified";
14 }
15
b33f451f 16 me.isCreate = !me.iface;
a58001dd 17
05a977a2 18 let iface_vtype;
a58001dd
DM
19
20 if (me.iftype === 'bridge') {
21 iface_vtype = 'BridgeName';
22 } else if (me.iftype === 'bond') {
23 iface_vtype = 'BondName';
b33f451f 24 } else if (me.iftype === 'eth' && !me.isCreate) {
a58001dd 25 iface_vtype = 'InterfaceName';
8aefd47c
AD
26 } else if (me.iftype === 'vlan') {
27 iface_vtype = 'VlanName';
a58001dd
DM
28 } else if (me.iftype === 'OVSBridge') {
29 iface_vtype = 'BridgeName';
30 } else if (me.iftype === 'OVSBond') {
31 iface_vtype = 'BondName';
32 } else if (me.iftype === 'OVSIntPort') {
33 iface_vtype = 'InterfaceName';
34 } else if (me.iftype === 'OVSPort') {
35 iface_vtype = 'InterfaceName';
36 } else {
37 console.log(me.iftype);
38 throw "unknown network device type specified";
39 }
40
41 me.subject = Proxmox.Utils.render_network_iface_type(me.iftype);
42
5c833def
TL
43 let column1 = [],
44 column2 = [],
1aaba242 45 columnB = [],
5c833def
TL
46 advancedColumn1 = [],
47 advancedColumn2 = [];
a58001dd 48
5c833def 49 if (!(me.iftype === 'OVSIntPort' || me.iftype === 'OVSPort' || me.iftype === 'OVSBond')) {
a58001dd 50 column2.push({
fccec7c6 51 xtype: 'proxmoxcheckbox',
a58001dd
DM
52 fieldLabel: gettext('Autostart'),
53 name: 'autostart',
54 uncheckedValue: 0,
01031528 55 checked: me.isCreate ? true : undefined,
a58001dd
DM
56 });
57 }
58
59 if (me.iftype === 'bridge') {
60 column2.push({
fccec7c6 61 xtype: 'proxmoxcheckbox',
a58001dd
DM
62 fieldLabel: gettext('VLAN aware'),
63 name: 'bridge_vlan_aware',
01031528 64 deleteEmpty: !me.isCreate,
a58001dd
DM
65 });
66 column2.push({
67 xtype: 'textfield',
68 fieldLabel: gettext('Bridge ports'),
01031528 69 name: 'bridge_ports',
a58001dd
DM
70 });
71 } else if (me.iftype === 'OVSBridge') {
72 column2.push({
73 xtype: 'textfield',
74 fieldLabel: gettext('Bridge ports'),
01031528 75 name: 'ovs_ports',
a58001dd
DM
76 });
77 column2.push({
78 xtype: 'textfield',
79 fieldLabel: gettext('OVS options'),
01031528 80 name: 'ovs_options',
a58001dd
DM
81 });
82 } else if (me.iftype === 'OVSPort' || me.iftype === 'OVSIntPort') {
83 column2.push({
b33f451f 84 xtype: me.isCreate ? 'PVE.form.BridgeSelector' : 'displayfield',
a58001dd
DM
85 fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'),
86 allowBlank: false,
87 nodename: me.nodename,
88 bridgeType: 'OVSBridge',
01031528 89 name: 'ovs_bridge',
a58001dd
DM
90 });
91 column2.push({
92 xtype: 'pveVlanField',
b33f451f 93 deleteEmpty: !me.isCreate,
a58001dd 94 name: 'ovs_tag',
01031528 95 value: '',
a58001dd
DM
96 });
97 column2.push({
98 xtype: 'textfield',
99 fieldLabel: gettext('OVS options'),
01031528 100 name: 'ovs_options',
a58001dd 101 });
8aefd47c 102 } else if (me.iftype === 'vlan') {
ea7da80c 103 if (!me.isCreate) {
ea7da80c
TL
104 me.disablevlanid = false;
105 me.disablevlanrawdevice = false;
106 me.vlanrawdevicevalue = '';
107 me.vlanidvalue = '';
8aefd47c 108
ea7da80c
TL
109 if (Proxmox.Utils.VlanInterface_match.test(me.iface)) {
110 me.disablevlanid = true;
111 me.disablevlanrawdevice = true;
05a977a2 112 let arr = Proxmox.Utils.VlanInterface_match.exec(me.iface);
ea7da80c
TL
113 me.vlanrawdevicevalue = arr[1];
114 me.vlanidvalue = arr[2];
ea7da80c
TL
115 } else if (Proxmox.Utils.Vlan_match.test(me.iface)) {
116 me.disablevlanid = true;
05a977a2 117 let arr = Proxmox.Utils.Vlan_match.exec(me.iface);
ea7da80c
TL
118 me.vlanidvalue = arr[1];
119 }
120 } else {
ea7da80c
TL
121 me.disablevlanid = true;
122 me.disablevlanrawdevice = true;
8aefd47c
AD
123 }
124
125 column2.push({
126 xtype: 'textfield',
127 fieldLabel: gettext('Vlan raw device'),
128 name: 'vlan-raw-device',
ea7da80c 129 value: me.vlanrawdevicevalue,
01031528 130 disabled: me.disablevlanrawdevice,
418ec858 131 allowBlank: false,
8aefd47c
AD
132 });
133
134 column2.push({
135 xtype: 'pveVlanField',
136 name: 'vlan-id',
ea7da80c 137 value: me.vlanidvalue,
01031528 138 disabled: me.disablevlanid,
1aaba242 139 });
8aefd47c 140
1aaba242
TL
141 columnB.push({
142 xtype: 'label',
143 userCls: 'pmx-hint',
144 text: 'Either add the VLAN number to an existing interface name, or choose your own name and set the VLAN raw device (for the latter ifupdown1 supports vlanXY naming only)',
8aefd47c 145 });
a58001dd
DM
146 } else if (me.iftype === 'bond') {
147 column2.push({
148 xtype: 'textfield',
149 fieldLabel: gettext('Slaves'),
01031528 150 name: 'slaves',
a58001dd
DM
151 });
152
05a977a2 153 let policySelector = Ext.createWidget('bondPolicySelector', {
a58001dd
DM
154 fieldLabel: gettext('Hash policy'),
155 name: 'bond_xmit_hash_policy',
b33f451f 156 deleteEmpty: !me.isCreate,
01031528 157 disabled: true,
a58001dd
DM
158 });
159
05a977a2 160 let primaryfield = Ext.createWidget('textfield', {
0915cbb1 161 fieldLabel: 'bond-primary',
b154853a
AD
162 name: 'bond-primary',
163 value: '',
01031528 164 disabled: true,
b154853a
AD
165 });
166
a58001dd
DM
167 column2.push({
168 xtype: 'bondModeSelector',
169 fieldLabel: gettext('Mode'),
170 name: 'bond_mode',
b33f451f 171 value: me.isCreate ? 'balance-rr' : undefined,
a58001dd
DM
172 listeners: {
173 change: function(f, value) {
174 if (value === 'balance-xor' ||
175 value === '802.3ad') {
176 policySelector.setDisabled(false);
b154853a
AD
177 primaryfield.setDisabled(true);
178 primaryfield.setValue('');
179 } else if (value === 'active-backup') {
180 primaryfield.setDisabled(false);
181 policySelector.setDisabled(true);
182 policySelector.setValue('');
a58001dd
DM
183 } else {
184 policySelector.setDisabled(true);
185 policySelector.setValue('');
b154853a
AD
186 primaryfield.setDisabled(true);
187 primaryfield.setValue('');
a58001dd 188 }
01031528 189 },
a58001dd 190 },
01031528 191 allowBlank: false,
a58001dd
DM
192 });
193
194 column2.push(policySelector);
b154853a 195 column2.push(primaryfield);
a58001dd
DM
196 } else if (me.iftype === 'OVSBond') {
197 column2.push({
b33f451f 198 xtype: me.isCreate ? 'PVE.form.BridgeSelector' : 'displayfield',
a58001dd
DM
199 fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'),
200 allowBlank: false,
201 nodename: me.nodename,
202 bridgeType: 'OVSBridge',
01031528 203 name: 'ovs_bridge',
a58001dd
DM
204 });
205 column2.push({
206 xtype: 'pveVlanField',
b33f451f 207 deleteEmpty: !me.isCreate,
a58001dd 208 name: 'ovs_tag',
01031528 209 value: '',
a58001dd
DM
210 });
211 column2.push({
212 xtype: 'textfield',
213 fieldLabel: gettext('OVS options'),
01031528 214 name: 'ovs_options',
a58001dd
DM
215 });
216 }
217
218 column2.push({
219 xtype: 'textfield',
220 fieldLabel: gettext('Comment'),
221 allowBlank: true,
222 nodename: me.nodename,
01031528 223 name: 'comments',
a58001dd
DM
224 });
225
05a977a2
TL
226 let url;
227 let method;
a58001dd 228
b33f451f 229 if (me.isCreate) {
a58001dd
DM
230 url = "/api2/extjs/nodes/" + me.nodename + "/network";
231 method = 'POST';
232 } else {
233 url = "/api2/extjs/nodes/" + me.nodename + "/network/" + me.iface;
234 method = 'PUT';
235 }
236
5c833def 237 column1.push({
ea7da80c
TL
238 xtype: 'hiddenfield',
239 name: 'type',
01031528 240 value: me.iftype,
ea7da80c
TL
241 },
242 {
243 xtype: me.isCreate ? 'textfield' : 'displayfield',
244 fieldLabel: gettext('Name'),
245 name: 'iface',
246 value: me.iface,
247 vtype: iface_vtype,
248 allowBlank: false,
60ed17bf 249 maxLength: 15,
4ed84281
DJ
250 autoEl: {
251 tag: 'div',
252 'data-qtip': gettext('For example, vmbr0.100, vmbr0, vlan0.100, vlan0'),
253 },
ea7da80c
TL
254 listeners: {
255 change: function(f, value) {
256 if (me.isCreate && iface_vtype === 'VlanName') {
05a977a2
TL
257 let vlanidField = me.down('field[name=vlan-id]');
258 let vlanrawdeviceField = me.down('field[name=vlan-raw-device]');
ea7da80c
TL
259 if (Proxmox.Utils.VlanInterface_match.test(value)) {
260 vlanidField.setDisabled(true);
261 vlanrawdeviceField.setDisabled(true);
0174c458
DJ
262 // User defined those values in the `iface` (Name)
263 // field. Match them (instead of leaving the
264 // previous value) to make clear what is submitted
265 // and how the fields `iface`, `vlan-id` and
266 // `vlan-raw-device` are connected
267 vlanidField.setValue(
268 value.match(Proxmox.Utils.VlanInterface_match)[2],
269 );
270 vlanrawdeviceField.setValue(
271 value.match(Proxmox.Utils.VlanInterface_match)[1],
272 );
ea7da80c
TL
273 } else if (Proxmox.Utils.Vlan_match.test(value)) {
274 vlanidField.setDisabled(true);
0174c458
DJ
275 vlanidField.setValue(
276 value.match(Proxmox.Utils.Vlan_match)[1],
277 );
ea7da80c
TL
278 vlanrawdeviceField.setDisabled(false);
279 } else {
280 vlanidField.setDisabled(false);
281 vlanrawdeviceField.setDisabled(false);
282 }
283 }
01031528
TL
284 },
285 },
5c833def 286 });
a58001dd
DM
287
288 if (me.iftype === 'OVSBond') {
289 column1.push(
290 {
291 xtype: 'bondModeSelector',
292 fieldLabel: gettext('Mode'),
293 name: 'bond_mode',
294 openvswitch: true,
b33f451f 295 value: me.isCreate ? 'active-backup' : undefined,
01031528 296 allowBlank: false,
a58001dd
DM
297 },
298 {
299 xtype: 'textfield',
300 fieldLabel: gettext('Slaves'),
01031528
TL
301 name: 'ovs_bonds',
302 },
a58001dd
DM
303 );
304 } else {
a58001dd
DM
305 column1.push(
306 {
a0ec1620 307 xtype: 'proxmoxtextfield',
b33f451f 308 deleteEmpty: !me.isCreate,
8e2d096c
DC
309 fieldLabel: 'IPv4/CIDR',
310 vtype: 'IPCIDRAddress',
01031528 311 name: 'cidr',
a58001dd
DM
312 },
313 {
a0ec1620 314 xtype: 'proxmoxtextfield',
b33f451f 315 deleteEmpty: !me.isCreate,
8e2d096c 316 fieldLabel: gettext('Gateway') + ' (IPv4)',
a58001dd 317 vtype: 'IPAddress',
01031528 318 name: 'gateway',
a58001dd
DM
319 },
320 {
a0ec1620 321 xtype: 'proxmoxtextfield',
b33f451f 322 deleteEmpty: !me.isCreate,
8e2d096c
DC
323 fieldLabel: 'IPv6/CIDR',
324 vtype: 'IP6CIDRAddress',
01031528 325 name: 'cidr6',
a58001dd
DM
326 },
327 {
a0ec1620 328 xtype: 'proxmoxtextfield',
b33f451f 329 deleteEmpty: !me.isCreate,
8e2d096c 330 fieldLabel: gettext('Gateway') + ' (IPv6)',
a58001dd 331 vtype: 'IP6Address',
01031528 332 name: 'gateway6',
aedaf2b6 333 },
5c833def 334 );
a58001dd 335 }
82327aca
TL
336 advancedColumn1.push(
337 {
338 xtype: 'proxmoxintegerfield',
339 minValue: 1280,
340 maxValue: 65520,
341 deleteEmpty: !me.isCreate,
342 emptyText: 1500,
343 fieldLabel: 'MTU',
344 name: 'mtu',
345 },
346 );
a58001dd
DM
347
348 Ext.applyIf(me, {
349 url: url,
350 method: method,
351 items: {
352 xtype: 'inputpanel',
353 column1: column1,
5c833def 354 column2: column2,
1aaba242 355 columnB: columnB,
5c833def
TL
356 advancedColumn1: advancedColumn1,
357 advancedColumn2: advancedColumn2,
01031528 358 },
a58001dd
DM
359 });
360
361 me.callParent();
362
b33f451f 363 if (me.isCreate) {
a58001dd
DM
364 me.down('field[name=iface]').setValue(me.iface_default);
365 } else {
366 me.load({
367 success: function(response, options) {
05a977a2 368 let data = response.result.data;
a58001dd 369 if (data.type !== me.iftype) {
05a977a2 370 let msg = "Got unexpected device type";
a58001dd
DM
371 Ext.Msg.alert(gettext('Error'), msg, function() {
372 me.close();
373 });
374 return;
375 }
376 me.setValues(data);
377 me.isValid(); // trigger validation
01031528 378 },
a58001dd
DM
379 });
380 }
01031528 381 },
a58001dd 382});