From 6bf32f98d6fbca3ecb1333aa12cb65a4927952fe Mon Sep 17 00:00:00 2001 From: rcourtman Date: Sat, 8 Nov 2025 23:07:49 +0000 Subject: [PATCH] Fix storage/disk/backup disappearing for clusters with VerifySSL enabled Related to #670, #657 The fix in v4.26.5 (commit 59a97f2e3) attempted to resolve storage disappearing by preferring hostnames over IPs when TLS hostname verification is required (VerifySSL=true and no fingerprint). However, that fix was ineffective because the cluster discovery code was populating BOTH the Host and IP fields with the IP address. **Root Cause:** In internal/api/config_handlers.go, the detectPVECluster function was setting: - endpoint.Host = schemePrefix + clusterNode.IP (when IP was available) - endpoint.IP = clusterNode.IP This meant both fields contained the same IP address. When the monitoring code tried to prefer endpoint.Host for TLS validation (internal/monitoring/monitor.go: 361-368), it was still getting an IP, causing certificate validation to fail with "certificate is valid for pve01.example.com, not 10.0.0.44". **Solution:** Separate the Host and IP fields properly during cluster discovery: - endpoint.Host = hostname (e.g., "https://pve01:8006") for TLS validation - endpoint.IP = IP address (e.g., "10.0.0.44") for DNS-free connections The existing logic in clusterEndpointEffectiveURL() can now correctly choose between them based on TLS requirements. **Impact:** Users with VerifySSL=true who upgraded to v4.26.1-v4.26.5 and lost storage visibility should now see storage, VM disks, and backups again after this fix. --- internal/api/config_handlers.go | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/internal/api/config_handlers.go b/internal/api/config_handlers.go index 403ef84..27414ed 100644 --- a/internal/api/config_handlers.go +++ b/internal/api/config_handlers.go @@ -666,22 +666,22 @@ func detectPVECluster(clientConfig proxmox.ClientConfig, nodeName string, existi } // Build the host URL with proper port - // Prefer IP if available, otherwise use node name - nodeHost := clusterNode.IP - if nodeHost == "" { - nodeHost = clusterNode.Name - } - nodeHost = ensureHostHasPort(nodeHost, defaultPort) - + // Store hostname in Host field (for TLS validation), IP separately endpoint := config.ClusterEndpoint{ NodeID: clusterNode.ID, NodeName: clusterNode.Name, - Host: schemePrefix + nodeHost, GuestURL: findExistingGuestURL(clusterNode.Name, existingEndpoints), Online: clusterNode.Online == 1, LastSeen: time.Now(), } + // Populate Host field with hostname (if available) for TLS certificate validation + if clusterNode.Name != "" { + nodeHost := ensureHostHasPort(clusterNode.Name, defaultPort) + endpoint.Host = schemePrefix + nodeHost + } + + // Populate IP field separately for DNS-free connections if clusterNode.IP != "" { endpoint.IP = clusterNode.IP } @@ -696,24 +696,25 @@ func detectPVECluster(clientConfig proxmox.ClientConfig, nodeName string, existi Msg("All detected cluster nodes failed validation; falling back to cluster metadata") for _, clusterNode := range unvalidatedNodes { - nodeHost := clusterNode.IP - if nodeHost == "" { - nodeHost = clusterNode.Name - } - if nodeHost == "" { + if clusterNode.Name == "" && clusterNode.IP == "" { continue } - nodeHost = ensureHostHasPort(nodeHost, defaultPort) endpoint := config.ClusterEndpoint{ NodeID: clusterNode.ID, NodeName: clusterNode.Name, - Host: schemePrefix + nodeHost, GuestURL: findExistingGuestURL(clusterNode.Name, existingEndpoints), Online: clusterNode.Online == 1, LastSeen: time.Now(), } + // Populate Host field with hostname (if available) for TLS certificate validation + if clusterNode.Name != "" { + nodeHost := ensureHostHasPort(clusterNode.Name, defaultPort) + endpoint.Host = schemePrefix + nodeHost + } + + // Populate IP field separately for DNS-free connections if clusterNode.IP != "" { endpoint.IP = clusterNode.IP }