]>
Commit | Line | Data |
---|---|---|
aff192e6 DM |
1 | Ext.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 | }); |