]>
Commit | Line | Data |
---|---|---|
a2f57991 | 1 | /*jslint confusion: true */ |
9021b40c DM |
2 | Ext.define('PVE.OpenVZ.NetIfEdit', { |
3 | extend: 'PVE.window.Edit', | |
4 | ||
f3bb9bb6 DM |
5 | isAdd: true, |
6 | ||
9021b40c DM |
7 | getValues: function() { |
8 | var me = this; | |
9 | ||
10 | var values = me.formPanel.getValues(); | |
661d27c1 DM |
11 | |
12 | if (!me.create) { | |
13 | values.ifname = me.ifname; | |
14 | } | |
9021b40c DM |
15 | |
16 | var newdata = Ext.clone(me.netif); | |
17 | newdata[values.ifname] = values; | |
18 | return { netif: PVE.Parser.printOpenVZNetIf(newdata) }; | |
19 | }, | |
20 | ||
21 | initComponent : function() { | |
22 | var me = this; | |
23 | ||
24 | if (!me.dataCache) { | |
25 | throw "no dataCache specified"; | |
26 | } | |
27 | ||
28 | if (!me.nodename) { | |
29 | throw "no node name specified"; | |
30 | } | |
31 | ||
32 | me.netif = PVE.Parser.parseOpenVZNetIf(me.dataCache.netif) || {}; | |
33 | ||
34 | var cdata = {}; | |
35 | ||
36 | if (!me.create) { | |
37 | if (!me.ifname) { | |
38 | throw "no interface name specified"; | |
39 | } | |
40 | cdata = me.netif[me.ifname]; | |
41 | if (!cdata) { | |
42 | throw "no such interface '" + me.ifname + "'"; | |
43 | } | |
44 | } | |
45 | ||
46 | Ext.apply(me, { | |
f3bb9bb6 | 47 | subject: gettext('Network Device') + ' (veth)', |
9021b40c DM |
48 | digest: me.dataCache.digest, |
49 | width: 350, | |
50 | fieldDefaults: { | |
51 | labelWidth: 130 | |
52 | }, | |
53 | items: [ | |
54 | { | |
55 | xtype: me.create ? 'textfield' : 'displayfield', | |
56 | name: 'ifname', | |
57 | height: 22, // hack: set same height as text fields | |
f3bb9bb6 | 58 | fieldLabel: gettext('Name') + ' (i.e. eth0)', |
9021b40c DM |
59 | allowBlank: false, |
60 | value: cdata.ifname, | |
61 | validator: function(value) { | |
62 | if (me.create && me.netif[value]) { | |
63 | return "interface name already in use"; | |
64 | } | |
65 | return true; | |
66 | } | |
67 | }, | |
68 | { | |
69 | xtype: 'textfield', | |
70 | name: 'mac', | |
0070ee37 | 71 | fieldLabel: gettext('MAC address'), |
9021b40c DM |
72 | vtype: 'MacAddress', |
73 | value: cdata.mac, | |
74 | allowBlank: me.create, | |
75 | emptyText: 'auto' | |
76 | }, | |
77 | { | |
78 | xtype: 'PVE.form.BridgeSelector', | |
79 | name: 'bridge', | |
80 | nodename: me.nodename, | |
0070ee37 | 81 | fieldLabel: gettext('Bridge'), |
9021b40c DM |
82 | value: cdata.bridge, |
83 | allowBlank: false | |
84 | }, | |
85 | { | |
86 | xtype: 'textfield', | |
87 | name: 'host_ifname', | |
0070ee37 | 88 | fieldLabel: gettext('Host device name'), |
9021b40c DM |
89 | value: cdata.host_ifname, |
90 | allowBlank: true, | |
91 | emptyText: 'auto' | |
92 | }, | |
93 | { | |
94 | xtype: 'textfield', | |
95 | name: 'host_mac', | |
0070ee37 | 96 | fieldLabel: gettext('Host MAC address'), |
9021b40c DM |
97 | vtype: 'MacAddress', |
98 | value: cdata.host_mac, | |
99 | allowBlank: true, | |
100 | emptyText: 'auto' | |
101 | } | |
102 | ] | |
103 | }); | |
104 | ||
105 | me.callParent(); | |
106 | } | |
107 | }); | |
108 | ||
109 | Ext.define('PVE.OpenVZ.IPAdd', { | |
110 | extend: 'PVE.window.Edit', | |
111 | ||
f3bb9bb6 DM |
112 | isAdd: true, |
113 | ||
114 | create: true, | |
115 | ||
9021b40c DM |
116 | getValues: function() { |
117 | var me = this; | |
118 | ||
119 | var values = me.formPanel.getValues(); | |
9021b40c DM |
120 | |
121 | if (me.dataCache.ip_address) { | |
122 | return { ip_address: me.dataCache.ip_address + ' ' + values.ipaddress }; | |
123 | } else { | |
124 | return { ip_address: values.ipaddress }; | |
a2f57991 | 125 | } |
9021b40c DM |
126 | }, |
127 | ||
128 | initComponent : function() { | |
129 | var me = this; | |
130 | ||
131 | if (!me.dataCache) { | |
132 | throw "no dataCache specified"; | |
133 | } | |
134 | ||
135 | Ext.apply(me, { | |
f3bb9bb6 | 136 | subject: gettext('IP address') + ' (venet)', |
9021b40c DM |
137 | digest: me.dataCache.digest, |
138 | width: 350, | |
139 | items: { | |
140 | xtype: 'textfield', | |
141 | name: 'ipaddress', | |
f3bb9bb6 | 142 | fieldLabel: gettext('IP address'), |
9021b40c DM |
143 | vtype: 'IPAddress', |
144 | allowBlank: false | |
145 | } | |
146 | }); | |
147 | ||
148 | me.callParent(); | |
149 | } | |
150 | }); | |
151 | ||
152 | ||
153 | Ext.define('PVE.openvz.NetworkView', { | |
154 | extend: 'Ext.grid.GridPanel', | |
9021b40c DM |
155 | alias: ['widget.pveOpenVZNetworkView'], |
156 | ||
157 | dataCache: {}, // used to store result of last load | |
158 | ||
f3bb9bb6 DM |
159 | ipAddressText: gettext('IP address'), |
160 | networkText: gettext('Network'), | |
161 | networkDeviceText: gettext('Network Device'), | |
162 | ||
9021b40c | 163 | renderType: function(value, metaData, record, rowIndex, colIndex, store) { |
f3bb9bb6 | 164 | var me = this; |
9021b40c | 165 | if (value === 'ip') { |
f3bb9bb6 | 166 | return me.ipAddressText; |
9021b40c | 167 | } else if (value === 'net') { |
f3bb9bb6 | 168 | return me.networkText; |
9021b40c | 169 | } else if (value === 'veth') { |
f3bb9bb6 | 170 | return me.networkDeviceText; |
9021b40c DM |
171 | } else { |
172 | return value; | |
173 | } | |
174 | }, | |
175 | ||
176 | renderValue: function(value, metaData, record, rowIndex, colIndex, store) { | |
177 | var type = record.data.type; | |
178 | if (type === 'veth') { | |
179 | return record.data.ifname; | |
180 | } else { | |
181 | return value; | |
182 | } | |
183 | }, | |
184 | ||
185 | load: function() { | |
186 | var me = this; | |
187 | ||
5f663f5f | 188 | PVE.Utils.setErrorMask(me, true); |
9021b40c DM |
189 | |
190 | PVE.Utils.API2Request({ | |
191 | url: me.url, | |
192 | failure: function(response, opts) { | |
f3bb9bb6 | 193 | PVE.Utils.setErrorMask(me, gettext('Error') + ': ' + response.htmlStatus); |
9021b40c DM |
194 | }, |
195 | success: function(response, opts) { | |
5f663f5f | 196 | PVE.Utils.setErrorMask(me, false); |
9021b40c DM |
197 | var result = Ext.decode(response.responseText); |
198 | var data = result.data || {}; | |
199 | me.dataCache = data; | |
200 | var ipAddress = data.ip_address; | |
201 | var records = []; | |
202 | if (ipAddress) { | |
203 | var ind = 0; | |
204 | Ext.Array.each(ipAddress.split(' '), function(value) { | |
205 | if (value) { | |
206 | records.push({ | |
207 | type: 'ip', | |
208 | id: 'ip' + ind, | |
209 | value: value | |
210 | }); | |
211 | ind++; | |
212 | } | |
213 | }); | |
214 | } | |
215 | var netif = PVE.Parser.parseOpenVZNetIf(me.dataCache.netif); | |
216 | if (netif) { | |
217 | Ext.Object.each(netif, function(iface, data) { | |
218 | ||
219 | records.push(Ext.apply({ | |
220 | type: 'veth', | |
221 | id: iface, | |
222 | value: data.raw | |
223 | }, data)); | |
224 | }); | |
225 | } | |
226 | me.store.loadData(records); | |
227 | } | |
228 | }); | |
229 | }, | |
230 | ||
231 | initComponent : function() { | |
232 | var me = this; | |
233 | ||
a2f57991 | 234 | var nodename = me.pveSelNode.data.node; |
9021b40c DM |
235 | if (!nodename) { |
236 | throw "no node name specified"; | |
237 | } | |
238 | ||
a2f57991 | 239 | var vmid = me.pveSelNode.data.vmid; |
9021b40c DM |
240 | if (!vmid) { |
241 | throw "no VM ID specified"; | |
242 | } | |
243 | ||
8fb7d745 DM |
244 | var caps = Ext.state.Manager.get('GuiCap'); |
245 | ||
9021b40c DM |
246 | me.url = '/nodes/' + nodename + '/openvz/' + vmid + '/config'; |
247 | ||
248 | var store = new Ext.data.Store({ | |
249 | model: 'pve-openvz-network' | |
250 | }); | |
251 | ||
f3bb9bb6 | 252 | var sm = Ext.create('Ext.selection.RowModel', {}); |
9021b40c | 253 | |
f3bb9bb6 DM |
254 | var remove_btn = new PVE.button.Button({ |
255 | text: gettext('Remove'), | |
256 | disabled: true, | |
257 | selModel: sm, | |
8fb7d745 DM |
258 | enableFn: function(rec) { |
259 | return !!caps.vms['VM.Config.Network']; | |
260 | }, | |
f3bb9bb6 DM |
261 | confirmMsg: function (rec) { |
262 | var idtext = rec.id; | |
263 | if (rec.data.type === 'ip') { | |
264 | idtext = rec.data.value; | |
265 | } else if (rec.data.type === 'veth') { | |
266 | idtext = rec.data.id; | |
9021b40c | 267 | } |
f3bb9bb6 DM |
268 | return Ext.String.format(gettext('Are you sure you want to remove entry {0}'), |
269 | "'" + idtext + "'"); | |
270 | }, | |
271 | handler: function(btn, event, rec) { | |
272 | var values = { digest: me.dataCache.digest }; | |
9021b40c | 273 | |
9021b40c | 274 | if (rec.data.type === 'ip') { |
f3bb9bb6 DM |
275 | var ipa = []; |
276 | Ext.Array.each(me.dataCache.ip_address.split(' '), function(value) { | |
277 | if (value && value !== rec.data.value) { | |
278 | ipa.push(value); | |
279 | } | |
280 | }); | |
281 | values.ip_address = ipa.join(' '); | |
9021b40c | 282 | } else if (rec.data.type === 'veth') { |
f3bb9bb6 DM |
283 | var netif = PVE.Parser.parseOpenVZNetIf(me.dataCache.netif); |
284 | delete netif[rec.data.id]; | |
285 | values.netif = PVE.Parser.printOpenVZNetIf(netif); | |
9021b40c | 286 | } else { |
f3bb9bb6 | 287 | return; // not implemented |
9021b40c DM |
288 | } |
289 | ||
f3bb9bb6 DM |
290 | PVE.Utils.API2Request({ |
291 | url: me.url, | |
292 | waitMsgTarget: me, | |
293 | method: 'PUT', | |
294 | params: values, | |
295 | callback: function() { | |
296 | me.load(); | |
297 | }, | |
298 | failure: function (response, opts) { | |
299 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
9021b40c | 300 | } |
9021b40c DM |
301 | }); |
302 | } | |
303 | }); | |
304 | ||
305 | var run_editor = function() { | |
9021b40c DM |
306 | var rec = sm.getSelection()[0]; |
307 | if (!rec || rec.data.type !== 'veth') { | |
308 | return; | |
309 | } | |
310 | ||
8fb7d745 DM |
311 | if (!caps.vms['VM.Config.Network']) { |
312 | return false; | |
313 | } | |
314 | ||
9021b40c DM |
315 | var win = Ext.create('PVE.OpenVZ.NetIfEdit', { |
316 | url: me.url, | |
317 | nodename: nodename, | |
318 | dataCache: me.dataCache, | |
319 | ifname: rec.data.id | |
320 | }); | |
321 | win.on('destroy', me.load, me); | |
322 | win.show(); | |
a2f57991 | 323 | }; |
9021b40c | 324 | |
f3bb9bb6 DM |
325 | var edit_btn = new PVE.button.Button({ |
326 | text: gettext('Edit'), | |
327 | selModel: sm, | |
9021b40c | 328 | disabled: true, |
f3bb9bb6 | 329 | enableFn: function(rec) { |
8fb7d745 DM |
330 | if (!caps.vms['VM.Config.Network']) { |
331 | return false; | |
332 | } | |
f3bb9bb6 DM |
333 | return rec.data.type === 'veth'; |
334 | }, | |
9021b40c DM |
335 | handler: run_editor |
336 | }); | |
337 | ||
9021b40c DM |
338 | |
339 | Ext.applyIf(me, { | |
340 | store: store, | |
f3bb9bb6 | 341 | selModel: sm, |
9021b40c | 342 | stateful: false, |
9021b40c DM |
343 | tbar: [ |
344 | { | |
f3bb9bb6 | 345 | text: gettext('Add'), |
9021b40c DM |
346 | menu: new Ext.menu.Menu({ |
347 | items: [ | |
348 | { | |
f3bb9bb6 | 349 | text: gettext('IP address') + ' (venet)', |
8fb7d745 | 350 | disabled: !caps.vms['VM.Config.Network'], |
9021b40c DM |
351 | //plain: true, |
352 | //iconCls: 'pve-itype-icon-storage', | |
353 | handler: function() { | |
354 | var win = Ext.create('PVE.OpenVZ.IPAdd', { | |
355 | url: me.url, | |
356 | dataCache: me.dataCache | |
357 | }); | |
358 | win.on('destroy', me.load, me); | |
359 | win.show(); | |
360 | } | |
361 | }, | |
362 | { | |
f3bb9bb6 | 363 | text: gettext('Network Device') + ' (veth)', |
8fb7d745 | 364 | disabled: !caps.vms['VM.Config.Network'], |
9021b40c DM |
365 | //plain: true, |
366 | //iconCls: 'pve-itype-icon-storage', | |
367 | handler: function() { | |
368 | var win = Ext.create('PVE.OpenVZ.NetIfEdit', { | |
369 | url: me.url, | |
370 | nodename: nodename, | |
371 | create: true, | |
372 | dataCache: me.dataCache | |
373 | }); | |
374 | win.on('destroy', me.load, me); | |
375 | win.show(); | |
376 | } | |
377 | } | |
378 | ] | |
379 | }) | |
380 | }, | |
381 | remove_btn, | |
382 | edit_btn | |
383 | ], | |
384 | columns: [ | |
385 | { | |
f3bb9bb6 | 386 | header: gettext('Type'), |
9021b40c DM |
387 | width: 110, |
388 | dataIndex: 'type', | |
389 | renderer: me.renderType | |
390 | }, | |
391 | { | |
f3bb9bb6 | 392 | header: gettext('IP address') +'/' + gettext('Name'), |
9021b40c DM |
393 | width: 110, |
394 | dataIndex: 'value', | |
395 | renderer: me.renderValue | |
396 | }, | |
397 | { | |
0070ee37 | 398 | header: gettext('Bridge'), |
9021b40c DM |
399 | width: 110, |
400 | dataIndex: 'bridge' | |
401 | }, | |
402 | { | |
0070ee37 | 403 | header: gettext('MAC address'), |
9021b40c DM |
404 | width: 110, |
405 | dataIndex: 'mac' | |
406 | }, | |
407 | { | |
0070ee37 | 408 | header: gettext('Host ifname'), |
9021b40c DM |
409 | width: 110, |
410 | dataIndex: 'host_ifname' | |
411 | }, | |
412 | { | |
0070ee37 | 413 | header: gettext('Host MAC address'), |
9021b40c DM |
414 | width: 110, |
415 | dataIndex: 'host_mac' | |
416 | } | |
417 | ], | |
418 | listeners: { | |
419 | show: me.load, | |
f3bb9bb6 | 420 | itemdblclick: run_editor |
9021b40c DM |
421 | } |
422 | }); | |
423 | ||
a2f57991 | 424 | me.callParent(); |
9021b40c DM |
425 | |
426 | me.load(); | |
427 | } | |
428 | }, function() { | |
429 | ||
430 | Ext.define('pve-openvz-network', { | |
431 | extend: "Ext.data.Model", | |
432 | proxy: { type: 'memory' }, | |
433 | fields: [ 'id', 'type', 'value', 'ifname', 'mac', 'bridge', 'host_ifname', 'host_mac' ] | |
434 | }); | |
435 | ||
436 | }); | |
437 |