From 959eaa58cf17d1fd3ce540bf4e9b4184d08f65b5 Mon Sep 17 00:00:00 2001 From: Tibi <110664232+TiberiuGC@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:39:16 +0300 Subject: [PATCH] Support custom nested fields that have path that contains types other than struct (#538) Issue #, if available: Description of changes: Say we want to overwrite a nested field type e.g. for `WAFv2` controller (this is needed due to a cyclic dependency): ``` resources: RuleGroup: Rules.Statement.AndStatement: type: string ``` Currently, the [overwrite code logic](https://github.com/aws-controllers-k8s/code-generator/blob/62466746500d0c01fcfa8e8e3ca6abd9386e4687/pkg/model/crd.go#L660-L687) does not work for the above scenario and it returns the following error: ``` Expected parent field to be of type structure, but found list ``` This happens because `Rules` is not of type `struct`, but `[]struct`, and the referenced code logic requires that all fields within the path (i.e. `Rules` and `Statement` to be of type `struct`). This PR relaxes the logic to allow fields within the path to also be of types `[]struct` and `map[]struct`. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. --- pkg/model/crd.go | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/pkg/model/crd.go b/pkg/model/crd.go index 7618b80e..7aca21b1 100644 --- a/pkg/model/crd.go +++ b/pkg/model/crd.go @@ -656,17 +656,23 @@ func (crd *CRD) addCustomNestedFields(customNestedFields map[string]*ackgenconfi topLevelField := fieldParts[0] f, ok := crd.checkSpecOrStatus(topLevelField) - - if ok && f.ShapeRef.Shape.Type != "structure" { - // We need to panic here because the user is providing wrong configuration. - msg := fmt.Sprintf("Expected parent field to be of type structure, but found %s", f.ShapeRef.Shape.Type) + if !ok { + msg := fmt.Sprintf("Expected top level field %s to be present in Spec or Status", topLevelField) panic(msg) } - // If the provided top level field is not in the crd.SpecFields or crd.StatusFields... - if !ok { - // We need to panic here because the user is providing wrong configuration. - msg := fmt.Sprintf("Expected top level field %s to be present in Spec or Status", topLevelField) + shape := f.ShapeRef.Shape + isValidShapeType := func(shape *awssdkmodel.Shape) bool { + if shape.Type == "structure" || + (shape.Type == "list" && shape.MemberRef.Shape.Type == "structure") || + (shape.Type == "map" && shape.ValueRef.Shape.Type == "structure") { + return true + } + return false + } + + if !isValidShapeType(shape) { + msg := fmt.Sprintf("Expected top level field %s to be of type structure, []structure or map[]structure, but found %s", topLevelField, shape.Type) panic(msg) } @@ -676,13 +682,20 @@ func (crd *CRD) addCustomNestedFields(customNestedFields map[string]*ackgenconfi // loop over the all left fieldParts except the last one for _, currentFieldName := range fieldParts[1 : len(fieldParts)-1] { - // Check if parentField contains current field currentField, ok := parentField.MemberFields[currentFieldName] - if !ok || currentField.ShapeRef.Shape.Type != "structure" { - // Check if the field exists AND is of type structure - msg := fmt.Sprintf("Cannot inject field, %s member doesn't exist or isn't a structure", currentFieldName) + shape := currentField.ShapeRef.Shape + + // if the parentField doesn't contain the current field + if !ok { + msg := fmt.Sprintf("Cannot inject field, nested field %s doesn't exist", currentFieldName) panic(msg) } + + if !isValidShapeType(shape) { + msg := fmt.Sprintf("Expected nested field %s to be of type structure, []structure or map[]structure, but found %s", currentFieldName, shape.Type) + panic(msg) + } + parentField = currentField }