Skip to content

Commit e786654

Browse files
authored
Add Table resource custom hooks, terminalCodes and e2e tests (#3)
Part of aws-controllers-k8s/community#803 Description of changes - Add custom hooks, terminalCodes, printcomns to `Table` resource in `generator.yaml` - Add e2e tests for `Table` 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 9730082 commit e786654

17 files changed

+655
-2
lines changed

generator.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ resources:
44
errors:
55
404:
66
code: ResourceNotFoundException
7+
terminal_codes:
8+
- InternalServerError
9+
- LimitExceededException
10+
- ResourceInUseException
11+
hooks:
12+
sdk_read_one_post_set_output:
13+
template_path: hooks/table/sdk_read_one_post_set_output.go.tpl
14+
sdk_update_pre_build_request:
15+
template_path: hooks/table/sdk_update_pre_build_request.go.tpl
16+
sdk_delete_pre_build_request:
17+
template_path: hooks/table/sdk_delete_pre_build_request.go.tpl
718
GlobalTable:
819
exceptions:
920
errors:

pkg/resource/table/conditions.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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 table
15+
16+
import (
17+
corev1 "k8s.io/api/core/v1"
18+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19+
20+
ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1"
21+
)
22+
23+
// getSyncedCondition returns the Condition in the resource's Conditions
24+
// collection that is of type ConditionTypeResourceSynced. If no such condition
25+
// is found, returns nil.
26+
//
27+
// TODO(jaypipes): Move to ACK code-gen templates.
28+
func getSyncedCondition(r *resource) *ackv1alpha1.Condition {
29+
return getConditionOfType(r, ackv1alpha1.ConditionTypeResourceSynced)
30+
}
31+
32+
// getTerminalCondition returns the Condition in the resource's Conditions
33+
// collection that is of type ConditionTypeTerminal. If no such condition is
34+
// found, returns nil.
35+
//
36+
// TODO(jaypipes): Move to ACK code-gen templates.
37+
func getTerminalCondition(r *resource) *ackv1alpha1.Condition {
38+
return getConditionOfType(r, ackv1alpha1.ConditionTypeTerminal)
39+
}
40+
41+
// getConditionOfType returns the Condition in the resource's Conditions
42+
// collection of the supplied type. If no such condition is found, returns nil.
43+
//
44+
// TODO(jaypipes): Move to ACK code-gen templates.
45+
func getConditionOfType(
46+
r *resource,
47+
condType ackv1alpha1.ConditionType,
48+
) *ackv1alpha1.Condition {
49+
for _, condition := range r.ko.Status.Conditions {
50+
if condition.Type == condType {
51+
return condition
52+
}
53+
}
54+
return nil
55+
}
56+
57+
// setSyncedCondition sets the resource's Condition of type
58+
// ConditionTypeResourceSynced to the supplied status, optional message and
59+
// reason.
60+
//
61+
// TODO(jaypipes): Move to ACK code-gen templates.
62+
func setSyncedCondition(
63+
r *resource,
64+
status corev1.ConditionStatus,
65+
message *string,
66+
reason *string,
67+
) {
68+
c := getSyncedCondition(r)
69+
if c == nil {
70+
c = &ackv1alpha1.Condition{
71+
Type: ackv1alpha1.ConditionTypeResourceSynced,
72+
}
73+
r.ko.Status.Conditions = append(r.ko.Status.Conditions, c)
74+
}
75+
now := metav1.Now()
76+
c.LastTransitionTime = &now
77+
c.Status = status
78+
}
79+
80+
// setTerminalCondition sets the resource's Condition of type
81+
// ConditionTypeTerminal to the supplied status, optional message and reason.
82+
//
83+
// TODO(jaypipes): Move to ACK code-gen templates.
84+
func setTerminalCondition(
85+
r *resource,
86+
status corev1.ConditionStatus,
87+
message *string,
88+
reason *string,
89+
) {
90+
c := getTerminalCondition(r)
91+
if c == nil {
92+
c = &ackv1alpha1.Condition{
93+
Type: ackv1alpha1.ConditionTypeTerminal,
94+
}
95+
r.ko.Status.Conditions = append(r.ko.Status.Conditions, c)
96+
}
97+
now := metav1.Now()
98+
c.LastTransitionTime = &now
99+
c.Status = status
100+
c.Message = message
101+
c.Reason = reason
102+
}

pkg/resource/table/hooks.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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 table
15+
16+
import (
17+
"errors"
18+
"time"
19+
20+
"github.com/aws-controllers-k8s/dynamodb-controller/apis/v1alpha1"
21+
ackrequeue "github.com/aws-controllers-k8s/runtime/pkg/requeue"
22+
)
23+
24+
var (
25+
ErrTableDeleting = errors.New("Table in 'DELETING' state, cannot be modified or deleted")
26+
ErrTableCreating = errors.New("Table in 'CREATING' state, cannot be modified or deleted")
27+
ErrTableUpdating = errors.New("Table in 'UPDATING' state, cannot be modified or deleted")
28+
)
29+
30+
var (
31+
// TerminalStatuses are the status strings that are terminal states for a
32+
// DynamoDB table
33+
TerminalStatuses = []v1alpha1.TableStatus_SDK{
34+
v1alpha1.TableStatus_SDK_ARCHIVING,
35+
v1alpha1.TableStatus_SDK_DELETING,
36+
}
37+
)
38+
39+
var (
40+
requeueWaitWhileDeleting = ackrequeue.NeededAfter(
41+
ErrTableDeleting,
42+
5*time.Second,
43+
)
44+
requeueWaitWhileCreating = ackrequeue.NeededAfter(
45+
ErrTableDeleting,
46+
5*time.Second,
47+
)
48+
requeueWaitWhileUpdating = ackrequeue.NeededAfter(
49+
ErrTableUpdating,
50+
5*time.Second,
51+
)
52+
)
53+
54+
// tableHasTerminalStatus returns whether the supplied Dynamodb table is in a
55+
// terminal state
56+
func tableHasTerminalStatus(r *resource) bool {
57+
if r.ko.Status.TableStatus == nil {
58+
return false
59+
}
60+
ts := *r.ko.Status.TableStatus
61+
for _, s := range TerminalStatuses {
62+
if ts == string(s) {
63+
return true
64+
}
65+
}
66+
return false
67+
}
68+
69+
// isTableCreating returns true if the supplied DynamodbDB table is in the process
70+
// of being created
71+
func isTableCreating(r *resource) bool {
72+
if r.ko.Status.TableStatus == nil {
73+
return false
74+
}
75+
dbis := *r.ko.Status.TableStatus
76+
return dbis == string(v1alpha1.TableStatus_SDK_CREATING)
77+
}
78+
79+
// isTableDeleting returns true if the supplied DynamodbDB table is in the process
80+
// of being deleted
81+
func isTableDeleting(r *resource) bool {
82+
if r.ko.Status.TableStatus == nil {
83+
return false
84+
}
85+
dbis := *r.ko.Status.TableStatus
86+
return dbis == string(v1alpha1.TableStatus_SDK_DELETING)
87+
}
88+
89+
// isTableUpdating returns true if the supplied DynamodbDB table is in the process
90+
// of being deleted
91+
func isTableUpdating(r *resource) bool {
92+
if r.ko.Status.TableStatus == nil {
93+
return false
94+
}
95+
dbis := *r.ko.Status.TableStatus
96+
return dbis == string(v1alpha1.TableStatus_SDK_UPDATING)
97+
}

pkg/resource/table/sdk.go

Lines changed: 48 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
if isTableDeleting(r) {
2+
return requeueWaitWhileDeleting
3+
}
4+
if isTableUpdating(r) {
5+
return requeueWaitWhileUpdating
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
if isTableCreating(&resource{ko}) {
2+
return &resource{ko}, requeueWaitWhileCreating
3+
}
4+
if isTableUpdating(&resource{ko}) {
5+
return &resource{ko}, requeueWaitWhileUpdating
6+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
if isTableDeleting(latest) {
2+
msg := "table is currently being deleted"
3+
setSyncedCondition(desired, corev1.ConditionFalse, &msg, nil)
4+
return desired, requeueWaitWhileDeleting
5+
}
6+
if isTableCreating(latest) {
7+
msg := "table is currently being created"
8+
setSyncedCondition(desired, corev1.ConditionFalse, &msg, nil)
9+
return desired, requeueWaitWhileCreating
10+
}
11+
if isTableUpdating(latest) {
12+
msg := "table is currently being updated"
13+
setSyncedCondition(desired, corev1.ConditionFalse, &msg, nil)
14+
return desired, requeueWaitWhileUpdating
15+
}
16+
if tableHasTerminalStatus(latest) {
17+
msg := "table is in '"+*latest.ko.Status.TableStatus+"' status"
18+
setTerminalCondition(desired, corev1.ConditionTrue, &msg, nil)
19+
setSyncedCondition(desired, corev1.ConditionTrue, nil, nil)
20+
return desired, nil
21+
}

test/e2e/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
__pycache__/
2+
*.py[cod]
3+
**/bootstrap.yaml

0 commit comments

Comments
 (0)