From e309a3fd90d082909a95eb79ca995e4a037866ad Mon Sep 17 00:00:00 2001 From: Markus Date: Sat, 20 Nov 2021 11:02:22 +0100 Subject: [PATCH] feat: first draft --- packages/@aws-cdk/aws-docdb/lib/cluster.ts | 24 ++++++++++++------- .../@aws-cdk/aws-docdb/lib/database-secret.ts | 15 ++++++++++-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/@aws-cdk/aws-docdb/lib/cluster.ts b/packages/@aws-cdk/aws-docdb/lib/cluster.ts index b71be1e321c2d..11d78f870406a 100644 --- a/packages/@aws-cdk/aws-docdb/lib/cluster.ts +++ b/packages/@aws-cdk/aws-docdb/lib/cluster.ts @@ -311,6 +311,11 @@ export class DatabaseCluster extends DatabaseClusterBase { */ public readonly secret?: secretsmanager.ISecret; + /** + * The secret attached to this cluster + */ + public readonly databaseSecret?: DatabaseSecret | undefined; + /** * The underlying CloudFormation resource for a database cluster. */ @@ -374,9 +379,8 @@ export class DatabaseCluster extends DatabaseClusterBase { } // Create the secret manager secret if no password is specified - let secret: DatabaseSecret | undefined; if (!props.masterUser.password) { - secret = new DatabaseSecret(this, 'Secret', { + this.databaseSecret = new DatabaseSecret(this, 'Secret', { username: props.masterUser.username, encryptionKey: props.masterUser.kmsKey, excludeCharacters: props.masterUser.excludeCharacters, @@ -401,9 +405,9 @@ export class DatabaseCluster extends DatabaseClusterBase { dbClusterParameterGroupName: props.parameterGroup?.parameterGroupName, deletionProtection: props.deletionProtection, // Admin - masterUsername: secret ? secret.secretValueFromJson('username').toString() : props.masterUser.username, - masterUserPassword: secret - ? secret.secretValueFromJson('password').toString() + masterUsername: this.secret ? this.secret.secretValueFromJson('username').toString() : props.masterUser.username, + masterUserPassword: this.secret + ? this.secret.secretValueFromJson('password').toString() : props.masterUser.password!.toString(), // Backup backupRetentionPeriod: props.backup?.retention?.toDays(), @@ -427,8 +431,8 @@ export class DatabaseCluster extends DatabaseClusterBase { this.clusterEndpoint = new Endpoint(this.cluster.attrEndpoint, port); this.clusterReadEndpoint = new Endpoint(this.cluster.attrReadEndpoint, port); - if (secret) { - this.secret = secret.attach(this); + if (this.databaseSecret) { + this.secret = this.databaseSecret.attach(this); } // Create the instances @@ -476,7 +480,7 @@ export class DatabaseCluster extends DatabaseClusterBase { * before Secrets Manager triggers the next automatic rotation. */ public addRotationSingleUser(automaticallyAfter?: Duration): secretsmanager.SecretRotation { - if (!this.secret) { + if (!this.secret || !this.databaseSecret) { throw new Error('Cannot add single user rotation for a cluster without secret.'); } @@ -490,6 +494,7 @@ export class DatabaseCluster extends DatabaseClusterBase { secret: this.secret, automaticallyAfter, application: DatabaseCluster.SINGLE_USER_ROTATION_APPLICATION, + excludeCharacters: this.databaseSecret.excludedCharacters, vpc: this.vpc, vpcSubnets: this.vpcSubnets, target: this, @@ -500,13 +505,14 @@ export class DatabaseCluster extends DatabaseClusterBase { * Adds the multi user rotation to this cluster. */ public addRotationMultiUser(id: string, options: RotationMultiUserOptions): secretsmanager.SecretRotation { - if (!this.secret) { + if (!this.secret || !this.databaseSecret) { throw new Error('Cannot add multi user rotation for a cluster without secret.'); } return new secretsmanager.SecretRotation(this, id, { secret: options.secret, masterSecret: this.secret, automaticallyAfter: options.automaticallyAfter, + excludeCharacters: this.databaseSecret.excludedCharacters, application: DatabaseCluster.MULTI_USER_ROTATION_APPLICATION, vpc: this.vpc, vpcSubnets: this.vpcSubnets, diff --git a/packages/@aws-cdk/aws-docdb/lib/database-secret.ts b/packages/@aws-cdk/aws-docdb/lib/database-secret.ts index 8f1bca671da6d..d15ca413fedb5 100644 --- a/packages/@aws-cdk/aws-docdb/lib/database-secret.ts +++ b/packages/@aws-cdk/aws-docdb/lib/database-secret.ts @@ -36,7 +36,7 @@ export interface DatabaseSecretProps { /** * Characters to not include in the generated password. * - * @default "\"@/" + * @default '\"@/' */ readonly excludeCharacters?: string; } @@ -48,7 +48,16 @@ export interface DatabaseSecretProps { * @resource AWS::SecretsManager::Secret */ export class DatabaseSecret extends Secret { + + /** + * the excluded characters for this Secret + */ + readonly excludedCharacters: string; + constructor(scope: Construct, id: string, props: DatabaseSecretProps) { + + const excludedCharacters = props.excludeCharacters ?? '"@/'; + super(scope, id, { secretName: props.secretName, description: `Generated by the CDK for stack: ${Aws.STACK_NAME}`, @@ -68,8 +77,10 @@ export class DatabaseSecret extends Secret { masterarn: props.masterSecret?.secretArn, }), generateStringKey: 'password', - excludeCharacters: props.excludeCharacters ?? '"@/', + excludeCharacters: excludedCharacters, }, }); + + this.excludedCharacters = excludedCharacters; } }