From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 2169F1FF0E0 for ; Thu, 09 Jul 2026 11:21:12 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 3324221641; Thu, 09 Jul 2026 11:19:40 +0200 (CEST) From: Hannes Laimer To: pve-devel@lists.proxmox.com Subject: [PATCH pve-manager v2 25/27] ui: sdn: microseg: add name regex matcher Date: Thu, 9 Jul 2026 11:18:50 +0200 Message-ID: <20260709091852.538885-26-h.laimer@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260709091852.538885-1-h.laimer@proxmox.com> References: <20260709091852.538885-1-h.laimer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1783588754322 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.267 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 6YLY2WLZGIW37SKQ4SZ4Z2IVUQJ7QSU3 X-Message-ID-Hash: 6YLY2WLZGIW37SKQ4SZ4Z2IVUQJ7QSU3 X-MailFrom: h.laimer@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Register the regex assignment type with its own input panel (name regex, interface, groups, comment) and label it in the microseg tree. The add-assignment menu and tree filter pick it up from the schema registry automatically. Signed-off-by: Hannes Laimer --- www/manager6/Utils.js | 5 ++ www/manager6/sdn/microseg/AssignmentEdit.js | 73 +++++++++++++++++++++ www/manager6/sdn/microseg/Base.js | 1 + www/manager6/sdn/microseg/Tree.js | 6 ++ 4 files changed, 85 insertions(+) diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js index 52022a6a..8b483ba1 100644 --- a/www/manager6/Utils.js +++ b/www/manager6/Utils.js @@ -985,6 +985,11 @@ Ext.define('PVE.Utils', { ipanel: 'TagAssignmentInputPanel', urlType: 'assignment', }, + regexassignment: { + name: gettext('Regex Assignment'), + ipanel: 'RegexAssignmentInputPanel', + urlType: 'assignment', + }, }, format_sdnmicroseg_type: function (value, md, record) { diff --git a/www/manager6/sdn/microseg/AssignmentEdit.js b/www/manager6/sdn/microseg/AssignmentEdit.js index 9fca4685..81f8ca9d 100644 --- a/www/manager6/sdn/microseg/AssignmentEdit.js +++ b/www/manager6/sdn/microseg/AssignmentEdit.js @@ -58,6 +58,79 @@ Ext.define('PVE.sdn.microseg.GuestAssignmentInputPanel', { }, }); +Ext.define('PVE.sdn.microseg.RegexAssignmentInputPanel', { + extend: 'PVE.panel.SDNMicrosegBase', + + onlineHelp: 'pvesdn_microseg_assignment', + + autoId: true, + + onGetValues: function (values) { + let me = this; + if (me.isCreate) { + values.type = me.type; + } + if (values.iface === '' || values.iface === null || values.iface === undefined) { + delete values.iface; + } + return me.callParent([values]); + }, + + initComponent: function () { + let me = this; + + me.items = [ + { + xtype: 'proxmoxtextfield', + name: 'name_regex', + fieldLabel: gettext('Name regex'), + allowBlank: false, + maxLength: 1024, + emptyText: '^web-', + disabled: !me.isCreate, + validator: function (value) { + if (!value) { + return true; + } + try { + new RegExp(value); + return true; + } catch (err) { + return err.message; + } + }, + }, + { + xtype: 'proxmoxintegerfield', + name: 'iface', + fieldLabel: gettext('Network interface'), + minValue: 0, + maxValue: 31, + allowBlank: true, + emptyText: gettext('All NICs'), + disabled: !me.isCreate, + }, + { + xtype: 'pveMicrosegGroupSelector', + name: 'groups', + fieldLabel: gettext('Groups'), + multiSelect: true, + allowBlank: false, + }, + { + xtype: 'proxmoxtextfield', + name: 'comment', + fieldLabel: gettext('Comment'), + allowBlank: true, + maxLength: 256, + deleteEmpty: !me.isCreate, + }, + ]; + + me.callParent(); + }, +}); + Ext.define('PVE.sdn.microseg.TagAssignmentInputPanel', { extend: 'PVE.panel.SDNMicrosegBase', diff --git a/www/manager6/sdn/microseg/Base.js b/www/manager6/sdn/microseg/Base.js index a2c263f9..b1d7b596 100644 --- a/www/manager6/sdn/microseg/Base.js +++ b/www/manager6/sdn/microseg/Base.js @@ -19,6 +19,7 @@ Ext.define('pve-sdn-microseg', { 'groups', 'tags', 'tag_match', + 'name_regex', 'direction', ], idProperty: 'id', diff --git a/www/manager6/sdn/microseg/Tree.js b/www/manager6/sdn/microseg/Tree.js index 47c13dfa..8d473b56 100644 --- a/www/manager6/sdn/microseg/Tree.js +++ b/www/manager6/sdn/microseg/Tree.js @@ -22,6 +22,9 @@ Ext.define('PVE.sdn.MicrosegTree', { let match = pv(a, 'tag_match') || 'any'; return `${match}{${(pv(a, 'tags') || []).join(', ')}}${iface}`; } + if (a.type === 'regexassignment') { + return `/${pv(a, 'name_regex')}/${iface}`; + } return `vm${pv(a, 'vmid')}${iface}`; }; @@ -29,6 +32,9 @@ Ext.define('PVE.sdn.MicrosegTree', { if (a.type === 'tagassignment') { return 'fa fa-fw fa-tag'; } + if (a.type === 'regexassignment') { + return 'fa fa-fw fa-code'; + } return 'fa fa-fw fa-link'; }; -- 2.47.3