Skip to content

Commit a4bd77b

Browse files
authored
Add new $field.set[].To configuration (#441)
Issue aws-controllers-k8s/community#1775 - Add new generator config to allow setting an `sdkField` from a specific CR field By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 9e2542c commit a4bd77b

File tree

6 files changed

+100
-1
lines changed

6 files changed

+100
-1
lines changed

pkg/config/field.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,19 @@ type SetFieldConfig struct {
191191
// f17elem = *f17iter.DBSecurityGroupName
192192
// ```
193193
From *string `json:"from,omitempty"`
194+
// To instructs the code generator to output Go code that sets the value of
195+
// an Input sdkField with the content of a CR field.
196+
//
197+
// ```yaml
198+
// resources:
199+
// User:
200+
// fields:
201+
// URL:
202+
// set:
203+
// - method: Update
204+
// to: NewURL
205+
// ```
206+
To *string `json:"to,omitempty"`
194207
// Ignore instructs the code generator to ignore this field in the Output
195208
// shape when setting the value of the resource's field in the Spec. This
196209
// is useful when we know that, for example, the returned value of field in

pkg/generate/code/set_resource.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
"github.com/aws-controllers-k8s/code-generator/pkg/util"
2828
)
2929

30-
// SetResource returns the Go code that sets a CRD's field value to the value
30+
// SetResource returns the Go code that sets a CRD's field value from the value
3131
// of an output shape's member fields. Status fields are always updated.
3232
//
3333
// Assume a CRD called Repository that looks like this pseudo-schema:

pkg/generate/code/set_sdk.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,15 @@ func SetSDK(
222222
op.ExportedName,
223223
memberName,
224224
)
225+
226+
// Check if we have any configurations instructing the code
227+
// generator to set an SDK input field from this specific
228+
// field path.
229+
fallbackFieldName := r.GetMatchingInputShapeFieldName(opType, fieldName)
230+
if fallbackFieldName != "" {
231+
fieldName = fallbackFieldName
232+
}
233+
225234
inSpec, inStatus := r.HasMember(fieldName, op.ExportedName)
226235
if inSpec {
227236
sourceAdaptedVarName += cfg.PrefixConfig.SpecField

pkg/generate/code/set_sdk_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,3 +2164,27 @@ func Test_SetSDK_ECR_Repository_newListRequestPayload(t *testing.T) {
21642164
code.SetSDK(crd.Config(), crd, model.OpTypeList, "r.ko", "res", 1),
21652165
)
21662166
}
2167+
2168+
func TestSetSDK_IAM_User_NewPath(t *testing.T) {
2169+
assert := assert.New(t)
2170+
require := require.New(t)
2171+
2172+
g := testutil.NewModelForServiceWithOptions(t, "iam", &testutil.TestingModelOptions{
2173+
GeneratorConfigFile: "generator-user-newpath.yaml",
2174+
})
2175+
2176+
crd := testutil.GetCRDByName(t, g, "User")
2177+
require.NotNil(crd)
2178+
expected := `
2179+
if r.ko.Spec.Path != nil {
2180+
res.SetNewPath(*r.ko.Spec.Path)
2181+
}
2182+
if r.ko.Spec.UserName != nil {
2183+
res.SetUserName(*r.ko.Spec.UserName)
2184+
}
2185+
`
2186+
assert.Equal(
2187+
expected,
2188+
code.SetSDK(crd.Config(), crd, model.OpTypeUpdate, "r.ko", "res", 1),
2189+
)
2190+
}

pkg/model/crd.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,36 @@ func (r *CRD) GetPrimaryKeyField() (*Field, error) {
415415
return primaryField, nil
416416
}
417417

418+
// GetMatchingInputShapeFieldName returns the name of the field in the Input shape.
419+
// For simplicity, we assume that there will be only one setConfig for the
420+
// any unique sdkField, per operation. Which means that we will never set
421+
// two different sdk field from the same
422+
func (r *CRD) GetMatchingInputShapeFieldName(opType OpType, sdkField string) string {
423+
// At this stage nil-checks for r.cfg is not necessary
424+
for _, f := range r.Fields {
425+
if f.FieldConfig == nil {
426+
continue
427+
}
428+
rmMethod := ResourceManagerMethodFromOpType(opType)
429+
for _, setCfg := range f.FieldConfig.Set {
430+
if setCfg == nil {
431+
continue
432+
}
433+
if setCfg.Ignore == true || setCfg.To == nil {
434+
continue
435+
}
436+
// If the Method attribute is nil, that means the setter config applies to
437+
// all resource manager methods for this field.
438+
if setCfg.Method == nil || strings.EqualFold(rmMethod, *setCfg.Method) {
439+
if setCfg.To != nil && *setCfg.To == sdkField {
440+
return f.Names.Camel
441+
}
442+
}
443+
}
444+
}
445+
return ""
446+
}
447+
418448
// SetOutputCustomMethodName returns custom set output operation as *string for
419449
// given operation on custom resource
420450
func (r *CRD) SetOutputCustomMethodName(
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
ignore:
2+
resource_names:
3+
- AccessKey
4+
- AccountAlias
5+
- Group
6+
- InstanceProfile
7+
- LoginProfile
8+
- OpenIDConnectProvider
9+
- Policy
10+
- PolicyVersion
11+
- Role
12+
- SAMLProvider
13+
- ServiceLinkedRole
14+
- ServiceSpecificCredential
15+
# User
16+
- VirtualMFADevice
17+
resources:
18+
User:
19+
fields:
20+
Path:
21+
set:
22+
- method: Update
23+
to: NewPath

0 commit comments

Comments
 (0)