Skip to content

Commit d0f3d78

Browse files
authored
Merge pull request #414 from A-Hilaly/revert-references
Revert resource reference resolution
2 parents 675b95b + 51b3583 commit d0f3d78

File tree

6 files changed

+112
-326
lines changed

6 files changed

+112
-326
lines changed

pkg/generate/ack/controller.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,6 @@ var (
183183
return code.InitializeNestedStructField(r, sourceVarName, f,
184184
apiPkgImportName, indentLevel)
185185
},
186-
"GoCodeResolveReference": func(f *ackmodel.Field, sourceVarName string, indentLevel int) string {
187-
return code.ResolveReferencesForField(f, sourceVarName, indentLevel)
188-
},
189186
}
190187
)
191188

pkg/generate/code/resource_reference.go

Lines changed: 2 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func ReferenceFieldsValidation(
9898
out += fmt.Sprintf("%sif %s.%s != nil"+
9999
" && %s.%s != nil {\n", fIndent, pathVarPrefix, field.GetReferenceFieldName().Camel, pathVarPrefix, field.Names.Camel)
100100
out += fmt.Sprintf("%s\treturn "+
101-
"ackerr.ResourceReferenceAndIDNotSupportedFor(%q, %q)\n",
101+
"ackerr.ResourceReferenceAndIDNotSupportedFor(\"%s\", \"%s\")\n",
102102
fIndent, field.Path, field.ReferenceFieldPath())
103103

104104
// Close out all the curly braces with proper indentation
@@ -117,7 +117,7 @@ func ReferenceFieldsValidation(
117117
" %s.%s == nil {\n", fIndent, pathVarPrefix,
118118
field.ReferenceFieldPath(), pathVarPrefix, field.Path)
119119
out += fmt.Sprintf("%s\treturn "+
120-
"ackerr.ResourceReferenceOrIDRequiredFor(%q, %q)\n",
120+
"ackerr.ResourceReferenceOrIDRequiredFor(\"%s\", \"%s\")\n",
121121
fIndent, field.Path, field.ReferenceFieldPath())
122122
out += fmt.Sprintf("%s}\n", fIndent)
123123
}
@@ -185,111 +185,6 @@ func ReferenceFieldsPresent(
185185
return iteratorsOut + returnOut
186186
}
187187

188-
// ResolveReferencesForField produces Go code for accessing all references that
189-
// are related to the given concrete field, determining whether its in a valid
190-
// condition and updating the concrete field with the referenced value.
191-
// Sample code (resolving a nested singular reference):
192-
//
193-
// ```
194-
//
195-
// if ko.Spec.JWTConfiguration != nil {
196-
// if ko.Spec.JWTConfiguration.IssuerRef != nil && ko.Spec.JWTConfiguration.IssuerRef.From != nil {
197-
// arr := ko.Spec.JWTConfiguration.IssuerRef.From
198-
// if arr == nil || arr.Name == nil || *arr.Name == "" {
199-
// return fmt.Errorf("provided resource reference is nil or empty: \"JWTConfiguration.IssuerRef"\")
200-
// }
201-
// obj := &svcapitypes.API{}
202-
// if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil {
203-
// return err
204-
// }
205-
// ko.Spec.JWTConfiguration.Issuer = obj.Status.APIID
206-
// }
207-
// }
208-
//
209-
// ```
210-
func ResolveReferencesForField(field *model.Field, sourceVarName string, indentLevel int) string {
211-
r := field.CRD
212-
fp := fieldpath.FromString(field.Path)
213-
214-
outPrefix := ""
215-
outSuffix := ""
216-
217-
fieldAccessPrefix := fmt.Sprintf("%s%s", sourceVarName, r.Config().PrefixConfig.SpecField)
218-
targetVarName := fmt.Sprintf("%s.%s", fieldAccessPrefix, field.Path)
219-
220-
for idx := 0; idx < fp.Size(); idx++ {
221-
curFP := fp.CopyAt(idx).String()
222-
cur, ok := r.Fields[curFP]
223-
if !ok {
224-
panic(fmt.Sprintf("unable to find field with path %q. crd: %q", curFP, r.Kind))
225-
}
226-
227-
ref := cur.ShapeRef
228-
229-
indent := strings.Repeat("\t", indentLevel+idx)
230-
231-
switch ref.Shape.Type {
232-
case ("structure"):
233-
fieldAccessPrefix = fmt.Sprintf("%s.%s", fieldAccessPrefix, fp.At(idx))
234-
235-
outPrefix += fmt.Sprintf("%sif %s != nil {\n", indent, fieldAccessPrefix)
236-
outSuffix = fmt.Sprintf("%s}\n%s", indent, outSuffix)
237-
case ("list"):
238-
if (fp.Size() - idx) > 1 {
239-
// TODO(nithomso): add support for structs nested within lists
240-
// The logic for structs nested within lists needs to not only
241-
// be added here, but also in a custom patching solution since
242-
// it isn't supported by `StrategicMergePatch`
243-
// see https://github.com/aws-controllers-k8s/community/issues/1291
244-
panic(fmt.Errorf("references within lists inside lists aren't supported. crd: %q, path: %q", r.Kind, field.Path))
245-
}
246-
fieldAccessPrefix = fmt.Sprintf("%s.%s", fieldAccessPrefix, fp.At(idx))
247-
248-
iterVarName := fmt.Sprintf("iter%d", idx)
249-
250-
// base case for references in a list
251-
outPrefix += fmt.Sprintf("%s%s = %s{}\n", indent, targetVarName, field.GoType)
252-
outPrefix += fmt.Sprintf("%sfor _, %s := range %s {\n", indent, iterVarName, fieldAccessPrefix)
253-
254-
fieldAccessPrefix = iterVarName
255-
outPrefix += fmt.Sprintf("%s\tarr := %s.From\n", indent, fieldAccessPrefix)
256-
outPrefix += fmt.Sprintf("%s\tif arr == nil || arr.Name == nil || *arr.Name == \"\" {\n", indent)
257-
outPrefix += fmt.Sprintf("%s\t\treturn fmt.Errorf(\"provided resource reference is nil or empty: \\%q\\\")\n", indent, field.ReferenceFieldPath())
258-
outPrefix += fmt.Sprintf("%s\t}\n", indent)
259-
260-
outPrefix += fmt.Sprintf("%s\tif err := getReferencedResourceState_%s(ctx, apiReader, obj, *arr.Name, namespace); err != nil {\n", indent, field.FieldConfig.References.Resource)
261-
outPrefix += fmt.Sprintf("%s\t\treturn err\n", indent)
262-
outPrefix += fmt.Sprintf("%s\t}\n", indent)
263-
outPrefix += fmt.Sprintf("%s\t%s = append(%s, obj.%s)\n", indent, targetVarName, targetVarName, field.FieldConfig.References.Path)
264-
outPrefix += fmt.Sprintf("%s}\n", indent)
265-
case ("map"):
266-
panic("references cannot be within a map")
267-
default:
268-
// base case for single references
269-
fieldAccessPrefix = fmt.Sprintf("%s.%s", fieldAccessPrefix, cur.GetReferenceFieldName().Camel)
270-
271-
outPrefix += fmt.Sprintf("%sif %s != nil && %s.From != nil {\n", indent, fieldAccessPrefix, fieldAccessPrefix)
272-
outPrefix += fmt.Sprintf("%s\tarr := %s.From\n", indent, fieldAccessPrefix)
273-
outPrefix += fmt.Sprintf("%s\tif arr == nil || arr.Name == nil || *arr.Name == \"\" {\n", indent)
274-
outPrefix += fmt.Sprintf("%s\t\treturn fmt.Errorf(\"provided resource reference is nil or empty: \\%q\\\")\n", indent, field.ReferenceFieldPath())
275-
outPrefix += fmt.Sprintf("%s\t}\n", indent)
276-
277-
if field.FieldConfig.References.ServiceName == "" {
278-
outPrefix += fmt.Sprintf("%s\tobj := &svcapitypes.%s{}\n", indent, field.FieldConfig.References.Resource)
279-
} else {
280-
outPrefix += fmt.Sprintf("%s\tobj := &%sapitypes.%s{}\n", indent, field.ReferencedServiceName(), field.FieldConfig.References.Resource)
281-
}
282-
outPrefix += fmt.Sprintf("%s\tif err := getReferencedResourceState_%s(ctx, apiReader, obj, *arr.Name, namespace); err != nil {\n", indent, field.FieldConfig.References.Resource)
283-
outPrefix += fmt.Sprintf("%s\t\treturn err\n", indent)
284-
outPrefix += fmt.Sprintf("%s\t}\n", indent)
285-
outPrefix += fmt.Sprintf("%s\t%s = obj.%s\n", indent, targetVarName, field.FieldConfig.References.Path)
286-
outPrefix += fmt.Sprintf("%s}\n", indent)
287-
}
288-
}
289-
290-
return outPrefix + outSuffix
291-
}
292-
293188
func nestedStructNilCheck(path fieldpath.Path, fieldAccessPrefix string) string {
294189
out := ""
295190
fieldNamePrefix := ""

pkg/generate/code/resource_reference_test.go

Lines changed: 0 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -198,127 +198,3 @@ if ko.Spec.Routes != nil {
198198
return false || (ko.Spec.VPCRef != nil)`
199199
assert.Equal(expected, code.ReferenceFieldsPresent(crd, "ko"))
200200
}
201-
202-
func Test_ResolveReferencesForField_SingleReference(t *testing.T) {
203-
assert := assert.New(t)
204-
require := require.New(t)
205-
206-
g := testutil.NewModelForServiceWithOptions(t, "apigatewayv2",
207-
&testutil.TestingModelOptions{
208-
GeneratorConfigFile: "generator-with-reference.yaml",
209-
})
210-
211-
crd := testutil.GetCRDByName(t, g, "Integration")
212-
require.NotNil(crd)
213-
expected :=
214-
` if ko.Spec.APIRef != nil && ko.Spec.APIRef.From != nil {
215-
arr := ko.Spec.APIRef.From
216-
if arr == nil || arr.Name == nil || *arr.Name == "" {
217-
return fmt.Errorf("provided resource reference is nil or empty: \"APIRef"\")
218-
}
219-
obj := &svcapitypes.API{}
220-
if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil {
221-
return err
222-
}
223-
ko.Spec.APIID = obj.Status.APIID
224-
}
225-
`
226-
227-
field := crd.Fields["APIID"]
228-
assert.Equal(expected, code.ResolveReferencesForField(field, "ko", 1))
229-
}
230-
231-
func Test_ResolveReferencesForField_SliceOfReferences(t *testing.T) {
232-
assert := assert.New(t)
233-
require := require.New(t)
234-
235-
g := testutil.NewModelForServiceWithOptions(t, "apigatewayv2",
236-
&testutil.TestingModelOptions{
237-
GeneratorConfigFile: "generator-with-reference.yaml",
238-
})
239-
240-
crd := testutil.GetCRDByName(t, g, "VpcLink")
241-
require.NotNil(crd)
242-
expected :=
243-
` ko.Spec.SecurityGroupIDs = []*string{}
244-
for _, iter0 := range ko.Spec.SecurityGroupIDs {
245-
arr := iter0.From
246-
if arr == nil || arr.Name == nil || *arr.Name == "" {
247-
return fmt.Errorf("provided resource reference is nil or empty: \"SecurityGroupRefs"\")
248-
}
249-
if err := getReferencedResourceState_SecurityGroup(ctx, apiReader, obj, *arr.Name, namespace); err != nil {
250-
return err
251-
}
252-
ko.Spec.SecurityGroupIDs = append(ko.Spec.SecurityGroupIDs, obj.Status.ID)
253-
}
254-
`
255-
256-
field := crd.Fields["SecurityGroupIDs"]
257-
assert.Equal(expected, code.ResolveReferencesForField(field, "ko", 1))
258-
}
259-
260-
func Test_ResolveReferencesForField_NestedSingleReference(t *testing.T) {
261-
assert := assert.New(t)
262-
require := require.New(t)
263-
264-
g := testutil.NewModelForServiceWithOptions(t, "apigatewayv2",
265-
&testutil.TestingModelOptions{
266-
GeneratorConfigFile: "generator-with-nested-reference.yaml",
267-
})
268-
269-
crd := testutil.GetCRDByName(t, g, "Authorizer")
270-
require.NotNil(crd)
271-
expected :=
272-
` if ko.Spec.JWTConfiguration != nil {
273-
if ko.Spec.JWTConfiguration.IssuerRef != nil && ko.Spec.JWTConfiguration.IssuerRef.From != nil {
274-
arr := ko.Spec.JWTConfiguration.IssuerRef.From
275-
if arr == nil || arr.Name == nil || *arr.Name == "" {
276-
return fmt.Errorf("provided resource reference is nil or empty: \"JWTConfiguration.IssuerRef"\")
277-
}
278-
obj := &svcapitypes.API{}
279-
if err := getReferencedResourceState_API(ctx, apiReader, obj, *arr.Name, namespace); err != nil {
280-
return err
281-
}
282-
ko.Spec.JWTConfiguration.Issuer = obj.Status.APIID
283-
}
284-
}
285-
`
286-
287-
field := crd.Fields["JWTConfiguration.Issuer"]
288-
assert.Equal(expected, code.ResolveReferencesForField(field, "ko", 1))
289-
}
290-
291-
func Test_ResolveReferencesForField_SingleReference_DeeplyNested(t *testing.T) {
292-
assert := assert.New(t)
293-
require := require.New(t)
294-
295-
g := testutil.NewModelForServiceWithOptions(t, "s3",
296-
&testutil.TestingModelOptions{
297-
GeneratorConfigFile: "generator-with-nested-references.yaml",
298-
})
299-
300-
crd := testutil.GetCRDByName(t, g, "Bucket")
301-
require.NotNil(crd)
302-
303-
// the Go template has the appropriate nil checks to ensure the parent path exists
304-
expected :=
305-
` if ko.Spec.Logging != nil {
306-
if ko.Spec.Logging.LoggingEnabled != nil {
307-
if ko.Spec.Logging.LoggingEnabled.TargetBucketRef != nil && ko.Spec.Logging.LoggingEnabled.TargetBucketRef.From != nil {
308-
arr := ko.Spec.Logging.LoggingEnabled.TargetBucketRef.From
309-
if arr == nil || arr.Name == nil || *arr.Name == "" {
310-
return fmt.Errorf("provided resource reference is nil or empty: \"Logging.LoggingEnabled.TargetBucketRef"\")
311-
}
312-
obj := &svcapitypes.Bucket{}
313-
if err := getReferencedResourceState_Bucket(ctx, apiReader, obj, *arr.Name, namespace); err != nil {
314-
return err
315-
}
316-
ko.Spec.Logging.LoggingEnabled.TargetBucket = obj.Spec.Name
317-
}
318-
}
319-
}
320-
`
321-
322-
field := crd.Fields["Logging.LoggingEnabled.TargetBucket"]
323-
assert.Equal(expected, code.ResolveReferencesForField(field, "ko", 1))
324-
}

pkg/testdata/models/apis/s3/0000-00-00/generator-with-nested-references.yaml

Lines changed: 0 additions & 34 deletions
This file was deleted.

templates/pkg/resource/references.go.tpl

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,72 @@ func resolveReferenceFor{{ $field.FieldPathWithUnderscore }}(
115115
}
116116
{{ end -}}
117117

118-
{{ GoCodeResolveReference $field "ko" 1 }}
118+
{{- $fp := ConstructFieldPath $field.Path -}}
119+
{{ $_ := $fp.Pop -}}
120+
{{ $isNested := gt $fp.Size 0 -}}
121+
{{ $isList := eq $field.ShapeRef.Shape.Type "list" -}}
122+
{{ if and (not $isList) (not $isNested) -}}
123+
if ko.Spec.{{ $field.ReferenceFieldPath }} != nil &&
124+
ko.Spec.{{ $field.ReferenceFieldPath }}.From != nil {
125+
arr := ko.Spec.{{ $field.ReferenceFieldPath }}.From
126+
{{ template "read_referenced_resource_and_validate" $field }}
127+
referencedValue := string(*obj.{{ $field.FieldConfig.References.Path }})
128+
ko.Spec.{{ $field.Path }} = &referencedValue
129+
}
119130
return nil
120131
}
121-
132+
{{ else if not $isNested -}}
133+
if ko.Spec.{{ $field.ReferenceFieldPath }} != nil &&
134+
len(ko.Spec.{{ $field.ReferenceFieldPath }}) > 0 {
135+
resolvedReferences := []*string{}
136+
for _, arrw := range ko.Spec.{{ $field.ReferenceFieldPath }} {
137+
arr := arrw.From
122138
{{ template "read_referenced_resource_and_validate" $field }}
139+
referencedValue := string(*obj.{{ $field.FieldConfig.References.Path }})
140+
resolvedReferences = append(resolvedReferences, &referencedValue)
141+
}
142+
ko.Spec.{{ $field.Path }} = resolvedReferences
143+
}
144+
return nil
145+
}
146+
{{ else }}
147+
{{ $parentField := index .CRD.Fields $fp.String }}
148+
{{ if eq $parentField.ShapeRef.Shape.Type "list" -}}
149+
if len(ko.Spec.{{ $parentField.Path }}) > 0 {
150+
for _, elem := range ko.Spec.{{ $parentField.Path }} {
151+
arrw := elem.{{ $field.GetReferenceFieldName.Camel }}
152+
153+
if arrw == nil || arrw.From == nil {
154+
continue
155+
}
156+
157+
arr := arrw.From
158+
if arr.Name == nil || *arr.Name == "" {
159+
return fmt.Errorf("provided resource reference is nil or empty")
160+
}
123161

162+
{{ template "read_referenced_resource_and_validate" $field }}
163+
referencedValue := string(*obj.{{ $field.FieldConfig.References.Path }})
164+
elem.{{ $field.Names.Camel }} = &referencedValue
165+
}
166+
}
167+
return nil
168+
}
169+
{{ else -}}
170+
if ko.Spec.{{ $field.ReferenceFieldPath }} != nil &&
171+
len(ko.Spec.{{ $field.ReferenceFieldPath }}) > 0 {
172+
resolvedReferences := []*string{}
173+
for _, arrw := range ko.Spec.{{ $field.ReferenceFieldPath }} {
174+
arr := arrw.From
175+
{{ template "read_referenced_resource_and_validate" $field }}
176+
referencedValue := string(*obj.{{ $field.FieldConfig.References.Path }})
177+
resolvedReferences = append(resolvedReferences, &referencedValue)
178+
}
179+
ko.Spec.{{ $field.Path }} = resolvedReferences
180+
}
181+
return nil
182+
}
183+
{{ end -}}
184+
{{ end -}}
124185
{{ end -}}
125186
{{ end -}}
126-

0 commit comments

Comments
 (0)