Skip to content
This repository was archived by the owner on Aug 28, 2025. It is now read-only.

Commit 5cd1b84

Browse files
committed
use GVK instead of Kind as a kay
On-behalf-of: @SAP [email protected] Signed-off-by: Artem Shcherbatiuk <[email protected]>
1 parent 9f14440 commit 5cd1b84

File tree

1 file changed

+63
-40
lines changed

1 file changed

+63
-40
lines changed

listener/pkg/apischema/builder.go

Lines changed: 63 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ type SchemaBuilder struct {
3737
schemas map[string]*spec.Schema
3838
err *multierror.Error
3939
log *logger.Logger
40-
kindRegistry map[string][]ResourceInfo
41-
preferredVersions map[string]string // map[group/kind]preferredVersion
40+
kindRegistry map[GroupVersionKind]ResourceInfo // Changed: Use GVK as key for precise lookup
41+
preferredVersions map[string]string // map[group/kind]preferredVersion
4242
}
4343

4444
// ResourceInfo holds information about a resource for relationship resolution
@@ -52,7 +52,7 @@ type ResourceInfo struct {
5252
func NewSchemaBuilder(oc openapi.Client, preferredApiGroups []string, log *logger.Logger) *SchemaBuilder {
5353
b := &SchemaBuilder{
5454
schemas: make(map[string]*spec.Schema),
55-
kindRegistry: make(map[string][]ResourceInfo),
55+
kindRegistry: make(map[GroupVersionKind]ResourceInfo),
5656
preferredVersions: make(map[string]string),
5757
log: log,
5858
}
@@ -274,53 +274,78 @@ func (b *SchemaBuilder) buildKindRegistry() {
274274

275275
gvk := gvks[0]
276276

277-
// Add to kind registry
277+
// Add to kind registry with precise GVK key
278278
resourceInfo := ResourceInfo{
279279
Group: gvk.Group,
280280
Version: gvk.Version,
281281
Kind: gvk.Kind,
282282
SchemaKey: schemaKey,
283283
}
284284

285-
// Index by lowercase kind name for consistent lookup
286-
key := strings.ToLower(gvk.Kind)
287-
b.kindRegistry[key] = append(b.kindRegistry[key], resourceInfo)
285+
// Index by full GroupVersionKind for precise lookup (no collisions)
286+
gvkKey := GroupVersionKind{
287+
Group: gvk.Group,
288+
Version: gvk.Version,
289+
Kind: gvk.Kind,
290+
}
291+
b.kindRegistry[gvkKey] = resourceInfo
288292
}
289293

290-
// Sort by preferred version first, then by stability and group priority
291-
for kindKey, infos := range b.kindRegistry {
292-
slices.SortFunc(infos, func(a, bInfo ResourceInfo) int {
293-
// 1. Prioritize resources with preferred versions
294-
aKey := fmt.Sprintf("%s/%s", a.Group, a.Kind)
295-
bKey := fmt.Sprintf("%s/%s", bInfo.Group, bInfo.Kind)
296-
297-
aPreferred := b.preferredVersions[aKey] == a.Version
298-
bPreferred := b.preferredVersions[bKey] == bInfo.Version
294+
// No sorting needed - each GVK is now uniquely indexed
295+
b.log.Debug().Int("gvkCount", len(b.kindRegistry)).Msg("built kind registry for relationships")
296+
}
299297

300-
if aPreferred && !bPreferred {
301-
return -1 // a is preferred, comes first
302-
}
303-
if !aPreferred && bPreferred {
304-
return 1 // b is preferred, comes first
305-
}
298+
// findBestResourceForKind finds the best matching resource for a given kind name
299+
// using preferred version logic and group prioritization
300+
func (b *SchemaBuilder) findBestResourceForKind(kindName string) *ResourceInfo {
301+
// Collect all resources with matching kind name
302+
candidates := make([]ResourceInfo, 0)
306303

307-
// 2. If both or neither are preferred, prioritize by group (core comes first)
308-
if cmp := b.compareGroups(a.Group, bInfo.Group); cmp != 0 {
309-
return cmp
310-
}
304+
for gvk, resourceInfo := range b.kindRegistry {
305+
if strings.EqualFold(gvk.Kind, kindName) {
306+
candidates = append(candidates, resourceInfo)
307+
}
308+
}
311309

312-
// 3. Then by version stability (v1 > v1beta1 > v1alpha1)
313-
if cmp := b.compareVersionStability(a.Version, bInfo.Version); cmp != 0 {
314-
return cmp
315-
}
310+
if len(candidates) == 0 {
311+
return nil
312+
}
316313

317-
// 4. Finally by schema key for deterministic ordering
318-
return strings.Compare(a.SchemaKey, bInfo.SchemaKey)
319-
})
320-
b.kindRegistry[kindKey] = infos
314+
if len(candidates) == 1 {
315+
return &candidates[0]
321316
}
322317

323-
b.log.Debug().Int("kindCount", len(b.kindRegistry)).Msg("built kind registry for relationships")
318+
// Sort candidates using preferred version logic
319+
slices.SortFunc(candidates, func(a, bRes ResourceInfo) int {
320+
// 1. Prioritize resources with preferred versions
321+
aKey := fmt.Sprintf("%s/%s", a.Group, a.Kind)
322+
bKey := fmt.Sprintf("%s/%s", bRes.Group, bRes.Kind)
323+
324+
aPreferred := b.preferredVersions[aKey] == a.Version
325+
bPreferred := b.preferredVersions[bKey] == bRes.Version
326+
327+
if aPreferred && !bPreferred {
328+
return -1 // a is preferred, comes first
329+
}
330+
if !aPreferred && bPreferred {
331+
return 1 // b is preferred, comes first
332+
}
333+
334+
// 2. If both or neither are preferred, prioritize by group (core comes first)
335+
if cmp := b.compareGroups(a.Group, bRes.Group); cmp != 0 {
336+
return cmp
337+
}
338+
339+
// 3. Then by version stability (v1 > v1beta1 > v1alpha1)
340+
if cmp := b.compareVersionStability(a.Version, bRes.Version); cmp != 0 {
341+
return cmp
342+
}
343+
344+
// 4. Finally by schema key for deterministic ordering
345+
return strings.Compare(a.SchemaKey, bRes.SchemaKey)
346+
})
347+
348+
return &candidates[0]
324349
}
325350

326351
// compareGroups prioritizes core Kubernetes groups over custom groups
@@ -385,19 +410,17 @@ func (b *SchemaBuilder) expandRelationships(schema *spec.Schema) {
385410
}
386411

387412
baseKind := strings.TrimSuffix(propName, "Ref")
388-
lookupKey := strings.ToLower(baseKind)
389413

390-
resourceTypes, exists := b.kindRegistry[lookupKey]
391-
if !exists || len(resourceTypes) == 0 {
414+
// Find the best resource for this kind name using preferred version logic
415+
target := b.findBestResourceForKind(baseKind)
416+
if target == nil {
392417
continue
393418
}
394419

395420
fieldName := strings.ToLower(baseKind)
396421
if _, exists := schema.Properties[fieldName]; exists {
397422
continue
398423
}
399-
400-
target := resourceTypes[0]
401424
ref := spec.MustCreateRef(fmt.Sprintf("#/definitions/%s.%s.%s", target.Group, target.Version, target.Kind))
402425
schema.Properties[fieldName] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
403426

0 commit comments

Comments
 (0)