1414package acl
1515
1616import (
17+ "context"
1718 "github.com/pkg/errors"
1819
1920 "github.com/aws-controllers-k8s/runtime/pkg/requeue"
21+ ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log"
22+ ackutil "github.com/aws-controllers-k8s/runtime/pkg/util"
23+
24+ svcapitypes "github.com/aws-controllers-k8s/memorydb-controller/apis/v1alpha1"
25+ svcsdk "github.com/aws/aws-sdk-go/service/memorydb"
2026)
2127
2228// validateACLNeedsUpdate this function's purpose is to requeue if the resource is currently unavailable
@@ -34,3 +40,130 @@ func (rm *resourceManager) validateACLNeedsUpdate(
3440
3541 return nil
3642}
43+
44+ // getTags gets tags from given ParameterGroup.
45+ func (rm * resourceManager ) getTags (
46+ ctx context.Context ,
47+ resourceARN string ,
48+ ) ([]* svcapitypes.Tag , error ) {
49+ resp , err := rm .sdkapi .ListTagsWithContext (
50+ ctx ,
51+ & svcsdk.ListTagsInput {
52+ ResourceArn : & resourceARN ,
53+ },
54+ )
55+ rm .metrics .RecordAPICall ("GET" , "ListTags" , err )
56+ if err != nil {
57+ return nil , err
58+ }
59+ tags := resourceTagsFromSDKTags (resp .TagList )
60+ return tags , nil
61+ }
62+
63+ // updateTags updates tags of given ParameterGroup to desired tags.
64+ func (rm * resourceManager ) updateTags (
65+ ctx context.Context ,
66+ desired * resource ,
67+ latest * resource ,
68+ ) (err error ) {
69+ rlog := ackrtlog .FromContext (ctx )
70+ exit := rlog .Trace ("rm.updateTags" )
71+ defer func (err error ) { exit (err ) }(err )
72+
73+ arn := (* string )(latest .ko .Status .ACKResourceMetadata .ARN )
74+
75+ toAdd , toDelete := computeTagsDelta (
76+ desired .ko .Spec .Tags , latest .ko .Spec .Tags ,
77+ )
78+
79+ if len (toDelete ) > 0 {
80+ rlog .Debug ("removing tags from ACL" , "tags" , toDelete )
81+ _ , err = rm .sdkapi .UntagResourceWithContext (
82+ ctx ,
83+ & svcsdk.UntagResourceInput {
84+ ResourceArn : arn ,
85+ TagKeys : toDelete ,
86+ },
87+ )
88+ rm .metrics .RecordAPICall ("UPDATE" , "UntagResource" , err )
89+ if err != nil {
90+ return err
91+ }
92+ }
93+
94+ if len (toAdd ) > 0 {
95+ rlog .Debug ("adding tags to ACL" , "tags" , toAdd )
96+ _ , err = rm .sdkapi .TagResourceWithContext (
97+ ctx ,
98+ & svcsdk.TagResourceInput {
99+ ResourceArn : arn ,
100+ Tags : sdkTagsFromResourceTags (toAdd ),
101+ },
102+ )
103+ rm .metrics .RecordAPICall ("UPDATE" , "TagResource" , err )
104+ if err != nil {
105+ return err
106+ }
107+ }
108+
109+ return nil
110+ }
111+
112+ func computeTagsDelta (
113+ desired []* svcapitypes.Tag ,
114+ latest []* svcapitypes.Tag ,
115+ ) (addedOrUpdated []* svcapitypes.Tag , removed []* string ) {
116+ var visitedIndexes []string
117+
118+ for _ , latestElement := range latest {
119+ visitedIndexes = append (visitedIndexes , * latestElement .Key )
120+ for _ , desiredElement := range desired {
121+ if equalStrings (latestElement .Key , desiredElement .Key ) {
122+ if ! equalStrings (latestElement .Value , desiredElement .Value ) {
123+ addedOrUpdated = append (addedOrUpdated , desiredElement )
124+ }
125+ continue
126+ }
127+ }
128+ removed = append (removed , latestElement .Key )
129+ }
130+ for _ , desiredElement := range desired {
131+ if ! ackutil .InStrings (* desiredElement .Key , visitedIndexes ) {
132+ addedOrUpdated = append (addedOrUpdated , desiredElement )
133+ }
134+ }
135+ return addedOrUpdated , removed
136+ }
137+
138+ func sdkTagsFromResourceTags (
139+ rTags []* svcapitypes.Tag ,
140+ ) []* svcsdk.Tag {
141+ tags := make ([]* svcsdk.Tag , len (rTags ))
142+ for i := range rTags {
143+ tags [i ] = & svcsdk.Tag {
144+ Key : rTags [i ].Key ,
145+ Value : rTags [i ].Value ,
146+ }
147+ }
148+ return tags
149+ }
150+
151+ func resourceTagsFromSDKTags (
152+ sdkTags []* svcsdk.Tag ,
153+ ) []* svcapitypes.Tag {
154+ tags := make ([]* svcapitypes.Tag , len (sdkTags ))
155+ for i := range sdkTags {
156+ tags [i ] = & svcapitypes.Tag {
157+ Key : sdkTags [i ].Key ,
158+ Value : sdkTags [i ].Value ,
159+ }
160+ }
161+ return tags
162+ }
163+
164+ func equalStrings (a , b * string ) bool {
165+ if a == nil {
166+ return b == nil || * b == ""
167+ }
168+ return (* a == "" && b == nil ) || * a == * b
169+ }
0 commit comments