]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/lxc/Network.js
remove displayfield height hack
[pve-manager.git] / www / manager6 / lxc / Network.js
1 Ext.define('PVE.lxc.NetworkInputPanel', {
2 extend: 'PVE.panel.InputPanel',
3 alias: 'widget.pveLxcNetworkInputPanel',
4
5 insideWizard: false,
6
7 setNodename: function(nodename) {
8 var me = this;
9
10 if (!nodename || (me.nodename === nodename)) {
11 return;
12 }
13
14 me.nodename = nodename;
15
16 var bridgesel = me.query("[isFormField][name=bridge]")[0];
17 bridgesel.setNodename(nodename);
18 },
19
20 onGetValues: function(values) {
21 var me = this;
22
23 var id;
24 if (me.create) {
25 id = values.id;
26 delete values.id;
27 } else {
28 id = me.ifname;
29 }
30
31 if (!id) {
32 return {};
33 }
34
35 var newdata = {};
36
37 if (values['ipv6mode'] !== 'static')
38 values['ip6'] = values['ipv6mode'];
39 if (values['ipv4mode'] !== 'static')
40 values['ip'] = values['ipv4mode']
41 newdata[id] = PVE.Parser.printLxcNetwork(values);
42 return newdata;
43 },
44
45 initComponent : function() {
46 var me = this;
47
48 if (!me.dataCache) {
49 throw "no dataCache specified";
50 }
51
52 var cdata = {};
53
54 if (me.insideWizard) {
55 me.ifname = 'net0';
56 cdata.name = 'eth0';
57 }
58
59 if (!me.create) {
60 if (!me.ifname) {
61 throw "no interface name specified";
62 }
63 if (!me.dataCache[me.ifname]) {
64 throw "no such interface '" + me.ifname + "'";
65 }
66
67 cdata = PVE.Parser.parseLxcNetwork(me.dataCache[me.ifname]);
68 }
69
70 var i, netlist = [];
71 for (i = 0; i < 10; i++) {
72 netlist.push({ "name": "net" + i });
73 }
74
75 var netliststore = Ext.create('Ext.data.Store', {
76 fields: ['name'],
77 data: netlist
78 });
79
80 var ifselector = {
81 xtype: 'combobox',
82 fieldLabel: gettext('ID'),
83 store: netliststore,
84 editable: false,
85 name: 'id',
86 value: me.ifname,
87 disabled: !me.create,
88 queryMode: 'local',
89 displayField: 'name',
90 valueField: 'name',
91 validator: function(value) {
92 if (me.create && me.dataCache[value]) {
93 return "Network ID already in use";
94 }
95 return true;
96 }
97 };
98
99 me.column1 = [
100 ifselector,
101 {
102 xtype: 'textfield',
103 name: 'name',
104 fieldLabel: gettext('Name') + ' (i.e. eth0)',
105 allowBlank: false,
106 value: cdata.name,
107 validator: function(value) {
108 var result = true;
109 Ext.Object.each(me.dataCache, function(key, netstr) {
110 if (!key.match(/^net\d+/) || key === me.ifname) {
111 return; // continue
112 }
113 var net = PVE.Parser.parseLxcNetwork(netstr);
114 if (net.name === value) {
115 result = "interface name already in use";
116 return false;
117 }
118 });
119 return result;
120 }
121 },
122 {
123 xtype: 'textfield',
124 name: 'hwaddr',
125 fieldLabel: gettext('MAC address'),
126 vtype: 'MacAddress',
127 value: cdata.hwaddr,
128 allowBlank: true,
129 emptyText: 'auto'
130 },
131 {
132 xtype: 'PVE.form.BridgeSelector',
133 name: 'bridge',
134 nodename: me.nodename,
135 fieldLabel: gettext('Bridge'),
136 value: cdata.bridge,
137 allowBlank: false
138 },
139 {
140 xtype: 'pveVlanField',
141 name: 'tag',
142 value: cdata.tag,
143 },
144 {
145 xtype: 'pvecheckbox',
146 fieldLabel: gettext('Firewall'),
147 name: 'firewall',
148 checked: cdata.firewall,
149 }
150 ];
151
152 var dhcp4 = (cdata.ip === 'dhcp');
153 if (dhcp4) {
154 cdata.ip = '';
155 cdata.gw = '';
156 }
157
158 var auto6 = (cdata.ip6 === 'auto');
159 var dhcp6 = (cdata.ip6 === 'dhcp');
160 if (auto6 || dhcp6) {
161 cdata.ip6 = '';
162 cdata.gw6 = '';
163 }
164
165 me.column2 = [
166 {
167 layout: {
168 type: 'hbox',
169 align: 'middle'
170 },
171 border: false,
172 margin: '0 0 5 0',
173 items: [
174 {
175 xtype: 'label',
176 text: gettext('IPv4') + ':',
177 },
178 {
179 xtype: 'radiofield',
180 boxLabel: gettext('Static'),
181 name: 'ipv4mode',
182 inputValue: 'static',
183 checked: !dhcp4,
184 margin: '0 0 0 10',
185 listeners: {
186 change: function(cb, value) {
187 me.down('field[name=ip]').setDisabled(!value);
188 me.down('field[name=gw]').setDisabled(!value);
189 }
190 }
191 },
192 {
193 xtype: 'radiofield',
194 boxLabel: gettext('DHCP'),
195 name: 'ipv4mode',
196 inputValue: 'dhcp',
197 checked: dhcp4,
198 margin: '0 0 0 10'
199 }
200 ]
201 },
202 {
203 xtype: 'textfield',
204 name: 'ip',
205 vtype: 'IPCIDRAddress',
206 value: cdata.ip,
207 disabled: dhcp4,
208 fieldLabel: gettext('IPv4/CIDR')
209 },
210 {
211 xtype: 'textfield',
212 name: 'gw',
213 value: cdata.gw,
214 vtype: 'IPAddress',
215 disabled: dhcp4,
216 fieldLabel: gettext('Gateway') + ' (' + gettext('IPv4') +')',
217 margin: '0 0 3 0' // override bottom margin to account for the menuseparator
218 },
219 {
220 xtype: 'menuseparator',
221 height: '3',
222 margin: '0'
223 },
224 {
225 layout: {
226 type: 'hbox',
227 align: 'middle'
228 },
229 border: false,
230 margin: '0 0 5 0',
231 items: [
232 {
233 xtype: 'label',
234 text: gettext('IPv6') + ':',
235 },
236 {
237 xtype: 'radiofield',
238 boxLabel: gettext('Static'),
239 name: 'ipv6mode',
240 inputValue: 'static',
241 checked: !(auto6 || dhcp6),
242 margin: '0 0 0 10',
243 listeners: {
244 change: function(cb, value) {
245 me.down('field[name=ip6]').setDisabled(!value);
246 me.down('field[name=gw6]').setDisabled(!value);
247 }
248 }
249 },
250 {
251 xtype: 'radiofield',
252 boxLabel: gettext('DHCP'),
253 name: 'ipv6mode',
254 inputValue: 'dhcp',
255 checked: dhcp6,
256 margin: '0 0 0 10'
257 },
258 {
259 xtype: 'radiofield',
260 boxLabel: gettext('SLAAC'),
261 name: 'ipv6mode',
262 inputValue: 'auto',
263 checked: auto6,
264 margin: '0 0 0 10'
265 }
266 ]
267 },
268 {
269 xtype: 'textfield',
270 name: 'ip6',
271 value: cdata.ip6,
272 vtype: 'IP6CIDRAddress',
273 disabled: (dhcp6 || auto6),
274 fieldLabel: gettext('IPv6/CIDR')
275 },
276 {
277 xtype: 'textfield',
278 name: 'gw6',
279 vtype: 'IP6Address',
280 value: cdata.gw6,
281 disabled: (dhcp6 || auto6),
282 fieldLabel: gettext('Gateway') + ' (' + gettext('IPv6') +')'
283 }
284 ];
285
286 me.callParent();
287 }
288 });
289
290 /*jslint confusion: true */
291 Ext.define('PVE.lxc.NetworkEdit', {
292 extend: 'PVE.window.Edit',
293
294 isAdd: true,
295
296 initComponent : function() {
297 var me = this;
298
299 if (!me.dataCache) {
300 throw "no dataCache specified";
301 }
302
303 if (!me.nodename) {
304 throw "no node name specified";
305 }
306
307 var ipanel = Ext.create('PVE.lxc.NetworkInputPanel', {
308 ifname: me.ifname,
309 nodename: me.nodename,
310 dataCache: me.dataCache,
311 create: me.create
312 });
313
314 Ext.apply(me, {
315 subject: gettext('Network Device') + ' (veth)',
316 digest: me.dataCache.digest,
317 items: [ ipanel ]
318 });
319
320 me.callParent();
321 }
322 });
323
324 Ext.define('PVE.lxc.NetworkView', {
325 extend: 'Ext.grid.GridPanel',
326 alias: ['widget.pveLxcNetworkView'],
327
328 dataCache: {}, // used to store result of last load
329
330 load: function() {
331 var me = this;
332
333 PVE.Utils.setErrorMask(me, true);
334
335 PVE.Utils.API2Request({
336 url: me.url,
337 failure: function(response, opts) {
338 PVE.Utils.setErrorMask(me, gettext('Error') + ': ' + response.htmlStatus);
339 },
340 success: function(response, opts) {
341 PVE.Utils.setErrorMask(me, false);
342 var result = Ext.decode(response.responseText);
343 var data = result.data || {};
344 me.dataCache = data;
345 var records = [];
346 Ext.Object.each(data, function(key, value) {
347 if (!key.match(/^net\d+/)) {
348 return; // continue
349 }
350 var net = PVE.Parser.parseLxcNetwork(value);
351 net.id = key;
352 records.push(net);
353 });
354 me.store.loadData(records);
355 }
356 });
357 },
358
359 initComponent : function() {
360 var me = this;
361
362 var nodename = me.pveSelNode.data.node;
363 if (!nodename) {
364 throw "no node name specified";
365 }
366
367 var vmid = me.pveSelNode.data.vmid;
368 if (!vmid) {
369 throw "no VM ID specified";
370 }
371
372 var caps = Ext.state.Manager.get('GuiCap');
373
374 me.url = '/nodes/' + nodename + '/lxc/' + vmid + '/config';
375
376 var store = new Ext.data.Store({
377 model: 'pve-lxc-network',
378 sorters: [
379 {
380 property : 'id',
381 direction: 'ASC'
382 }
383 ]
384 });
385
386 var sm = Ext.create('Ext.selection.RowModel', {});
387
388 var remove_btn = new PVE.button.Button({
389 text: gettext('Remove'),
390 disabled: true,
391 selModel: sm,
392 enableFn: function(rec) {
393 return !!caps.vms['VM.Config.Network'];
394 },
395 confirmMsg: function (rec) {
396 return Ext.String.format(gettext('Are you sure you want to remove entry {0}'),
397 "'" + rec.data.id + "'");
398 },
399 handler: function(btn, event, rec) {
400 PVE.Utils.API2Request({
401 url: me.url,
402 waitMsgTarget: me,
403 method: 'PUT',
404 params: { 'delete': rec.data.id, digest: me.dataCache.digest },
405 callback: function() {
406 me.load();
407 },
408 failure: function (response, opts) {
409 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
410 }
411 });
412 }
413 });
414
415 var run_editor = function() {
416 var rec = sm.getSelection()[0];
417 if (!rec) {
418 return;
419 }
420
421 if (!caps.vms['VM.Config.Network']) {
422 return false;
423 }
424
425 var win = Ext.create('PVE.lxc.NetworkEdit', {
426 url: me.url,
427 nodename: nodename,
428 dataCache: me.dataCache,
429 ifname: rec.data.id
430 });
431 win.on('destroy', me.load, me);
432 win.show();
433 };
434
435 var edit_btn = new PVE.button.Button({
436 text: gettext('Edit'),
437 selModel: sm,
438 disabled: true,
439 enableFn: function(rec) {
440 if (!caps.vms['VM.Config.Network']) {
441 return false;
442 }
443 return true;
444 },
445 handler: run_editor
446 });
447
448 Ext.apply(me, {
449 store: store,
450 selModel: sm,
451 stateful: false,
452 tbar: [
453 {
454 text: gettext('Add'),
455 disabled: !caps.vms['VM.Config.Network'],
456 handler: function() {
457 var win = Ext.create('PVE.lxc.NetworkEdit', {
458 url: me.url,
459 nodename: nodename,
460 create: true,
461 dataCache: me.dataCache
462 });
463 win.on('destroy', me.load, me);
464 win.show();
465 }
466 },
467 remove_btn,
468 edit_btn
469 ],
470 columns: [
471 {
472 header: gettext('ID'),
473 width: 50,
474 dataIndex: 'id'
475 },
476 {
477 header: gettext('Name'),
478 width: 80,
479 dataIndex: 'name'
480 },
481 {
482 header: gettext('Bridge'),
483 width: 80,
484 dataIndex: 'bridge'
485 },
486 {
487 header: gettext('Firewall'),
488 width: 80,
489 dataIndex: 'firewall',
490 renderer: PVE.Utils.format_boolean
491 },
492 {
493 header: gettext('VLAN Tag'),
494 width: 80,
495 dataIndex: 'tag'
496 },
497 {
498 header: gettext('MAC address'),
499 width: 110,
500 dataIndex: 'hwaddr'
501 },
502 {
503 header: gettext('IP address'),
504 width: 150,
505 dataIndex: 'ip',
506 renderer: function(value, metaData, rec) {
507 if (rec.data.ip && rec.data.ip6) {
508 return rec.data.ip + "<br>" + rec.data.ip6;
509 } else if (rec.data.ip6) {
510 return rec.data.ip6;
511 } else {
512 return rec.data.ip;
513 }
514 }
515 },
516 {
517 header: gettext('Gateway'),
518 width: 150,
519 dataIndex: 'gw',
520 renderer: function(value, metaData, rec) {
521 if (rec.data.gw && rec.data.gw6) {
522 return rec.data.gw + "<br>" + rec.data.gw6;
523 } else if (rec.data.gw6) {
524 return rec.data.gw6;
525 } else {
526 return rec.data.gw;
527 }
528 }
529 }
530 ],
531 listeners: {
532 activate: me.load,
533 itemdblclick: run_editor
534 }
535 });
536
537 me.callParent();
538 }
539 }, function() {
540
541 Ext.define('pve-lxc-network', {
542 extend: "Ext.data.Model",
543 proxy: { type: 'memory' },
544 fields: [ 'id', 'name', 'hwaddr', 'bridge',
545 'ip', 'gw', 'ip6', 'gw6', 'tag', 'firewall' ]
546 });
547
548 });
549