]> git.proxmox.com Git - pve-manager.git/blame - www/manager/node/NetworkEdit.js
add bridge vlan aware checkbox
[pve-manager.git] / www / manager / node / NetworkEdit.js
CommitLineData
aff192e6
DM
1Ext.define('PVE.node.NetworkEdit', {
2 extend: 'PVE.window.Edit',
3 alias: ['widget.pveNodeNetworkEdit'],
4
5 initComponent : function() {
6 var me = this;
7
8 var nodename = me.pveSelNode.data.node;
9 if (!nodename) {
10 throw "no node name specified";
11 }
12
13 if (!me.iftype) {
14 throw "no network device type specified";
15 }
16
17 me.create = !me.iface;
18
aff192e6
DM
19 var iface_vtype;
20
e4d5bf72 21 if (me.iftype === 'bridge') {
e4d5bf72
DM
22 iface_vtype = 'BridgeName';
23 } else if (me.iftype === 'bond') {
e4d5bf72 24 iface_vtype = 'BondName';
5cc52e70 25 } else if (me.iftype === 'eth' && !me.create) {
d11733f8
DM
26 iface_vtype = 'InterfaceName';
27 } else if (me.iftype === 'OVSBridge') {
28 iface_vtype = 'BridgeName';
29 } else if (me.iftype === 'OVSBond') {
30 iface_vtype = 'BondName';
31 } else if (me.iftype === 'OVSIntPort') {
32 iface_vtype = 'InterfaceName';
33 } else if (me.iftype === 'OVSPort') {
34 iface_vtype = 'InterfaceName';
aff192e6 35 } else {
d11733f8
DM
36 console.log(me.iftype);
37 throw "unknown network device type specified";
aff192e6
DM
38 }
39
d11733f8
DM
40 me.subject = PVE.Utils.render_network_iface_type(me.iftype);
41
42 var column2 = [];
43
44 if (!(me.iftype === 'OVSIntPort' || me.iftype === 'OVSPort' ||
45 me.iftype === 'OVSBond')) {
46 column2.push({
aff192e6 47 xtype: 'pvecheckbox',
0070ee37 48 fieldLabel: gettext('Autostart'),
aff192e6
DM
49 name: 'autostart',
50 uncheckedValue: 0,
51 checked: me.create ? true : undefined
d11733f8
DM
52 });
53 }
aff192e6
DM
54
55 if (me.iftype === 'bridge') {
a1604d70
AD
56 column2.push({
57 xtype: 'pvecheckbox',
58 fieldLabel: gettext('Vlan Aware'),
59 name: 'bridge_vlan_aware',
60 deleteEmpty: !me.create,
61 });
aff192e6
DM
62 column2.push({
63 xtype: 'textfield',
0070ee37 64 fieldLabel: gettext('Bridge ports'),
aff192e6
DM
65 name: 'bridge_ports'
66 });
d11733f8
DM
67 } else if (me.iftype === 'OVSBridge') {
68 column2.push({
69 xtype: 'textfield',
70 fieldLabel: gettext('Bridge ports'),
71 name: 'ovs_ports'
72 });
73 column2.push({
74 xtype: 'textfield',
75 fieldLabel: gettext('OVS options'),
76 name: 'ovs_options'
77 });
78 } else if (me.iftype === 'OVSPort' || me.iftype === 'OVSIntPort') {
79 column2.push({
80 xtype: me.create ? 'PVE.form.BridgeSelector' : 'displayfield',
81 height: 22, // hack: set same height as text fields
82 fieldLabel: PVE.Utils.render_network_iface_type('OVSBridge'),
83 allowBlank: false,
84 nodename: nodename,
85 bridgeType: 'OVSBridge',
86 name: 'ovs_bridge'
87 });
4c917e97
DM
88 column2.push({
89 xtype: 'pveVlanField',
90 deleteEmpty: !me.create,
91 name: 'ovs_tag',
92 value: ''
93 });
d11733f8
DM
94 column2.push({
95 xtype: 'textfield',
96 fieldLabel: gettext('OVS options'),
97 name: 'ovs_options'
98 });
aff192e6
DM
99 } else if (me.iftype === 'bond') {
100 column2.push({
101 xtype: 'textfield',
0070ee37 102 fieldLabel: gettext('Slaves'),
aff192e6
DM
103 name: 'slaves'
104 });
ffffb625
DM
105
106 var policySelector = Ext.createWidget('bondPolicySelector', {
107 fieldLabel: gettext('Hash policy'),
108 name: 'bond_xmit_hash_policy',
109 deleteEmpty: !me.create,
110 disabled: true
111 });
112
aff192e6
DM
113 column2.push({
114 xtype: 'bondModeSelector',
0070ee37 115 fieldLabel: gettext('Mode'),
aff192e6
DM
116 name: 'bond_mode',
117 value: me.create ? 'balance-rr' : undefined,
ffffb625
DM
118 listeners: {
119 change: function(f, value) {
120 if (value === 'balance-xor' ||
121 value === '802.3ad') {
122 policySelector.setDisabled(false);
123 } else {
124 policySelector.setDisabled(true);
125 policySelector.setValue('');
126 }
127 }
128 },
aff192e6
DM
129 allowBlank: false
130 });
ffffb625
DM
131
132 column2.push(policySelector);
133
d11733f8
DM
134 } else if (me.iftype === 'OVSBond') {
135 column2.push({
136 xtype: me.create ? 'PVE.form.BridgeSelector' : 'displayfield',
137 height: 22, // hack: set same height as text fields
138 fieldLabel: PVE.Utils.render_network_iface_type('OVSBridge'),
139 allowBlank: false,
140 nodename: nodename,
141 bridgeType: 'OVSBridge',
142 name: 'ovs_bridge'
143 });
4c917e97
DM
144 column2.push({
145 xtype: 'pveVlanField',
146 deleteEmpty: !me.create,
147 name: 'ovs_tag',
148 value: ''
149 });
d11733f8
DM
150 column2.push({
151 xtype: 'textfield',
152 fieldLabel: gettext('OVS options'),
153 name: 'ovs_options'
154 });
aff192e6
DM
155 }
156
157 var url;
158 var method;
159
160 if (me.create) {
161 url = "/api2/extjs/nodes/" + nodename + "/network";
162 method = 'POST';
163 } else {
164 url = "/api2/extjs/nodes/" + nodename + "/network/" + me.iface;
165 method = 'PUT';
166 }
167
168 var column1 = [
d11733f8
DM
169 {
170 xtype: 'hiddenfield',
171 name: 'type',
172 value: me.iftype
173 },
aff192e6
DM
174 {
175 xtype: me.create ? 'textfield' : 'displayfield',
e4d5bf72 176 fieldLabel: gettext('Name'),
aff192e6
DM
177 height: 22, // hack: set same height as text fields
178 name: 'iface',
179 value: me.iface,
180 vtype: iface_vtype,
181 allowBlank: false
d11733f8
DM
182 }
183 ];
184
78f6a286 185 if (me.iftype === 'OVSBond') {
d11733f8 186 column1.push([
d11733f8
DM
187 {
188 xtype: 'bondModeSelector',
189 fieldLabel: gettext('Mode'),
190 name: 'bond_mode',
191 openvswitch: true,
192 value: me.create ? 'active-backup' : undefined,
193 allowBlank: false
4c917e97
DM
194 },
195 {
196 xtype: 'textfield',
197 fieldLabel: gettext('Slaves'),
198 name: 'ovs_bonds'
d11733f8
DM
199 }
200 ]);
201 } else {
202
203 column1.push([
204 {
205 xtype: 'pvetextfield',
206 deleteEmpty: !me.create,
207 fieldLabel: gettext('IP address'),
208 vtype: 'IPAddress',
209 name: 'address'
210 },
211 {
212 xtype: 'pvetextfield',
213 deleteEmpty: !me.create,
214 fieldLabel: gettext('Subnet mask'),
215 vtype: 'IPAddress',
216 name: 'netmask',
217 validator: function(value) {
218 /*jslint confusion: true */
219 if (!me.items) {
220 return true;
aff192e6 221 }
d11733f8
DM
222 var address = me.down('field[name=address]').getValue();
223 if (value !== '') {
224 if (address === '') {
225 return "Subnet mask requires option 'IP address'";
226 }
227 } else {
228 if (address !== '') {
229 return "Option 'IP address' requires a subnet mask";
230 }
aff192e6 231 }
aff192e6 232
d11733f8
DM
233 return true;
234 }
235 },
236 {
237 xtype: 'pvetextfield',
238 deleteEmpty: !me.create,
239 fieldLabel: gettext('Gateway'),
240 vtype: 'IPAddress',
241 name: 'gateway'
e3c88f89
WB
242 },
243 {
244 xtype: 'pvetextfield',
245 deleteEmpty: !me.create,
246 fieldLabel: gettext('IPv6 address'),
247 vtype: 'IP6Address',
248 name: 'address6'
249 },
250 {
9e945126 251 xtype: 'pvetextfield',
e3c88f89
WB
252 deleteEmpty: !me.create,
253 fieldLabel: gettext('Prefix length'),
9e945126 254 vtype: 'IP6PrefixLength',
e3c88f89
WB
255 name: 'netmask6',
256 value: '',
e3c88f89
WB
257 allowBlank: true,
258 validator: function(value) {
259 /*jslint confusion: true */
260 if (!me.items) {
261 return true;
262 }
263 var address = me.down('field[name=address6]').getValue();
264 if (value !== '') {
265 if (address === '') {
266 return "IPv6 prefix length requires option 'IPv6 address'";
267 }
268 } else {
269 if (address !== '') {
270 return "Option 'IPv6 address' requires an IPv6 prefix length";
271 }
272 }
273
274 return true;
275 }
276 },
277 {
278 xtype: 'pvetextfield',
279 deleteEmpty: !me.create,
280 fieldLabel: gettext('Gateway'),
281 vtype: 'IP6Address',
282 name: 'gateway6'
aff192e6 283 }
d11733f8
DM
284 ]);
285 }
aff192e6
DM
286
287 Ext.applyIf(me, {
aff192e6
DM
288 url: url,
289 method: method,
290 items: {
291 xtype: 'inputpanel',
292 column1: column1,
293 column2: column2
294 }
295 });
296
297 me.callParent();
298
299 if (me.create) {
300 me.down('field[name=iface]').setValue(me.iface_default);
301 } else {
302 me.load({
303 success: function(response, options) {
304 var data = response.result.data;
305 if (data.type !== me.iftype) {
306 var msg = "Got unexpected device type";
e4d5bf72 307 Ext.Msg.alert(gettext('Error'), msg, function() {
aff192e6
DM
308 me.close();
309 });
310 return;
311 }
312 me.setValues(data);
e4d5bf72 313 me.isValid(); // trigger validation
aff192e6
DM
314 }
315 });
316 }
317 }
318});