Skip to content

Commit 77778f3

Browse files
authored
Extend GoTag configuration to nested fields and attributes (#487)
Building upon the introduced `GoTag` configuration in 3753ca3, this commit expands the functionality to cover nested fields and attributes. Now users will be able to set custom Go Tags for nested fields using JSONPath style directives. e.g: ```yaml resources: AccessEntries: fields: AccessPolicies.AccessScope.Type: go_tag: json:"type,omitempty" ``` This patch also refactors `updateTypeDefAttributeWithReference` function to reuse the code for finding and mutating Attribute objects. Tested with eks-controller (`AccessPolicies.AccessScope.Type`). Signed-off-by: Amine Hilaly <[email protected]> By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 610c476 commit 77778f3

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

pkg/model/attr.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
package model
1515

1616
import (
17+
"fmt"
18+
1719
"github.com/aws-controllers-k8s/pkg/names"
1820
awssdkmodel "github.com/aws/aws-sdk-go/private/model/api"
1921
)
@@ -22,6 +24,7 @@ type Attr struct {
2224
Names names.Names
2325
GoType string
2426
Shape *awssdkmodel.Shape
27+
GoTag string
2528
}
2629

2730
func NewAttr(
@@ -35,3 +38,13 @@ func NewAttr(
3538
Shape: shape,
3639
}
3740
}
41+
42+
// GetGoTag returns the Go Tag to inject for this attribute. If the GoTag
43+
// field is not empty, it will be used. Otherwise, one will be generated
44+
// from the attribute's name.
45+
func (a *Attr) GetGoTag() string {
46+
if a.GoTag != "" {
47+
return a.GoTag
48+
}
49+
return fmt.Sprintf("`json:\"%s,omitempty\"`", a.Names.CamelLower)
50+
}

pkg/model/model.go

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -502,21 +502,32 @@ func (m *Model) processNestedFieldTypeDefs(
502502
replaceSecretAttrGoType(crd, field, tdefs)
503503
}
504504
if field.FieldConfig.References != nil {
505-
updateTypeDefAttributeWithReference(fieldPath, tdefs, crd)
505+
updateTypeDefAttributeWithReference(crd, fieldPath, tdefs)
506+
}
507+
if field.FieldConfig.GoTag != nil {
508+
setTypeDefAttributeGoTag(crd, fieldPath, field, tdefs)
506509
}
507510
}
508511
}
509512
}
510513

511-
// updateTypeDefAttributeWithReference adds a new AWSResourceReference attribute
512-
// for the corresponding attribute represented by fieldPath of nested field
513-
func updateTypeDefAttributeWithReference(fieldPath string, tdefs []*TypeDef, crd *CRD) {
514+
// getAttributeFromPath extracts the parent TypeDef and the target attribute for
515+
// the corresponding fieldPath of nested field. This function should only be
516+
// called for nested fieldPath. Non-nested fieldPath should be handled by higher
517+
// level functions.
518+
//
519+
// This function doesn't return an error "urgh" because a lot of the code
520+
// generation code is written in a way that panics are used to indicate
521+
// programmer error. This is one of those cases.
522+
//
523+
// NOTE(a-hilaly): Consider refactoring the code generation code to flow back
524+
// errors instead of panicking.
525+
func getAttributeFromPath(crd *CRD, fieldPath string, tdefs []*TypeDef) (parentTypeDef *TypeDef, target *Attr) {
514526
fp := ackfp.FromString(fieldPath)
515527
if fp.Size() < 2 {
516-
// TypeDef should only be updated with Reference fields for nested fieldPath.
517-
// For non-nested fieldPath, the references are added directly to the resource
518-
// Spec.
519-
return
528+
// This function should only be called for nested fieldPath. Non-nested
529+
// fieldPath should be handled by higher level functions.
530+
return nil, nil
520531
}
521532
// First part of nested reference fieldPath is the name of top level Spec
522533
// field. Ex: For 'ResourcesVpcConfig.SecurityGroupIds' fieldpath the
@@ -587,8 +598,25 @@ func updateTypeDefAttributeWithReference(fieldPath string, tdefs []*TypeDef, crd
587598
" inside %s TypeDef to create reference for %s",
588599
fieldName, parentFieldTypeDefName, fieldPath))
589600
}
601+
return parentFieldTypeDef, fieldAttr
602+
}
590603

591-
addReferenceAttribute(parentFieldTypeDef, fieldAttr)
604+
// setTypeDefAttributeGoTag sets the GoTag for the corresponding attribute
605+
// represented by fieldPath of nested field.
606+
func setTypeDefAttributeGoTag(crd *CRD, fieldPath string, f *Field, tdefs []*TypeDef) {
607+
_, fieldAttr := getAttributeFromPath(crd, fieldPath, tdefs)
608+
if fieldAttr != nil {
609+
fieldAttr.GoTag = f.GetGoTag()
610+
}
611+
}
612+
613+
// updateTypeDefAttributeWithReference adds a new AWSResourceReference attribute
614+
// for the corresponding attribute represented by fieldPath of nested field
615+
func updateTypeDefAttributeWithReference(crd *CRD, fieldPath string, tdefs []*TypeDef) {
616+
parentFieldTypeDef, fieldAttr := getAttributeFromPath(crd, fieldPath, tdefs)
617+
if fieldAttr != nil && parentFieldTypeDef != nil {
618+
addReferenceAttribute(parentFieldTypeDef, fieldAttr)
619+
}
592620
}
593621

594622
// addReferenceAttribute creates a corresponding reference attribute for

templates/apis/type_def.go.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ type {{ .Names.Camel }} struct {
77
{{- if $attr.Shape.Documentation }}
88
{{ $attr.Shape.Documentation }}
99
{{- end }}
10-
{{ $attr.Names.Camel }} {{ $attr.GoType }} `json:"{{ $attr.Names.CamelLower }},omitempty"`
10+
{{ $attr.Names.Camel }} {{ $attr.GoType }} {{ $attr.GetGoTag }}
1111
{{- end }}
1212
}
1313
{{- end -}}

0 commit comments

Comments
 (0)