Skip to content

Commit 6177f8a

Browse files
authored
Add GlobalTable resource custom hooks, terminalCodes and e2e tests (#4)
Part of aws-controllers-k8s/community#803 Description of changes - Add custom hooks, terminalCodes to `GlobalTable` resource in `generator.yaml` - Add e2e tests for `GlobalTable` create and delete operations By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent e786654 commit 6177f8a

File tree

9 files changed

+216
-47
lines changed

9 files changed

+216
-47
lines changed

generator.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
operations:
2+
UpdateGlobalTable:
3+
operation_type: Delete
4+
resource_name: GlobalTable
15
resources:
26
Table:
37
exceptions:
@@ -20,6 +24,9 @@ resources:
2024
errors:
2125
404:
2226
code: GlobalTableNotFoundException
27+
hooks:
28+
sdk_delete_post_build_request:
29+
code: customSetDeleteInput(r, input)
2330
Backup:
2431
exceptions:
2532
errors:

pkg/resource/backup/manager.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package global_table
15+
16+
import svcsdk "github.com/aws/aws-sdk-go/service/dynamodb"
17+
18+
func customSetDeleteInput(r *resource, input *svcsdk.UpdateGlobalTableInput) {
19+
for _, replica := range r.ko.Spec.ReplicationGroup {
20+
replicaUpdate := &svcsdk.ReplicaUpdate{
21+
Delete: &svcsdk.DeleteReplicaAction{
22+
RegionName: replica.RegionName,
23+
},
24+
}
25+
input.ReplicaUpdates = append(input.ReplicaUpdates, replicaUpdate)
26+
}
27+
}

pkg/resource/global_table/manager.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/resource/global_table/sdk.go

Lines changed: 18 additions & 47 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/resource/table/manager.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

templates/hooks/global_table/sdk_create_pre_build_request.go.tpl

Whitespace-only changes.

test/e2e/resources/global_table.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: dynamodb.services.k8s.aws/v1alpha1
2+
kind: GlobalTable
3+
metadata:
4+
name: $GLOBAL_TABLE_NAME
5+
spec:
6+
globalTableName: $GLOBAL_TABLE_NAME
7+
replicationGroup:
8+
- regionName: $REGION_NAME

test/e2e/tests/test_global_table.py

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
# not use this file except in compliance with the License. A copy of the
5+
# License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is distributed
10+
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
# express or implied. See the License for the specific language governing
12+
# permissions and limitations under the License.
13+
14+
15+
16+
import boto3
17+
import pytest
18+
import json
19+
import time
20+
import logging
21+
from typing import Dict, Tuple
22+
23+
from acktest.resources import random_suffix_name
24+
from acktest.k8s import resource as k8s
25+
from acktest.aws.identity import get_region
26+
from e2e import (
27+
service_marker,
28+
CRD_GROUP,
29+
CRD_VERSION,
30+
load_dynamodb_resource,
31+
wait_for_cr_status,
32+
)
33+
from e2e.replacement_values import REPLACEMENT_VALUES
34+
35+
RESOURCE_PLURAL = "globaltables"
36+
37+
CREATE_WAIT_AFTER_SECONDS = 10
38+
DELETE_WAIT_AFTER_SECONDS = 30
39+
40+
@pytest.fixture(scope="module")
41+
def dynamodb_client():
42+
return boto3.client("dynamodb")
43+
44+
@pytest.fixture(scope="module")
45+
def dynamodb_table():
46+
resource_name = random_suffix_name("table", 32)
47+
48+
replacements = REPLACEMENT_VALUES.copy()
49+
replacements["TABLE_NAME"] = resource_name
50+
51+
# load resource
52+
resource_data = load_dynamodb_resource(
53+
"table_forums",
54+
additional_replacements=replacements,
55+
)
56+
57+
table_reference = k8s.CustomResourceReference(
58+
CRD_GROUP, CRD_VERSION, "tables",
59+
resource_name, namespace="default",
60+
)
61+
62+
# Create table
63+
k8s.create_custom_resource(table_reference, resource_data)
64+
table_resource = k8s.wait_resource_consumed_by_controller(table_reference)
65+
66+
assert table_resource is not None
67+
assert k8s.get_resource_exists(table_reference)
68+
69+
wait_for_cr_status(
70+
table_reference,
71+
"tableStatus",
72+
"ACTIVE",
73+
10,
74+
5,
75+
)
76+
77+
yield (table_reference, table_resource)
78+
79+
_, deleted = k8s.delete_custom_resource(table_reference)
80+
assert deleted
81+
82+
@service_marker
83+
@pytest.mark.canary
84+
class TestGlobalTable:
85+
86+
def get_global_table(self, dynamodb_client, global_table_name: str) -> dict:
87+
try:
88+
resp = dynamodb_client.describe_global_table(
89+
GlobalTableName=global_table_name,
90+
)
91+
return resp["GlobalTableDescription"]
92+
93+
except Exception as e:
94+
logging.debug(e)
95+
return None
96+
97+
def global_table_exists(self, dynamodb_client, global_table_name: str) -> bool:
98+
return self.get_global_table(dynamodb_client, global_table_name) is not None
99+
100+
def test_smoke(self, dynamodb_client, dynamodb_table):
101+
(_, table_resource) = dynamodb_table
102+
103+
# Global Tables must have the same name as dynamodb Tables
104+
global_table_name = table_resource["spec"]["tableName"]
105+
106+
replacements = REPLACEMENT_VALUES.copy()
107+
replacements["REGION_NAME"] = get_region()
108+
replacements["TABLE_NAME"] = global_table_name
109+
replacements["GLOBAL_TABLE_NAME"] = global_table_name
110+
111+
# Load GLobal Table CR
112+
resource_data = load_dynamodb_resource(
113+
"global_table",
114+
additional_replacements=replacements,
115+
)
116+
logging.debug(resource_data)
117+
118+
# Create k8s resource
119+
ref = k8s.CustomResourceReference(
120+
CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
121+
global_table_name, namespace="default",
122+
)
123+
k8s.create_custom_resource(ref, resource_data)
124+
cr = k8s.wait_resource_consumed_by_controller(ref)
125+
126+
assert cr is not None
127+
assert k8s.get_resource_exists(ref)
128+
129+
wait_for_cr_status(
130+
ref,
131+
"globalTableStatus",
132+
"ACTIVE",
133+
10,
134+
5,
135+
)
136+
137+
# Check DynamoDB Global Table exists
138+
exists = self.global_table_exists(dynamodb_client, global_table_name)
139+
assert exists
140+
141+
_, deleted = k8s.delete_custom_resource(ref)
142+
assert deleted is True
143+
144+
time.sleep(DELETE_WAIT_AFTER_SECONDS)
145+
146+
exists = self.global_table_exists(dynamodb_client, global_table_name)
147+
assert not exists

0 commit comments

Comments
 (0)