@@ -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