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