From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 665099865B for ; Thu, 11 May 2023 11:47:01 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 411A21F3E7 for ; Thu, 11 May 2023 11:46:31 +0200 (CEST) Received: from maui.proxmox.com (unknown [94.136.29.99]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Thu, 11 May 2023 11:46:30 +0200 (CEST) Received: from maui.proxmox.com (localhost.localdomain [127.0.0.1]) by maui.proxmox.com (Proxmox) with ESMTP id DF2F0401417 for ; Thu, 11 May 2023 11:46:29 +0200 (CEST) Received: from maui.proxmox.com (localhost.localdomain [127.0.0.1]) by maui.proxmox.com (Proxmox) with ESMTP id 9BF324019FA for ; Thu, 11 May 2023 11:46:28 +0200 (CEST) From: Christoph Heiss To: pve-devel@lists.proxmox.com Date: Thu, 11 May 2023 11:46:20 +0200 Message-Id: <20230511094620.667892-3-c.heiss@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230511094620.667892-1-c.heiss@proxmox.com> References: <20230511094620.667892-1-c.heiss@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.485 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pve-devel] [PATCH manager 2/2] ui: fw: allow selecting network interface for rules using combogrid X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 May 2023 09:47:01 -0000 For nodes, VMs and CTs we can show the user a list of available network interfaces (as that information is available) when creating a new firewall rule, much like it is already done in similar places. Adds a lot of convenience when creating new firewall rules if they are interface-specific, as you get a nice summary of the available ones and can simply select it instead of typing it out each time. Nodes can use the new `NetworkInterfaceSelector`, for VMs and CTs a new component is needed, as the VM/CT config needs to be parsed appropriately. It's mostly modeled after the `NetworkInterfaceSelector` component and pretty straight-forward. For datacenter rules, the simple textbox is kept. Signed-off-by: Christoph Heiss --- Note: iptables(8) allows two wildcards for the interface, `!` and `+`. For VMs and CTs this cannot be specified currently anyway, as the API only allows /^net\d+$/. For nodes, since they accept any arbritrary string as interface name, this possibility to specify a wildcard for the interface gets essentially lost. I guess we could still allow users to input any strings if they want - is that something that should be possible (using the GUI)? IOW, do we want to allow that? www/manager6/Makefile | 1 + .../form/VMNetworkInterfaceSelector.js | 79 +++++++++++++++++++ www/manager6/grid/FirewallRules.js | 37 ++++++++- www/manager6/lxc/Config.js | 1 + www/manager6/qemu/Config.js | 1 + 5 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 www/manager6/form/VMNetworkInterfaceSelector.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index a2f5116c..57ba331b 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -71,6 +71,7 @@ JSSRC= \ form/UserSelector.js \ form/VLanField.js \ form/VMCPUFlagSelector.js \ + form/VMNetworkInterfaceSelector.js \ form/VMSelector.js \ form/VNCKeyboardSelector.js \ form/ViewSelector.js \ diff --git a/www/manager6/form/VMNetworkInterfaceSelector.js b/www/manager6/form/VMNetworkInterfaceSelector.js new file mode 100644 index 00000000..fbe631ba --- /dev/null +++ b/www/manager6/form/VMNetworkInterfaceSelector.js @@ -0,0 +1,79 @@ +Ext.define('PVE.form.VMNetworkInterfaceSelector', { + extend: 'Proxmox.form.ComboGrid', + alias: 'widget.PVE.form.VMNetworkInterfaceSelector', + mixins: ['Proxmox.Mixin.CBind'], + + cbindData: (initialConfig) => ({ + isQemu: initialConfig.pveSelNode.data.type === 'qemu', + }), + + displayField: 'id', + + store: { + fields: ['id', 'name', 'bridge', 'ip'], + filterOnLoad: true, + sorters: { + property: 'id', + direction: 'ASC', + }, + }, + + listConfig: { + cbind: {}, + columns: [ + { + header: 'ID', + dataIndex: 'id', + hideable: false, + width: 80, + }, + { + header: gettext('Name'), + dataIndex: 'name', + flex: 1, + cbind: { + hidden: '{isQemu}', + }, + }, + { + header: gettext('Bridge'), + dataIndex: 'bridge', + flex: 1, + }, + { + header: gettext('IP address'), + dataIndex: 'ip', + flex: 1, + cbind: { + hidden: '{isQemu}', + }, + }, + ], + }, + + initComponent: function() { + const { node: nodename, type, vmid } = this.pveSelNode.data; + + Proxmox.Utils.API2Request({ + url: `/nodes/${nodename}/${type}/${vmid}/config`, + method: 'GET', + success: ({ result: { data } }) => { + let networks = []; + for (const [id, value] of Object.entries(data)) { + if (id.match(/^net\d+/)) { + const parsed = type === 'lxc' + ? PVE.Parser.parseLxcNetwork(value) + : PVE.Parser.parseQemuNetwork(id, value); + + networks.push({ ...parsed, id }); + } + } + + this.store.loadData(networks); + }, + }); + + this.callParent(); + }, +}); + diff --git a/www/manager6/grid/FirewallRules.js b/www/manager6/grid/FirewallRules.js index 5777c7f4..9085bd64 100644 --- a/www/manager6/grid/FirewallRules.js +++ b/www/manager6/grid/FirewallRules.js @@ -153,6 +153,7 @@ Ext.define('PVE.FirewallRulePanel', { allow_iface: false, list_refs_url: undefined, + pveSelNode: undefined, onGetValues: function(values) { var me = this; @@ -206,13 +207,35 @@ Ext.define('PVE.FirewallRulePanel', { ]; if (me.allow_iface) { - me.column1.push({ - xtype: 'proxmoxtextfield', + const commonFields = { name: 'iface', deleteEmpty: !me.isCreate, - value: '', fieldLabel: gettext('Interface'), - }); + allowBlank: true, + autoSelect: false, + }; + + if (me.pveSelNode?.data.type === 'node') { + me.column1.push({ + ...commonFields, + xtype: 'PVE.form.NetworkInterfaceSelector', + nodename: me.pveSelNode.data.node, + }); + } else if (me.pveSelNode?.data.type) { + // qemu and lxc + me.column1.push({ + ...commonFields, + xtype: 'PVE.form.VMNetworkInterfaceSelector', + pveSelNode: me.pveSelNode, + }); + } else { + // datacenter + me.column1.push({ + ...commonFields, + xtype: 'proxmoxtextfield', + value: '', + }); + } } else { me.column1.push({ xtype: 'displayfield', @@ -386,6 +409,7 @@ Ext.define('PVE.FirewallRuleEdit', { base_url: undefined, list_refs_url: undefined, + pveSelNode: undefined, allow_iface: false, @@ -414,6 +438,7 @@ Ext.define('PVE.FirewallRuleEdit', { list_refs_url: me.list_refs_url, allow_iface: me.allow_iface, rule_pos: me.rule_pos, + pveSelNode: me.pveSelNode, }); Ext.apply(me, { @@ -546,6 +571,7 @@ Ext.define('PVE.FirewallRules', { base_url: undefined, list_refs_url: undefined, + pveSelNode: undefined, addBtn: undefined, removeBtn: undefined, @@ -671,6 +697,7 @@ Ext.define('PVE.FirewallRules', { base_url: me.base_url, list_refs_url: me.list_refs_url, rule_pos: rec.data.pos, + pveSelNode: me.pveSelNode, }); win.show(); @@ -692,6 +719,7 @@ Ext.define('PVE.FirewallRules', { allow_iface: me.allow_iface, base_url: me.base_url, list_refs_url: me.list_refs_url, + pveSelNode: me.pveSelNode, }); win.on('destroy', reload); win.show(); @@ -713,6 +741,7 @@ Ext.define('PVE.FirewallRules', { base_url: me.base_url, list_refs_url: me.list_refs_url, rec: rec, + pveSelNode: me.pveSelNode, }); win.show(); win.on('destroy', reload); diff --git a/www/manager6/lxc/Config.js b/www/manager6/lxc/Config.js index 23c17d2e..1bd82413 100644 --- a/www/manager6/lxc/Config.js +++ b/www/manager6/lxc/Config.js @@ -314,6 +314,7 @@ Ext.define('PVE.lxc.Config', { base_url: base_url + '/firewall/rules', list_refs_url: base_url + '/firewall/refs', itemId: 'firewall', + pveSelNode: me.pveSelNode, }, { xtype: 'pveFirewallOptions', diff --git a/www/manager6/qemu/Config.js b/www/manager6/qemu/Config.js index 94c540c5..dfe2c56f 100644 --- a/www/manager6/qemu/Config.js +++ b/www/manager6/qemu/Config.js @@ -349,6 +349,7 @@ Ext.define('PVE.qemu.Config', { base_url: base_url + '/firewall/rules', list_refs_url: base_url + '/firewall/refs', itemId: 'firewall', + pveSelNode: me.pveSelNode, }, { xtype: 'pveFirewallOptions', -- 2.39.2