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 938721FF0E4 for ; Tue, 14 Jul 2026 16:58:30 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id EA0A62134B; Tue, 14 Jul 2026 16:58:29 +0200 (CEST) Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Tue, 14 Jul 2026 16:57:51 +0200 Message-Id: To: "Elias Huhsovitz" , Subject: Re: [PATCH manager 2/3] fix #7803: api: nodes: resolve 'localhost' alias in node-specific endpoints X-Mailer: aerc 0.20.0 References: <20260714145027.53038-1-e.huhsovitz@proxmox.com> <20260714145027.53038-3-e.huhsovitz@proxmox.com> In-Reply-To: <20260714145027.53038-3-e.huhsovitz@proxmox.com> From: "Shannon Sterz" X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1784041055604 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.292 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) RCVD_IN_DNSWL_LOW -0.7 Sender listed at https://www.dnswl.org/, low trust 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: B4FFJ3CLITIC4EICNHV7MC7R3QLDEQE2 X-Message-ID-Hash: B4FFJ3CLITIC4EICNHV7MC7R3QLDEQE2 X-MailFrom: s.sterz@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: On Tue Jul 14, 2026 at 4:50 PM CEST, Elias Huhsovitz wrote: > When 'localhost' is used as the node parameter, the API proxy correctly > routes the request to the local node. However, several endpoint handlers > used the literal string 'localhost' to construct file paths or validate > cluster nodes, resulting in empty data or validation errors. > > Use the new PVE::INotify::resolve_nodename() helper to correctly resolve > the alias before accessing the cluster filesystem or checking node > existence. This fixes the following endpoints: > - NodeConfig (get_config, set_options) > - Certificates (info, upload_custom_cert, remove_custom_cert) > - Nodes (rrd, rrddata, migrateall) > > Signed-off-by: Elias Huhsovitz > --- > PVE/API2/Certificates.pm | 8 +++++--- > PVE/API2/NodeConfig.pm | 6 ++++-- > PVE/API2/Nodes.pm | 13 ++++++------- > 3 files changed, 15 insertions(+), 12 deletions(-) > > diff --git a/PVE/API2/Certificates.pm b/PVE/API2/Certificates.pm > index de8762c5..d567939c 100644 > --- a/PVE/API2/Certificates.pm > +++ b/PVE/API2/Certificates.pm > @@ -7,6 +7,7 @@ use PVE::API2::ACME; > use PVE::Certificate; > use PVE::CertHelpers; > use PVE::Exception qw(raise_param_exc); > +use PVE::INotify; > use PVE::JSONSchema qw(get_standard_option); > use PVE::Tools qw(extract_param file_get_contents file_set_contents); > > @@ -66,7 +67,8 @@ __PACKAGE__->register_method({ > code =3D> sub { > my ($param) =3D @_; > > - my $node_path =3D "/etc/pve/nodes/$param->{node}"; > + my $node =3D PVE::INotify::resolve_nodename($param->{node}); > + my $node_path =3D "/etc/pve/nodes/$node"; this hunk overlaps with my commit in the tls rotation series [1]. since your series tackles this problem in a more complete fashion, the commit in my series can simply be dropped if your patches make it in first. just thought i'd mention it here :) [1]: https://lore.proxmox.com/pdm-devel/20260611120327.257523-4-s.sterz@pro= xmox.com/ > > my $res =3D []; > my $cert_paths =3D [ > @@ -125,7 +127,7 @@ __PACKAGE__->register_method({ > code =3D> sub { > my ($param) =3D @_; > > - my $node =3D extract_param($param, 'node'); > + my $node =3D PVE::INotify::resolve_nodename(extract_param($param= , 'node')); > my $cert_prefix =3D PVE::CertHelpers::cert_path_prefix($node); > > my $certs =3D extract_param($param, 'certificates'); > @@ -188,7 +190,7 @@ __PACKAGE__->register_method({ > code =3D> sub { > my ($param) =3D @_; > > - my $node =3D extract_param($param, 'node'); > + my $node =3D PVE::INotify::resolve_nodename(extract_param($param= , 'node')); > my $cert_prefix =3D PVE::CertHelpers::cert_path_prefix($node); > > my $code =3D sub { > diff --git a/PVE/API2/NodeConfig.pm b/PVE/API2/NodeConfig.pm > index cc726dac..cad81c3e 100644 > --- a/PVE/API2/NodeConfig.pm > +++ b/PVE/API2/NodeConfig.pm > @@ -3,6 +3,7 @@ package PVE::API2::NodeConfig; > use strict; > use warnings; > > +use PVE::INotify; > use PVE::JSONSchema qw(get_standard_option); > use PVE::NodeConfig; > use PVE::Tools qw(extract_param); > @@ -61,7 +62,8 @@ __PACKAGE__->register_method({ > code =3D> sub { > my ($param) =3D @_; > > - my $config =3D PVE::NodeConfig::load_config($param->{node}); > + my $node =3D PVE::INotify::resolve_nodename($param->{node}); > + my $config =3D PVE::NodeConfig::load_config($node); > > if (defined(my $prop =3D $param->{property})) { > return {} if !exists $config->{$prop}; > @@ -91,7 +93,7 @@ __PACKAGE__->register_method({ > my ($param) =3D @_; > > my $delete =3D extract_param($param, 'delete'); > - my $node =3D extract_param($param, 'node'); > + my $node =3D PVE::INotify::resolve_nodename(extract_param($param= , 'node')); > my $digest =3D extract_param($param, 'digest'); > > my $code =3D sub { > diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm > index dfe3b4cf..90ce3c10 100644 > --- a/PVE/API2/Nodes.pm > +++ b/PVE/API2/Nodes.pm > @@ -830,9 +830,9 @@ __PACKAGE__->register_method({ > }, > code =3D> sub { > my ($param) =3D @_; > - > + my $node =3D PVE::INotify::resolve_nodename($param->{node}); > return PVE::RRD::create_rrd_graph( > - "pve-node-9.0/$param->{node}", $param->{timeframe}, $param->= {ds}, $param->{cf}, > + "pve-node-9.0/$node", $param->{timeframe}, $param->{ds}, $pa= ram->{cf}, > ); > > }, > @@ -873,9 +873,9 @@ __PACKAGE__->register_method({ > }, > code =3D> sub { > my ($param) =3D @_; > - > + my $node =3D PVE::INotify::resolve_nodename($param->{node}); > return PVE::RRD::create_rrd_data( > - "pve-node-9.0/$param->{node}", $param->{timeframe}, $param->= {cf}, > + "pve-node-9.0/$node", $param->{timeframe}, $param->{cf}, > ); > }, > }); > @@ -2718,10 +2718,9 @@ __PACKAGE__->register_method({ > } > } > > - my $nodename =3D $param->{node}; > - $nodename =3D PVE::INotify::nodename() if $nodename eq 'localhos= t'; > + my $nodename =3D PVE::INotify::resolve_nodename($param->{node}); > > - my $target =3D $param->{target}; > + my $target =3D PVE::INotify::resolve_nodename($param->{target}); > my $with_local_disks =3D $param->{'with-local-disks'}; > raise_param_exc({ target =3D> "target is local node." }) if $tar= get eq $nodename; >