mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-24 04:33:17 +00:00
Keep parent node identity out of Proxmox child aliases (#2561)
Guests and storage copy their node's NodeIdentity, NodeName and NodeAliases into ProxmoxData so search and filters agree after a node rename. canonicalAliases then listed those values as aliases of the child itself, so every guest answered to the node's alert resource ID (for example homelab-minipc). The workloads table matches alerts against canonical aliases, so a single node temperature or memory alert painted every guest on that node yellow and showed up in each guest's Needs Attention panel. The shared alias also made the node's own alias lookup ambiguous in the registry index. Only the node resource now lists its node identity as canonical aliases. Children keep the inherited fields in ProxmoxData, which is what search, storage and backup consumers already read.
This commit is contained in:
@@ -684,7 +684,11 @@ but registry IDs, merge keys, parent links, metrics targets, source-native
|
||||
guest IDs, external URLs, discovery targets, and actions must not. Children
|
||||
such as VMs, containers, and storage inherit the parent's presentation and
|
||||
native aliases so Overview, search, API/websocket/mobile, storage, backups,
|
||||
and filters agree. A linked agent may enrich the canonical node but cannot
|
||||
and filters agree. That inheritance stays in the child's `ProxmoxData`: only
|
||||
the node itself lists its node identity, native name, and native-name aliases
|
||||
as canonical aliases, because a child carrying them would answer to the node's
|
||||
alert resource ID and every guest would show each node alert as its own.
|
||||
A linked agent may enrich the canonical node but cannot
|
||||
replace a configured override with its hostname; same-name cluster identity
|
||||
remains provider scoped even after a native rename.
|
||||
Physical-disk resources own cross-source disk identity. When Proxmox inventory
|
||||
|
||||
@@ -111,12 +111,18 @@ func canonicalAliases(resource Resource, primaryID, platformID, hostname string)
|
||||
values = append(values, "agent:"+agentID)
|
||||
}
|
||||
if resource.Proxmox != nil {
|
||||
values = append(
|
||||
values,
|
||||
strings.TrimSpace(resource.Proxmox.NodeIdentity),
|
||||
strings.TrimSpace(resource.Proxmox.NodeName),
|
||||
)
|
||||
values = append(values, resource.Proxmox.NodeAliases...)
|
||||
// Only the node owns its node identity. Guests and storage inherit
|
||||
// the parent's NodeIdentity and NodeAliases for presentation and
|
||||
// search, but as aliases they would make every child answer to the
|
||||
// node's alert resource ID, so one node alert painted every guest.
|
||||
if CanonicalResourceType(resource.Type) == ResourceTypeAgent {
|
||||
values = append(
|
||||
values,
|
||||
strings.TrimSpace(resource.Proxmox.NodeIdentity),
|
||||
strings.TrimSpace(resource.Proxmox.NodeName),
|
||||
)
|
||||
values = append(values, resource.Proxmox.NodeAliases...)
|
||||
}
|
||||
// PVE disk alerts predate the unified resource registry and retain a
|
||||
// path-shaped resource reference. Resolve it to this exact physical
|
||||
// disk so a UI mute reaches both new and restored occurrences (#2112).
|
||||
|
||||
@@ -176,6 +176,42 @@ func TestRefreshCanonicalIdentityKeepsProxmoxPresentationSeparateFromNativeAlias
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefreshCanonicalIdentityKeepsParentNodeIdentityOffProxmoxChildren(t *testing.T) {
|
||||
parentNode := &ProxmoxData{
|
||||
Instance: "homelab",
|
||||
NodeIdentity: "homelab-minipc",
|
||||
NodeName: "minipc",
|
||||
NodeAliases: []string{"minipc-old"},
|
||||
}
|
||||
for _, resourceType := range []ResourceType{ResourceTypeVM, ResourceTypeSystemContainer, ResourceTypeStorage} {
|
||||
resource := Resource{
|
||||
ID: string(resourceType) + "-1",
|
||||
Type: resourceType,
|
||||
Name: "cloudflared",
|
||||
Proxmox: &ProxmoxData{
|
||||
SourceID: "homelab:minipc:104",
|
||||
Instance: parentNode.Instance,
|
||||
NodeIdentity: parentNode.NodeIdentity,
|
||||
NodeName: parentNode.NodeName,
|
||||
NodeAliases: append([]string(nil), parentNode.NodeAliases...),
|
||||
},
|
||||
MetricsTarget: &MetricsTarget{ResourceType: string(resourceType), ResourceID: "homelab:minipc:104"},
|
||||
}
|
||||
|
||||
RefreshCanonicalIdentity(&resource)
|
||||
|
||||
if resource.Canonical == nil {
|
||||
t.Fatalf("%s: canonical identity missing", resourceType)
|
||||
}
|
||||
for _, alias := range resource.Canonical.Aliases {
|
||||
if alias == "homelab-minipc" || alias == "minipc-old" {
|
||||
t.Fatalf("%s carries parent node identity %q as an alias, so node alerts attach to it: %v",
|
||||
resourceType, alias, resource.Canonical.Aliases)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxmoxDiskAlertAliasIsScopedAndNotPrimaryIdentity(t *testing.T) {
|
||||
resource := Resource{
|
||||
ID: "physical-disk-1", Type: ResourceTypePhysicalDisk,
|
||||
|
||||
Reference in New Issue
Block a user