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