-
Notifications
You must be signed in to change notification settings - Fork 4.3k
feat(s3-tables): add L2 construct support for Table and Namespace resources #35023
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
Changes from 6 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
c1d460c
Add S3Tables Namespace L2 construct
88c6cc4
Add Table L2 construct with tests
d8255fa
Add integration tests for Namespace and Table constructs
df946bf
Fix heading in README.md
9210524
Remove temporary assertion in namespace tests
9761bcb
Fix typos in name validations
09c5750
Update tests to reflect new naming errors
65cf1a9
Merge branch 'main' into tables-namespaces
xuxey e9f81a1
Address review comments around testing and docs
49342c9
Merge branch 'main' into tables-namespaces
xuxey 5dbaf2f
Add GetTableMaintenanceConfig Assertions in integration tests
865b3bf
Merge branch 'main' into tables-namespaces
mergify[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| import { Construct } from 'constructs'; | ||
| import { IResource, RemovalPolicy, Resource, Token, UnscopedValidationError } from 'aws-cdk-lib/core'; | ||
| import { ITableBucket } from './table-bucket'; | ||
| import { addConstructMetadata } from 'aws-cdk-lib/core/lib/metadata-resource'; | ||
| import { CfnNamespace } from 'aws-cdk-lib/aws-s3tables'; | ||
| import { EOL } from 'os'; | ||
|
|
||
| /** | ||
| * Represents an S3 Tables Namespace. | ||
| */ | ||
| export interface INamespace extends IResource { | ||
| /** | ||
| * The name of this namespace | ||
| * @attribute | ||
| */ | ||
| readonly namespaceName: string; | ||
|
|
||
| /** | ||
| * The table bucket which this namespace belongs to | ||
| * @attribute | ||
| */ | ||
| readonly tableBucket: ITableBucket; | ||
| } | ||
|
|
||
| /** | ||
| * Parameters for constructing a Namespace | ||
| */ | ||
| export interface NamespaceProps { | ||
| /** | ||
| * A name for the namespace | ||
| */ | ||
| readonly namespaceName: string; | ||
| /** | ||
| * The table bucket this namespace belongs to. | ||
| */ | ||
| readonly tableBucket: ITableBucket; | ||
| /** | ||
| * Policy to apply when the policy is removed from this stack. | ||
| * @default RemovalPolicy.DESTROY | ||
| */ | ||
| readonly removalPolicy?: RemovalPolicy; | ||
| } | ||
|
|
||
| /** | ||
| * Attributes for importing an existing namespace | ||
| */ | ||
| export interface NamespaceAttributes { | ||
| /** | ||
| * The name of the namespace | ||
| */ | ||
| readonly namespaceName: string; | ||
|
|
||
| /** | ||
| * The table bucket this namespace belongs to | ||
| */ | ||
| readonly tableBucket: ITableBucket; | ||
| } | ||
|
|
||
| /** | ||
| * An S3 Tables Namespace with helpers. | ||
| * | ||
| * A namespace is a logical container for tables within a table bucket. | ||
| */ | ||
| export class Namespace extends Resource implements INamespace { | ||
| /** | ||
| * Import an existing namespace from its attributes | ||
| */ | ||
| public static fromNamespaceAttributes(scope: Construct, id: string, attrs: NamespaceAttributes): INamespace { | ||
| class Import extends Resource implements INamespace { | ||
| public readonly namespaceName = attrs.namespaceName; | ||
| public readonly tableBucket = attrs.tableBucket; | ||
| } | ||
|
|
||
| return new Import(scope, id); | ||
| } | ||
| /** | ||
| * See https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-buckets-naming.html | ||
| * @param namespaceName Name of the namespace | ||
| * @throws UnscopedValidationError if any naming errors are detected | ||
| */ | ||
| public static validateNamespaceName(namespaceName: string) { | ||
| if (namespaceName == undefined || Token.isUnresolved(namespaceName)) { | ||
| // the name is a late-bound value, not a defined string, so skip validation | ||
| return; | ||
| } | ||
|
|
||
| const errors: string[] = []; | ||
|
|
||
| // Length validation | ||
| if (namespaceName.length < 1 || namespaceName.length > 255) { | ||
| errors.push( | ||
| 'Namespace name must be at least 1 and no more than 255 characters', | ||
| ); | ||
| } | ||
|
|
||
| // Character set validation | ||
| const illegalCharsetRegEx = /[^a-z0-9_]/; | ||
| const allowedEdgeCharsetRegEx = /[a-z0-9]/; | ||
|
|
||
| const illegalCharMatch = namespaceName.match(illegalCharsetRegEx); | ||
| if (illegalCharMatch) { | ||
| errors.push( | ||
| 'Namespace name must only contain lowercase characters, numbers, and underscores (_)' + | ||
| ` (offset: ${illegalCharMatch.index})`, | ||
| ); | ||
| } | ||
|
|
||
| // Edge character validation | ||
| if (!allowedEdgeCharsetRegEx.test(namespaceName.charAt(0))) { | ||
| errors.push( | ||
| 'Namespace name must start with a lowercase letter or number (offset: 0)', | ||
| ); | ||
| } | ||
| if ( | ||
| !allowedEdgeCharsetRegEx.test(namespaceName.charAt(namespaceName.length - 1)) | ||
| ) { | ||
| errors.push( | ||
| `Namespace name must end with a lowercase letter or number (offset: ${ | ||
| namespaceName.length - 1 | ||
| })`, | ||
| ); | ||
| } | ||
|
|
||
| if (namespaceName.startsWith('aws')) { | ||
| errors.push('Namespace name must not start with reserved prefix \'aws\''); | ||
| } | ||
|
|
||
| if (errors.length > 0) { | ||
| throw new UnscopedValidationError( | ||
| `Invalid S3 Tables namespace name (value: ${namespaceName})${EOL}${errors.join(EOL)}`, | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * @internal The underlying policy resource. | ||
xuxey marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| */ | ||
| private readonly _resource: CfnNamespace; | ||
|
|
||
| /** | ||
| * The name of this namespace | ||
| */ | ||
| public readonly namespaceName: string; | ||
|
|
||
| /** | ||
| * The table bucket which this namespace belongs to | ||
| */ | ||
| public readonly tableBucket: ITableBucket; | ||
|
|
||
| constructor(scope: Construct, id: string, props: NamespaceProps) { | ||
| super(scope, id); | ||
| // Enhanced CDK Analytics Telemetry | ||
| addConstructMetadata(this, props); | ||
|
|
||
| Namespace.validateNamespaceName(props.namespaceName); | ||
|
|
||
| this.tableBucket = props.tableBucket; | ||
| this.namespaceName = props.namespaceName; | ||
| this._resource = new CfnNamespace(this, id, { | ||
| namespace: props.namespaceName, | ||
| tableBucketArn: this.tableBucket.tableBucketArn, | ||
| }); | ||
|
|
||
| if (props.removalPolicy) { | ||
| this._resource.applyRemovalPolicy(props.removalPolicy); | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.