]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/node/NetworkEdit.js
language selector: increase only picker list view
[proxmox-widget-toolkit.git] / src / node / NetworkEdit.js
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 autoEl: {
71 tag: 'div',
72 'data-qtip': gettext('Space-separated list of interfaces, for example: enp0s0 enp1s0'),
73 },
74 });
75 } else if (me.iftype === 'OVSBridge') {
76 column2.push({
77 xtype: 'textfield',
78 fieldLabel: gettext('Bridge ports'),
79 name: 'ovs_ports',
80 autoEl: {
81 tag: 'div',
82 'data-qtip': gettext('Space-separated list of interfaces, for example: enp0s0 enp1s0'),
83 },
84 });
85 column2.push({
86 xtype: 'textfield',
87 fieldLabel: gettext('OVS options'),
88 name: 'ovs_options',
89 });
90 } else if (me.iftype === 'OVSPort' || me.iftype === 'OVSIntPort') {
91 column2.push({
92 xtype: me.isCreate ? 'PVE.form.BridgeSelector' : 'displayfield',
93 fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'),
94 allowBlank: false,
95 nodename: me.nodename,
96 bridgeType: 'OVSBridge',
97 name: 'ovs_bridge',
98 });
99 column2.push({
100 xtype: 'pveVlanField',
101 deleteEmpty: !me.isCreate,
102 name: 'ovs_tag',
103 value: '',
104 });
105 column2.push({
106 xtype: 'textfield',
107 fieldLabel: gettext('OVS options'),
108 name: 'ovs_options',
109 });
110 } else if (me.iftype === 'vlan') {
111 if (!me.isCreate) {
112 me.disablevlanid = false;
113 me.disablevlanrawdevice = false;
114 me.vlanrawdevicevalue = '';
115 me.vlanidvalue = '';
116
117 if (Proxmox.Utils.VlanInterface_match.test(me.iface)) {
118 me.disablevlanid = true;
119 me.disablevlanrawdevice = true;
120 let arr = Proxmox.Utils.VlanInterface_match.exec(me.iface);
121 me.vlanrawdevicevalue = arr[1];
122 me.vlanidvalue = arr[2];
123 } else if (Proxmox.Utils.Vlan_match.test(me.iface)) {
124 me.disablevlanid = true;
125 let arr = Proxmox.Utils.Vlan_match.exec(me.iface);
126 me.vlanidvalue = arr[1];
127 }
128 } else {
129 me.disablevlanid = true;
130 me.disablevlanrawdevice = true;
131 }
132
133 column2.push({
134 xtype: 'textfield',
135 fieldLabel: gettext('Vlan raw device'),
136 name: 'vlan-raw-device',
137 value: me.vlanrawdevicevalue,
138 disabled: me.disablevlanrawdevice,
139 allowBlank: false,
140 });
141
142 column2.push({
143 xtype: 'pveVlanField',
144 name: 'vlan-id',
145 value: me.vlanidvalue,
146 disabled: me.disablevlanid,
147 });
148
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)',
153 });
154 } else if (me.iftype === 'bond') {
155 column2.push({
156 xtype: 'textfield',
157 fieldLabel: gettext('Slaves'),
158 name: 'slaves',
159 });
160
161 let policySelector = Ext.createWidget('bondPolicySelector', {
162 fieldLabel: gettext('Hash policy'),
163 name: 'bond_xmit_hash_policy',
164 deleteEmpty: !me.isCreate,
165 disabled: true,
166 });
167
168 let primaryfield = Ext.createWidget('textfield', {
169 fieldLabel: 'bond-primary',
170 name: 'bond-primary',
171 value: '',
172 disabled: true,
173 });
174
175 column2.push({
176 xtype: 'bondModeSelector',
177 fieldLabel: gettext('Mode'),
178 name: 'bond_mode',
179 value: me.isCreate ? 'balance-rr' : undefined,
180 listeners: {
181 change: function(f, value) {
182 if (value === 'balance-xor' ||
183 value === '802.3ad') {
184 policySelector.setDisabled(false);
185 primaryfield.setDisabled(true);
186 primaryfield.setValue('');
187 } else if (value === 'active-backup') {
188 primaryfield.setDisabled(false);
189 policySelector.setDisabled(true);
190 policySelector.setValue('');
191 } else {
192 policySelector.setDisabled(true);
193 policySelector.setValue('');
194 primaryfield.setDisabled(true);
195 primaryfield.setValue('');
196 }
197 },
198 },
199 allowBlank: false,
200 });
201
202 column2.push(policySelector);
203 column2.push(primaryfield);
204 } else if (me.iftype === 'OVSBond') {
205 column2.push({
206 xtype: me.isCreate ? 'PVE.form.BridgeSelector' : 'displayfield',
207 fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'),
208 allowBlank: false,
209 nodename: me.nodename,
210 bridgeType: 'OVSBridge',
211 name: 'ovs_bridge',
212 });
213 column2.push({
214 xtype: 'pveVlanField',
215 deleteEmpty: !me.isCreate,
216 name: 'ovs_tag',
217 value: '',
218 });
219 column2.push({
220 xtype: 'textfield',
221 fieldLabel: gettext('OVS options'),
222 name: 'ovs_options',
223 });
224 }
225
226 column2.push({
227 xtype: 'textfield',
228 fieldLabel: gettext('Comment'),
229 allowBlank: true,
230 nodename: me.nodename,
231 name: 'comments',
232 });
233
234 let url;
235 let method;
236
237 if (me.isCreate) {
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
245 column1.push({
246 xtype: 'hiddenfield',
247 name: 'type',
248 value: me.iftype,
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,
257 maxLength: 15,
258 autoEl: {
259 tag: 'div',
260 'data-qtip': gettext('For example, vmbr0.100, vmbr0, vlan0.100, vlan0'),
261 },
262 listeners: {
263 change: function(f, value) {
264 if (me.isCreate && iface_vtype === 'VlanName') {
265 let vlanidField = me.down('field[name=vlan-id]');
266 let vlanrawdeviceField = me.down('field[name=vlan-raw-device]');
267 if (Proxmox.Utils.VlanInterface_match.test(value)) {
268 vlanidField.setDisabled(true);
269 vlanrawdeviceField.setDisabled(true);
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 );
281 } else if (Proxmox.Utils.Vlan_match.test(value)) {
282 vlanidField.setDisabled(true);
283 vlanidField.setValue(
284 value.match(Proxmox.Utils.Vlan_match)[1],
285 );
286 vlanrawdeviceField.setDisabled(false);
287 } else {
288 vlanidField.setDisabled(false);
289 vlanrawdeviceField.setDisabled(false);
290 }
291 }
292 },
293 },
294 });
295
296 if (me.iftype === 'OVSBond') {
297 column1.push(
298 {
299 xtype: 'bondModeSelector',
300 fieldLabel: gettext('Mode'),
301 name: 'bond_mode',
302 openvswitch: true,
303 value: me.isCreate ? 'active-backup' : undefined,
304 allowBlank: false,
305 },
306 {
307 xtype: 'textfield',
308 fieldLabel: gettext('Slaves'),
309 name: 'ovs_bonds',
310 },
311 );
312 } else {
313 column1.push(
314 {
315 xtype: 'proxmoxtextfield',
316 deleteEmpty: !me.isCreate,
317 fieldLabel: 'IPv4/CIDR',
318 vtype: 'IPCIDRAddress',
319 name: 'cidr',
320 },
321 {
322 xtype: 'proxmoxtextfield',
323 deleteEmpty: !me.isCreate,
324 fieldLabel: gettext('Gateway') + ' (IPv4)',
325 vtype: 'IPAddress',
326 name: 'gateway',
327 },
328 {
329 xtype: 'proxmoxtextfield',
330 deleteEmpty: !me.isCreate,
331 fieldLabel: 'IPv6/CIDR',
332 vtype: 'IP6CIDRAddress',
333 name: 'cidr6',
334 },
335 {
336 xtype: 'proxmoxtextfield',
337 deleteEmpty: !me.isCreate,
338 fieldLabel: gettext('Gateway') + ' (IPv6)',
339 vtype: 'IP6Address',
340 name: 'gateway6',
341 },
342 );
343 }
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 );
355
356 Ext.applyIf(me, {
357 url: url,
358 method: method,
359 items: {
360 xtype: 'inputpanel',
361 column1: column1,
362 column2: column2,
363 columnB: columnB,
364 advancedColumn1: advancedColumn1,
365 advancedColumn2: advancedColumn2,
366 },
367 });
368
369 me.callParent();
370
371 if (me.isCreate) {
372 me.down('field[name=iface]').setValue(me.iface_default);
373 } else {
374 me.load({
375 success: function(response, options) {
376 let data = response.result.data;
377 if (data.type !== me.iftype) {
378 let msg = "Got unexpected device type";
379 Ext.Msg.alert(gettext('Error'), msg, function() {
380 me.close();
381 });
382 return;
383 }
384 me.setValues(data);
385 me.isValid(); // trigger validation
386 },
387 });
388 }
389 },
390 });