@go-to-k/cdkd 0.311.0 → 0.312.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/README.md +2 -2
- package/dist/{asg-provider-CIg_guZ-.js → asg-provider-CVLTQtQr.js} +3 -3
- package/dist/{asg-provider-CIg_guZ-.js.map → asg-provider-CVLTQtQr.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{created-resource-sink-DlzoIY-1.js → created-resource-sink-BT2Dfnpt.js} +2 -2
- package/dist/{created-resource-sink-DlzoIY-1.js.map → created-resource-sink-BT2Dfnpt.js.map} +1 -1
- package/dist/{db-instance-modify-retry-1y0kIPCO.js → db-instance-modify-retry-D7wXWxVo.js} +2 -2
- package/dist/{db-instance-modify-retry-1y0kIPCO.js.map → db-instance-modify-retry-D7wXWxVo.js.map} +1 -1
- package/dist/{deploy-engine-BF5exXUb.js → deploy-engine-CVNzK__j.js} +303 -78
- package/dist/deploy-engine-CVNzK__j.js.map +1 -0
- package/dist/{iam-role-provider-qvhlVnrn.js → iam-role-provider-DM7bN9m1.js} +3 -3
- package/dist/{iam-role-provider-qvhlVnrn.js.map → iam-role-provider-DM7bN9m1.js.map} +1 -1
- package/dist/index.js +3 -3
- package/dist/{neptune-provider-D9ac71Ca.js → neptune-provider-qdoLunCh.js} +53 -6
- package/dist/neptune-provider-qdoLunCh.js.map +1 -0
- package/dist/{program-DbnTHlwR.js → program-Nk_95KKk.js} +16 -10
- package/dist/program-Nk_95KKk.js.map +1 -0
- package/dist/{provider-classes-DktsDsTf.js → provider-classes-Dz0pYmlJ.js} +1045 -80
- package/dist/provider-classes-Dz0pYmlJ.js.map +1 -0
- package/dist/{rds-provider-0LUsn9Wl.js → rds-provider-CXSZq1c8.js} +25 -14
- package/dist/rds-provider-CXSZq1c8.js.map +1 -0
- package/dist/{version-BA4rBBLp.js → version-BqCEt5Wu.js} +2 -2
- package/dist/{version-BA4rBBLp.js.map → version-BqCEt5Wu.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-BF5exXUb.js.map +0 -1
- package/dist/neptune-provider-D9ac71Ca.js.map +0 -1
- package/dist/program-DbnTHlwR.js.map +0 -1
- package/dist/provider-classes-DktsDsTf.js.map +0 -1
- package/dist/rds-provider-0LUsn9Wl.js.map +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { r as getAwsClients, s as withApiGatewayPacing } from "./aws-clients-Bu9EMILF.js";
|
|
2
2
|
import { B as SECRET_REF_MAX_CODE_POINTS, C as generateResourceName, D as getCurrentStackInstanceId, J as displayStackName, K as displayIdent, M as recordedGeneratedNameKept, Q as safeMsg, T as generatedNameFor, Y as isPasteableIdent, Z as plainIdentOr, a as safeStringify, i as isAwsAuthoredFailure, k as isBeforeStateRead, n as describeAwsFailure, q as displaySafe, r as describeAwsStatusReason, s as getLogger, t as VERBOSE_POINTER, w as generateResourceNameWithFallback } from "./aws-failure-text-NSBdKPYK.js";
|
|
3
|
-
import { $ as
|
|
3
|
+
import { $ as logGroupProtectionSite, $n as plainOrDescribed, A as withoutServerErrorRetries, Ar as markNonRetryable, At as createMaskedLogSinks, B as quotedRemedyLogicalId, C as RecentIdSet, Ct as compositeIdSeparatorRefusal, D as replayFollowedAmbiguousAttempt, Dr as THROTTLING_ERROR_NAMES, E as isInsideWindow, Et as packCompositeId, F as VALUE_NOT_SHOWN, Ft as withDerivedNameMasks, G as ProtectionFlipRegistry, Gt as markCreatedBeforeFailure, H as remedyLogicalId, Ht as isAuxiliaryFailure, I as isPlainImportJson, J as deleteWithProtectionCompensation, Jn as commandHole, Kt as markSupersedesEarlierCreate, L as isPlainImportValue, Mn as ProvisioningError, Mr as wrapMaskedAwsError, Mt as isSecretDerivedValue, N as markNotGone, Nt as maskDeep, O as replayedSendWindow, Or as isMarkedNonRetryable, Ot as segmentAfterAnchor, P as assertRegionMatch, Pn as ResourceUpdateNotSupportedError, Pt as maskerOrIdentity, Q as isTerminalDeleteFailure, R as isQuotableImportValue, Rt as clearCreatedBeforeFailure, S as AmbiguousCreateLatch, Sr as isExplicitDenyError, St as compositeIdFormatMessage, T as createAttemptKey, Tr as isTransientServerError, Tt as logicalIdShown, U as resolveExplicitPhysicalId, V as refusalTypeShown, Wt as markAuxiliaryFailure, Xn as isInertUnquoted, Yn as hasClauseBreak, Z as isTerminalDbWaitStatus, Zn as pasteableCommand, _n as CdkdError, a as retractCreatedResource, an as injectiveKey, at as userPoolProtectionSite, bt as startInterruptWatch, c as SECRET_DERIVED_READ_LIVE, ct as WITHHELD_AWS_COMMAND, d as readPrincipalLists, dn as ambientClientDefaults, dt as protectedReplacementAdvice, et as observeThenDisableProtection, fn as ambientCredentialConfig, fr as markNameCollision, ft as renderDisableCommand, h as clearOnUpdateRemoval, hn as AccountIdUnavailableError, i as reportCreatedResource, j as RESOURCE_NOT_FOUND, jr as markRedactedCause, jt as createMaskedRetryLogger, k as setBounded, kr as isThrottlingError, kt as stateOrphanRecordRemedy, l as holdsSecretDerivedEntry, lt as isAwsCliLiteral, mn as credentialFingerprint, mr as relayedNameCollision, mt as ElapsedBudgetRegistry, nr as shellQuote, nt as rdsFamilyProtectionSite, on as injectiveKeyPrefix, p as recordedPrincipalsRepair, pn as clientDefaultsFor, pr as markReplayMayCollide, pt as ElapsedBudget, q as deleteAfterProtectionFlipWithFinalSnapshot, rr as withheldTargetClause, st as UNNAMEABLE_ID_CLAUSE, tt as protectionFlipKey, u as onlySecretDerived, un as withPasteableAwsProfile, ut as pasteableAwsCommand, v as removedTemplateKeys, vr as explicitDenyPolicyKind, w as ambiguousAttemptLead, wr as isRetryableTransientError, wt as compositeIdSkipResult, x as AMBIGUOUS_LATCH_TTL_MS, xr as isAmbiguousOutcomeError, xt as canonicalizeRoute53QueryName, y as withRemovalDefaults, yt as isInterruptedWaitError, z as normalizeAwsTagsToCfn } from "./created-resource-sink-BT2Dfnpt.js";
|
|
4
4
|
import { c as ambientRegion } from "./aws-client-defaults-BX9Y_fKp.js";
|
|
5
|
-
import { $
|
|
6
|
-
import { n as collectInlinePolicyNamesManagedBySiblings, r as IamCreateClientCache, t as IAMRoleProvider } from "./iam-role-provider-
|
|
7
|
-
import { a as resolveSecretDerivedPrincipals, i as isResolvableSecretPrincipalList, n as runDestroyForStack, o as canonicalizeIpProtocolValue, r as holdsUnprovenSecretPrincipalToken, s as resolvedResourceTimeoutMs, t as canonicalizeIpv4Cidr } from "./program-
|
|
8
|
-
import { t as modifyDbInstanceWhenAvailable } from "./db-instance-modify-retry-
|
|
9
|
-
import { RDSProvider } from "./rds-provider-
|
|
10
|
-
import { NeptuneProvider } from "./neptune-provider-
|
|
11
|
-
import { ASGProvider } from "./asg-provider-
|
|
5
|
+
import { $ as getPriorAttempts, $s as isWarmThroughputDecrease, A as DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS, Ad as renderAssemblyPathEscape, Ai as acquireIdempotencyToken, Ao as accountArgs, B as deleteTableWithIndexBusyRetry, Bc as markSameGenerationBag, Bi as refuseMalformedDesiredTags, Bn as isRedactedRecordedValue, Bs as findSilentDropProperties, C as planContributorInsightsOp, Co as passedParameterClassesOf, D as reverseMapTableContributorInsights, E as reverseMapIndexContributorInsights, Ei as earliestDefined, F as resolveDynamoDbDeleteBudgetClock, Fa as s3BucketDomainName, Fi as markDeleteStarted, Fr as getStackRecords, G as isTtlRateLimited, H as relayedIndexBusyDelete, Hc as recordReferenceProvenanceEntry, Hi as tagPlanWarning, Hn as redactedDeleteAddressSkip, Hs as withoutSilentDropProperties, I as resolveDynamoDbDeleteBudgetMs, Ia as s3BucketDualStackDomainName, Ii as DBPROXY_TAGS_WHAT, It as getNestedRevertRun, J as sendTtlWaitingOutRateLimit, K as planTimeToLive, Kc as hasMaskableValues, L as DELETE_INDEX_WAIT_PROCEED_NOTE, La as s3BucketRegionalDomainName, Li as DBPROXY_TAG_OPTIONS, Ln as getCurrentProducerRegions, Lr as replacedDeleteFailureVerdict, Ls as withheldAccountClause, M as beginDeleteWait, N as compensateRemovedDeletionProtection, Na as isSettledInstanceState, Nr as awaitInFlightSibling, O as stripIndexContributorInsights, Od as describeFileReadFailure, Oi as reserveStackCreateToken, P as deleteBudgetKey, Pa as s3BucketArn, Pc as passedNoEchoParametersOf, Pi as isRefusedByName, Q as isTruthyCfnBoolean, Qs as coerceWarmThroughput$1, R as INDEX_SETTLE_POLL_INTERVAL_MS, Ra as s3BucketWebsiteUrl, Ri as planTagDiff, S as indexDeclaresContributorInsights, Sa as reEnableInstanceApiTermination, Sc as sameLambdaFunctionAddress, T as readContributorInsightsSpec, Ta as isUsableAttemptedName, Ts as refuseMalformedResourcesForDestroy, U as waitForIndexesSettled, Ua as outputReferenceProvenanceOf, Uc as snapshotPassProvenance, Ui as definedAttributes, Ut as getCurrentNestedStackContext, V as maskedLogger, Vc as redactForState, Vi as tagMapAsList, Vn as redactedDeleteAddressFields, W as isTtlAlreadyDisabled, Wi as stringifyIfAssigned, Wt as withNestedStackContext, X as S3_AUTO_DELETE_OBJECTS_TAG, Xi as waitForLambdaFunctionActive, Y as ECR_AUTO_DELETE_IMAGES_TAG, Z as hasCdkAutoDeleteTag, Zs as WARM_THROUGHPUT_MEMBERS, _ as streamMemberRefusals, _l as recordAttributeIdCopy, ac as configIntegerRefusal, as as refuseMalformedNestedChildOutputs, b as CONTRIBUTOR_INSIGHTS_KEY, ba as observeThenDisableInstanceApiTermination, bc as canonicalLambdaFunctionName, bl as carriesSecretMask, bo as parseWebACLArn, c as DynamoDBGlobalTableProvider, ca as unchangedBehindSecretReference, cc as replayWarn, cl as dynamicReferenceTokens, d as declaredStreamPolicyMember, dc as requireConfigString, dd as decodeListingKey, dt as listNestedTemplateRows, ea as getCurrentResourceSecrets, ec as toCfnInteger, en as chunks, et as markRefusedBeforeApplying, f as declaredStreamTagsMember, ft as renderNestedTemplateTreeDefect, fu as rewriteTemplateAssetReferences, g as streamDeclaresTags, ga as markWaitAbandoned, gc as blockDeviceMappingsDifferOnlyInDeleteOnTermination, gl as physicalNameCopiesOf, h as streamDeclaresPolicy, ha as isWaitAbandonedError, hc as withRetry, hd as derivePartitionAndUrlSuffix, hl as recoverMaskedOutput, ic as configBooleanRefusal, iu as timePhase, j as DYNAMODB_DELETE_POLL_COST_MS, jd as resolveAssemblyPath, k as DYNAMODB_DELETE_DEADLINE_MARGIN_MS, kd as displayAssemblyPath, l as STREAM_POLICY_KEY, lc as requireConfigArray, lo as getAccountInfo, lt as findNestedTemplateTreeDefect, m as reverseMapStreamPolicy, ma as withIndeterminateGuard, md as canonicalizeRegion, nc as coerceCfnBoolean, nn as lookupEachName, oa as slowCcOperationTimeoutMs, oc as configStringRefusal, ol as withoutPhysicalNameCopies, p as planStreamMemberOps, pa as deleteSkipReason, pi as secretNamedAttributeNamesOf, q as readTtlSpec, rc as coerceCfnInteger, rn as withApiLimit, sa as onlySecretReferencesDiffer, sc as readConfigString, su as stringifyValue, t as DeployEngine, tc as toFiniteNumber, tn as isAccessDeniedError, u as STREAM_TAGS_KEY, uc as requireConfigObject, ut as isAbsoluteAssetPath, v as streamPolicyMatchesDeclared, va as ec2InstanceProtectionSite, vc as ecsServiceLaunchTypeSetOrChanged, vt as enclosingDeadlineExpired, w as planIndexContributorInsightsOps, x as contributorInsightsRefusals, xa as reDisableInstanceApiTermination, xc as lambdaFunctionNameForMask, y as streamTagsMatchDeclared, ya as isTerminationProtectionPropagationError, yc as emrClusterInstancesReplaced, yt as enclosingDeadlineRemainingMs, z as TABLE_INDEX_NOUN, zi as readTagList, zn as REDACTED_DELETE_ADDRESS_SKIP_REASON, zt as revertNestedChildFromJournal } from "./deploy-engine-CVNzK__j.js";
|
|
6
|
+
import { n as collectInlinePolicyNamesManagedBySiblings, r as IamCreateClientCache, t as IAMRoleProvider } from "./iam-role-provider-DM7bN9m1.js";
|
|
7
|
+
import { a as resolveSecretDerivedPrincipals, i as isResolvableSecretPrincipalList, n as runDestroyForStack, o as canonicalizeIpProtocolValue, r as holdsUnprovenSecretPrincipalToken, s as resolvedResourceTimeoutMs, t as canonicalizeIpv4Cidr } from "./program-Nk_95KKk.js";
|
|
8
|
+
import { t as modifyDbInstanceWhenAvailable } from "./db-instance-modify-retry-D7wXWxVo.js";
|
|
9
|
+
import { RDSProvider } from "./rds-provider-CXSZq1c8.js";
|
|
10
|
+
import { NeptuneProvider } from "./neptune-provider-qdoLunCh.js";
|
|
11
|
+
import { ASGProvider } from "./asg-provider-CVLTQtQr.js";
|
|
12
12
|
import { createHash, randomUUID } from "node:crypto";
|
|
13
13
|
import { CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListBucketsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client } from "@aws-sdk/client-s3";
|
|
14
14
|
import { AddRoleToInstanceProfileCommand, AddUserToGroupCommand, AttachGroupPolicyCommand, AttachRolePolicyCommand, AttachUserPolicyCommand, CreateAccessKeyCommand, CreateGroupCommand, CreateInstanceProfileCommand, CreateLoginProfileCommand, CreatePolicyCommand, CreatePolicyVersionCommand, CreateUserCommand, DeleteAccessKeyCommand, DeleteGroupCommand, DeleteGroupPolicyCommand, DeleteInstanceProfileCommand, DeleteLoginProfileCommand, DeletePolicyCommand, DeletePolicyVersionCommand, DeleteRolePolicyCommand, DeleteUserCommand, DeleteUserPermissionsBoundaryCommand, DeleteUserPolicyCommand, DetachGroupPolicyCommand, DetachRolePolicyCommand, DetachUserPolicyCommand, GetAccessKeyLastUsedCommand, GetGroupCommand, GetGroupPolicyCommand, GetInstanceProfileCommand, GetPolicyCommand, GetPolicyVersionCommand, GetRolePolicyCommand, GetUserCommand, GetUserPolicyCommand, IAMClient, ListAccessKeysCommand, ListAttachedGroupPoliciesCommand, ListAttachedUserPoliciesCommand, ListEntitiesForPolicyCommand, ListGroupPoliciesCommand, ListGroupsForUserCommand, ListPoliciesCommand, ListPolicyTagsCommand, ListPolicyVersionsCommand, ListUserPoliciesCommand, NoSuchEntityException, PutGroupPolicyCommand, PutRolePolicyCommand, PutUserPermissionsBoundaryCommand, PutUserPolicyCommand, RemoveRoleFromInstanceProfileCommand, RemoveUserFromGroupCommand, TagPolicyCommand, TagUserCommand, UntagPolicyCommand, UntagUserCommand, UpdateAccessKeyCommand, UpdateGroupCommand, UpdateLoginProfileCommand, UpdateUserCommand } from "@aws-sdk/client-iam";
|
|
@@ -63,7 +63,7 @@ import { CodeCommitClient, CreateCommitCommand, CreateRepositoryCommand as Creat
|
|
|
63
63
|
import { CreateLifecyclePolicyCommand, DLMClient, DeleteLifecyclePolicyCommand as DeleteLifecyclePolicyCommand$1, GetLifecyclePoliciesCommand, GetLifecyclePolicyCommand as GetLifecyclePolicyCommand$1, ResourceNotFoundException as ResourceNotFoundException$16, TagResourceCommand as TagResourceCommand$26, UntagResourceCommand as UntagResourceCommand$27, UpdateLifecyclePolicyCommand } from "@aws-sdk/client-dlm";
|
|
64
64
|
import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$18, S3VectorsClient, TagResourceCommand as TagResourceCommand$27, UntagResourceCommand as UntagResourceCommand$28 } from "@aws-sdk/client-s3vectors";
|
|
65
65
|
import { ListTagsForResourceCommand as ListTagsForResourceCommand$19, S3ControlClient, TagResourceCommand as TagResourceCommand$28, UntagResourceCommand as UntagResourceCommand$29 } from "@aws-sdk/client-s3-control";
|
|
66
|
-
import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableCommand as DeleteTableCommand$2, GetNamespaceCommand as GetNamespaceCommand$1, GetTableBucketCommand, GetTableCommand as GetTableCommand$1, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$20, NotFoundException as NotFoundException$7, RenameTableCommand, S3TablesClient, TagResourceCommand as TagResourceCommand$29, UntagResourceCommand as UntagResourceCommand$30 } from "@aws-sdk/client-s3tables";
|
|
66
|
+
import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableBucketMetricsConfigurationCommand, DeleteTableBucketReplicationCommand, DeleteTableCommand as DeleteTableCommand$2, GetNamespaceCommand as GetNamespaceCommand$1, GetTableBucketCommand, GetTableBucketEncryptionCommand, GetTableBucketMaintenanceConfigurationCommand, GetTableBucketMetricsConfigurationCommand, GetTableBucketReplicationCommand, GetTableBucketStorageClassCommand, GetTableCommand as GetTableCommand$1, GetTableMaintenanceConfigurationCommand, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$20, NotFoundException as NotFoundException$7, PutTableBucketEncryptionCommand, PutTableBucketMaintenanceConfigurationCommand, PutTableBucketMetricsConfigurationCommand, PutTableBucketReplicationCommand, PutTableBucketStorageClassCommand, PutTableMaintenanceConfigurationCommand, RenameTableCommand, S3TablesClient, TagResourceCommand as TagResourceCommand$29, UntagResourceCommand as UntagResourceCommand$30 } from "@aws-sdk/client-s3tables";
|
|
67
67
|
|
|
68
68
|
//#region src/provisioning/providers/iam-policy-provider.ts
|
|
69
69
|
const POLICY_NAME_SKIP_REASON = "no policy name in state — no delete issued";
|
|
@@ -11517,6 +11517,11 @@ var LambdaNetworkConnectorProvider = class {
|
|
|
11517
11517
|
const tagList = refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, void 0, "Tags", DBPROXY_TAGS_WHAT, DBPROXY_TAG_OPTIONS);
|
|
11518
11518
|
const name = typeof properties["Name"] === "string" && properties["Name"] !== "" ? properties["Name"] : generatedNameFor("AWS::Lambda::NetworkConnector", logicalId);
|
|
11519
11519
|
const vpc = this.readVpcEgress(properties, logicalId, resourceType, void 0);
|
|
11520
|
+
if (declaredElasticIp(properties) !== void 0) {
|
|
11521
|
+
const message = elasticIpRefusalMessage(logicalId, "create");
|
|
11522
|
+
if (context?.replayingState !== true) throw new ProvisioningError(message, resourceType, logicalId);
|
|
11523
|
+
this.logger.warn(safeMsg`${message} Proceeding without it: this create replays a cdkd state record.`);
|
|
11524
|
+
}
|
|
11520
11525
|
const createToken = acquireIdempotencyToken({
|
|
11521
11526
|
scope: "CreateNetworkConnector",
|
|
11522
11527
|
logicalId
|
|
@@ -11556,6 +11561,12 @@ var LambdaNetworkConnectorProvider = class {
|
|
|
11556
11561
|
assertRegionMatch(context?.expectedRegion ? await this.client.config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
11557
11562
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId, "Tags", DBPROXY_TAGS_WHAT, DBPROXY_TAG_OPTIONS);
|
|
11558
11563
|
const vpc = this.readVpcEgress(properties, logicalId, resourceType, physicalId);
|
|
11564
|
+
const desiredElasticIp = declaredElasticIp(properties);
|
|
11565
|
+
if (desiredElasticIp !== void 0 && !isDeepStrictEqual(desiredElasticIp, declaredElasticIp(previousProperties))) {
|
|
11566
|
+
const message = elasticIpRefusalMessage(logicalId, "update");
|
|
11567
|
+
if (context?.replayingState !== true && context?.desiredFromAwsReadback !== true) throw new ProvisioningError(message, resourceType, logicalId, physicalId);
|
|
11568
|
+
this.logger.warn(safeMsg`${message} Proceeding without it: this update restores a recorded or read-back configuration.`);
|
|
11569
|
+
}
|
|
11559
11570
|
const updateRole = this.readOperatorRole(properties, logicalId, resourceType, physicalId, context);
|
|
11560
11571
|
if (typeof previousProperties["OperatorRole"] === "string" && properties["OperatorRole"] === void 0 && context?.replayingState !== true && context?.desiredFromAwsReadback !== true) throw new ProvisioningError(`OperatorRole cannot be removed in place for Lambda network connector ${logicalIdShown(logicalId)}: cdkd sends no role when the template declares none, so the current one would stay attached. Set it to another role, or replace the connector (change its Name).`, resourceType, logicalId, physicalId);
|
|
11561
11572
|
try {
|
|
@@ -11754,6 +11765,15 @@ var LambdaNetworkConnectorProvider = class {
|
|
|
11754
11765
|
return markRedactedCause(build(`${failure.summary}${relayedNameCollision(failure.detail)}`));
|
|
11755
11766
|
}
|
|
11756
11767
|
};
|
|
11768
|
+
const ELASTIC_IP_KEY = "ElasticIpConfiguration";
|
|
11769
|
+
function declaredElasticIp(properties) {
|
|
11770
|
+
const config = properties["Configuration"];
|
|
11771
|
+
const vpc = isPlainRecord$3(config) ? config["VpcEgressConfiguration"] : void 0;
|
|
11772
|
+
return isPlainRecord$3(vpc) ? vpc[ELASTIC_IP_KEY] : void 0;
|
|
11773
|
+
}
|
|
11774
|
+
function elasticIpRefusalMessage(logicalId, mode) {
|
|
11775
|
+
return `AWS::Lambda::NetworkConnector ${logicalIdShown(logicalId)}: Configuration.VpcEgressConfiguration.${ELASTIC_IP_KEY} cannot be sent by cdkd yet — the AWS SDK for JavaScript (@aws-sdk/client-lambda-core) does not model the member, so it would be dropped from the ${mode === "create" ? "CreateNetworkConnector" : "UpdateNetworkConnector"} request without an error. Remove ${ELASTIC_IP_KEY} from Configuration.VpcEgressConfiguration to deploy the connector without it.`;
|
|
11776
|
+
}
|
|
11757
11777
|
var TerminalConnectorStateError = class extends Error {};
|
|
11758
11778
|
function buildAttributes(resp) {
|
|
11759
11779
|
return definedAttributes({
|
|
@@ -11820,6 +11840,120 @@ async function waitForGoneAfterDelete(opts) {
|
|
|
11820
11840
|
}
|
|
11821
11841
|
}
|
|
11822
11842
|
|
|
11843
|
+
//#endregion
|
|
11844
|
+
//#region src/provisioning/dynamodb-vector-indexes.ts
|
|
11845
|
+
function vectorIndexesByName(value) {
|
|
11846
|
+
const out = /* @__PURE__ */ new Map();
|
|
11847
|
+
if (!Array.isArray(value)) return out;
|
|
11848
|
+
for (const entry of value) {
|
|
11849
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) continue;
|
|
11850
|
+
const name = entry["IndexName"];
|
|
11851
|
+
if (typeof name === "string") out.set(name, entry);
|
|
11852
|
+
}
|
|
11853
|
+
return out;
|
|
11854
|
+
}
|
|
11855
|
+
function vectorIndexForSend(entry) {
|
|
11856
|
+
const out = {};
|
|
11857
|
+
for (const key of [
|
|
11858
|
+
"IndexName",
|
|
11859
|
+
"VectorAttribute",
|
|
11860
|
+
"Projection",
|
|
11861
|
+
"DistanceFunction"
|
|
11862
|
+
]) if (entry[key] !== void 0) out[key] = entry[key];
|
|
11863
|
+
if (entry["Dimensions"] !== void 0) out["Dimensions"] = coerceCfnInteger(entry["Dimensions"]) ?? entry["Dimensions"];
|
|
11864
|
+
if (entry["SearchSchema"] !== void 0) out["SearchSchema"] = entry["SearchSchema"];
|
|
11865
|
+
return out;
|
|
11866
|
+
}
|
|
11867
|
+
function vectorIndexesForCreate(value) {
|
|
11868
|
+
if (value === void 0 || value === null) return void 0;
|
|
11869
|
+
if (!Array.isArray(value)) return value;
|
|
11870
|
+
return value.map((entry) => typeof entry === "object" && entry !== null && !Array.isArray(entry) ? vectorIndexForSend(entry) : entry);
|
|
11871
|
+
}
|
|
11872
|
+
function sortedByJson(list) {
|
|
11873
|
+
if (!Array.isArray(list)) return list;
|
|
11874
|
+
return [...list].sort((a, b) => {
|
|
11875
|
+
const x = JSON.stringify(a) ?? "";
|
|
11876
|
+
const y = JSON.stringify(b) ?? "";
|
|
11877
|
+
return x < y ? -1 : x > y ? 1 : 0;
|
|
11878
|
+
});
|
|
11879
|
+
}
|
|
11880
|
+
function vectorIndexKey(entry) {
|
|
11881
|
+
const e = entry;
|
|
11882
|
+
const projection = e["Projection"];
|
|
11883
|
+
const normalizedProjection = typeof projection === "object" && projection !== null && !Array.isArray(projection) ? {
|
|
11884
|
+
ProjectionType: projection["ProjectionType"],
|
|
11885
|
+
NonKeyAttributes: sortedByJson(nonEmpty(projection["NonKeyAttributes"]))
|
|
11886
|
+
} : projection;
|
|
11887
|
+
const attribute = e["VectorAttribute"];
|
|
11888
|
+
return JSON.stringify([
|
|
11889
|
+
e["IndexName"],
|
|
11890
|
+
typeof attribute === "object" && attribute !== null ? attribute["AttributeName"] : attribute,
|
|
11891
|
+
coerceCfnInteger(e["Dimensions"]) ?? e["Dimensions"],
|
|
11892
|
+
e["DistanceFunction"],
|
|
11893
|
+
normalizedProjection,
|
|
11894
|
+
sortedByJson(Array.isArray(e["SearchSchema"]) && e["SearchSchema"].length > 0 ? e["SearchSchema"].map((s) => typeof s === "object" && s !== null ? {
|
|
11895
|
+
AttributeName: s["AttributeName"],
|
|
11896
|
+
SearchSchemaElementType: s["SearchSchemaElementType"]
|
|
11897
|
+
} : s) : nonEmpty(e["SearchSchema"]))
|
|
11898
|
+
]);
|
|
11899
|
+
}
|
|
11900
|
+
function nonEmpty(value) {
|
|
11901
|
+
return Array.isArray(value) && value.length === 0 ? void 0 : value;
|
|
11902
|
+
}
|
|
11903
|
+
function planVectorIndexUpdates(previous, desired, live) {
|
|
11904
|
+
const prevByName = vectorIndexesByName(previous);
|
|
11905
|
+
const desiredByName = vectorIndexesByName(desired);
|
|
11906
|
+
const liveByName = live === void 0 ? void 0 : new Map(live.filter((d) => typeof d.IndexName === "string").map((d) => [d.IndexName, d]));
|
|
11907
|
+
const plan = {
|
|
11908
|
+
ops: [],
|
|
11909
|
+
changed: [],
|
|
11910
|
+
adopted: [],
|
|
11911
|
+
alreadyGone: []
|
|
11912
|
+
};
|
|
11913
|
+
const liveHolds = (name, entry) => {
|
|
11914
|
+
const l = liveByName?.get(name);
|
|
11915
|
+
return l !== void 0 && l.IndexStatus !== "DELETING" && vectorIndexKey(l) === vectorIndexKey(entry);
|
|
11916
|
+
};
|
|
11917
|
+
for (const name of prevByName.keys()) {
|
|
11918
|
+
if (desiredByName.has(name)) continue;
|
|
11919
|
+
const l = liveByName?.get(name);
|
|
11920
|
+
if (liveByName !== void 0 && (l === void 0 || l.IndexStatus === "DELETING")) {
|
|
11921
|
+
plan.alreadyGone.push(name);
|
|
11922
|
+
continue;
|
|
11923
|
+
}
|
|
11924
|
+
plan.ops.push({ Delete: { IndexName: name } });
|
|
11925
|
+
}
|
|
11926
|
+
for (const [name, entry] of desiredByName) {
|
|
11927
|
+
const before = prevByName.get(name);
|
|
11928
|
+
if (before === void 0) {
|
|
11929
|
+
const l = liveByName?.get(name);
|
|
11930
|
+
if (l === void 0 || l.IndexStatus === "DELETING") plan.ops.push({ Create: vectorIndexForSend(entry) });
|
|
11931
|
+
else if (liveHolds(name, entry)) plan.adopted.push(name);
|
|
11932
|
+
else plan.changed.push(name);
|
|
11933
|
+
continue;
|
|
11934
|
+
}
|
|
11935
|
+
if (vectorIndexKey(before) === vectorIndexKey(entry)) continue;
|
|
11936
|
+
if (!liveHolds(name, entry)) plan.changed.push(name);
|
|
11937
|
+
}
|
|
11938
|
+
return plan;
|
|
11939
|
+
}
|
|
11940
|
+
function readbackVectorIndexes(live) {
|
|
11941
|
+
if (live === void 0 || live.length === 0) return void 0;
|
|
11942
|
+
return live.map((d) => {
|
|
11943
|
+
const out = {};
|
|
11944
|
+
if (d.IndexName !== void 0) out["IndexName"] = d.IndexName;
|
|
11945
|
+
if (d.VectorAttribute !== void 0) out["VectorAttribute"] = d.VectorAttribute;
|
|
11946
|
+
if (d.Dimensions !== void 0) out["Dimensions"] = d.Dimensions;
|
|
11947
|
+
if (d.DistanceFunction !== void 0) out["DistanceFunction"] = d.DistanceFunction;
|
|
11948
|
+
if (d.Projection !== void 0) out["Projection"] = d.Projection;
|
|
11949
|
+
if (d.SearchSchema !== void 0 && d.SearchSchema.length > 0) out["SearchSchema"] = d.SearchSchema;
|
|
11950
|
+
return out;
|
|
11951
|
+
});
|
|
11952
|
+
}
|
|
11953
|
+
function vectorIndexesSettled(live) {
|
|
11954
|
+
return (live ?? []).every((d) => d.IndexStatus === void 0 || d.IndexStatus === "ACTIVE");
|
|
11955
|
+
}
|
|
11956
|
+
|
|
11823
11957
|
//#endregion
|
|
11824
11958
|
//#region src/provisioning/providers/dynamodb-table-provider.ts
|
|
11825
11959
|
function isTableName(id) {
|
|
@@ -12246,7 +12380,7 @@ var DynamoDBTableProvider = class {
|
|
|
12246
12380
|
if (!failure.redacted) return wrapMaskedAwsError(m, error, build);
|
|
12247
12381
|
this.logger.debug(m(build(m(failure.detail)).message));
|
|
12248
12382
|
const relay = isAuxiliaryFailure(error) ? "" : relayedNameCollision(failure.detail);
|
|
12249
|
-
const wrapped = build(`${m(failure.summary)}${relay}${relayedIndexBusyDelete(failure.detail)}`);
|
|
12383
|
+
const wrapped = build(`${m(failure.summary)}${relay}${relayedIndexBusyDelete(failure.detail, TABLE_INDEX_NOUN)}`);
|
|
12250
12384
|
return error instanceof Error ? markRedactedCause(wrapped) : wrapped;
|
|
12251
12385
|
}
|
|
12252
12386
|
handledProperties = /* @__PURE__ */ new Map([["AWS::DynamoDB::Table", /* @__PURE__ */ new Set([
|
|
@@ -12268,7 +12402,8 @@ var DynamoDBTableProvider = class {
|
|
|
12268
12402
|
"TimeToLiveSpecification",
|
|
12269
12403
|
"ResourcePolicy",
|
|
12270
12404
|
"KinesisStreamSpecification",
|
|
12271
|
-
"ContributorInsightsSpecification"
|
|
12405
|
+
"ContributorInsightsSpecification",
|
|
12406
|
+
"VectorIndexes"
|
|
12272
12407
|
])]]);
|
|
12273
12408
|
unhandledByDesign = /* @__PURE__ */ new Map([["AWS::DynamoDB::Table", /* @__PURE__ */ 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"]])]]);
|
|
12274
12409
|
deleteBudgets = new ElapsedBudgetRegistry();
|
|
@@ -12342,6 +12477,8 @@ var DynamoDBTableProvider = class {
|
|
|
12342
12477
|
const declaredGsis = properties["GlobalSecondaryIndexes"];
|
|
12343
12478
|
createParams.GlobalSecondaryIndexes = Array.isArray(declaredGsis) ? declaredGsis.map((entry) => this.coerceIndexThroughputForCreate(logicalId, stripIndexContributorInsights(entry), maskSecrets)) : declaredGsis;
|
|
12344
12479
|
}
|
|
12480
|
+
const createVectorIndexes = vectorIndexesForCreate(properties["VectorIndexes"]);
|
|
12481
|
+
if (createVectorIndexes !== void 0) createParams.VectorIndexes = createVectorIndexes;
|
|
12345
12482
|
if (properties["LocalSecondaryIndexes"]) createParams.LocalSecondaryIndexes = properties["LocalSecondaryIndexes"];
|
|
12346
12483
|
const sseCreateRefusal = sseSpecificationRefusal(properties["SSESpecification"], logicalId);
|
|
12347
12484
|
if (sseCreateRefusal !== void 0 && context?.replayingState !== true) throw new ProvisioningError(`${maskSecrets(sseCreateRefusal)}. Nothing was created; fix the template value`, resourceType, logicalId);
|
|
@@ -12366,8 +12503,12 @@ var DynamoDBTableProvider = class {
|
|
|
12366
12503
|
tableCreated = true;
|
|
12367
12504
|
createdTableId = createOut?.TableDescription?.TableId;
|
|
12368
12505
|
reportCreatedResource(logicalId, resourceType, tableName, createdTableId);
|
|
12369
|
-
|
|
12370
|
-
const tableInfo = await timePhase("provider waits", "DynamoDB table: wait for ACTIVE", () => this.waitForTableActive(tableName), logicalId);
|
|
12506
|
+
debug(`CreateTable initiated for ${tableName}, waiting for ACTIVE status`);
|
|
12507
|
+
const tableInfo = await timePhase("provider waits", "DynamoDB table: wait for ACTIVE", () => this.waitForTableActive(tableName, maskSecrets), logicalId);
|
|
12508
|
+
if (createVectorIndexes !== void 0) await timePhase("provider waits", "DynamoDB table: wait for vector indexes", () => this.waitForTableAndIndexesActive(tableName, void 0, {
|
|
12509
|
+
after: "CreateTable",
|
|
12510
|
+
maskSecrets
|
|
12511
|
+
}), logicalId);
|
|
12371
12512
|
await this.applyPointInTimeRecovery(tableName, properties["PointInTimeRecoverySpecification"], void 0, maskSecrets);
|
|
12372
12513
|
await this.applyTimeToLive(tableName, properties["TimeToLiveSpecification"], void 0, "create", {
|
|
12373
12514
|
logicalId,
|
|
@@ -12378,7 +12519,7 @@ var DynamoDBTableProvider = class {
|
|
|
12378
12519
|
await this.applyContributorInsights(tableName, properties["ContributorInsightsSpecification"], void 0, maskSecrets);
|
|
12379
12520
|
await this.applyIndexContributorInsights(tableName, properties["GlobalSecondaryIndexes"], void 0, maskSecrets);
|
|
12380
12521
|
await this.applyStreamMembers(logicalId, resourceType, tableName, tableInfo.streamArn, properties["StreamSpecification"], void 0, true, maskSecrets);
|
|
12381
|
-
|
|
12522
|
+
debug(`Successfully created DynamoDB table ${logicalId}: ${tableName}`);
|
|
12382
12523
|
return {
|
|
12383
12524
|
physicalId: tableName,
|
|
12384
12525
|
attributes: {
|
|
@@ -12392,7 +12533,7 @@ var DynamoDBTableProvider = class {
|
|
|
12392
12533
|
let tableLeftBehind = false;
|
|
12393
12534
|
if (tableCreated) {
|
|
12394
12535
|
try {
|
|
12395
|
-
await this.
|
|
12536
|
+
await this.rollBackCreatedTable(logicalId, tableName, maskSecrets);
|
|
12396
12537
|
retractCreatedResource(logicalId, resourceType, tableName);
|
|
12397
12538
|
debug(`Rolled back partially-created DynamoDB table ${tableName}`);
|
|
12398
12539
|
} catch (cleanupError) {
|
|
@@ -12410,6 +12551,38 @@ var DynamoDBTableProvider = class {
|
|
|
12410
12551
|
throw thrown;
|
|
12411
12552
|
}
|
|
12412
12553
|
}
|
|
12554
|
+
async rollBackCreatedTable(logicalId, tableName, maskSecrets) {
|
|
12555
|
+
const logger = maskedLogger(this.logger, maskSecrets, tableName);
|
|
12556
|
+
const allowanceMs = Math.min(resolveDynamoDbDeleteBudgetMs(), enclosingDeadlineRemainingMs() - DYNAMODB_DELETE_DEADLINE_MARGIN_MS);
|
|
12557
|
+
const budget = allowanceMs > 0 ? new ElapsedBudget(allowanceMs, resolveDynamoDbDeleteBudgetClock()) : void 0;
|
|
12558
|
+
await deleteTableWithIndexBusyRetry({
|
|
12559
|
+
logicalId,
|
|
12560
|
+
physicalId: tableName,
|
|
12561
|
+
typeLabel: "table",
|
|
12562
|
+
indexNoun: TABLE_INDEX_NOUN,
|
|
12563
|
+
maxRetries: 14,
|
|
12564
|
+
logger,
|
|
12565
|
+
deleteTable: async () => {
|
|
12566
|
+
await this.dynamoDBClient.send(new DeleteTableCommand({ TableName: tableName }));
|
|
12567
|
+
},
|
|
12568
|
+
reArm: () => {
|
|
12569
|
+
const wait = beginDeleteWait(900, budget);
|
|
12570
|
+
return waitForIndexesSettled({
|
|
12571
|
+
tableName,
|
|
12572
|
+
logicalId,
|
|
12573
|
+
logger,
|
|
12574
|
+
describeTable: () => this.dynamoDBClient.send(new DescribeTableCommand({ TableName: tableName })),
|
|
12575
|
+
maxAttempts: wait.grantedPolls,
|
|
12576
|
+
budgetWait: wait,
|
|
12577
|
+
shortCapUnlessVectorBusy: 60,
|
|
12578
|
+
proceedNote: DELETE_INDEX_WAIT_PROCEED_NOTE
|
|
12579
|
+
});
|
|
12580
|
+
},
|
|
12581
|
+
shouldKeepRetrying: () => budget !== void 0 && !budget.isExhausted(),
|
|
12582
|
+
retryWarning: () => `DynamoDB table ${logicalId}: AWS refused the DeleteTable rolling back the partially-created table ${tableName} because ${TABLE_INDEX_NOUN} is still being created, updated or deleted. Waiting for the indexes to settle and retrying (up to ${14} retries in all, within ~${Math.max(1, Math.round((budget?.totalMs ?? 0) / 6e4))} minutes).`,
|
|
12583
|
+
sleepSeam: deleteTableRetryDelays
|
|
12584
|
+
});
|
|
12585
|
+
}
|
|
12413
12586
|
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
12414
12587
|
const markUnsettled = (key) => context?.markUnsettled?.(key);
|
|
12415
12588
|
const maskSecrets = context?.maskSecrets ?? ((text) => text);
|
|
@@ -12454,6 +12627,12 @@ var DynamoDBTableProvider = class {
|
|
|
12454
12627
|
if (context?.replayingState !== true && context?.desiredFromAwsReadback !== true) throw new ProvisioningError(`${lsiMessage}. Nothing was applied to the table; revert the LocalSecondaryIndexes change, or create a new table under a new logical ID (a new table starts empty)`, resourceType, logicalId, physicalId);
|
|
12455
12628
|
warn(`${lsiMessage}; the LocalSecondaryIndexes change was not applied`);
|
|
12456
12629
|
}
|
|
12630
|
+
const vectorIndexPlan = JSON.stringify(properties["VectorIndexes"]) !== JSON.stringify(previousProperties["VectorIndexes"]) ? planVectorIndexUpdates(previousProperties["VectorIndexes"], properties["VectorIndexes"], table?.VectorIndexes ?? (table === void 0 ? void 0 : [])) : void 0;
|
|
12631
|
+
if (vectorIndexPlan !== void 0 && vectorIndexPlan.changed.length > 0) {
|
|
12632
|
+
const vectorMessage = `AWS::DynamoDB::Table ${logicalId}: VectorIndexes ${vectorIndexPlan.changed.map((n) => maskSecrets(n)).join(", ")} changed definition, which DynamoDB cannot modify in place`;
|
|
12633
|
+
if (context?.replayingState !== true && context?.desiredFromAwsReadback !== true) throw new ProvisioningError(`${maskSecrets(vectorMessage)}. Nothing was applied to the table; rename the index (so it is dropped and re-created) or revert the change`, resourceType, logicalId, physicalId);
|
|
12634
|
+
warn(`${vectorMessage}; that change was not applied`);
|
|
12635
|
+
}
|
|
12457
12636
|
let latestStreamArn = table?.LatestStreamArn;
|
|
12458
12637
|
if (table?.TableArn) await this.applyTagDiff(table.TableArn, resourceType, logicalId, previousProperties["Tags"], properties["Tags"], {
|
|
12459
12638
|
forceUpsert: context?.unsettledProperties?.has("Tags") === true,
|
|
@@ -12572,7 +12751,7 @@ var DynamoDBTableProvider = class {
|
|
|
12572
12751
|
if (tableClassChanged) markUnsettled("TableClass");
|
|
12573
12752
|
if (updateInput.GlobalSecondaryIndexUpdates !== void 0) markUnsettled("GlobalSecondaryIndexes");
|
|
12574
12753
|
await this.dynamoDBClient.send(new UpdateTableCommand(updateInput));
|
|
12575
|
-
if (billingMode !== liveBillingMode) await this.waitForTableAndIndexesActive(physicalId, BILLING_FLIP_ACTIVE_WAIT_ATTEMPTS);
|
|
12754
|
+
if (billingMode !== liveBillingMode) await this.waitForTableAndIndexesActive(physicalId, BILLING_FLIP_ACTIVE_WAIT_ATTEMPTS, { maskSecrets });
|
|
12576
12755
|
else await this.waitForTableActiveAfterUpdate(physicalId, 60);
|
|
12577
12756
|
this.logger.debug(`Updated BillingMode/ProvisionedThroughput/TableClass on DynamoDB table ${physicalId}`);
|
|
12578
12757
|
}
|
|
@@ -12687,6 +12866,7 @@ var DynamoDBTableProvider = class {
|
|
|
12687
12866
|
markUnsettled("GlobalSecondaryIndexes");
|
|
12688
12867
|
await this.applyGsiUpdates(physicalId, resourceType, logicalId, previousProperties["GlobalSecondaryIndexes"], properties["GlobalSecondaryIndexes"], properties["AttributeDefinitions"], gsiHandledByBillingFlip, currentLiveIndexNames, currentLiveIndexByName, liveCapacityComparable, effectiveBillingMode === "PAY_PER_REQUEST", maskSecrets, (indexName) => context?.markAttempted?.("GlobalSecondaryIndexes", [indexName]));
|
|
12689
12868
|
}
|
|
12869
|
+
if (vectorIndexPlan !== void 0) await this.applyVectorIndexUpdates(physicalId, vectorIndexPlan, properties["AttributeDefinitions"], maskSecrets, () => markUnsettled("VectorIndexes"), (indexName) => context?.markAttempted?.("VectorIndexes", [indexName]));
|
|
12690
12870
|
if (JSON.stringify(properties["PointInTimeRecoverySpecification"]) !== JSON.stringify(previousProperties["PointInTimeRecoverySpecification"])) {
|
|
12691
12871
|
markUnsettled("PointInTimeRecoverySpecification");
|
|
12692
12872
|
await this.applyPointInTimeRecovery(physicalId, properties["PointInTimeRecoverySpecification"], previousProperties["PointInTimeRecoverySpecification"], maskSecrets);
|
|
@@ -12802,16 +12982,18 @@ var DynamoDBTableProvider = class {
|
|
|
12802
12982
|
}
|
|
12803
12983
|
try {
|
|
12804
12984
|
const reArmPolls = () => {
|
|
12805
|
-
const wait = beginDeleteWait(
|
|
12985
|
+
const wait = beginDeleteWait(900, budget);
|
|
12806
12986
|
return {
|
|
12807
12987
|
maxAttempts: wait.grantedPolls,
|
|
12808
|
-
budgetWait: wait
|
|
12988
|
+
budgetWait: wait,
|
|
12989
|
+
shortCapUnlessVectorBusy: 60
|
|
12809
12990
|
};
|
|
12810
12991
|
};
|
|
12811
12992
|
await deleteTableWithIndexBusyRetry({
|
|
12812
12993
|
logicalId,
|
|
12813
12994
|
physicalId,
|
|
12814
12995
|
typeLabel: "table",
|
|
12996
|
+
indexNoun: TABLE_INDEX_NOUN,
|
|
12815
12997
|
maxRetries: 14,
|
|
12816
12998
|
logger: loopLogger,
|
|
12817
12999
|
deleteTable: async () => {
|
|
@@ -13203,7 +13385,7 @@ var DynamoDBTableProvider = class {
|
|
|
13203
13385
|
const warn = (message) => this.logger.warn(maskSecrets(message));
|
|
13204
13386
|
const ops = planIndexContributorInsightsOps(desiredIndexes, previousIndexes, (indexName, reason) => warn(`${this.indexScopeAt(indexName, tableName, maskSecrets)}: ${reason}, so its Contributor Insights was left as it is. Fix the template value and re-deploy.`));
|
|
13205
13387
|
if (ops.length === 0) return;
|
|
13206
|
-
await this.waitForTableAndIndexesActive(tableName);
|
|
13388
|
+
await this.waitForTableAndIndexesActive(tableName, void 0, { maskSecrets });
|
|
13207
13389
|
for (const op of ops) {
|
|
13208
13390
|
beforeSend();
|
|
13209
13391
|
await this.sendContributorInsightsOp(tableName, op, maskSecrets);
|
|
@@ -13220,11 +13402,11 @@ var DynamoDBTableProvider = class {
|
|
|
13220
13402
|
})), `set ContributorInsights on ${target}`);
|
|
13221
13403
|
debug(`Set ContributorInsightsAction=${op.action}${op.mode !== void 0 ? ` Mode=${op.mode}` : ""} on ${target}`);
|
|
13222
13404
|
}
|
|
13223
|
-
async waitForTableActive(tableName, maxAttempts = 60) {
|
|
13405
|
+
async waitForTableActive(tableName, maskSecrets, maxAttempts = 60) {
|
|
13224
13406
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
13225
13407
|
const response = await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: tableName }));
|
|
13226
13408
|
const status = response.Table?.TableStatus;
|
|
13227
|
-
this.logger.debug(`Table ${tableName} status: ${status} (attempt ${attempt}/${maxAttempts})`);
|
|
13409
|
+
this.logger.debug(maskSecrets(`Table ${tableName} status: ${status} (attempt ${attempt}/${maxAttempts})`));
|
|
13228
13410
|
if (status === "ACTIVE") return {
|
|
13229
13411
|
tableArn: response.Table?.TableArn,
|
|
13230
13412
|
tableId: response.Table?.TableId,
|
|
@@ -13262,15 +13444,36 @@ var DynamoDBTableProvider = class {
|
|
|
13262
13444
|
}
|
|
13263
13445
|
throw new Error(maskSecrets(`DynamoDB table ${tableName} was still ${last ?? "unread"} ${KINESIS_DESTINATION_SETTLE_POLLS * KINESIS_DESTINATION_SETTLE_POLL_MS / 1e3} seconds after its encryption change`));
|
|
13264
13446
|
}
|
|
13265
|
-
async waitForTableAndIndexesActive(tableName, maxAttempts = 1800) {
|
|
13447
|
+
async waitForTableAndIndexesActive(tableName, maxAttempts = 1800, opts = {}) {
|
|
13266
13448
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
13267
13449
|
const table = (await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: tableName }))).Table;
|
|
13268
13450
|
const tableActive = table?.TableStatus === "ACTIVE";
|
|
13269
13451
|
const indexesActive = (table?.GlobalSecondaryIndexes ?? []).every((gsi) => gsi.IndexStatus === "ACTIVE");
|
|
13270
|
-
if (tableActive && indexesActive) return;
|
|
13452
|
+
if (tableActive && indexesActive && vectorIndexesSettled(table?.VectorIndexes)) return;
|
|
13271
13453
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
13272
13454
|
}
|
|
13273
|
-
|
|
13455
|
+
const m = maskerOrIdentity(opts.maskSecrets);
|
|
13456
|
+
throw new Error(m(`Table ${m(tableName)} and its indexes did not reach ACTIVE within ${maxAttempts} seconds after ${opts.after ?? "UpdateTable"}`));
|
|
13457
|
+
}
|
|
13458
|
+
async applyVectorIndexUpdates(physicalId, plan, desiredAttributeDefinitions, maskSecrets, beforeFirstOp, onCreated) {
|
|
13459
|
+
const debug = (message) => this.logger.debug(maskSecrets(message));
|
|
13460
|
+
const warn = (message) => this.logger.warn(maskSecrets(message));
|
|
13461
|
+
for (const name of plan.alreadyGone) debug(`${this.vectorIndexScopeAt(name, physicalId, maskSecrets)} is recorded in cdkd state but not live; skipping its Delete (already removed)`);
|
|
13462
|
+
for (const name of plan.adopted) warn(`${this.vectorIndexScopeAt(name, physicalId, maskSecrets)} already exists in AWS with the declared definition but is absent from cdkd's recorded previous state, so its Create is being skipped. This usually means an earlier deploy created the index and then failed before state was written.`);
|
|
13463
|
+
if (plan.ops.length === 0) return;
|
|
13464
|
+
await this.waitForTableAndIndexesActive(physicalId, void 0, { maskSecrets });
|
|
13465
|
+
beforeFirstOp();
|
|
13466
|
+
for (const op of plan.ops) {
|
|
13467
|
+
const input = {
|
|
13468
|
+
TableName: physicalId,
|
|
13469
|
+
VectorIndexUpdates: [op]
|
|
13470
|
+
};
|
|
13471
|
+
if (op.Create && desiredAttributeDefinitions) input.AttributeDefinitions = desiredAttributeDefinitions;
|
|
13472
|
+
await this.dynamoDBClient.send(new UpdateTableCommand(input));
|
|
13473
|
+
if (op.Create?.IndexName !== void 0) onCreated(op.Create.IndexName);
|
|
13474
|
+
await this.waitForTableAndIndexesActive(physicalId, void 0, { maskSecrets });
|
|
13475
|
+
debug(`${op.Create ? "created" : "deleted"} ` + this.vectorIndexScopeAt(op.Create?.IndexName ?? op.Delete?.IndexName, physicalId, maskSecrets));
|
|
13476
|
+
}
|
|
13274
13477
|
}
|
|
13275
13478
|
async applyGsiUpdates(physicalId, resourceType, logicalId, previousGsis, desiredGsis, desiredAttributeDefinitions, handledByBillingFlip, liveIndexNames, liveIndexByName, liveCapacityComparable, onDemandCeilingsSendable, maskSecrets, onCreated = () => void 0) {
|
|
13276
13479
|
const warn = (message) => this.logger.warn(maskSecrets(message));
|
|
@@ -13374,6 +13577,9 @@ var DynamoDBTableProvider = class {
|
|
|
13374
13577
|
this.logger.warn(maskSecrets(`${this.indexScopeAt(name, physicalId, maskSecrets)} is live, but neither cdkd's record nor the template declares it, so cdkd left it in place while converging the unsettled GlobalSecondaryIndexes (CloudFormation never deletes an index it did not record). It may belong to another tool, or an earlier failed cdkd update may have created it; cdkd cannot tell which. If it should not exist, delete it ` + (secretDerived ? `with an UpdateTable GlobalSecondaryIndexUpdates Delete for the index.` : `with: aws dynamodb update-table --table-name ${physicalId} --global-secondary-index-updates '[{"Delete":{"IndexName":"${name}"}}]' (in the table's region)`)));
|
|
13375
13578
|
}
|
|
13376
13579
|
}
|
|
13580
|
+
vectorIndexScopeAt(indexName, physicalId, maskSecrets) {
|
|
13581
|
+
return `vector index ${typeof indexName === "string" ? maskSecrets(indexName) : "<unnamed>"} on DynamoDB table ${maskSecrets(physicalId)}`;
|
|
13582
|
+
}
|
|
13377
13583
|
indexScopeAt(indexName, physicalId, maskSecrets) {
|
|
13378
13584
|
return `GSI ${typeof indexName === "string" ? maskSecrets(indexName) : "<unnamed>"} on DynamoDB table ${physicalId}`;
|
|
13379
13585
|
}
|
|
@@ -13521,7 +13727,7 @@ var DynamoDBTableProvider = class {
|
|
|
13521
13727
|
if (op.Create && desiredAttributeDefinitions) input.AttributeDefinitions = desiredAttributeDefinitions;
|
|
13522
13728
|
await this.dynamoDBClient.send(new UpdateTableCommand(input));
|
|
13523
13729
|
if (op.Create?.IndexName !== void 0) onCreated(op.Create.IndexName);
|
|
13524
|
-
await this.waitForTableAndIndexesActive(physicalId);
|
|
13730
|
+
await this.waitForTableAndIndexesActive(physicalId, void 0, { maskSecrets });
|
|
13525
13731
|
debug(`${op.Create ? "created" : op.Delete ? "deleted" : "updated"} ${this.indexScopeAt(op.Create?.IndexName ?? op.Delete?.IndexName ?? op.Update?.IndexName, physicalId, maskSecrets)}`);
|
|
13526
13732
|
}
|
|
13527
13733
|
}
|
|
@@ -13583,7 +13789,8 @@ var DynamoDBTableProvider = class {
|
|
|
13583
13789
|
return [
|
|
13584
13790
|
"AttributeDefinitions",
|
|
13585
13791
|
"GlobalSecondaryIndexes[]",
|
|
13586
|
-
"LocalSecondaryIndexes[]"
|
|
13792
|
+
"LocalSecondaryIndexes[]",
|
|
13793
|
+
"VectorIndexes"
|
|
13587
13794
|
];
|
|
13588
13795
|
}
|
|
13589
13796
|
getDriftUnknownPaths(resourceType, properties) {
|
|
@@ -13670,6 +13877,10 @@ var DynamoDBTableProvider = class {
|
|
|
13670
13877
|
out["GlobalSecondaryIndexes"] = projectIndexesOnto(out["GlobalSecondaryIndexes"], recordedProperties?.["GlobalSecondaryIndexes"], desiredProperties?.["GlobalSecondaryIndexes"], attemptedItems?.get("GlobalSecondaryIndexes"));
|
|
13671
13878
|
if (out["GlobalSecondaryIndexes"] === void 0) delete out["GlobalSecondaryIndexes"];
|
|
13672
13879
|
}
|
|
13880
|
+
if (names.has("VectorIndexes")) {
|
|
13881
|
+
out["VectorIndexes"] = projectIndexesOnto(out["VectorIndexes"], recordedProperties?.["VectorIndexes"], desiredProperties?.["VectorIndexes"], attemptedItems?.get("VectorIndexes"));
|
|
13882
|
+
if (out["VectorIndexes"] === void 0) delete out["VectorIndexes"];
|
|
13883
|
+
}
|
|
13673
13884
|
const strict = async (key, read) => {
|
|
13674
13885
|
if (!names.has(key)) return;
|
|
13675
13886
|
const value = await read();
|
|
@@ -13758,6 +13969,8 @@ var DynamoDBTableProvider = class {
|
|
|
13758
13969
|
const desiredByName = desiredIndexEntriesByName(properties?.["LocalSecondaryIndexes"]);
|
|
13759
13970
|
result["LocalSecondaryIndexes"] = table.LocalSecondaryIndexes.map((live) => reverseMapSecondaryIndex(live, live.IndexName === void 0 ? void 0 : desiredByName.get(live.IndexName), bagInformative));
|
|
13760
13971
|
}
|
|
13972
|
+
const liveVectorIndexes = readbackVectorIndexes(table.VectorIndexes);
|
|
13973
|
+
if (liveVectorIndexes !== void 0) result["VectorIndexes"] = liveVectorIndexes;
|
|
13761
13974
|
if (table.SSEDescription?.Status === "ENABLED") {
|
|
13762
13975
|
const sse = { SSEEnabled: true };
|
|
13763
13976
|
if (table.SSEDescription.KMSMasterKeyArn !== void 0) sse["KMSMasterKeyId"] = table.SSEDescription.KMSMasterKeyArn;
|
|
@@ -22917,6 +23130,20 @@ var ApiGatewayV2Provider = class ApiGatewayV2Provider {
|
|
|
22917
23130
|
])]
|
|
22918
23131
|
]);
|
|
22919
23132
|
removalDefaults = /* @__PURE__ */ new Map([["AWS::ApiGatewayV2::Authorizer", /* @__PURE__ */ new Map([["IdentitySource", []]])]]);
|
|
23133
|
+
removalHandledInUpdate = /* @__PURE__ */ new Map([["AWS::ApiGatewayV2::Route", /* @__PURE__ */ new Set([
|
|
23134
|
+
"ApiId",
|
|
23135
|
+
"RouteKey",
|
|
23136
|
+
"AuthorizationScopes",
|
|
23137
|
+
"Target",
|
|
23138
|
+
"AuthorizationType",
|
|
23139
|
+
"AuthorizerId",
|
|
23140
|
+
"OperationName",
|
|
23141
|
+
"ApiKeyRequired",
|
|
23142
|
+
"RequestModels",
|
|
23143
|
+
"RequestParameters",
|
|
23144
|
+
"ModelSelectionExpression",
|
|
23145
|
+
"RouteResponseSelectionExpression"
|
|
23146
|
+
])]]);
|
|
22920
23147
|
unhandledByDesign = /* @__PURE__ */ new Map([["AWS::ApiGatewayV2::Api", /* @__PURE__ */ new Map([
|
|
22921
23148
|
["Body", "OpenAPI/Swagger inline spec; routed through ImportApi, not the field-by-field CreateApi path."],
|
|
22922
23149
|
["BodyS3Location", "OpenAPI/Swagger spec on S3; routed through ImportApi, not the field-by-field CreateApi path."],
|
|
@@ -23954,12 +24181,15 @@ var ApiGatewayV2Provider = class ApiGatewayV2Provider {
|
|
|
23954
24181
|
input.OperationName = properties["OperationName"];
|
|
23955
24182
|
changed = true;
|
|
23956
24183
|
}
|
|
23957
|
-
{
|
|
24184
|
+
if (restoreFromAws) {
|
|
23958
24185
|
const r = this.clearableUpdate(properties["ApiKeyRequired"], previousProperties["ApiKeyRequired"], false);
|
|
23959
24186
|
if (r.changed) {
|
|
23960
24187
|
input.ApiKeyRequired = r.value;
|
|
23961
24188
|
changed = true;
|
|
23962
24189
|
}
|
|
24190
|
+
} else if (properties["ApiKeyRequired"] !== void 0 && properties["ApiKeyRequired"] !== previousProperties["ApiKeyRequired"]) {
|
|
24191
|
+
input.ApiKeyRequired = properties["ApiKeyRequired"];
|
|
24192
|
+
changed = true;
|
|
23963
24193
|
}
|
|
23964
24194
|
if (restoreFromAws) {
|
|
23965
24195
|
const merged = this.mapWithRemovals(properties["RequestModels"], previousProperties["RequestModels"]);
|
|
@@ -26412,6 +26642,60 @@ function isEcsErrorNamed(error, names) {
|
|
|
26412
26642
|
return typeof name === "string" && names.includes(name);
|
|
26413
26643
|
}
|
|
26414
26644
|
const settleRolloutDelays = { sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)) };
|
|
26645
|
+
function requestedRolloutOf(service) {
|
|
26646
|
+
if (!service) return void 0;
|
|
26647
|
+
const primary = service.deployments?.find((d) => d.status === "PRIMARY");
|
|
26648
|
+
const deploymentId = typeof primary?.id === "string" && primary.id ? primary.id : void 0;
|
|
26649
|
+
const taskDefinitionRaw = primary?.taskDefinition ?? service.taskDefinition;
|
|
26650
|
+
const taskDefinition = typeof taskDefinitionRaw === "string" && taskDefinitionRaw ? taskDefinitionRaw : void 0;
|
|
26651
|
+
if (deploymentId === void 0 && taskDefinition === void 0) return void 0;
|
|
26652
|
+
return {
|
|
26653
|
+
deploymentId,
|
|
26654
|
+
taskDefinition
|
|
26655
|
+
};
|
|
26656
|
+
}
|
|
26657
|
+
function failedRequestedDeployment(requested, deployments) {
|
|
26658
|
+
if (!Array.isArray(deployments)) return void 0;
|
|
26659
|
+
const target = requested?.deploymentId !== void 0 ? deployments.find((d) => d?.id === requested.deploymentId) : deployments.find((d) => d?.status === "PRIMARY");
|
|
26660
|
+
return target?.rolloutState === "FAILED" ? target : void 0;
|
|
26661
|
+
}
|
|
26662
|
+
function taskDefinitionRevision(arn) {
|
|
26663
|
+
const match = typeof arn === "string" ? /:task-definition\/[^:]+:(\d+)$/.exec(arn) : null;
|
|
26664
|
+
return match ? match[1] : void 0;
|
|
26665
|
+
}
|
|
26666
|
+
function describeRollout(rollout) {
|
|
26667
|
+
const revision = taskDefinitionRevision(rollout.taskDefinition);
|
|
26668
|
+
const id = typeof rollout.id === "string" && /^ecs-svc\/\d+$/.test(rollout.id) ? rollout.id : void 0;
|
|
26669
|
+
if (id && revision) return `deployment ${id} (task definition revision ${revision})`;
|
|
26670
|
+
if (id) return `deployment ${id}`;
|
|
26671
|
+
if (revision) return `task definition revision ${revision}`;
|
|
26672
|
+
return "another deployment";
|
|
26673
|
+
}
|
|
26674
|
+
var EcsCircuitBreakerVerdict = class extends Error {
|
|
26675
|
+
constructor(message) {
|
|
26676
|
+
super(message);
|
|
26677
|
+
this.name = "EcsCircuitBreakerVerdict";
|
|
26678
|
+
}
|
|
26679
|
+
};
|
|
26680
|
+
function wrapBreakerFailedError(failed) {
|
|
26681
|
+
return new EcsCircuitBreakerVerdict(`its deployment circuit breaker failed the rollout of ${describeRollout(failed)} (deployment FAILED). The new tasks failed to start or failed their health checks`);
|
|
26682
|
+
}
|
|
26683
|
+
function controllerSkipsWait(properties) {
|
|
26684
|
+
let type;
|
|
26685
|
+
try {
|
|
26686
|
+
type = readConfigString(properties["DeploymentController"], "Type", "ECS", "DeploymentController");
|
|
26687
|
+
} catch {
|
|
26688
|
+
return "its DeploymentController could not be read";
|
|
26689
|
+
}
|
|
26690
|
+
if (type === "ECS") return void 0;
|
|
26691
|
+
if (type === "CODE_DEPLOY" || type === "EXTERNAL") return `its DeploymentController is ${type}, which ECS does not settle`;
|
|
26692
|
+
return "its DeploymentController type is not one cdkd can settle";
|
|
26693
|
+
}
|
|
26694
|
+
function rolloutSupersededBy(requested, settled) {
|
|
26695
|
+
if (!requested || !settled) return void 0;
|
|
26696
|
+
if (requested.deploymentId !== void 0 && typeof settled.id === "string" && settled.id) return settled.id === requested.deploymentId ? void 0 : describeRollout(settled);
|
|
26697
|
+
if (requested.taskDefinition !== void 0 && typeof settled.taskDefinition === "string" && settled.taskDefinition) return settled.taskDefinition === requested.taskDefinition ? void 0 : describeRollout(settled);
|
|
26698
|
+
}
|
|
26415
26699
|
function markNotGoneOnNotFoundClass$1(error, wrapped) {
|
|
26416
26700
|
return error instanceof Error && error.name.includes("NotFound") ? markNotGone(wrapped) : wrapped;
|
|
26417
26701
|
}
|
|
@@ -26561,7 +26845,7 @@ var ECSProvider = class {
|
|
|
26561
26845
|
switch (resourceType) {
|
|
26562
26846
|
case "AWS::ECS::Cluster": return this.createCluster(logicalId, resourceType, properties, this.operationSinks(context, [[properties["ClusterName"], properties["ClusterName"]]]));
|
|
26563
26847
|
case "AWS::ECS::TaskDefinition": return this.createTaskDefinition(logicalId, resourceType, properties, this.operationSinks(context, [[properties["Family"], properties["Family"]]]));
|
|
26564
|
-
case "AWS::ECS::Service": return this.createService(logicalId, resourceType, properties, this.operationSinks(context, [[properties["ServiceName"], properties["ServiceName"]], [properties["Cluster"], clusterNameOfRef(properties["Cluster"])]]));
|
|
26848
|
+
case "AWS::ECS::Service": return this.createService(logicalId, resourceType, properties, this.operationSinks(context, [[properties["ServiceName"], properties["ServiceName"]], [properties["Cluster"], clusterNameOfRef(properties["Cluster"])]]), context?.replayingState === true);
|
|
26565
26849
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
|
|
26566
26850
|
}
|
|
26567
26851
|
}
|
|
@@ -26578,7 +26862,7 @@ var ECSProvider = class {
|
|
|
26578
26862
|
[properties["Cluster"], recordedCluster],
|
|
26579
26863
|
[previousProperties["Cluster"], recordedCluster],
|
|
26580
26864
|
[properties["Cluster"], clusterNameOfRef(properties["Cluster"])]
|
|
26581
|
-
]), context?.desiredFromAwsReadback === true);
|
|
26865
|
+
]), context?.desiredFromAwsReadback === true, context?.replayingState === true);
|
|
26582
26866
|
}
|
|
26583
26867
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId, physicalId);
|
|
26584
26868
|
}
|
|
@@ -26798,14 +27082,15 @@ var ECSProvider = class {
|
|
|
26798
27082
|
default: return;
|
|
26799
27083
|
}
|
|
26800
27084
|
}
|
|
26801
|
-
async createService(logicalId, resourceType, properties, log) {
|
|
27085
|
+
async createService(logicalId, resourceType, properties, log, replayingState) {
|
|
26802
27086
|
log.debug(`Creating ECS service ${logicalId}`);
|
|
26803
27087
|
const desiredTags = refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId);
|
|
26804
27088
|
const client = this.getClient();
|
|
26805
27089
|
const serviceName = properties["ServiceName"] || generatedNameFor("AWS::ECS::Service", logicalId);
|
|
26806
27090
|
let survivorArn;
|
|
26807
27091
|
try {
|
|
26808
|
-
const
|
|
27092
|
+
const skipReason = controllerSkipsWait(properties);
|
|
27093
|
+
const heldBefore = process.env["CDKD_NO_WAIT"] !== "true" && skipReason === void 0 && !replayingState ? await nameHeldBefore(() => this.serviceNameHeld(properties["Cluster"], serviceName), (error) => hasErrorName(error, ["ClusterNotFoundException"])) : "free";
|
|
26809
27094
|
const service = (await client.send(new CreateServiceCommand({
|
|
26810
27095
|
cluster: properties["Cluster"],
|
|
26811
27096
|
serviceName,
|
|
@@ -26838,8 +27123,18 @@ var ECSProvider = class {
|
|
|
26838
27123
|
log.debug(`Successfully created ECS service ${logicalId}: ${service.serviceArn}`);
|
|
26839
27124
|
if (heldBefore === "free") reportCreatedResource(logicalId, resourceType, service.serviceArn);
|
|
26840
27125
|
try {
|
|
26841
|
-
await this.settleService(logicalId, service.serviceName ?? service.serviceArn, properties["Cluster"], log);
|
|
27126
|
+
await this.settleService(logicalId, service.serviceName ?? service.serviceArn, properties["Cluster"], log, requestedRolloutOf(service), skipReason);
|
|
26842
27127
|
} catch (waitError) {
|
|
27128
|
+
if (replayingState) {
|
|
27129
|
+
log.warn(`${this.wrapSteadyStateError(logicalId, waitError, properties["Cluster"], log, false).message} Continuing the rollback: the restored service stays recorded.`);
|
|
27130
|
+
return {
|
|
27131
|
+
physicalId: service.serviceArn,
|
|
27132
|
+
attributes: {
|
|
27133
|
+
ServiceArn: service.serviceArn,
|
|
27134
|
+
Name: service.serviceName
|
|
27135
|
+
}
|
|
27136
|
+
};
|
|
27137
|
+
}
|
|
26843
27138
|
const aws = pasteableAwsCommand(log.mask);
|
|
26844
27139
|
const cleanupCluster = properties["Cluster"];
|
|
26845
27140
|
const clusterArg = cleanupCluster ? aws` --cluster ${cleanupCluster}` : aws``;
|
|
@@ -26861,10 +27156,7 @@ var ECSProvider = class {
|
|
|
26861
27156
|
if (cleanupFailure.redacted) log.debug(`${cleanupHead}${cleanupFailure.detail}`);
|
|
26862
27157
|
log.warn(`${cleanupHead}${cleanupFailure.redacted ? `${cleanupFailure.summary} ` : `${cleanupFailure.detail}. `}Manual deletion may be required before the next deploy: ${deleteCommand.render()}`);
|
|
26863
27158
|
}
|
|
26864
|
-
|
|
26865
|
-
if (waitFailure.redacted) log.debug(`ECS service ${logicalId} steady-state wait failed: ${waitFailure.detail}`);
|
|
26866
|
-
const steadyStateError = new Error(`ECS service ${logicalIdShown(logicalId)} did not reach steady state under --full-wait: ${waitFailure.summary.replace(/\.$/, "")}. Inspect why its tasks stopped (stopped tasks stay visible for about an hour): ${listStopped.render()}, then ${aws`aws ecs describe-tasks${clusterArg} --tasks '<task-arn>' --query 'tasks[].[stoppedReason,containers[].reason]'`.render()}`, { cause: waitError });
|
|
26867
|
-
throw waitFailure.redacted ? markRedactedCause(steadyStateError) : steadyStateError;
|
|
27159
|
+
throw this.wrapSteadyStateError(logicalId, waitError, properties["Cluster"], log);
|
|
26868
27160
|
}
|
|
26869
27161
|
return {
|
|
26870
27162
|
physicalId: service.serviceArn,
|
|
@@ -26907,30 +27199,68 @@ var ECSProvider = class {
|
|
|
26907
27199
|
reduced.name = error.name;
|
|
26908
27200
|
return markRedactedCause(reduced);
|
|
26909
27201
|
}
|
|
26910
|
-
|
|
26911
|
-
|
|
27202
|
+
wrapSteadyStateError(logicalId, waitError, cluster, log, offerNoWait = true) {
|
|
27203
|
+
const aws = pasteableAwsCommand(log.mask);
|
|
27204
|
+
const clusterArg = cluster ? aws` --cluster ${cluster}` : aws``;
|
|
27205
|
+
const listStopped = aws`aws ecs list-tasks${clusterArg} --desired-status STOPPED`;
|
|
27206
|
+
const waitFailure = describeAwsFailure(waitError);
|
|
27207
|
+
if (waitFailure.redacted) log.debug(`ECS service ${logicalId} steady-state wait failed: ${waitFailure.detail}`);
|
|
27208
|
+
const flagsAvailable = offerNoWait && process.env["CDKD_WAIT_FLAGS_AVAILABLE"] === "true";
|
|
27209
|
+
const timeoutHint = flagsAvailable && !(waitError instanceof EcsCircuitBreakerVerdict) ? ` To wait longer, raise the limit with --resource-timeout AWS::ECS::Service=${commandHole("duration")}.` : "";
|
|
27210
|
+
const noWaitHint = flagsAvailable ? " To deploy without waiting for steady state, pass --no-wait." : "";
|
|
27211
|
+
const steadyStateError = new Error(`ECS service ${logicalIdShown(logicalId)} did not reach steady state: ${waitFailure.summary.replace(/\.$/, "")}. Inspect why its tasks stopped (stopped tasks stay visible for about an hour): ${listStopped.render()}, then ${aws`aws ecs describe-tasks${clusterArg} --tasks '<task-arn>' --query 'tasks[].[stoppedReason,containers[].reason]'`.render()}.${timeoutHint}${noWaitHint}`, { cause: waitError });
|
|
27212
|
+
return waitFailure.redacted ? markRedactedCause(steadyStateError) : steadyStateError;
|
|
27213
|
+
}
|
|
27214
|
+
async settleService(logicalId, serviceRef, cluster, log, requested, skipReason) {
|
|
27215
|
+
if (skipReason !== void 0) {
|
|
27216
|
+
this.logger.info(log.mask(`ECS service ${logicalIdShown(logicalId)} accepted (not waiting for steady state: ${skipReason}).`));
|
|
27217
|
+
return;
|
|
27218
|
+
}
|
|
27219
|
+
if (process.env["CDKD_NO_WAIT"] !== "true") {
|
|
26912
27220
|
log.debug(`Waiting for ECS service ${logicalId} to reach steady state...`);
|
|
26913
27221
|
const maxWaitTime = Math.max(600, (resolvedResourceTimeoutMs("AWS::ECS::Service") ?? 0) / 1e3);
|
|
27222
|
+
const client = this.getClient();
|
|
27223
|
+
const breakerVerdict = new AbortController();
|
|
27224
|
+
let failedRollout;
|
|
27225
|
+
const watchedClient = { send: async (command) => {
|
|
27226
|
+
const output = await client.send(command);
|
|
27227
|
+
if (failedRollout === void 0) {
|
|
27228
|
+
failedRollout = failedRequestedDeployment(requested, output?.services?.[0]?.deployments);
|
|
27229
|
+
if (failedRollout !== void 0) breakerVerdict.abort();
|
|
27230
|
+
}
|
|
27231
|
+
return output;
|
|
27232
|
+
} };
|
|
26914
27233
|
try {
|
|
26915
27234
|
await waitUntilServicesStable({
|
|
26916
|
-
client:
|
|
27235
|
+
client: watchedClient,
|
|
26917
27236
|
maxWaitTime,
|
|
26918
27237
|
minDelay: 5,
|
|
26919
|
-
maxDelay: 10
|
|
27238
|
+
maxDelay: 10,
|
|
27239
|
+
abortSignal: breakerVerdict.signal
|
|
26920
27240
|
}, {
|
|
26921
27241
|
cluster,
|
|
26922
27242
|
services: [serviceRef]
|
|
26923
27243
|
});
|
|
26924
27244
|
} catch (waiterError) {
|
|
27245
|
+
if (failedRollout !== void 0) {
|
|
27246
|
+
log.debug(`ECS service ${logicalId} deployment ${failedRollout.id ?? "(no id)"} FAILED: ${failedRollout.rolloutStateReason ?? "(no rollout reason)"}`);
|
|
27247
|
+
throw wrapBreakerFailedError(failedRollout);
|
|
27248
|
+
}
|
|
26925
27249
|
throw this.wrapWaiterResultError(waiterError, logicalId, log);
|
|
26926
27250
|
}
|
|
27251
|
+
if (failedRollout !== void 0) throw wrapBreakerFailedError(failedRollout);
|
|
26927
27252
|
const rolloutDeadline = Date.now() + 12e4;
|
|
27253
|
+
let settledDeployment;
|
|
26928
27254
|
for (;;) {
|
|
26929
27255
|
const deployments = (await this.getClient().send(new DescribeServicesCommand({
|
|
26930
27256
|
cluster,
|
|
26931
27257
|
services: [serviceRef]
|
|
26932
27258
|
})))?.services?.[0]?.deployments;
|
|
26933
|
-
const
|
|
27259
|
+
const failedNow = failedRequestedDeployment(requested, deployments);
|
|
27260
|
+
if (failedNow !== void 0) throw wrapBreakerFailedError(failedNow);
|
|
27261
|
+
settledDeployment = deployments && deployments.length === 1 ? deployments[0] : void 0;
|
|
27262
|
+
const rolloutState = settledDeployment?.rolloutState;
|
|
27263
|
+
if (settledDeployment !== void 0 && rolloutState === "FAILED") throw wrapBreakerFailedError(settledDeployment);
|
|
26934
27264
|
if (rolloutState === void 0 || rolloutState === "COMPLETED") break;
|
|
26935
27265
|
if (Date.now() >= rolloutDeadline) {
|
|
26936
27266
|
log.warn(`ECS service ${logicalId} is steady but its rollout is still ${rolloutState} after the post-stability grace window; continuing`);
|
|
@@ -26938,15 +27268,22 @@ var ECSProvider = class {
|
|
|
26938
27268
|
}
|
|
26939
27269
|
await settleRolloutDelays.sleep(3e3);
|
|
26940
27270
|
}
|
|
27271
|
+
const supersededBy = rolloutSupersededBy(requested, settledDeployment);
|
|
27272
|
+
if (supersededBy !== void 0) {
|
|
27273
|
+
log.debug(`ECS service ${logicalId} settled deployment ${settledDeployment?.id ?? "(no id)"}: ${settledDeployment?.rolloutStateReason ?? "(no rollout reason)"}`);
|
|
27274
|
+
throw new EcsCircuitBreakerVerdict(`its deployment circuit breaker rolled the rollout back: the service settled on ${supersededBy}, not on the deployment this update started (${describeRollout({
|
|
27275
|
+
id: requested.deploymentId,
|
|
27276
|
+
taskDefinition: requested.taskDefinition
|
|
27277
|
+
})}). The new tasks failed to start or failed their health checks`);
|
|
27278
|
+
}
|
|
26941
27279
|
log.debug(`ECS service ${logicalId} reached steady state`);
|
|
26942
27280
|
return;
|
|
26943
27281
|
}
|
|
26944
27282
|
const aws = pasteableAwsCommand(log.mask);
|
|
26945
27283
|
const clusterArg = cluster ? aws` --cluster ${cluster}` : aws``;
|
|
26946
|
-
|
|
26947
|
-
this.logger.info(log.mask(`ECS service ${logicalIdShown(logicalId)} accepted (not waiting for steady state${fullWaitHint}). To wait manually: ${aws`aws ecs wait services-stable${clusterArg} --services ${serviceRef}`.render()}`));
|
|
27284
|
+
this.logger.info(log.mask(`ECS service ${logicalIdShown(logicalId)} accepted (not waiting for steady state under --no-wait). To wait manually: ${aws`aws ecs wait services-stable${clusterArg} --services ${serviceRef}`.render()}`));
|
|
26948
27285
|
}
|
|
26949
|
-
async updateService(logicalId, physicalId, resourceType, properties, previousProperties, log, desiredFromAwsReadback) {
|
|
27286
|
+
async updateService(logicalId, physicalId, resourceType, properties, previousProperties, log, desiredFromAwsReadback, replayingState) {
|
|
26950
27287
|
log.debug(`Updating ECS service ${logicalId}: ${physicalId}`);
|
|
26951
27288
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
26952
27289
|
const client = this.getClient();
|
|
@@ -27016,7 +27353,12 @@ var ECSProvider = class {
|
|
|
27016
27353
|
forceNewDeployment: forceNewDeploymentInput
|
|
27017
27354
|
}))).service;
|
|
27018
27355
|
if (service?.serviceArn) await this.applyTagDiff(service.serviceArn, resourceType, logicalId, previousProperties["Tags"], properties["Tags"], log);
|
|
27019
|
-
|
|
27356
|
+
try {
|
|
27357
|
+
await this.settleService(logicalId, service?.serviceName ?? physicalId, properties["Cluster"], log, requestedRolloutOf(service), desiredFromAwsReadback ? "a drift revert does not wait for it" : controllerSkipsWait(properties));
|
|
27358
|
+
} catch (waitError) {
|
|
27359
|
+
if (replayingState) log.warn(`${this.wrapSteadyStateError(logicalId, waitError, properties["Cluster"], log, false).message} The rollback update was applied; continuing.`);
|
|
27360
|
+
else throw this.wrapSteadyStateError(logicalId, waitError, properties["Cluster"], log);
|
|
27361
|
+
}
|
|
27020
27362
|
return {
|
|
27021
27363
|
physicalId,
|
|
27022
27364
|
wasReplaced: false,
|
|
@@ -29360,6 +29702,7 @@ const POLL_INTERVAL_MS$1 = 5e3;
|
|
|
29360
29702
|
const POLL_TIMEOUT_MS$1 = 18e5;
|
|
29361
29703
|
const RETAINED_ON_REMOVAL = [
|
|
29362
29704
|
"Auth",
|
|
29705
|
+
"DefaultAuthScheme",
|
|
29363
29706
|
"RequireTLS",
|
|
29364
29707
|
"IdleClientTimeout",
|
|
29365
29708
|
"DebugLogging",
|
|
@@ -29371,7 +29714,14 @@ const CFN_KEEPS_ON_REMOVAL$1 = /* @__PURE__ */ new Set([
|
|
|
29371
29714
|
"DebugLogging",
|
|
29372
29715
|
"VpcSecurityGroupIds"
|
|
29373
29716
|
]);
|
|
29374
|
-
const authRemovalRefused = (properties) => {
|
|
29717
|
+
const authRemovalRefused = (properties, previousProperties) => authRequired({ DefaultAuthScheme: properties["DefaultAuthScheme"] !== void 0 ? properties["DefaultAuthScheme"] : previousProperties["DefaultAuthScheme"] });
|
|
29718
|
+
const leavesProxyWithoutAuth = (properties, previousProperties) => {
|
|
29719
|
+
const desired = properties["Auth"];
|
|
29720
|
+
const declaredEmpty = desired === null || Array.isArray(desired) && desired.length === 0;
|
|
29721
|
+
if (properties["DefaultAuthScheme"] === "NONE" && previousProperties["DefaultAuthScheme"] !== "NONE" && (desired === void 0 || declaredEmpty)) return true;
|
|
29722
|
+
return declaredEmpty && JSON.stringify(desired) !== JSON.stringify(previousProperties["Auth"]) && authRemovalRefused(properties, previousProperties);
|
|
29723
|
+
};
|
|
29724
|
+
const authRequired = (properties) => {
|
|
29375
29725
|
const scheme = properties["DefaultAuthScheme"];
|
|
29376
29726
|
return scheme === void 0 || scheme === "NONE";
|
|
29377
29727
|
};
|
|
@@ -29391,6 +29741,9 @@ var RDSDBProxyProvider = class {
|
|
|
29391
29741
|
"RequireTLS",
|
|
29392
29742
|
"IdleClientTimeout",
|
|
29393
29743
|
"DebugLogging",
|
|
29744
|
+
"DefaultAuthScheme",
|
|
29745
|
+
"EndpointNetworkType",
|
|
29746
|
+
"TargetConnectionNetworkType",
|
|
29394
29747
|
"Tags"
|
|
29395
29748
|
])]]);
|
|
29396
29749
|
getClient() {
|
|
@@ -29417,18 +29770,21 @@ var RDSDBProxyProvider = class {
|
|
|
29417
29770
|
const engineFamily = properties["EngineFamily"];
|
|
29418
29771
|
if (!engineFamily) throw new ProvisioningError(`EngineFamily is required for AWS::RDS::DBProxy ${logicalId}`, resourceType, logicalId);
|
|
29419
29772
|
const auth = properties["Auth"];
|
|
29420
|
-
if (!auth || auth.length === 0) throw new ProvisioningError(`Auth (at least one entry) is required for AWS::RDS::DBProxy ${logicalId}`, resourceType, logicalId);
|
|
29773
|
+
if ((!auth || auth.length === 0) && authRequired(properties)) throw new ProvisioningError(`Auth (at least one entry) is required for AWS::RDS::DBProxy ${logicalId} while DefaultAuthScheme is NONE or unset`, resourceType, logicalId);
|
|
29421
29774
|
const roleArn = properties["RoleArn"];
|
|
29422
29775
|
if (!roleArn) throw new ProvisioningError(`RoleArn is required for AWS::RDS::DBProxy ${logicalId}`, resourceType, logicalId);
|
|
29423
29776
|
const vpcSubnetIds = properties["VpcSubnetIds"];
|
|
29424
29777
|
if (!vpcSubnetIds || vpcSubnetIds.length === 0) throw new ProvisioningError(`VpcSubnetIds (at least one) is required for AWS::RDS::DBProxy ${logicalId}`, resourceType, logicalId);
|
|
29425
29778
|
const client = this.getClient();
|
|
29426
|
-
this.logger.debug(`Creating DBProxy ${dbProxyName} (${engineFamily})`);
|
|
29779
|
+
this.logger.debug(mask(`Creating DBProxy ${dbProxyName} (${engineFamily})`));
|
|
29427
29780
|
try {
|
|
29428
29781
|
await this.getCreateClient().send(new CreateDBProxyCommand({
|
|
29429
29782
|
DBProxyName: dbProxyName,
|
|
29430
29783
|
EngineFamily: engineFamily,
|
|
29431
|
-
Auth: auth,
|
|
29784
|
+
Auth: auth && auth.length > 0 ? auth : void 0,
|
|
29785
|
+
DefaultAuthScheme: properties["DefaultAuthScheme"],
|
|
29786
|
+
EndpointNetworkType: properties["EndpointNetworkType"],
|
|
29787
|
+
TargetConnectionNetworkType: properties["TargetConnectionNetworkType"],
|
|
29432
29788
|
RoleArn: roleArn,
|
|
29433
29789
|
VpcSubnetIds: vpcSubnetIds,
|
|
29434
29790
|
VpcSecurityGroupIds: properties["VpcSecurityGroupIds"],
|
|
@@ -29480,13 +29836,16 @@ var RDSDBProxyProvider = class {
|
|
|
29480
29836
|
}
|
|
29481
29837
|
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
29482
29838
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId, "Tags", DBPROXY_TAGS_WHAT, DBPROXY_TAG_OPTIONS);
|
|
29483
|
-
if (context?.replayingState !== true && context?.desiredFromAwsReadback !== true && this.removedRetained(properties, previousProperties, context).includes("Auth") && authRemovalRefused(properties)) throw markNonRetryable(new ProvisioningError(safeMsg`${logicalId} (${resourceType}): Auth was removed from the template, but AWS requires Auth while DefaultAuthScheme is NONE or unset, and CloudFormation's update fails on the same change. Declare Auth again; nothing was changed.`, resourceType, logicalId, physicalId));
|
|
29839
|
+
if (context?.replayingState !== true && context?.desiredFromAwsReadback !== true && this.removedRetained(properties, previousProperties, context).includes("Auth") && authRemovalRefused(properties, previousProperties)) throw markNonRetryable(new ProvisioningError(safeMsg`${logicalId} (${resourceType}): Auth was removed from the template, but AWS requires Auth while DefaultAuthScheme is NONE or unset, and CloudFormation's update fails on the same change. Declare Auth again; nothing was changed.`, resourceType, logicalId, physicalId));
|
|
29840
|
+
if (context?.replayingState !== true && context?.desiredFromAwsReadback !== true && leavesProxyWithoutAuth(properties, previousProperties)) throw markNonRetryable(new ProvisioningError(safeMsg`${logicalId} (${resourceType}): the update leaves the proxy with no Auth while DefaultAuthScheme is NONE or unset, and AWS requires Auth then. Declare Auth; nothing was changed.`, resourceType, logicalId, physicalId));
|
|
29484
29841
|
const client = this.getClient();
|
|
29485
29842
|
const { mask } = withDerivedNameMasks(this.logger, createMaskedLogSinks(this.logger, context?.maskSecrets), [[previousProperties["DBProxyName"], physicalId]]);
|
|
29486
29843
|
for (const field of [
|
|
29487
29844
|
"DBProxyName",
|
|
29488
29845
|
"EngineFamily",
|
|
29489
|
-
"VpcSubnetIds"
|
|
29846
|
+
"VpcSubnetIds",
|
|
29847
|
+
"EndpointNetworkType",
|
|
29848
|
+
"TargetConnectionNetworkType"
|
|
29490
29849
|
]) if (JSON.stringify(properties[field]) !== JSON.stringify(previousProperties[field]) && !await unchangedBehindSecretReference({
|
|
29491
29850
|
resourceType,
|
|
29492
29851
|
key: field,
|
|
@@ -29499,6 +29858,7 @@ var RDSDBProxyProvider = class {
|
|
|
29499
29858
|
let hasModify = false;
|
|
29500
29859
|
for (const key of [
|
|
29501
29860
|
"Auth",
|
|
29861
|
+
"DefaultAuthScheme",
|
|
29502
29862
|
"RequireTLS",
|
|
29503
29863
|
"IdleClientTimeout",
|
|
29504
29864
|
"DebugLogging",
|
|
@@ -29626,7 +29986,10 @@ var RDSDBProxyProvider = class {
|
|
|
29626
29986
|
SecretArn: a.SecretArn,
|
|
29627
29987
|
IAMAuth: a.IAMAuth,
|
|
29628
29988
|
ClientPasswordAuthType: a.ClientPasswordAuthType
|
|
29629
|
-
}))
|
|
29989
|
+
})),
|
|
29990
|
+
...p.DefaultAuthScheme !== void 0 && { DefaultAuthScheme: p.DefaultAuthScheme },
|
|
29991
|
+
...p.EndpointNetworkType !== void 0 && { EndpointNetworkType: p.EndpointNetworkType },
|
|
29992
|
+
...p.TargetConnectionNetworkType !== void 0 && { TargetConnectionNetworkType: p.TargetConnectionNetworkType }
|
|
29630
29993
|
};
|
|
29631
29994
|
if (p.DBProxyArn) try {
|
|
29632
29995
|
const tagResp = await client.send(new ListTagsForResourceCommand$10({ ResourceName: p.DBProxyArn }));
|
|
@@ -29729,6 +30092,7 @@ var RDSDBProxyEndpointProvider = class {
|
|
|
29729
30092
|
"VpcSubnetIds",
|
|
29730
30093
|
"VpcSecurityGroupIds",
|
|
29731
30094
|
"TargetRole",
|
|
30095
|
+
"EndpointNetworkType",
|
|
29732
30096
|
"Tags"
|
|
29733
30097
|
])]]);
|
|
29734
30098
|
getClient() {
|
|
@@ -29765,6 +30129,7 @@ var RDSDBProxyEndpointProvider = class {
|
|
|
29765
30129
|
VpcSubnetIds: vpcSubnetIds,
|
|
29766
30130
|
VpcSecurityGroupIds: properties["VpcSecurityGroupIds"],
|
|
29767
30131
|
TargetRole: properties["TargetRole"],
|
|
30132
|
+
EndpointNetworkType: properties["EndpointNetworkType"],
|
|
29768
30133
|
Tags: tags.length > 0 ? tags : void 0
|
|
29769
30134
|
}));
|
|
29770
30135
|
} catch (error) {
|
|
@@ -29820,7 +30185,8 @@ var RDSDBProxyEndpointProvider = class {
|
|
|
29820
30185
|
"DBProxyName",
|
|
29821
30186
|
"DBProxyEndpointName",
|
|
29822
30187
|
"VpcSubnetIds",
|
|
29823
|
-
"TargetRole"
|
|
30188
|
+
"TargetRole",
|
|
30189
|
+
"EndpointNetworkType"
|
|
29824
30190
|
]) if (JSON.stringify(properties[field]) !== JSON.stringify(previousProperties[field]) && !await unchangedBehindSecretReference({
|
|
29825
30191
|
resourceType,
|
|
29826
30192
|
key: field,
|
|
@@ -29924,7 +30290,8 @@ var RDSDBProxyEndpointProvider = class {
|
|
|
29924
30290
|
DBProxyName: e.DBProxyName,
|
|
29925
30291
|
VpcSubnetIds: e.VpcSubnetIds ?? [],
|
|
29926
30292
|
VpcSecurityGroupIds: e.VpcSecurityGroupIds ?? [],
|
|
29927
|
-
TargetRole: e.TargetRole ?? "READ_WRITE"
|
|
30293
|
+
TargetRole: e.TargetRole ?? "READ_WRITE",
|
|
30294
|
+
...e.EndpointNetworkType !== void 0 && { EndpointNetworkType: e.EndpointNetworkType }
|
|
29928
30295
|
};
|
|
29929
30296
|
if (e.DBProxyEndpointArn) try {
|
|
29930
30297
|
const tagResp = await client.send(new ListTagsForResourceCommand$10({ ResourceName: e.DBProxyEndpointArn }));
|
|
@@ -30587,6 +30954,25 @@ function masterUserPasswordToSend(properties, previousProperties, context) {
|
|
|
30587
30954
|
return typeof desired === "string" && typeof recorded === "string" && recorded === desired && dynamicReferenceTokens(recorded).length === 0 && recorded !== "***" ? void 0 : desired;
|
|
30588
30955
|
}
|
|
30589
30956
|
const DOCDB_DEFAULT_PORT = 27017;
|
|
30957
|
+
const DOCDB_CLUSTER_KEPT_ON_REMOVAL = [
|
|
30958
|
+
"DeletionProtection",
|
|
30959
|
+
"BackupRetentionPeriod",
|
|
30960
|
+
"VpcSecurityGroupIds",
|
|
30961
|
+
"EngineVersion",
|
|
30962
|
+
"PreferredBackupWindow",
|
|
30963
|
+
"PreferredMaintenanceWindow",
|
|
30964
|
+
"DBClusterParameterGroupName"
|
|
30965
|
+
];
|
|
30966
|
+
const DOCDB_INSTANCE_KEPT_ON_REMOVAL = ["PreferredMaintenanceWindow"];
|
|
30967
|
+
function keptOnRemovalWarning$1(keys, properties, previousProperties, context, logicalId, resourceType) {
|
|
30968
|
+
const removedSet = context?.removedProperties ?? new Set(removedTemplateKeys(previousProperties, properties));
|
|
30969
|
+
const removed = keys.filter((key) => removedSet.has(key));
|
|
30970
|
+
if (removed.length === 0) return void 0;
|
|
30971
|
+
const one = removed.length === 1;
|
|
30972
|
+
const names = `${one ? "property" : "properties"} ${removed.join(", ")}`;
|
|
30973
|
+
const modify = resourceType === "AWS::DocDB::DBInstance" ? "ModifyDBInstance" : "ModifyDBCluster";
|
|
30974
|
+
return context?.replayingState ? safeMsg`${logicalId} (${resourceType}): ${names} ${one ? "is" : "are"} absent from the state being restored; ${modify} keeps a setting it is not sent, so the rollback leaves any value the failed deploy applied in place.` : safeMsg`${logicalId} (${resourceType}): ${names} ${one ? "was" : "were"} removed from the template; cdkd leaves the current AWS ${one ? "value" : "values"} in place, as CloudFormation does. Declare ${one ? "it" : "them"} to change ${one ? "it" : "them"}.`;
|
|
30975
|
+
}
|
|
30590
30976
|
const SECURITY_GROUP_CHANGE_MEMBER_STATUSES = /* @__PURE__ */ new Set(["modifying"]);
|
|
30591
30977
|
const PORT_CHANGE_MEMBER_STATUSES = /* @__PURE__ */ new Set(["modifying", "rebooting"]);
|
|
30592
30978
|
function numberOrUndefined(value) {
|
|
@@ -30628,6 +31014,25 @@ var DocDBProvider = class {
|
|
|
30628
31014
|
logger = getLogger().child("DocDBProvider");
|
|
30629
31015
|
protectionFlips = new ProtectionFlipRegistry();
|
|
30630
31016
|
disableCcApiFallback = true;
|
|
31017
|
+
removalHandledInUpdate = /* @__PURE__ */ new Map([["AWS::DocDB::DBCluster", /* @__PURE__ */ new Set([
|
|
31018
|
+
"DBClusterIdentifier",
|
|
31019
|
+
"DBSubnetGroupName",
|
|
31020
|
+
"KmsKeyId",
|
|
31021
|
+
"MasterUsername",
|
|
31022
|
+
"StorageEncrypted",
|
|
31023
|
+
"Port",
|
|
31024
|
+
"Tags",
|
|
31025
|
+
"MasterUserPassword",
|
|
31026
|
+
...DOCDB_CLUSTER_KEPT_ON_REMOVAL
|
|
31027
|
+
])], ["AWS::DocDB::DBInstance", /* @__PURE__ */ new Set([
|
|
31028
|
+
"DBInstanceIdentifier",
|
|
31029
|
+
"DBClusterIdentifier",
|
|
31030
|
+
"AvailabilityZone",
|
|
31031
|
+
"DBInstanceClass",
|
|
31032
|
+
"Tags",
|
|
31033
|
+
"AutoMinorVersionUpgrade",
|
|
31034
|
+
...DOCDB_INSTANCE_KEPT_ON_REMOVAL
|
|
31035
|
+
])]]);
|
|
30631
31036
|
handledProperties = /* @__PURE__ */ new Map([["AWS::DocDB::DBCluster", /* @__PURE__ */ new Set([
|
|
30632
31037
|
"DBClusterIdentifier",
|
|
30633
31038
|
"EngineVersion",
|
|
@@ -30681,7 +31086,7 @@ var DocDBProvider = class {
|
|
|
30681
31086
|
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
30682
31087
|
switch (resourceType) {
|
|
30683
31088
|
case "AWS::DocDB::DBCluster": return this.updateDBCluster(logicalId, physicalId, resourceType, properties, previousProperties, context);
|
|
30684
|
-
case "AWS::DocDB::DBInstance": return this.updateDBInstance(logicalId, physicalId, resourceType, properties, previousProperties, context
|
|
31089
|
+
case "AWS::DocDB::DBInstance": return this.updateDBInstance(logicalId, physicalId, resourceType, properties, previousProperties, context);
|
|
30685
31090
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId, physicalId);
|
|
30686
31091
|
}
|
|
30687
31092
|
}
|
|
@@ -30773,6 +31178,8 @@ var DocDBProvider = class {
|
|
|
30773
31178
|
for (const member of described?.DBClusterMembers ?? []) if (member.DBInstanceIdentifier) await this.waitForMemberAfterClusterChange(member.DBInstanceIdentifier, logicalId, SECURITY_GROUP_CHANGE_MEMBER_STATUSES, "VPC security groups");
|
|
30774
31179
|
}
|
|
30775
31180
|
if (described?.DBClusterArn) await applyDocDBTagDiff(this.getClient(), this.logger, described.DBClusterArn, resourceType, logicalId, previousProperties["Tags"], properties["Tags"]);
|
|
31181
|
+
const keptWarning = keptOnRemovalWarning$1(DOCDB_CLUSTER_KEPT_ON_REMOVAL, properties, previousProperties, context, logicalId, resourceType);
|
|
31182
|
+
if (keptWarning !== void 0) this.logger.warn(keptWarning);
|
|
30776
31183
|
return {
|
|
30777
31184
|
physicalId,
|
|
30778
31185
|
wasReplaced: false,
|
|
@@ -30896,8 +31303,9 @@ var DocDBProvider = class {
|
|
|
30896
31303
|
throw thrown;
|
|
30897
31304
|
}
|
|
30898
31305
|
}
|
|
30899
|
-
async updateDBInstance(logicalId, physicalId, resourceType, properties, previousProperties,
|
|
31306
|
+
async updateDBInstance(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
30900
31307
|
this.logger.debug(`Updating DocDB DBInstance ${logicalId}: ${physicalId}`);
|
|
31308
|
+
const mask = context?.maskSecrets;
|
|
30901
31309
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
30902
31310
|
try {
|
|
30903
31311
|
await modifyDbInstanceWhenAvailable({
|
|
@@ -30918,6 +31326,8 @@ var DocDBProvider = class {
|
|
|
30918
31326
|
this.logger.debug(`Successfully updated DocDB DBInstance ${logicalId}`);
|
|
30919
31327
|
const described = await this.describeDBInstance(physicalId);
|
|
30920
31328
|
if (described?.DBInstanceArn) await applyDocDBTagDiff(this.getClient(), this.logger, described.DBInstanceArn, resourceType, logicalId, previousProperties["Tags"], properties["Tags"]);
|
|
31329
|
+
const keptWarning = keptOnRemovalWarning$1(DOCDB_INSTANCE_KEPT_ON_REMOVAL, properties, previousProperties, context, logicalId, resourceType);
|
|
31330
|
+
if (keptWarning !== void 0) this.logger.warn(keptWarning);
|
|
30921
31331
|
return {
|
|
30922
31332
|
physicalId,
|
|
30923
31333
|
wasReplaced: false,
|
|
@@ -34150,6 +34560,36 @@ function nodesToRemove(nodes, desiredCount, desiredZones) {
|
|
|
34150
34560
|
if (keep.size + unnamed < desiredCount) return void 0;
|
|
34151
34561
|
return named.map((n) => n.id).filter((id) => !keep.has(id)).sort();
|
|
34152
34562
|
}
|
|
34563
|
+
const KEPT_ON_REMOVAL$1 = [
|
|
34564
|
+
"EngineVersion",
|
|
34565
|
+
"CacheParameterGroupName",
|
|
34566
|
+
"PreferredMaintenanceWindow",
|
|
34567
|
+
"SnapshotWindow",
|
|
34568
|
+
"IpDiscovery",
|
|
34569
|
+
"SnapshotRetentionLimit",
|
|
34570
|
+
"AutoMinorVersionUpgrade",
|
|
34571
|
+
"NotificationTopicArn",
|
|
34572
|
+
"VpcSecurityGroupIds",
|
|
34573
|
+
"TransitEncryptionEnabled",
|
|
34574
|
+
"PreferredAvailabilityZone"
|
|
34575
|
+
];
|
|
34576
|
+
const NOT_MODIFIABLE = /* @__PURE__ */ new Set(["TransitEncryptionEnabled", "PreferredAvailabilityZone"]);
|
|
34577
|
+
const PLACEMENT_ON_REMOVAL = ["AZMode", "PreferredAvailabilityZones"];
|
|
34578
|
+
const removalWarnings = (logicalId, kept, placement, caller) => {
|
|
34579
|
+
const lines = [];
|
|
34580
|
+
const head = (names) => safeMsg`${logicalId} (AWS::ElastiCache::CacheCluster): ${names.length === 1 ? "property" : "properties"} ${names.join(", ")}`;
|
|
34581
|
+
if (kept.length > 0) {
|
|
34582
|
+
const one = kept.length === 1;
|
|
34583
|
+
const fixed = kept.filter((name) => NOT_MODIFIABLE.has(name));
|
|
34584
|
+
const replaceNote = fixed.length === 0 ? "" : safeMsg` (${fixed.join(", ")} ${fixed.length === 1 ? "changes" : "change"} only by replacing the cluster)`;
|
|
34585
|
+
lines.push(caller === "rollback" ? `${head(kept)} ${one ? "is" : "are"} absent from the state being restored; the rollback sends nothing for ${one ? "it" : "them"}, so the cluster keeps the value it holds now.` : `${head(kept)} ${one ? "was" : "were"} removed from the template and ${one ? "keeps its" : "keep their"} current AWS value, as CloudFormation leaves ${one ? "it" : "them"}; cdkd sends nothing for a removed property. To change a value, declare it explicitly${replaceNote}.`);
|
|
34586
|
+
}
|
|
34587
|
+
if (placement.length > 0) {
|
|
34588
|
+
const one = placement.length === 1;
|
|
34589
|
+
lines.push(caller === "rollback" ? `${head(placement)} ${one ? "is" : "are"} absent from the state being restored; the rollback leaves the cluster unchanged.` : `${head(placement)} ${one ? "was" : "were"} removed from the template; cdkd sends nothing for a removed property, so the nodes stay in their zones. CloudFormation updates a cross-az cluster, or a single-az one that keeps its zone list, in place. It replaces a memcached single-az cluster left with no zone, and cdkd plans that replacement too (go-to-k/cdkd#5558). To move the nodes, replace the cluster, for example by changing its logical ID.`);
|
|
34590
|
+
}
|
|
34591
|
+
return lines;
|
|
34592
|
+
};
|
|
34153
34593
|
var ElastiCacheProvider = class {
|
|
34154
34594
|
client;
|
|
34155
34595
|
createClient;
|
|
@@ -34199,6 +34639,22 @@ var ElastiCacheProvider = class {
|
|
|
34199
34639
|
"TransitEncryptionEnabled"
|
|
34200
34640
|
])]]);
|
|
34201
34641
|
unhandledByDesign = /* @__PURE__ */ new Map([["AWS::ElastiCache::CacheCluster", /* @__PURE__ */ new Map([["CacheSecurityGroupNames", "EC2-Classic-only — use VpcSecurityGroupIds for VPC-deployed clusters (EC2-Classic retired 2022-08-15)"]])]]);
|
|
34642
|
+
removalHandledInUpdate = /* @__PURE__ */ new Map([["AWS::ElastiCache::CacheCluster", /* @__PURE__ */ new Set([
|
|
34643
|
+
"CacheSubnetGroupName",
|
|
34644
|
+
"ClusterName",
|
|
34645
|
+
"Engine",
|
|
34646
|
+
"NetworkType",
|
|
34647
|
+
"Port",
|
|
34648
|
+
"SnapshotName",
|
|
34649
|
+
"SnapshotArns",
|
|
34650
|
+
"CacheSecurityGroupNames",
|
|
34651
|
+
"CacheNodeType",
|
|
34652
|
+
"NumCacheNodes",
|
|
34653
|
+
"Tags",
|
|
34654
|
+
"LogDeliveryConfigurations",
|
|
34655
|
+
...KEPT_ON_REMOVAL$1,
|
|
34656
|
+
...PLACEMENT_ON_REMOVAL
|
|
34657
|
+
])]]);
|
|
34202
34658
|
getClient() {
|
|
34203
34659
|
if (!this.client) {
|
|
34204
34660
|
this.client = new ElastiCacheClient({
|
|
@@ -34228,7 +34684,7 @@ var ElastiCacheProvider = class {
|
|
|
34228
34684
|
const mask = context?.maskSecrets;
|
|
34229
34685
|
switch (resourceType) {
|
|
34230
34686
|
case "AWS::ElastiCache::SubnetGroup": return this.updateSubnetGroup(logicalId, physicalId, resourceType, properties, previousProperties, mask);
|
|
34231
|
-
case "AWS::ElastiCache::CacheCluster": return this.updateCacheCluster(logicalId, physicalId, resourceType, properties, previousProperties, mask);
|
|
34687
|
+
case "AWS::ElastiCache::CacheCluster": return this.updateCacheCluster(logicalId, physicalId, resourceType, properties, previousProperties, mask, context);
|
|
34232
34688
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId, physicalId);
|
|
34233
34689
|
}
|
|
34234
34690
|
}
|
|
@@ -34360,7 +34816,7 @@ var ElastiCacheProvider = class {
|
|
|
34360
34816
|
throw thrown;
|
|
34361
34817
|
}
|
|
34362
34818
|
}
|
|
34363
|
-
async updateCacheCluster(logicalId, physicalId, resourceType, properties, previousProperties, mask) {
|
|
34819
|
+
async updateCacheCluster(logicalId, physicalId, resourceType, properties, previousProperties, mask, context) {
|
|
34364
34820
|
this.logger.debug(`Updating CacheCluster ${logicalId}: ${physicalId}`);
|
|
34365
34821
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
34366
34822
|
try {
|
|
@@ -34399,6 +34855,7 @@ var ElastiCacheProvider = class {
|
|
|
34399
34855
|
const described = await this.describeCacheCluster(physicalId);
|
|
34400
34856
|
this.warnTransitEncryptionNotApplied(logicalId, properties, previousProperties, described?.TransitEncryptionEnabled);
|
|
34401
34857
|
if (described?.ARN) await this.applyTagDiff(described.ARN, resourceType, logicalId, previousProperties["Tags"], properties["Tags"]);
|
|
34858
|
+
this.warnRemovalsLeftInPlace(logicalId, properties, previousProperties, context);
|
|
34402
34859
|
const attributes = {};
|
|
34403
34860
|
if (described?.CacheNodes?.[0]?.Endpoint) {
|
|
34404
34861
|
const endpoint = described.CacheNodes[0].Endpoint;
|
|
@@ -34499,6 +34956,13 @@ var ElastiCacheProvider = class {
|
|
|
34499
34956
|
if (notApplied.length === 0) return;
|
|
34500
34957
|
this.logger.warn(safeMsg`CacheCluster ${logicalId}: the ${notApplied.join(", ")} change is not applied to the ` + "existing cluster (ModifyCacheCluster cannot change it, and CloudFormation leaves it unchanged too). To apply it, replace the cluster, for example by changing its logical ID.");
|
|
34501
34958
|
}
|
|
34959
|
+
warnRemovalsLeftInPlace(logicalId, properties, previousProperties, context) {
|
|
34960
|
+
if (context?.desiredFromAwsReadback) return;
|
|
34961
|
+
const removed = context?.removedProperties;
|
|
34962
|
+
const wasRemoved = (key) => removed !== void 0 ? removed.has(key) : properties[key] === void 0 && previousProperties[key] !== void 0;
|
|
34963
|
+
const lines = removalWarnings(logicalId, KEPT_ON_REMOVAL$1.filter(wasRemoved), PLACEMENT_ON_REMOVAL.filter(wasRemoved), context?.replayingState ? "rollback" : "deploy");
|
|
34964
|
+
for (const line of lines) this.logger.warn(line);
|
|
34965
|
+
}
|
|
34502
34966
|
buildLogDeliveryConfigurationsForUpdate(newConfigs, previousConfigs) {
|
|
34503
34967
|
const kept = newConfigs ?? [];
|
|
34504
34968
|
const keptLogTypes = new Set(kept.map((c) => c.LogType).filter((t) => t !== void 0));
|
|
@@ -35665,6 +36129,25 @@ const APPSYNC_APIKEY_ID_FORMAT = {
|
|
|
35665
36129
|
label: "AppSync ApiKey",
|
|
35666
36130
|
segments: ["apiId", "apiKeyId"]
|
|
35667
36131
|
};
|
|
36132
|
+
const CFN_APPSYNC_ARN_RESOURCE_PATHS = {
|
|
36133
|
+
"AWS::AppSync::GraphQLApi": /^apis\/([^/|]+)$/,
|
|
36134
|
+
"AWS::AppSync::DataSource": /^apis\/([^/|]+)\/datasources\/([^/|]+)$/,
|
|
36135
|
+
"AWS::AppSync::Resolver": /^apis\/([^/|]+)\/types\/([^/|]+)\/resolvers\/([^/|]+)$/,
|
|
36136
|
+
"AWS::AppSync::ApiKey": /^apis\/([^/|]+)\/apikeys?\/([^/|]+)$/
|
|
36137
|
+
};
|
|
36138
|
+
function graphQLSchemaApiId(physicalId) {
|
|
36139
|
+
const schema = /^([a-z0-9]+)GraphQLSchema$/.exec(physicalId);
|
|
36140
|
+
return schema ? schema[1] : physicalId;
|
|
36141
|
+
}
|
|
36142
|
+
function appSyncPhysicalIdFromCfn(resourceType, logicalId, physicalId, region) {
|
|
36143
|
+
if (resourceType === "AWS::AppSync::GraphQLSchema") return graphQLSchemaApiId(physicalId);
|
|
36144
|
+
const pathPattern = CFN_APPSYNC_ARN_RESOURCE_PATHS[resourceType];
|
|
36145
|
+
const arn = /^arn:[^:]+:appsync:([^:]*):[^:]*:(.+)$/.exec(physicalId);
|
|
36146
|
+
const segments = pathPattern && arn ? pathPattern.exec(arn[2]) : null;
|
|
36147
|
+
if (!arn || !segments) return physicalId;
|
|
36148
|
+
if (canonicalizeRegion(arn[1]) !== canonicalizeRegion(region)) throw markNonRetryable(new ProvisioningError(safeMsg`${resourceType} ${physicalId} is in region ${arn[1]}, not the import region ${region}`, resourceType, logicalId, physicalId));
|
|
36149
|
+
return segments.slice(1).join("|");
|
|
36150
|
+
}
|
|
35668
36151
|
const MUTABLE_GRAPHQL_API_CONFIG_PROPERTIES = [
|
|
35669
36152
|
"UserPoolConfig",
|
|
35670
36153
|
"OpenIDConnectConfig",
|
|
@@ -35804,7 +36287,7 @@ var AppSyncProvider = class {
|
|
|
35804
36287
|
}
|
|
35805
36288
|
if (resourceType === "AWS::AppSync::ApiKey" && parts.length === 2) {
|
|
35806
36289
|
const [apiId, apiKeyId] = parts;
|
|
35807
|
-
const apiKeyArn = await arn(`apis/${apiId}/
|
|
36290
|
+
const apiKeyArn = await arn(`apis/${apiId}/apikeys/${apiKeyId}`);
|
|
35808
36291
|
return {
|
|
35809
36292
|
ApiKey: apiKeyId,
|
|
35810
36293
|
...apiKeyArn && { Arn: apiKeyArn }
|
|
@@ -35953,12 +36436,13 @@ var AppSyncProvider = class {
|
|
|
35953
36436
|
};
|
|
35954
36437
|
}
|
|
35955
36438
|
async updateGraphQLSchema(logicalId, physicalId, resourceType, properties, previousProperties, mask = maskerOrIdentity(void 0)) {
|
|
36439
|
+
const recordedApiId = graphQLSchemaApiId(physicalId);
|
|
35956
36440
|
if (properties["ApiId"] !== void 0 && previousProperties["ApiId"] !== void 0 && properties["ApiId"] !== previousProperties["ApiId"] && !await unchangedBehindSecretReference({
|
|
35957
36441
|
resourceType,
|
|
35958
36442
|
key: "ApiId",
|
|
35959
36443
|
desired: properties["ApiId"],
|
|
35960
36444
|
previous: previousProperties["ApiId"],
|
|
35961
|
-
physicalName:
|
|
36445
|
+
physicalName: recordedApiId,
|
|
35962
36446
|
maskSecrets: mask
|
|
35963
36447
|
})) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, "AWS AppSync GraphQLSchema.ApiId cannot move a schema to another API in place (CloudFormation fails a template change of it too) — deploy with --replace, or give the schema a new logical ID, to create it on the new API");
|
|
35964
36448
|
const newDef = properties["Definition"];
|
|
@@ -35983,7 +36467,7 @@ var AppSyncProvider = class {
|
|
|
35983
36467
|
physicalId,
|
|
35984
36468
|
wasReplaced: false
|
|
35985
36469
|
};
|
|
35986
|
-
const apiId = properties["ApiId"] ??
|
|
36470
|
+
const apiId = properties["ApiId"] ?? recordedApiId;
|
|
35987
36471
|
try {
|
|
35988
36472
|
await this.getClient().send(new StartSchemaCreationCommand({
|
|
35989
36473
|
apiId,
|
|
@@ -36907,7 +37391,7 @@ var AppSyncProvider = class {
|
|
|
36907
37391
|
maskSecrets: context?.maskSecrets,
|
|
36908
37392
|
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
36909
37393
|
});
|
|
36910
|
-
const apiKeyArn = await this.buildAppSyncArnOrWarn(`apis/${apiId}/
|
|
37394
|
+
const apiKeyArn = await this.buildAppSyncArnOrWarn(`apis/${apiId}/apikeys/${apiKeyId}`, logicalId, physicalId);
|
|
36911
37395
|
return {
|
|
36912
37396
|
physicalId,
|
|
36913
37397
|
attributes: {
|
|
@@ -36992,10 +37476,11 @@ var AppSyncProvider = class {
|
|
|
36992
37476
|
}
|
|
36993
37477
|
}
|
|
36994
37478
|
async readGraphQLSchema(physicalId, properties) {
|
|
37479
|
+
const apiId = graphQLSchemaApiId(physicalId);
|
|
36995
37480
|
let resp;
|
|
36996
37481
|
try {
|
|
36997
37482
|
resp = await this.getClient().send(new GetIntrospectionSchemaCommand({
|
|
36998
|
-
apiId
|
|
37483
|
+
apiId,
|
|
36999
37484
|
format: "SDL"
|
|
37000
37485
|
}));
|
|
37001
37486
|
} catch (err) {
|
|
@@ -37012,7 +37497,7 @@ var AppSyncProvider = class {
|
|
|
37012
37497
|
if (await this.canonicalizeSdl(stateDefinition, "state") === canonicalAws) definitionToReturn = stateDefinition;
|
|
37013
37498
|
}
|
|
37014
37499
|
return {
|
|
37015
|
-
ApiId:
|
|
37500
|
+
ApiId: apiId,
|
|
37016
37501
|
Definition: definitionToReturn
|
|
37017
37502
|
};
|
|
37018
37503
|
}
|
|
@@ -37253,14 +37738,18 @@ var AppSyncProvider = class {
|
|
|
37253
37738
|
return RESOURCE_NOT_FOUND;
|
|
37254
37739
|
}
|
|
37255
37740
|
async import(input) {
|
|
37741
|
+
const known = input.knownPhysicalId && appSyncPhysicalIdFromCfn(input.resourceType, input.logicalId, input.knownPhysicalId, input.region);
|
|
37256
37742
|
if (input.resourceType !== "AWS::AppSync::GraphQLApi") {
|
|
37257
|
-
if (
|
|
37258
|
-
physicalId:
|
|
37259
|
-
attributes: await this.childImportAttributes(input.resourceType,
|
|
37743
|
+
if (known) return {
|
|
37744
|
+
physicalId: known,
|
|
37745
|
+
attributes: await this.childImportAttributes(input.resourceType, known, input.region)
|
|
37260
37746
|
};
|
|
37261
37747
|
return null;
|
|
37262
37748
|
}
|
|
37263
|
-
const explicit = resolveExplicitPhysicalId(
|
|
37749
|
+
const explicit = resolveExplicitPhysicalId(known ? {
|
|
37750
|
+
...input,
|
|
37751
|
+
knownPhysicalId: known
|
|
37752
|
+
} : input, null);
|
|
37264
37753
|
if (explicit) try {
|
|
37265
37754
|
const response = await this.getClient().send(new GetGraphqlApiCommand({ apiId: explicit }));
|
|
37266
37755
|
return {
|
|
@@ -43077,7 +43566,7 @@ var EFSProvider = class {
|
|
|
43077
43566
|
const log = createMaskedLogSinks(this.logger, context?.maskSecrets);
|
|
43078
43567
|
properties = withRemovalDefaults(this.removalDefaults, resourceType, properties, previousProperties, context);
|
|
43079
43568
|
switch (resourceType) {
|
|
43080
|
-
case "AWS::EFS::FileSystem": return this.updateFileSystem(logicalId, physicalId, resourceType, properties, previousProperties, log);
|
|
43569
|
+
case "AWS::EFS::FileSystem": return this.updateFileSystem(logicalId, physicalId, resourceType, properties, previousProperties, log, context?.replayingState === true || context?.desiredFromAwsReadback === true);
|
|
43081
43570
|
case "AWS::EFS::MountTarget": return this.updateMountTarget(logicalId, physicalId, resourceType, properties, log);
|
|
43082
43571
|
case "AWS::EFS::AccessPoint": return this.updateAccessPoint(logicalId, physicalId, resourceType, properties, previousProperties, log);
|
|
43083
43572
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId, physicalId);
|
|
@@ -43125,7 +43614,7 @@ var EFSProvider = class {
|
|
|
43125
43614
|
throw this.wrapMaskedError(log, error, (text) => new ProvisioningError(`Failed to update EFS AccessPoint ${logicalId}: ${text}`, resourceType, logicalId, physicalId, cause));
|
|
43126
43615
|
}
|
|
43127
43616
|
}
|
|
43128
|
-
async updateFileSystem(logicalId, physicalId, resourceType, properties, previousProperties, log) {
|
|
43617
|
+
async updateFileSystem(logicalId, physicalId, resourceType, properties, previousProperties, log, stateBorneDesired) {
|
|
43129
43618
|
for (const key of [
|
|
43130
43619
|
"Encrypted",
|
|
43131
43620
|
"KmsKeyId",
|
|
@@ -43140,8 +43629,13 @@ var EFSProvider = class {
|
|
|
43140
43629
|
const newProvisioned = properties["ProvisionedThroughputInMibps"];
|
|
43141
43630
|
const oldThroughputMode = previousProperties["ThroughputMode"];
|
|
43142
43631
|
const oldProvisioned = previousProperties["ProvisionedThroughputInMibps"];
|
|
43632
|
+
const throughputValueMissing = newThroughputMode === "provisioned" && newProvisioned === void 0 && (oldProvisioned !== void 0 || oldThroughputMode !== "provisioned");
|
|
43633
|
+
if (throughputValueMissing) {
|
|
43634
|
+
if (!stateBorneDesired) throw new ProvisioningError(`Failed to update EFS FileSystem ${logicalId}: Throughput value must be specified for provisioned throughput mode. The template sets ThroughputMode: provisioned without ProvisionedThroughputInMibps, which CloudFormation rejects too. Set ProvisionedThroughputInMibps, or change ThroughputMode (e.g. to bursting or elastic).`, resourceType, logicalId, physicalId);
|
|
43635
|
+
log.warn(`EFS FileSystem ${logicalId}: the desired properties (from cdkd state or an AWS readback, not the template) set ThroughputMode: provisioned without ProvisionedThroughputInMibps, which AWS rejects; leaving the file system's throughput as it is on AWS and applying the rest of the update. Its throughput may now differ from the record: run cdkd drift to see it.`);
|
|
43636
|
+
}
|
|
43143
43637
|
const effectiveThroughputMode = newThroughputMode === void 0 && newProvisioned === void 0 && oldThroughputMode === "provisioned" ? "bursting" : newThroughputMode;
|
|
43144
|
-
const throughputModeChanged = effectiveThroughputMode !== void 0 && effectiveThroughputMode !== oldThroughputMode;
|
|
43638
|
+
const throughputModeChanged = !throughputValueMissing && effectiveThroughputMode !== void 0 && effectiveThroughputMode !== oldThroughputMode;
|
|
43145
43639
|
const provisionedChanged = newProvisioned !== void 0 && newProvisioned !== oldProvisioned;
|
|
43146
43640
|
const changed = (key) => JSON.stringify(properties[key]) !== JSON.stringify(previousProperties[key]);
|
|
43147
43641
|
const lifecycleChanged = changed("LifecyclePolicies");
|
|
@@ -48642,7 +49136,8 @@ var CodeBuildProvider = class {
|
|
|
48642
49136
|
batchReportMode: cfnBuildBatchConfig["BatchReportMode"],
|
|
48643
49137
|
restrictions: restrictions ? {
|
|
48644
49138
|
maximumBuildsAllowed: restrictions["MaximumBuildsAllowed"],
|
|
48645
|
-
computeTypesAllowed: restrictions["ComputeTypesAllowed"]
|
|
49139
|
+
computeTypesAllowed: restrictions["ComputeTypesAllowed"],
|
|
49140
|
+
fleetsAllowed: restrictions["FleetsAllowed"]
|
|
48646
49141
|
} : void 0
|
|
48647
49142
|
};
|
|
48648
49143
|
}
|
|
@@ -48951,6 +49446,7 @@ var CodeBuildProvider = class {
|
|
|
48951
49446
|
const r = {};
|
|
48952
49447
|
if (project.buildBatchConfig.restrictions.maximumBuildsAllowed !== void 0) r["MaximumBuildsAllowed"] = project.buildBatchConfig.restrictions.maximumBuildsAllowed;
|
|
48953
49448
|
if (project.buildBatchConfig.restrictions.computeTypesAllowed !== void 0) r["ComputeTypesAllowed"] = project.buildBatchConfig.restrictions.computeTypesAllowed;
|
|
49449
|
+
if (project.buildBatchConfig.restrictions.fleetsAllowed !== void 0) r["FleetsAllowed"] = project.buildBatchConfig.restrictions.fleetsAllowed;
|
|
48954
49450
|
bbc["Restrictions"] = r;
|
|
48955
49451
|
}
|
|
48956
49452
|
if (project.buildBatchConfig.timeoutInMins !== void 0) bbc["TimeoutInMins"] = project.buildBatchConfig.timeoutInMins;
|
|
@@ -49519,6 +50015,28 @@ var CodeCommitRepositoryProvider = class {
|
|
|
49519
50015
|
|
|
49520
50016
|
//#endregion
|
|
49521
50017
|
//#region src/provisioning/providers/dlm-lifecycle-policy-provider.ts
|
|
50018
|
+
const KEPT_ON_REMOVAL = [
|
|
50019
|
+
"Description",
|
|
50020
|
+
"ExecutionRoleArn",
|
|
50021
|
+
"State",
|
|
50022
|
+
"PolicyDetails",
|
|
50023
|
+
"CreateInterval",
|
|
50024
|
+
"RetainInterval",
|
|
50025
|
+
"CopyTags",
|
|
50026
|
+
"ExtendDeletion",
|
|
50027
|
+
"CrossRegionCopyTargets",
|
|
50028
|
+
"Exclusions"
|
|
50029
|
+
];
|
|
50030
|
+
function keptRemovedNames(properties, previousProperties, context) {
|
|
50031
|
+
if (context?.desiredFromAwsReadback) return [];
|
|
50032
|
+
const removed = context?.removedProperties;
|
|
50033
|
+
return KEPT_ON_REMOVAL.filter((key) => previousProperties[key] != null && properties[key] == null && (removed === void 0 || removed.has(key) || properties[key] === null));
|
|
50034
|
+
}
|
|
50035
|
+
const keptOnRemovalWarning = (logicalId, names, caller) => {
|
|
50036
|
+
const one = names.length === 1;
|
|
50037
|
+
const subject = one ? "property" : "properties";
|
|
50038
|
+
return caller === "rollback" ? safeMsg`${logicalId} (AWS::DLM::LifecyclePolicy): ${subject} ${names.join(", ")} ${one ? "is" : "are"} absent from the state being restored; UpdateLifecyclePolicy keeps a field it is not sent, so the rollback leaves the value the failed deploy applied in place.` : safeMsg`${logicalId} (AWS::DLM::LifecyclePolicy): ${subject} ${names.join(", ")} ${one ? "was" : "were"} removed from the template and ${one ? "keeps its" : "keep their"} current AWS value, as CloudFormation leaves ${one ? "it" : "them"}; UpdateLifecyclePolicy keeps a field it is not sent. Declare the intended value explicitly to change it.`;
|
|
50039
|
+
};
|
|
49522
50040
|
const createLifecyclePolicyLatch = new AmbiguousCreateLatch("dlm:CreateLifecyclePolicy");
|
|
49523
50041
|
const policiesCreatedByThisProcess = new RecentIdSet();
|
|
49524
50042
|
var DLMLifecyclePolicyProvider = class {
|
|
@@ -49548,6 +50066,11 @@ var DLMLifecyclePolicyProvider = class {
|
|
|
49548
50066
|
"CrossRegionCopyTargets",
|
|
49549
50067
|
"Exclusions"
|
|
49550
50068
|
])]]);
|
|
50069
|
+
removalHandledInUpdate = /* @__PURE__ */ new Map([["AWS::DLM::LifecyclePolicy", /* @__PURE__ */ new Set([
|
|
50070
|
+
...KEPT_ON_REMOVAL,
|
|
50071
|
+
"Tags",
|
|
50072
|
+
"DefaultPolicy"
|
|
50073
|
+
])]]);
|
|
49551
50074
|
getClient() {
|
|
49552
50075
|
if (!this.client) this.client = new DLMClient({
|
|
49553
50076
|
...ambientClientDefaults(),
|
|
@@ -49672,6 +50195,8 @@ var DLMLifecyclePolicyProvider = class {
|
|
|
49672
50195
|
...properties["CreateInterval"] != null && { CreateInterval: Number(properties["CreateInterval"]) },
|
|
49673
50196
|
...properties["RetainInterval"] != null && { RetainInterval: Number(properties["RetainInterval"]) }
|
|
49674
50197
|
}));
|
|
50198
|
+
const keptNames = keptRemovedNames(properties, previousProperties, context);
|
|
50199
|
+
if (keptNames.length > 0) this.logger.warn(keptOnRemovalWarning(logicalId, keptNames, context?.replayingState ? "rollback" : "deploy"));
|
|
49675
50200
|
const plan = planTagDiff(previousProperties["Tags"], properties["Tags"]);
|
|
49676
50201
|
const tagWarning = tagPlanWarning(plan, resourceType, logicalId);
|
|
49677
50202
|
if (tagWarning !== void 0) this.logger.warn(tagWarning);
|
|
@@ -50875,6 +51400,173 @@ function tableIdentityFromGetTable(tableARN, namespace, name) {
|
|
|
50875
51400
|
name
|
|
50876
51401
|
};
|
|
50877
51402
|
}
|
|
51403
|
+
function isCfnObject(value) {
|
|
51404
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
51405
|
+
}
|
|
51406
|
+
function desiredObject(properties, key, resourceType, logicalId, physicalId) {
|
|
51407
|
+
const value = properties[key];
|
|
51408
|
+
if (value === void 0) return void 0;
|
|
51409
|
+
if (isCfnObject(value)) return value;
|
|
51410
|
+
throw new ProvisioningError(`${key} for ${resourceType} ${logicalId} must be an object; refusing before any call`, resourceType, logicalId, physicalId);
|
|
51411
|
+
}
|
|
51412
|
+
function recordedObject(properties, key) {
|
|
51413
|
+
const value = properties[key];
|
|
51414
|
+
return isCfnObject(value) ? value : void 0;
|
|
51415
|
+
}
|
|
51416
|
+
var NotAnInteger = class extends Error {
|
|
51417
|
+
member;
|
|
51418
|
+
constructor(member) {
|
|
51419
|
+
super(`${member} must be an integer`);
|
|
51420
|
+
this.member = member;
|
|
51421
|
+
}
|
|
51422
|
+
};
|
|
51423
|
+
function integer(value, member) {
|
|
51424
|
+
if (value === void 0) return void 0;
|
|
51425
|
+
const n = typeof value === "number" ? value : typeof value === "string" && value.trim() !== "" ? Number(value) : NaN;
|
|
51426
|
+
if (Number.isInteger(n)) return n;
|
|
51427
|
+
throw new NotAnInteger(member);
|
|
51428
|
+
}
|
|
51429
|
+
function refuseNonIntegers(convert, key, resourceType, logicalId, physicalId) {
|
|
51430
|
+
try {
|
|
51431
|
+
return convert();
|
|
51432
|
+
} catch (error) {
|
|
51433
|
+
if (!(error instanceof NotAnInteger)) throw error;
|
|
51434
|
+
throw new ProvisioningError(`${key}.${error.member} for ${resourceType} ${logicalId} must be an integer; refusing before any call`, resourceType, logicalId, physicalId, error);
|
|
51435
|
+
}
|
|
51436
|
+
}
|
|
51437
|
+
function list(value) {
|
|
51438
|
+
return Array.isArray(value) ? value : void 0;
|
|
51439
|
+
}
|
|
51440
|
+
function defined(value) {
|
|
51441
|
+
return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== void 0));
|
|
51442
|
+
}
|
|
51443
|
+
function maintenanceStatus(value) {
|
|
51444
|
+
return typeof value === "string" ? value.toLowerCase() : void 0;
|
|
51445
|
+
}
|
|
51446
|
+
function sdkEncryption(cfn) {
|
|
51447
|
+
return defined({
|
|
51448
|
+
sseAlgorithm: cfn["SSEAlgorithm"],
|
|
51449
|
+
kmsKeyArn: cfn["KMSKeyArn"]
|
|
51450
|
+
});
|
|
51451
|
+
}
|
|
51452
|
+
function sdkStorageClass(cfn) {
|
|
51453
|
+
return defined({ storageClass: cfn["StorageClass"] });
|
|
51454
|
+
}
|
|
51455
|
+
function sdkReplication(cfn) {
|
|
51456
|
+
return defined({
|
|
51457
|
+
role: cfn["Role"],
|
|
51458
|
+
rules: list(cfn["Rules"])?.map((rule) => defined({ destinations: list(isCfnObject(rule) ? rule["Destinations"] : void 0)?.map((destination) => defined({ destinationTableBucketARN: isCfnObject(destination) ? destination["DestinationTableBucketARN"] : void 0 })) }))
|
|
51459
|
+
});
|
|
51460
|
+
}
|
|
51461
|
+
function sdkUnreferencedFileRemoval(cfn) {
|
|
51462
|
+
const unreferencedDays = integer(cfn["UnreferencedDays"], "UnreferencedDays");
|
|
51463
|
+
const nonCurrentDays = integer(cfn["NoncurrentDays"], "NoncurrentDays");
|
|
51464
|
+
return defined({
|
|
51465
|
+
status: maintenanceStatus(cfn["Status"]),
|
|
51466
|
+
settings: unreferencedDays === void 0 && nonCurrentDays === void 0 ? void 0 : { icebergUnreferencedFileRemoval: defined({
|
|
51467
|
+
unreferencedDays,
|
|
51468
|
+
nonCurrentDays
|
|
51469
|
+
}) }
|
|
51470
|
+
});
|
|
51471
|
+
}
|
|
51472
|
+
function sdkCompaction(cfn) {
|
|
51473
|
+
const targetFileSizeMB = integer(cfn["TargetFileSizeMB"], "TargetFileSizeMB");
|
|
51474
|
+
return defined({
|
|
51475
|
+
status: maintenanceStatus(cfn["Status"]),
|
|
51476
|
+
settings: targetFileSizeMB === void 0 ? void 0 : { icebergCompaction: { targetFileSizeMB } }
|
|
51477
|
+
});
|
|
51478
|
+
}
|
|
51479
|
+
function sdkSnapshotManagement(cfn) {
|
|
51480
|
+
const minSnapshotsToKeep = integer(cfn["MinSnapshotsToKeep"], "MinSnapshotsToKeep");
|
|
51481
|
+
const maxSnapshotAgeHours = integer(cfn["MaxSnapshotAgeHours"], "MaxSnapshotAgeHours");
|
|
51482
|
+
return defined({
|
|
51483
|
+
status: maintenanceStatus(cfn["Status"]),
|
|
51484
|
+
settings: minSnapshotsToKeep === void 0 && maxSnapshotAgeHours === void 0 ? void 0 : { icebergSnapshotManagement: defined({
|
|
51485
|
+
minSnapshotsToKeep,
|
|
51486
|
+
maxSnapshotAgeHours
|
|
51487
|
+
}) }
|
|
51488
|
+
});
|
|
51489
|
+
}
|
|
51490
|
+
function mapObjects(value, map) {
|
|
51491
|
+
return list(value)?.map((element) => map(isCfnObject(element) ? element : {}));
|
|
51492
|
+
}
|
|
51493
|
+
function sdkIcebergMetadata(cfn) {
|
|
51494
|
+
const schema = isCfnObject(cfn["IcebergSchema"]) ? cfn["IcebergSchema"] : void 0;
|
|
51495
|
+
const schemaV2 = isCfnObject(cfn["IcebergSchemaV2"]) ? cfn["IcebergSchemaV2"] : void 0;
|
|
51496
|
+
const partitionSpec = isCfnObject(cfn["IcebergPartitionSpec"]) ? cfn["IcebergPartitionSpec"] : void 0;
|
|
51497
|
+
const sortOrder = isCfnObject(cfn["IcebergSortOrder"]) ? cfn["IcebergSortOrder"] : void 0;
|
|
51498
|
+
return defined({
|
|
51499
|
+
schema: schema && defined({ fields: mapObjects(schema["SchemaFieldList"], (f) => defined({
|
|
51500
|
+
id: integer(f["Id"], "IcebergSchema.SchemaFieldList.Id"),
|
|
51501
|
+
name: f["Name"],
|
|
51502
|
+
type: f["Type"],
|
|
51503
|
+
required: f["Required"]
|
|
51504
|
+
})) }),
|
|
51505
|
+
schemaV2: schemaV2 && defined({
|
|
51506
|
+
type: schemaV2["SchemaV2FieldType"],
|
|
51507
|
+
fields: mapObjects(schemaV2["SchemaV2FieldList"], (f) => defined({
|
|
51508
|
+
id: integer(f["Id"], "IcebergSchemaV2.SchemaV2FieldList.Id"),
|
|
51509
|
+
name: f["Name"],
|
|
51510
|
+
type: f["Type"],
|
|
51511
|
+
required: f["Required"],
|
|
51512
|
+
doc: f["Doc"]
|
|
51513
|
+
})),
|
|
51514
|
+
schemaId: integer(schemaV2["SchemaId"], "IcebergSchemaV2.SchemaId"),
|
|
51515
|
+
identifierFieldIds: list(schemaV2["IdentifierFieldIds"])?.map((id) => integer(id, "IcebergSchemaV2.IdentifierFieldIds"))
|
|
51516
|
+
}),
|
|
51517
|
+
partitionSpec: partitionSpec && defined({
|
|
51518
|
+
fields: mapObjects(partitionSpec["Fields"], (f) => defined({
|
|
51519
|
+
sourceId: integer(f["SourceId"], "IcebergPartitionSpec.Fields.SourceId"),
|
|
51520
|
+
transform: f["Transform"],
|
|
51521
|
+
name: f["Name"],
|
|
51522
|
+
fieldId: integer(f["FieldId"], "IcebergPartitionSpec.Fields.FieldId")
|
|
51523
|
+
})),
|
|
51524
|
+
specId: integer(partitionSpec["SpecId"], "IcebergPartitionSpec.SpecId")
|
|
51525
|
+
}),
|
|
51526
|
+
writeOrder: sortOrder && defined({
|
|
51527
|
+
orderId: integer(sortOrder["OrderId"], "IcebergSortOrder.OrderId"),
|
|
51528
|
+
fields: mapObjects(sortOrder["Fields"], (f) => defined({
|
|
51529
|
+
sourceId: integer(f["SourceId"], "IcebergSortOrder.Fields.SourceId"),
|
|
51530
|
+
transform: f["Transform"],
|
|
51531
|
+
direction: f["Direction"],
|
|
51532
|
+
nullOrder: f["NullOrder"]
|
|
51533
|
+
}))
|
|
51534
|
+
}),
|
|
51535
|
+
properties: isCfnObject(cfn["TableProperties"]) ? cfn["TableProperties"] : void 0
|
|
51536
|
+
});
|
|
51537
|
+
}
|
|
51538
|
+
const UPDATABLE_CONFIG_KEYS = {
|
|
51539
|
+
"AWS::S3Tables::TableBucket": [
|
|
51540
|
+
"EncryptionConfiguration",
|
|
51541
|
+
"StorageClassConfiguration",
|
|
51542
|
+
"MetricsConfiguration",
|
|
51543
|
+
"UnreferencedFileRemoval",
|
|
51544
|
+
"ReplicationConfiguration"
|
|
51545
|
+
],
|
|
51546
|
+
"AWS::S3Tables::Table": ["Compaction", "SnapshotManagement"]
|
|
51547
|
+
};
|
|
51548
|
+
function metricsEnabled(metrics, resourceType, logicalId, physicalId) {
|
|
51549
|
+
const status = metrics?.["Status"];
|
|
51550
|
+
if (status === void 0 || status === "Disabled") return false;
|
|
51551
|
+
if (status === "Enabled") return true;
|
|
51552
|
+
throw new ProvisioningError(safeMsg`MetricsConfiguration.Status for ${resourceType} ${logicalId} must be 'Enabled' or 'Disabled'; refusing before any call`, resourceType, logicalId, physicalId);
|
|
51553
|
+
}
|
|
51554
|
+
const TABLE_MAINTENANCE = [[
|
|
51555
|
+
"Compaction",
|
|
51556
|
+
"icebergCompaction",
|
|
51557
|
+
sdkCompaction
|
|
51558
|
+
], [
|
|
51559
|
+
"SnapshotManagement",
|
|
51560
|
+
"icebergSnapshotManagement",
|
|
51561
|
+
sdkSnapshotManagement
|
|
51562
|
+
]];
|
|
51563
|
+
const INTEGER_BEARING_CONFIGS = {
|
|
51564
|
+
"AWS::S3Tables::TableBucket": [["UnreferencedFileRemoval", sdkUnreferencedFileRemoval]],
|
|
51565
|
+
"AWS::S3Tables::Table": TABLE_MAINTENANCE.map(([key, , toSdk]) => [key, toSdk])
|
|
51566
|
+
};
|
|
51567
|
+
function cfnBucketStatus(status) {
|
|
51568
|
+
return status === void 0 ? void 0 : `${status.charAt(0).toUpperCase()}${status.slice(1)}`;
|
|
51569
|
+
}
|
|
50878
51570
|
function sentence(text) {
|
|
50879
51571
|
return text.endsWith(".") ? text : `${text}.`;
|
|
50880
51572
|
}
|
|
@@ -50891,7 +51583,15 @@ var S3TablesProvider = class {
|
|
|
50891
51583
|
return markRedactedCause(build(`${m(failure.summary)}${relayedNameCollision(failure.detail)}`));
|
|
50892
51584
|
}
|
|
50893
51585
|
handledProperties = /* @__PURE__ */ new Map([
|
|
50894
|
-
["AWS::S3Tables::TableBucket", /* @__PURE__ */ new Set([
|
|
51586
|
+
["AWS::S3Tables::TableBucket", /* @__PURE__ */ new Set([
|
|
51587
|
+
"TableBucketName",
|
|
51588
|
+
"Tags",
|
|
51589
|
+
"EncryptionConfiguration",
|
|
51590
|
+
"StorageClassConfiguration",
|
|
51591
|
+
"MetricsConfiguration",
|
|
51592
|
+
"UnreferencedFileRemoval",
|
|
51593
|
+
"ReplicationConfiguration"
|
|
51594
|
+
])],
|
|
50895
51595
|
["AWS::S3Tables::Namespace", /* @__PURE__ */ new Set(["TableBucketARN", "Namespace"])],
|
|
50896
51596
|
["AWS::S3Tables::Table", /* @__PURE__ */ new Set([
|
|
50897
51597
|
"TableBucketARN",
|
|
@@ -50900,9 +51600,24 @@ var S3TablesProvider = class {
|
|
|
50900
51600
|
"Name",
|
|
50901
51601
|
"OpenTableFormat",
|
|
50902
51602
|
"Format",
|
|
50903
|
-
"Tags"
|
|
51603
|
+
"Tags",
|
|
51604
|
+
"IcebergMetadata",
|
|
51605
|
+
"StorageClassConfiguration",
|
|
51606
|
+
"Compaction",
|
|
51607
|
+
"SnapshotManagement",
|
|
51608
|
+
"WithoutMetadata"
|
|
50904
51609
|
])]
|
|
50905
51610
|
]);
|
|
51611
|
+
getDriftUnknownPaths(resourceType) {
|
|
51612
|
+
return resourceType === "AWS::S3Tables::Table" ? [
|
|
51613
|
+
"IcebergMetadata",
|
|
51614
|
+
"StorageClassConfiguration",
|
|
51615
|
+
"WithoutMetadata"
|
|
51616
|
+
] : [];
|
|
51617
|
+
}
|
|
51618
|
+
getDriftAbsentMeansDefaultKeys(resourceType, properties) {
|
|
51619
|
+
return resourceType === "AWS::S3Tables::TableBucket" && properties["ReplicationConfiguration"] === void 0 ? ["ReplicationConfiguration"] : [];
|
|
51620
|
+
}
|
|
50906
51621
|
getClient() {
|
|
50907
51622
|
if (!this.client) {
|
|
50908
51623
|
this.client = new S3TablesClient({
|
|
@@ -50931,18 +51646,25 @@ var S3TablesProvider = class {
|
|
|
50931
51646
|
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
50932
51647
|
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
50933
51648
|
if (resourceType === "AWS::S3Tables::Table" || resourceType === "AWS::S3Tables::TableBucket") refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
51649
|
+
for (const key of UPDATABLE_CONFIG_KEYS[resourceType] ?? []) desiredObject(properties, key, resourceType, logicalId, physicalId);
|
|
51650
|
+
for (const [key, convert] of INTEGER_BEARING_CONFIGS[resourceType] ?? []) {
|
|
51651
|
+
const value = desiredObject(properties, key, resourceType, logicalId, physicalId);
|
|
51652
|
+
if (value !== void 0) refuseNonIntegers(() => convert(value), key, resourceType, logicalId, physicalId);
|
|
51653
|
+
}
|
|
51654
|
+
if (resourceType === "AWS::S3Tables::TableBucket") metricsEnabled(recordedObject(properties, "MetricsConfiguration"), resourceType, logicalId, physicalId);
|
|
50934
51655
|
try {
|
|
50935
|
-
return await this.applyUpdate(logicalId, physicalId, resourceType, properties, previousProperties, context?.maskSecrets, context?.recordedAttributes);
|
|
51656
|
+
return await this.applyUpdate(logicalId, physicalId, resourceType, properties, previousProperties, context?.maskSecrets, context?.recordedAttributes, (key) => context?.markUnsettled?.(key));
|
|
50936
51657
|
} catch (error) {
|
|
50937
51658
|
if (error instanceof CdkdError) throw error;
|
|
50938
51659
|
const cause = error instanceof Error ? error : void 0;
|
|
50939
51660
|
throw this.wrapCaughtError(context?.maskSecrets, error, (text) => new ProvisioningError(`Failed to update S3 Tables resource ${logicalId}: ${text}`, resourceType, logicalId, physicalId, cause));
|
|
50940
51661
|
}
|
|
50941
51662
|
}
|
|
50942
|
-
async applyUpdate(logicalId, physicalId, resourceType, properties, previousProperties, mask, recordedAttributes) {
|
|
51663
|
+
async applyUpdate(logicalId, physicalId, resourceType, properties, previousProperties, mask, recordedAttributes, markUnsettled) {
|
|
50943
51664
|
if (resourceType === "AWS::S3Tables::Table") {
|
|
50944
51665
|
const rename = await this.planTableRename(logicalId, physicalId, resourceType, properties, mask);
|
|
50945
51666
|
await this.applyTableTagsDiff(logicalId, physicalId, resourceType, previousProperties["Tags"], properties["Tags"], mask);
|
|
51667
|
+
await this.applyTableMaintenanceUpdate(logicalId, physicalId, resourceType, properties, previousProperties, markUnsettled);
|
|
50946
51668
|
if (rename === void 0) return {
|
|
50947
51669
|
physicalId,
|
|
50948
51670
|
wasReplaced: false
|
|
@@ -50957,8 +51679,10 @@ var S3TablesProvider = class {
|
|
|
50957
51679
|
physicalId: rename.physicalId,
|
|
50958
51680
|
wasReplaced: false
|
|
50959
51681
|
};
|
|
50960
|
-
} else if (resourceType === "AWS::S3Tables::TableBucket")
|
|
50961
|
-
|
|
51682
|
+
} else if (resourceType === "AWS::S3Tables::TableBucket") {
|
|
51683
|
+
await this.applyTableBucketTagsDiff(logicalId, physicalId, resourceType, previousProperties["Tags"], properties["Tags"], mask);
|
|
51684
|
+
await this.applyTableBucketConfigUpdate(logicalId, physicalId, resourceType, properties, previousProperties, markUnsettled);
|
|
51685
|
+
} else this.logger.debug(`Update is no-op for ${resourceType} ${logicalId}`);
|
|
50962
51686
|
return {
|
|
50963
51687
|
physicalId,
|
|
50964
51688
|
wasReplaced: false
|
|
@@ -50979,11 +51703,32 @@ var S3TablesProvider = class {
|
|
|
50979
51703
|
const tableBucketName = properties["TableBucketName"];
|
|
50980
51704
|
if (!tableBucketName) throw new ProvisioningError(`TableBucketName is required for S3 Table Bucket ${logicalId}`, resourceType, logicalId);
|
|
50981
51705
|
const tags = this.tagListToSdkMap(desiredTags);
|
|
51706
|
+
const encryption = desiredObject(properties, "EncryptionConfiguration", resourceType, logicalId);
|
|
51707
|
+
const storageClass = desiredObject(properties, "StorageClassConfiguration", resourceType, logicalId);
|
|
51708
|
+
const metricsOn = metricsEnabled(desiredObject(properties, "MetricsConfiguration", resourceType, logicalId), resourceType, logicalId);
|
|
51709
|
+
const unreferenced = desiredObject(properties, "UnreferencedFileRemoval", resourceType, logicalId);
|
|
51710
|
+
const replication = desiredObject(properties, "ReplicationConfiguration", resourceType, logicalId);
|
|
51711
|
+
const unreferencedValue = unreferenced && refuseNonIntegers(() => sdkUnreferencedFileRemoval(unreferenced), "UnreferencedFileRemoval", resourceType, logicalId);
|
|
51712
|
+
let createdArn;
|
|
50982
51713
|
try {
|
|
50983
51714
|
const tableBucketARN = (await this.getCreateClient().send(new CreateTableBucketCommand({
|
|
50984
51715
|
name: tableBucketName,
|
|
51716
|
+
...encryption !== void 0 && { encryptionConfiguration: sdkEncryption(encryption) },
|
|
51717
|
+
...storageClass !== void 0 && { storageClassConfiguration: sdkStorageClass(storageClass) },
|
|
50985
51718
|
...tags !== void 0 && { tags }
|
|
50986
51719
|
}))).arn;
|
|
51720
|
+
createdArn = tableBucketARN;
|
|
51721
|
+
reportCreatedResource(logicalId, resourceType, tableBucketARN);
|
|
51722
|
+
if (metricsOn) await this.getClient().send(new PutTableBucketMetricsConfigurationCommand({ tableBucketARN }));
|
|
51723
|
+
if (unreferencedValue !== void 0) await this.getClient().send(new PutTableBucketMaintenanceConfigurationCommand({
|
|
51724
|
+
tableBucketARN,
|
|
51725
|
+
type: "icebergUnreferencedFileRemoval",
|
|
51726
|
+
value: unreferencedValue
|
|
51727
|
+
}));
|
|
51728
|
+
if (replication !== void 0) await this.getClient().send(new PutTableBucketReplicationCommand({
|
|
51729
|
+
tableBucketARN,
|
|
51730
|
+
configuration: sdkReplication(replication)
|
|
51731
|
+
}));
|
|
50987
51732
|
this.logger.debug(`Successfully created S3 Table Bucket ${logicalId}: ${tableBucketARN}`);
|
|
50988
51733
|
return {
|
|
50989
51734
|
physicalId: tableBucketARN,
|
|
@@ -50991,7 +51736,104 @@ var S3TablesProvider = class {
|
|
|
50991
51736
|
};
|
|
50992
51737
|
} catch (error) {
|
|
50993
51738
|
const cause = error instanceof Error ? error : void 0;
|
|
50994
|
-
|
|
51739
|
+
const thrown = this.wrapCaughtError(context?.maskSecrets, error, (text) => new ProvisioningError(`Failed to create S3 Table Bucket ${logicalId}: ${text}`, resourceType, logicalId, void 0, cause));
|
|
51740
|
+
if (createdArn !== void 0) markCreatedBeforeFailure(thrown, logicalId, resourceType, createdArn);
|
|
51741
|
+
throw thrown;
|
|
51742
|
+
}
|
|
51743
|
+
}
|
|
51744
|
+
async applyTableBucketConfigUpdate(logicalId, tableBucketARN, resourceType, properties, previousProperties, markUnsettled) {
|
|
51745
|
+
const changed = (key) => {
|
|
51746
|
+
const next = desiredObject(properties, key, resourceType, logicalId, tableBucketARN);
|
|
51747
|
+
return [next, !isDeepStrictEqual(next, recordedObject(previousProperties, key))];
|
|
51748
|
+
};
|
|
51749
|
+
const client = this.getClient();
|
|
51750
|
+
const [encryption, encryptionChanged] = changed("EncryptionConfiguration");
|
|
51751
|
+
if (encryptionChanged) {
|
|
51752
|
+
if (encryption !== void 0) {
|
|
51753
|
+
markUnsettled("EncryptionConfiguration");
|
|
51754
|
+
await client.send(new PutTableBucketEncryptionCommand({
|
|
51755
|
+
tableBucketARN,
|
|
51756
|
+
encryptionConfiguration: sdkEncryption(encryption)
|
|
51757
|
+
}));
|
|
51758
|
+
} else this.warnRemovalKept(logicalId, "EncryptionConfiguration");
|
|
51759
|
+
}
|
|
51760
|
+
const [storageClass, storageClassChanged] = changed("StorageClassConfiguration");
|
|
51761
|
+
if (storageClassChanged) {
|
|
51762
|
+
if (storageClass !== void 0) {
|
|
51763
|
+
markUnsettled("StorageClassConfiguration");
|
|
51764
|
+
await client.send(new PutTableBucketStorageClassCommand({
|
|
51765
|
+
tableBucketARN,
|
|
51766
|
+
storageClassConfiguration: sdkStorageClass(storageClass)
|
|
51767
|
+
}));
|
|
51768
|
+
} else this.warnRemovalKept(logicalId, "StorageClassConfiguration");
|
|
51769
|
+
}
|
|
51770
|
+
const metricsOn = metricsEnabled(desiredObject(properties, "MetricsConfiguration", resourceType, logicalId, tableBucketARN), resourceType, logicalId);
|
|
51771
|
+
const metricsWasOn = recordedObject(previousProperties, "MetricsConfiguration")?.["Status"] === "Enabled";
|
|
51772
|
+
if (metricsOn && !metricsWasOn) {
|
|
51773
|
+
markUnsettled("MetricsConfiguration");
|
|
51774
|
+
await client.send(new PutTableBucketMetricsConfigurationCommand({ tableBucketARN }));
|
|
51775
|
+
} else if (!metricsOn && metricsWasOn) {
|
|
51776
|
+
markUnsettled("MetricsConfiguration");
|
|
51777
|
+
await this.deleteBucketConfig(tableBucketARN, new DeleteTableBucketMetricsConfigurationCommand({ tableBucketARN }));
|
|
51778
|
+
}
|
|
51779
|
+
const [unreferenced, unreferencedChanged] = changed("UnreferencedFileRemoval");
|
|
51780
|
+
if (unreferencedChanged) {
|
|
51781
|
+
if (unreferenced !== void 0) {
|
|
51782
|
+
markUnsettled("UnreferencedFileRemoval");
|
|
51783
|
+
await client.send(new PutTableBucketMaintenanceConfigurationCommand({
|
|
51784
|
+
tableBucketARN,
|
|
51785
|
+
type: "icebergUnreferencedFileRemoval",
|
|
51786
|
+
value: sdkUnreferencedFileRemoval(unreferenced)
|
|
51787
|
+
}));
|
|
51788
|
+
} else this.warnRemovalKept(logicalId, "UnreferencedFileRemoval");
|
|
51789
|
+
}
|
|
51790
|
+
const [replication, replicationChanged] = changed("ReplicationConfiguration");
|
|
51791
|
+
if (replicationChanged) {
|
|
51792
|
+
if (replication !== void 0) {
|
|
51793
|
+
markUnsettled("ReplicationConfiguration");
|
|
51794
|
+
await client.send(new PutTableBucketReplicationCommand({
|
|
51795
|
+
tableBucketARN,
|
|
51796
|
+
configuration: sdkReplication(replication)
|
|
51797
|
+
}));
|
|
51798
|
+
} else {
|
|
51799
|
+
markUnsettled("ReplicationConfiguration");
|
|
51800
|
+
await this.deleteBucketConfig(tableBucketARN, new DeleteTableBucketReplicationCommand({ tableBucketARN }));
|
|
51801
|
+
}
|
|
51802
|
+
}
|
|
51803
|
+
}
|
|
51804
|
+
async applyTableMaintenanceUpdate(logicalId, physicalId, resourceType, properties, previousProperties, markUnsettled) {
|
|
51805
|
+
const writes = [];
|
|
51806
|
+
for (const [key, type, toSdk] of TABLE_MAINTENANCE) {
|
|
51807
|
+
const next = desiredObject(properties, key, resourceType, logicalId, physicalId);
|
|
51808
|
+
if (isDeepStrictEqual(next, recordedObject(previousProperties, key))) continue;
|
|
51809
|
+
if (next === void 0) this.warnRemovalKept(logicalId, key);
|
|
51810
|
+
else writes.push({
|
|
51811
|
+
key,
|
|
51812
|
+
type,
|
|
51813
|
+
value: toSdk(next)
|
|
51814
|
+
});
|
|
51815
|
+
}
|
|
51816
|
+
if (writes.length === 0) return;
|
|
51817
|
+
const table = await this.resolveTableParts(physicalId);
|
|
51818
|
+
if (table === "not-found" || table === "unparseable") throw new ProvisioningError(table === "not-found" ? safeMsg`S3 Tables Table '${physicalId}' no longer exists (state is out of sync); ` + `refusing to record a maintenance configuration that was not applied` : compositeIdFormatMessage(S3_TABLES_TABLE_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
|
|
51819
|
+
for (const { key, type, value } of writes) {
|
|
51820
|
+
markUnsettled(key);
|
|
51821
|
+
await this.getClient().send(new PutTableMaintenanceConfigurationCommand({
|
|
51822
|
+
...table,
|
|
51823
|
+
type,
|
|
51824
|
+
value
|
|
51825
|
+
}));
|
|
51826
|
+
}
|
|
51827
|
+
}
|
|
51828
|
+
warnRemovalKept(logicalId, key) {
|
|
51829
|
+
this.logger.warn(safeMsg`${logicalId}: ${key} was removed from the template; cdkd leaves its current AWS value in ` + `place. Declare the value you want (e.g. its default) to change it.`);
|
|
51830
|
+
}
|
|
51831
|
+
async deleteBucketConfig(tableBucketARN, command) {
|
|
51832
|
+
try {
|
|
51833
|
+
await this.getClient().send(command);
|
|
51834
|
+
} catch (error) {
|
|
51835
|
+
if (!(error instanceof NotFoundException$7)) throw error;
|
|
51836
|
+
await this.getClient().send(new GetTableBucketCommand({ tableBucketARN }));
|
|
50995
51837
|
}
|
|
50996
51838
|
}
|
|
50997
51839
|
async deleteTableBucket(logicalId, physicalId, resourceType, context) {
|
|
@@ -51126,6 +51968,17 @@ var S3TablesProvider = class {
|
|
|
51126
51968
|
const format = properties["OpenTableFormat"] ?? properties["Format"];
|
|
51127
51969
|
if (!format) throw new ProvisioningError(`OpenTableFormat is required for S3 Tables Table ${logicalId}`, resourceType, logicalId);
|
|
51128
51970
|
const tags = this.tagListToSdkMap(desiredTags);
|
|
51971
|
+
const icebergCfn = desiredObject(properties, "IcebergMetadata", resourceType, logicalId);
|
|
51972
|
+
const iceberg = icebergCfn && refuseNonIntegers(() => sdkIcebergMetadata(icebergCfn), "IcebergMetadata", resourceType, logicalId);
|
|
51973
|
+
const storageClass = desiredObject(properties, "StorageClassConfiguration", resourceType, logicalId);
|
|
51974
|
+
const maintenance = [];
|
|
51975
|
+
for (const [key, type, toSdk] of TABLE_MAINTENANCE) {
|
|
51976
|
+
const value = desiredObject(properties, key, resourceType, logicalId);
|
|
51977
|
+
if (value !== void 0) maintenance.push({
|
|
51978
|
+
type,
|
|
51979
|
+
value: refuseNonIntegers(() => toSdk(value), key, resourceType, logicalId)
|
|
51980
|
+
});
|
|
51981
|
+
}
|
|
51129
51982
|
const physicalId = packCompositeId(resourceType, logicalId, [
|
|
51130
51983
|
{
|
|
51131
51984
|
name: "tableBucketARN",
|
|
@@ -51150,10 +52003,18 @@ var S3TablesProvider = class {
|
|
|
51150
52003
|
namespace,
|
|
51151
52004
|
name,
|
|
51152
52005
|
format,
|
|
52006
|
+
...iceberg !== void 0 && { metadata: { iceberg } },
|
|
52007
|
+
...storageClass !== void 0 && { storageClassConfiguration: sdkStorageClass(storageClass) },
|
|
51153
52008
|
...tags !== void 0 && { tags }
|
|
51154
52009
|
}));
|
|
51155
52010
|
tableCreated = true;
|
|
51156
52011
|
reportCreatedResource(logicalId, resourceType, physicalId);
|
|
52012
|
+
for (const write of maintenance) await this.getClient().send(new PutTableMaintenanceConfigurationCommand({
|
|
52013
|
+
tableBucketARN,
|
|
52014
|
+
namespace,
|
|
52015
|
+
name,
|
|
52016
|
+
...write
|
|
52017
|
+
}));
|
|
51157
52018
|
if (!response.tableARN) throw new ProvisioningError(`CreateTable did not return a tableARN for ${logicalId} (${physicalId}) — refusing to record an empty TableARN attribute`, resourceType, logicalId, physicalId);
|
|
51158
52019
|
const tableARN = response.tableARN;
|
|
51159
52020
|
this.logger.debug(`Successfully created S3 Tables Table ${logicalId}: ${physicalId}`);
|
|
@@ -51189,8 +52050,58 @@ var S3TablesProvider = class {
|
|
|
51189
52050
|
const result = {};
|
|
51190
52051
|
if (bucket.name !== void 0) result["TableBucketName"] = bucket.name;
|
|
51191
52052
|
result["Tags"] = await this.readTagsBestEffort(physicalId);
|
|
52053
|
+
Object.assign(result, await this.readTableBucketConfigs(physicalId));
|
|
51192
52054
|
return result;
|
|
51193
52055
|
}
|
|
52056
|
+
async readTableBucketConfigs(tableBucketARN, strict = false) {
|
|
52057
|
+
const client = this.getClient();
|
|
52058
|
+
const out = {};
|
|
52059
|
+
await this.readConfig(out, "EncryptionConfiguration", async () => {
|
|
52060
|
+
const e = (await client.send(new GetTableBucketEncryptionCommand({ tableBucketARN }))).encryptionConfiguration;
|
|
52061
|
+
return defined({
|
|
52062
|
+
SSEAlgorithm: e?.sseAlgorithm ?? "AES256",
|
|
52063
|
+
KMSKeyArn: e?.kmsKeyArn
|
|
52064
|
+
});
|
|
52065
|
+
}, { SSEAlgorithm: "AES256" }, strict);
|
|
52066
|
+
await this.readConfig(out, "StorageClassConfiguration", async () => {
|
|
52067
|
+
return { StorageClass: (await client.send(new GetTableBucketStorageClassCommand({ tableBucketARN }))).storageClassConfiguration?.storageClass ?? "STANDARD" };
|
|
52068
|
+
}, { StorageClass: "STANDARD" }, strict);
|
|
52069
|
+
await this.readConfig(out, "MetricsConfiguration", async () => {
|
|
52070
|
+
await client.send(new GetTableBucketMetricsConfigurationCommand({ tableBucketARN }));
|
|
52071
|
+
return { Status: "Enabled" };
|
|
52072
|
+
}, { Status: "Disabled" }, strict);
|
|
52073
|
+
await this.readConfig(out, "UnreferencedFileRemoval", async () => {
|
|
52074
|
+
const value = (await client.send(new GetTableBucketMaintenanceConfigurationCommand({ tableBucketARN }))).configuration?.icebergUnreferencedFileRemoval;
|
|
52075
|
+
const settings = value?.settings?.icebergUnreferencedFileRemoval;
|
|
52076
|
+
return defined({
|
|
52077
|
+
Status: cfnBucketStatus(value?.status) ?? "Enabled",
|
|
52078
|
+
UnreferencedDays: settings?.unreferencedDays,
|
|
52079
|
+
NoncurrentDays: settings?.nonCurrentDays
|
|
52080
|
+
});
|
|
52081
|
+
}, { Status: "Enabled" }, strict);
|
|
52082
|
+
await this.readConfig(out, "ReplicationConfiguration", async () => {
|
|
52083
|
+
const c = (await client.send(new GetTableBucketReplicationCommand({ tableBucketARN }))).configuration;
|
|
52084
|
+
if (c === void 0) return void 0;
|
|
52085
|
+
return defined({
|
|
52086
|
+
Role: c.role,
|
|
52087
|
+
Rules: (c.rules ?? []).map((rule) => ({ Destinations: (rule.destinations ?? []).map((d) => ({ DestinationTableBucketARN: d.destinationTableBucketARN })) }))
|
|
52088
|
+
});
|
|
52089
|
+
}, "absent", strict);
|
|
52090
|
+
return out;
|
|
52091
|
+
}
|
|
52092
|
+
async readConfig(out, key, read, notFound, strict = false) {
|
|
52093
|
+
try {
|
|
52094
|
+
const value = await read();
|
|
52095
|
+
if (value !== void 0) out[key] = value;
|
|
52096
|
+
} catch (err) {
|
|
52097
|
+
if (err instanceof NotFoundException$7) {
|
|
52098
|
+
if (notFound !== "absent") out[key] = notFound;
|
|
52099
|
+
return;
|
|
52100
|
+
}
|
|
52101
|
+
if (strict) throw err;
|
|
52102
|
+
this.logger.debug(safeMsg`readCurrentState: reading ${key} failed: ${describeAwsFailure(err).detail} — leaving it out`);
|
|
52103
|
+
}
|
|
52104
|
+
}
|
|
51194
52105
|
async readNamespaceCurrentState(physicalId) {
|
|
51195
52106
|
const [tableBucketARN, namespaceName] = physicalId.split("|");
|
|
51196
52107
|
if (!tableBucketARN || !namespaceName) return void 0;
|
|
@@ -51264,8 +52175,62 @@ var S3TablesProvider = class {
|
|
|
51264
52175
|
result["Format"] = resp.format;
|
|
51265
52176
|
}
|
|
51266
52177
|
result["Tags"] = resp.tableARN ? await this.readTagsBestEffort(resp.tableARN) : [];
|
|
52178
|
+
Object.assign(result, await this.readTableMaintenance(physicalId, {
|
|
52179
|
+
tableBucketARN,
|
|
52180
|
+
namespace,
|
|
52181
|
+
name
|
|
52182
|
+
}));
|
|
52183
|
+
return result;
|
|
52184
|
+
}
|
|
52185
|
+
async readTableMaintenance(physicalId, table, strict = false) {
|
|
52186
|
+
const result = {};
|
|
52187
|
+
let maintenance;
|
|
52188
|
+
let maintenanceRead = true;
|
|
52189
|
+
try {
|
|
52190
|
+
maintenance = (await this.getClient().send(new GetTableMaintenanceConfigurationCommand(table))).configuration;
|
|
52191
|
+
} catch (err) {
|
|
52192
|
+
maintenanceRead = err instanceof NotFoundException$7;
|
|
52193
|
+
if (!maintenanceRead) {
|
|
52194
|
+
if (strict) throw err;
|
|
52195
|
+
this.logger.debug(safeMsg`readCurrentState: reading the maintenance configuration of ${physicalId} failed: ` + safeMsg`${describeAwsFailure(err).detail} — leaving Compaction / SnapshotManagement out`);
|
|
52196
|
+
}
|
|
52197
|
+
}
|
|
52198
|
+
if (maintenanceRead) {
|
|
52199
|
+
const compaction = maintenance?.icebergCompaction;
|
|
52200
|
+
const compactionSettings = compaction?.settings && "icebergCompaction" in compaction.settings ? compaction.settings.icebergCompaction : void 0;
|
|
52201
|
+
result["Compaction"] = defined({
|
|
52202
|
+
Status: compaction?.status ?? "enabled",
|
|
52203
|
+
TargetFileSizeMB: compactionSettings?.targetFileSizeMB
|
|
52204
|
+
});
|
|
52205
|
+
const snapshots = maintenance?.icebergSnapshotManagement;
|
|
52206
|
+
const snapshotSettings = snapshots?.settings && "icebergSnapshotManagement" in snapshots.settings ? snapshots.settings.icebergSnapshotManagement : void 0;
|
|
52207
|
+
result["SnapshotManagement"] = defined({
|
|
52208
|
+
Status: snapshots?.status ?? "enabled",
|
|
52209
|
+
MinSnapshotsToKeep: snapshotSettings?.minSnapshotsToKeep,
|
|
52210
|
+
MaxSnapshotAgeHours: snapshotSettings?.maxSnapshotAgeHours
|
|
52211
|
+
});
|
|
52212
|
+
}
|
|
51267
52213
|
return result;
|
|
51268
52214
|
}
|
|
52215
|
+
async readUnsettled(physicalId, logicalId, resourceType, names) {
|
|
52216
|
+
let live;
|
|
52217
|
+
if (resourceType === "AWS::S3Tables::TableBucket") {
|
|
52218
|
+
try {
|
|
52219
|
+
await this.getClient().send(new GetTableBucketCommand({ tableBucketARN: physicalId }));
|
|
52220
|
+
} catch (err) {
|
|
52221
|
+
if (err instanceof NotFoundException$7) return RESOURCE_NOT_FOUND;
|
|
52222
|
+
throw err;
|
|
52223
|
+
}
|
|
52224
|
+
live = await this.readTableBucketConfigs(physicalId, true);
|
|
52225
|
+
} else if (resourceType === "AWS::S3Tables::Table") {
|
|
52226
|
+
const table = await this.resolveTableParts(physicalId);
|
|
52227
|
+
if (table === "not-found") return RESOURCE_NOT_FOUND;
|
|
52228
|
+
if (table === "unparseable") throw new ProvisioningError(compositeIdFormatMessage(S3_TABLES_TABLE_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
|
|
52229
|
+
if (await this.lookupTableArn(table.tableBucketARN, table.namespace, table.name) === null) return RESOURCE_NOT_FOUND;
|
|
52230
|
+
live = await this.readTableMaintenance(physicalId, table, true);
|
|
52231
|
+
} else return;
|
|
52232
|
+
return Object.fromEntries(Object.entries(live).filter(([key]) => names.has(key)));
|
|
52233
|
+
}
|
|
51269
52234
|
async import(input) {
|
|
51270
52235
|
switch (input.resourceType) {
|
|
51271
52236
|
case "AWS::S3Tables::TableBucket": return this.importTableBucket(input);
|
|
@@ -52713,4 +53678,4 @@ var ACMCertificateProvider = class {
|
|
|
52713
53678
|
|
|
52714
53679
|
//#endregion
|
|
52715
53680
|
export { ACMCertificateProvider, ASGProvider, AgentCoreBrowserProvider, AgentCoreCodeInterpreterProvider, AgentCoreEvaluatorProvider, AgentCoreRuntimeProvider, ApiGatewayProvider, ApiGatewayV2Provider, AppSyncProvider, BudgetsBudgetProvider, CloudFrontDistributionProvider, CloudFrontOACProvider, CloudFrontOAIProvider, CloudTrailProvider, CloudWatchAlarmProvider, CloudWatchAnomalyDetectorProvider, CodeBuildProvider, CodeCommitRepositoryProvider, CognitoUserPoolProvider, DLMLifecyclePolicyProvider, DocDBProvider, DocDBSubnetGroupProvider, DynamoDBGlobalTableProvider, DynamoDBTableProvider, EC2Provider, ECRProvider, ECSProvider, EFSProvider, ELBv2Provider, EMRClusterProvider, EMRInstanceFleetConfigProvider, EMRInstanceGroupConfigProvider, ElastiCacheProvider, EventBridgeBusProvider, EventBridgeRuleProvider, FSxFileSystemProvider, FirehoseProvider, GlueConnectionProvider, GlueCrawlerProvider, GlueJobProvider, GlueProvider, GlueSecurityConfigurationProvider, GlueTriggerProvider, GlueWorkflowProvider, IAMAccessKeyProvider, IAMInstanceProfileProvider, IAMManagedPolicyProvider, IAMPolicyProvider, IAMRoleProvider, IAMUserGroupProvider, KMSProvider, KinesisStreamConsumerProvider, KinesisStreamProvider, LambdaEventInvokeConfigProvider, LambdaEventSourceMappingProvider, LambdaFunctionProvider, LambdaLayerVersionProvider, LambdaMicrovmImageProvider, LambdaNetworkConnectorProvider, LambdaPermissionProvider, LambdaUrlProvider, LambdaWebFunctionEndpointProvider, LambdaWebFunctionRevisionProvider, LogsLogGroupProvider, NeptuneProvider, NestedStackProvider, PipesPipeProvider, RDSDBProxyEndpointProvider, RDSDBProxyProvider, RDSDBProxyTargetGroupProvider, RDSProvider, Route53Provider, S3BucketPolicyProvider, S3BucketProvider, S3DirectoryBucketProvider, S3TablesProvider, S3VectorsProvider, SNSSubscriptionProvider, SNSTopicPolicyProvider, SNSTopicProvider, SQSQueuePolicyProvider, SQSQueueProvider, SSMParameterProvider, SchedulerScheduleProvider, SecretsManagerSecretProvider, ServiceDiscoveryProvider, StepFunctionsProvider, WAFv2WebACLProvider, WaitConditionHandleProvider };
|
|
52716
|
-
//# sourceMappingURL=provider-classes-
|
|
53681
|
+
//# sourceMappingURL=provider-classes-Dz0pYmlJ.js.map
|