]>
Commit | Line | Data |
---|---|---|
1 | Ext.define('Proxmox.node.NetworkEdit', { | |
2 | extend: 'Proxmox.window.Edit', | |
3 | alias: ['widget.proxmoxNodeNetworkEdit'], | |
4 | ||
5 | initComponent: function() { | |
6 | let me = this; | |
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 | ||
16 | me.isCreate = !me.iface; | |
17 | ||
18 | let iface_vtype; | |
19 | ||
20 | if (me.iftype === 'bridge') { | |
21 | iface_vtype = 'BridgeName'; | |
22 | } else if (me.iftype === 'bond') { | |
23 | iface_vtype = 'BondName'; | |
24 | } else if (me.iftype === 'eth' && !me.isCreate) { | |
25 | iface_vtype = 'InterfaceName'; | |
26 | } else if (me.iftype === 'vlan') { | |
27 | iface_vtype = 'VlanName'; | |
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 | ||
43 | let column1 = [], | |
44 | column2 = [], | |
45 | columnB = [], | |
46 | advancedColumn1 = [], | |
47 | advancedColumn2 = []; | |
48 | ||
49 | if (!(me.iftype === 'OVSIntPort' || me.iftype === 'OVSPort' || me.iftype === 'OVSBond')) { | |
50 | column2.push({ | |
51 | xtype: 'proxmoxcheckbox', | |
52 | fieldLabel: gettext('Autostart'), | |
53 | name: 'autostart', | |
54 | uncheckedValue: 0, | |
55 | checked: me.isCreate ? true : undefined, | |
56 | }); | |
57 | } | |
58 | ||
59 | if (me.iftype === 'bridge') { | |
60 | column2.push({ | |
61 | xtype: 'proxmoxcheckbox', | |
62 | fieldLabel: gettext('VLAN aware'), | |
63 | name: 'bridge_vlan_aware', | |
64 | deleteEmpty: !me.isCreate, | |
65 | }); | |
66 | column2.push({ | |
67 | xtype: 'textfield', | |
68 | fieldLabel: gettext('Bridge ports'), | |
69 | name: 'bridge_ports', | |
70 | }); | |
71 | } else if (me.iftype === 'OVSBridge') { | |
72 | column2.push({ | |
73 | xtype: 'textfield', | |
74 | fieldLabel: gettext('Bridge ports'), | |
75 | name: 'ovs_ports', | |
76 | }); | |
77 | column2.push({ | |
78 | xtype: 'textfield', | |
79 | fieldLabel: gettext('OVS options'), | |
80 | name: 'ovs_options', | |
81 | }); | |
82 | } else if (me.iftype === 'OVSPort' || me.iftype === 'OVSIntPort') { | |
83 | column2.push({ | |
84 | xtype: me.isCreate ? 'PVE.form.BridgeSelector' : 'displayfield', | |
85 | fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'), | |
86 | allowBlank: false, | |
87 | nodename: me.nodename, | |
88 | bridgeType: 'OVSBridge', | |
89 | name: 'ovs_bridge', | |
90 | }); | |
91 | column2.push({ | |
92 | xtype: 'pveVlanField', | |
93 | deleteEmpty: !me.isCreate, | |
94 | name: 'ovs_tag', | |
95 | value: '', | |
96 | }); | |
97 | column2.push({ | |
98 | xtype: 'textfield', | |
99 | fieldLabel: gettext('OVS options'), | |
100 | name: 'ovs_options', | |
101 | }); | |
102 | } else if (me.iftype === 'vlan') { | |
103 | if (!me.isCreate) { | |
104 | me.disablevlanid = false; | |
105 | me.disablevlanrawdevice = false; | |
106 | me.vlanrawdevicevalue = ''; | |
107 | me.vlanidvalue = ''; | |
108 | ||
109 | if (Proxmox.Utils.VlanInterface_match.test(me.iface)) { | |
110 | me.disablevlanid = true; | |
111 | me.disablevlanrawdevice = true; | |
112 | let arr = Proxmox.Utils.VlanInterface_match.exec(me.iface); | |
113 | me.vlanrawdevicevalue = arr[1]; | |
114 | me.vlanidvalue = arr[2]; | |
115 | } else if (Proxmox.Utils.Vlan_match.test(me.iface)) { | |
116 | me.disablevlanid = true; | |
117 | let arr = Proxmox.Utils.Vlan_match.exec(me.iface); | |
118 | me.vlanidvalue = arr[1]; | |
119 | } | |
120 | } else { | |
121 | me.disablevlanid = true; | |
122 | me.disablevlanrawdevice = true; | |
123 | } | |
124 | ||
125 | column2.push({ | |
126 | xtype: 'textfield', | |
127 | fieldLabel: gettext('Vlan raw device'), | |
128 | name: 'vlan-raw-device', | |
129 | value: me.vlanrawdevicevalue, | |
130 | disabled: me.disablevlanrawdevice, | |
131 | allowBlank: false, | |
132 | }); | |
133 | ||
134 | column2.push({ | |
135 | xtype: 'pveVlanField', | |
136 | name: 'vlan-id', | |
137 | value: me.vlanidvalue, | |
138 | disabled: me.disablevlanid, | |
139 | }); | |
140 | ||
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)', | |
145 | }); | |
146 | } else if (me.iftype === 'bond') { | |
147 | column2.push({ | |
148 | xtype: 'textfield', | |
149 | fieldLabel: gettext('Slaves'), | |
150 | name: 'slaves', | |
151 | }); | |
152 | ||
153 | let policySelector = Ext.createWidget('bondPolicySelector', { | |
154 | fieldLabel: gettext('Hash policy'), | |
155 | name: 'bond_xmit_hash_policy', | |
156 | deleteEmpty: !me.isCreate, | |
157 | disabled: true, | |
158 | }); | |
159 | ||
160 | let primaryfield = Ext.createWidget('textfield', { | |
161 | fieldLabel: 'bond-primary', | |
162 | name: 'bond-primary', | |
163 | value: '', | |
164 | disabled: true, | |
165 | }); | |
166 | ||
167 | column2.push({ | |
168 | xtype: 'bondModeSelector', | |
169 | fieldLabel: gettext('Mode'), | |
170 | name: 'bond_mode', | |
171 | value: me.isCreate ? 'balance-rr' : undefined, | |
172 | listeners: { | |
173 | change: function(f, value) { | |
174 | if (value === 'balance-xor' || | |
175 | value === '802.3ad') { | |
176 | policySelector.setDisabled(false); | |
177 | primaryfield.setDisabled(true); | |
178 | primaryfield.setValue(''); | |
179 | } else if (value === 'active-backup') { | |
180 | primaryfield.setDisabled(false); | |
181 | policySelector.setDisabled(true); | |
182 | policySelector.setValue(''); | |
183 | } else { | |
184 | policySelector.setDisabled(true); | |
185 | policySelector.setValue(''); | |
186 | primaryfield.setDisabled(true); | |
187 | primaryfield.setValue(''); | |
188 | } | |
189 | }, | |
190 | }, | |
191 | allowBlank: false, | |
192 | }); | |
193 | ||
194 | column2.push(policySelector); | |
195 | column2.push(primaryfield); | |
196 | } else if (me.iftype === 'OVSBond') { | |
197 | column2.push({ | |
198 | xtype: me.isCreate ? 'PVE.form.BridgeSelector' : 'displayfield', | |
199 | fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'), | |
200 | allowBlank: false, | |
201 | nodename: me.nodename, | |
202 | bridgeType: 'OVSBridge', | |
203 | name: 'ovs_bridge', | |
204 | }); | |
205 | column2.push({ | |
206 | xtype: 'pveVlanField', | |
207 | deleteEmpty: !me.isCreate, | |
208 | name: 'ovs_tag', | |
209 | value: '', | |
210 | }); | |
211 | column2.push({ | |
212 | xtype: 'textfield', | |
213 | fieldLabel: gettext('OVS options'), | |
214 | name: 'ovs_options', | |
215 | }); | |
216 | } | |
217 | ||
218 | column2.push({ | |
219 | xtype: 'textfield', | |
220 | fieldLabel: gettext('Comment'), | |
221 | allowBlank: true, | |
222 | nodename: me.nodename, | |
223 | name: 'comments', | |
224 | }); | |
225 | ||
226 | let url; | |
227 | let method; | |
228 | ||
229 | if (me.isCreate) { | |
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 | ||
237 | column1.push({ | |
238 | xtype: 'hiddenfield', | |
239 | name: 'type', | |
240 | value: me.iftype, | |
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, | |
249 | autoEl: { | |
250 | tag: 'div', | |
251 | 'data-qtip': gettext('For example, vmbr0.100, vmbr0, vlan0.100, vlan0'), | |
252 | }, | |
253 | listeners: { | |
254 | change: function(f, value) { | |
255 | if (me.isCreate && iface_vtype === 'VlanName') { | |
256 | let vlanidField = me.down('field[name=vlan-id]'); | |
257 | let vlanrawdeviceField = me.down('field[name=vlan-raw-device]'); | |
258 | if (Proxmox.Utils.VlanInterface_match.test(value)) { | |
259 | vlanidField.setDisabled(true); | |
260 | vlanrawdeviceField.setDisabled(true); | |
261 | } else if (Proxmox.Utils.Vlan_match.test(value)) { | |
262 | vlanidField.setDisabled(true); | |
263 | vlanrawdeviceField.setDisabled(false); | |
264 | } else { | |
265 | vlanidField.setDisabled(false); | |
266 | vlanrawdeviceField.setDisabled(false); | |
267 | } | |
268 | } | |
269 | }, | |
270 | }, | |
271 | }); | |
272 | ||
273 | if (me.iftype === 'OVSBond') { | |
274 | column1.push( | |
275 | { | |
276 | xtype: 'bondModeSelector', | |
277 | fieldLabel: gettext('Mode'), | |
278 | name: 'bond_mode', | |
279 | openvswitch: true, | |
280 | value: me.isCreate ? 'active-backup' : undefined, | |
281 | allowBlank: false, | |
282 | }, | |
283 | { | |
284 | xtype: 'textfield', | |
285 | fieldLabel: gettext('Slaves'), | |
286 | name: 'ovs_bonds', | |
287 | }, | |
288 | ); | |
289 | } else { | |
290 | column1.push( | |
291 | { | |
292 | xtype: 'proxmoxtextfield', | |
293 | deleteEmpty: !me.isCreate, | |
294 | fieldLabel: 'IPv4/CIDR', | |
295 | vtype: 'IPCIDRAddress', | |
296 | name: 'cidr', | |
297 | }, | |
298 | { | |
299 | xtype: 'proxmoxtextfield', | |
300 | deleteEmpty: !me.isCreate, | |
301 | fieldLabel: gettext('Gateway') + ' (IPv4)', | |
302 | vtype: 'IPAddress', | |
303 | name: 'gateway', | |
304 | }, | |
305 | { | |
306 | xtype: 'proxmoxtextfield', | |
307 | deleteEmpty: !me.isCreate, | |
308 | fieldLabel: 'IPv6/CIDR', | |
309 | vtype: 'IP6CIDRAddress', | |
310 | name: 'cidr6', | |
311 | }, | |
312 | { | |
313 | xtype: 'proxmoxtextfield', | |
314 | deleteEmpty: !me.isCreate, | |
315 | fieldLabel: gettext('Gateway') + ' (IPv6)', | |
316 | vtype: 'IP6Address', | |
317 | name: 'gateway6', | |
318 | }, | |
319 | ); | |
320 | } | |
321 | advancedColumn1.push( | |
322 | { | |
323 | xtype: 'proxmoxintegerfield', | |
324 | minValue: 1280, | |
325 | maxValue: 65520, | |
326 | deleteEmpty: !me.isCreate, | |
327 | emptyText: 1500, | |
328 | fieldLabel: 'MTU', | |
329 | name: 'mtu', | |
330 | }, | |
331 | ); | |
332 | ||
333 | Ext.applyIf(me, { | |
334 | url: url, | |
335 | method: method, | |
336 | items: { | |
337 | xtype: 'inputpanel', | |
338 | column1: column1, | |
339 | column2: column2, | |
340 | columnB: columnB, | |
341 | advancedColumn1: advancedColumn1, | |
342 | advancedColumn2: advancedColumn2, | |
343 | }, | |
344 | }); | |
345 | ||
346 | me.callParent(); | |
347 | ||
348 | if (me.isCreate) { | |
349 | me.down('field[name=iface]').setValue(me.iface_default); | |
350 | } else { | |
351 | me.load({ | |
352 | success: function(response, options) { | |
353 | let data = response.result.data; | |
354 | if (data.type !== me.iftype) { | |
355 | let msg = "Got unexpected device type"; | |
356 | Ext.Msg.alert(gettext('Error'), msg, function() { | |
357 | me.close(); | |
358 | }); | |
359 | return; | |
360 | } | |
361 | me.setValues(data); | |
362 | me.isValid(); // trigger validation | |
363 | }, | |
364 | }); | |
365 | } | |
366 | }, | |
367 | }); |