@go-to-k/cdkd 0.215.0 → 0.217.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-DWUnLza1.js";
|
|
3
|
-
import { $ as CFN_TEMPLATE_URL_LIMIT, A as DagBuilder, B as getDockerCmd, C as CloudControlProvider, D as IntrinsicFunctionResolver, Dt as withErrorHandling, E as isTerminationProtectionPropagationError, Et as normalizeAwsError, F as AssetPublisher, Ft as generateResourceName, G as getLegacyStateBucketName, H as runDockerStreaming, I as stringifyValue, It as generateResourceNameWithFallback, J as resolveSkipPrefix, K as resolveApp, L as WorkGraph, Lt as withSkipPrefix, M as LockManager, Mt as getLiveRenderer, N as S3StateBackend, Nt as PATTERN_B_NAME_PROPERTIES, O as applyRoleArnIfSet, P as shouldRetainResource, Pt as PATTERN_B_RESOURCE_TYPES, Q as CFN_TEMPLATE_BODY_LIMIT, R as buildDockerImage, Rt as withStackName, S as findActionableSilentDrops, T as disableInstanceApiTermination, U as Synthesizer, V as runDockerForeground, W as getDefaultStateBucketName, X as resolveStateBucketWithDefaultAndSource, Y as resolveStateBucketWithDefault, Z as warnDeprecatedNoPrefixCliFlag, _ as CDK_PATH_TAG, _t as ProvisioningError, a as withRetry, at as resolveBucketRegion, b as resolveExplicitPhysicalId, bt as StackHasActiveImportsError, c as formatResourceLine, d as gray, dt as LocalMigrateError, et as MIGRATE_TMP_PREFIX, f as green, ft as LocalStartServiceError, g as collectInlinePolicyNamesManagedBySiblings, gt as PartialFailureError, h as IAMRoleProvider, ht as NestedStackChildDirectDestroyError, i as withResourceDeadline, j as TemplateParser, jt as runStackBuffered, k as DiffCalculator, kt as getLogger, l as bold, m as yellow, mt as MissingCdkCliError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as uploadCfnTemplate, o as isRetryableTransientError, p as red, q as resolveCaptureObservedState, r as DeployEngine, rt as AssemblyReader, s as IMPLICIT_DELETE_DEPENDENCIES, st as CdkdError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as findLargeInlineResources, u as cyan, ut as LocalInvokeBuildError$1, v as matchesCdkPath, vt as ResourceTimeoutError, w as assertRegionMatch, x as ProviderRegistry, xt as StackTerminationProtectionError, y as normalizeAwsTagsToCfn, yt as ResourceUpdateNotSupportedError, z as formatDockerLoginError } from "./deploy-engine-
|
|
3
|
+
import { $ as CFN_TEMPLATE_URL_LIMIT, A as DagBuilder, B as getDockerCmd, C as CloudControlProvider, D as IntrinsicFunctionResolver, Dt as withErrorHandling, E as isTerminationProtectionPropagationError, Et as normalizeAwsError, F as AssetPublisher, Ft as generateResourceName, G as getLegacyStateBucketName, H as runDockerStreaming, I as stringifyValue, It as generateResourceNameWithFallback, J as resolveSkipPrefix, K as resolveApp, L as WorkGraph, Lt as withSkipPrefix, M as LockManager, Mt as getLiveRenderer, N as S3StateBackend, Nt as PATTERN_B_NAME_PROPERTIES, O as applyRoleArnIfSet, P as shouldRetainResource, Pt as PATTERN_B_RESOURCE_TYPES, Q as CFN_TEMPLATE_BODY_LIMIT, R as buildDockerImage, Rt as withStackName, S as findActionableSilentDrops, T as disableInstanceApiTermination, U as Synthesizer, V as runDockerForeground, W as getDefaultStateBucketName, X as resolveStateBucketWithDefaultAndSource, Y as resolveStateBucketWithDefault, Z as warnDeprecatedNoPrefixCliFlag, _ as CDK_PATH_TAG, _t as ProvisioningError, a as withRetry, at as resolveBucketRegion, b as resolveExplicitPhysicalId, bt as StackHasActiveImportsError, c as formatResourceLine, d as gray, dt as LocalMigrateError, et as MIGRATE_TMP_PREFIX, f as green, ft as LocalStartServiceError, g as collectInlinePolicyNamesManagedBySiblings, gt as PartialFailureError, h as IAMRoleProvider, ht as NestedStackChildDirectDestroyError, i as withResourceDeadline, j as TemplateParser, jt as runStackBuffered, k as DiffCalculator, kt as getLogger, l as bold, m as yellow, mt as MissingCdkCliError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as uploadCfnTemplate, o as isRetryableTransientError, p as red, q as resolveCaptureObservedState, r as DeployEngine, rt as AssemblyReader, s as IMPLICIT_DELETE_DEPENDENCIES, st as CdkdError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as findLargeInlineResources, u as cyan, ut as LocalInvokeBuildError$1, v as matchesCdkPath, vt as ResourceTimeoutError, w as assertRegionMatch, x as ProviderRegistry, xt as StackTerminationProtectionError, y as normalizeAwsTagsToCfn, yt as ResourceUpdateNotSupportedError, z as formatDockerLoginError } from "./deploy-engine-UctzfQ8M.js";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
5
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
6
6
|
import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListBucketsCommand, ListDirectoryBucketsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -10,7 +10,7 @@ import { CreateTopicCommand, DeleteTopicCommand, GetSubscriptionAttributesComman
|
|
|
10
10
|
import { AddPermissionCommand, CreateEventSourceMappingCommand, CreateFunctionCommand, CreateFunctionUrlConfigCommand, DeleteEventSourceMappingCommand, DeleteFunctionCommand, DeleteFunctionConcurrencyCommand, DeleteFunctionUrlConfigCommand, DeleteLayerVersionCommand, GetEventSourceMappingCommand, GetFunctionCommand, GetFunctionConcurrencyCommand, GetFunctionRecursionConfigCommand, GetFunctionUrlConfigCommand, GetLayerVersionByArnCommand, GetPolicyCommand as GetPolicyCommand$1, LambdaClient, ListFunctionsCommand, ListLayersCommand, ListTagsCommand, PublishLayerVersionCommand, PutFunctionConcurrencyCommand, PutFunctionRecursionConfigCommand, RemovePermissionCommand, ResourceNotFoundException, TagResourceCommand as TagResourceCommand$1, UntagResourceCommand as UntagResourceCommand$1, UpdateEventSourceMappingCommand, UpdateFunctionCodeCommand, UpdateFunctionConfigurationCommand, UpdateFunctionUrlConfigCommand, waitUntilFunctionUpdatedV2 } from "@aws-sdk/client-lambda";
|
|
11
11
|
import { AssumeRoleCommand, GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
|
|
12
12
|
import { AssociateRouteTableCommand, AttachInternetGatewayCommand, AuthorizeSecurityGroupEgressCommand, AuthorizeSecurityGroupIngressCommand, CreateInternetGatewayCommand, CreateNatGatewayCommand, CreateNetworkAclCommand, CreateNetworkAclEntryCommand, CreateRouteCommand, CreateRouteTableCommand, CreateSecurityGroupCommand, CreateSubnetCommand, CreateTagsCommand, CreateVpcCommand, DeleteInternetGatewayCommand, DeleteNatGatewayCommand, DeleteNetworkAclCommand, DeleteNetworkAclEntryCommand, DeleteNetworkInterfaceCommand, DeleteRouteCommand, DeleteRouteTableCommand, DeleteSecurityGroupCommand, DeleteSubnetCommand, DeleteTagsCommand, DeleteVpcCommand, DescribeAvailabilityZonesCommand, DescribeInstanceAttributeCommand, DescribeInstancesCommand, DescribeInternetGatewaysCommand, DescribeNatGatewaysCommand, DescribeNetworkAclsCommand, DescribeNetworkInterfacesCommand, DescribeRouteTablesCommand, DescribeSecurityGroupsCommand, DescribeSubnetsCommand, DescribeVolumesCommand, DescribeVpcAttributeCommand, DescribeVpcsCommand, DetachInternetGatewayCommand, DisassociateRouteTableCommand, EC2Client, ModifySubnetAttributeCommand, ModifyVpcAttributeCommand, ReplaceNetworkAclAssociationCommand, RevokeSecurityGroupEgressCommand, RevokeSecurityGroupIngressCommand, RunInstancesCommand, TerminateInstancesCommand, waitUntilInstanceRunning, waitUntilInstanceTerminated, waitUntilNatGatewayAvailable, waitUntilNatGatewayDeleted } from "@aws-sdk/client-ec2";
|
|
13
|
-
import { CreateTableCommand, DeleteTableCommand, DescribeContinuousBackupsCommand, DescribeContributorInsightsCommand, DescribeKinesisStreamingDestinationCommand, DescribeTableCommand, DescribeTimeToLiveCommand, DynamoDBClient, ListTablesCommand, ListTagsOfResourceCommand, ResourceNotFoundException as ResourceNotFoundException$1, TagResourceCommand as TagResourceCommand$2, UntagResourceCommand as UntagResourceCommand$2, UpdateContinuousBackupsCommand, UpdateTableCommand, UpdateTimeToLiveCommand } from "@aws-sdk/client-dynamodb";
|
|
13
|
+
import { CreateTableCommand, DeleteResourcePolicyCommand, DeleteTableCommand, DescribeContinuousBackupsCommand, DescribeContributorInsightsCommand, DescribeKinesisStreamingDestinationCommand, DescribeTableCommand, DescribeTimeToLiveCommand, DisableKinesisStreamingDestinationCommand, DynamoDBClient, EnableKinesisStreamingDestinationCommand, GetResourcePolicyCommand, ListTablesCommand, ListTagsOfResourceCommand, PutResourcePolicyCommand, ResourceNotFoundException as ResourceNotFoundException$1, TagResourceCommand as TagResourceCommand$2, UntagResourceCommand as UntagResourceCommand$2, UpdateContinuousBackupsCommand, UpdateContributorInsightsCommand, UpdateTableCommand, UpdateTimeToLiveCommand } from "@aws-sdk/client-dynamodb";
|
|
14
14
|
import { CloudFormationClient, CreateChangeSetCommand, DeleteChangeSetCommand, DeleteStackCommand, DescribeChangeSetCommand, DescribeStackEventsCommand, DescribeStackResourcesCommand, DescribeStacksCommand, DescribeTypeCommand, ExecuteChangeSetCommand, GetTemplateCommand, UpdateStackCommand, waitUntilChangeSetCreateComplete, waitUntilStackDeleteComplete, waitUntilStackImportComplete, waitUntilStackUpdateComplete } from "@aws-sdk/client-cloudformation";
|
|
15
15
|
import { APIGatewayClient, CreateAuthorizerCommand, CreateDeploymentCommand, CreateResourceCommand, CreateStageCommand, DeleteAuthorizerCommand, DeleteDeploymentCommand, DeleteMethodCommand, DeleteResourceCommand, DeleteStageCommand, GetAccountCommand, GetAuthorizerCommand, GetDeploymentCommand, GetMethodCommand, GetResourceCommand, GetStageCommand, NotFoundException as NotFoundException$1, PutIntegrationCommand, PutIntegrationResponseCommand, PutMethodCommand, PutMethodResponseCommand, TagResourceCommand as TagResourceCommand$3, UntagResourceCommand as UntagResourceCommand$3, UpdateAccountCommand, UpdateAuthorizerCommand, UpdateMethodCommand, UpdateStageCommand } from "@aws-sdk/client-api-gateway";
|
|
16
16
|
import { CreateEventBusCommand, DeleteEventBusCommand, DeleteRuleCommand, DescribeEventBusCommand, DescribeRuleCommand, EventBridgeClient, ListEventBusesCommand, ListRulesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$1, ListTargetsByRuleCommand, PutRuleCommand, PutTargetsCommand, RemoveTargetsCommand, ResourceNotFoundException as ResourceNotFoundException$2, TagResourceCommand as TagResourceCommand$4, UntagResourceCommand as UntagResourceCommand$4, UpdateEventBusCommand } from "@aws-sdk/client-eventbridge";
|
|
@@ -46,7 +46,7 @@ import { CreateClusterCommand, CreateServiceCommand, DeleteClusterCommand, Delet
|
|
|
46
46
|
import { AddTagsToResourceCommand as AddTagsToResourceCommand$2, CreateDBClusterCommand as CreateDBClusterCommand$1, CreateDBInstanceCommand as CreateDBInstanceCommand$1, CreateDBSubnetGroupCommand as CreateDBSubnetGroupCommand$1, DeleteDBClusterCommand as DeleteDBClusterCommand$1, DeleteDBInstanceCommand as DeleteDBInstanceCommand$1, DeleteDBSubnetGroupCommand as DeleteDBSubnetGroupCommand$1, DescribeDBClustersCommand as DescribeDBClustersCommand$1, DescribeDBInstancesCommand as DescribeDBInstancesCommand$1, DescribeDBSubnetGroupsCommand as DescribeDBSubnetGroupsCommand$1, DocDBClient, ListTagsForResourceCommand as ListTagsForResourceCommand$11, ModifyDBClusterCommand as ModifyDBClusterCommand$1, ModifyDBInstanceCommand as ModifyDBInstanceCommand$1, ModifyDBSubnetGroupCommand as ModifyDBSubnetGroupCommand$1, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$2 } from "@aws-sdk/client-docdb";
|
|
47
47
|
import { AddTagsToResourceCommand as AddTagsToResourceCommand$3, CreateDBClusterCommand as CreateDBClusterCommand$2, CreateDBInstanceCommand as CreateDBInstanceCommand$2, CreateDBSubnetGroupCommand as CreateDBSubnetGroupCommand$2, DeleteDBClusterCommand as DeleteDBClusterCommand$2, DeleteDBInstanceCommand as DeleteDBInstanceCommand$2, DeleteDBSubnetGroupCommand as DeleteDBSubnetGroupCommand$2, DescribeDBClustersCommand as DescribeDBClustersCommand$2, DescribeDBInstancesCommand as DescribeDBInstancesCommand$2, DescribeDBSubnetGroupsCommand as DescribeDBSubnetGroupsCommand$2, ListTagsForResourceCommand as ListTagsForResourceCommand$12, ModifyDBClusterCommand as ModifyDBClusterCommand$2, ModifyDBInstanceCommand as ModifyDBInstanceCommand$2, ModifyDBSubnetGroupCommand as ModifyDBSubnetGroupCommand$2, NeptuneClient, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$3 } from "@aws-sdk/client-neptune";
|
|
48
48
|
import { CreateWebACLCommand, DeleteWebACLCommand, GetWebACLCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$13, ListWebACLsCommand, TagResourceCommand as TagResourceCommand$13, UntagResourceCommand as UntagResourceCommand$12, UpdateWebACLCommand, WAFNonexistentItemException, WAFV2Client } from "@aws-sdk/client-wafv2";
|
|
49
|
-
import { CognitoIdentityProviderClient, CreateUserPoolCommand, DeleteUserPoolCommand, DescribeUserPoolCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$14, ListUserPoolsCommand, ResourceNotFoundException as ResourceNotFoundException$7, UpdateUserPoolCommand } from "@aws-sdk/client-cognito-identity-provider";
|
|
49
|
+
import { CognitoIdentityProviderClient, CreateUserPoolCommand, DeleteUserPoolCommand, DescribeUserPoolCommand, GetUserPoolMfaConfigCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$14, ListUserPoolsCommand, ResourceNotFoundException as ResourceNotFoundException$7, SetUserPoolMfaConfigCommand, UpdateUserPoolCommand } from "@aws-sdk/client-cognito-identity-provider";
|
|
50
50
|
import { AddTagsToResourceCommand as AddTagsToResourceCommand$4, CreateCacheClusterCommand, CreateCacheSubnetGroupCommand, DeleteCacheClusterCommand, DeleteCacheSubnetGroupCommand, DescribeCacheClustersCommand, DescribeCacheSubnetGroupsCommand, ElastiCacheClient, ListTagsForResourceCommand as ListTagsForResourceCommand$15, ModifyCacheClusterCommand, ModifyCacheSubnetGroupCommand, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$4 } from "@aws-sdk/client-elasticache";
|
|
51
51
|
import { CreatePrivateDnsNamespaceCommand, CreateServiceCommand as CreateServiceCommand$1, DeleteNamespaceCommand, DeleteServiceCommand as DeleteServiceCommand$1, GetNamespaceCommand, GetOperationCommand, GetServiceCommand, ListNamespacesCommand, ListServicesCommand as ListServicesCommand$1, ListTagsForResourceCommand as ListTagsForResourceCommand$16, NamespaceNotFound, ServiceDiscoveryClient, ServiceNotFound, UpdatePrivateDnsNamespaceCommand, UpdateServiceCommand as UpdateServiceCommand$1 } from "@aws-sdk/client-servicediscovery";
|
|
52
52
|
import { AppSyncClient, CreateApiKeyCommand, CreateDataSourceCommand, CreateGraphqlApiCommand, CreateResolverCommand, DeleteApiKeyCommand, DeleteDataSourceCommand, DeleteGraphqlApiCommand, DeleteResolverCommand, GetDataSourceCommand, GetGraphqlApiCommand, GetIntrospectionSchemaCommand, GetResolverCommand, ListApiKeysCommand, ListGraphqlApisCommand, NotFoundException as NotFoundException$4, StartSchemaCreationCommand, TagResourceCommand as TagResourceCommand$14, UntagResourceCommand as UntagResourceCommand$13, UpdateApiKeyCommand, UpdateDataSourceCommand, UpdateGraphqlApiCommand, UpdateResolverCommand } from "@aws-sdk/client-appsync";
|
|
@@ -8997,8 +8997,12 @@ var DynamoDBTableProvider = class {
|
|
|
8997
8997
|
"DeletionProtectionEnabled",
|
|
8998
8998
|
"TableClass",
|
|
8999
8999
|
"PointInTimeRecoverySpecification",
|
|
9000
|
-
"TimeToLiveSpecification"
|
|
9000
|
+
"TimeToLiveSpecification",
|
|
9001
|
+
"ResourcePolicy",
|
|
9002
|
+
"KinesisStreamSpecification",
|
|
9003
|
+
"ContributorInsightsSpecification"
|
|
9001
9004
|
])]]);
|
|
9005
|
+
unhandledByDesign = new Map([["AWS::DynamoDB::Table", new Map([["ImportSourceSpecification", "S3 import uses the separate ImportTable API (not CreateTable) and is create-only with no readback; deferred to a dedicated import-from-S3 PR"]])]]);
|
|
9002
9006
|
constructor() {
|
|
9003
9007
|
const awsClients = getAwsClients();
|
|
9004
9008
|
this.dynamoDBClient = awsClients.dynamoDB;
|
|
@@ -9041,12 +9045,16 @@ var DynamoDBTableProvider = class {
|
|
|
9041
9045
|
if (properties["Tags"]) createParams.Tags = properties["Tags"];
|
|
9042
9046
|
if (properties["DeletionProtectionEnabled"] !== void 0) createParams.DeletionProtectionEnabled = properties["DeletionProtectionEnabled"];
|
|
9043
9047
|
if (properties["TableClass"]) createParams.TableClass = properties["TableClass"];
|
|
9048
|
+
const createResourcePolicyDoc = this.extractResourcePolicyDocument(properties["ResourcePolicy"]);
|
|
9049
|
+
if (createResourcePolicyDoc !== void 0) createParams.ResourcePolicy = createResourcePolicyDoc;
|
|
9044
9050
|
await this.dynamoDBClient.send(new CreateTableCommand(createParams));
|
|
9045
9051
|
tableCreated = true;
|
|
9046
9052
|
this.logger.debug(`CreateTable initiated for ${tableName}, waiting for ACTIVE status`);
|
|
9047
9053
|
const tableInfo = await this.waitForTableActive(tableName);
|
|
9048
9054
|
await this.applyPointInTimeRecovery(tableName, properties["PointInTimeRecoverySpecification"]);
|
|
9049
9055
|
await this.applyTimeToLive(tableName, properties["TimeToLiveSpecification"]);
|
|
9056
|
+
await this.applyKinesisStreamingDestination(tableName, properties["KinesisStreamSpecification"]);
|
|
9057
|
+
await this.applyContributorInsights(tableName, properties["ContributorInsightsSpecification"]);
|
|
9050
9058
|
this.logger.debug(`Successfully created DynamoDB table ${logicalId}: ${tableName}`);
|
|
9051
9059
|
return {
|
|
9052
9060
|
physicalId: tableName,
|
|
@@ -9101,6 +9109,12 @@ var DynamoDBTableProvider = class {
|
|
|
9101
9109
|
}
|
|
9102
9110
|
if (JSON.stringify(properties["PointInTimeRecoverySpecification"]) !== JSON.stringify(previousProperties["PointInTimeRecoverySpecification"])) await this.applyPointInTimeRecovery(physicalId, properties["PointInTimeRecoverySpecification"], previousProperties["PointInTimeRecoverySpecification"]);
|
|
9103
9111
|
if (JSON.stringify(properties["TimeToLiveSpecification"]) !== JSON.stringify(previousProperties["TimeToLiveSpecification"])) await this.applyTimeToLive(physicalId, properties["TimeToLiveSpecification"], previousProperties["TimeToLiveSpecification"]);
|
|
9112
|
+
if (JSON.stringify(properties["ResourcePolicy"]) !== JSON.stringify(previousProperties["ResourcePolicy"])) {
|
|
9113
|
+
if (!table?.TableArn) throw new ProvisioningError(`Cannot apply ResourcePolicy change for DynamoDB table ${logicalId}: DescribeTable returned no TableArn`, resourceType, logicalId, physicalId);
|
|
9114
|
+
await this.applyResourcePolicy(table.TableArn, properties["ResourcePolicy"], previousProperties["ResourcePolicy"]);
|
|
9115
|
+
}
|
|
9116
|
+
if (JSON.stringify(properties["KinesisStreamSpecification"]) !== JSON.stringify(previousProperties["KinesisStreamSpecification"])) await this.applyKinesisStreamingDestination(physicalId, properties["KinesisStreamSpecification"], previousProperties["KinesisStreamSpecification"]);
|
|
9117
|
+
if (JSON.stringify(properties["ContributorInsightsSpecification"]) !== JSON.stringify(previousProperties["ContributorInsightsSpecification"])) await this.applyContributorInsights(physicalId, properties["ContributorInsightsSpecification"], previousProperties["ContributorInsightsSpecification"]);
|
|
9104
9118
|
return {
|
|
9105
9119
|
physicalId,
|
|
9106
9120
|
wasReplaced: false,
|
|
@@ -9275,6 +9289,114 @@ var DynamoDBTableProvider = class {
|
|
|
9275
9289
|
}
|
|
9276
9290
|
}
|
|
9277
9291
|
/**
|
|
9292
|
+
* Extract the resource-policy document from the CFn `ResourcePolicy`
|
|
9293
|
+
* property and serialize it to the JSON string the DynamoDB APIs expect.
|
|
9294
|
+
*
|
|
9295
|
+
* CFn shape is `{ PolicyDocument: <JSON object | string> }`. Both
|
|
9296
|
+
* `CreateTable.ResourcePolicy` and `PutResourcePolicy.Policy` take a JSON
|
|
9297
|
+
* STRING, so a document already supplied as a string is passed through
|
|
9298
|
+
* verbatim (CDK can emit either an object or, post-intrinsic-resolution, a
|
|
9299
|
+
* string). Returns `undefined` when there is no policy document to apply.
|
|
9300
|
+
*/
|
|
9301
|
+
extractResourcePolicyDocument(spec) {
|
|
9302
|
+
if (spec === void 0 || spec === null) return void 0;
|
|
9303
|
+
const doc = spec["PolicyDocument"];
|
|
9304
|
+
if (doc === void 0 || doc === null) return void 0;
|
|
9305
|
+
return typeof doc === "string" ? doc : JSON.stringify(doc);
|
|
9306
|
+
}
|
|
9307
|
+
/**
|
|
9308
|
+
* Apply the table's `ResourcePolicy` via the separate `PutResourcePolicy` /
|
|
9309
|
+
* `DeleteResourcePolicy` APIs (used by `update()` — `create()` rides the
|
|
9310
|
+
* policy on CreateTable directly). On removal — when the template drops the
|
|
9311
|
+
* block but it was present before — the existing policy is deleted.
|
|
9312
|
+
*/
|
|
9313
|
+
async applyResourcePolicy(tableArn, spec, previousSpec) {
|
|
9314
|
+
const policyDoc = this.extractResourcePolicyDocument(spec);
|
|
9315
|
+
if (policyDoc !== void 0) {
|
|
9316
|
+
await this.retryOnTransientControlPlane(() => this.dynamoDBClient.send(new PutResourcePolicyCommand({
|
|
9317
|
+
ResourceArn: tableArn,
|
|
9318
|
+
Policy: policyDoc
|
|
9319
|
+
})), `put ResourcePolicy on ${tableArn}`);
|
|
9320
|
+
this.logger.debug(`Put ResourcePolicy on DynamoDB table ${tableArn}`);
|
|
9321
|
+
return;
|
|
9322
|
+
}
|
|
9323
|
+
if (previousSpec !== void 0 && previousSpec !== null) try {
|
|
9324
|
+
await this.retryOnTransientControlPlane(() => this.dynamoDBClient.send(new DeleteResourcePolicyCommand({ ResourceArn: tableArn })), `delete ResourcePolicy on ${tableArn}`);
|
|
9325
|
+
this.logger.debug(`Deleted ResourcePolicy on DynamoDB table ${tableArn}`);
|
|
9326
|
+
} catch (error) {
|
|
9327
|
+
if (!(error instanceof ResourceNotFoundException$1)) throw error;
|
|
9328
|
+
}
|
|
9329
|
+
}
|
|
9330
|
+
/**
|
|
9331
|
+
* Apply the table's `KinesisStreamSpecification` via the separate
|
|
9332
|
+
* Enable/Disable/Update `KinesisStreamingDestination` APIs (NOT a field on
|
|
9333
|
+
* CreateTable). CFn shape is
|
|
9334
|
+
* `{ StreamArn: string, ApproximateCreationDateTimePrecision?: 'MICROSECOND' | 'MILLISECOND' }`.
|
|
9335
|
+
*
|
|
9336
|
+
* Called from both `create()` (after the table is ACTIVE) and `update()`
|
|
9337
|
+
* (only when the value changed). On `update()`-side removal — template drops
|
|
9338
|
+
* the block but it was present before — streaming is disabled to the PREVIOUS
|
|
9339
|
+
* stream ARN. A same-ARN change of only the precision is a deliberate no-op
|
|
9340
|
+
* (re-enabling against an already-enabled stream errors), matching the
|
|
9341
|
+
* pre-existing WarmThroughput "no clean remap" stance; precision changes flow
|
|
9342
|
+
* through on the create / first-enable path.
|
|
9343
|
+
*/
|
|
9344
|
+
async applyKinesisStreamingDestination(tableName, spec, previousSpec) {
|
|
9345
|
+
const newArn = this.extractKinesisStreamArn(spec);
|
|
9346
|
+
const prevArn = this.extractKinesisStreamArn(previousSpec);
|
|
9347
|
+
if (newArn === prevArn) {
|
|
9348
|
+
if (newArn && JSON.stringify(spec?.["ApproximateCreationDateTimePrecision"]) !== JSON.stringify(previousSpec?.["ApproximateCreationDateTimePrecision"])) this.logger.warn(`Kinesis streaming ApproximateCreationDateTimePrecision change on ${tableName} was not applied (same stream ARN; precision-only updates are not yet supported)`);
|
|
9349
|
+
return;
|
|
9350
|
+
}
|
|
9351
|
+
if (prevArn) {
|
|
9352
|
+
await this.retryOnTransientControlPlane(() => this.dynamoDBClient.send(new DisableKinesisStreamingDestinationCommand({
|
|
9353
|
+
TableName: tableName,
|
|
9354
|
+
StreamArn: prevArn
|
|
9355
|
+
})), `disable Kinesis streaming on ${tableName}`);
|
|
9356
|
+
this.logger.debug(`Disabled Kinesis streaming destination ${prevArn} on DynamoDB table ${tableName}`);
|
|
9357
|
+
}
|
|
9358
|
+
if (newArn) {
|
|
9359
|
+
const precision = spec["ApproximateCreationDateTimePrecision"];
|
|
9360
|
+
await this.retryOnTransientControlPlane(() => this.dynamoDBClient.send(new EnableKinesisStreamingDestinationCommand({
|
|
9361
|
+
TableName: tableName,
|
|
9362
|
+
StreamArn: newArn,
|
|
9363
|
+
...precision ? { EnableKinesisStreamingConfiguration: { ApproximateCreationDateTimePrecision: precision } } : {}
|
|
9364
|
+
})), `enable Kinesis streaming on ${tableName}`);
|
|
9365
|
+
this.logger.debug(`Enabled Kinesis streaming destination ${newArn} on DynamoDB table ${tableName}`);
|
|
9366
|
+
}
|
|
9367
|
+
}
|
|
9368
|
+
extractKinesisStreamArn(spec) {
|
|
9369
|
+
if (spec === void 0 || spec === null) return void 0;
|
|
9370
|
+
const arn = spec["StreamArn"];
|
|
9371
|
+
return typeof arn === "string" ? arn : void 0;
|
|
9372
|
+
}
|
|
9373
|
+
/**
|
|
9374
|
+
* Apply the table's `ContributorInsightsSpecification` via the separate
|
|
9375
|
+
* `UpdateContributorInsights` API (NOT a field on CreateTable). CFn shape is
|
|
9376
|
+
* `{ Enabled: boolean, Mode?: 'ACCESSED_AND_THROTTLED_KEYS' | 'THROTTLED_KEYS' }`.
|
|
9377
|
+
*
|
|
9378
|
+
* Called from both `create()` (after the table is ACTIVE) and `update()`
|
|
9379
|
+
* (only when the value changed). On `update()`-side removal — template drops
|
|
9380
|
+
* the block but it was present before — insights is disabled.
|
|
9381
|
+
*/
|
|
9382
|
+
async applyContributorInsights(tableName, spec, previousSpec) {
|
|
9383
|
+
let action;
|
|
9384
|
+
let mode;
|
|
9385
|
+
if (spec !== void 0 && spec !== null) {
|
|
9386
|
+
const s = spec;
|
|
9387
|
+
const enabled = Boolean(s["Enabled"]);
|
|
9388
|
+
action = enabled ? "ENABLE" : "DISABLE";
|
|
9389
|
+
if (enabled && s["Mode"] !== void 0) mode = s["Mode"];
|
|
9390
|
+
} else if (previousSpec !== void 0 && previousSpec !== null) action = "DISABLE";
|
|
9391
|
+
if (action === void 0) return;
|
|
9392
|
+
await this.retryOnTransientControlPlane(() => this.dynamoDBClient.send(new UpdateContributorInsightsCommand({
|
|
9393
|
+
TableName: tableName,
|
|
9394
|
+
ContributorInsightsAction: action,
|
|
9395
|
+
...mode ? { ContributorInsightsMode: mode } : {}
|
|
9396
|
+
})), `set ContributorInsights on ${tableName}`);
|
|
9397
|
+
this.logger.debug(`Set ContributorInsightsAction=${action}${mode !== void 0 ? ` Mode=${mode}` : ""} on DynamoDB table ${tableName}`);
|
|
9398
|
+
}
|
|
9399
|
+
/**
|
|
9278
9400
|
* Poll DescribeTable until the table reaches ACTIVE status
|
|
9279
9401
|
*
|
|
9280
9402
|
* Uses a tight polling loop (1s intervals) instead of CC API's exponential
|
|
@@ -9425,6 +9547,39 @@ var DynamoDBTableProvider = class {
|
|
|
9425
9547
|
} catch (err) {
|
|
9426
9548
|
this.logger.debug(`Could not read TimeToLive for ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
9427
9549
|
}
|
|
9550
|
+
if (table.TableArn) try {
|
|
9551
|
+
const rpResp = await this.dynamoDBClient.send(new GetResourcePolicyCommand({ ResourceArn: table.TableArn }));
|
|
9552
|
+
if (rpResp.Policy) {
|
|
9553
|
+
let doc = rpResp.Policy;
|
|
9554
|
+
try {
|
|
9555
|
+
doc = JSON.parse(rpResp.Policy);
|
|
9556
|
+
} catch {}
|
|
9557
|
+
result["ResourcePolicy"] = { PolicyDocument: doc };
|
|
9558
|
+
}
|
|
9559
|
+
} catch (err) {
|
|
9560
|
+
if (!(err instanceof ResourceNotFoundException$1)) this.logger.debug(`Could not read ResourcePolicy for ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
9561
|
+
}
|
|
9562
|
+
try {
|
|
9563
|
+
const active = ((await this.dynamoDBClient.send(new DescribeKinesisStreamingDestinationCommand({ TableName: physicalId }))).KinesisDataStreamDestinations ?? []).find((d) => d.DestinationStatus === "ACTIVE" || d.DestinationStatus === "ENABLING");
|
|
9564
|
+
if (active?.StreamArn) {
|
|
9565
|
+
const kspec = { StreamArn: active.StreamArn };
|
|
9566
|
+
if (active.ApproximateCreationDateTimePrecision !== void 0) kspec["ApproximateCreationDateTimePrecision"] = active.ApproximateCreationDateTimePrecision;
|
|
9567
|
+
result["KinesisStreamSpecification"] = kspec;
|
|
9568
|
+
}
|
|
9569
|
+
} catch (err) {
|
|
9570
|
+
this.logger.debug(`Could not read KinesisStreamingDestination for ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
9571
|
+
}
|
|
9572
|
+
try {
|
|
9573
|
+
const ciResp = await this.dynamoDBClient.send(new DescribeContributorInsightsCommand({ TableName: physicalId }));
|
|
9574
|
+
const status = ciResp.ContributorInsightsStatus;
|
|
9575
|
+
if (status === "ENABLED" || status === "DISABLED") {
|
|
9576
|
+
const cspec = { Enabled: status === "ENABLED" };
|
|
9577
|
+
if (status === "ENABLED" && ciResp.ContributorInsightsMode !== void 0) cspec["Mode"] = ciResp.ContributorInsightsMode;
|
|
9578
|
+
result["ContributorInsightsSpecification"] = cspec;
|
|
9579
|
+
}
|
|
9580
|
+
} catch (err) {
|
|
9581
|
+
this.logger.debug(`Could not read ContributorInsights for ${physicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
9582
|
+
}
|
|
9428
9583
|
return result;
|
|
9429
9584
|
} catch (err) {
|
|
9430
9585
|
if (err instanceof ResourceNotFoundException$1) return void 0;
|
|
@@ -24112,6 +24267,83 @@ function isEmptyObjectPlaceholder(value) {
|
|
|
24112
24267
|
return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
|
|
24113
24268
|
}
|
|
24114
24269
|
/**
|
|
24270
|
+
* The CFn `EnabledMfas` factor names AND their MFA-config-API meaning.
|
|
24271
|
+
*
|
|
24272
|
+
* `EnabledMfas` is a CFn-level `Array of String`, but Cognito has no
|
|
24273
|
+
* `EnabledMfas` field on `CreateUserPool` / `UpdateUserPool`. The factors are
|
|
24274
|
+
* activated via the separate `SetUserPoolMfaConfig` control-plane API, one
|
|
24275
|
+
* sub-block per factor:
|
|
24276
|
+
*
|
|
24277
|
+
* - `SMS_MFA` -> `SmsMfaConfiguration` (needs the pool's
|
|
24278
|
+
* `SmsConfiguration` SNS-caller ARN to be set too)
|
|
24279
|
+
* - `SOFTWARE_TOKEN_MFA` -> `SoftwareTokenMfaConfiguration.Enabled = true`
|
|
24280
|
+
* - `EMAIL_OTP` -> `EmailMfaConfiguration` (carries the email-OTP
|
|
24281
|
+
* message/subject template — i.e. CFn's
|
|
24282
|
+
* `EmailAuthenticationMessage` / `Subject`)
|
|
24283
|
+
*/
|
|
24284
|
+
const MFA_FACTOR_SMS = "SMS_MFA";
|
|
24285
|
+
const MFA_FACTOR_SOFTWARE_TOKEN = "SOFTWARE_TOKEN_MFA";
|
|
24286
|
+
const MFA_FACTOR_EMAIL_OTP = "EMAIL_OTP";
|
|
24287
|
+
/**
|
|
24288
|
+
* Build the `SetUserPoolMfaConfig` request from the CFn-level MFA properties,
|
|
24289
|
+
* or return `undefined` when none of the MFA-config-API-routed properties are
|
|
24290
|
+
* present (so the caller skips the extra control-plane call entirely).
|
|
24291
|
+
*
|
|
24292
|
+
* The properties that route through `SetUserPoolMfaConfig` (NOT CreateUserPool):
|
|
24293
|
+
* - `EnabledMfas` -> per-factor sub-blocks (see constants above)
|
|
24294
|
+
* - `EmailAuthenticationMessage`/`EmailAuthenticationSubject` -> the
|
|
24295
|
+
* `EmailMfaConfiguration` message/subject (email-OTP template)
|
|
24296
|
+
* - `WebAuthnRelyingPartyID`/`WebAuthnUserVerification` -> `WebAuthnConfiguration`
|
|
24297
|
+
*
|
|
24298
|
+
* `MfaConfiguration` (ON/OFF/OPTIONAL) MUST be threaded into this request:
|
|
24299
|
+
* `SetUserPoolMfaConfig` is a full-replace of the pool's MFA state, and an
|
|
24300
|
+
* omitted `MfaConfiguration` defaults to OFF on the wire — which resets the
|
|
24301
|
+
* pool to MFA-disabled and makes AWS reject (or silently drop) the per-factor
|
|
24302
|
+
* sub-blocks we are trying to enable. Use the template's `MfaConfiguration`
|
|
24303
|
+
* when present; default to `OPTIONAL` when factors are present but the template
|
|
24304
|
+
* omitted it (factors are meaningless under OFF, and OPTIONAL enables them
|
|
24305
|
+
* without forcing MFA on every user).
|
|
24306
|
+
*/
|
|
24307
|
+
/**
|
|
24308
|
+
* True when any MFA-config-API-routed property is present, i.e. a
|
|
24309
|
+
* `SetUserPoolMfaConfig` call will run post-create. When true, `create()` must
|
|
24310
|
+
* NOT forward `MfaConfiguration` to `CreateUserPool`: AWS rejects
|
|
24311
|
+
* `CreateUserPool` with `MfaConfiguration: ON/OPTIONAL` unless the pool already
|
|
24312
|
+
* has SMS configured (+ phone_number auto-verification) OR software-token MFA
|
|
24313
|
+
* enabled — but software-token / email-OTP MFA can only be enabled via the
|
|
24314
|
+
* post-create `SetUserPoolMfaConfig` call, not on `CreateUserPool`. So the
|
|
24315
|
+
* correct sequence is: `CreateUserPool` WITHOUT `MfaConfiguration` (defaults
|
|
24316
|
+
* OFF) -> `SetUserPoolMfaConfig` sets `MfaConfiguration` + the factor blocks
|
|
24317
|
+
* together (the factor satisfies the MFA requirement, no SMS needed). This
|
|
24318
|
+
* mirrors how CloudFormation/CDK sequence the two calls.
|
|
24319
|
+
*/
|
|
24320
|
+
function hasMfaConfigProps(properties) {
|
|
24321
|
+
const enabledMfas = Array.isArray(properties["EnabledMfas"]) ? properties["EnabledMfas"] : void 0;
|
|
24322
|
+
return enabledMfas !== void 0 && enabledMfas.length > 0 || !!properties["EmailAuthenticationMessage"] || !!properties["EmailAuthenticationSubject"] || !!properties["WebAuthnRelyingPartyID"] || !!properties["WebAuthnUserVerification"];
|
|
24323
|
+
}
|
|
24324
|
+
function buildMfaConfigRequest(physicalId, properties) {
|
|
24325
|
+
const enabledMfas = Array.isArray(properties["EnabledMfas"]) ? properties["EnabledMfas"] : void 0;
|
|
24326
|
+
const emailMessage = properties["EmailAuthenticationMessage"] || void 0;
|
|
24327
|
+
const emailSubject = properties["EmailAuthenticationSubject"] || void 0;
|
|
24328
|
+
const webAuthnRpId = properties["WebAuthnRelyingPartyID"] || void 0;
|
|
24329
|
+
const webAuthnUserVerification = properties["WebAuthnUserVerification"] || void 0;
|
|
24330
|
+
if (!hasMfaConfigProps(properties)) return void 0;
|
|
24331
|
+
const request = { UserPoolId: physicalId };
|
|
24332
|
+
request.MfaConfiguration = properties["MfaConfiguration"] ?? "OPTIONAL";
|
|
24333
|
+
const factors = new Set(enabledMfas ?? []);
|
|
24334
|
+
if (factors.has(MFA_FACTOR_SOFTWARE_TOKEN)) request.SoftwareTokenMfaConfiguration = { Enabled: true };
|
|
24335
|
+
if (factors.has(MFA_FACTOR_SMS)) request.SmsMfaConfiguration = { ...properties["SmsConfiguration"] ? { SmsConfiguration: properties["SmsConfiguration"] } : {} };
|
|
24336
|
+
if (factors.has(MFA_FACTOR_EMAIL_OTP) || emailMessage !== void 0 || emailSubject !== void 0) request.EmailMfaConfiguration = {
|
|
24337
|
+
...emailMessage !== void 0 ? { Message: emailMessage } : {},
|
|
24338
|
+
...emailSubject !== void 0 ? { Subject: emailSubject } : {}
|
|
24339
|
+
};
|
|
24340
|
+
if (webAuthnRpId !== void 0 || webAuthnUserVerification !== void 0) request.WebAuthnConfiguration = {
|
|
24341
|
+
...webAuthnRpId !== void 0 ? { RelyingPartyId: webAuthnRpId } : {},
|
|
24342
|
+
...webAuthnUserVerification !== void 0 ? { UserVerification: webAuthnUserVerification } : {}
|
|
24343
|
+
};
|
|
24344
|
+
return request;
|
|
24345
|
+
}
|
|
24346
|
+
/**
|
|
24115
24347
|
* AWS Cognito User Pool Provider
|
|
24116
24348
|
*
|
|
24117
24349
|
* Implements resource provisioning for AWS::Cognito::UserPool using the Cognito SDK.
|
|
@@ -24146,8 +24378,15 @@ var CognitoUserPoolProvider = class {
|
|
|
24146
24378
|
"EmailVerificationMessage",
|
|
24147
24379
|
"EmailVerificationSubject",
|
|
24148
24380
|
"SmsAuthenticationMessage",
|
|
24149
|
-
"SmsVerificationMessage"
|
|
24381
|
+
"SmsVerificationMessage",
|
|
24382
|
+
"UserPoolTier",
|
|
24383
|
+
"EnabledMfas",
|
|
24384
|
+
"EmailAuthenticationMessage",
|
|
24385
|
+
"EmailAuthenticationSubject",
|
|
24386
|
+
"WebAuthnRelyingPartyID",
|
|
24387
|
+
"WebAuthnUserVerification"
|
|
24150
24388
|
])]]);
|
|
24389
|
+
unhandledByDesign = new Map([["AWS::Cognito::UserPool", new Map([["WebAuthnFactorConfiguration", "No SDK wire path: @aws-sdk/client-cognito-identity-provider has no field accepting SINGLE_FACTOR | MULTI_FACTOR_WITH_USER_VERIFICATION (not on CreateUserPool/UpdateUserPool, nor SetUserPoolMfaConfig.WebAuthnConfiguration which only carries RelyingPartyId/UserVerification); CC-API-registry-only property"]])]]);
|
|
24151
24390
|
getClient() {
|
|
24152
24391
|
if (!this.cognitoClient) this.cognitoClient = new CognitoIdentityProviderClient(this.providerRegion ? { region: this.providerRegion } : {});
|
|
24153
24392
|
return this.cognitoClient;
|
|
@@ -24158,6 +24397,7 @@ var CognitoUserPoolProvider = class {
|
|
|
24158
24397
|
async create(logicalId, resourceType, properties) {
|
|
24159
24398
|
this.logger.debug(`Creating Cognito User Pool ${logicalId}`);
|
|
24160
24399
|
const poolName = properties["UserPoolName"] || generateResourceName(logicalId, { maxLength: 128 });
|
|
24400
|
+
let createdUserPoolId;
|
|
24161
24401
|
try {
|
|
24162
24402
|
const createParams = { PoolName: poolName };
|
|
24163
24403
|
if (properties["AutoVerifiedAttributes"]) createParams.AutoVerifiedAttributes = properties["AutoVerifiedAttributes"];
|
|
@@ -24168,7 +24408,7 @@ var CognitoUserPoolProvider = class {
|
|
|
24168
24408
|
}
|
|
24169
24409
|
if (properties["Schema"]) createParams.Schema = properties["Schema"];
|
|
24170
24410
|
if (properties["LambdaConfig"]) createParams.LambdaConfig = properties["LambdaConfig"];
|
|
24171
|
-
if (properties["MfaConfiguration"]) createParams.MfaConfiguration = properties["MfaConfiguration"];
|
|
24411
|
+
if (properties["MfaConfiguration"] && !hasMfaConfigProps(properties)) createParams.MfaConfiguration = properties["MfaConfiguration"];
|
|
24172
24412
|
if (properties["UserPoolTags"]) createParams.UserPoolTags = properties["UserPoolTags"];
|
|
24173
24413
|
if (properties["AdminCreateUserConfig"]) createParams.AdminCreateUserConfig = properties["AdminCreateUserConfig"];
|
|
24174
24414
|
if (properties["AccountRecoverySetting"]) createParams.AccountRecoverySetting = properties["AccountRecoverySetting"];
|
|
@@ -24185,13 +24425,16 @@ var CognitoUserPoolProvider = class {
|
|
|
24185
24425
|
if (properties["EmailVerificationSubject"]) createParams.EmailVerificationSubject = properties["EmailVerificationSubject"];
|
|
24186
24426
|
if (properties["SmsAuthenticationMessage"]) createParams.SmsAuthenticationMessage = properties["SmsAuthenticationMessage"];
|
|
24187
24427
|
if (properties["SmsVerificationMessage"]) createParams.SmsVerificationMessage = properties["SmsVerificationMessage"];
|
|
24428
|
+
if (properties["UserPoolTier"]) createParams.UserPoolTier = properties["UserPoolTier"];
|
|
24188
24429
|
const userPool = (await this.getClient().send(new CreateUserPoolCommand(createParams))).UserPool;
|
|
24189
24430
|
if (!userPool?.Id) throw new Error("CreateUserPool did not return UserPool.Id");
|
|
24190
24431
|
const userPoolId = userPool.Id;
|
|
24432
|
+
createdUserPoolId = userPoolId;
|
|
24191
24433
|
const userPoolArn = userPool.Arn;
|
|
24192
24434
|
const region = await this.getClient().config.region();
|
|
24193
24435
|
const providerName = `cognito-idp.${region}.amazonaws.com/${userPoolId}`;
|
|
24194
24436
|
const providerUrl = `https://cognito-idp.${region}.amazonaws.com/${userPoolId}`;
|
|
24437
|
+
await this.applyMfaConfig(userPoolId, properties);
|
|
24195
24438
|
this.logger.debug(`Successfully created Cognito User Pool ${logicalId}: ${userPoolId}`);
|
|
24196
24439
|
return {
|
|
24197
24440
|
physicalId: userPoolId,
|
|
@@ -24203,11 +24446,46 @@ var CognitoUserPoolProvider = class {
|
|
|
24203
24446
|
}
|
|
24204
24447
|
};
|
|
24205
24448
|
} catch (error) {
|
|
24449
|
+
if (createdUserPoolId) try {
|
|
24450
|
+
await this.getClient().send(new DeleteUserPoolCommand({ UserPoolId: createdUserPoolId }));
|
|
24451
|
+
this.logger.debug(`Rolled back partially-created Cognito User Pool ${createdUserPoolId}`);
|
|
24452
|
+
} catch (rollbackError) {
|
|
24453
|
+
this.logger.warn(`Failed to roll back partially-created Cognito User Pool ${createdUserPoolId}: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`);
|
|
24454
|
+
}
|
|
24206
24455
|
const cause = error instanceof Error ? error : void 0;
|
|
24207
24456
|
throw new ProvisioningError(`Failed to create Cognito User Pool ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, poolName, cause);
|
|
24208
24457
|
}
|
|
24209
24458
|
}
|
|
24210
24459
|
/**
|
|
24460
|
+
* Apply the MFA-config-API-routed properties (EnabledMfas / email-OTP
|
|
24461
|
+
* message+subject / WebAuthn) via SetUserPoolMfaConfig. No-op when none are
|
|
24462
|
+
* present. Wrapped in a transient-error retry because back-to-back
|
|
24463
|
+
* control-plane writes on a freshly-created pool can briefly conflict
|
|
24464
|
+
* (mirrors DynamoDBTableProvider.retryOnTransientControlPlane).
|
|
24465
|
+
*/
|
|
24466
|
+
async applyMfaConfig(physicalId, properties) {
|
|
24467
|
+
const request = buildMfaConfigRequest(physicalId, properties);
|
|
24468
|
+
if (!request) return;
|
|
24469
|
+
await this.retryOnTransientControlPlane(() => this.getClient().send(new SetUserPoolMfaConfigCommand(request)), `SetUserPoolMfaConfig(${physicalId})`);
|
|
24470
|
+
}
|
|
24471
|
+
/**
|
|
24472
|
+
* Retry a Cognito control-plane call on transient "settling" errors. A
|
|
24473
|
+
* SetUserPoolMfaConfig issued immediately after CreateUserPool (or another
|
|
24474
|
+
* control-plane write) can briefly hit `ConcurrentModificationException` /
|
|
24475
|
+
* "please retry". Backoff 1s -> 2s -> 4s, default 3 attempts.
|
|
24476
|
+
*/
|
|
24477
|
+
async retryOnTransientControlPlane(fn, label, maxAttempts = 3) {
|
|
24478
|
+
for (let attempt = 1;; attempt++) try {
|
|
24479
|
+
return await fn();
|
|
24480
|
+
} catch (error) {
|
|
24481
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
24482
|
+
if (!((error instanceof Error ? error.name : "") === "ConcurrentModificationException" || /concurrent modification|please retry|try again|in progress/i.test(msg)) || attempt >= maxAttempts) throw error;
|
|
24483
|
+
const delayMs = Math.min(1e3 * 2 ** (attempt - 1), 4e3);
|
|
24484
|
+
this.logger.debug(`Transient error on "${label}" (attempt ${attempt}/${maxAttempts}): ${msg} — retrying in ${delayMs}ms`);
|
|
24485
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
24486
|
+
}
|
|
24487
|
+
}
|
|
24488
|
+
/**
|
|
24211
24489
|
* Update a Cognito User Pool
|
|
24212
24490
|
*
|
|
24213
24491
|
* Note: PoolName (UserPoolName) and Schema are immutable and cannot be changed after creation.
|
|
@@ -24238,7 +24516,9 @@ var CognitoUserPoolProvider = class {
|
|
|
24238
24516
|
if (properties["EmailVerificationSubject"] !== void 0) updateParams.EmailVerificationSubject = properties["EmailVerificationSubject"];
|
|
24239
24517
|
if (properties["SmsAuthenticationMessage"] !== void 0) updateParams.SmsAuthenticationMessage = properties["SmsAuthenticationMessage"];
|
|
24240
24518
|
if (properties["SmsVerificationMessage"] !== void 0) updateParams.SmsVerificationMessage = properties["SmsVerificationMessage"];
|
|
24519
|
+
if (properties["UserPoolTier"]) updateParams.UserPoolTier = properties["UserPoolTier"];
|
|
24241
24520
|
await this.getClient().send(new UpdateUserPoolCommand(updateParams));
|
|
24521
|
+
await this.applyMfaConfig(physicalId, properties);
|
|
24242
24522
|
this.logger.debug(`Successfully updated Cognito User Pool ${logicalId}`);
|
|
24243
24523
|
const userPool = (await this.getClient().send(new DescribeUserPoolCommand({ UserPoolId: physicalId }))).UserPool;
|
|
24244
24524
|
const region = await this.getClient().config.region();
|
|
@@ -24372,6 +24652,21 @@ var CognitoUserPoolProvider = class {
|
|
|
24372
24652
|
for (const [k, v] of Object.entries(pool.UserPoolTags)) if (!k.startsWith("aws:")) userTags[k] = v;
|
|
24373
24653
|
}
|
|
24374
24654
|
result["UserPoolTags"] = userTags;
|
|
24655
|
+
result["UserPoolTier"] = pool.UserPoolTier ?? "ESSENTIALS";
|
|
24656
|
+
try {
|
|
24657
|
+
const mfa = await this.getClient().send(new GetUserPoolMfaConfigCommand({ UserPoolId: physicalId }));
|
|
24658
|
+
const enabledMfas = [];
|
|
24659
|
+
if (mfa.SmsMfaConfiguration) enabledMfas.push(MFA_FACTOR_SMS);
|
|
24660
|
+
if (mfa.SoftwareTokenMfaConfiguration?.Enabled) enabledMfas.push(MFA_FACTOR_SOFTWARE_TOKEN);
|
|
24661
|
+
if (mfa.EmailMfaConfiguration) enabledMfas.push(MFA_FACTOR_EMAIL_OTP);
|
|
24662
|
+
result["EnabledMfas"] = enabledMfas;
|
|
24663
|
+
result["EmailAuthenticationMessage"] = mfa.EmailMfaConfiguration?.Message ?? "";
|
|
24664
|
+
result["EmailAuthenticationSubject"] = mfa.EmailMfaConfiguration?.Subject ?? "";
|
|
24665
|
+
result["WebAuthnRelyingPartyID"] = mfa.WebAuthnConfiguration?.RelyingPartyId ?? "";
|
|
24666
|
+
result["WebAuthnUserVerification"] = mfa.WebAuthnConfiguration?.UserVerification ?? "";
|
|
24667
|
+
} catch (mfaErr) {
|
|
24668
|
+
this.logger.debug(`GetUserPoolMfaConfig failed for ${physicalId}, skipping MFA-derived drift keys: ${mfaErr instanceof Error ? mfaErr.message : String(mfaErr)}`);
|
|
24669
|
+
}
|
|
24375
24670
|
return result;
|
|
24376
24671
|
}
|
|
24377
24672
|
/**
|
|
@@ -53033,7 +53328,7 @@ function reorderArgs(argv) {
|
|
|
53033
53328
|
async function main() {
|
|
53034
53329
|
installPipeCloseHandler();
|
|
53035
53330
|
const program = new Command();
|
|
53036
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
53331
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.217.0");
|
|
53037
53332
|
program.addCommand(createBootstrapCommand());
|
|
53038
53333
|
program.addCommand(createSynthCommand());
|
|
53039
53334
|
program.addCommand(createListCommand());
|