Skip to content

Commit

Permalink
Add GlobalTable resource custom hooks, terminalCodes and e2e tests (#4
Browse files Browse the repository at this point in the history
)

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.
  • Loading branch information
a-hilaly authored Jun 14, 2021
1 parent e786654 commit 6177f8a
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 47 deletions.
7 changes: 7 additions & 0 deletions generator.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
operations:
UpdateGlobalTable:
operation_type: Delete
resource_name: GlobalTable
resources:
Table:
exceptions:
Expand All @@ -20,6 +24,9 @@ resources:
errors:
404:
code: GlobalTableNotFoundException
hooks:
sdk_delete_post_build_request:
code: customSetDeleteInput(r, input)
Backup:
exceptions:
errors:
Expand Down
3 changes: 3 additions & 0 deletions pkg/resource/backup/manager.go

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

27 changes: 27 additions & 0 deletions pkg/resource/global_table/custom_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.

package global_table

import svcsdk "github.com/aws/aws-sdk-go/service/dynamodb"

func customSetDeleteInput(r *resource, input *svcsdk.UpdateGlobalTableInput) {
for _, replica := range r.ko.Spec.ReplicationGroup {
replicaUpdate := &svcsdk.ReplicaUpdate{
Delete: &svcsdk.DeleteReplicaAction{
RegionName: replica.RegionName,
},
}
input.ReplicaUpdates = append(input.ReplicaUpdates, replicaUpdate)
}
}
3 changes: 3 additions & 0 deletions pkg/resource/global_table/manager.go

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

65 changes: 18 additions & 47 deletions pkg/resource/global_table/sdk.go

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

3 changes: 3 additions & 0 deletions pkg/resource/table/manager.go

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

Empty file.
8 changes: 8 additions & 0 deletions test/e2e/resources/global_table.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: dynamodb.services.k8s.aws/v1alpha1
kind: GlobalTable
metadata:
name: $GLOBAL_TABLE_NAME
spec:
globalTableName: $GLOBAL_TABLE_NAME
replicationGroup:
- regionName: $REGION_NAME
147 changes: 147 additions & 0 deletions test/e2e/tests/test_global_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.



import boto3
import pytest
import json
import time
import logging
from typing import Dict, Tuple

from acktest.resources import random_suffix_name
from acktest.k8s import resource as k8s
from acktest.aws.identity import get_region
from e2e import (
service_marker,
CRD_GROUP,
CRD_VERSION,
load_dynamodb_resource,
wait_for_cr_status,
)
from e2e.replacement_values import REPLACEMENT_VALUES

RESOURCE_PLURAL = "globaltables"

CREATE_WAIT_AFTER_SECONDS = 10
DELETE_WAIT_AFTER_SECONDS = 30

@pytest.fixture(scope="module")
def dynamodb_client():
return boto3.client("dynamodb")

@pytest.fixture(scope="module")
def dynamodb_table():
resource_name = random_suffix_name("table", 32)

replacements = REPLACEMENT_VALUES.copy()
replacements["TABLE_NAME"] = resource_name

# load resource
resource_data = load_dynamodb_resource(
"table_forums",
additional_replacements=replacements,
)

table_reference = k8s.CustomResourceReference(
CRD_GROUP, CRD_VERSION, "tables",
resource_name, namespace="default",
)

# Create table
k8s.create_custom_resource(table_reference, resource_data)
table_resource = k8s.wait_resource_consumed_by_controller(table_reference)

assert table_resource is not None
assert k8s.get_resource_exists(table_reference)

wait_for_cr_status(
table_reference,
"tableStatus",
"ACTIVE",
10,
5,
)

yield (table_reference, table_resource)

_, deleted = k8s.delete_custom_resource(table_reference)
assert deleted

@service_marker
@pytest.mark.canary
class TestGlobalTable:

def get_global_table(self, dynamodb_client, global_table_name: str) -> dict:
try:
resp = dynamodb_client.describe_global_table(
GlobalTableName=global_table_name,
)
return resp["GlobalTableDescription"]

except Exception as e:
logging.debug(e)
return None

def global_table_exists(self, dynamodb_client, global_table_name: str) -> bool:
return self.get_global_table(dynamodb_client, global_table_name) is not None

def test_smoke(self, dynamodb_client, dynamodb_table):
(_, table_resource) = dynamodb_table

# Global Tables must have the same name as dynamodb Tables
global_table_name = table_resource["spec"]["tableName"]

replacements = REPLACEMENT_VALUES.copy()
replacements["REGION_NAME"] = get_region()
replacements["TABLE_NAME"] = global_table_name
replacements["GLOBAL_TABLE_NAME"] = global_table_name

# Load GLobal Table CR
resource_data = load_dynamodb_resource(
"global_table",
additional_replacements=replacements,
)
logging.debug(resource_data)

# Create k8s resource
ref = k8s.CustomResourceReference(
CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
global_table_name, namespace="default",
)
k8s.create_custom_resource(ref, resource_data)
cr = k8s.wait_resource_consumed_by_controller(ref)

assert cr is not None
assert k8s.get_resource_exists(ref)

wait_for_cr_status(
ref,
"globalTableStatus",
"ACTIVE",
10,
5,
)

# Check DynamoDB Global Table exists
exists = self.global_table_exists(dynamodb_client, global_table_name)
assert exists

_, deleted = k8s.delete_custom_resource(ref)
assert deleted is True

time.sleep(DELETE_WAIT_AFTER_SECONDS)

exists = self.global_table_exists(dynamodb_client, global_table_name)
assert not exists

0 comments on commit 6177f8a

Please sign in to comment.