Skip to content

Commit 2104960

Browse files
committed
Add only_set_unchanged_fields config to UpdateOperationConfig
- Add config field only_set_unchanged_fields to UpdateOperationConfig. - Add CRD.OnlySetChangedFieldsOnUpdate() func to check if only_set_unchanged_fields value - Add logic in SetResource to add delta.DifferentAt() checks when only_set_unchanged_fields is set. - Create unit test to verify new SetResource() behavior
1 parent 82d9fa6 commit 2104960

File tree

5 files changed

+207
-0
lines changed

5 files changed

+207
-0
lines changed

pkg/config/resource.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,12 @@ type UpdateOperationConfig struct {
339339
// will leverage `delta.DifferentAt` to check whether a field have changed or not
340340
// before including it in the update request.
341341
OmitUnchangedFields bool `json:"omit_unchanged_fields"`
342+
// OnlySetChangedField instructs the code generator on how to generate logic for setting
343+
// the value of Spec fields after a successful Update operation in the `sdkUpdate` function.
344+
// If the boolean is true, the code generator uses `delta.DifferentAt` to check if a
345+
// field had changed or not before setting it's value to that returned by the Update AWS API's
346+
// response. Defaults to false.
347+
OnlySetChangedField bool `json:"only_set_unchanged_fields"`
342348
}
343349

344350
// ReadOperationsConfig contains instructions for the code generator to handle

pkg/generate/code/set_resource.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,18 @@ func SetResource(
235235
continue
236236
}
237237

238+
onlySetChangedFieldsOnUpdate := op == r.Ops.Update && r.OnlySetChangedFieldsOnUpdate()
239+
if onlySetChangedFieldsOnUpdate && inSpec {
240+
fieldJSONPath := fmt.Sprintf("%s.%s", cfg.PrefixConfig.SpecField[1:], f.Names.Camel)
241+
out += fmt.Sprintf(
242+
"%sif delta.DifferentAt(%q) {\n", indent, fieldJSONPath,
243+
)
244+
245+
// increase indentation level
246+
indentLevel++
247+
indent = "\t" + indent
248+
}
249+
238250
sourceMemberShapeRef := outputShape.MemberRefs[memberName]
239251
if sourceMemberShapeRef.Shape == nil {
240252
// We may have some instructions to specially handle this field by
@@ -413,6 +425,16 @@ func SetResource(
413425
} else {
414426
indentLevel += 1
415427
}
428+
429+
if onlySetChangedFieldsOnUpdate && inSpec {
430+
// decrease indentation level
431+
indentLevel--
432+
indent = indent[1:]
433+
434+
out += fmt.Sprintf(
435+
"%s}\n", indent,
436+
)
437+
}
416438
}
417439
return out
418440
}

pkg/generate/code/set_resource_test.go

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package code_test
1515

1616
import (
17+
"fmt"
1718
"testing"
1819

1920
"github.com/stretchr/testify/assert"
@@ -5050,3 +5051,150 @@ func TestSetResource_WAFv2_RuleGroup_ReadOne(t *testing.T) {
50505051
code.SetResource(crd.Config(), crd, op, "resp", "ko", 1),
50515052
)
50525053
}
5054+
5055+
func TestSetResource_MQ_OnlySetUnchangedFields_Update(t *testing.T) {
5056+
assert := assert.New(t)
5057+
require := require.New(t)
5058+
5059+
g := testutil.NewModelForServiceWithOptions(t, "mq", &testutil.TestingModelOptions{
5060+
GeneratorConfigFile: "generator-only-set-unchanged-fields.yaml",
5061+
})
5062+
op := model.OpTypeUpdate
5063+
5064+
crd := testutil.GetCRDByName(t, g, "Broker")
5065+
require.NotNil(crd)
5066+
5067+
expected := `
5068+
if delta.DifferentAt("Spec.AuthenticationStrategy") {
5069+
if resp.AuthenticationStrategy != "" {
5070+
ko.Spec.AuthenticationStrategy = aws.String(string(resp.AuthenticationStrategy))
5071+
} else {
5072+
ko.Spec.AuthenticationStrategy = nil
5073+
}
5074+
}
5075+
if delta.DifferentAt("Spec.AutoMinorVersionUpgrade") {
5076+
if resp.AutoMinorVersionUpgrade != nil {
5077+
ko.Spec.AutoMinorVersionUpgrade = resp.AutoMinorVersionUpgrade
5078+
} else {
5079+
ko.Spec.AutoMinorVersionUpgrade = nil
5080+
}
5081+
}
5082+
if resp.BrokerId != nil {
5083+
ko.Status.BrokerID = resp.BrokerId
5084+
} else {
5085+
ko.Status.BrokerID = nil
5086+
}
5087+
if delta.DifferentAt("Spec.Configuration") {
5088+
if resp.Configuration != nil {
5089+
f3 := &svcapitypes.ConfigurationID{}
5090+
if resp.Configuration.Id != nil {
5091+
f3.ID = resp.Configuration.Id
5092+
}
5093+
if resp.Configuration.Revision != nil {
5094+
revisionCopy := int64(*resp.Configuration.Revision)
5095+
f3.Revision = &revisionCopy
5096+
}
5097+
ko.Spec.Configuration = f3
5098+
} else {
5099+
ko.Spec.Configuration = nil
5100+
}
5101+
}
5102+
if delta.DifferentAt("Spec.EngineVersion") {
5103+
if resp.EngineVersion != nil {
5104+
ko.Spec.EngineVersion = resp.EngineVersion
5105+
} else {
5106+
ko.Spec.EngineVersion = nil
5107+
}
5108+
}
5109+
if delta.DifferentAt("Spec.HostInstanceType") {
5110+
if resp.HostInstanceType != nil {
5111+
ko.Spec.HostInstanceType = resp.HostInstanceType
5112+
} else {
5113+
ko.Spec.HostInstanceType = nil
5114+
}
5115+
}
5116+
if delta.DifferentAt("Spec.LDAPServerMetadata") {
5117+
if resp.LdapServerMetadata != nil {
5118+
f8 := &svcapitypes.LDAPServerMetadataInput{}
5119+
if resp.LdapServerMetadata.Hosts != nil {
5120+
f8.Hosts = aws.StringSlice(resp.LdapServerMetadata.Hosts)
5121+
}
5122+
if resp.LdapServerMetadata.RoleBase != nil {
5123+
f8.RoleBase = resp.LdapServerMetadata.RoleBase
5124+
}
5125+
if resp.LdapServerMetadata.RoleName != nil {
5126+
f8.RoleName = resp.LdapServerMetadata.RoleName
5127+
}
5128+
if resp.LdapServerMetadata.RoleSearchMatching != nil {
5129+
f8.RoleSearchMatching = resp.LdapServerMetadata.RoleSearchMatching
5130+
}
5131+
if resp.LdapServerMetadata.RoleSearchSubtree != nil {
5132+
f8.RoleSearchSubtree = resp.LdapServerMetadata.RoleSearchSubtree
5133+
}
5134+
if resp.LdapServerMetadata.ServiceAccountUsername != nil {
5135+
f8.ServiceAccountUsername = resp.LdapServerMetadata.ServiceAccountUsername
5136+
}
5137+
if resp.LdapServerMetadata.UserBase != nil {
5138+
f8.UserBase = resp.LdapServerMetadata.UserBase
5139+
}
5140+
if resp.LdapServerMetadata.UserRoleName != nil {
5141+
f8.UserRoleName = resp.LdapServerMetadata.UserRoleName
5142+
}
5143+
if resp.LdapServerMetadata.UserSearchMatching != nil {
5144+
f8.UserSearchMatching = resp.LdapServerMetadata.UserSearchMatching
5145+
}
5146+
if resp.LdapServerMetadata.UserSearchSubtree != nil {
5147+
f8.UserSearchSubtree = resp.LdapServerMetadata.UserSearchSubtree
5148+
}
5149+
ko.Spec.LDAPServerMetadata = f8
5150+
} else {
5151+
ko.Spec.LDAPServerMetadata = nil
5152+
}
5153+
}
5154+
if delta.DifferentAt("Spec.Logs") {
5155+
if resp.Logs != nil {
5156+
f9 := &svcapitypes.Logs{}
5157+
if resp.Logs.Audit != nil {
5158+
f9.Audit = resp.Logs.Audit
5159+
}
5160+
if resp.Logs.General != nil {
5161+
f9.General = resp.Logs.General
5162+
}
5163+
ko.Spec.Logs = f9
5164+
} else {
5165+
ko.Spec.Logs = nil
5166+
}
5167+
}
5168+
if delta.DifferentAt("Spec.MaintenanceWindowStartTime") {
5169+
if resp.MaintenanceWindowStartTime != nil {
5170+
f10 := &svcapitypes.WeeklyStartTime{}
5171+
if resp.MaintenanceWindowStartTime.DayOfWeek != "" {
5172+
f10.DayOfWeek = aws.String(string(resp.MaintenanceWindowStartTime.DayOfWeek))
5173+
}
5174+
if resp.MaintenanceWindowStartTime.TimeOfDay != nil {
5175+
f10.TimeOfDay = resp.MaintenanceWindowStartTime.TimeOfDay
5176+
}
5177+
if resp.MaintenanceWindowStartTime.TimeZone != nil {
5178+
f10.TimeZone = resp.MaintenanceWindowStartTime.TimeZone
5179+
}
5180+
ko.Spec.MaintenanceWindowStartTime = f10
5181+
} else {
5182+
ko.Spec.MaintenanceWindowStartTime = nil
5183+
}
5184+
}
5185+
if delta.DifferentAt("Spec.SecurityGroups") {
5186+
if resp.SecurityGroups != nil {
5187+
ko.Spec.SecurityGroups = aws.StringSlice(resp.SecurityGroups)
5188+
} else {
5189+
ko.Spec.SecurityGroups = nil
5190+
}
5191+
}
5192+
`
5193+
actual := code.SetResource(crd.Config(), crd, op, "resp", "ko", 1)
5194+
fmt.Print(actual)
5195+
5196+
assert.Equal(
5197+
expected,
5198+
actual,
5199+
)
5200+
}

pkg/model/crd.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,21 @@ func (r *CRD) OmitUnchangedFieldsOnUpdate() bool {
351351
return false
352352
}
353353

354+
// OnlySetChangedFieldsOnUpdate returns whether the controller needs to ensure that
355+
// only values included in the delta are updated based on the Update operation's response.
356+
func (r *CRD) OnlySetChangedFieldsOnUpdate() bool {
357+
if r.Config() == nil {
358+
return false
359+
}
360+
rConfig, found := r.Config().Resources[r.Names.Original]
361+
if found {
362+
if rConfig.UpdateOperation != nil {
363+
return rConfig.UpdateOperation.OnlySetChangedField
364+
}
365+
}
366+
return false
367+
}
368+
354369
// IsARNPrimaryKey returns true if the CRD uses its ARN as its primary key in
355370
// ReadOne calls.
356371
func (r *CRD) IsARNPrimaryKey() bool {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
ignore:
2+
resources:
3+
- Configuration
4+
- User
5+
field_paths:
6+
- CreateBrokerInput.DataReplicationMode
7+
- CreateBrokerInput.DataReplicationPrimaryBrokerArn
8+
- User.ReplicationUser
9+
resources:
10+
Broker:
11+
fields:
12+
Users.Password:
13+
is_secret: true
14+
update_operation:
15+
omit_unchanged_fields: true
16+
only_set_unchanged_fields: true

0 commit comments

Comments
 (0)