]> git.proxmox.com Git - proxmox-widget-toolkit.git/blame - src/node/NetworkEdit.js
bump version to 4.2.3
[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',
d62ef2a8
CH
70 autoEl: {
71 tag: 'div',
72 'data-qtip': gettext('Space-separated list of interfaces, for example: enp0s0 enp1s0'),
73 },
a58001dd
DM
74 });
75 } else if (me.iftype === 'OVSBridge') {
76 column2.push({
77 xtype: 'textfield',
78 fieldLabel: gettext('Bridge ports'),
01031528 79 name: 'ovs_ports',
d62ef2a8
CH
80 autoEl: {
81 tag: 'div',
82 'data-qtip': gettext('Space-separated list of interfaces, for example: enp0s0 enp1s0'),
83 },
a58001dd
DM
84 });
85 column2.push({
86 xtype: 'textfield',
87 fieldLabel: gettext('OVS options'),
01031528 88 name: 'ovs_options',
a58001dd
DM
89 });
90 } else if (me.iftype === 'OVSPort' || me.iftype === 'OVSIntPort') {
91 column2.push({
b33f451f 92 xtype: me.isCreate ? 'PVE.form.BridgeSelector' : 'displayfield',
a58001dd
DM
93 fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'),
94 allowBlank: false,
95 nodename: me.nodename,
96 bridgeType: 'OVSBridge',
01031528 97 name: 'ovs_bridge',
a58001dd
DM
98 });
99 column2.push({
3251f404 100 xtype: 'proxmoxvlanfield',
b33f451f 101 deleteEmpty: !me.isCreate,
a58001dd 102 name: 'ovs_tag',
01031528 103 value: '',
a58001dd
DM
104 });
105 column2.push({
106 xtype: 'textfield',
107 fieldLabel: gettext('OVS options'),
01031528 108 name: 'ovs_options',
a58001dd 109 });
8aefd47c 110 } else if (me.iftype === 'vlan') {
ea7da80c 111 if (!me.isCreate) {
ea7da80c
TL
112 me.disablevlanid = false;
113 me.disablevlanrawdevice = false;
114 me.vlanrawdevicevalue = '';
115 me.vlanidvalue = '';
8aefd47c 116
ea7da80c
TL
117 if (Proxmox.Utils.VlanInterface_match.test(me.iface)) {
118 me.disablevlanid = true;
119 me.disablevlanrawdevice = true;
05a977a2 120 let arr = Proxmox.Utils.VlanInterface_match.exec(me.iface);
ea7da80c
TL
121 me.vlanrawdevicevalue = arr[1];
122 me.vlanidvalue = arr[2];
ea7da80c
TL
123 } else if (Proxmox.Utils.Vlan_match.test(me.iface)) {
124 me.disablevlanid = true;
05a977a2 125 let arr = Proxmox.Utils.Vlan_match.exec(me.iface);
ea7da80c
TL
126 me.vlanidvalue = arr[1];
127 }
128 } else {
ea7da80c
TL
129 me.disablevlanid = true;
130 me.disablevlanrawdevice = true;
8aefd47c
AD
131 }
132
133 column2.push({
134 xtype: 'textfield',
135 fieldLabel: gettext('Vlan raw device'),
136 name: 'vlan-raw-device',
ea7da80c 137 value: me.vlanrawdevicevalue,
01031528 138 disabled: me.disablevlanrawdevice,
418ec858 139 allowBlank: false,
8aefd47c
AD
140 });
141
142 column2.push({
3251f404 143 xtype: 'proxmoxvlanfield',
8aefd47c 144 name: 'vlan-id',
ea7da80c 145 value: me.vlanidvalue,
01031528 146 disabled: me.disablevlanid,
1aaba242 147 });
8aefd47c 148
1aaba242
TL
149 columnB.push({
150 xtype: 'label',
151 userCls: 'pmx-hint',
152 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 153 });
a58001dd
DM
154 } else if (me.iftype === 'bond') {
155 column2.push({
156 xtype: 'textfield',
157 fieldLabel: gettext('Slaves'),
01031528 158 name: 'slaves',
a58001dd
DM
159 });
160
05a977a2 161 let policySelector = Ext.createWidget('bondPolicySelector', {
a58001dd
DM
162 fieldLabel: gettext('Hash policy'),
163 name: 'bond_xmit_hash_policy',
b33f451f 164 deleteEmpty: !me.isCreate,
01031528 165 disabled: true,
a58001dd
DM
166 });
167
05a977a2 168 let primaryfield = Ext.createWidget('textfield', {
0915cbb1 169 fieldLabel: 'bond-primary',
b154853a
AD
170 name: 'bond-primary',
171 value: '',
01031528 172 disabled: true,
b154853a
AD
173 });
174
a58001dd
DM
175 column2.push({
176 xtype: 'bondModeSelector',
177 fieldLabel: gettext('Mode'),
178 name: 'bond_mode',
b33f451f 179 value: me.isCreate ? 'balance-rr' : undefined,
a58001dd
DM
180 listeners: {
181 change: function(f, value) {
182 if (value === 'balance-xor' ||
183 value === '802.3ad') {
184 policySelector.setDisabled(false);
b154853a
AD
185 primaryfield.setDisabled(true);
186 primaryfield.setValue('');
187 } else if (value === 'active-backup') {
188 primaryfield.setDisabled(false);
189 policySelector.setDisabled(true);
190 policySelector.setValue('');
a58001dd
DM
191 } else {
192 policySelector.setDisabled(true);
193 policySelector.setValue('');
b154853a
AD
194 primaryfield.setDisabled(true);
195 primaryfield.setValue('');
a58001dd 196 }
01031528 197 },
a58001dd 198 },
01031528 199 allowBlank: false,
a58001dd
DM
200 });
201
202 column2.push(policySelector);
b154853a 203 column2.push(primaryfield);
a58001dd
DM
204 } else if (me.iftype === 'OVSBond') {
205 column2.push({
b33f451f 206 xtype: me.isCreate ? 'PVE.form.BridgeSelector' : 'displayfield',
a58001dd
DM
207 fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'),
208 allowBlank: false,
209 nodename: me.nodename,
210 bridgeType: 'OVSBridge',
01031528 211 name: 'ovs_bridge',
a58001dd
DM
212 });
213 column2.push({
3251f404 214 xtype: 'proxmoxvlanfield',
b33f451f 215 deleteEmpty: !me.isCreate,
a58001dd 216 name: 'ovs_tag',
01031528 217 value: '',
a58001dd
DM
218 });
219 column2.push({
220 xtype: 'textfield',
221 fieldLabel: gettext('OVS options'),
01031528 222 name: 'ovs_options',
a58001dd
DM
223 });
224 }
225
226 column2.push({
227 xtype: 'textfield',
228 fieldLabel: gettext('Comment'),
229 allowBlank: true,
230 nodename: me.nodename,
01031528 231 name: 'comments',
a58001dd
DM
232 });
233
05a977a2
TL
234 let url;
235 let method;
a58001dd 236
b33f451f 237 if (me.isCreate) {
a58001dd
DM
238 url = "/api2/extjs/nodes/" + me.nodename + "/network";
239 method = 'POST';
240 } else {
241 url = "/api2/extjs/nodes/" + me.nodename + "/network/" + me.iface;
242 method = 'PUT';
243 }
244
5c833def 245 column1.push({
ea7da80c
TL
246 xtype: 'hiddenfield',
247 name: 'type',
01031528 248 value: me.iftype,
ea7da80c
TL
249 },
250 {
251 xtype: me.isCreate ? 'textfield' : 'displayfield',
252 fieldLabel: gettext('Name'),
253 name: 'iface',
254 value: me.iface,
255 vtype: iface_vtype,
256 allowBlank: false,
9ffe9009 257 maxLength: iface_vtype === 'BridgeName' ? 10 : 15,
4ed84281
DJ
258 autoEl: {
259 tag: 'div',
260 'data-qtip': gettext('For example, vmbr0.100, vmbr0, vlan0.100, vlan0'),
261 },
ea7da80c
TL
262 listeners: {
263 change: function(f, value) {
264 if (me.isCreate && iface_vtype === 'VlanName') {
05a977a2
TL
265 let vlanidField = me.down('field[name=vlan-id]');
266 let vlanrawdeviceField = me.down('field[name=vlan-raw-device]');
ea7da80c
TL
267 if (Proxmox.Utils.VlanInterface_match.test(value)) {
268 vlanidField.setDisabled(true);
269 vlanrawdeviceField.setDisabled(true);
0174c458
DJ
270 // User defined those values in the `iface` (Name)
271 // field. Match them (instead of leaving the
272 // previous value) to make clear what is submitted
273 // and how the fields `iface`, `vlan-id` and
274 // `vlan-raw-device` are connected
275 vlanidField.setValue(
276 value.match(Proxmox.Utils.VlanInterface_match)[2],
277 );
278 vlanrawdeviceField.setValue(
279 value.match(Proxmox.Utils.VlanInterface_match)[1],
280 );
ea7da80c
TL
281 } else if (Proxmox.Utils.Vlan_match.test(value)) {
282 vlanidField.setDisabled(true);
0174c458
DJ
283 vlanidField.setValue(
284 value.match(Proxmox.Utils.Vlan_match)[1],
285 );
ea7da80c
TL
286 vlanrawdeviceField.setDisabled(false);
287 } else {
288 vlanidField.setDisabled(false);
289 vlanrawdeviceField.setDisabled(false);
290 }
291 }
01031528
TL
292 },
293 },
5c833def 294 });
a58001dd
DM
295
296 if (me.iftype === 'OVSBond') {
297 column1.push(
298 {
299 xtype: 'bondModeSelector',
300 fieldLabel: gettext('Mode'),
301 name: 'bond_mode',
302 openvswitch: true,
b33f451f 303 value: me.isCreate ? 'active-backup' : undefined,
01031528 304 allowBlank: false,
a58001dd
DM
305 },
306 {
307 xtype: 'textfield',
308 fieldLabel: gettext('Slaves'),
01031528
TL
309 name: 'ovs_bonds',
310 },
a58001dd
DM
311 );
312 } else {
a58001dd
DM
313 column1.push(
314 {
a0ec1620 315 xtype: 'proxmoxtextfield',
b33f451f 316 deleteEmpty: !me.isCreate,
8e2d096c
DC
317 fieldLabel: 'IPv4/CIDR',
318 vtype: 'IPCIDRAddress',
01031528 319 name: 'cidr',
a58001dd
DM
320 },
321 {
a0ec1620 322 xtype: 'proxmoxtextfield',
b33f451f 323 deleteEmpty: !me.isCreate,
8e2d096c 324 fieldLabel: gettext('Gateway') + ' (IPv4)',
a58001dd 325 vtype: 'IPAddress',
01031528 326 name: 'gateway',
a58001dd
DM
327 },
328 {
a0ec1620 329 xtype: 'proxmoxtextfield',
b33f451f 330 deleteEmpty: !me.isCreate,
8e2d096c
DC
331 fieldLabel: 'IPv6/CIDR',
332 vtype: 'IP6CIDRAddress',
01031528 333 name: 'cidr6',
a58001dd
DM
334 },
335 {
a0ec1620 336 xtype: 'proxmoxtextfield',
b33f451f 337 deleteEmpty: !me.isCreate,
8e2d096c 338 fieldLabel: gettext('Gateway') + ' (IPv6)',
a58001dd 339 vtype: 'IP6Address',
01031528 340 name: 'gateway6',
aedaf2b6 341 },
5c833def 342 );
a58001dd 343 }
82327aca
TL
344 advancedColumn1.push(
345 {
346 xtype: 'proxmoxintegerfield',
347 minValue: 1280,
348 maxValue: 65520,
349 deleteEmpty: !me.isCreate,
350 emptyText: 1500,
351 fieldLabel: 'MTU',
352 name: 'mtu',
353 },
354 );
a58001dd
DM
355
356 Ext.applyIf(me, {
357 url: url,
358 method: method,
359 items: {
360 xtype: 'inputpanel',
361 column1: column1,
5c833def 362 column2: column2,
1aaba242 363 columnB: columnB,
5c833def
TL
364 advancedColumn1: advancedColumn1,
365 advancedColumn2: advancedColumn2,
01031528 366 },
a58001dd
DM
367 });
368
369 me.callParent();
370
b33f451f 371 if (me.isCreate) {
a58001dd
DM
372 me.down('field[name=iface]').setValue(me.iface_default);
373 } else {
374 me.load({
375 success: function(response, options) {
05a977a2 376 let data = response.result.data;
a58001dd 377 if (data.type !== me.iftype) {
05a977a2 378 let msg = "Got unexpected device type";
a58001dd
DM
379 Ext.Msg.alert(gettext('Error'), msg, function() {
380 me.close();
381 });
382 return;
383 }
384 me.setValues(data);
385 me.isValid(); // trigger validation
01031528 386 },
a58001dd
DM
387 });
388 }
01031528 389 },
a58001dd 390});