Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions pkg/generate/code/resource_reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ func ReferenceFieldsValidation(
indentLevel int,
) string {
out := ""
for _, field := range crd.Fields {
// Sorted fieldnames are used for consistent code-generation
for _, fieldName := range crd.SortedFieldNames() {
Comment on lines +38 to +39
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏼

field := crd.Fields[fieldName]
if field.HasReference() {
indent := strings.Repeat("\t", indentLevel)
// Validation to make sure both target field and reference are
Expand Down Expand Up @@ -75,7 +77,9 @@ func ReferenceFieldsPresent(
sourceVarName string,
) string {
out := "false"
for _, field := range crd.Fields {
// Sorted fieldnames are used for consistent code-generation
for _, fieldName := range crd.SortedFieldNames() {
field := crd.Fields[fieldName]
if field.IsReference() {
out += fmt.Sprintf(" || %s.Spec.%s != nil", sourceVarName,
field.Names.Camel)
Expand Down
8 changes: 7 additions & 1 deletion pkg/generate/code/resource_reference_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ func Test_ReferenceFieldsValidation_SliceOfReferences(t *testing.T) {
` if ko.Spec.SecurityGroupRefs != nil && ko.Spec.SecurityGroupIDs != nil {
return ackerr.ResourceReferenceAndIDNotSupportedFor("SecurityGroupIDs", "SecurityGroupRefs")
}
if ko.Spec.SubnetRefs != nil && ko.Spec.SubnetIDs != nil {
return ackerr.ResourceReferenceAndIDNotSupportedFor("SubnetIDs", "SubnetRefs")
}
if ko.Spec.SubnetRefs == nil && ko.Spec.SubnetIDs == nil {
return ackerr.ResourceReferenceOrIDRequiredFor("SubnetIDs", "SubnetRefs")
}
`
assert.Equal(expected, code.ReferenceFieldsValidation(crd, "ko", 1))
}
Expand Down Expand Up @@ -123,6 +129,6 @@ func Test_ReferenceFieldsPresent_SliceOfReferences(t *testing.T) {
// just to test code generation for slices of reference
crd := testutil.GetCRDByName(t, g, "VpcLink")
require.NotNil(crd)
expected := "false || ko.Spec.SecurityGroupRefs != nil"
expected := "false || ko.Spec.SecurityGroupRefs != nil || ko.Spec.SubnetRefs != nil"
assert.Equal(expected, code.ReferenceFieldsPresent(crd, "ko"))
}
33 changes: 33 additions & 0 deletions pkg/model/crd.go
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,39 @@ func (r *CRD) HasReferenceFields() bool {
return false
}

// ReferencedServiceNames returns the set of service names for ACK controllers
// whose resources are referenced inside the CRD. The service name is
// the go package name for the AWS service inside aws-sdk-go.
//
// If a CRD has no reference fields, nil is returned(zero vale of slice)
func (r *CRD) ReferencedServiceNames() (serviceNames []string) {
// We are using Map to implement a Set of service names
serviceNamesMap := make(map[string]struct{})
existsValue := struct{}{}

for _, field := range r.Fields {
if serviceName := field.ReferencedServiceName(); serviceName != "" {
serviceNamesMap[serviceName] = existsValue
}
}

for serviceName, _ := range serviceNamesMap {
serviceNames = append(serviceNames, serviceName)
}
return serviceNames
}

// SortedFieldNames returns the fieldNames of the CRD in a sorted
// order.
func (r *CRD) SortedFieldNames() []string {
fieldNames := make([]string, 0, len(r.Fields))
for fieldName := range r.Fields {
fieldNames = append(fieldNames, fieldName)
}
sort.Strings(fieldNames)
return fieldNames
}

// NewCRD returns a pointer to a new `ackmodel.CRD` struct that describes a
// single top-level resource in an AWS service API
func NewCRD(
Expand Down
51 changes: 33 additions & 18 deletions pkg/model/model_apigwv2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ func TestAPIGatewayV2_Api(t *testing.T) {
// The required property should get overriden for Name and ProtocolType fields.
assert.False(crd.SpecFields["Name"].IsRequired())
assert.False(crd.SpecFields["ProtocolType"].IsRequired())

assert.Nil(crd.ReferencedServiceNames())
}

func TestAPIGatewayV2_Route(t *testing.T) {
Expand Down Expand Up @@ -174,6 +176,8 @@ func TestAPIGatewayV2_Route(t *testing.T) {
"RouteID",
}
assert.Equal(expStatusFieldCamel, attrCamelNames(statusFields))

assert.Nil(crd.ReferencedServiceNames())
}

func TestAPIGatewayV2_WithReference(t *testing.T) {
Expand All @@ -188,26 +192,37 @@ func TestAPIGatewayV2_WithReference(t *testing.T) {
require.Nil(err)

// Single reference
crd := getCRDByName("Integration", crds)
require.NotNil(crd)
integrationCrd := getCRDByName("Integration", crds)
require.NotNil(integrationCrd)

assert.Equal("Integration", crd.Names.Camel)
assert.Equal("integration", crd.Names.CamelLower)
assert.Equal("integration", crd.Names.Snake)
assert.Equal("Integration", integrationCrd.Names.Camel)
assert.Equal("integration", integrationCrd.Names.CamelLower)
assert.Equal("integration", integrationCrd.Names.Snake)

assert.NotNil(crd.SpecFields["ApiId"])
assert.NotNil(crd.SpecFields["ApiRef"])
assert.Equal("*ackv1alpha1.AWSResourceReferenceWrapper", crd.SpecFields["ApiRef"].GoType)
assert.NotNil(integrationCrd.SpecFields["ApiId"])
assert.NotNil(integrationCrd.SpecFields["ApiRef"])
assert.Equal("*ackv1alpha1.AWSResourceReferenceWrapper", integrationCrd.SpecFields["ApiRef"].GoType)

// List of References
crd = getCRDByName("VpcLink", crds)
require.NotNil(crd)

assert.Equal("VPCLink", crd.Names.Camel)
assert.Equal("vpcLink", crd.Names.CamelLower)
assert.Equal("vpc_link", crd.Names.Snake)
referencedServiceNames := integrationCrd.ReferencedServiceNames()
assert.NotNil(referencedServiceNames)
assert.Contains(referencedServiceNames, "apigatewayv2")
assert.Equal(1, len(referencedServiceNames))

assert.NotNil(crd.SpecFields["SecurityGroupIds"])
assert.NotNil(crd.SpecFields["SecurityGroupRefs"])
assert.Equal("[]*ackv1alpha1.AWSResourceReferenceWrapper", crd.SpecFields["SecurityGroupRefs"].GoType)
// List of References
vpcLinkCrd := getCRDByName("VpcLink", crds)
require.NotNil(vpcLinkCrd)

assert.Equal("VPCLink", vpcLinkCrd.Names.Camel)
assert.Equal("vpcLink", vpcLinkCrd.Names.CamelLower)
assert.Equal("vpc_link", vpcLinkCrd.Names.Snake)

assert.NotNil(vpcLinkCrd.SpecFields["SecurityGroupIds"])
assert.NotNil(vpcLinkCrd.SpecFields["SecurityGroupRefs"])
assert.Equal("[]*ackv1alpha1.AWSResourceReferenceWrapper", vpcLinkCrd.SpecFields["SecurityGroupRefs"].GoType)

referencedServiceNames = vpcLinkCrd.ReferencedServiceNames()
assert.NotNil(referencedServiceNames)
assert.Contains(referencedServiceNames, "ec2")
assert.Contains(referencedServiceNames, "ec2-modified")
assert.Equal(2, len(referencedServiceNames))
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ resources:
fields:
SecurityGroupIds:
references:
resource: API
path: Status.APIID
resource: SecurityGroup
path: Status.ID
service_name: ec2
SubnetIds:
references:
resource: Subnet
path: Status.SubnetID
service_name: ec2-modified #This is a dummy service name to validate multiple service references
ignore:
resource_names:
- ApiMapping
Expand Down
6 changes: 3 additions & 3 deletions templates/pkg/resource/references.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import (
{{ $servicePackageName := .ServicePackageName -}}
{{ $apiVersion := .APIVersion -}}
{{ if .CRD.HasReferenceFields -}}
{{ range $fieldName, $field := .CRD.Fields -}}
{{ if and $field.HasReference (not (eq $field.ReferencedServiceName $servicePackageName)) -}}
{{ $field.ReferencedServiceName }}apitypes "github.com/aws-controllers-k8s/{{ $field.ReferencedServiceName }}-controller/apis/{{ $apiVersion }}"
{{ range $referencedServiceName := .CRD.ReferencedServiceNames -}}
{{ if not (eq $referencedServiceName $servicePackageName) -}}
{{ $referencedServiceName }}apitypes "github.com/aws-controllers-k8s/{{ $referencedServiceName }}-controller/apis/{{ $apiVersion }}"
{{- end }}
{{- end }}
{{- end }}
Expand Down