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