Skip to content

Commit 74eb2d2

Browse files
committed
added support for node selectors and matchLables
On-behalf-of: @SAP [email protected] Signed-off-by: Artem Shcherbatiuk <[email protected]>
1 parent 6e1ef38 commit 74eb2d2

File tree

2 files changed

+106
-30
lines changed

2 files changed

+106
-30
lines changed

gateway/resolver/resolver.go

Lines changed: 96 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,62 +25,132 @@ import (
2525
"github.com/openmfp/golang-commons/logger"
2626
)
2727

28-
// convertMapsToArrays transforms labels and annotations from maps to arrays (for GraphQL output)
28+
// convertMapsToArrays transforms label-like fields from maps to arrays (for GraphQL output)
2929
// map[string]string → []Label
3030
func convertMapsToArrays(obj any) any {
3131
objMap, ok := obj.(map[string]interface{})
3232
if !ok {
3333
return obj
3434
}
3535

36-
// Check if this object has metadata
37-
metadata, hasMetadata := objMap["metadata"]
38-
if !hasMetadata {
39-
return obj
40-
}
41-
42-
metadataMap, ok := metadata.(map[string]interface{})
43-
if !ok {
44-
return obj
36+
// Process metadata fields
37+
if metadata := objMap["metadata"]; metadata != nil {
38+
objMap["metadata"] = processMetadataToArrays(metadata)
4539
}
4640

47-
// Transform labels and annotations to arrays (in-place)
48-
for k, v := range metadataMap {
49-
if (k == "labels" || k == "annotations") && v != nil {
50-
metadataMap[k] = mapToArray(v)
51-
}
41+
// Process spec fields
42+
if spec := objMap["spec"]; spec != nil {
43+
objMap["spec"] = processSpecToArrays(spec)
5244
}
5345

5446
return obj
5547
}
5648

57-
// convertArraysToMaps transforms labels and annotations from arrays to maps (for Kubernetes input)
49+
// convertArraysToMaps transforms label-like fields from arrays to maps (for Kubernetes input)
5850
// []Label → map[string]string
5951
func convertArraysToMaps(obj any) any {
6052
objMap, ok := obj.(map[string]interface{})
6153
if !ok {
6254
return obj
6355
}
6456

65-
// Check if this object has metadata
66-
metadata, hasMetadata := objMap["metadata"]
67-
if !hasMetadata {
68-
return obj
57+
// Process metadata fields
58+
if metadata := objMap["metadata"]; metadata != nil {
59+
objMap["metadata"] = processMetadataToMaps(metadata)
60+
}
61+
62+
// Process spec fields
63+
if spec := objMap["spec"]; spec != nil {
64+
objMap["spec"] = processSpecToMaps(spec)
65+
}
66+
67+
return obj
68+
}
69+
70+
// processMetadataToArrays handles metadata.labels and metadata.annotations conversion to arrays
71+
func processMetadataToArrays(metadata any) any {
72+
metadataMap, ok := metadata.(map[string]interface{})
73+
if !ok {
74+
return metadata
75+
}
76+
77+
if labels := metadataMap["labels"]; labels != nil {
78+
metadataMap["labels"] = mapToArray(labels)
79+
}
80+
if annotations := metadataMap["annotations"]; annotations != nil {
81+
metadataMap["annotations"] = mapToArray(annotations)
6982
}
7083

84+
return metadataMap
85+
}
86+
87+
// processMetadataToMaps handles metadata.labels and metadata.annotations conversion to maps
88+
func processMetadataToMaps(metadata any) any {
7189
metadataMap, ok := metadata.(map[string]interface{})
7290
if !ok {
73-
return obj
91+
return metadata
92+
}
93+
94+
if labels := metadataMap["labels"]; labels != nil {
95+
metadataMap["labels"] = arrayToMap(labels)
96+
}
97+
if annotations := metadataMap["annotations"]; annotations != nil {
98+
metadataMap["annotations"] = arrayToMap(annotations)
99+
}
100+
101+
return metadataMap
102+
}
103+
104+
// processSpecToArrays handles spec.nodeSelector and spec.selector.matchLabels conversion to arrays
105+
func processSpecToArrays(spec any) any {
106+
specMap, ok := spec.(map[string]interface{})
107+
if !ok {
108+
return spec
109+
}
110+
111+
if nodeSelector := specMap["nodeSelector"]; nodeSelector != nil {
112+
specMap["nodeSelector"] = mapToArray(nodeSelector)
113+
}
114+
if selector := specMap["selector"]; selector != nil {
115+
specMap["selector"] = processSelector(selector, true)
116+
}
117+
118+
return specMap
119+
}
120+
121+
// processSpecToMaps handles spec.nodeSelector and spec.selector.matchLabels conversion to maps
122+
func processSpecToMaps(spec any) any {
123+
specMap, ok := spec.(map[string]interface{})
124+
if !ok {
125+
return spec
126+
}
127+
128+
if nodeSelector := specMap["nodeSelector"]; nodeSelector != nil {
129+
specMap["nodeSelector"] = arrayToMap(nodeSelector)
130+
}
131+
if selector := specMap["selector"]; selector != nil {
132+
specMap["selector"] = processSelector(selector, false)
74133
}
75134

76-
// Transform labels and annotations to maps (in-place)
77-
for k, v := range metadataMap {
78-
if (k == "labels" || k == "annotations") && v != nil {
79-
metadataMap[k] = arrayToMap(v)
135+
return specMap
136+
}
137+
138+
// processSelector handles selector.matchLabels conversion
139+
func processSelector(selector any, toArray bool) any {
140+
selectorMap, ok := selector.(map[string]interface{})
141+
if !ok {
142+
return selector
143+
}
144+
145+
if matchLabels := selectorMap["matchLabels"]; matchLabels != nil {
146+
if toArray {
147+
selectorMap["matchLabels"] = mapToArray(matchLabels)
148+
} else {
149+
selectorMap["matchLabels"] = arrayToMap(matchLabels)
80150
}
81151
}
82152

83-
return obj
153+
return selectorMap
84154
}
85155

86156
// mapToArray converts a label map to array format

gateway/schema/schema.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -448,18 +448,24 @@ func (g *Gateway) handleObjectFieldSpecType(fieldSpec spec.Schema, typePrefix st
448448
} else if fieldSpec.AdditionalProperties != nil && fieldSpec.AdditionalProperties.Schema != nil {
449449
// Handle map types
450450
if len(fieldSpec.AdditionalProperties.Schema.Type) == 1 && fieldSpec.AdditionalProperties.Schema.Type[0] == "string" {
451-
// Check if this is a labels or annotations field
451+
// Check if this is a field that should use Label arrays for dot-notation support
452452
currentFieldName := ""
453453
if len(fieldPath) > 0 {
454454
currentFieldName = fieldPath[len(fieldPath)-1]
455455
}
456456

457-
// Check if we're in a metadata context or processing a known ObjectMeta type
457+
// Check various contexts where Label arrays should be used
458458
isInMetadata := len(fieldPath) >= 2 && fieldPath[len(fieldPath)-2] == "metadata"
459459
isObjectMetaType := strings.Contains(typePrefix, "ObjectMeta") || strings.Contains(typePrefix, "meta_v1")
460+
isInSelector := len(fieldPath) >= 2 && fieldPath[len(fieldPath)-2] == "selector"
461+
isInSpec := len(fieldPath) >= 2 && fieldPath[len(fieldPath)-2] == "spec"
460462

461-
if (isInMetadata || isObjectMetaType) && (currentFieldName == "labels" || currentFieldName == "annotations") {
462-
// This is a labels or annotations field
463+
// Identify fields that need Label array treatment
464+
isLabelsOrAnnotations := (isInMetadata || isObjectMetaType) && (currentFieldName == "labels" || currentFieldName == "annotations")
465+
isNodeSelector := isInSpec && currentFieldName == "nodeSelector"
466+
isMatchLabels := isInSelector && currentFieldName == "matchLabels"
467+
468+
if isLabelsOrAnnotations || isNodeSelector || isMatchLabels {
463469
// Use List(LabelType) for output (allows querying key/value fields)
464470
// Use List(LabelInputType) for input (supports array syntax)
465471
return graphql.NewList(LabelType), graphql.NewList(LabelInputType), nil

0 commit comments

Comments
 (0)