Skip to content

Commit 5499458

Browse files
committed
Fix nil pointer exceptions + infinite recursion
On-behalf-of: @SAP [email protected] Signed-off-by: Artem Shcherbatiuk <[email protected]>
1 parent ed11c85 commit 5499458

File tree

3 files changed

+57
-41
lines changed

3 files changed

+57
-41
lines changed

gateway/resolver/relations.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func NewRelationResolver(service *Service) *RelationResolver {
2828

2929
// CreateResolver creates a GraphQL resolver for relation fields
3030
func (rr *RelationResolver) CreateResolver(fieldName string) graphql.FieldResolveFn {
31-
return func(p graphql.ResolveParams) (interface{}, error) {
31+
return func(p graphql.ResolveParams) (any, error) {
3232
parentObj, ok := p.Source.(map[string]any)
3333
if !ok {
3434
return nil, nil
@@ -76,7 +76,7 @@ func (rr *RelationResolver) extractReferenceInfo(parentObj map[string]any, field
7676
}
7777

7878
// resolveReference fetches a referenced Kubernetes resource
79-
func (rr *RelationResolver) resolveReference(ctx context.Context, name, namespace, kind, apiGroup string) (interface{}, error) {
79+
func (rr *RelationResolver) resolveReference(ctx context.Context, name, namespace, kind, apiGroup string) (any, error) {
8080
// Try RESTMapper preferred mapping first
8181
if rr.service != nil && rr.service.restMapper != nil {
8282
gk := schema.GroupKind{Group: apiGroup, Kind: kind}

gateway/schema/relations.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,12 @@ func (re *RelationEnhancer) matchesTargetKind(defSchema spec.Schema, targetKind
125125
return false
126126
}
127127

128-
gvkSlice, ok := gvkExt.([]interface{})
128+
gvkSlice, ok := gvkExt.([]any)
129129
if !ok || len(gvkSlice) == 0 {
130130
return false
131131
}
132132

133-
gvkMap, ok := gvkSlice[0].(map[string]interface{})
133+
gvkMap, ok := gvkSlice[0].(map[string]any)
134134
if !ok {
135135
return false
136136
}

listener/pkg/apischema/builder.go

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -118,69 +118,84 @@ func (b *SchemaBuilder) WithScope(rm meta.RESTMapper) *SchemaBuilder {
118118
Str("group", gvks[0].Group).
119119
Str("version", gvks[0].Version).
120120
Str("kind", gvks[0].Kind).
121-
Msg("failed to determine if GVK is namespaced")
121+
Msg("failed to get namespaced info for GVK")
122122
continue
123123
}
124124

125125
if namespaced {
126-
schema.VendorExtensible.AddExtension(common.ScopeExtensionKey, apiextensionsv1.NamespaceScoped)
126+
if schema.VendorExtensible.Extensions == nil {
127+
schema.VendorExtensible.Extensions = map[string]any{}
128+
}
129+
schema.VendorExtensible.Extensions[common.ScopeExtensionKey] = apiextensionsv1.NamespaceScoped
127130
} else {
128-
schema.VendorExtensible.AddExtension(common.ScopeExtensionKey, apiextensionsv1.ClusterScoped)
131+
if schema.VendorExtensible.Extensions == nil {
132+
schema.VendorExtensible.Extensions = map[string]any{}
133+
}
134+
schema.VendorExtensible.Extensions[common.ScopeExtensionKey] = apiextensionsv1.ClusterScoped
129135
}
130-
131136
}
132-
133137
return b
134138
}
135139

136140
func (b *SchemaBuilder) WithCRDCategories(crd *apiextensionsv1.CustomResourceDefinition) *SchemaBuilder {
137-
categories := crd.Spec.Names.Categories
138-
if len(categories) == 0 {
139-
return b
140-
}
141-
gvk, err := getCRDGroupVersionKind(crd.Spec)
142-
if err != nil {
143-
b.err = multierror.Append(b.err, errors.Join(ErrGetCRDGVK, err))
141+
if crd == nil {
144142
return b
145143
}
146144

147-
schema, ok := b.schemas[getOpenAPISchemaKey(*gvk)]
148-
if !ok {
145+
gkv, err := getCRDGroupVersionKind(crd.Spec)
146+
if err != nil {
147+
b.err = multierror.Append(b.err, ErrGetCRDGVK)
149148
return b
150149
}
151150

152-
schema.VendorExtensible.AddExtension(common.CategoriesExtensionKey, categories)
151+
for _, v := range crd.Spec.Versions {
152+
resourceKey := getOpenAPISchemaKey(metav1.GroupVersionKind{Group: gkv.Group, Version: v.Name, Kind: gkv.Kind})
153+
resourceSchema, ok := b.schemas[resourceKey]
154+
if !ok {
155+
continue
156+
}
153157

158+
if len(crd.Spec.Names.Categories) == 0 {
159+
b.log.Debug().Str("resource", resourceKey).Msg("no categories provided for CRD kind")
160+
continue
161+
}
162+
if resourceSchema.VendorExtensible.Extensions == nil {
163+
resourceSchema.VendorExtensible.Extensions = map[string]any{}
164+
}
165+
resourceSchema.VendorExtensible.Extensions[common.CategoriesExtensionKey] = crd.Spec.Names.Categories
166+
b.schemas[resourceKey] = resourceSchema
167+
}
154168
return b
155169
}
156170

157171
func (b *SchemaBuilder) WithApiResourceCategories(list []*metav1.APIResourceList) *SchemaBuilder {
172+
if len(list) == 0 {
173+
return b
174+
}
175+
158176
for _, apiResourceList := range list {
177+
gv, err := runtimeSchema.ParseGroupVersion(apiResourceList.GroupVersion)
178+
if err != nil {
179+
b.err = multierror.Append(b.err, errors.Join(ErrParseGroupVersion, err))
180+
continue
181+
}
159182
for _, apiResource := range apiResourceList.APIResources {
160183
if apiResource.Categories == nil {
161184
continue
162185
}
163-
164-
gv, err := runtimeSchema.ParseGroupVersion(apiResourceList.GroupVersion)
165-
if err != nil {
166-
b.err = multierror.Append(b.err, errors.Join(ErrParseGroupVersion, err))
167-
continue
168-
}
169-
gvk := metav1.GroupVersionKind{
170-
Group: gv.Group,
171-
Version: gv.Version,
172-
Kind: apiResource.Kind,
173-
}
174-
175-
schema, ok := b.schemas[getOpenAPISchemaKey(gvk)]
186+
gvk := metav1.GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: apiResource.Kind}
187+
resourceKey := getOpenAPISchemaKey(gvk)
188+
resourceSchema, ok := b.schemas[resourceKey]
176189
if !ok {
177190
continue
178191
}
179-
180-
schema.VendorExtensible.AddExtension(common.CategoriesExtensionKey, apiResource.Categories)
192+
if resourceSchema.VendorExtensible.Extensions == nil {
193+
resourceSchema.VendorExtensible.Extensions = map[string]any{}
194+
}
195+
resourceSchema.VendorExtensible.Extensions[common.CategoriesExtensionKey] = apiResource.Categories
196+
b.schemas[resourceKey] = resourceSchema
181197
}
182198
}
183-
184199
return b
185200
}
186201

@@ -298,10 +313,11 @@ func (b *SchemaBuilder) expandRelationships(schema *spec.Schema) {
298313
}
299314
}
300315

301-
// Recursively process nested objects
302-
for _, prop := range schema.Properties {
316+
// Recursively process nested objects and write back modifications
317+
for key, prop := range schema.Properties {
303318
if prop.Type.Contains("object") && prop.Properties != nil {
304319
b.expandRelationships(&prop)
320+
schema.Properties[key] = prop
305321
}
306322
}
307323
}
@@ -313,18 +329,18 @@ func (b *SchemaBuilder) Complete() ([]byte, error) {
313329
},
314330
})
315331
if err != nil {
316-
b.err = multierror.Append(b.err, errors.Join(ErrMarshalOpenAPISchema, err))
317-
return nil, b.err
332+
return nil, errors.Join(ErrMarshalOpenAPISchema, err)
318333
}
334+
319335
v2JSON, err := ConvertJSON(v3JSON)
320336
if err != nil {
321-
b.err = multierror.Append(b.err, errors.Join(ErrConvertOpenAPISchema, err))
322-
return nil, b.err
337+
return nil, errors.Join(ErrConvertOpenAPISchema, err)
323338
}
324339

325340
return v2JSON, nil
326341
}
327342

343+
// getOpenAPISchemaKey creates the key that kubernetes uses in its OpenAPI Definitions
328344
func getOpenAPISchemaKey(gvk metav1.GroupVersionKind) string {
329345
// we need to inverse group to match the runtimeSchema key(io.openmfp.core.v1alpha1.Account)
330346
parts := strings.Split(gvk.Group, ".")

0 commit comments

Comments
 (0)