Skip to content

Commit d0b074a

Browse files
authored
feat(dynamodb): add TableGrants and StreamGrants (#36093)
### What is changing? This PR introduces two new classes, `TableGrants` and `StreamGrants`, that allow the assignment of permissions, in a uniform way, to both L1s and L2s: ```ts const table = new Table(...); // or new CfnTable(...) const role = new Role(...); // Allow the role to read data from the table const grant = TableGrants._fromTable(table).readData(role); ``` To make the interface more similar to the auto-generated grants (e.g., `TopicGrants`), `TableGrants._fromTable()` takes a new interface, `IIndexableRegionalTable` as a parameter. ```ts export interface IIndexableRegionalTable extends ITableRef { /** * Additional regions other than the main one that this table is replicated to * * @default no regions */ readonly regions?: string[]; /** * Whether this table has indexes * * If so, permissions are granted on all table indexes as well. * * @default false */ readonly hasIndex?: boolean; } ``` And now `TableBase` implements `IIndexableRegionalTable`. `TableBase` has also gained two additional public immutable properties: `grants` and `streamGrants`, that should be used to grant permissions on a table. The existing `grant*()` methods will be deprecated soon. ### Why did the integration test templates change? The current implementation uses `Lazy.string()` to produce the regional ARNs. Since the `produce()` method has to return _something_, it returned `Aws.NO_VALUE` when there was no real value to produce. In `TableGrants`, by contrast, the ARNs are computed eagerly in the constructor, so there is no need for pseudo-values. This is what caused the integration test templates to change. There are additional changes that are purely in the order of JSON properties. ### Why does `StreamGrants` not have a `_fromStream()` static method? Unlike table, a table stream is not a resource in CloudFormation. So, although we could try to mimic one, by creating interfaces like `ITableStream`, `ITableStreamRef`, `TableStreamReference`, there is nothing to gain from it. The consumer would still have to assemble an object from properties of a `Table` of `CfnTable` anyway. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 183ec35 commit d0b074a

File tree

39 files changed

+5310
-6548
lines changed

39 files changed

+5310
-6548
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda-connect-disconnect-trigger.js.snapshot/integ-apigwv2-lambda-connect-integration.template.json

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,12 @@
5252
"dynamodb:UpdateItem"
5353
],
5454
"Effect": "Allow",
55-
"Resource": [
56-
{
57-
"Fn::GetAtt": [
58-
"WebSocketLogTable7F74AAC5",
59-
"Arn"
60-
]
61-
},
62-
{
63-
"Ref": "AWS::NoValue"
64-
}
65-
]
55+
"Resource": {
56+
"Fn::GetAtt": [
57+
"WebSocketLogTable7F74AAC5",
58+
"Arn"
59+
]
60+
}
6661
}
6762
],
6863
"Version": "2012-10-17"
@@ -97,7 +92,7 @@
9792
"Arn"
9893
]
9994
},
100-
"Runtime": "nodejs14.x",
95+
"Runtime": "nodejs22.x",
10196
"Timeout": 5
10297
},
10398
"DependsOn": [
@@ -157,17 +152,12 @@
157152
"dynamodb:UpdateItem"
158153
],
159154
"Effect": "Allow",
160-
"Resource": [
161-
{
162-
"Fn::GetAtt": [
163-
"WebSocketLogTable7F74AAC5",
164-
"Arn"
165-
]
166-
},
167-
{
168-
"Ref": "AWS::NoValue"
169-
}
170-
]
155+
"Resource": {
156+
"Fn::GetAtt": [
157+
"WebSocketLogTable7F74AAC5",
158+
"Arn"
159+
]
160+
}
171161
}
172162
],
173163
"Version": "2012-10-17"
@@ -202,7 +192,7 @@
202192
"Arn"
203193
]
204194
},
205-
"Runtime": "nodejs14.x",
195+
"Runtime": "nodejs22.x",
206196
"Timeout": 5
207197
},
208198
"DependsOn": [

packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda-connect-disconnect-trigger.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const webSocketTableName = 'WebSocketConnections';
1717

1818
const connectFunction = new lambda.Function(stack, 'Connect Function', {
1919
functionName: 'process_connect_requests',
20-
runtime: lambda.Runtime.NODEJS_14_X,
20+
runtime: lambda.Runtime.NODEJS_22_X,
2121
handler: 'index.handler',
2222
code: lambda.Code.fromAsset(path.join(__dirname, 'lambdas', 'connect')),
2323
timeout: cdk.Duration.seconds(5),
@@ -31,7 +31,7 @@ const disconnectFunction = new lambda.Function(
3131
'Disconnect Function',
3232
{
3333
functionName: 'process_disconnect_requests',
34-
runtime: lambda.Runtime.NODEJS_14_X,
34+
runtime: lambda.Runtime.NODEJS_22_X,
3535
handler: 'index.handler',
3636
code: lambda.Code.fromAsset(
3737
path.join(__dirname, 'lambdas', 'disconnect'),

packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.appsync-eventapi-dynamodb.js.snapshot/EventApiDynamoDBStack.template.json

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,12 @@
7777
"dynamodb:UpdateItem"
7878
],
7979
"Effect": "Allow",
80-
"Resource": [
81-
{
82-
"Fn::GetAtt": [
83-
"table8235A42E",
84-
"Arn"
85-
]
86-
},
87-
{
88-
"Ref": "AWS::NoValue"
89-
}
90-
]
80+
"Resource": {
81+
"Fn::GetAtt": [
82+
"table8235A42E",
83+
"Arn"
84+
]
85+
}
9186
}
9287
],
9388
"Version": "2012-10-17"

packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.auth-apikey.js.snapshot/aws-appsync-integ.assets.json

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

packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.auth-apikey.js.snapshot/aws-appsync-integ.template.json

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,12 @@
7171
"dynamodb:UpdateItem"
7272
],
7373
"Effect": "Allow",
74-
"Resource": [
75-
{
76-
"Fn::GetAtt": [
77-
"TestTable5769773A",
78-
"Arn"
79-
]
80-
},
81-
{
82-
"Ref": "AWS::NoValue"
83-
}
84-
]
74+
"Resource": {
75+
"Fn::GetAtt": [
76+
"TestTable5769773A",
77+
"Arn"
78+
]
79+
}
8580
}
8681
],
8782
"Version": "2012-10-17"
@@ -103,8 +98,6 @@
10398
"ApiId"
10499
]
105100
},
106-
"Name": "testDataSource",
107-
"Type": "AMAZON_DYNAMODB",
108101
"DynamoDBConfig": {
109102
"AwsRegion": {
110103
"Ref": "AWS::Region"
@@ -113,12 +106,14 @@
113106
"Ref": "TestTable5769773A"
114107
}
115108
},
109+
"Name": "testDataSource",
116110
"ServiceRoleArn": {
117111
"Fn::GetAtt": [
118112
"ApitestDataSourceServiceRoleACBC3F3D",
119113
"Arn"
120114
]
121-
}
115+
},
116+
"Type": "AMAZON_DYNAMODB"
122117
}
123118
},
124119
"ApiQueryGetTestsF8C40170": {
@@ -130,12 +125,12 @@
130125
"ApiId"
131126
]
132127
},
133-
"FieldName": "getTests",
134-
"TypeName": "Query",
135128
"DataSourceName": "testDataSource",
129+
"FieldName": "getTests",
136130
"Kind": "UNIT",
137131
"RequestMappingTemplate": "{\"version\" : \"2017-02-28\", \"operation\" : \"Scan\", \"consistentRead\": false}",
138-
"ResponseMappingTemplate": "$util.toJson($ctx.result.items)"
132+
"ResponseMappingTemplate": "$util.toJson($ctx.result.items)",
133+
"TypeName": "Query"
139134
},
140135
"DependsOn": [
141136
"ApiSchema510EECD7",
@@ -151,12 +146,12 @@
151146
"ApiId"
152147
]
153148
},
154-
"FieldName": "addTest",
155-
"TypeName": "Mutation",
156149
"DataSourceName": "testDataSource",
150+
"FieldName": "addTest",
157151
"Kind": "UNIT",
158152
"RequestMappingTemplate": "\n #set($input = $ctx.args.test)\n \n {\n \"version\": \"2017-02-28\",\n \"operation\": \"PutItem\",\n \"key\" : {\n \"id\" : $util.dynamodb.toDynamoDBJson($util.autoId())\n },\n \"attributeValues\": $util.dynamodb.toMapValuesJson($input)\n }",
159-
"ResponseMappingTemplate": "$util.toJson($ctx.result)"
153+
"ResponseMappingTemplate": "$util.toJson($ctx.result)",
154+
"TypeName": "Mutation"
160155
},
161156
"DependsOn": [
162157
"ApiSchema510EECD7",
@@ -166,19 +161,19 @@
166161
"TestTable5769773A": {
167162
"Type": "AWS::DynamoDB::Table",
168163
"Properties": {
169-
"KeySchema": [
164+
"AttributeDefinitions": [
170165
{
171166
"AttributeName": "id",
172-
"KeyType": "HASH"
167+
"AttributeType": "S"
173168
}
174169
],
175-
"AttributeDefinitions": [
170+
"BillingMode": "PAY_PER_REQUEST",
171+
"KeySchema": [
176172
{
177173
"AttributeName": "id",
178-
"AttributeType": "S"
174+
"KeyType": "HASH"
179175
}
180-
],
181-
"BillingMode": "PAY_PER_REQUEST"
176+
]
182177
},
183178
"UpdateReplacePolicy": "Delete",
184179
"DeletionPolicy": "Delete"

packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.auth-apikey.js.snapshot/cdk.out

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.auth-apikey.js.snapshot/integ.json

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

0 commit comments

Comments
 (0)