Skip to content

feat: Add contributorInsights field to Table resource #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 1, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 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: "2025-03-28T01:43:12Z"
build_date: "2025-04-01T02:35:33Z"
build_hash: 980cb1e4734f673d16101cf55206b84ca639ec01
go_version: go1.24.1
version: v0.44.0
api_directory_checksum: cb49386ebd7bb50e2521072a76262c72b9dbd285
api_directory_checksum: 2f94829f12ad90f9c36c48823459c161c1670093
api_version: v1alpha1
aws_sdk_go_version: v1.32.6
generator_config_info:
file_checksum: 4533fa8aca3b134b5895ad6ce9a093c3446d99da
file_checksum: e7e79c3c7c21273967ca24947fda0f26b344c8f0
original_file_name: generator.yaml
last_modification:
reason: API generation
6 changes: 6 additions & 0 deletions apis/v1alpha1/generator.yaml
Original file line number Diff line number Diff line change
@@ -70,6 +70,10 @@ resources:
service_name: kms
resource: Key
path: Status.ACKResourceMetadata.ARN
ContributorInsights:
from:
operation: UpdateContributorInsights
path: ContributorInsightsAction
exceptions:
errors:
404:
@@ -86,6 +90,8 @@ resources:
template_path: hooks/table/sdk_create_post_set_output.go.tpl
sdk_read_one_post_set_output:
template_path: hooks/table/sdk_read_one_post_set_output.go.tpl
sdk_update_pre_build_request:
template_path: hooks/table/sdk_update_pre_build_request.go.tpl
sdk_delete_pre_build_request:
template_path: hooks/table/sdk_delete_pre_build_request.go.tpl
synced:
2 changes: 2 additions & 0 deletions apis/v1alpha1/table.go

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

5 changes: 5 additions & 0 deletions apis/v1alpha1/zz_generated.deepcopy.go

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

3 changes: 3 additions & 0 deletions config/crd/bases/dynamodb.services.k8s.aws_tables.yaml
Original file line number Diff line number Diff line change
@@ -88,6 +88,9 @@ spec:
pointInTimeRecoveryEnabled:
type: boolean
type: object
contributorInsights:
description: Represents the contributor insights action.
type: string
deletionProtectionEnabled:
description: |-
Indicates whether deletion protection is to be enabled (true) or disabled
6 changes: 6 additions & 0 deletions generator.yaml
Original file line number Diff line number Diff line change
@@ -70,6 +70,10 @@ resources:
service_name: kms
resource: Key
path: Status.ACKResourceMetadata.ARN
ContributorInsights:
from:
operation: UpdateContributorInsights
path: ContributorInsightsAction
exceptions:
errors:
404:
@@ -86,6 +90,8 @@ resources:
template_path: hooks/table/sdk_create_post_set_output.go.tpl
sdk_read_one_post_set_output:
template_path: hooks/table/sdk_read_one_post_set_output.go.tpl
sdk_update_pre_build_request:
template_path: hooks/table/sdk_update_pre_build_request.go.tpl
sdk_delete_pre_build_request:
template_path: hooks/table/sdk_delete_pre_build_request.go.tpl
synced:
3 changes: 3 additions & 0 deletions helm/crds/dynamodb.services.k8s.aws_tables.yaml
Original file line number Diff line number Diff line change
@@ -88,6 +88,9 @@ spec:
pointInTimeRecoveryEnabled:
type: boolean
type: object
contributorInsights:
description: Represents the contributor insights action.
type: string
deletionProtectionEnabled:
description: |-
Indicates whether deletion protection is to be enabled (true) or disabled
7 changes: 7 additions & 0 deletions pkg/resource/table/delta.go

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

90 changes: 90 additions & 0 deletions pkg/resource/table/hooks.go
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@ import (
corev1 "k8s.io/api/core/v1"

"github.com/aws-controllers-k8s/dynamodb-controller/apis/v1alpha1"
svcapitypes "github.com/aws-controllers-k8s/dynamodb-controller/apis/v1alpha1"
)

var (
@@ -136,6 +137,15 @@ func isTableUpdating(r *resource) bool {
return dbis == string(v1alpha1.TableStatus_SDK_UPDATING)
}

func isTableContributorInsightsUpdating(r *resource) bool {
if r.ko.Spec.ContributorInsights == nil {
return false
}
insightStatus := *r.ko.Spec.ContributorInsights
return insightStatus == string(svcsdktypes.ContributorInsightsStatusEnabling) ||
insightStatus == string(svcsdktypes.ContributorInsightsStatusDisabling)
}

func (rm *resourceManager) customUpdateTable(
ctx context.Context,
desired *resource,
@@ -212,6 +222,13 @@ func (rm *resourceManager) customUpdateTable(
}
}

if delta.DifferentAt("Spec.ContributorInsights") {
err = rm.updateContributorInsights(ctx, desired)
if err != nil {
return &resource{ko}, err
}
}

// We want to update fast fields first
// Then attributes
// then GSI
@@ -455,6 +472,9 @@ func (rm *resourceManager) setResourceAdditionalFields(
ko.Spec.ContinuousBackups = pitrSpec
}

if err = rm.setContributorInsights(ctx, ko); err != nil {
return err
}
return nil
}

@@ -590,6 +610,11 @@ func customPreCompare(
if a.ko.Spec.DeletionProtectionEnabled == nil {
a.ko.Spec.DeletionProtectionEnabled = aws.Bool(false)
}

if a.ko.Spec.ContributorInsights == nil && b.ko.Spec.ContributorInsights != nil &&
*b.ko.Spec.ContributorInsights == string(svcsdktypes.ContributorInsightsActionDisable) {
a.ko.Spec.ContributorInsights = b.ko.Spec.ContributorInsights
}
}

// equalAttributeDefinitions return whether two AttributeDefinition arrays are equal or not.
@@ -724,3 +749,68 @@ func equalLocalSecondaryIndexes(
}
return true
}

// setContributorInsights retrieves the table's cloudformationInsights
// configuration
func (rm *resourceManager) setContributorInsights(
ctx context.Context,
ko *svcapitypes.Table,
) (err error) {
rlog := ackrtlog.FromContext(ctx)
exit := rlog.Trace("rm.setCloudformationInsights")
defer func() {
exit(err)
}()

resp, err := rm.sdkapi.DescribeContributorInsights(
ctx,
&svcsdk.DescribeContributorInsightsInput{
TableName: ko.Spec.TableName,
},
)
rm.metrics.RecordAPICall("READ_ONE", "DescribeContributorInsights", err)
if err != nil {
return err
}

switch resp.ContributorInsightsStatus {
case svcsdktypes.ContributorInsightsStatusEnabled:
ko.Spec.ContributorInsights = aws.String(string(svcsdktypes.ContributorInsightsActionEnable))
case svcsdktypes.ContributorInsightsStatusDisabled:
ko.Spec.ContributorInsights = aws.String(string(svcsdktypes.ContributorInsightsActionDisable))
default:
ko.Spec.ContributorInsights = aws.String(string(resp.ContributorInsightsStatus))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about just ko.Spec.ContributorInsights = aws.String(string(resp.ContributorInsightsStatus)) are the other cases necessary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

describe returns: enabled, disabled, enabling, disabling
update accepts: enable, disable

converting them here makes the delta easier...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we just requeue if it's in a transition state and assume that if we reach this block of code it's either DISABLED or ENABLED?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the requeue is happening at the end of sdkFind..inside isTableContributorInsightsUpdating that i'm adding


}

return nil
}

func (rm *resourceManager) updateContributorInsights(
ctx context.Context,
r *resource,
) (err error) {
rlog := ackrtlog.FromContext(ctx)
exit := rlog.Trace("rm.updateCloudformationInsights")
defer func() {
exit(err)
}()
insight := svcsdktypes.ContributorInsightsActionDisable
if r.ko.Spec.ContributorInsights != nil {
insight = svcsdktypes.ContributorInsightsAction(*r.ko.Spec.ContributorInsights)
}

_, err = rm.sdkapi.UpdateContributorInsights(
ctx,
&svcsdk.UpdateContributorInsightsInput{
TableName: r.ko.Spec.TableName,
ContributorInsightsAction: insight,
},
)
rm.metrics.RecordAPICall("READ_ONE", "UpdateContributorInsights", err)
if err != nil {
return err
}

return nil
}
14 changes: 11 additions & 3 deletions pkg/resource/table/sdk.go

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

8 changes: 7 additions & 1 deletion templates/hooks/table/sdk_create_post_set_output.go.tpl
Original file line number Diff line number Diff line change
@@ -2,4 +2,10 @@
if err := rm.syncTTL(ctx, desired, &resource{ko}); err != nil {
return nil, err
}
}
}

if desired.ko.Spec.ContributorInsights != nil {
if err := rm.updateContributorInsights(ctx, desired); err != nil {
return nil, err
}
}
8 changes: 4 additions & 4 deletions templates/hooks/table/sdk_read_one_post_set_output.go.tpl
Original file line number Diff line number Diff line change
@@ -57,12 +57,12 @@
if isTableCreating(&resource{ko}) {
return &resource{ko}, requeueWaitWhileCreating
}
if isTableUpdating(&resource{ko}) {
return &resource{ko}, requeueWaitWhileUpdating
}
if !canUpdateTableGSIs(&resource{ko}) {
return &resource{ko}, requeueWaitGSIReady
}
if err := rm.setResourceAdditionalFields(ctx, ko); err != nil {
return nil, err
}
}
if isTableUpdating(&resource{ko}) || isTableContributorInsightsUpdating(&resource{ko}) {
return &resource{ko}, requeueWaitWhileUpdating
}
20 changes: 20 additions & 0 deletions test/e2e/resources/table_insights.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Table used to test multiple interfering updates at once
apiVersion: dynamodb.services.k8s.aws/v1alpha1
kind: Table
metadata:
name: $TABLE_NAME
spec:
tableName: $TABLE_NAME
billingMode: PAY_PER_REQUEST
tableClass: STANDARD
contributorInsights: ENABLE
attributeDefinitions:
- attributeName: Bill
attributeType: S
- attributeName: Total
attributeType: S
keySchema:
- attributeName: Bill
keyType: HASH
- attributeName: Total
keyType: RANGE
12 changes: 12 additions & 0 deletions test/e2e/table.py
Original file line number Diff line number Diff line change
@@ -236,6 +236,18 @@ def get(table_name):
except c.exceptions.ResourceNotFoundException:
return None

def get_insights(table_name):
"""Returns a dict containing the Role record from the IAM API.

If no such Table exists, returns None.
"""
c = boto3.client('dynamodb', region_name=get_region())
try:
resp = c.describe_contributor_insights(TableName=table_name)
return resp['ContributorInsightsStatus']
except c.exceptions.ResourceNotFoundException:
return None


def get_time_to_live(table_name):
"""Returns the TTL specification for the table with a supplied name.
Loading