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