]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/node/NetworkEdit.js
node: repos: improve repo-parsing error message
[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 });
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 // User defined those values in the `iface` (Name)
262 // field. Match them (instead of leaving the
263 // previous value) to make clear what is submitted
264 // and how the fields `iface`, `vlan-id` and
265 // `vlan-raw-device` are connected
266 vlanidField.setValue(
267 value.match(Proxmox.Utils.VlanInterface_match)[2],
268 );
269 vlanrawdeviceField.setValue(
270 value.match(Proxmox.Utils.VlanInterface_match)[1],
271 );
272 } else if (Proxmox.Utils.Vlan_match.test(value)) {
273 vlanidField.setDisabled(true);
274 vlanidField.setValue(
275 value.match(Proxmox.Utils.Vlan_match)[1],
276 );
277 vlanrawdeviceField.setDisabled(false);
278 } else {
279 vlanidField.setDisabled(false);
280 vlanrawdeviceField.setDisabled(false);
281 }
282 }
283 },
284 },
285 });
286
287 if (me.iftype === 'OVSBond') {
288 column1.push(
289 {
290 xtype: 'bondModeSelector',
291 fieldLabel: gettext('Mode'),
292 name: 'bond_mode',
293 openvswitch: true,
294 value: me.isCreate ? 'active-backup' : undefined,
295 allowBlank: false,
296 },
297 {
298 xtype: 'textfield',
299 fieldLabel: gettext('Slaves'),
300 name: 'ovs_bonds',
301 },
302 );
303 } else {
304 column1.push(
305 {
306 xtype: 'proxmoxtextfield',
307 deleteEmpty: !me.isCreate,
308 fieldLabel: 'IPv4/CIDR',
309 vtype: 'IPCIDRAddress',
310 name: 'cidr',
311 },
312 {
313 xtype: 'proxmoxtextfield',
314 deleteEmpty: !me.isCreate,
315 fieldLabel: gettext('Gateway') + ' (IPv4)',
316 vtype: 'IPAddress',
317 name: 'gateway',
318 },
319 {
320 xtype: 'proxmoxtextfield',
321 deleteEmpty: !me.isCreate,
322 fieldLabel: 'IPv6/CIDR',
323 vtype: 'IP6CIDRAddress',
324 name: 'cidr6',
325 },
326 {
327 xtype: 'proxmoxtextfield',
328 deleteEmpty: !me.isCreate,
329 fieldLabel: gettext('Gateway') + ' (IPv6)',
330 vtype: 'IP6Address',
331 name: 'gateway6',
332 },
333 );
334 }
335 advancedColumn1.push(
336 {
337 xtype: 'proxmoxintegerfield',
338 minValue: 1280,
339 maxValue: 65520,
340 deleteEmpty: !me.isCreate,
341 emptyText: 1500,
342 fieldLabel: 'MTU',
343 name: 'mtu',
344 },
345 );
346
347 Ext.applyIf(me, {
348 url: url,
349 method: method,
350 items: {
351 xtype: 'inputpanel',
352 column1: column1,
353 column2: column2,
354 columnB: columnB,
355 advancedColumn1: advancedColumn1,
356 advancedColumn2: advancedColumn2,
357 },
358 });
359
360 me.callParent();
361
362 if (me.isCreate) {
363 me.down('field[name=iface]').setValue(me.iface_default);
364 } else {
365 me.load({
366 success: function(response, options) {
367 let data = response.result.data;
368 if (data.type !== me.iftype) {
369 let msg = "Got unexpected device type";
370 Ext.Msg.alert(gettext('Error'), msg, function() {
371 me.close();
372 });
373 return;
374 }
375 me.setValues(data);
376 me.isValid(); // trigger validation
377 },
378 });
379 }
380 },
381 });