From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 7C99B1FF0E4 for ; Tue, 14 Jul 2026 16:50:43 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 628EF21429; Tue, 14 Jul 2026 16:50:42 +0200 (CEST) From: Elias Huhsovitz To: pve-devel@lists.proxmox.com Subject: [PATCH manager 2/3] fix #7803: api: nodes: resolve 'localhost' alias in node-specific endpoints Date: Tue, 14 Jul 2026 16:50:26 +0200 Message-ID: <20260714145027.53038-3-e.huhsovitz@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260714145027.53038-1-e.huhsovitz@proxmox.com> References: <20260714145027.53038-1-e.huhsovitz@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1784040621490 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.295 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: PPQMCRTADNRCJYM33PCSTRKDEUB2UX2Y X-Message-ID-Hash: PPQMCRTADNRCJYM33PCSTRKDEUB2UX2Y X-MailFrom: e.huhsovitz@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: Elias Huhsovitz X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: 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 => sub { my ($param) = @_; - my $node_path = "/etc/pve/nodes/$param->{node}"; + my $node = PVE::INotify::resolve_nodename($param->{node}); + my $node_path = "/etc/pve/nodes/$node"; my $res = []; my $cert_paths = [ @@ -125,7 +127,7 @@ __PACKAGE__->register_method({ code => sub { my ($param) = @_; - my $node = extract_param($param, 'node'); + my $node = PVE::INotify::resolve_nodename(extract_param($param, 'node')); my $cert_prefix = PVE::CertHelpers::cert_path_prefix($node); my $certs = extract_param($param, 'certificates'); @@ -188,7 +190,7 @@ __PACKAGE__->register_method({ code => sub { my ($param) = @_; - my $node = extract_param($param, 'node'); + my $node = PVE::INotify::resolve_nodename(extract_param($param, 'node')); my $cert_prefix = PVE::CertHelpers::cert_path_prefix($node); my $code = 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 => sub { my ($param) = @_; - my $config = PVE::NodeConfig::load_config($param->{node}); + my $node = PVE::INotify::resolve_nodename($param->{node}); + my $config = PVE::NodeConfig::load_config($node); if (defined(my $prop = $param->{property})) { return {} if !exists $config->{$prop}; @@ -91,7 +93,7 @@ __PACKAGE__->register_method({ my ($param) = @_; my $delete = extract_param($param, 'delete'); - my $node = extract_param($param, 'node'); + my $node = PVE::INotify::resolve_nodename(extract_param($param, 'node')); my $digest = extract_param($param, 'digest'); my $code = 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 => sub { my ($param) = @_; - + my $node = 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}, $param->{cf}, ); }, @@ -873,9 +873,9 @@ __PACKAGE__->register_method({ }, code => sub { my ($param) = @_; - + my $node = 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 = $param->{node}; - $nodename = PVE::INotify::nodename() if $nodename eq 'localhost'; + my $nodename = PVE::INotify::resolve_nodename($param->{node}); - my $target = $param->{target}; + my $target = PVE::INotify::resolve_nodename($param->{target}); my $with_local_disks = $param->{'with-local-disks'}; raise_param_exc({ target => "target is local node." }) if $target eq $nodename; -- 2.47.3