From 0629d3bbcb72ef3f22124e03d014bcd587321426 Mon Sep 17 00:00:00 2001 From: Pulse Monitor Date: Sun, 17 Aug 2025 20:09:45 +0000 Subject: [PATCH] fix: prevent cluster/resources calls on non-clustered nodes Non-clustered Proxmox nodes were getting certificate verification errors when Pulse tried to use the cluster/resources endpoint. Now checks if the node is actually in a cluster before attempting efficient polling. --- internal/monitoring/monitor.go | 14 ++++++++++++++ pkg/proxmox/cluster_client.go | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/internal/monitoring/monitor.go b/internal/monitoring/monitor.go index 5909545e0..16f8c6ce8 100644 --- a/internal/monitoring/monitor.go +++ b/internal/monitoring/monitor.go @@ -38,6 +38,7 @@ type PVEClientInterface interface { GetVMStatus(ctx context.Context, node string, vmid int) (*proxmox.VMStatus, error) GetContainerStatus(ctx context.Context, node string, vmid int) (*proxmox.Container, error) GetClusterResources(ctx context.Context, resourceType string) ([]proxmox.ClusterResource, error) + IsClusterMember(ctx context.Context) (bool, error) } // Monitor handles all monitoring operations @@ -855,6 +856,19 @@ func (m *Monitor) pollPVEInstance(ctx context.Context, instanceName string, clie // pollVMsAndContainersEfficient uses the cluster/resources endpoint to get all VMs and containers in one call func (m *Monitor) pollVMsAndContainersEfficient(ctx context.Context, instanceName string, client PVEClientInterface) bool { + // First check if this is actually a cluster member + // Non-clustered nodes will trigger certificate errors when trying to use cluster/resources + isCluster, err := client.IsClusterMember(ctx) + if err != nil { + log.Debug().Err(err).Str("instance", instanceName).Msg("Could not determine cluster membership, falling back to traditional polling") + return false + } + + if !isCluster { + log.Debug().Str("instance", instanceName).Msg("Node is not in a cluster, using traditional polling") + return false + } + log.Info().Str("instance", instanceName).Msg("Polling VMs and containers using cluster/resources") // Get all resources in a single API call diff --git a/pkg/proxmox/cluster_client.go b/pkg/proxmox/cluster_client.go index bcc027501..4bf8674fa 100644 --- a/pkg/proxmox/cluster_client.go +++ b/pkg/proxmox/cluster_client.go @@ -619,6 +619,20 @@ func (cc *ClusterClient) GetContainerStatus(ctx context.Context, node string, vm return result, err } +// IsClusterMember checks if this node is part of a cluster +func (cc *ClusterClient) IsClusterMember(ctx context.Context) (bool, error) { + var result bool + err := cc.executeWithFailover(ctx, func(client *Client) error { + isMember, err := client.IsClusterMember(ctx) + if err != nil { + return err + } + result = isMember + return nil + }) + return result, err +} + // GetClusterHealthInfo returns detailed health information about the cluster func (cc *ClusterClient) GetClusterHealthInfo() models.ClusterHealth { cc.mu.RLock()