From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 25A541FF143 for ; Sat, 28 Mar 2026 21:19:12 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8A46284F0; Sat, 28 Mar 2026 21:19:35 +0100 (CET) Message-ID: <69536c3b-c7dc-4409-981d-783949dc5d03@proxmox.com> Date: Sat, 28 Mar 2026 21:19:31 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Beta Subject: Re: [PATCH pve-manager v8 21/21] sdn: add dry-run diff view for sdn apply To: Gabriel Goller , pve-devel@lists.proxmox.com References: <20260327150127.545193-1-g.goller@proxmox.com> <20260327150127.545193-22-g.goller@proxmox.com> Content-Language: en-US From: Thomas Lamprecht In-Reply-To: <20260327150127.545193-22-g.goller@proxmox.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1774729119527 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.011 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 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. 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: K74E2XKGZY7CUXPU77ORFMKOZPQFRC2G X-Message-ID-Hash: K74E2XKGZY7CUXPU77ORFMKOZPQFRC2G X-MailFrom: t.lamprecht@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 CC: Wolfgang Bumiller X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Am 27.03.26 um 16:01 schrieb Gabriel Goller: > Introduce a new SdnDiffView modal that runs a dry-run and shows the frr > and ifupdown2 configuration changes which will be made when clicking > apply. Now the user knows which config options will be set without > needing to apply the config. This is not really a ideal (modern) ExtJS component implementation, i.e. could be more declarative, and has some smaller UX issues, like scrolling the whole view, not the two panels that can actually get taller separately. We also might want to load this for all nodes, as with more than a handful of nodes this becomes rather very annoying to cross-check. But that we can still do/extend later just fine, so no hard feelings here for now. My reimplementation that's still relatively close to yours semantically: Ext.define('PVE.sdn.SdnDiffView', { extend: 'Ext.window.Window', width: 800, height: 900, modal: true, title: gettext('Pending SDN configuration changes'), layout: { type: 'vbox', align: 'stretch', }, viewModel: { data: { node: undefined, frr_diff: '', interfaces_diff: '', }, }, controller: { xclass: 'Ext.app.ViewController', nodeChange: function (_field, value) { let me = this; let vm = me.getViewModel(); let view = me.getView(); vm.set('node', value); view.setLoading(gettext('Fetching diff...')); Proxmox.Async.api2({ url: '/cluster/sdn/dry-run', params: { node: value }, method: 'GET', }) .then((req) => { let diff = req.result.data; vm.set('frr_diff', Ext.htmlEncode(diff['frr-diff'] ?? gettext('No changes'))); vm.set( 'interfaces_diff', Ext.htmlEncode(diff['interfaces-diff'] ?? gettext('No changes')), ); }) .catch(Proxmox.Utils.alertResponseFailure) .finally(() => { view.setLoading(false); }); }, }, items: [ { xtype: 'pveNodeSelector', fieldLabel: gettext('Node'), padding: 10, labelWidth: 120, name: 'node', allowBlank: false, listeners: { change: 'nodeChange', }, }, { xtype: 'panel', title: gettext('FRR Config'), flex: 1, scrollable: true, items: [ { xtype: 'component', padding: 5, style: { 'white-space': 'pre', 'font-family': 'monospace', }, bind: { html: '{frr_diff}', }, }, ], }, { xtype: 'panel', title: gettext('Interfaces Config'), flex: 1, scrollable: true, items: [ { xtype: 'component', padding: 5, style: { 'white-space': 'pre', 'font-family': 'monospace', }, bind: { html: '{interfaces_diff}', }, }, ], }, ], buttons: [ { text: gettext('Close'), handler: function () { this.up('window').close(); }, }, ], });