Skip to content

Commit 386dc0d

Browse files
authored
allow resource references across service controllers (#288)
Issue #, if available: aws-controllers-k8s/community#1091 Description of changes: * aws-controllers-k8s/community#1092 * Adds a new `ServiceName` parameter in `ReferencesConfig` to indicate when the referenced resource is from another service controller * Based on the `ServiceName` parameter imports the API-types from that service controller * Adds the additional RBAC permissions to allow reading the referenced resource from another service controller Tested by generating and running apigatewayv2-controller which refers the Subnet and SecurityGroup resource from ec2 controller. Please see the [proposal link](aws-controllers-k8s/community#1092) for generated code. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent f8c0f47 commit 386dc0d

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

pkg/generate/config/field.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,18 @@ type LateInitializeConfig struct {
284284
// read the referred 'API' resource and copy the value from 'Status.APIID' in
285285
// 'Integration' resource's 'APIID' field
286286
type ReferencesConfig struct {
287+
// ServiceName mentions the AWS service name where "Resource" exists.
288+
// This field is used to generate the API Group for the "Resource".
289+
//
290+
// ServiceName is the go package name for AWS service in
291+
// aws-sdk-go/service/<package_name>/api.go
292+
// Ex: Use "opensearchservice" to refer "Domain" resource from
293+
// opensearchservice-controller because it is the go package name for
294+
// "aws-sdk-go/service/opensearchservice/api.go"
295+
//
296+
// When not specified, 'ServiceName' defaults to service name of controller
297+
// which contains generator.yaml
298+
ServiceName string `json:"service_name,omitempty"`
287299
// Resource mentions the K8s resource which is read to resolve the
288300
// reference
289301
Resource string `json:"resource"`

pkg/model/field.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,35 @@ func (f *Field) GetReferenceFieldName() names.Names {
149149
return names.New(refName)
150150
}
151151

152+
// ReferencedServiceName returns the serviceName for the referenced resource
153+
// when the field has 'ReferencesConfig'
154+
// If the field does not have 'ReferencesConfig', empty string is returned
155+
func (f *Field) ReferencedServiceName() (referencedServiceName string) {
156+
if f.FieldConfig != nil && f.FieldConfig.References != nil {
157+
if f.FieldConfig.References.ServiceName != "" {
158+
return f.FieldConfig.References.ServiceName
159+
} else {
160+
return f.CRD.sdkAPI.API.PackageName()
161+
}
162+
}
163+
return referencedServiceName
164+
}
165+
166+
// ReferencedResourceNamePlural returns the plural of referenced resource
167+
// when the field has a 'ReferencesConfig'
168+
// If the field does not have 'ReferencesConfig', empty string is returned
169+
func (f *Field) ReferencedResourceNamePlural() string {
170+
var referencedResourceName string
171+
pluralize := pluralize.NewClient()
172+
if f.FieldConfig != nil && f.FieldConfig.References != nil {
173+
referencedResourceName = f.FieldConfig.References.Resource
174+
}
175+
if referencedResourceName != "" {
176+
return pluralize.Plural(referencedResourceName)
177+
}
178+
return referencedResourceName
179+
}
180+
152181
// NewReferenceField returns a pointer to a new Field object.
153182
// The go-type of field is either slice of '*AWSResourceReferenceWrapper' or
154183
// '*AWSResourceReferenceWrapper' depending on whether 'shapeRef' parameter

templates/pkg/resource/references.go.tpl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,29 @@ import (
1818
ackerr "github.com/aws-controllers-k8s/runtime/pkg/errors"
1919
{{ end -}}
2020
acktypes "github.com/aws-controllers-k8s/runtime/pkg/types"
21+
{{ $servicePackageName := .ServicePackageName -}}
22+
{{ $apiVersion := .APIVersion -}}
23+
{{ if .CRD.HasReferenceFields -}}
24+
{{ range $fieldName, $field := .CRD.Fields -}}
25+
{{ if and $field.HasReference (not (eq $field.ReferencedServiceName $servicePackageName)) -}}
26+
{{ $field.ReferencedServiceName }}apitypes "github.com/aws-controllers-k8s/{{ $field.ReferencedServiceName }}-controller/apis/{{ $apiVersion }}"
27+
{{ end -}}
28+
{{ end -}}
29+
{{ end -}}
2130

2231
svcapitypes "github.com/aws-controllers-k8s/{{ .ServicePackageName }}-controller/apis/{{ .APIVersion }}"
2332
)
2433

34+
{{ if .CRD.HasReferenceFields -}}
35+
{{ range $fieldName, $field := .CRD.Fields -}}
36+
{{ if and $field.HasReference (not (eq $field.ReferencedServiceName $servicePackageName)) -}}
37+
// +kubebuilder:rbac:groups={{ $field.ReferencedServiceName -}}.services.k8s.aws,resources={{ ToLower $field.ReferencedResourceNamePlural }},verbs=get;list
38+
// +kubebuilder:rbac:groups={{ $field.ReferencedServiceName -}}.services.k8s.aws,resources={{ ToLower $field.ReferencedResourceNamePlural }}/status,verbs=get;list
39+
40+
{{ end -}}
41+
{{ end -}}
42+
{{ end -}}
43+
2544
// ResolveReferences finds if there are any Reference field(s) present
2645
// inside AWSResource passed in the parameter and attempts to resolve
2746
// those reference field(s) into target field(s).

templates/pkg/resource/references_read_referenced_resource.go.tpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ Where field is of type 'Field' from aws-controllers-k8s/code-generator/pkg/model
1212
Namespace: namespace,
1313
Name: *arr.Name,
1414
}
15+
{{ if eq .FieldConfig.References.ServiceName "" -}}
1516
obj := svcapitypes.{{ .FieldConfig.References.Resource }}{}
17+
{{ else -}}
18+
obj := {{ .ReferencedServiceName }}apitypes.{{ .FieldConfig.References.Resource }}{}
19+
{{ end -}}
1620
err := apiReader.Get(ctx, namespacedName, &obj)
1721
if err != nil {
1822
return err

0 commit comments

Comments
 (0)