@@ -39,6 +39,11 @@ type ReferenceField struct {
3939 ReferencedKind string
4040 ReferencedGroup string
4141 ReferencedVersion string
42+ // RequiredSegments tracks whether each meaningful path segment is required.
43+ // The slice aligns with the meaningful parts of FieldPath (excluding "properties", "items").
44+ // For example, for FieldPath "properties.spec.properties.groupRef",
45+ // RequiredSegments[0] indicates if "spec" is required, RequiredSegments[1] if "groupRef" is required.
46+ RequiredSegments []bool
4247}
4348
4449type IndexerInfo struct {
@@ -179,12 +184,13 @@ func parseAPIMapping(apiMappingsStr string, schema *apiextensionsv1.JSONSchemaPr
179184 var references []ReferenceField
180185
181186 // Recursively search for x-kubernetes-mapping
182- findReferences (mapping , "" , schema , & references )
187+ // Start with empty requiredSegments slice
188+ findReferences (mapping , "" , schema , nil , & references )
183189
184190 return references , nil
185191}
186192
187- func processKubernetesMapping (v map [string ]any , path string , references * []ReferenceField ) {
193+ func processKubernetesMapping (v map [string ]any , path string , requiredSegments [] bool , references * []ReferenceField ) {
188194 kubeMapping , exists := v ["x-kubernetes-mapping" ]
189195 if ! exists {
190196 return
@@ -217,22 +223,27 @@ func processKubernetesMapping(v map[string]any, path string, references *[]Refer
217223 }
218224
219225 if kind != "" && fieldName != "" {
226+ // Make a copy of requiredSegments to avoid sharing the underlying array
227+ reqCopy := make ([]bool , len (requiredSegments ))
228+ copy (reqCopy , requiredSegments )
229+
220230 ref := ReferenceField {
221231 FieldName : fieldName ,
222232 FieldPath : path ,
223233 ReferencedKind : kind ,
224234 ReferencedGroup : group ,
225235 ReferencedVersion : version ,
236+ RequiredSegments : reqCopy ,
226237 }
227238 * references = append (* references , ref )
228239 }
229240}
230241
231- func findReferences (data any , path string , schema * apiextensionsv1.JSONSchemaProps , references * []ReferenceField ) {
242+ func findReferences (data any , path string , schema * apiextensionsv1.JSONSchemaProps , requiredSegments [] bool , references * []ReferenceField ) {
232243 switch v := data .(type ) {
233244 case map [string ]any :
234245 // Check if this is a kubernetes mapping and process it
235- processKubernetesMapping (v , path , references )
246+ processKubernetesMapping (v , path , requiredSegments , references )
236247
237248 for key , value := range v {
238249 newPath := path
@@ -243,8 +254,18 @@ func findReferences(data any, path string, schema *apiextensionsv1.JSONSchemaPro
243254
244255 // Resolve the child schema for this key and pass it into the recursive call
245256 required , childSchema := getSchemaForPathSegment (schema , key )
246- _ = required
247- findReferences (value , newPath , childSchema , references )
257+
258+ // Track required status for meaningful segments (not "properties" or "items")
259+ newRequiredSegments := requiredSegments
260+ if key != "properties" && key != "items" {
261+ // Special case: the top-level "spec" property is never required per Kubernetes convention
262+ if key == "spec" && len (requiredSegments ) == 0 {
263+ required = false
264+ }
265+ newRequiredSegments = append (requiredSegments , required )
266+ }
267+
268+ findReferences (value , newPath , childSchema , newRequiredSegments , references )
248269 }
249270 case []any :
250271 for i , item := range v {
@@ -253,11 +274,9 @@ func findReferences(data any, path string, schema *apiextensionsv1.JSONSchemaPro
253274 // For arrays pass the items schema if available
254275 var childSchema * apiextensionsv1.JSONSchemaProps
255276 if schema != nil {
256- var required bool
257- required , childSchema = getSchemaForPathSegment (schema , "items" )
258- _ = required
277+ _ , childSchema = getSchemaForPathSegment (schema , "items" )
259278 }
260- findReferences (item , newPath , childSchema , references )
279+ findReferences (item , newPath , childSchema , requiredSegments , references )
261280 }
262281 }
263282}
@@ -285,6 +304,10 @@ func getSchemaForPathSegment(schema *apiextensionsv1.JSONSchemaProps, key string
285304 }
286305
287306 if key == "items" {
307+ // Return the items schema for arrays
308+ if schema .Items != nil && schema .Items .Schema != nil {
309+ return false , schema .Items .Schema
310+ }
288311 return false , nil
289312 }
290313
0 commit comments