Skip to content

Commit

Permalink
Supports Tag and Untag API for cluster.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyrie Chen committed Dec 22, 2022
1 parent d86b927 commit c263865
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 3 deletions.
2 changes: 1 addition & 1 deletion apis/v1alpha1/ack-generate-metadata.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ack_generate_info:
build_date: "2022-12-14T00:10:49Z"
build_date: "2022-12-22T20:12:01Z"
build_hash: 16f0e201b37a06b535370cc69e11adb934a22d33
go_version: go1.19
version: v0.20.1-18-g16f0e20
Expand Down
129 changes: 129 additions & 0 deletions pkg/resource/cluster/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ import (
"context"
"errors"
"fmt"
ackutil "github.com/aws-controllers-k8s/runtime/pkg/util"

ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare"
ackerr "github.com/aws-controllers-k8s/runtime/pkg/errors"
ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log"
"strconv"

svcapitypes "github.com/aws-controllers-k8s/memorydb-controller/apis/v1alpha1"
Expand Down Expand Up @@ -262,3 +264,130 @@ func (rm *resourceManager) newMemoryDBClusterUploadPayload(

return res
}

// getTags gets tags from given ParameterGroup.
func (rm *resourceManager) getTags(
ctx context.Context,
resourceARN string,
) ([]*svcapitypes.Tag, error) {
resp, err := rm.sdkapi.ListTagsWithContext(
ctx,
&svcsdk.ListTagsInput{
ResourceArn: &resourceARN,
},
)
rm.metrics.RecordAPICall("GET", "ListTags", err)
if err != nil {
return nil, err
}
tags := resourceTagsFromSDKTags(resp.TagList)
return tags, nil
}

// updateTags updates tags of given ParameterGroup to desired tags.
func (rm *resourceManager) updateTags(
ctx context.Context,
desired *resource,
latest *resource,
) (err error) {
rlog := ackrtlog.FromContext(ctx)
exit := rlog.Trace("rm.updateTags")
defer func(err error) { exit(err) }(err)

arn := (*string)(latest.ko.Status.ACKResourceMetadata.ARN)

toAdd, toDelete := computeTagsDelta(
desired.ko.Spec.Tags, latest.ko.Spec.Tags,
)

if len(toDelete) > 0 {
rlog.Debug("removing tags from parameter group", "tags", toDelete)
_, err = rm.sdkapi.UntagResourceWithContext(
ctx,
&svcsdk.UntagResourceInput{
ResourceArn: arn,
TagKeys: toDelete,
},
)
rm.metrics.RecordAPICall("UPDATE", "UntagResource", err)
if err != nil {
return err
}
}

if len(toAdd) > 0 {
rlog.Debug("adding tags to parameter group", "tags", toAdd)
_, err = rm.sdkapi.TagResourceWithContext(
ctx,
&svcsdk.TagResourceInput{
ResourceArn: arn,
Tags: sdkTagsFromResourceTags(toAdd),
},
)
rm.metrics.RecordAPICall("UPDATE", "TagResource", err)
if err != nil {
return err
}
}

return nil
}

func computeTagsDelta(
desired []*svcapitypes.Tag,
latest []*svcapitypes.Tag,
) (addedOrUpdated []*svcapitypes.Tag, removed []*string) {
var visitedIndexes []string

for _, latestElement := range latest {
visitedIndexes = append(visitedIndexes, *latestElement.Key)
for _, desiredElement := range desired {
if equalStrings(latestElement.Key, desiredElement.Key) {
if !equalStrings(latestElement.Value, desiredElement.Value) {
addedOrUpdated = append(addedOrUpdated, desiredElement)
}
continue
}
}
removed = append(removed, latestElement.Key)
}
for _, desiredElement := range desired {
if !ackutil.InStrings(*desiredElement.Key, visitedIndexes) {
addedOrUpdated = append(addedOrUpdated, desiredElement)
}
}
return addedOrUpdated, removed
}

func sdkTagsFromResourceTags(
rTags []*svcapitypes.Tag,
) []*svcsdk.Tag {
tags := make([]*svcsdk.Tag, len(rTags))
for i := range rTags {
tags[i] = &svcsdk.Tag{
Key: rTags[i].Key,
Value: rTags[i].Value,
}
}
return tags
}

func resourceTagsFromSDKTags(
sdkTags []*svcsdk.Tag,
) []*svcapitypes.Tag {
tags := make([]*svcapitypes.Tag, len(sdkTags))
for i := range sdkTags {
tags[i] = &svcapitypes.Tag{
Key: sdkTags[i].Key,
Value: sdkTags[i].Value,
}
}
return tags
}

func equalStrings(a, b *string) bool {
if a == nil {
return b == nil || *b == ""
}
return (*a == "" && b == nil) || *a == *b
}
20 changes: 20 additions & 0 deletions pkg/resource/cluster/sdk.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion templates/hooks/cluster/sdk_read_many_post_set_output.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,11 @@
respErr := rm.setAllowedNodeTypeUpdates(ctx, ko)
if respErr != nil {
return nil, respErr
}
}

resourceARN := (*string)(ko.Status.ACKResourceMetadata.ARN)
tags, err := rm.getTags(ctx, *resourceARN)
if err != nil {
return nil, err
}
ko.Spec.Tags = tags
13 changes: 12 additions & 1 deletion templates/hooks/cluster/sdk_update_pre_build_request.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,15 @@

if err != nil || res!= nil{
return res, err
}
}

if delta.DifferentAt("Spec.Tags") {
err = rm.updateTags(ctx, desired, latest)
if err != nil {
return nil, err
}
}

if !delta.DifferentExcept("Spec.Tags") {
return desired, nil
}
84 changes: 84 additions & 0 deletions test/e2e/scenarios/Cluster/cluster_update_with_tags.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
id: "CLUSTER_UPDATE_WITH_TAGS"
description: "In this test we create cluster and update cluster with tags"
#marks:
# - slow
# - blocked
steps:
- id: "CLUSTER_INITIAL_CREATE"
description: "Create Cluster with no tags"
create:
apiVersion: $CRD_GROUP/$CRD_VERSION
kind: Cluster
metadata:
name: cluster$RANDOM_SUFFIX
spec:
name: cluster$RANDOM_SUFFIX
nodeType: db.t4g.small
aclName: open-access
numShards: 1
wait:
status:
conditions:
ACK.ResourceSynced:
status: "True"
timeout: 7200
- id: "CLUSTER_ADD_TAGS"
description: "Add tags in Cluster"
patch:
apiVersion: $CRD_GROUP/$CRD_VERSION
kind: Cluster
metadata:
name: cluster$RANDOM_SUFFIX
spec:
tags:
- key: "test_key_1"
value: "test_value_1"
- key: "test_key_2"
- key:
wait:
status:
conditions:
ACK.ResourceSynced:
status: "True"
timeout: 100
- id: "CLUSTER_DELETE_TAGS"
description: "Delete tags in Cluster"
patch:
apiVersion: $CRD_GROUP/$CRD_VERSION
kind: Cluster
metadata:
name: cluster$RANDOM_SUFFIX
spec:
tags:
- key: "test_key_1"
value: "test_value_1"
wait:
status:
conditions:
ACK.ResourceSynced:
status: "True"
timeout: 100
- id: "Cluster_ADD_AND_DELETE_TAGS"
description: "Add some tags and delete some tags in Cluster"
patch:
apiVersion: $CRD_GROUP/$CRD_VERSION
kind: Cluster
metadata:
name: cluster$RANDOM_SUFFIX
spec:
tags:
- key: "test_key_2"
value: "test_value_2"
wait:
status:
conditions:
ACK.ResourceSynced:
status: "True"
timeout: 100
- id: "DELETE_CLUSTER"
description: "Delete the cluster"
delete:
apiVersion: $CRD_GROUP/$CRD_VERSION
kind: Cluster
metadata:
name: cluster$RANDOM_SUFFIX

0 comments on commit c263865

Please sign in to comment.