]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - node/NetworkEdit.js
72aab6f771c56fb3d629aca5f851e38ce3a3efb8
[proxmox-widget-toolkit.git] / 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 });
132
133 column2.push({
134 xtype: 'pveVlanField',
135 name: 'vlan-id',
136 value: me.vlanidvalue,
137 disabled: me.disablevlanid,
138 });
139
140 columnB.push({
141 xtype: 'label',
142 userCls: 'pmx-hint',
143 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)',
144 });
145 } else if (me.iftype === 'bond') {
146 column2.push({
147 xtype: 'textfield',
148 fieldLabel: gettext('Slaves'),
149 name: 'slaves',
150 });
151
152 let policySelector = Ext.createWidget('bondPolicySelector', {
153 fieldLabel: gettext('Hash policy'),
154 name: 'bond_xmit_hash_policy',
155 deleteEmpty: !me.isCreate,
156 disabled: true,
157 });
158
159 let primaryfield = Ext.createWidget('textfield', {
160 fieldLabel: gettext('bond-primary'),
161 name: 'bond-primary',
162 value: '',
163 disabled: true,
164 });
165
166 column2.push({
167 xtype: 'bondModeSelector',
168 fieldLabel: gettext('Mode'),
169 name: 'bond_mode',
170 value: me.isCreate ? 'balance-rr' : undefined,
171 listeners: {
172 change: function(f, value) {
173 if (value === 'balance-xor' ||
174 value === '802.3ad') {
175 policySelector.setDisabled(false);
176 primaryfield.setDisabled(true);
177 primaryfield.setValue('');
178 } else if (value === 'active-backup') {
179 primaryfield.setDisabled(false);
180 policySelector.setDisabled(true);
181 policySelector.setValue('');
182 } else {
183 policySelector.setDisabled(true);
184 policySelector.setValue('');
185 primaryfield.setDisabled(true);
186 primaryfield.setValue('');
187 }
188 },
189 },
190 allowBlank: false,
191 });
192
193 column2.push(policySelector);
194 column2.push(primaryfield);
195 } else if (me.iftype === 'OVSBond') {
196 column2.push({
197 xtype: me.isCreate ? 'PVE.form.BridgeSelector' : 'displayfield',
198 fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'),
199 allowBlank: false,
200 nodename: me.nodename,
201 bridgeType: 'OVSBridge',
202 name: 'ovs_bridge',
203 });
204 column2.push({
205 xtype: 'pveVlanField',
206 deleteEmpty: !me.isCreate,
207 name: 'ovs_tag',
208 value: '',
209 });
210 column2.push({
211 xtype: 'textfield',
212 fieldLabel: gettext('OVS options'),
213 name: 'ovs_options',
214 });
215 }
216
217 column2.push({
218 xtype: 'textfield',
219 fieldLabel: gettext('Comment'),
220 allowBlank: true,
221 nodename: me.nodename,
222 name: 'comments',
223 });
224
225 let url;
226 let method;
227
228 if (me.isCreate) {
229 url = "/api2/extjs/nodes/" + me.nodename + "/network";
230 method = 'POST';
231 } else {
232 url = "/api2/extjs/nodes/" + me.nodename + "/network/" + me.iface;
233 method = 'PUT';
234 }
235
236 column1.push({
237 xtype: 'hiddenfield',
238 name: 'type',
239 value: me.iftype,
240 },
241 {
242 xtype: me.isCreate ? 'textfield' : 'displayfield',
243 fieldLabel: gettext('Name'),
244 name: 'iface',
245 value: me.iface,
246 vtype: iface_vtype,
247 allowBlank: false,
248 listeners: {
249 change: function(f, value) {
250 if (me.isCreate && iface_vtype === 'VlanName') {
251 let vlanidField = me.down('field[name=vlan-id]');
252 let vlanrawdeviceField = me.down('field[name=vlan-raw-device]');
253 if (Proxmox.Utils.VlanInterface_match.test(value)) {
254 vlanidField.setDisabled(true);
255 vlanrawdeviceField.setDisabled(true);
256 } else if (Proxmox.Utils.Vlan_match.test(value)) {
257 vlanidField.setDisabled(true);
258 vlanrawdeviceField.setDisabled(false);
259 } else {
260 vlanidField.setDisabled(false);
261 vlanrawdeviceField.setDisabled(false);
262 }
263 }
264 },
265 },
266 });
267
268 if (me.iftype === 'OVSBond') {
269 column1.push(
270 {
271 xtype: 'bondModeSelector',
272 fieldLabel: gettext('Mode'),
273 name: 'bond_mode',
274 openvswitch: true,
275 value: me.isCreate ? 'active-backup' : undefined,
276 allowBlank: false,
277 },
278 {
279 xtype: 'textfield',
280 fieldLabel: gettext('Slaves'),
281 name: 'ovs_bonds',
282 },
283 );
284 } else {
285 column1.push(
286 {
287 xtype: 'proxmoxtextfield',
288 deleteEmpty: !me.isCreate,
289 fieldLabel: 'IPv4/CIDR',
290 vtype: 'IPCIDRAddress',
291 name: 'cidr',
292 },
293 {
294 xtype: 'proxmoxtextfield',
295 deleteEmpty: !me.isCreate,
296 fieldLabel: gettext('Gateway') + ' (IPv4)',
297 vtype: 'IPAddress',
298 name: 'gateway',
299 },
300 {
301 xtype: 'proxmoxtextfield',
302 deleteEmpty: !me.isCreate,
303 fieldLabel: 'IPv6/CIDR',
304 vtype: 'IP6CIDRAddress',
305 name: 'cidr6',
306 },
307 {
308 xtype: 'proxmoxtextfield',
309 deleteEmpty: !me.isCreate,
310 fieldLabel: gettext('Gateway') + ' (IPv6)',
311 vtype: 'IP6Address',
312 name: 'gateway6',
313 },
314 );
315 advancedColumn1.push(
316 {
317 xtype: 'proxmoxintegerfield',
318 minValue: 1280,
319 maxValue: 65520,
320 deleteEmpty: !me.isCreate,
321 emptyText: 1500,
322 fieldLabel: 'MTU',
323 name: 'mtu',
324 },
325 );
326 }
327
328 Ext.applyIf(me, {
329 url: url,
330 method: method,
331 items: {
332 xtype: 'inputpanel',
333 column1: column1,
334 column2: column2,
335 columnB: columnB,
336 advancedColumn1: advancedColumn1,
337 advancedColumn2: advancedColumn2,
338 },
339 });
340
341 me.callParent();
342
343 if (me.isCreate) {
344 me.down('field[name=iface]').setValue(me.iface_default);
345 } else {
346 me.load({
347 success: function(response, options) {
348 let data = response.result.data;
349 if (data.type !== me.iftype) {
350 let msg = "Got unexpected device type";
351 Ext.Msg.alert(gettext('Error'), msg, function() {
352 me.close();
353 });
354 return;
355 }
356 me.setValues(data);
357 me.isValid(); // trigger validation
358 },
359 });
360 }
361 },
362 });