]>
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
: 'proxmoxcheckbox',
278 fieldLabel
: gettext('Disconnect'),
280 value
: cdata
.link_down
,
283 xtype
: 'proxmoxintegerfield',
285 emptyText
: gettext('Same as bridge'),
293 me
.advancedColumn2
= [
295 xtype
: 'numberfield',
297 fieldLabel
: gettext('Rate limit') + ' (MB/s)',
301 emptyText
: 'unlimited',
310 Ext
.define('PVE.lxc.NetworkEdit', {
311 extend
: 'Proxmox.window.Edit',
315 initComponent: function() {
319 throw "no dataCache specified";
322 throw "no node name specified";
326 subject
: gettext('Network Device') + ' (veth)',
327 digest
: me
.dataCache
.digest
,
330 xtype
: 'pveLxcNetworkInputPanel',
332 nodename
: me
.nodename
,
333 dataCache
: me
.dataCache
,
334 isCreate
: me
.isCreate
,
343 Ext
.define('PVE.lxc.NetworkView', {
344 extend
: 'Ext.grid.GridPanel',
345 alias
: 'widget.pveLxcNetworkView',
347 onlineHelp
: 'pct_container_network',
349 dataCache
: {}, // used to store result of last load
352 stateId
: 'grid-lxc-network',
357 Proxmox
.Utils
.setErrorMask(me
, true);
359 Proxmox
.Utils
.API2Request({
361 failure: function(response
, opts
) {
362 Proxmox
.Utils
.setErrorMask(me
, gettext('Error') + ': ' + response
.htmlStatus
);
364 success: function(response
, opts
) {
365 Proxmox
.Utils
.setErrorMask(me
, false);
366 let result
= Ext
.decode(response
.responseText
);
367 me
.dataCache
= result
.data
|| {};
369 for (const [key
, value
] of Object
.entries(me
.dataCache
)) {
370 if (key
.match(/^net\d+/)) {
371 let net
= PVE
.Parser
.parseLxcNetwork(value
);
376 me
.store
.loadData(records
);
377 me
.down('button[name=addButton]').setDisabled(records
.length
>= 32);
382 initComponent: function() {
385 let nodename
= me
.pveSelNode
.data
.node
;
387 throw "no node name specified";
390 let vmid
= me
.pveSelNode
.data
.vmid
;
392 throw "no VM ID specified";
395 let caps
= Ext
.state
.Manager
.get('GuiCap');
397 me
.url
= `/nodes/${nodename}/lxc/${vmid}/config`;
399 let store
= new Ext
.data
.Store({
400 model
: 'pve-lxc-network',
409 let sm
= Ext
.create('Ext.selection.RowModel', {});
411 let run_editor = function() {
412 let rec
= sm
.getSelection()[0];
413 if (!rec
|| !caps
.vms
['VM.Config.Network']) {
414 return false; // disable default-propagation when triggered by grid dblclick
416 Ext
.create('PVE.lxc.NetworkEdit', {
419 dataCache
: me
.dataCache
,
422 destroy
: () => me
.load(),
426 return undefined; // make eslint happier
434 text
: gettext('Add'),
436 disabled
: !caps
.vms
['VM.Config.Network'],
437 handler: function() {
438 Ext
.create('PVE.lxc.NetworkEdit', {
442 dataCache
: me
.dataCache
,
444 destroy
: () => me
.load(),
451 xtype
: 'proxmoxButton',
452 text
: gettext('Remove'),
455 enableFn: function(rec
) {
456 return !!caps
.vms
['VM.Config.Network'];
458 confirmMsg
: ({ data
}) =>
459 Ext
.String
.format(gettext('Are you sure you want to remove entry {0}'), `'${data.id}'`),
460 handler: function(btn
, e
, rec
) {
461 Proxmox
.Utils
.API2Request({
466 'delete': rec
.data
.id
,
467 digest
: me
.dataCache
.digest
,
469 callback
: () => me
.load(),
470 failure
: (response
, opts
) => Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
),
475 xtype
: 'proxmoxButton',
476 text
: gettext('Edit'),
479 enableFn
: rec
=> !!caps
.vms
['VM.Config.Network'],
490 header
: gettext('Name'),
495 header
: gettext('Bridge'),
500 header
: gettext('Firewall'),
502 dataIndex
: 'firewall',
503 renderer
: Proxmox
.Utils
.format_boolean
,
506 header
: gettext('VLAN Tag'),
511 header
: gettext('MAC address'),
516 header
: gettext('IP address'),
519 renderer: function(value
, metaData
, rec
) {
520 if (rec
.data
.ip
&& rec
.data
.ip6
) {
521 return rec
.data
.ip
+ "<br>" + rec
.data
.ip6
;
522 } else if (rec
.data
.ip6
) {
530 header
: gettext('Gateway'),
533 renderer: function(value
, metaData
, rec
) {
534 if (rec
.data
.gw
&& rec
.data
.gw6
) {
535 return rec
.data
.gw
+ "<br>" + rec
.data
.gw6
;
536 } else if (rec
.data
.gw6
) {
544 header
: gettext('MTU'),
549 header
: gettext('Disconnected'),
551 dataIndex
: 'link_down',
552 renderer
: Proxmox
.Utils
.format_boolean
,
557 itemdblclick
: run_editor
,
564 Ext
.define('pve-lxc-network', {
565 extend
: "Ext.data.Model",
566 proxy
: { type
: 'memory' },