]>
Commit | Line | Data |
---|---|---|
a58001dd DM |
1 | Ext.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 | }); |