Skip to content

Commit

Permalink
Adds updateTags API for snapshot.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyrie Chen committed Dec 28, 2022
1 parent 2e57557 commit e998ffe
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 18 deletions.
4 changes: 2 additions & 2 deletions apis/v1alpha1/ack-generate-metadata.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
ack_generate_info:
build_date: "2022-12-23T17:00:07Z"
build_date: "2022-12-24T00:37:23Z"
build_hash: 16f0e201b37a06b535370cc69e11adb934a22d33
go_version: go1.19
version: v0.20.1-18-g16f0e20
api_directory_checksum: a1e396caca4bdd1612fa7d09f0ee56f3e4976ff7
api_version: v1alpha1
aws_sdk_go_version: v1.44.93
generator_config_info:
file_checksum: f50534e33903e1ca74491595fd6c21351988eb1c
file_checksum: d7ad13c5bc8d9e9e2171c92dc3ac51c2b5e3b769
original_file_name: generator.yaml
last_modification:
reason: API generation
2 changes: 2 additions & 0 deletions apis/v1alpha1/generator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ resources:
from:
operation: CreateSnapshot
path: ClusterName
update_operation:
custom_method_name: customUpdate
hooks:
sdk_create_pre_build_request:
template_path: hooks/snapshot/sdk_create_pre_build_request.go.tpl
Expand Down
2 changes: 2 additions & 0 deletions generator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ resources:
from:
operation: CreateSnapshot
path: ClusterName
update_operation:
custom_method_name: customUpdate
hooks:
sdk_create_pre_build_request:
template_path: hooks/snapshot/sdk_create_pre_build_request.go.tpl
Expand Down
164 changes: 155 additions & 9 deletions pkg/resource/snapshot/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ import (
"context"
"errors"

svcapitypes "github.com/aws-controllers-k8s/memorydb-controller/apis/v1alpha1"
ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1"
ackerr "github.com/aws-controllers-k8s/runtime/pkg/errors"
"github.com/aws/aws-sdk-go/service/memorydb"
svcsdk "github.com/aws/aws-sdk-go/service/memorydb"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

svcapitypes "github.com/aws-controllers-k8s/memorydb-controller/apis/v1alpha1"
ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1"
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"
ackutil "github.com/aws-controllers-k8s/runtime/pkg/util"
)

func (rm *resourceManager) customDescribeSnapshotSetOutput(
resp *memorydb.DescribeSnapshotsOutput,
resp *svcsdk.DescribeSnapshotsOutput,
ko *svcapitypes.Snapshot,
) (*svcapitypes.Snapshot, error) {
if len(resp.Snapshots) == 0 {
Expand All @@ -40,23 +42,23 @@ func (rm *resourceManager) customDescribeSnapshotSetOutput(
}

func (rm *resourceManager) customCreateSnapshotSetOutput(
resp *memorydb.CreateSnapshotOutput,
resp *svcsdk.CreateSnapshotOutput,
ko *svcapitypes.Snapshot,
) (*svcapitypes.Snapshot, error) {
rm.customSetOutput(resp.Snapshot, ko)
return ko, nil
}

func (rm *resourceManager) customCopySnapshotSetOutput(
resp *memorydb.CopySnapshotOutput,
resp *svcsdk.CopySnapshotOutput,
ko *svcapitypes.Snapshot,
) *svcapitypes.Snapshot {
rm.customSetOutput(resp.Snapshot, ko)
return ko
}

func (rm *resourceManager) customSetOutput(
respSnapshot *memorydb.Snapshot,
respSnapshot *svcsdk.Snapshot,
ko *svcapitypes.Snapshot,
) {
if ko.Status.Conditions == nil {
Expand Down Expand Up @@ -245,3 +247,147 @@ func (rm *resourceManager) newCopySnapshotPayload(

return res, nil
}

// 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
}

func (rm *resourceManager) customUpdate(
ctx context.Context,
desired *resource,
latest *resource,
delta *ackcompare.Delta,
) (updated *resource, err error) {
rlog := ackrtlog.FromContext(ctx)
exit := rlog.Trace("rm.customUpdate")
defer func(err error) { exit(err) }(err)
if delta.DifferentAt("Spec.Tags") {
if err = rm.updateTags(ctx, desired, latest); err != nil {
return nil, err
}
}
return desired, 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 snapshot", "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 snapshot", "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
}
10 changes: 8 additions & 2 deletions pkg/resource/snapshot/sdk.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,11 @@
ko, err = rm.customDescribeSnapshotSetOutput(resp, ko)
if err != nil {
return nil, err
}
}

resourceARN := (*string)(ko.Status.ACKResourceMetadata.ARN)
tags, err := rm.getTags(ctx, *resourceARN)
if err != nil {
return nil, err
}
ko.Spec.Tags = tags
6 changes: 4 additions & 2 deletions test/e2e/scenarios/Snapshot/snapshot_copy.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
id: "SNAPSHOT_COPY"
description: "In this test we copy snapshot from another snapshot"
#marks:
# - slow
# - blocked
steps:
- id: "CREATE_INITIAL_SNAPSHOT"
description: "Create Initial Snapshot"
create:
apiVersion: $CRD_GROUP/$CRD_VERSION
kind: Snapshot
metadata:
name: snapshot$RANDOM_SUFFIX
name: snapshot$RANDOM_SUFFIX
spec:
description: "Create ACK snapshot"
clusterName: $SNAPSHOT_CLUSTER_NAME2
name: snapshot$RANDOM_SUFFIX
wait:
Expand Down
4 changes: 3 additions & 1 deletion test/e2e/scenarios/Snapshot/snapshot_create.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
id: "SNAPSHOT_CREATE"
description: "In this test we create Snapshot"
#marks:
# - slow
# - blocked
steps:
- id: "CREATE_SNAPSHOT"
description: "ACK Snapshot"
Expand All @@ -9,7 +12,6 @@ steps:
metadata:
name: snapshot$RANDOM_SUFFIX
spec:
description: "Create ACK snapshot"
clusterName: $SNAPSHOT_CLUSTER_NAME1
name: snapshot$RANDOM_SUFFIX
wait:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
id: "SNAPSHOT_CREATE_TERMINAL_CONDITION"
description: "In this test we try to create snapshot without specifying cluster"
#marks:
# - slow
# - blocked
steps:
- id: "SNAPSHOT_INITIAL_CREATE"
description: "Create snapshot with no clustername "
Expand All @@ -9,7 +12,6 @@ steps:
metadata:
name: snapshot$RANDOM_SUFFIX
spec:
description: "Create ACK snapshot"
name: snapshot$RANDOM_SUFFIX
wait: 120
expect:
Expand Down
Loading

0 comments on commit e998ffe

Please sign in to comment.