UNPKG

aws-cdk-lib

Version:

Version 2 of the AWS Cloud Development Kit library

6 lines (5 loc) 37.2 kB
"use strict";var __decorate=exports&&exports.__decorate||function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r},_a,_b,_c;Object.defineProperty(exports,"__esModule",{value:!0}),exports.DatabaseClusterFromSnapshot=exports.DatabaseCluster=exports.DatabaseClusterBase=exports.DatabaseInsightsMode=exports.ClusterScailabilityType=exports.ClusterScalabilityType=exports.InstanceUpdateBehaviour=exports.DBClusterStorageType=exports.EngineLifecycleSupport=void 0;var jsiiDeprecationWarnings=()=>{var tmp=require("../../.warnings.jsii.js");return jsiiDeprecationWarnings=()=>tmp,tmp};const JSII_RTTI_SYMBOL_1=Symbol.for("jsii.rtti");var aurora_cluster_instance_1=()=>{var tmp=require("./aurora-cluster-instance");return aurora_cluster_instance_1=()=>tmp,tmp},endpoint_1=()=>{var tmp=require("./endpoint");return endpoint_1=()=>tmp,tmp},parameter_group_1=()=>{var tmp=require("./parameter-group");return parameter_group_1=()=>tmp,tmp},perms_1=()=>{var tmp=require("./perms");return perms_1=()=>tmp,tmp},util_1=()=>{var tmp=require("./private/util");return util_1=()=>tmp,tmp},props_1=()=>{var tmp=require("./props");return props_1=()=>tmp,tmp},proxy_1=()=>{var tmp=require("./proxy");return proxy_1=()=>tmp,tmp},rds_generated_1=()=>{var tmp=require("./rds.generated");return rds_generated_1=()=>tmp,tmp},subnet_group_1=()=>{var tmp=require("./subnet-group");return subnet_group_1=()=>tmp,tmp},validate_database_cluster_props_1=()=>{var tmp=require("./validate-database-cluster-props");return validate_database_cluster_props_1=()=>tmp,tmp},ec2=()=>{var tmp=require("../../aws-ec2");return ec2=()=>tmp,tmp},iam=()=>{var tmp=require("../../aws-iam");return iam=()=>tmp,tmp},aws_iam_1=()=>{var tmp=require("../../aws-iam");return aws_iam_1=()=>tmp,tmp},logs=()=>{var tmp=require("../../aws-logs");return logs=()=>tmp,tmp},secretsmanager=()=>{var tmp=require("../../aws-secretsmanager");return secretsmanager=()=>tmp,tmp},core_1=()=>{var tmp=require("../../core");return core_1=()=>tmp,tmp},errors_1=()=>{var tmp=require("../../core/lib/errors");return errors_1=()=>tmp,tmp},metadata_resource_1=()=>{var tmp=require("../../core/lib/metadata-resource");return metadata_resource_1=()=>tmp,tmp},prop_injectable_1=()=>{var tmp=require("../../core/lib/prop-injectable");return prop_injectable_1=()=>tmp,tmp},cxapi=()=>{var tmp=require("../../cx-api");return cxapi=()=>tmp,tmp},EngineLifecycleSupport;(function(EngineLifecycleSupport2){EngineLifecycleSupport2.OPEN_SOURCE_RDS_EXTENDED_SUPPORT="open-source-rds-extended-support",EngineLifecycleSupport2.OPEN_SOURCE_RDS_EXTENDED_SUPPORT_DISABLED="open-source-rds-extended-support-disabled"})(EngineLifecycleSupport||(exports.EngineLifecycleSupport=EngineLifecycleSupport={}));var DBClusterStorageType;(function(DBClusterStorageType2){DBClusterStorageType2.AURORA="aurora",DBClusterStorageType2.AURORA_IOPT1="aurora-iopt1"})(DBClusterStorageType||(exports.DBClusterStorageType=DBClusterStorageType={}));var InstanceUpdateBehaviour;(function(InstanceUpdateBehaviour2){InstanceUpdateBehaviour2.BULK="BULK",InstanceUpdateBehaviour2.ROLLING="ROLLING"})(InstanceUpdateBehaviour||(exports.InstanceUpdateBehaviour=InstanceUpdateBehaviour={}));var ClusterScalabilityType;(function(ClusterScalabilityType2){ClusterScalabilityType2.STANDARD="standard",ClusterScalabilityType2.LIMITLESS="limitless"})(ClusterScalabilityType||(exports.ClusterScalabilityType=ClusterScalabilityType={}));var ClusterScailabilityType;(function(ClusterScailabilityType2){ClusterScailabilityType2.STANDARD="standard",ClusterScailabilityType2.LIMITLESS="limitless"})(ClusterScailabilityType||(exports.ClusterScailabilityType=ClusterScailabilityType={}));var DatabaseInsightsMode;(function(DatabaseInsightsMode2){DatabaseInsightsMode2.STANDARD="standard",DatabaseInsightsMode2.ADVANCED="advanced"})(DatabaseInsightsMode||(exports.DatabaseInsightsMode=DatabaseInsightsMode={}));class DatabaseClusterBase extends core_1().Resource{get clusterArn(){return core_1().Stack.of(this).formatArn({service:"rds",resource:"cluster",arnFormat:core_1().ArnFormat.COLON_RESOURCE_NAME,resourceName:this.clusterIdentifier})}addProxy(id,options){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_rds_DatabaseProxyOptions(options)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.addProxy),error}return new(proxy_1()).DatabaseProxy(this,id,{proxyTarget:proxy_1().ProxyTarget.fromCluster(this),...options})}asSecretAttachmentTarget(){return{targetId:this.clusterIdentifier,targetType:secretsmanager().AttachmentTargetType.RDS_DB_CLUSTER}}grantConnect(grantee,dbUser){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_iam_IGrantable(grantee)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.grantConnect),error}return iam().Grant.addToPrincipal({actions:["rds-db:connect"],grantee,resourceArns:[core_1().Stack.of(this).formatArn({service:"rds-db",resource:"dbuser",resourceName:`${this.clusterResourceIdentifier}/${dbUser}`,arnFormat:core_1().ArnFormat.COLON_RESOURCE_NAME})]})}grantDataApiAccess(grantee){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_iam_IGrantable(grantee)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.grantDataApiAccess),error}if(this.enableDataApi===!1)throw new(errors_1()).ValidationError("Cannot grant Data API access when the Data API is disabled",this);this.enableDataApi=!0;const ret=iam().Grant.addToPrincipal({grantee,actions:perms_1().DATA_API_ACTIONS,resourceArns:[this.clusterArn],scope:this});return this.secret?.grantRead(grantee),ret}}exports.DatabaseClusterBase=DatabaseClusterBase,_a=JSII_RTTI_SYMBOL_1,DatabaseClusterBase[_a]={fqn:"aws-cdk-lib.aws_rds.DatabaseClusterBase",version:"2.202.0"};class DatabaseClusterNew extends DatabaseClusterBase{constructor(scope,id,props){if(super(scope,id),props.clusterScalabilityType!==void 0&&props.clusterScailabilityType!==void 0)throw new(errors_1()).ValidationError("You cannot specify both clusterScalabilityType and clusterScailabilityType (deprecated). Use clusterScalabilityType.",this);if(props.vpc&&props.instanceProps?.vpc||!props.vpc&&!props.instanceProps?.vpc)throw new(errors_1()).ValidationError("Provide either vpc or instanceProps.vpc, but not both",this);if(props.vpcSubnets&&props.instanceProps?.vpcSubnets)throw new(errors_1()).ValidationError("Provide either vpcSubnets or instanceProps.vpcSubnets, but not both",this);this.vpc=props.instanceProps?.vpc??props.vpc,this.vpcSubnets=props.instanceProps?.vpcSubnets??props.vpcSubnets,this.cloudwatchLogGroups={},this.singleUserRotationApplication=props.engine.singleUserRotationApplication,this.multiUserRotationApplication=props.engine.multiUserRotationApplication,this.serverlessV2MaxCapacity=props.serverlessV2MaxCapacity??2,this.serverlessV2MinCapacity=props.serverlessV2MinCapacity??.5,this.serverlessV2AutoPauseDuration=props.serverlessV2AutoPauseDuration,this.enableDataApi=props.enableDataApi;const{subnetIds}=this.vpc.selectSubnets(this.vpcSubnets);subnetIds.length<2&&core_1().Annotations.of(this).addError(`Cluster requires at least 2 subnets, got ${subnetIds.length}`),this.subnetGroup=props.subnetGroup??new(subnet_group_1()).SubnetGroup(this,"Subnets",{description:`Subnets for ${id} database`,vpc:this.vpc,vpcSubnets:this.vpcSubnets,removalPolicy:(0,util_1().renderUnless)((0,util_1().helperRemovalPolicy)(props.removalPolicy),core_1().RemovalPolicy.DESTROY)}),this.securityGroups=props.instanceProps?.securityGroups??props.securityGroups??[new(ec2()).SecurityGroup(this,"SecurityGroup",{description:"RDS security group",vpc:this.vpc})];const combineRoles=props.engine.combineImportAndExportRoles??!1;let{s3ImportRole,s3ExportRole}=(0,util_1().setupS3ImportExport)(this,props,combineRoles);if(props.parameterGroup&&props.parameters)throw new(errors_1()).ValidationError("You cannot specify both parameterGroup and parameters",this);const parameterGroup=props.parameterGroup??(props.parameters?new(parameter_group_1()).ParameterGroup(this,"ParameterGroup",{engine:props.engine,parameters:props.parameters}):void 0),clusterEngineBindConfig=props.engine.bindToCluster(this,{s3ImportRole,s3ExportRole,parameterGroup}),clusterAssociatedRoles=[];s3ImportRole&&clusterAssociatedRoles.push({roleArn:s3ImportRole.roleArn,featureName:clusterEngineBindConfig.features?.s3Import}),s3ExportRole&&(s3ExportRole!==s3ImportRole||clusterEngineBindConfig.features?.s3Import!==clusterEngineBindConfig.features?.s3Export)&&clusterAssociatedRoles.push({roleArn:s3ExportRole.roleArn,featureName:clusterEngineBindConfig.features?.s3Export});const clusterParameterGroupConfig=(props.parameterGroup??clusterEngineBindConfig.parameterGroup)?.bindToCluster({});this.engine=props.engine;const clusterIdentifier=core_1().FeatureFlags.of(this).isEnabled(cxapi().RDS_LOWERCASE_DB_IDENTIFIER)&&!core_1().Token.isUnresolved(props.clusterIdentifier)?props.clusterIdentifier?.toLowerCase():props.clusterIdentifier;props.domain&&(this.domainId=props.domain,this.domainRole=props.domainRole??new(iam()).Role(this,"RDSClusterDirectoryServiceRole",{assumedBy:new(iam()).CompositePrincipal(new(iam()).ServicePrincipal("rds.amazonaws.com"),new(iam()).ServicePrincipal("directoryservice.rds.amazonaws.com")),managedPolicies:[iam().ManagedPolicy.fromAwsManagedPolicyName("service-role/AmazonRDSDirectoryServiceAccess")]})),(0,validate_database_cluster_props_1().validateDatabaseClusterProps)(this,props),this.validateServerlessScalingConfig(clusterEngineBindConfig);const enablePerformanceInsights=props.enablePerformanceInsights||props.performanceInsightRetention!==void 0||props.performanceInsightEncryptionKey!==void 0||props.databaseInsightsMode===DatabaseInsightsMode.ADVANCED;if(this.performanceInsightsEnabled=enablePerformanceInsights,this.performanceInsightRetention=enablePerformanceInsights?props.performanceInsightRetention||props_1().PerformanceInsightRetention.DEFAULT:void 0,this.performanceInsightEncryptionKey=props.performanceInsightEncryptionKey,this.databaseInsightsMode=props.databaseInsightsMode,this.monitoringRole=props.monitoringRole,!props.monitoringRole&&props.monitoringInterval&&props.monitoringInterval.toSeconds()&&(this.monitoringRole=new(aws_iam_1()).Role(this,"MonitoringRole",{assumedBy:new(aws_iam_1()).ServicePrincipal("monitoring.rds.amazonaws.com"),managedPolicies:[aws_iam_1().ManagedPolicy.fromAwsManagedPolicyName("service-role/AmazonRDSEnhancedMonitoringRole")]})),props.enableClusterLevelEnhancedMonitoring&&!props.monitoringInterval)throw new(errors_1()).ValidationError("`monitoringInterval` must be set when `enableClusterLevelEnhancedMonitoring` is true.",this);if(props.monitoringInterval&&!props.monitoringInterval.isUnresolved()&&[0,1,5,10,15,30,60].indexOf(props.monitoringInterval.toSeconds())===-1)throw new(errors_1()).ValidationError(`'monitoringInterval' must be one of 0, 1, 5, 10, 15, 30, or 60 seconds, got: ${props.monitoringInterval.toSeconds()} seconds.`,this);this.newCfnProps={engine:props.engine.engineType,engineVersion:props.engine.engineVersion?.fullVersion,dbClusterIdentifier:clusterIdentifier,dbSubnetGroupName:this.subnetGroup.subnetGroupName,vpcSecurityGroupIds:this.securityGroups.map(sg=>sg.securityGroupId),port:props.port??clusterEngineBindConfig.port,dbClusterParameterGroupName:clusterParameterGroupConfig?.parameterGroupName,associatedRoles:clusterAssociatedRoles.length>0?clusterAssociatedRoles:void 0,deletionProtection:(0,util_1().defaultDeletionProtection)(props.deletionProtection,props.removalPolicy),enableIamDatabaseAuthentication:props.iamAuthentication,enableHttpEndpoint:core_1().Lazy.any({produce:()=>this.enableDataApi}),networkType:props.networkType,serverlessV2ScalingConfiguration:core_1().Lazy.any({produce:()=>{if(this.hasServerlessInstance)return{minCapacity:this.serverlessV2MinCapacity,maxCapacity:this.serverlessV2MaxCapacity,secondsUntilAutoPause:this.serverlessV2AutoPauseDuration?.toSeconds()}}}),storageType:props.storageType?.toString(),enableLocalWriteForwarding:props.enableLocalWriteForwarding,clusterScalabilityType:props.clusterScalabilityType??props.clusterScailabilityType,backtrackWindow:props.backtrackWindow?.toSeconds(),backupRetentionPeriod:props.backup?.retention?.toDays(),preferredBackupWindow:props.backup?.preferredWindow,preferredMaintenanceWindow:props.preferredMaintenanceWindow,databaseName:props.defaultDatabaseName,enableCloudwatchLogsExports:props.cloudwatchLogsExports,kmsKeyId:props.storageEncryptionKey?.keyArn,storageEncrypted:props.storageEncryptionKey?!0:props.storageEncrypted,copyTagsToSnapshot:props.copyTagsToSnapshot??!0,domain:this.domainId,domainIamRoleName:this.domainRole?.roleName,performanceInsightsEnabled:this.performanceInsightsEnabled||props.enablePerformanceInsights,performanceInsightsKmsKeyId:this.performanceInsightEncryptionKey?.keyArn,performanceInsightsRetentionPeriod:this.performanceInsightRetention,databaseInsightsMode:this.databaseInsightsMode,autoMinorVersionUpgrade:props.autoMinorVersionUpgrade,monitoringInterval:props.enableClusterLevelEnhancedMonitoring?props.monitoringInterval?.toSeconds():void 0,monitoringRoleArn:props.enableClusterLevelEnhancedMonitoring?this.monitoringRole?.roleArn:void 0,engineLifecycleSupport:props.engineLifecycleSupport}}_createInstances(props){const instanceEndpoints=[],instanceIdentifiers=[],readers=[],writer=props.writer.bind(this,this,{monitoringInterval:props.enableClusterLevelEnhancedMonitoring?void 0:props.monitoringInterval,monitoringRole:props.enableClusterLevelEnhancedMonitoring?void 0:this.monitoringRole,removalPolicy:props.removalPolicy??core_1().RemovalPolicy.SNAPSHOT,subnetGroup:this.subnetGroup,promotionTier:0});return instanceIdentifiers.push(writer.instanceIdentifier),instanceEndpoints.push(new(endpoint_1()).Endpoint(writer.dbInstanceEndpointAddress,this.clusterEndpoint.port)),(props.readers??[]).forEach(instance=>{const clusterInstance=instance.bind(this,this,{monitoringInterval:props.enableClusterLevelEnhancedMonitoring?void 0:props.monitoringInterval,monitoringRole:props.enableClusterLevelEnhancedMonitoring?void 0:this.monitoringRole,removalPolicy:props.removalPolicy??core_1().RemovalPolicy.SNAPSHOT,subnetGroup:this.subnetGroup});readers.push(clusterInstance),clusterInstance.node.addDependency(writer),clusterInstance.tier<2&&this.validateReaderInstance(writer,clusterInstance),instanceEndpoints.push(new(endpoint_1()).Endpoint(clusterInstance.dbInstanceEndpointAddress,this.clusterEndpoint.port)),instanceIdentifiers.push(clusterInstance.instanceIdentifier)}),this.validateClusterInstances(writer,readers),{instanceEndpoints,instanceIdentifiers}}validateClusterInstances(writer,readers){if(writer.type===aurora_cluster_instance_1().InstanceType.SERVERLESS_V2&&(this.hasServerlessInstance=!0),validatePerformanceInsightsSettings(this,{nodeId:writer.node.id,performanceInsightsEnabled:writer.performanceInsightsEnabled,performanceInsightRetention:writer.performanceInsightRetention,performanceInsightEncryptionKey:writer.performanceInsightEncryptionKey}),readers.length>0){const sortedReaders=readers.sort((a,b)=>a.tier-b.tier),highestTierReaders=[],highestTier=sortedReaders[0].tier;let hasProvisionedReader=!1,noFailoverTierInstances=!0,serverlessInHighestTier=!1,hasServerlessReader=!1;const someProvisionedReadersDontMatchWriter=[];for(const reader of sortedReaders)reader.type===aurora_cluster_instance_1().InstanceType.SERVERLESS_V2?(hasServerlessReader=!0,this.hasServerlessInstance=!0):(hasProvisionedReader=!0,reader.instanceSize!==writer.instanceSize&&someProvisionedReadersDontMatchWriter.push(reader)),reader.tier===highestTier&&(reader.type===aurora_cluster_instance_1().InstanceType.SERVERLESS_V2&&(serverlessInHighestTier=!0),highestTierReaders.push(reader)),reader.tier<=1&&(noFailoverTierInstances=!1),validatePerformanceInsightsSettings(this,{nodeId:reader.node.id,performanceInsightsEnabled:reader.performanceInsightsEnabled,performanceInsightRetention:reader.performanceInsightRetention,performanceInsightEncryptionKey:reader.performanceInsightEncryptionKey});hasServerlessReader&&!hasProvisionedReader?noFailoverTierInstances&&core_1().Annotations.of(this).addWarningV2("@aws-cdk/aws-rds:noFailoverServerlessReaders",`Cluster ${this.node.id} only has serverless readers and no reader is in promotion tier 0-1.Serverless readers in promotion tiers >= 2 will NOT scale with the writer, which can lead to availability issues if a failover event occurs. It is recommended that at least one reader has \`scaleWithWriter\` set to true`):(serverlessInHighestTier&&highestTier>1&&core_1().Annotations.of(this).addWarningV2("@aws-cdk/aws-rds:serverlessInHighestTier2-15",`There are serverlessV2 readers in tier ${highestTier}. Since there are no instances in a higher tier, any instance in this tier is a failover target. Since this tier is > 1 the serverless reader will not scale with the writer which could lead to availability issues during failover.`),someProvisionedReadersDontMatchWriter.length>0&&writer.type===aurora_cluster_instance_1().InstanceType.PROVISIONED&&core_1().Annotations.of(this).addWarningV2("@aws-cdk/aws-rds:provisionedReadersDontMatchWriter",`There are provisioned readers in the highest promotion tier ${highestTier} that do not have the same InstanceSize as the writer. Any of these instances could be chosen as the new writer in the event of a failover. Writer InstanceSize: ${writer.instanceSize} Reader InstanceSizes: ${someProvisionedReadersDontMatchWriter.map(reader=>reader.instanceSize).join(", ")}`))}}validateReaderInstance(writer,reader){writer.type===aurora_cluster_instance_1().InstanceType.PROVISIONED&&reader.type===aurora_cluster_instance_1().InstanceType.SERVERLESS_V2&&(instanceSizeSupportedByServerlessV2(writer.instanceSize,this.serverlessV2MaxCapacity)||core_1().Annotations.of(this).addWarningV2("@aws-cdk/aws-rds:serverlessInstanceCantScaleWithWriter",`For high availability any serverless instances in promotion tiers 0-1 should be able to scale to match the provisioned instance capacity. Serverless instance ${reader.node.id} is in promotion tier ${reader.tier}, But can not scale to match the provisioned writer instance (${writer.instanceSize})`))}metricServerlessDatabaseCapacity(props){return this.metric("ServerlessDatabaseCapacity",{statistic:"Average",...props})}metricACUUtilization(props){return this.metric("ACUUtilization",{statistic:"Average",...props})}validateServerlessScalingConfig(config){if(this.serverlessV2MaxCapacity>256||this.serverlessV2MaxCapacity<1)throw new(errors_1()).ValidationError("serverlessV2MaxCapacity must be >= 1 & <= 256",this);if(this.serverlessV2MinCapacity>256||this.serverlessV2MinCapacity<0)throw new(errors_1()).ValidationError("serverlessV2MinCapacity must be >= 0 & <= 256",this);if(this.serverlessV2MaxCapacity<this.serverlessV2MinCapacity)throw new(errors_1()).ValidationError("serverlessV2MaxCapacity must be greater than serverlessV2MinCapacity",this);const regexp=new RegExp(/^[0-9]+\.?5?$/);if(!regexp.test(this.serverlessV2MaxCapacity.toString())||!regexp.test(this.serverlessV2MinCapacity.toString()))throw new(errors_1()).ValidationError(`serverlessV2MinCapacity & serverlessV2MaxCapacity must be in 0.5 step increments, received min: ${this.serverlessV2MaxCapacity}, max: ${this.serverlessV2MaxCapacity}`,this);if(this.serverlessV2AutoPauseDuration){if(!config.features?.serverlessV2AutoPauseSupported)throw new(errors_1()).ValidationError(`serverlessV2 auto-pause feature is not supported by ${this.engine?.engineType} ${this.engine?.engineVersion?.fullVersion}.`,this);if(!this.serverlessV2AutoPauseDuration.isUnresolved()&&(this.serverlessV2AutoPauseDuration.toSeconds()<300||this.serverlessV2AutoPauseDuration.toSeconds()>86400))throw new(errors_1()).ValidationError(`serverlessV2AutoPause must be between 300 seconds (5 minutes) and 86,400 seconds (24 hours), received ${this.serverlessV2AutoPauseDuration.toSeconds()} seconds`,this)}}addRotationSingleUser(options={}){if(!this.secret)throw new(errors_1()).ValidationError("Cannot add a single user rotation for a cluster without a secret.",this);const id="RotationSingleUser";if(this.node.tryFindChild(id))throw new(errors_1()).ValidationError("A single user rotation was already added to this cluster.",this);return new(secretsmanager()).SecretRotation(this,id,{...(0,util_1().applyDefaultRotationOptions)(options,this.vpcSubnets),secret:this.secret,application:this.singleUserRotationApplication,vpc:this.vpc,target:this})}addRotationMultiUser(id,options){if(!this.secret)throw new(errors_1()).ValidationError("Cannot add a multi user rotation for a cluster without a secret.",this);return new(secretsmanager()).SecretRotation(this,id,{...(0,util_1().applyDefaultRotationOptions)(options,this.vpcSubnets),secret:options.secret,masterSecret:this.secret,application:this.multiUserRotationApplication,vpc:this.vpc,target:this})}}let ImportedDatabaseCluster=class extends DatabaseClusterBase{constructor(scope,id,attrs){super(scope,id),(0,metadata_resource_1().addConstructMetadata)(this,attrs),this.clusterIdentifier=attrs.clusterIdentifier,this._clusterResourceIdentifier=attrs.clusterResourceIdentifier;const defaultPort=attrs.port?ec2().Port.tcp(attrs.port):void 0;this.connections=new(ec2()).Connections({securityGroups:attrs.securityGroups,defaultPort}),this.engine=attrs.engine,this.secret=attrs.secret,this.enableDataApi=attrs.dataApiEnabled??!1,this._clusterEndpoint=attrs.clusterEndpointAddress&&attrs.port?new(endpoint_1()).Endpoint(attrs.clusterEndpointAddress,attrs.port):void 0,this._clusterReadEndpoint=attrs.readerEndpointAddress&&attrs.port?new(endpoint_1()).Endpoint(attrs.readerEndpointAddress,attrs.port):void 0,this._instanceIdentifiers=attrs.instanceIdentifiers,this._instanceEndpoints=attrs.instanceEndpointAddresses&&attrs.port?attrs.instanceEndpointAddresses.map(addr=>new(endpoint_1()).Endpoint(addr,attrs.port)):void 0}get clusterResourceIdentifier(){if(!this._clusterResourceIdentifier)throw new(errors_1()).ValidationError("Cannot access `clusterResourceIdentifier` of an imported cluster without a clusterResourceIdentifier",this);return this._clusterResourceIdentifier}get clusterEndpoint(){if(!this._clusterEndpoint)throw new(errors_1()).ValidationError("Cannot access `clusterEndpoint` of an imported cluster without an endpoint address and port",this);return this._clusterEndpoint}get clusterReadEndpoint(){if(!this._clusterReadEndpoint)throw new(errors_1()).ValidationError("Cannot access `clusterReadEndpoint` of an imported cluster without a readerEndpointAddress and port",this);return this._clusterReadEndpoint}get instanceIdentifiers(){if(!this._instanceIdentifiers)throw new(errors_1()).ValidationError("Cannot access `instanceIdentifiers` of an imported cluster without provided instanceIdentifiers",this);return this._instanceIdentifiers}get instanceEndpoints(){if(!this._instanceEndpoints)throw new(errors_1()).ValidationError("Cannot access `instanceEndpoints` of an imported cluster without instanceEndpointAddresses and port",this);return this._instanceEndpoints}};ImportedDatabaseCluster.PROPERTY_INJECTION_ID="aws-cdk-lib.aws-rds.ImportedDatabaseCluster",ImportedDatabaseCluster=__decorate([prop_injectable_1().propertyInjectable],ImportedDatabaseCluster);let DatabaseCluster=class DatabaseCluster2 extends DatabaseClusterNew{static fromDatabaseClusterAttributes(scope,id,attrs){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_rds_DatabaseClusterAttributes(attrs)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.fromDatabaseClusterAttributes),error}return new ImportedDatabaseCluster(scope,id,attrs)}constructor(scope,id,props){super(scope,id,props);try{jsiiDeprecationWarnings().aws_cdk_lib_aws_rds_DatabaseClusterProps(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,DatabaseCluster2),error}(0,metadata_resource_1().addConstructMetadata)(this,props);const credentials=(0,util_1().renderCredentials)(this,props.engine,props.credentials),secret=credentials.secret,canHaveCredentials=props.replicationSourceIdentifier==null,cluster=new(rds_generated_1()).CfnDBCluster(this,"Resource",{...this.newCfnProps,masterUsername:canHaveCredentials?credentials.username:void 0,masterUserPassword:canHaveCredentials?credentials.password?.unsafeUnwrap():void 0,replicationSourceIdentifier:props.replicationSourceIdentifier});this.clusterIdentifier=cluster.ref,this.clusterResourceIdentifier=cluster.attrDbClusterResourceId,secret&&(this.secret=secret.attach(this));const portAttribute=core_1().Token.asNumber(cluster.attrEndpointPort);if(this.clusterEndpoint=new(endpoint_1()).Endpoint(cluster.attrEndpointAddress,portAttribute),this.clusterReadEndpoint=new(endpoint_1()).Endpoint(cluster.attrReadEndpointAddress,portAttribute),this.connections=new(ec2()).Connections({securityGroups:this.securityGroups,defaultPort:ec2().Port.tcp(this.clusterEndpoint.port)}),cluster.applyRemovalPolicy(props.removalPolicy??core_1().RemovalPolicy.SNAPSHOT),setLogRetention(this,props),props.clusterScalabilityType!==ClusterScalabilityType.LIMITLESS&&props.clusterScailabilityType!==ClusterScailabilityType.LIMITLESS){if((props.writer||props.readers)&&(props.instances||props.instanceProps))throw new(errors_1()).ValidationError("Cannot provide writer or readers if instances or instanceProps are provided",this);if(!props.instanceProps&&!props.writer)throw new(errors_1()).ValidationError("writer must be provided",this);const createdInstances=props.writer?this._createInstances(props):legacyCreateInstances(this,props,this.subnetGroup);this.instanceIdentifiers=createdInstances.instanceIdentifiers,this.instanceEndpoints=createdInstances.instanceEndpoints}else this.instanceIdentifiers=[],this.instanceEndpoints=[]}};exports.DatabaseCluster=DatabaseCluster,_b=JSII_RTTI_SYMBOL_1,DatabaseCluster[_b]={fqn:"aws-cdk-lib.aws_rds.DatabaseCluster",version:"2.202.0"},DatabaseCluster.PROPERTY_INJECTION_ID="aws-cdk-lib.aws-rds.DatabaseCluster",exports.DatabaseCluster=DatabaseCluster=__decorate([prop_injectable_1().propertyInjectable],DatabaseCluster);const INSTANCE_TYPE_XLARGE_MEMORY_MAPPING={m5:16,m5d:16,m6g:16,t4g:16,t3:16,m4:16,r6g:32,r5:32,r5b:32,r5d:32,r4:30.5,x2g:64,x1e:122,x1:61,z1d:32};function instanceSizeSupportedByServerlessV2(instanceSize,serverlessV2MaxCapacity){const serverlessMaxMem=serverlessV2MaxCapacity*2,sizeParts=instanceSize.split(".");if(sizeParts.length===2){const type=sizeParts[0],size=sizeParts[1],xlargeMem=INSTANCE_TYPE_XLARGE_MEMORY_MAPPING[type];if(size.endsWith("xlarge")){if((size==="xlarge"?xlargeMem:Number(size.slice(0,-6))*xlargeMem)>serverlessMaxMem)return!1}else return!0}else if(["db.r5.2xlarge.tpc2.mem8x","db.r5.4xlarge.tpc2.mem3x","db.r5.4xlarge.tpc2.mem4x","db.r5.6xlarge.tpc2.mem4x","db.r5.8xlarge.tpc2.mem3x","db.r5.12xlarge.tpc2.mem2x"].includes(instanceSize))return!1;return!0}let DatabaseClusterFromSnapshot=class DatabaseClusterFromSnapshot2 extends DatabaseClusterNew{constructor(scope,id,props){super(scope,id,props);try{jsiiDeprecationWarnings().aws_cdk_lib_aws_rds_DatabaseClusterFromSnapshotProps(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,DatabaseClusterFromSnapshot2),error}(0,metadata_resource_1().addConstructMetadata)(this,props),props.credentials&&!props.credentials.password&&!props.credentials.secret&&core_1().Annotations.of(this).addWarningV2("@aws-cdk/aws-rds:useSnapshotCredentials","Use `snapshotCredentials` to modify password of a cluster created from a snapshot."),!props.credentials&&!props.snapshotCredentials&&core_1().Annotations.of(this).addWarningV2("@aws-cdk/aws-rds:generatedCredsNotApplied","Generated credentials will not be applied to cluster. Use `snapshotCredentials` instead. `addRotationSingleUser()` and `addRotationMultiUser()` cannot be used on this cluster.");const deprecatedCredentials=core_1().FeatureFlags.of(this).isEnabled(cxapi().RDS_PREVENT_RENDERING_DEPRECATED_CREDENTIALS)?void 0:(0,util_1().renderCredentials)(this,props.engine,props.credentials),credentials=(0,util_1().renderSnapshotCredentials)(this,props.snapshotCredentials),cluster=new(rds_generated_1()).CfnDBCluster(this,"Resource",{...this.newCfnProps,snapshotIdentifier:props.snapshotIdentifier,masterUserPassword:credentials?.secret?.secretValueFromJson("password")?.unsafeUnwrap()??credentials?.password?.unsafeUnwrap()});if(this.clusterIdentifier=cluster.ref,this.clusterResourceIdentifier=cluster.attrDbClusterResourceId,credentials?.secret&&(this.secret=credentials.secret.attach(this)),deprecatedCredentials?.secret){const deprecatedSecret=deprecatedCredentials.secret.attach(this);this.secret||(this.secret=deprecatedSecret)}const portAttribute=core_1().Token.asNumber(cluster.attrEndpointPort);if(this.clusterEndpoint=new(endpoint_1()).Endpoint(cluster.attrEndpointAddress,portAttribute),this.clusterReadEndpoint=new(endpoint_1()).Endpoint(cluster.attrReadEndpointAddress,portAttribute),this.connections=new(ec2()).Connections({securityGroups:this.securityGroups,defaultPort:ec2().Port.tcp(this.clusterEndpoint.port)}),cluster.applyRemovalPolicy(props.removalPolicy??core_1().RemovalPolicy.SNAPSHOT),setLogRetention(this,props),(props.writer||props.readers)&&(props.instances||props.instanceProps))throw new(errors_1()).ValidationError("Cannot provide clusterInstances if instances or instanceProps are provided",this);const createdInstances=props.writer?this._createInstances(props):legacyCreateInstances(this,props,this.subnetGroup);this.instanceIdentifiers=createdInstances.instanceIdentifiers,this.instanceEndpoints=createdInstances.instanceEndpoints}};exports.DatabaseClusterFromSnapshot=DatabaseClusterFromSnapshot,_c=JSII_RTTI_SYMBOL_1,DatabaseClusterFromSnapshot[_c]={fqn:"aws-cdk-lib.aws_rds.DatabaseClusterFromSnapshot",version:"2.202.0"},DatabaseClusterFromSnapshot.PROPERTY_INJECTION_ID="aws-cdk-lib.aws-rds.DatabaseClusterFromSnapshot",exports.DatabaseClusterFromSnapshot=DatabaseClusterFromSnapshot=__decorate([prop_injectable_1().propertyInjectable],DatabaseClusterFromSnapshot);function setLogRetention(cluster,props){if(props.cloudwatchLogsExports){const unsupportedLogTypes=props.cloudwatchLogsExports.filter(logType=>!props.engine.supportedLogTypes.includes(logType));if(unsupportedLogTypes.length>0)throw new(errors_1()).ValidationError(`Unsupported logs for the current engine type: ${unsupportedLogTypes.join(",")}`,cluster);if(props.cloudwatchLogsRetention)for(const log of props.cloudwatchLogsExports){const logGroupName=`/aws/rds/cluster/${cluster.clusterIdentifier}/${log}`;new(logs()).LogRetention(cluster,`LogRetention${log}`,{logGroupName,retention:props.cloudwatchLogsRetention,role:props.cloudwatchLogsRetentionRole}),cluster.cloudwatchLogGroups[log]=logs().LogGroup.fromLogGroupName(cluster,`LogGroup${cluster.clusterIdentifier}${log}`,logGroupName)}}}function legacyCreateInstances(cluster,props,subnetGroup){const instanceCount=props.instances!=null?props.instances:2,instanceUpdateBehaviour=props.instanceUpdateBehaviour??InstanceUpdateBehaviour.BULK;if(core_1().Token.isUnresolved(instanceCount))throw new(errors_1()).ValidationError("The number of instances an RDS Cluster consists of cannot be provided as a deploy-time only value!",cluster);if(instanceCount<1)throw new(errors_1()).ValidationError("At least one instance is required",cluster);const instanceIdentifiers=[],instanceEndpoints=[],portAttribute=cluster.clusterEndpoint.port,instanceProps=props.instanceProps,internetConnected=instanceProps.vpc.selectSubnets(instanceProps.vpcSubnets).internetConnectivityEstablished,enablePerformanceInsights=instanceProps.enablePerformanceInsights||instanceProps.performanceInsightRetention!==void 0||instanceProps.performanceInsightEncryptionKey!==void 0;if(enablePerformanceInsights&&instanceProps.enablePerformanceInsights===!1)throw new(errors_1()).ValidationError("`enablePerformanceInsights` disabled, but `performanceInsightRetention` or `performanceInsightEncryptionKey` was set",cluster);const performanceInsightRetention=enablePerformanceInsights?instanceProps.performanceInsightRetention||props_1().PerformanceInsightRetention.DEFAULT:void 0;validatePerformanceInsightsSettings(cluster,{performanceInsightsEnabled:enablePerformanceInsights,performanceInsightRetention,performanceInsightEncryptionKey:instanceProps.performanceInsightEncryptionKey});const instanceType=instanceProps.instanceType??ec2().InstanceType.of(ec2().InstanceClass.T3,ec2().InstanceSize.MEDIUM);if(instanceProps.parameterGroup&&instanceProps.parameters)throw new(errors_1()).ValidationError("You cannot specify both parameterGroup and parameters",cluster);const instanceParameterGroupConfig=(instanceProps.parameterGroup??(instanceProps.parameters?new(parameter_group_1()).ParameterGroup(cluster,"InstanceParameterGroup",{engine:props.engine,parameters:instanceProps.parameters}):void 0))?.bindToInstance({}),instances=[];for(let i=0;i<instanceCount;i++){const instanceIndex=i+1,instanceIdentifier=props.instanceIdentifierBase!=null?`${props.instanceIdentifierBase}${instanceIndex}`:props.clusterIdentifier!=null?`${props.clusterIdentifier}instance${instanceIndex}`:void 0,instance=new(rds_generated_1()).CfnDBInstance(cluster,`Instance${instanceIndex}`,{engine:props.engine.engineType,dbClusterIdentifier:cluster.clusterIdentifier,dbInstanceIdentifier:instanceIdentifier,dbInstanceClass:databaseInstanceType(instanceType),publiclyAccessible:instanceProps.publiclyAccessible??(instanceProps.vpcSubnets&&instanceProps.vpcSubnets.subnetType===ec2().SubnetType.PUBLIC),enablePerformanceInsights:enablePerformanceInsights||instanceProps.enablePerformanceInsights,performanceInsightsKmsKeyId:instanceProps.performanceInsightEncryptionKey?.keyArn,performanceInsightsRetentionPeriod:performanceInsightRetention,dbSubnetGroupName:subnetGroup.subnetGroupName,dbParameterGroupName:instanceParameterGroupConfig?.parameterGroupName,monitoringInterval:props.enableClusterLevelEnhancedMonitoring?void 0:props.monitoringInterval?.toSeconds(),monitoringRoleArn:props.enableClusterLevelEnhancedMonitoring?void 0:cluster.monitoringRole?.roleArn,autoMinorVersionUpgrade:instanceProps.autoMinorVersionUpgrade,allowMajorVersionUpgrade:instanceProps.allowMajorVersionUpgrade,deleteAutomatedBackups:instanceProps.deleteAutomatedBackups,preferredMaintenanceWindow:instanceProps.preferredMaintenanceWindow});instance.applyRemovalPolicy((0,util_1().helperRemovalPolicy)(props.removalPolicy)),instance.node.addDependency(internetConnected),instanceIdentifiers.push(instance.ref),instanceEndpoints.push(new(endpoint_1()).Endpoint(instance.attrEndpointAddress,portAttribute)),instances.push(instance)}if(instanceUpdateBehaviour===InstanceUpdateBehaviour.ROLLING)for(let i=1;i<instanceCount;i++)instances[i].node.addDependency(instances[i-1]);return{instanceEndpoints,instanceIdentifiers}}function databaseInstanceType(instanceType){return"db."+instanceType.toString()}function validatePerformanceInsightsSettings(cluster,instance){const target=instance.nodeId?`instance '${instance.nodeId}'`:"`instanceProps`";if(cluster.performanceInsightsEnabled&&instance.performanceInsightsEnabled===!1&&core_1().Annotations.of(cluster).addWarningV2("@aws-cdk/aws-rds:instancePerformanceInsightsOverridden",`Performance Insights is enabled on cluster '${cluster.node.id}' at cluster level, but disabled for ${target}. However, Performance Insights for this instance will also be automatically enabled if enabled at cluster level.`),cluster.performanceInsightRetention&&instance.performanceInsightRetention&&instance.performanceInsightRetention!==cluster.performanceInsightRetention)throw new(errors_1()).ValidationError(`\`performanceInsightRetention\` for each instance must be the same as the one at cluster level, got ${target}: ${instance.performanceInsightRetention}, cluster: ${cluster.performanceInsightRetention}`,cluster);if(cluster.performanceInsightEncryptionKey&&instance.performanceInsightEncryptionKey){const clusterKeyArn=cluster.performanceInsightEncryptionKey.keyArn,instanceKeyArn=instance.performanceInsightEncryptionKey.keyArn,compared=core_1().Token.compareStrings(clusterKeyArn,instanceKeyArn);if(compared===core_1().TokenComparison.DIFFERENT)throw new(errors_1()).ValidationError(`\`performanceInsightEncryptionKey\` for each instance must be the same as the one at cluster level, got ${target}: '${instance.performanceInsightEncryptionKey.keyArn}', cluster: '${cluster.performanceInsightEncryptionKey.keyArn}'`,cluster);if(compared===core_1().TokenComparison.BOTH_UNRESOLVED&&clusterKeyArn!==instanceKeyArn)throw new(errors_1()).ValidationError("`performanceInsightEncryptionKey` for each instance must be the same as the one at cluster level",cluster)}}