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