@@ -1065,7 +1065,7 @@ func (c *clusterCache) IterateHierarchyV2(keys []kube.ResourceKey, action func(r
1065
1065
}
1066
1066
for namespace , namespaceKeys := range keysPerNamespace {
1067
1067
nsNodes := c .nsIndex [namespace ]
1068
- graph := buildGraph (nsNodes )
1068
+ graph := buildGraph (nsNodes , c . resources )
1069
1069
visited := make (map [kube.ResourceKey ]int )
1070
1070
for _ , key := range namespaceKeys {
1071
1071
visited [key ] = 0
@@ -1095,7 +1095,7 @@ func (c *clusterCache) IterateHierarchyV2(keys []kube.ResourceKey, action func(r
1095
1095
}
1096
1096
}
1097
1097
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 {
1099
1099
// Prepare to construct a graph
1100
1100
nodesByUID := make (map [types.UID ][]* Resource , len (nsNodes ))
1101
1101
for _ , node := range nsNodes {
@@ -1106,6 +1106,7 @@ func buildGraph(nsNodes map[kube.ResourceKey]*Resource) map[kube.ResourceKey]map
1106
1106
graph := make (map [kube.ResourceKey ]map [types.UID ]* Resource )
1107
1107
1108
1108
// 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
1109
1110
for _ , childNode := range nsNodes {
1110
1111
for i , ownerRef := range childNode .OwnerRefs {
1111
1112
// First, backfill UID of inferred owner child references.
@@ -1115,7 +1116,16 @@ func buildGraph(nsNodes map[kube.ResourceKey]*Resource) map[kube.ResourceKey]map
1115
1116
// APIVersion is invalid, so we couldn't find the parent.
1116
1117
continue
1117
1118
}
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
+
1119
1129
if ! ok {
1120
1130
// No resource found with the given graph key, so move on.
1121
1131
continue
@@ -1126,6 +1136,18 @@ func buildGraph(nsNodes map[kube.ResourceKey]*Resource) map[kube.ResourceKey]map
1126
1136
1127
1137
// Now that we have the UID of the parent, update the graph.
1128
1138
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
+
1129
1151
if ok {
1130
1152
for _ , uidNode := range uidNodes {
1131
1153
// 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
1148
1170
}
1149
1171
}
1150
1172
}
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
+
1151
1198
return graph
1152
1199
}
1153
1200
0 commit comments