@@ -17,18 +17,20 @@ import (
1717 "context"
1818 "errors"
1919
20- svcapitypes "github.com/aws-controllers-k8s/memorydb-controller/apis/v1alpha1"
21- ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1"
22- ackerr "github.com/aws-controllers-k8s/runtime/pkg/errors"
23- "github.com/aws/aws-sdk-go/service/memorydb"
2420 svcsdk "github.com/aws/aws-sdk-go/service/memorydb"
25-
2621 corev1 "k8s.io/api/core/v1"
2722 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
24+ svcapitypes "github.com/aws-controllers-k8s/memorydb-controller/apis/v1alpha1"
25+ ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1"
26+ ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare"
27+ ackerr "github.com/aws-controllers-k8s/runtime/pkg/errors"
28+ ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log"
29+ ackutil "github.com/aws-controllers-k8s/runtime/pkg/util"
2830)
2931
3032func (rm * resourceManager ) customDescribeSnapshotSetOutput (
31- resp * memorydb .DescribeSnapshotsOutput ,
33+ resp * svcsdk .DescribeSnapshotsOutput ,
3234 ko * svcapitypes.Snapshot ,
3335) (* svcapitypes.Snapshot , error ) {
3436 if len (resp .Snapshots ) == 0 {
@@ -40,23 +42,23 @@ func (rm *resourceManager) customDescribeSnapshotSetOutput(
4042}
4143
4244func (rm * resourceManager ) customCreateSnapshotSetOutput (
43- resp * memorydb .CreateSnapshotOutput ,
45+ resp * svcsdk .CreateSnapshotOutput ,
4446 ko * svcapitypes.Snapshot ,
4547) (* svcapitypes.Snapshot , error ) {
4648 rm .customSetOutput (resp .Snapshot , ko )
4749 return ko , nil
4850}
4951
5052func (rm * resourceManager ) customCopySnapshotSetOutput (
51- resp * memorydb .CopySnapshotOutput ,
53+ resp * svcsdk .CopySnapshotOutput ,
5254 ko * svcapitypes.Snapshot ,
5355) * svcapitypes.Snapshot {
5456 rm .customSetOutput (resp .Snapshot , ko )
5557 return ko
5658}
5759
5860func (rm * resourceManager ) customSetOutput (
59- respSnapshot * memorydb .Snapshot ,
61+ respSnapshot * svcsdk .Snapshot ,
6062 ko * svcapitypes.Snapshot ,
6163) {
6264 if ko .Status .Conditions == nil {
@@ -245,3 +247,147 @@ func (rm *resourceManager) newCopySnapshotPayload(
245247
246248 return res , nil
247249}
250+
251+ // getTags gets tags from given ParameterGroup.
252+ func (rm * resourceManager ) getTags (
253+ ctx context.Context ,
254+ resourceARN string ,
255+ ) ([]* svcapitypes.Tag , error ) {
256+ resp , err := rm .sdkapi .ListTagsWithContext (
257+ ctx ,
258+ & svcsdk.ListTagsInput {
259+ ResourceArn : & resourceARN ,
260+ },
261+ )
262+ rm .metrics .RecordAPICall ("GET" , "ListTags" , err )
263+ if err != nil {
264+ return nil , err
265+ }
266+ tags := resourceTagsFromSDKTags (resp .TagList )
267+ return tags , nil
268+ }
269+
270+ func (rm * resourceManager ) customUpdate (
271+ ctx context.Context ,
272+ desired * resource ,
273+ latest * resource ,
274+ delta * ackcompare.Delta ,
275+ ) (updated * resource , err error ) {
276+ rlog := ackrtlog .FromContext (ctx )
277+ exit := rlog .Trace ("rm.customUpdate" )
278+ defer func (err error ) { exit (err ) }(err )
279+ if delta .DifferentAt ("Spec.Tags" ) {
280+ if err = rm .updateTags (ctx , desired , latest ); err != nil {
281+ return nil , err
282+ }
283+ }
284+ return desired , nil
285+ }
286+
287+ // updateTags updates tags of given ParameterGroup to desired tags.
288+ func (rm * resourceManager ) updateTags (
289+ ctx context.Context ,
290+ desired * resource ,
291+ latest * resource ,
292+ ) (err error ) {
293+ rlog := ackrtlog .FromContext (ctx )
294+ exit := rlog .Trace ("rm.updateTags" )
295+ defer func (err error ) { exit (err ) }(err )
296+
297+ arn := (* string )(latest .ko .Status .ACKResourceMetadata .ARN )
298+
299+ toAdd , toDelete := computeTagsDelta (
300+ desired .ko .Spec .Tags , latest .ko .Spec .Tags ,
301+ )
302+
303+ if len (toDelete ) > 0 {
304+ rlog .Debug ("removing tags from snapshot" , "tags" , toDelete )
305+ _ , err = rm .sdkapi .UntagResourceWithContext (
306+ ctx ,
307+ & svcsdk.UntagResourceInput {
308+ ResourceArn : arn ,
309+ TagKeys : toDelete ,
310+ },
311+ )
312+ rm .metrics .RecordAPICall ("UPDATE" , "UntagResource" , err )
313+ if err != nil {
314+ return err
315+ }
316+ }
317+
318+ if len (toAdd ) > 0 {
319+ rlog .Debug ("adding tags to snapshot" , "tags" , toAdd )
320+ _ , err = rm .sdkapi .TagResourceWithContext (
321+ ctx ,
322+ & svcsdk.TagResourceInput {
323+ ResourceArn : arn ,
324+ Tags : sdkTagsFromResourceTags (toAdd ),
325+ },
326+ )
327+ rm .metrics .RecordAPICall ("UPDATE" , "TagResource" , err )
328+ if err != nil {
329+ return err
330+ }
331+ }
332+
333+ return nil
334+ }
335+
336+ func computeTagsDelta (
337+ desired []* svcapitypes.Tag ,
338+ latest []* svcapitypes.Tag ,
339+ ) (addedOrUpdated []* svcapitypes.Tag , removed []* string ) {
340+ var visitedIndexes []string
341+
342+ for _ , latestElement := range latest {
343+ visitedIndexes = append (visitedIndexes , * latestElement .Key )
344+ for _ , desiredElement := range desired {
345+ if equalStrings (latestElement .Key , desiredElement .Key ) {
346+ if ! equalStrings (latestElement .Value , desiredElement .Value ) {
347+ addedOrUpdated = append (addedOrUpdated , desiredElement )
348+ }
349+ continue
350+ }
351+ }
352+ removed = append (removed , latestElement .Key )
353+ }
354+ for _ , desiredElement := range desired {
355+ if ! ackutil .InStrings (* desiredElement .Key , visitedIndexes ) {
356+ addedOrUpdated = append (addedOrUpdated , desiredElement )
357+ }
358+ }
359+ return addedOrUpdated , removed
360+ }
361+
362+ func sdkTagsFromResourceTags (
363+ rTags []* svcapitypes.Tag ,
364+ ) []* svcsdk.Tag {
365+ tags := make ([]* svcsdk.Tag , len (rTags ))
366+ for i := range rTags {
367+ tags [i ] = & svcsdk.Tag {
368+ Key : rTags [i ].Key ,
369+ Value : rTags [i ].Value ,
370+ }
371+ }
372+ return tags
373+ }
374+
375+ func resourceTagsFromSDKTags (
376+ sdkTags []* svcsdk.Tag ,
377+ ) []* svcapitypes.Tag {
378+ tags := make ([]* svcapitypes.Tag , len (sdkTags ))
379+ for i := range sdkTags {
380+ tags [i ] = & svcapitypes.Tag {
381+ Key : sdkTags [i ].Key ,
382+ Value : sdkTags [i ].Value ,
383+ }
384+ }
385+ return tags
386+ }
387+
388+ func equalStrings (a , b * string ) bool {
389+ if a == nil {
390+ return b == nil || * b == ""
391+ }
392+ return (* a == "" && b == nil ) || * a == * b
393+ }
0 commit comments