Skip to content

Commit d042f32

Browse files
committed
Track ownerrefs between cluster-scoped and namespaced objects
Signed-off-by: Jonathan Ogilvie <[email protected]>
1 parent dab4cc0 commit d042f32

File tree

2 files changed

+381
-7
lines changed

2 files changed

+381
-7
lines changed

pkg/cache/cluster.go

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,7 @@ func (c *clusterCache) IterateHierarchyV2(keys []kube.ResourceKey, action func(r
10651065
}
10661066
for namespace, namespaceKeys := range keysPerNamespace {
10671067
nsNodes := c.nsIndex[namespace]
1068-
graph := buildGraph(nsNodes)
1068+
graph := buildGraph(nsNodes, c.resources)
10691069
visited := make(map[kube.ResourceKey]int)
10701070
for _, key := range namespaceKeys {
10711071
visited[key] = 0
@@ -1095,7 +1095,7 @@ func (c *clusterCache) IterateHierarchyV2(keys []kube.ResourceKey, action func(r
10951095
}
10961096
}
10971097

1098-
func buildGraph(nsNodes map[kube.ResourceKey]*Resource) map[kube.ResourceKey]map[types.UID]*Resource {
1098+
func buildGraph(nsNodes map[kube.ResourceKey]*Resource, allResources map[kube.ResourceKey]*Resource) map[kube.ResourceKey]map[types.UID]*Resource {
10991099
// Prepare to construct a graph
11001100
nodesByUID := make(map[types.UID][]*Resource, len(nsNodes))
11011101
for _, node := range nsNodes {
@@ -1106,6 +1106,7 @@ func buildGraph(nsNodes map[kube.ResourceKey]*Resource) map[kube.ResourceKey]map
11061106
graph := make(map[kube.ResourceKey]map[types.UID]*Resource)
11071107

11081108
// Loop through all nodes, calling each one "childNode," because we're only bothering with it if it has a parent.
1109+
// First process nodes in the current namespace
11091110
for _, childNode := range nsNodes {
11101111
for i, ownerRef := range childNode.OwnerRefs {
11111112
// First, backfill UID of inferred owner child references.
@@ -1115,7 +1116,16 @@ func buildGraph(nsNodes map[kube.ResourceKey]*Resource) map[kube.ResourceKey]map
11151116
// APIVersion is invalid, so we couldn't find the parent.
11161117
continue
11171118
}
1118-
graphKeyNode, ok := nsNodes[kube.ResourceKey{Group: group.Group, Kind: ownerRef.Kind, Namespace: childNode.Ref.Namespace, Name: ownerRef.Name}]
1119+
// Try same-namespace lookup first (preserves existing behavior)
1120+
sameNSKey := kube.ResourceKey{Group: group.Group, Kind: ownerRef.Kind, Namespace: childNode.Ref.Namespace, Name: ownerRef.Name}
1121+
graphKeyNode, ok := nsNodes[sameNSKey]
1122+
1123+
// If not found and we have cross-namespace capabilities, try cluster-scoped lookup
1124+
if !ok && allResources != nil {
1125+
clusterScopedKey := kube.ResourceKey{Group: group.Group, Kind: ownerRef.Kind, Namespace: "", Name: ownerRef.Name}
1126+
graphKeyNode, ok = allResources[clusterScopedKey]
1127+
}
1128+
11191129
if !ok {
11201130
// No resource found with the given graph key, so move on.
11211131
continue
@@ -1126,6 +1136,18 @@ func buildGraph(nsNodes map[kube.ResourceKey]*Resource) map[kube.ResourceKey]map
11261136

11271137
// Now that we have the UID of the parent, update the graph.
11281138
uidNodes, ok := nodesByUID[ownerRef.UID]
1139+
if !ok && allResources != nil {
1140+
// If parent not found in current namespace, check if it exists in allResources
1141+
// and create a temporary uidNodes list for cross-namespace relationships
1142+
for _, parentCandidate := range allResources {
1143+
if parentCandidate.Ref.UID == ownerRef.UID {
1144+
uidNodes = []*Resource{parentCandidate}
1145+
ok = true
1146+
break
1147+
}
1148+
}
1149+
}
1150+
11291151
if ok {
11301152
for _, uidNode := range uidNodes {
11311153
// Update the graph for this owner to include the child.
@@ -1148,6 +1170,31 @@ func buildGraph(nsNodes map[kube.ResourceKey]*Resource) map[kube.ResourceKey]map
11481170
}
11491171
}
11501172
}
1173+
1174+
// Second pass: process cross-namespace children if allResources is provided
1175+
for _, childNode := range allResources {
1176+
// Skip if already processed in the current namespace
1177+
if _, exists := nsNodes[childNode.ResourceKey()]; exists {
1178+
continue
1179+
}
1180+
1181+
// Check if this child has a parent in the current namespace
1182+
for _, ownerRef := range childNode.OwnerRefs {
1183+
group, err := schema.ParseGroupVersion(ownerRef.APIVersion)
1184+
if err != nil {
1185+
continue
1186+
}
1187+
parentKey := kube.ResourceKey{Group: group.Group, Kind: ownerRef.Kind, Namespace: "", Name: ownerRef.Name}
1188+
if parentNode, exists := nsNodes[parentKey]; exists {
1189+
// Found a cross-namespace relationship
1190+
if _, ok := graph[parentNode.ResourceKey()]; !ok {
1191+
graph[parentNode.ResourceKey()] = make(map[types.UID]*Resource)
1192+
}
1193+
graph[parentNode.ResourceKey()][childNode.Ref.UID] = childNode
1194+
}
1195+
}
1196+
}
1197+
11511198
return graph
11521199
}
11531200

0 commit comments

Comments
 (0)