]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/lxc/Network.js
1 Ext
.define('PVE.lxc.NetworkInputPanel', {
2 extend
: 'Proxmox.panel.InputPanel',
3 alias
: 'widget.pveLxcNetworkInputPanel',
7 onlineHelp
: 'pct_container_network',
9 setNodename: function(nodename
) {
12 if (!nodename
|| me
.nodename
=== nodename
) {
15 me
.nodename
= nodename
;
17 let bridgeSelector
= me
.query("[isFormField][name=bridge]")[0];
18 bridgeSelector
.setNodename(nodename
);
21 onGetValues: function(values
) {
33 if (values
.ipv6mode
!== 'static') {
34 values
.ip6
= values
.ipv6mode
;
36 if (values
.ipv4mode
!== 'static') {
37 values
.ip
= values
.ipv4mode
;
39 newdata
[id
] = PVE
.Parser
.printLxcNetwork(values
);
44 initComponent: function() {
48 if (me
.insideWizard
) {
53 cdata
.firewall
= me
.insideWizard
|| me
.isCreate
;
56 throw "no dataCache specified";
61 throw "no interface name specified";
63 if (!me
.dataCache
[me
.ifname
]) {
64 throw "no such interface '" + me
.ifname
+ "'";
66 cdata
= PVE
.Parser
.parseLxcNetwork(me
.dataCache
[me
.ifname
]);
69 for (let i
= 0; i
< 32; i
++) {
70 let ifname
= 'net' + i
.toString();
71 if (me
.isCreate
&& !me
.dataCache
[ifname
]) {
86 fieldLabel
: gettext('Name'),
87 emptyText
: '(e.g., eth0)',
90 validator: function(value
) {
91 for (const [key
, netRaw
] of Object
.entries(me
.dataCache
)) {
92 if (!key
.match(/^net\d+/) || key
=== me
.ifname
) {
95 let net
= PVE
.Parser
.parseLxcNetwork(netRaw
);
96 if (net
.name
=== value
) {
97 return "interface name already in use";
106 fieldLabel
: gettext('MAC address'),
113 xtype
: 'PVE.form.BridgeSelector',
115 nodename
: me
.nodename
,
116 fieldLabel
: gettext('Bridge'),
121 xtype
: 'pveVlanField',
126 xtype
: 'proxmoxcheckbox',
127 fieldLabel
: gettext('Firewall'),
129 value
: cdata
.firewall
,
133 let dhcp4
= cdata
.ip
=== 'dhcp';
139 let auto6
= cdata
.ip6
=== 'auto';
140 let dhcp6
= cdata
.ip6
=== 'dhcp';
141 if (auto6
|| dhcp6
) {
157 text
: 'IPv4:', // do not localize
161 boxLabel
: gettext('Static'),
163 inputValue
: 'static',
167 change: function(cb
, value
) {
168 me
.down('field[name=ip]').setEmptyText(
169 value
? Proxmox
.Utils
.NoneText
: "",
171 me
.down('field[name=ip]').setDisabled(!value
);
172 me
.down('field[name=gw]').setDisabled(!value
);
178 boxLabel
: 'DHCP', // do not localize
189 vtype
: 'IPCIDRAddress',
191 emptyText
: dhcp4
? '' : Proxmox
.Utils
.NoneText
,
193 fieldLabel
: 'IPv4/CIDR', // do not localize
201 fieldLabel
: gettext('Gateway') + ' (IPv4)',
202 margin
: '0 0 3 0', // override bottom margin to account for the menuseparator
205 xtype
: 'menuseparator',
219 text
: 'IPv6:', // do not localize
223 boxLabel
: gettext('Static'),
225 inputValue
: 'static',
226 checked
: !(auto6
|| dhcp6
),
229 change: function(cb
, value
) {
230 me
.down('field[name=ip6]').setEmptyText(
231 value
? Proxmox
.Utils
.NoneText
: "",
233 me
.down('field[name=ip6]').setDisabled(!value
);
234 me
.down('field[name=gw6]').setDisabled(!value
);
240 boxLabel
: 'DHCP', // do not localize
248 boxLabel
: 'SLAAC', // do not localize
260 emptyText
: dhcp6
|| auto6
? '' : Proxmox
.Utils
.NoneText
,
261 vtype
: 'IP6CIDRAddress',
262 disabled
: dhcp6
|| auto6
,
263 fieldLabel
: 'IPv6/CIDR', // do not localize
270 disabled
: dhcp6
|| auto6
,
271 fieldLabel
: gettext('Gateway') + ' (IPv6)',
275 me
.advancedColumn1
= [
277 xtype
: 'proxmoxintegerfield',
279 emptyText
: gettext('Same as bridge'),
287 me
.advancedColumn2
= [
289 xtype
: 'numberfield',
291 fieldLabel
: gettext('Rate limit') + ' (MB/s)',
295 emptyText
: 'unlimited',
304 Ext
.define('PVE.lxc.NetworkEdit', {
305 extend
: 'Proxmox.window.Edit',
309 initComponent: function() {
313 throw "no dataCache specified";
316 throw "no node name specified";
320 subject
: gettext('Network Device') + ' (veth)',
321 digest
: me
.dataCache
.digest
,
324 xtype
: 'pveLxcNetworkInputPanel',
326 nodename
: me
.nodename
,
327 dataCache
: me
.dataCache
,
328 isCreate
: me
.isCreate
,
337 Ext
.define('PVE.lxc.NetworkView', {
338 extend
: 'Ext.grid.GridPanel',
339 alias
: 'widget.pveLxcNetworkView',
341 onlineHelp
: 'pct_container_network',
343 dataCache
: {}, // used to store result of last load
346 stateId
: 'grid-lxc-network',
351 Proxmox
.Utils
.setErrorMask(me
, true);
353 Proxmox
.Utils
.API2Request({
355 failure: function(response
, opts
) {
356 Proxmox
.Utils
.setErrorMask(me
, gettext('Error') + ': ' + response
.htmlStatus
);
358 success: function(response
, opts
) {
359 Proxmox
.Utils
.setErrorMask(me
, false);
360 let result
= Ext
.decode(response
.responseText
);
361 me
.dataCache
= result
.data
|| {};
363 for (const [key
, value
] of Object
.entries(me
.dataCache
)) {
364 if (key
.match(/^net\d+/)) {
365 let net
= PVE
.Parser
.parseLxcNetwork(value
);
370 me
.store
.loadData(records
);
371 me
.down('button[name=addButton]').setDisabled(records
.length
>= 32);
376 initComponent: function() {
379 let nodename
= me
.pveSelNode
.data
.node
;
381 throw "no node name specified";
384 let vmid
= me
.pveSelNode
.data
.vmid
;
386 throw "no VM ID specified";
389 let caps
= Ext
.state
.Manager
.get('GuiCap');
391 me
.url
= `/nodes/${nodename}/lxc/${vmid}/config`;
393 let store
= new Ext
.data
.Store({
394 model
: 'pve-lxc-network',
403 let sm
= Ext
.create('Ext.selection.RowModel', {});
405 let run_editor = function() {
406 let rec
= sm
.getSelection()[0];
407 if (!rec
|| !caps
.vms
['VM.Config.Network']) {
408 return false; // disable default-propagation when triggered by grid dblclick
410 Ext
.create('PVE.lxc.NetworkEdit', {
413 dataCache
: me
.dataCache
,
416 destroy
: () => me
.load(),
420 return undefined; // make eslint happier
428 text
: gettext('Add'),
430 disabled
: !caps
.vms
['VM.Config.Network'],
431 handler: function() {
432 Ext
.create('PVE.lxc.NetworkEdit', {
436 dataCache
: me
.dataCache
,
438 destroy
: () => me
.load(),
445 xtype
: 'proxmoxButton',
446 text
: gettext('Remove'),
449 enableFn: function(rec
) {
450 return !!caps
.vms
['VM.Config.Network'];
452 confirmMsg
: ({ data
}) =>
453 Ext
.String
.format(gettext('Are you sure you want to remove entry {0}'), `'${data.id}'`),
454 handler: function(btn
, e
, rec
) {
455 Proxmox
.Utils
.API2Request({
460 'delete': rec
.data
.id
,
461 digest
: me
.dataCache
.digest
,
463 callback
: () => me
.load(),
464 failure
: (response
, opts
) => Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
),
469 xtype
: 'proxmoxButton',
470 text
: gettext('Edit'),
473 enableFn
: rec
=> !!caps
.vms
['VM.Config.Network'],
484 header
: gettext('Name'),
489 header
: gettext('Bridge'),
494 header
: gettext('Firewall'),
496 dataIndex
: 'firewall',
497 renderer
: Proxmox
.Utils
.format_boolean
,
500 header
: gettext('VLAN Tag'),
505 header
: gettext('MAC address'),
510 header
: gettext('IP address'),
513 renderer: function(value
, metaData
, rec
) {
514 if (rec
.data
.ip
&& rec
.data
.ip6
) {
515 return rec
.data
.ip
+ "<br>" + rec
.data
.ip6
;
516 } else if (rec
.data
.ip6
) {
524 header
: gettext('Gateway'),
527 renderer: function(value
, metaData
, rec
) {
528 if (rec
.data
.gw
&& rec
.data
.gw6
) {
529 return rec
.data
.gw
+ "<br>" + rec
.data
.gw6
;
530 } else if (rec
.data
.gw6
) {
538 header
: gettext('MTU'),
545 itemdblclick
: run_editor
,
552 Ext
.define('pve-lxc-network', {
553 extend
: "Ext.data.Model",
554 proxy
: { type
: 'memory' },