mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-24 12:13:28 +00:00
fix(alerts): resolve intent overrides for agents merged with Proxmox nodes
A pulse-agent installed on a Proxmox node merges into one canonical
resource whose primary ID is node:{sourceID}, so the agent:{hostID}
reference the alert evaluator uses (hostResourceID) matched nothing in
the registry. Per-resource grace overrides and operator-state lookups
then silently resolved to factory policy: alerts fired with no grace
while the policy preview, which receives the canonical ID directly,
showed the override working. Index the prefixed agent ref as a
canonical identity alias so runtime resolution lands on the same
resource the override was saved against.
Refs #1497
Contract-Neutral: behavioral fix #1497: index agent: ref as canonical alias, no public contract shape change
This commit is contained in:
@@ -103,6 +103,13 @@ func canonicalAliases(resource Resource, primaryID, platformID, hostname string)
|
||||
strings.TrimSpace(resource.ID),
|
||||
)
|
||||
values = append(values, resource.Identity.Hostnames...)
|
||||
// Alert evaluation references host-agent resources as "agent:{hostID}"
|
||||
// (see alerts.hostResourceID). A merged PVE-node + pulse-agent resource
|
||||
// takes "node:..." as its primary ID, so the prefixed agent ref must be
|
||||
// indexed explicitly or per-resource policy lookups miss (#1497).
|
||||
if agentID := strings.TrimSpace(canonicalAgentID(resource)); agentID != "" {
|
||||
values = append(values, "agent:"+agentID)
|
||||
}
|
||||
if resource.Proxmox != nil {
|
||||
values = append(
|
||||
values,
|
||||
|
||||
@@ -65,6 +65,7 @@ func TestRefreshCanonicalIdentityPrefersTargetsAndCanonicalHostData(t *testing.T
|
||||
"tower.local",
|
||||
"machine-1",
|
||||
"agent-1",
|
||||
"agent:host-1",
|
||||
}
|
||||
if len(resource.Canonical.Aliases) != len(wantAliases) {
|
||||
t.Fatalf("aliases len = %d, want %d (%v)", len(resource.Canonical.Aliases), len(wantAliases), resource.Canonical.Aliases)
|
||||
@@ -435,6 +436,7 @@ func TestRefreshCanonicalIdentityCanonicalizesTargetResourceTypeAliases(t *testi
|
||||
"docker-runtime-1",
|
||||
"Tower",
|
||||
"agent-1",
|
||||
"agent:host-1",
|
||||
}
|
||||
if len(resource.Canonical.Aliases) != len(wantAliases) {
|
||||
t.Fatalf("aliases len = %d, want %d (%v)", len(resource.Canonical.Aliases), len(wantAliases), resource.Canonical.Aliases)
|
||||
|
||||
@@ -194,6 +194,53 @@ func TestResourceRegistry_GetByReferenceResolvesSourceIDAndCanonicalAlias(t *tes
|
||||
if resolvedID != "agent-host-1" || resource.ID != "agent-host-1" {
|
||||
t.Fatalf("alias reference resolved to id=%q resource=%q, want agent-host-1", resolvedID, resource.ID)
|
||||
}
|
||||
|
||||
resource, resolvedID, ok = rr.GetByReference("agent:machine-1")
|
||||
if !ok {
|
||||
t.Fatal("expected prefixed agent reference to resolve")
|
||||
}
|
||||
if resolvedID != "agent-host-1" || resource.ID != "agent-host-1" {
|
||||
t.Fatalf("agent reference resolved to id=%q resource=%q, want agent-host-1", resolvedID, resource.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// A pulse-agent installed on a Proxmox node merges into one canonical
|
||||
// resource whose primary ID is "node:{sourceID}", not "agent:{agentID}".
|
||||
// Alert evaluation still references the host as "agent:{hostID}"
|
||||
// (alerts.hostResourceID), and per-resource intent policies are keyed by the
|
||||
// canonical registry ID, so this reference must resolve or grace overrides
|
||||
// silently fall back to factory (#1497).
|
||||
func TestResourceRegistry_GetByReferenceResolvesAgentRefOnMergedProxmoxHost(t *testing.T) {
|
||||
rr := NewRegistry(nil)
|
||||
rr.IngestResources([]Resource{{
|
||||
ID: "agent-abcdef123456",
|
||||
Type: ResourceTypeAgent,
|
||||
Name: "proxmox2",
|
||||
Agent: &AgentData{
|
||||
AgentID: "machine-2",
|
||||
Hostname: "proxmox2.local",
|
||||
},
|
||||
Proxmox: &ProxmoxData{
|
||||
SourceID: "node/proxmox2",
|
||||
NodeName: "proxmox2",
|
||||
},
|
||||
}})
|
||||
|
||||
merged, ok := rr.Get("agent-abcdef123456")
|
||||
if !ok || merged.Canonical == nil {
|
||||
t.Fatalf("merged host missing canonical identity: ok=%v resource=%+v", ok, merged)
|
||||
}
|
||||
if merged.Canonical.PrimaryID != "node:node/proxmox2" {
|
||||
t.Fatalf("merged host primary ID = %q, want node:node/proxmox2", merged.Canonical.PrimaryID)
|
||||
}
|
||||
|
||||
resource, resolvedID, ok := rr.GetByReference("agent:machine-2")
|
||||
if !ok {
|
||||
t.Fatal("expected agent reference to resolve on merged Proxmox host")
|
||||
}
|
||||
if resolvedID != "agent-abcdef123456" || resource.ID != "agent-abcdef123456" {
|
||||
t.Fatalf("agent reference resolved to id=%q resource=%q, want agent-abcdef123456", resolvedID, resource.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonitorAdapterKeepsSameNamedProxmoxProvidersDistinct(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user