@go-to-k/cdkd 0.309.0 → 0.311.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{asg-provider-DQoKGfKH.js → asg-provider-CIg_guZ-.js} +5 -3
- package/dist/asg-provider-CIg_guZ-.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{iam-policy-targets-D94wh05t.js → created-resource-sink-DlzoIY-1.js} +51 -2
- package/dist/created-resource-sink-DlzoIY-1.js.map +1 -0
- package/dist/{db-instance-modify-retry-BUG7NMWS.js → db-instance-modify-retry-1y0kIPCO.js} +2 -2
- package/dist/{db-instance-modify-retry-BUG7NMWS.js.map → db-instance-modify-retry-1y0kIPCO.js.map} +1 -1
- package/dist/{deploy-engine-tQ0aqZMo.js → deploy-engine-BF5exXUb.js} +620 -114
- package/dist/deploy-engine-BF5exXUb.js.map +1 -0
- package/dist/{iam-role-provider-BI8Acvps.js → iam-role-provider-qvhlVnrn.js} +5 -3
- package/dist/iam-role-provider-qvhlVnrn.js.map +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/{neptune-provider-DmVmx69p.js → neptune-provider-D9ac71Ca.js} +6 -4
- package/dist/neptune-provider-D9ac71Ca.js.map +1 -0
- package/dist/{program-Bnt3Yt0k.js → program-DbnTHlwR.js} +27 -15
- package/dist/program-DbnTHlwR.js.map +1 -0
- package/dist/{provider-classes-DYke4HKr.js → provider-classes-DktsDsTf.js} +1277 -175
- package/dist/provider-classes-DktsDsTf.js.map +1 -0
- package/dist/{rds-provider-Qpf09VQv.js → rds-provider-0LUsn9Wl.js} +7 -4
- package/dist/rds-provider-0LUsn9Wl.js.map +1 -0
- package/dist/{version-9LVuCtBU.js → version-BA4rBBLp.js} +2 -2
- package/dist/{version-9LVuCtBU.js.map → version-BA4rBBLp.js.map} +1 -1
- package/package.json +8 -9
- package/dist/asg-provider-DQoKGfKH.js.map +0 -1
- package/dist/deploy-engine-tQ0aqZMo.js.map +0 -1
- package/dist/iam-policy-targets-D94wh05t.js.map +0 -1
- package/dist/iam-role-provider-BI8Acvps.js.map +0 -1
- package/dist/neptune-provider-DmVmx69p.js.map +0 -1
- package/dist/program-Bnt3Yt0k.js.map +0 -1
- package/dist/provider-classes-DYke4HKr.js.map +0 -1
- package/dist/rds-provider-Qpf09VQv.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 observeThenDisableProtection, A as RESOURCE_NOT_FOUND, An as ProvisioningError, Ar as wrapMaskedAwsError, At as isSecretDerivedValue, B as refusalTypeShown, Bt as isAuxiliaryFailure, C as ambiguousAttemptLead, Cr as isTransientServerError, Ct as logicalIdShown, D as replayedSendWindow, Dr as isThrottlingError, Dt as stateOrphanRecordRemedy, E as replayFollowedAmbiguousAttempt, Er as isMarkedNonRetryable, Et as segmentAfterAnchor, F as isPlainImportJson, H as resolveExplicitPhysicalId, Ht as markAuxiliaryFailure, I as isPlainImportValue, It as clearCreatedBeforeFailure, Jn as isInertUnquoted, K as deleteAfterProtectionFlipWithFinalSnapshot, Kn as commandHole, L as isQuotableImportValue, M as markNotGone, Mn as ResourceUpdateNotSupportedError, Mt as maskerOrIdentity, N as assertRegionMatch, Nt as withDerivedNameMasks, O as setBounded, Or as markNonRetryable, Ot as createMaskedLogSinks, P as VALUE_NOT_SHOWN, Q as logGroupProtectionSite, R as normalizeAwsTagsToCfn, S as RecentIdSet, Sr as isRetryableTransientError, St as compositeIdSkipResult, T as isInsideWindow, Tr as THROTTLING_ERROR_NAMES, Ut as markCreatedBeforeFailure, V as remedyLogicalId, W as ProtectionFlipRegistry, Wt as markSupersedesEarlierCreate, X as isTerminalDbWaitStatus, Yn as pasteableCommand, Z as isTerminalDeleteFailure, Zn as plainOrDescribed, _t as isInterruptedWaitError, a as retractCreatedResource, b as AMBIGUOUS_LATCH_TTL_MS, br as isExplicitDenyError, bt as compositeIdFormatMessage, c as SECRET_DERIVED_READ_LIVE, cn as withPasteableAwsProfile, ct as isAwsCliLiteral, d as readPrincipalLists, dn as clientDefaultsFor, dr as markReplayMayCollide, dt as renderDisableCommand, er as shellQuote, et as protectionFlipKey, fn as credentialFingerprint, fr as relayedNameCollision, ft as ElapsedBudgetRegistry, gr as explicitDenyPolicyKind, h as clearOnUpdateRemoval, hn as CdkdError, i as reportCreatedResource, in as injectiveKeyPrefix, it as userPoolProtectionSite, jt as maskDeep, k as withoutServerErrorRetries, kr as markRedactedCause, kt as createMaskedRetryLogger, l as holdsSecretDerivedEntry, ln as ambientClientDefaults, lt as pasteableAwsCommand, ot as UNNAMEABLE_ID_CLAUSE, p as recordedPrincipalsRepair, pn as AccountIdUnavailableError, q as deleteWithProtectionCompensation, qn as hasClauseBreak, rn as injectiveKey, st as WITHHELD_AWS_COMMAND, tr as withheldTargetClause, tt as rdsFamilyProtectionSite, u as onlySecretDerived, un as ambientCredentialConfig, ur as markNameCollision, ut as protectedReplacementAdvice, v as withRemovalDefaults, vt as startInterruptWatch, w as createAttemptKey, wt as packCompositeId, x as AmbiguousCreateLatch, xt as compositeIdSeparatorRefusal, yr as isAmbiguousOutcomeError, yt as canonicalizeRoute53QueryName, z as quotedRemedyLogicalId } from "./created-resource-sink-DlzoIY-1.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 { $s as coerceCfnBoolean, $t as isAccessDeniedError, A as DYNAMODB_DELETE_POLL_COST_MS, B as relayedIndexBusyDelete, Bc as snapshotPassProvenance, Bi as tagPlanWarning, Bn as redactedDeleteAddressSkip, C as planContributorInsightsOp, Ca as isUsableAttemptedName, Cs as refuseMalformedResourcesForDestroy, D as reverseMapTableContributorInsights, Dd as renderAssemblyPathEscape, E as reverseMapIndexContributorInsights, Ed as displayAssemblyPath, Ei as reserveStackCreateToken, F as resolveDynamoDbDeleteBudgetMs, Fa as s3BucketRegionalDomainName, Fi as DBPROXY_TAG_OPTIONS, Fn as getCurrentProducerRegions, Fr as replacedDeleteFailureVerdict, Fs as withheldAccountClause, G as readTtlSpec, H as isTtlAlreadyDisabled, Hi as stringifyIfAssigned, Ht as withNestedStackContext, I as DELETE_INDEX_WAIT_PROCEED_NOTE, Ia as s3BucketWebsiteUrl, Ii as planTagDiff, J as S3_AUTO_DELETE_OBJECTS_TAG, Ji as waitForLambdaFunctionActive, Js as WARM_THROUGHPUT_MEMBERS, K as sendTtlWaitingOutRateLimit, L as INDEX_SETTLE_POLL_INTERVAL_MS, Lc as markSameGenerationBag, Li as readTagList, Ln as REDACTED_DELETE_ADDRESS_SKIP_REASON, Ls as findSilentDropProperties, Lt as revertNestedChildFromJournal, M as compensateRemovedDeletionProtection, Ma as s3BucketArn, Mi as isRefusedByName, N as deleteBudgetKey, Na as s3BucketDomainName, Ni as markDeleteStarted, Nr as getStackRecords, O as stripIndexContributorInsights, Od as resolveAssemblyPath, Oi as acquireIdempotencyToken, Oo as accountArgs, P as resolveDynamoDbDeleteBudgetClock, Pa as s3BucketDualStackDomainName, Pi as DBPROXY_TAGS_WHAT, Pt as getNestedRevertRun, Q as markRefusedBeforeApplying, Qi as getCurrentResourceSecrets, Qs as toFiniteNumber, Qt as chunks, R as deleteTableWithIndexBusyRetry, Rc as redactForState, Ri as refuseMalformedDesiredTags, Rn as isRedactedRecordedValue, S as indexDeclaresContributorInsights, T as readContributorInsightsSpec, Td as describeFileReadFailure, U as isTtlRateLimited, Uc as hasMaskableValues, V as waitForIndexesSettled, Va as outputReferenceProvenanceOf, Vi as definedAttributes, Vt as getCurrentNestedStackContext, W as planTimeToLive, X as isTruthyCfnBoolean, Xs as isWarmThroughputDecrease, Y as hasCdkAutoDeleteTag, Ys as coerceWarmThroughput$1, Z as getPriorAttempts, Zs as toCfnInteger, _ as streamMemberRefusals, _a as isTerminationProtectionPropagationError, _c as canonicalLambdaFunctionName, _l as carriesSecretMask, _t as enclosingDeadlineRemainingMs, aa as onlySecretReferencesDiffer, ac as replayWarn, al as dynamicReferenceTokens, b as CONTRIBUTOR_INSIGHTS_KEY, ba as reEnableInstanceApiTermination, c as DynamoDBGlobalTableProvider, cc as requireConfigString, cd as decodeListingKey, ct as isAbsoluteAssetPath, d as declaredStreamPolicyMember, da as deleteSkipReason, dd as canonicalizeRegion, di as secretNamedAttributeNamesOf, ec as coerceCfnInteger, en as lookupEachName, f as declaredStreamTagsMember, fa as withIndeterminateGuard, fc as withRetry, fd as derivePartitionAndUrlSuffix, fl as recoverMaskedOutput, g as streamDeclaresTags, ga as ec2InstanceProtectionSite, gc as emrClusterInstancesReplaced, gt as enclosingDeadlineExpired, h as streamDeclaresPolicy, hc as ecsServiceLaunchTypeSetOrChanged, ia as slowCcOperationTimeoutMs, ic as readConfigString, iu as stringifyValue, j as beginDeleteWait, ja as isSettledInstanceState, jc as passedNoEchoParametersOf, jr as awaitInFlightSibling, k as DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS, l as STREAM_POLICY_KEY, lt as listNestedTemplateRows, lu as rewriteTemplateAssetReferences, m as reverseMapStreamPolicy, ma as markWaitAbandoned, ml as recordAttributeIdCopy, nc as configIntegerRefusal, oa as unchangedBehindSecretReference, oc as requireConfigArray, p as planStreamMemberOps, pa as isWaitAbandonedError, pc as blockDeviceMappingsDifferOnlyInDeleteOnTermination, pl as physicalNameCopiesOf, q as ECR_AUTO_DELETE_IMAGES_TAG, rc as configStringRefusal, rl as withoutPhysicalNameCopies, rs as refuseMalformedNestedChildOutputs, sc as requireConfigObject, so as getAccountInfo, st as findNestedTemplateTreeDefect, t as DeployEngine, tc as configBooleanRefusal, tn as withApiLimit, tu as timePhase, u as STREAM_TAGS_KEY, ut as renderNestedTemplateTreeDefect, v as streamPolicyMatchesDeclared, va as observeThenDisableInstanceApiTermination, vc as lambdaFunctionNameForMask, vo as parseWebACLArn, w as planIndexContributorInsightsOps, wi as earliestDefined, x as contributorInsightsRefusals, xo as passedParameterClassesOf, y as streamTagsMatchDeclared, ya as reDisableInstanceApiTermination, yc as sameLambdaFunctionAddress, z as maskedLogger, zc as recordReferenceProvenanceEntry, zi as tagMapAsList, zn as redactedDeleteAddressFields, zs as withoutSilentDropProperties } from "./deploy-engine-BF5exXUb.js";
|
|
6
|
+
import { n as collectInlinePolicyNamesManagedBySiblings, r as IamCreateClientCache, t as IAMRoleProvider } from "./iam-role-provider-qvhlVnrn.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-DbnTHlwR.js";
|
|
8
|
+
import { t as modifyDbInstanceWhenAvailable } from "./db-instance-modify-retry-1y0kIPCO.js";
|
|
9
|
+
import { RDSProvider } from "./rds-provider-0LUsn9Wl.js";
|
|
10
|
+
import { NeptuneProvider } from "./neptune-provider-D9ac71Ca.js";
|
|
11
|
+
import { ASGProvider } from "./asg-provider-CIg_guZ-.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";
|
|
@@ -57,7 +57,7 @@ import { AccessPointAlreadyExists, AccessPointNotFound, CreateAccessPointCommand
|
|
|
57
57
|
import { AssociateFileSystemAliasesCommand, CreateFileSystemCommand as CreateFileSystemCommand$1, CreateFileSystemFromBackupCommand, DeleteFileSystemCommand as DeleteFileSystemCommand$1, DescribeFileSystemAliasesCommand, DescribeFileSystemsCommand as DescribeFileSystemsCommand$1, DisassociateFileSystemAliasesCommand, FSxClient, FileSystemNotFound as FileSystemNotFound$1, TagResourceCommand as TagResourceCommand$24, UntagResourceCommand as UntagResourceCommand$25, UpdateFileSystemCommand as UpdateFileSystemCommand$1 } from "@aws-sdk/client-fsx";
|
|
58
58
|
import { AddInstanceFleetCommand, AddInstanceGroupsCommand, AddTagsCommand as AddTagsCommand$1, DescribeClusterCommand, EMRClient, InvalidRequestException, ListClustersCommand, ListInstanceFleetsCommand, ListInstanceGroupsCommand, ModifyClusterCommand, ModifyInstanceFleetCommand, ModifyInstanceGroupsCommand, PutAutoScalingPolicyCommand, PutAutoTerminationPolicyCommand, PutManagedScalingPolicyCommand, RemoveAutoScalingPolicyCommand, RemoveAutoTerminationPolicyCommand, RemoveManagedScalingPolicyCommand, RemoveTagsCommand as RemoveTagsCommand$1, RunJobFlowCommand, SetTerminationProtectionCommand, SetUnhealthyNodeReplacementCommand, SetVisibleToAllUsersCommand, TerminateJobFlowsCommand } from "@aws-sdk/client-emr";
|
|
59
59
|
import { CreateDeliveryStreamCommand, DeleteDeliveryStreamCommand, DescribeDeliveryStreamCommand, FirehoseClient, ListTagsForDeliveryStreamCommand, ResourceNotFoundException as ResourceNotFoundException$14, StartDeliveryStreamEncryptionCommand, StopDeliveryStreamEncryptionCommand, TagDeliveryStreamCommand, UntagDeliveryStreamCommand, UpdateDestinationCommand } from "@aws-sdk/client-firehose";
|
|
60
|
-
import { AddTagsCommand as AddTagsCommand$2, CloudTrailClient, CreateTrailCommand, DeleteTrailCommand, GetEventSelectorsCommand, GetInsightSelectorsCommand, GetTrailCommand, GetTrailStatusCommand, ListTagsCommand as ListTagsCommand$2, PutEventSelectorsCommand, PutInsightSelectorsCommand, RemoveTagsCommand as RemoveTagsCommand$2, StartLoggingCommand, StopLoggingCommand, TrailNotFoundException, UpdateTrailCommand } from "@aws-sdk/client-cloudtrail";
|
|
60
|
+
import { AddTagsCommand as AddTagsCommand$2, CloudTrailClient, CreateTrailCommand, DeleteTrailCommand, GetEventConfigurationCommand, GetEventSelectorsCommand, GetInsightSelectorsCommand, GetTrailCommand, GetTrailStatusCommand, ListTagsCommand as ListTagsCommand$2, PutEventConfigurationCommand, PutEventSelectorsCommand, PutInsightSelectorsCommand, RemoveTagsCommand as RemoveTagsCommand$2, StartLoggingCommand, StopLoggingCommand, TrailNotFoundException, UpdateTrailCommand } from "@aws-sdk/client-cloudtrail";
|
|
61
61
|
import { BatchGetProjectsCommand, CodeBuildClient, CreateProjectCommand, DeleteProjectCommand, ResourceNotFoundException as ResourceNotFoundException$15, UpdateProjectCommand, UpdateProjectVisibilityCommand } from "@aws-sdk/client-codebuild";
|
|
62
62
|
import { CodeCommitClient, CreateCommitCommand, CreateRepositoryCommand as CreateRepositoryCommand$1, DeleteRepositoryCommand as DeleteRepositoryCommand$1, GetRepositoryCommand, GetRepositoryTriggersCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$17, PutRepositoryTriggersCommand, RepositoryDoesNotExistException, TagResourceCommand as TagResourceCommand$25, UntagResourceCommand as UntagResourceCommand$26, UpdateRepositoryDescriptionCommand, UpdateRepositoryEncryptionKeyCommand, UpdateRepositoryNameCommand } from "@aws-sdk/client-codecommit";
|
|
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";
|
|
@@ -656,6 +656,7 @@ var IAMManagedPolicyProvider = class {
|
|
|
656
656
|
if (!policyArn) throw new ProvisioningError(`CreatePolicy succeeded but no Arn returned for ${logicalId}`, resourceType, logicalId, policyName);
|
|
657
657
|
leftBehindArn = policyArn;
|
|
658
658
|
createdPolicyIdentity = policyIdentityToken(response.Policy?.PolicyId);
|
|
659
|
+
reportCreatedResource(logicalId, resourceType, policyArn, createdPolicyIdentity);
|
|
659
660
|
log.debug(`Created IAM managed policy: ${v(policyArn)}`);
|
|
660
661
|
try {
|
|
661
662
|
await this.attachToPrincipals(policyArn, principals.lists.Groups, principals.lists.Roles, principals.lists.Users, log);
|
|
@@ -664,6 +665,7 @@ var IAMManagedPolicyProvider = class {
|
|
|
664
665
|
await this.detachAllPrincipals(policyArn);
|
|
665
666
|
await this.deleteAllNonDefaultVersions(policyArn);
|
|
666
667
|
await this.iamClient.send(new DeletePolicyCommand({ PolicyArn: policyArn }));
|
|
668
|
+
retractCreatedResource(logicalId, resourceType, policyArn);
|
|
667
669
|
leftBehindArn = void 0;
|
|
668
670
|
log.debug(`Cleaned up partially-created managed policy ${logicalId} (${v(policyArn)}) after attachment failure`);
|
|
669
671
|
} catch (cleanupError) {
|
|
@@ -1263,6 +1265,7 @@ var IAMInstanceProfileProvider = class {
|
|
|
1263
1265
|
}));
|
|
1264
1266
|
leftBehind = true;
|
|
1265
1267
|
createdProfileIdentity = instanceProfileIdentityToken(response.InstanceProfile?.InstanceProfileId);
|
|
1268
|
+
reportCreatedResource(logicalId, resourceType, instanceProfileName, createdProfileIdentity);
|
|
1266
1269
|
log.debug(`Created IAM instance profile: ${v(instanceProfileName)}`);
|
|
1267
1270
|
const attachedRoles = [];
|
|
1268
1271
|
try {
|
|
@@ -1285,6 +1288,7 @@ var IAMInstanceProfileProvider = class {
|
|
|
1285
1288
|
if (!(err instanceof NoSuchEntityException)) throw err;
|
|
1286
1289
|
}
|
|
1287
1290
|
await this.iamClient.send(new DeleteInstanceProfileCommand({ InstanceProfileName: instanceProfileName }));
|
|
1291
|
+
retractCreatedResource(logicalId, resourceType, instanceProfileName);
|
|
1288
1292
|
leftBehind = false;
|
|
1289
1293
|
log.debug(`Cleaned up partially-created IAM instance profile ${logicalId} (${v(instanceProfileName)}) after wiring failure`);
|
|
1290
1294
|
} catch (cleanupError) {
|
|
@@ -1534,12 +1538,14 @@ var IAMAccessKeyProvider = class {
|
|
|
1534
1538
|
const accessKeyId = response.AccessKey?.AccessKeyId;
|
|
1535
1539
|
const secretAccessKey = response.AccessKey?.SecretAccessKey;
|
|
1536
1540
|
leftBehindKeyId = accessKeyId;
|
|
1541
|
+
reportCreatedResource(logicalId, resourceType, accessKeyId ?? "");
|
|
1537
1542
|
if (!accessKeyId || !secretAccessKey) {
|
|
1538
1543
|
if (accessKeyId) try {
|
|
1539
1544
|
await this.iamClient.send(new DeleteAccessKeyCommand({
|
|
1540
1545
|
UserName: userName,
|
|
1541
1546
|
AccessKeyId: accessKeyId
|
|
1542
1547
|
}));
|
|
1548
|
+
retractCreatedResource(logicalId, resourceType, accessKeyId);
|
|
1543
1549
|
leftBehindKeyId = void 0;
|
|
1544
1550
|
} catch (cleanupError) {
|
|
1545
1551
|
const lead = `Failed to clean up IAM access key ${logicalId} (${v(accessKeyId)}) minted by a partial CreateAccessKey response`;
|
|
@@ -1559,6 +1565,7 @@ var IAMAccessKeyProvider = class {
|
|
|
1559
1565
|
UserName: userName,
|
|
1560
1566
|
AccessKeyId: accessKeyId
|
|
1561
1567
|
}));
|
|
1568
|
+
retractCreatedResource(logicalId, resourceType, accessKeyId);
|
|
1562
1569
|
leftBehindKeyId = void 0;
|
|
1563
1570
|
log.debug(`Cleaned up partially-created IAM access key ${logicalId} (${v(accessKeyId)}) after status wiring failure`);
|
|
1564
1571
|
} catch (cleanupError) {
|
|
@@ -1584,7 +1591,10 @@ var IAMAccessKeyProvider = class {
|
|
|
1584
1591
|
};
|
|
1585
1592
|
} catch (error) {
|
|
1586
1593
|
const reconciled = await this.deleteOrphanFromFailedAttempt(userName, logicalId, baseline, attemptStartMs, log);
|
|
1587
|
-
if (leftBehindKeyId !== void 0 && reconciled.has(leftBehindKeyId))
|
|
1594
|
+
if (leftBehindKeyId !== void 0 && reconciled.has(leftBehindKeyId)) {
|
|
1595
|
+
retractCreatedResource(logicalId, resourceType, leftBehindKeyId);
|
|
1596
|
+
leftBehindKeyId = void 0;
|
|
1597
|
+
}
|
|
1588
1598
|
const cause = error instanceof Error ? error : void 0;
|
|
1589
1599
|
const thrown = this.wrapMaskedError(log, error, (text) => new ProvisioningError(`Failed to create IAM access key ${logicalId}: ${text}`, resourceType, logicalId, void 0, cause));
|
|
1590
1600
|
if (leftBehindKeyId !== void 0) {
|
|
@@ -1935,6 +1945,7 @@ var IAMUserGroupProvider = class {
|
|
|
1935
1945
|
const response = await (await this.createClient.get()).send(new CreateUserCommand(createParams));
|
|
1936
1946
|
leftBehind = true;
|
|
1937
1947
|
createdUserIdentity = userOrGroupIdentityToken(response.User?.UserId);
|
|
1948
|
+
reportCreatedResource(logicalId, resourceType, userName, createdUserIdentity);
|
|
1938
1949
|
try {
|
|
1939
1950
|
const permissionsBoundary = properties["PermissionsBoundary"];
|
|
1940
1951
|
if (permissionsBoundary) {
|
|
@@ -1995,6 +2006,7 @@ var IAMUserGroupProvider = class {
|
|
|
1995
2006
|
if (!(err instanceof NoSuchEntityException)) throw err;
|
|
1996
2007
|
}
|
|
1997
2008
|
await this.iamClient.send(new DeleteUserCommand({ UserName: userName }));
|
|
2009
|
+
retractCreatedResource(logicalId, resourceType, userName);
|
|
1998
2010
|
leftBehind = false;
|
|
1999
2011
|
log.debug(`Cleaned up partially-created IAM user ${logicalId} (${v(userName)}) after wiring failure`);
|
|
2000
2012
|
} catch (cleanupError) {
|
|
@@ -2337,6 +2349,7 @@ var IAMUserGroupProvider = class {
|
|
|
2337
2349
|
const response = await (await this.createClient.get()).send(new CreateGroupCommand(createParams));
|
|
2338
2350
|
leftBehind = true;
|
|
2339
2351
|
createdGroupIdentity = userOrGroupIdentityToken(response.Group?.GroupId);
|
|
2352
|
+
reportCreatedResource(logicalId, resourceType, groupName, createdGroupIdentity);
|
|
2340
2353
|
try {
|
|
2341
2354
|
const managedPolicyArns = properties["ManagedPolicyArns"];
|
|
2342
2355
|
if (managedPolicyArns && Array.isArray(managedPolicyArns)) for (const policyArn of managedPolicyArns) {
|
|
@@ -2361,6 +2374,7 @@ var IAMUserGroupProvider = class {
|
|
|
2361
2374
|
await this.detachAllGroupPolicies(groupName, log);
|
|
2362
2375
|
await this.deleteAllGroupInlinePolicies(groupName, log);
|
|
2363
2376
|
await this.iamClient.send(new DeleteGroupCommand({ GroupName: groupName }));
|
|
2377
|
+
retractCreatedResource(logicalId, resourceType, groupName);
|
|
2364
2378
|
leftBehind = false;
|
|
2365
2379
|
log.debug(`Cleaned up partially-created IAM group ${logicalId} (${v(groupName)}) after wiring failure`);
|
|
2366
2380
|
} catch (cleanupError) {
|
|
@@ -4803,6 +4817,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
4803
4817
|
}
|
|
4804
4818
|
createdNewBucket = adoptedOwnLeftover || preflight.kind === "absent";
|
|
4805
4819
|
bucketLeftBehind = createdNewBucket;
|
|
4820
|
+
if (createdNewBucket) reportCreatedResource(logicalId, resourceType, bucketName);
|
|
4806
4821
|
if (createdNewBucket) windowSpent = true;
|
|
4807
4822
|
if (preflight.kind === "region" && preflight.region !== "us-east-1") this.refuseForeignRegionAdopt(logicalId, resourceType, bucketName, "us-east-1", preflight.region);
|
|
4808
4823
|
if (preflight.kind === "region" && !adoptedOwnLeftover) this.logger.warn(`S3 bucket ${this.shown(bucketName)} for ${displaySafe(logicalId)} (${resourceType}) already existed in ${preflight.region} and was ADOPTED, not created. In us-east-1 S3 answers a re-create of a bucket you already own with 200 OK and RESETS that bucket's access control lists, so any ACL previously set on ${this.shown(bucketName)} is now the default. cdkd will not delete this bucket if the rest of this create fails.`);
|
|
@@ -4832,6 +4847,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
4832
4847
|
if (createdNewBucket) try {
|
|
4833
4848
|
await this.s3Client.send(new DeleteBucketCommand({ Bucket: bucketName }));
|
|
4834
4849
|
bucketLeftBehind = false;
|
|
4850
|
+
retractCreatedResource(logicalId, resourceType, bucketName);
|
|
4835
4851
|
this.logger.debug(`Cleaned up partially-created S3 bucket ${displaySafe(logicalId)} (${this.shown(bucketName)}) after wiring failure`);
|
|
4836
4852
|
} catch (cleanupError) {
|
|
4837
4853
|
this.logger.debug(`DeleteBucket cleanup failed for S3 bucket ${displaySafe(logicalId)} (${this.shown(bucketName)}): ${describeAwsFailure(cleanupError).detail}`);
|
|
@@ -6263,7 +6279,7 @@ function normalizeStatement(statement) {
|
|
|
6263
6279
|
for (const key of PRINCIPAL_KEYS) if (Object.prototype.hasOwnProperty.call(out, key)) out[key] = normalizePrincipal(out[key]);
|
|
6264
6280
|
return out;
|
|
6265
6281
|
}
|
|
6266
|
-
function canonicalJson$
|
|
6282
|
+
function canonicalJson$3(value) {
|
|
6267
6283
|
const sortKeys = (v) => {
|
|
6268
6284
|
if (Array.isArray(v)) return v.map(sortKeys);
|
|
6269
6285
|
if (v !== null && typeof v === "object") {
|
|
@@ -6287,7 +6303,7 @@ function policyContentKey(document) {
|
|
|
6287
6303
|
if (Object.prototype.hasOwnProperty.call(doc, "Statement")) doc["Statement"] = (Array.isArray(doc["Statement"]) ? doc["Statement"] : [doc["Statement"]]).map(normalizeStatement);
|
|
6288
6304
|
value = doc;
|
|
6289
6305
|
}
|
|
6290
|
-
return canonicalJson$
|
|
6306
|
+
return canonicalJson$3(value);
|
|
6291
6307
|
}
|
|
6292
6308
|
|
|
6293
6309
|
//#endregion
|
|
@@ -6565,7 +6581,7 @@ function listedQueues(bag) {
|
|
|
6565
6581
|
function isListedQueueUrl(value) {
|
|
6566
6582
|
return isSqsQueueUrl(value) && !value.includes(",") && !value.includes("*");
|
|
6567
6583
|
}
|
|
6568
|
-
function canonicalJson$
|
|
6584
|
+
function canonicalJson$2(value) {
|
|
6569
6585
|
const sortKeys = (v) => {
|
|
6570
6586
|
if (Array.isArray(v)) return v.map(sortKeys);
|
|
6571
6587
|
if (v !== null && typeof v === "object") {
|
|
@@ -6580,14 +6596,14 @@ function canonicalJson$1(value) {
|
|
|
6580
6596
|
}
|
|
6581
6597
|
function canonicalPolicy$1(text) {
|
|
6582
6598
|
try {
|
|
6583
|
-
return canonicalJson$
|
|
6599
|
+
return canonicalJson$2(JSON.parse(text));
|
|
6584
6600
|
} catch {
|
|
6585
6601
|
return `raw:${text}`;
|
|
6586
6602
|
}
|
|
6587
6603
|
}
|
|
6588
6604
|
function policyReference(document) {
|
|
6589
6605
|
if (typeof document === "string" && document.length > 0) return canonicalPolicy$1(document);
|
|
6590
|
-
if (document !== null && typeof document === "object") return canonicalJson$
|
|
6606
|
+
if (document !== null && typeof document === "object") return canonicalJson$2(document);
|
|
6591
6607
|
}
|
|
6592
6608
|
function splitQueueUrls(physicalId) {
|
|
6593
6609
|
return physicalId.split(",").filter((url) => url.length > 0);
|
|
@@ -6683,7 +6699,8 @@ var SNSTopicProvider = class {
|
|
|
6683
6699
|
if (properties["MaximumMessageSize"] != null) topicAttributes["MaximumMessageSize"] = stringifyValue(properties["MaximumMessageSize"]);
|
|
6684
6700
|
let tags;
|
|
6685
6701
|
if (properties["Tags"] != null) tags = desiredTags;
|
|
6686
|
-
const
|
|
6702
|
+
const wiringDeclared = Boolean(properties["ArchivePolicy"]) || Boolean(properties["DataProtectionPolicy"]) || properties["DeliveryStatusLogging"] != null || Array.isArray(properties["Subscription"]);
|
|
6703
|
+
const heldBefore = wiringDeclared ? await this.topicHeldBefore(topicName) : "free";
|
|
6687
6704
|
const createParams = {
|
|
6688
6705
|
Name: topicName,
|
|
6689
6706
|
...Object.keys(topicAttributes).length > 0 && { Attributes: topicAttributes },
|
|
@@ -6691,6 +6708,7 @@ var SNSTopicProvider = class {
|
|
|
6691
6708
|
};
|
|
6692
6709
|
const topicArn = (await this.snsClient.send(new CreateTopicCommand(createParams))).TopicArn;
|
|
6693
6710
|
if (!topicArn) throw new Error("CreateTopic did not return TopicArn");
|
|
6711
|
+
if (wiringDeclared && heldBefore === "free") reportCreatedResource(logicalId, resourceType, topicArn);
|
|
6694
6712
|
try {
|
|
6695
6713
|
if (properties["ArchivePolicy"]) {
|
|
6696
6714
|
const archivePolicy = typeof properties["ArchivePolicy"] === "string" ? properties["ArchivePolicy"] : JSON.stringify(properties["ArchivePolicy"]);
|
|
@@ -6722,6 +6740,7 @@ var SNSTopicProvider = class {
|
|
|
6722
6740
|
if (heldBefore !== "free") warn(skippedCleanupText(heldBefore, `SNS topic ${logicalId} (${topicArn})`, pasteableAwsCommand(maskSecrets)`aws sns delete-topic --topic-arn ${topicArn}`.render()));
|
|
6723
6741
|
else try {
|
|
6724
6742
|
await this.snsClient.send(new DeleteTopicCommand({ TopicArn: topicArn }));
|
|
6743
|
+
retractCreatedResource(logicalId, resourceType, topicArn);
|
|
6725
6744
|
this.logger.debug(`Cleaned up partially-created SNS topic ${logicalId} (${topicArn}) after wiring failure`);
|
|
6726
6745
|
} catch (cleanupError) {
|
|
6727
6746
|
leftBehindArn = topicArn;
|
|
@@ -7609,7 +7628,7 @@ var SNSTopicPolicyProvider = class {
|
|
|
7609
7628
|
if (candidates.length === 0) return [];
|
|
7610
7629
|
let reference;
|
|
7611
7630
|
if (typeof document === "string" && document.length > 0) reference = canonicalPolicy(document);
|
|
7612
|
-
else if (document !== null && typeof document === "object") reference = canonicalJson(document);
|
|
7631
|
+
else if (document !== null && typeof document === "object") reference = canonicalJson$1(document);
|
|
7613
7632
|
if (reference === void 0) {
|
|
7614
7633
|
this.logger.warn(mask(safeMsg`The topics ${candidates.join(", ")} listed by ${logicalId} were not checked (no policy document recorded to compare with) and may still carry its policy.`));
|
|
7615
7634
|
return [];
|
|
@@ -7726,7 +7745,7 @@ function defaultTopicPolicy(topicArn) {
|
|
|
7726
7745
|
}]
|
|
7727
7746
|
});
|
|
7728
7747
|
}
|
|
7729
|
-
function canonicalJson(value) {
|
|
7748
|
+
function canonicalJson$1(value) {
|
|
7730
7749
|
const sortKeys = (v) => {
|
|
7731
7750
|
if (Array.isArray(v)) return v.map(sortKeys);
|
|
7732
7751
|
if (v !== null && typeof v === "object") {
|
|
@@ -7740,7 +7759,7 @@ function canonicalJson(value) {
|
|
|
7740
7759
|
}
|
|
7741
7760
|
function canonicalPolicy(text) {
|
|
7742
7761
|
try {
|
|
7743
|
-
return canonicalJson(JSON.parse(text));
|
|
7762
|
+
return canonicalJson$1(JSON.parse(text));
|
|
7744
7763
|
} catch {
|
|
7745
7764
|
return `raw:${text}`;
|
|
7746
7765
|
}
|
|
@@ -8059,6 +8078,7 @@ var LambdaFunctionProvider = class {
|
|
|
8059
8078
|
functionCreated = true;
|
|
8060
8079
|
createdFunctionName = response.FunctionName || functionName;
|
|
8061
8080
|
createdFunctionIdentity = functionIdentityToken(response.FunctionArn, response.LastModified);
|
|
8081
|
+
reportCreatedResource(logicalId, resourceType, createdFunctionName, createdFunctionIdentity);
|
|
8062
8082
|
const recursiveLoop = properties["RecursiveLoop"];
|
|
8063
8083
|
if (recursiveLoop !== void 0) await this.applyPostCreateConfig(() => this.lambdaClient.send(new PutFunctionRecursionConfigCommand({
|
|
8064
8084
|
FunctionName: functionName,
|
|
@@ -8093,6 +8113,7 @@ var LambdaFunctionProvider = class {
|
|
|
8093
8113
|
minDelay: 1,
|
|
8094
8114
|
maxDelay: 5
|
|
8095
8115
|
}, { FunctionName: functionName });
|
|
8116
|
+
reportCreatedResource(logicalId, resourceType, createdFunctionName);
|
|
8096
8117
|
await this.putRuntimeManagementConfig(functionName, runtimeManagementConfig);
|
|
8097
8118
|
createdFunctionIdentity = void 0;
|
|
8098
8119
|
}, {
|
|
@@ -8117,6 +8138,7 @@ var LambdaFunctionProvider = class {
|
|
|
8117
8138
|
const cause = error instanceof Error ? error : void 0;
|
|
8118
8139
|
const thrown = this.wrapMaskedError(log, error, (text) => new ProvisioningError(`Failed to create Lambda function ${logicalId}: ${text}`, resourceType, logicalId, functionName, cause ?? new Error(safeStringify(error))));
|
|
8119
8140
|
if (createdFunctionName !== void 0 && !postCreateCleanup.deleted) markCreatedBeforeFailure(thrown, logicalId, resourceType, createdFunctionName, createdFunctionIdentity);
|
|
8141
|
+
else if (createdFunctionName !== void 0) retractCreatedResource(logicalId, resourceType, createdFunctionName);
|
|
8120
8142
|
throw thrown;
|
|
8121
8143
|
}
|
|
8122
8144
|
}
|
|
@@ -10398,6 +10420,7 @@ var LambdaMicrovmImageProvider = class {
|
|
|
10398
10420
|
const imageArn = response.imageArn;
|
|
10399
10421
|
createdArn = imageArn;
|
|
10400
10422
|
if (!imageArn) throw new ProvisioningError(`CreateMicrovmImage succeeded but no imageArn returned for ${logicalId}`, resourceType, logicalId);
|
|
10423
|
+
reportCreatedResource(logicalId, resourceType, imageArn);
|
|
10401
10424
|
this.logger.debug(`Created MicroVM image ${logicalId}: ${imageArn} (state=${response.state})`);
|
|
10402
10425
|
const noWait = process.env["CDKD_NO_WAIT"] === "true";
|
|
10403
10426
|
let latest = {
|
|
@@ -10656,15 +10679,15 @@ function buildCommonImageInput(properties) {
|
|
|
10656
10679
|
return input;
|
|
10657
10680
|
}
|
|
10658
10681
|
function mapCodeArtifact(value) {
|
|
10659
|
-
if (!isRecord$
|
|
10682
|
+
if (!isRecord$2(value)) return void 0;
|
|
10660
10683
|
const uri = value["Uri"];
|
|
10661
10684
|
return typeof uri === "string" ? { uri } : void 0;
|
|
10662
10685
|
}
|
|
10663
10686
|
function mapLogging(value) {
|
|
10664
|
-
if (!isRecord$
|
|
10687
|
+
if (!isRecord$2(value)) return void 0;
|
|
10665
10688
|
if (value["Disabled"] === true) return { disabled: {} };
|
|
10666
10689
|
const cloudWatch = value["CloudWatch"];
|
|
10667
|
-
if (isRecord$
|
|
10690
|
+
if (isRecord$2(cloudWatch)) {
|
|
10668
10691
|
const cw = {};
|
|
10669
10692
|
if (typeof cloudWatch["LogGroup"] === "string") cw.logGroup = cloudWatch["LogGroup"];
|
|
10670
10693
|
if (typeof cloudWatch["LogStream"] === "string") cw.logStream = cloudWatch["LogStream"];
|
|
@@ -10673,32 +10696,32 @@ function mapLogging(value) {
|
|
|
10673
10696
|
}
|
|
10674
10697
|
function mapCpuConfigurations(value) {
|
|
10675
10698
|
if (!Array.isArray(value)) return void 0;
|
|
10676
|
-
return value.filter(isRecord$
|
|
10699
|
+
return value.filter(isRecord$2).map((c) => ({ architecture: c["Architecture"] }));
|
|
10677
10700
|
}
|
|
10678
10701
|
function mapResources(value) {
|
|
10679
10702
|
if (!Array.isArray(value)) return void 0;
|
|
10680
|
-
return value.filter(isRecord$
|
|
10703
|
+
return value.filter(isRecord$2).map((r) => Number(r["MinimumMemoryInMiB"])).filter((n) => Number.isFinite(n)).map((minimumMemoryInMiB) => ({ minimumMemoryInMiB }));
|
|
10681
10704
|
}
|
|
10682
10705
|
function mapHooks(value) {
|
|
10683
|
-
if (!isRecord$
|
|
10706
|
+
if (!isRecord$2(value)) return void 0;
|
|
10684
10707
|
return lowerFirstKeysDeep(value);
|
|
10685
10708
|
}
|
|
10686
10709
|
function mapKeyValueListToRecord(value) {
|
|
10687
10710
|
if (!Array.isArray(value)) return void 0;
|
|
10688
10711
|
const out = {};
|
|
10689
|
-
for (const entry of value) if (isRecord$
|
|
10712
|
+
for (const entry of value) if (isRecord$2(entry) && typeof entry["Key"] === "string") out[entry["Key"]] = typeof entry["Value"] === "string" ? entry["Value"] : "";
|
|
10690
10713
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
10691
10714
|
}
|
|
10692
10715
|
function lowerFirstKeysDeep(value) {
|
|
10693
10716
|
if (Array.isArray(value)) return value.map(lowerFirstKeysDeep);
|
|
10694
|
-
if (isRecord$
|
|
10717
|
+
if (isRecord$2(value)) {
|
|
10695
10718
|
const out = {};
|
|
10696
10719
|
for (const [k, v] of Object.entries(value)) out[k.charAt(0).toLowerCase() + k.slice(1)] = lowerFirstKeysDeep(v);
|
|
10697
10720
|
return out;
|
|
10698
10721
|
}
|
|
10699
10722
|
return value;
|
|
10700
10723
|
}
|
|
10701
|
-
function isRecord$
|
|
10724
|
+
function isRecord$2(value) {
|
|
10702
10725
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10703
10726
|
}
|
|
10704
10727
|
|
|
@@ -10784,7 +10807,10 @@ var LambdaWebFunctionRevisionProvider = class {
|
|
|
10784
10807
|
throw error;
|
|
10785
10808
|
}
|
|
10786
10809
|
createdArn = response.revisionArn;
|
|
10787
|
-
if (createdArn)
|
|
10810
|
+
if (createdArn) {
|
|
10811
|
+
revisionsCreatedByThisProcess.add(createdArn);
|
|
10812
|
+
reportCreatedResource(logicalId, resourceType, createdArn);
|
|
10813
|
+
}
|
|
10788
10814
|
const replayWindow = replayedSendWindow(response, attemptStartMs);
|
|
10789
10815
|
if (replayWindow !== void 0) await this.reportPossibleRevisionOrphans(logicalId, replayWindow, log, input.functionName);
|
|
10790
10816
|
if (!createdArn || !response.revisionId) throw new ProvisioningError(`CreateWebFunctionRevision succeeded but returned no revision ARN for ${logicalIdShown(logicalId)}`, resourceType, logicalId);
|
|
@@ -10798,6 +10824,7 @@ var LambdaWebFunctionRevisionProvider = class {
|
|
|
10798
10824
|
let leftBehindArn = createdArn;
|
|
10799
10825
|
if (leftBehindArn) try {
|
|
10800
10826
|
await this.delete(logicalId, leftBehindArn, resourceType, void 0, context?.maskSecrets ? { maskSecrets: context.maskSecrets } : void 0);
|
|
10827
|
+
retractCreatedResource(logicalId, resourceType, leftBehindArn);
|
|
10801
10828
|
leftBehindArn = void 0;
|
|
10802
10829
|
} catch (cleanupError) {
|
|
10803
10830
|
log.warn(safeMsg`Failed to delete partially-created Lambda web function revision ${logicalId}: ${describeAwsFailure(cleanupError).detail}. The failed deploy records it for \`cdkd rollback --revert-failed\`, or delete it by hand`);
|
|
@@ -11167,6 +11194,7 @@ var LambdaWebFunctionEndpointProvider = class {
|
|
|
11167
11194
|
try {
|
|
11168
11195
|
createdArn = (await this.client.send(new CreateWebFunctionEndpointCommand(input))).endpointArn;
|
|
11169
11196
|
if (!createdArn) throw new ProvisioningError(`CreateWebFunctionEndpoint succeeded but returned no endpoint ARN for ${logicalIdShown(logicalId)}`, resourceType, logicalId);
|
|
11197
|
+
reportCreatedResource(logicalId, resourceType, createdArn);
|
|
11170
11198
|
const settled = await this.waitForSettled(input.functionName, input.endpointName, logicalId, resourceType, "create", void 0, context?.maskSecrets);
|
|
11171
11199
|
return {
|
|
11172
11200
|
physicalId: createdArn,
|
|
@@ -11510,6 +11538,7 @@ var LambdaNetworkConnectorProvider = class {
|
|
|
11510
11538
|
try {
|
|
11511
11539
|
createdArn = (await this.client.send(new CreateNetworkConnectorCommand(input))).Arn;
|
|
11512
11540
|
if (!createdArn) throw new ProvisioningError(`CreateNetworkConnector succeeded but returned no ARN for ${logicalIdShown(logicalId)}`, resourceType, logicalId);
|
|
11541
|
+
reportCreatedResource(logicalId, resourceType, createdArn);
|
|
11513
11542
|
const settled = await this.waitForSettled(createdArn, logicalId, "create");
|
|
11514
11543
|
createToken.release();
|
|
11515
11544
|
return {
|
|
@@ -11739,6 +11768,58 @@ function versionOfArn(arn) {
|
|
|
11739
11768
|
return match ? Number(match[1]) : void 0;
|
|
11740
11769
|
}
|
|
11741
11770
|
|
|
11771
|
+
//#endregion
|
|
11772
|
+
//#region src/provisioning/delete-gone-wait.ts
|
|
11773
|
+
async function waitForGoneAfterDelete(opts) {
|
|
11774
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
11775
|
+
const now = opts.now ?? Date.now;
|
|
11776
|
+
const userTimeoutMs = resolvedResourceTimeoutMs(opts.resourceType);
|
|
11777
|
+
const maxWaitMs = userTimeoutMs === void 0 ? opts.maxWaitMs : Math.min(opts.maxWaitMs, userTimeoutMs / 2);
|
|
11778
|
+
const startedAt = now();
|
|
11779
|
+
const stopped = `${opts.what}: the delete was ACCEPTED by AWS, but cdkd stopped waiting for it to disappear`;
|
|
11780
|
+
const consequence = "AWS finishes the delete on its side; until it does, a create of the same name is refused with \"already exists\".";
|
|
11781
|
+
const watch = startInterruptWatch(`${opts.what} deletion wait`);
|
|
11782
|
+
try {
|
|
11783
|
+
let lastStatus;
|
|
11784
|
+
let sawNonFailedStatus = false;
|
|
11785
|
+
for (;;) {
|
|
11786
|
+
if (watch.isInterrupted()) {
|
|
11787
|
+
opts.logger.warn(safeMsg`${stopped} (interrupted). ${consequence}`);
|
|
11788
|
+
return;
|
|
11789
|
+
}
|
|
11790
|
+
try {
|
|
11791
|
+
const status = await opts.describe();
|
|
11792
|
+
if (status === void 0) {
|
|
11793
|
+
opts.logger.debug(safeMsg`${opts.what} is gone`);
|
|
11794
|
+
return;
|
|
11795
|
+
}
|
|
11796
|
+
const failure = opts.failedStatus?.(status);
|
|
11797
|
+
if (failure !== void 0) {
|
|
11798
|
+
if (sawNonFailedStatus || now() - startedAt >= opts.pollIntervalMs) throw markWaitAbandoned(failure);
|
|
11799
|
+
} else sawNonFailedStatus = true;
|
|
11800
|
+
lastStatus = status;
|
|
11801
|
+
opts.logger.debug(safeMsg`${opts.what} status: ${status}, waiting for it to disappear`);
|
|
11802
|
+
} catch (error) {
|
|
11803
|
+
if (isWaitAbandonedError(error)) throw error;
|
|
11804
|
+
if (!isThrottlingError(error) && !isTransientServerError(error)) {
|
|
11805
|
+
opts.logger.debug(safeMsg`${opts.what}: status read failed: ${describeAwsFailure(error).detail}`);
|
|
11806
|
+
opts.logger.warn(safeMsg`${stopped}: its status could not be read (${describeAwsFailure(error).summary}). ${consequence}`);
|
|
11807
|
+
return;
|
|
11808
|
+
}
|
|
11809
|
+
opts.logger.debug(safeMsg`${opts.what}: status read throttled or failed transiently, re-polling`);
|
|
11810
|
+
}
|
|
11811
|
+
const remainingMs = maxWaitMs - (now() - startedAt);
|
|
11812
|
+
if (remainingMs <= 0) {
|
|
11813
|
+
opts.logger.warn(safeMsg`${stopped} after ${Math.round(maxWaitMs / 1e3)}s` + safeMsg`${lastStatus !== void 0 ? ` (last status: ${lastStatus})` : ""}. ${consequence}`);
|
|
11814
|
+
return;
|
|
11815
|
+
}
|
|
11816
|
+
await sleep(Math.min(opts.pollIntervalMs, remainingMs));
|
|
11817
|
+
}
|
|
11818
|
+
} finally {
|
|
11819
|
+
watch.dispose();
|
|
11820
|
+
}
|
|
11821
|
+
}
|
|
11822
|
+
|
|
11742
11823
|
//#endregion
|
|
11743
11824
|
//#region src/provisioning/providers/dynamodb-table-provider.ts
|
|
11744
11825
|
function isTableName(id) {
|
|
@@ -12150,6 +12231,10 @@ const tableNameReleaseWait = {
|
|
|
12150
12231
|
maxPolls: 600,
|
|
12151
12232
|
intervalMs: INDEX_SETTLE_POLL_INTERVAL_MS
|
|
12152
12233
|
};
|
|
12234
|
+
const tableDeleteGoneWait = {
|
|
12235
|
+
maxWaitMs: 600 * DYNAMODB_DELETE_POLL_COST_MS,
|
|
12236
|
+
pollIntervalMs: INDEX_SETTLE_POLL_INTERVAL_MS
|
|
12237
|
+
};
|
|
12153
12238
|
var DynamoDBTableProvider = class {
|
|
12154
12239
|
dynamoDBClient;
|
|
12155
12240
|
createClient;
|
|
@@ -12280,6 +12365,7 @@ var DynamoDBTableProvider = class {
|
|
|
12280
12365
|
const createOut = await (await this.getCreateClient()).send(new CreateTableCommand(createParams));
|
|
12281
12366
|
tableCreated = true;
|
|
12282
12367
|
createdTableId = createOut?.TableDescription?.TableId;
|
|
12368
|
+
reportCreatedResource(logicalId, resourceType, tableName, createdTableId);
|
|
12283
12369
|
this.logger.debug(`CreateTable initiated for ${tableName}, waiting for ACTIVE status`);
|
|
12284
12370
|
const tableInfo = await timePhase("provider waits", "DynamoDB table: wait for ACTIVE", () => this.waitForTableActive(tableName), logicalId);
|
|
12285
12371
|
await this.applyPointInTimeRecovery(tableName, properties["PointInTimeRecoverySpecification"], void 0, maskSecrets);
|
|
@@ -12307,6 +12393,7 @@ var DynamoDBTableProvider = class {
|
|
|
12307
12393
|
if (tableCreated) {
|
|
12308
12394
|
try {
|
|
12309
12395
|
await this.dynamoDBClient.send(new DeleteTableCommand({ TableName: tableName }));
|
|
12396
|
+
retractCreatedResource(logicalId, resourceType, tableName);
|
|
12310
12397
|
debug(`Rolled back partially-created DynamoDB table ${tableName}`);
|
|
12311
12398
|
} catch (cleanupError) {
|
|
12312
12399
|
tableLeftBehind = true;
|
|
@@ -12370,7 +12457,10 @@ var DynamoDBTableProvider = class {
|
|
|
12370
12457
|
let latestStreamArn = table?.LatestStreamArn;
|
|
12371
12458
|
if (table?.TableArn) await this.applyTagDiff(table.TableArn, resourceType, logicalId, previousProperties["Tags"], properties["Tags"], {
|
|
12372
12459
|
forceUpsert: context?.unsettledProperties?.has("Tags") === true,
|
|
12373
|
-
beforeWrite: () => markUnsettled("Tags")
|
|
12460
|
+
beforeWrite: () => markUnsettled("Tags"),
|
|
12461
|
+
afterAdded: (keys) => {
|
|
12462
|
+
if (keys.length > 0) context?.markAttempted?.("Tags", keys);
|
|
12463
|
+
}
|
|
12374
12464
|
});
|
|
12375
12465
|
const normalizeTableClass = (v) => typeof v === "string" && v.length > 0 ? v : "STANDARD";
|
|
12376
12466
|
const tableClassChanged = normalizeTableClass(properties["TableClass"]) !== normalizeTableClass(previousProperties["TableClass"]);
|
|
@@ -12595,7 +12685,7 @@ var DynamoDBTableProvider = class {
|
|
|
12595
12685
|
if (context?.unsettledProperties?.has("GlobalSecondaryIndexes") === true && currentLiveIndexNames !== void 0) this.warnUndeclaredLiveIndexes(physicalId, currentLiveIndexNames, [previousProperties["GlobalSecondaryIndexes"], properties["GlobalSecondaryIndexes"]], maskSecrets);
|
|
12596
12686
|
if (JSON.stringify(properties["GlobalSecondaryIndexes"]) !== JSON.stringify(previousProperties["GlobalSecondaryIndexes"])) {
|
|
12597
12687
|
markUnsettled("GlobalSecondaryIndexes");
|
|
12598
|
-
await this.applyGsiUpdates(physicalId, resourceType, logicalId, previousProperties["GlobalSecondaryIndexes"], properties["GlobalSecondaryIndexes"], properties["AttributeDefinitions"], gsiHandledByBillingFlip, currentLiveIndexNames, currentLiveIndexByName, liveCapacityComparable, effectiveBillingMode === "PAY_PER_REQUEST", maskSecrets);
|
|
12688
|
+
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]));
|
|
12599
12689
|
}
|
|
12600
12690
|
if (JSON.stringify(properties["PointInTimeRecoverySpecification"]) !== JSON.stringify(previousProperties["PointInTimeRecoverySpecification"])) {
|
|
12601
12691
|
markUnsettled("PointInTimeRecoverySpecification");
|
|
@@ -12743,6 +12833,22 @@ var DynamoDBTableProvider = class {
|
|
|
12743
12833
|
},
|
|
12744
12834
|
sleepSeam: deleteTableRetryDelays
|
|
12745
12835
|
});
|
|
12836
|
+
const mask = maskerOrIdentity(context?.maskSecrets);
|
|
12837
|
+
await waitForGoneAfterDelete({
|
|
12838
|
+
what: mask(`DynamoDB table ${physicalId}`),
|
|
12839
|
+
resourceType,
|
|
12840
|
+
describe: async () => {
|
|
12841
|
+
try {
|
|
12842
|
+
return (await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: physicalId }))).Table?.TableStatus ?? "UNKNOWN";
|
|
12843
|
+
} catch (describeError) {
|
|
12844
|
+
if (describeError instanceof ResourceNotFoundException$1) return void 0;
|
|
12845
|
+
throw describeError;
|
|
12846
|
+
}
|
|
12847
|
+
},
|
|
12848
|
+
logger: loopLogger,
|
|
12849
|
+
pollIntervalMs: tableDeleteGoneWait.pollIntervalMs,
|
|
12850
|
+
maxWaitMs: Math.min(tableDeleteGoneWait.maxWaitMs, budget.remainingMs())
|
|
12851
|
+
});
|
|
12746
12852
|
this.logger.debug(`Successfully deleted DynamoDB table ${logicalId}`);
|
|
12747
12853
|
this.deleteBudgets.release(deleteBudgetKey(physicalId, context?.expectedRegion));
|
|
12748
12854
|
this.protectionFlips.release(deleteBudgetKey(physicalId, context?.expectedRegion));
|
|
@@ -12786,6 +12892,13 @@ var DynamoDBTableProvider = class {
|
|
|
12786
12892
|
ResourceArn: tableArn,
|
|
12787
12893
|
Tags: tagsToAdd
|
|
12788
12894
|
}));
|
|
12895
|
+
let recordedKeys;
|
|
12896
|
+
try {
|
|
12897
|
+
recordedKeys = /* @__PURE__ */ new Set([...planTagDiff(void 0, oldTagsRaw).set.keys()]);
|
|
12898
|
+
} catch {
|
|
12899
|
+
recordedKeys = void 0;
|
|
12900
|
+
}
|
|
12901
|
+
unsettled.afterAdded?.(tagsToAdd.map((t) => t.Key).filter((key) => recordedKeys !== void 0 && !recordedKeys.has(key)));
|
|
12789
12902
|
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on DynamoDB table ${tableArn}`);
|
|
12790
12903
|
}
|
|
12791
12904
|
}
|
|
@@ -13159,7 +13272,7 @@ var DynamoDBTableProvider = class {
|
|
|
13159
13272
|
}
|
|
13160
13273
|
throw new Error(`Table ${tableName} and its global secondary indexes did not reach ACTIVE within ${maxAttempts} seconds after UpdateTable`);
|
|
13161
13274
|
}
|
|
13162
|
-
async applyGsiUpdates(physicalId, resourceType, logicalId, previousGsis, desiredGsis, desiredAttributeDefinitions, handledByBillingFlip, liveIndexNames, liveIndexByName, liveCapacityComparable, onDemandCeilingsSendable, maskSecrets) {
|
|
13275
|
+
async applyGsiUpdates(physicalId, resourceType, logicalId, previousGsis, desiredGsis, desiredAttributeDefinitions, handledByBillingFlip, liveIndexNames, liveIndexByName, liveCapacityComparable, onDemandCeilingsSendable, maskSecrets, onCreated = () => void 0) {
|
|
13163
13276
|
const warn = (message) => this.logger.warn(maskSecrets(message));
|
|
13164
13277
|
const debug = (message) => this.logger.debug(maskSecrets(message));
|
|
13165
13278
|
const prev = previousGsis ?? [];
|
|
@@ -13234,7 +13347,7 @@ var DynamoDBTableProvider = class {
|
|
|
13234
13347
|
}
|
|
13235
13348
|
if (updateHasMember) ops.push({ Update: update });
|
|
13236
13349
|
}
|
|
13237
|
-
await this.runGsiOps(physicalId, ops, desiredAttributeDefinitions, maskSecrets);
|
|
13350
|
+
await this.runGsiOps(physicalId, ops, desiredAttributeDefinitions, maskSecrets, onCreated);
|
|
13238
13351
|
}
|
|
13239
13352
|
coerceWarmThroughputForSend(scope, value, maskSecrets) {
|
|
13240
13353
|
const warn = (message) => this.logger.warn(maskSecrets(message));
|
|
@@ -13398,7 +13511,7 @@ var DynamoDBTableProvider = class {
|
|
|
13398
13511
|
}
|
|
13399
13512
|
return sendable;
|
|
13400
13513
|
}
|
|
13401
|
-
async runGsiOps(physicalId, ops, desiredAttributeDefinitions, maskSecrets) {
|
|
13514
|
+
async runGsiOps(physicalId, ops, desiredAttributeDefinitions, maskSecrets, onCreated = () => void 0) {
|
|
13402
13515
|
const debug = (message) => this.logger.debug(maskSecrets(message));
|
|
13403
13516
|
for (const op of ops) {
|
|
13404
13517
|
const input = {
|
|
@@ -13407,6 +13520,7 @@ var DynamoDBTableProvider = class {
|
|
|
13407
13520
|
};
|
|
13408
13521
|
if (op.Create && desiredAttributeDefinitions) input.AttributeDefinitions = desiredAttributeDefinitions;
|
|
13409
13522
|
await this.dynamoDBClient.send(new UpdateTableCommand(input));
|
|
13523
|
+
if (op.Create?.IndexName !== void 0) onCreated(op.Create.IndexName);
|
|
13410
13524
|
await this.waitForTableAndIndexesActive(physicalId);
|
|
13411
13525
|
debug(`${op.Create ? "created" : op.Delete ? "deleted" : "updated"} ${this.indexScopeAt(op.Create?.IndexName ?? op.Delete?.IndexName ?? op.Update?.IndexName, physicalId, maskSecrets)}`);
|
|
13412
13526
|
}
|
|
@@ -13547,13 +13661,13 @@ var DynamoDBTableProvider = class {
|
|
|
13547
13661
|
aws
|
|
13548
13662
|
};
|
|
13549
13663
|
}
|
|
13550
|
-
async readUnsettled(physicalId, logicalId, resourceType, names, recordedProperties, desiredProperties) {
|
|
13664
|
+
async readUnsettled(physicalId, logicalId, resourceType, names, recordedProperties, desiredProperties, attemptedItems) {
|
|
13551
13665
|
const live = await this.readCurrentState(physicalId, logicalId, resourceType, recordedProperties);
|
|
13552
13666
|
if (typeof live !== "object" || live === null) return live;
|
|
13553
13667
|
const out = { ...live };
|
|
13554
13668
|
if (out["BillingMode"] === "PAY_PER_REQUEST") delete out["ProvisionedThroughput"];
|
|
13555
13669
|
if (names.has("GlobalSecondaryIndexes")) {
|
|
13556
|
-
out["GlobalSecondaryIndexes"] = projectIndexesOnto(out["GlobalSecondaryIndexes"], recordedProperties?.["GlobalSecondaryIndexes"], desiredProperties?.["GlobalSecondaryIndexes"]);
|
|
13670
|
+
out["GlobalSecondaryIndexes"] = projectIndexesOnto(out["GlobalSecondaryIndexes"], recordedProperties?.["GlobalSecondaryIndexes"], desiredProperties?.["GlobalSecondaryIndexes"], attemptedItems?.get("GlobalSecondaryIndexes"));
|
|
13557
13671
|
if (out["GlobalSecondaryIndexes"] === void 0) delete out["GlobalSecondaryIndexes"];
|
|
13558
13672
|
}
|
|
13559
13673
|
const strict = async (key, read) => {
|
|
@@ -13870,9 +13984,9 @@ var DynamoDBTableProvider = class {
|
|
|
13870
13984
|
function isTransientStreamReadFailure(err) {
|
|
13871
13985
|
return isThrottlingError(err) || isTransientServerError(err) || isAmbiguousOutcomeError(err) || err instanceof ResourceNotFoundException$1;
|
|
13872
13986
|
}
|
|
13873
|
-
function projectIndexesOnto(live, recorded, desired) {
|
|
13987
|
+
function projectIndexesOnto(live, recorded, desired, attempted = /* @__PURE__ */ new Set()) {
|
|
13874
13988
|
if (!Array.isArray(live)) return void 0;
|
|
13875
|
-
const named =
|
|
13989
|
+
const named = new Set([...attempted].filter(isUsableAttemptedName));
|
|
13876
13990
|
for (const list of [recorded, desired]) {
|
|
13877
13991
|
if (!Array.isArray(list)) continue;
|
|
13878
13992
|
for (const entry of list) {
|
|
@@ -13928,7 +14042,7 @@ var LogsLogGroupProvider = class {
|
|
|
13928
14042
|
"DeletionProtectionEnabled",
|
|
13929
14043
|
"BearerTokenAuthenticationEnabled"
|
|
13930
14044
|
])]]);
|
|
13931
|
-
unhandledByDesign = /* @__PURE__ */ new Map([["AWS::Logs::LogGroup", /* @__PURE__ */ new Map([["ResourcePolicyDocument", "
|
|
14045
|
+
unhandledByDesign = /* @__PURE__ */ new Map([["AWS::Logs::LogGroup", /* @__PURE__ */ new Map([["ResourcePolicyDocument", "not driven by this provider by decision (issue #1412): no CreateLogGroup / PutRetentionPolicy member carries it, and both policy lifecycles — the account-scoped AWS::Logs::ResourcePolicy type and the log-group-scoped logs:PutResourcePolicy (resourceArn + policyScope RESOURCE) — are ones this provider does not take on — routed via Cloud Control, whose handler applies it"]])]]);
|
|
13932
14046
|
constructor() {
|
|
13933
14047
|
const awsClients = getAwsClients();
|
|
13934
14048
|
this.logsClient = awsClients.cloudWatchLogs;
|
|
@@ -13991,6 +14105,7 @@ var LogsLogGroupProvider = class {
|
|
|
13991
14105
|
await this.logsClient.send(new CreateLogGroupCommand(createParams));
|
|
13992
14106
|
createdNewLogGroup = true;
|
|
13993
14107
|
leftBehind = true;
|
|
14108
|
+
reportCreatedResource(logicalId, resourceType, logGroupName);
|
|
13994
14109
|
} catch (createError) {
|
|
13995
14110
|
if (createError instanceof ResourceAlreadyExistsException) this.logger.debug(`Log group ${logGroupName} already exists, using existing`);
|
|
13996
14111
|
else throw createError;
|
|
@@ -14037,6 +14152,7 @@ var LogsLogGroupProvider = class {
|
|
|
14037
14152
|
if (createdNewLogGroup) try {
|
|
14038
14153
|
await this.logsClient.send(new DeleteLogGroupCommand({ logGroupName }));
|
|
14039
14154
|
leftBehind = false;
|
|
14155
|
+
retractCreatedResource(logicalId, resourceType, logGroupName);
|
|
14040
14156
|
this.logger.debug(`Cleaned up partially-created log group ${displaySafe(logicalId)} (${displaySafe(logGroupName)}) after wiring failure`);
|
|
14041
14157
|
} catch (cleanupError) {
|
|
14042
14158
|
const mask = maskerOrIdentity(context?.maskSecrets);
|
|
@@ -14387,6 +14503,29 @@ var LogsLogGroupProvider = class {
|
|
|
14387
14503
|
|
|
14388
14504
|
//#endregion
|
|
14389
14505
|
//#region src/provisioning/providers/cloudwatch-alarm-provider.ts
|
|
14506
|
+
function isDefaultEvaluationWindow(value) {
|
|
14507
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
14508
|
+
const keys = Object.keys(value);
|
|
14509
|
+
if (keys.length !== 1 || keys[0] !== "SlidingWindow") return false;
|
|
14510
|
+
const sliding = value["SlidingWindow"];
|
|
14511
|
+
return sliding !== null && typeof sliding === "object" && !Array.isArray(sliding) && Object.keys(sliding).length === 0;
|
|
14512
|
+
}
|
|
14513
|
+
const PROMQL_EXCLUDED_MEMBERS = [
|
|
14514
|
+
"Namespace",
|
|
14515
|
+
"MetricName",
|
|
14516
|
+
"Dimensions",
|
|
14517
|
+
"Period",
|
|
14518
|
+
"Unit",
|
|
14519
|
+
"Statistic",
|
|
14520
|
+
"ExtendedStatistic",
|
|
14521
|
+
"Metrics",
|
|
14522
|
+
"Threshold",
|
|
14523
|
+
"ComparisonOperator",
|
|
14524
|
+
"ThresholdMetricId",
|
|
14525
|
+
"EvaluationPeriods",
|
|
14526
|
+
"DatapointsToAlarm",
|
|
14527
|
+
"EvaluationWindow"
|
|
14528
|
+
];
|
|
14390
14529
|
function isAlarmWriteThrottle(error) {
|
|
14391
14530
|
return isThrottlingError(error) || error instanceof Error && error.message.includes("Rate exceeded");
|
|
14392
14531
|
}
|
|
@@ -14422,9 +14561,13 @@ var CloudWatchAlarmProvider = class {
|
|
|
14422
14561
|
"Tags",
|
|
14423
14562
|
"ExtendedStatistic",
|
|
14424
14563
|
"EvaluateLowSampleCountPercentile",
|
|
14425
|
-
"ThresholdMetricId"
|
|
14564
|
+
"ThresholdMetricId",
|
|
14565
|
+
"ActionConfiguration",
|
|
14566
|
+
"WarmUpConfiguration",
|
|
14567
|
+
"EvaluationWindow",
|
|
14568
|
+
"EvaluationCriteria",
|
|
14569
|
+
"EvaluationInterval"
|
|
14426
14570
|
])]]);
|
|
14427
|
-
unhandledByDesign = /* @__PURE__ */ new Map([["AWS::CloudWatch::Alarm", /* @__PURE__ */ new Map([["EvaluationCriteria", "Absent from both the SDK PutMetricAlarm input and the aws-cdk-lib CfnAlarm L1 (a newer CFn-schema-only property ahead of SDK/CDK support); no wire path to forward it and no CDK app can emit it."], ["EvaluationInterval", "Absent from both the SDK PutMetricAlarm input and the aws-cdk-lib CfnAlarm L1 (a newer CFn-schema-only property ahead of SDK/CDK support); no wire path to forward it and no CDK app can emit it."]])]]);
|
|
14428
14571
|
constructor() {
|
|
14429
14572
|
const awsClients = getAwsClients();
|
|
14430
14573
|
this.cloudWatchClient = awsClients.cloudWatch;
|
|
@@ -14573,7 +14716,12 @@ var CloudWatchAlarmProvider = class {
|
|
|
14573
14716
|
Unit: emptyToUndefined(properties["Unit"]),
|
|
14574
14717
|
ExtendedStatistic: emptyToUndefined(properties["ExtendedStatistic"]),
|
|
14575
14718
|
EvaluateLowSampleCountPercentile: emptyToUndefined(properties["EvaluateLowSampleCountPercentile"]),
|
|
14576
|
-
ThresholdMetricId: emptyToUndefined(properties["ThresholdMetricId"])
|
|
14719
|
+
ThresholdMetricId: emptyToUndefined(properties["ThresholdMetricId"]),
|
|
14720
|
+
ActionConfiguration: properties["ActionConfiguration"],
|
|
14721
|
+
WarmUpConfiguration: properties["WarmUpConfiguration"],
|
|
14722
|
+
EvaluationWindow: properties["EvaluationWindow"],
|
|
14723
|
+
EvaluationCriteria: properties["EvaluationCriteria"],
|
|
14724
|
+
EvaluationInterval: properties["EvaluationInterval"]
|
|
14577
14725
|
};
|
|
14578
14726
|
const metricsValue = properties["Metrics"];
|
|
14579
14727
|
if (Array.isArray(metricsValue) && metricsValue.length > 0) params["Metrics"] = metricsValue.map((m) => {
|
|
@@ -14605,6 +14753,7 @@ var CloudWatchAlarmProvider = class {
|
|
|
14605
14753
|
params["Period"] = properties["Period"];
|
|
14606
14754
|
params["Statistic"] = emptyToUndefined(properties["Statistic"]);
|
|
14607
14755
|
params["Dimensions"] = properties["Dimensions"];
|
|
14756
|
+
if (properties["EvaluationCriteria"] !== void 0 && Array.isArray(params["Dimensions"]) && params["Dimensions"].length === 0) delete params["Dimensions"];
|
|
14608
14757
|
}
|
|
14609
14758
|
return params;
|
|
14610
14759
|
}
|
|
@@ -14615,30 +14764,40 @@ var CloudWatchAlarmProvider = class {
|
|
|
14615
14764
|
}))).MetricAlarms?.[0];
|
|
14616
14765
|
if (!alarm) return RESOURCE_NOT_FOUND;
|
|
14617
14766
|
const result = {};
|
|
14767
|
+
const promql = alarm.EvaluationCriteria !== void 0;
|
|
14618
14768
|
if (alarm.AlarmName !== void 0) result["AlarmName"] = alarm.AlarmName;
|
|
14619
14769
|
result["AlarmDescription"] = alarm.AlarmDescription ?? "";
|
|
14620
|
-
|
|
14621
|
-
|
|
14622
|
-
|
|
14623
|
-
|
|
14624
|
-
|
|
14625
|
-
|
|
14626
|
-
|
|
14627
|
-
|
|
14770
|
+
if (!promql) {
|
|
14771
|
+
result["MetricName"] = alarm.MetricName ?? "";
|
|
14772
|
+
result["Namespace"] = alarm.Namespace ?? "";
|
|
14773
|
+
result["Statistic"] = alarm.Statistic ?? "";
|
|
14774
|
+
if (alarm.ComparisonOperator !== void 0) result["ComparisonOperator"] = alarm.ComparisonOperator;
|
|
14775
|
+
if (alarm.Threshold !== void 0) result["Threshold"] = alarm.Threshold;
|
|
14776
|
+
if (alarm.EvaluationPeriods !== void 0) result["EvaluationPeriods"] = alarm.EvaluationPeriods;
|
|
14777
|
+
if (alarm.Period !== void 0) result["Period"] = alarm.Period;
|
|
14778
|
+
if (alarm.DatapointsToAlarm !== void 0) result["DatapointsToAlarm"] = alarm.DatapointsToAlarm;
|
|
14779
|
+
}
|
|
14628
14780
|
result["ActionsEnabled"] = alarm.ActionsEnabled ?? true;
|
|
14629
14781
|
result["AlarmActions"] = alarm.AlarmActions ? [...alarm.AlarmActions] : [];
|
|
14630
14782
|
result["OKActions"] = alarm.OKActions ? [...alarm.OKActions] : [];
|
|
14631
14783
|
result["InsufficientDataActions"] = alarm.InsufficientDataActions ? [...alarm.InsufficientDataActions] : [];
|
|
14632
14784
|
result["TreatMissingData"] = alarm.TreatMissingData ?? "";
|
|
14633
|
-
|
|
14634
|
-
|
|
14635
|
-
|
|
14636
|
-
|
|
14637
|
-
|
|
14638
|
-
|
|
14639
|
-
|
|
14785
|
+
if (!promql) {
|
|
14786
|
+
result["Unit"] = alarm.Unit ?? "";
|
|
14787
|
+
result["Dimensions"] = (alarm.Dimensions ?? []).map((d) => ({
|
|
14788
|
+
...d.Name !== void 0 ? { Name: d.Name } : {},
|
|
14789
|
+
...d.Value !== void 0 ? { Value: d.Value } : {}
|
|
14790
|
+
}));
|
|
14791
|
+
result["Metrics"] = (alarm.Metrics ?? []).map((m) => m);
|
|
14792
|
+
}
|
|
14793
|
+
if (!promql && alarm.ExtendedStatistic !== void 0) result["ExtendedStatistic"] = alarm.ExtendedStatistic;
|
|
14640
14794
|
if (alarm.EvaluateLowSampleCountPercentile !== void 0) result["EvaluateLowSampleCountPercentile"] = alarm.EvaluateLowSampleCountPercentile;
|
|
14641
|
-
if (alarm.ThresholdMetricId !== void 0) result["ThresholdMetricId"] = alarm.ThresholdMetricId;
|
|
14795
|
+
if (!promql && alarm.ThresholdMetricId !== void 0) result["ThresholdMetricId"] = alarm.ThresholdMetricId;
|
|
14796
|
+
if (alarm.ActionConfiguration !== void 0) result["ActionConfiguration"] = alarm.ActionConfiguration;
|
|
14797
|
+
if (alarm.WarmUpConfiguration !== void 0) result["WarmUpConfiguration"] = alarm.WarmUpConfiguration;
|
|
14798
|
+
if (!promql && alarm.EvaluationWindow !== void 0 && !isDefaultEvaluationWindow(alarm.EvaluationWindow)) result["EvaluationWindow"] = alarm.EvaluationWindow;
|
|
14799
|
+
if (alarm.EvaluationCriteria !== void 0) result["EvaluationCriteria"] = alarm.EvaluationCriteria;
|
|
14800
|
+
if (promql && alarm.EvaluationInterval !== void 0) result["EvaluationInterval"] = alarm.EvaluationInterval;
|
|
14642
14801
|
if (alarm.AlarmArn) try {
|
|
14643
14802
|
const tagsResp = await this.cloudWatchClient.send(new ListTagsForResourceCommand$4({ ResourceARN: alarm.AlarmArn }));
|
|
14644
14803
|
result["Tags"] = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
@@ -14647,6 +14806,26 @@ var CloudWatchAlarmProvider = class {
|
|
|
14647
14806
|
}
|
|
14648
14807
|
return result;
|
|
14649
14808
|
}
|
|
14809
|
+
async canonicalizeDriftPair(resourceType, baseline, aws) {
|
|
14810
|
+
if (resourceType !== "AWS::CloudWatch::Alarm" || !isDefaultEvaluationWindow(baseline["EvaluationWindow"]) || aws["EvaluationWindow"] !== void 0) return {
|
|
14811
|
+
baseline,
|
|
14812
|
+
aws
|
|
14813
|
+
};
|
|
14814
|
+
const trimmed = { ...baseline };
|
|
14815
|
+
delete trimmed["EvaluationWindow"];
|
|
14816
|
+
return {
|
|
14817
|
+
baseline: trimmed,
|
|
14818
|
+
aws
|
|
14819
|
+
};
|
|
14820
|
+
}
|
|
14821
|
+
getDriftAbsentMeansDefaultKeys(resourceType, properties) {
|
|
14822
|
+
if (resourceType !== "AWS::CloudWatch::Alarm") return [];
|
|
14823
|
+
if (properties["EvaluationCriteria"] !== void 0) return [...PROMQL_EXCLUDED_MEMBERS].filter((key) => properties[key] === void 0);
|
|
14824
|
+
const keys = ["EvaluationCriteria", "EvaluationInterval"];
|
|
14825
|
+
const declared = properties["EvaluationWindow"];
|
|
14826
|
+
if (declared === void 0 || isDefaultEvaluationWindow(declared)) keys.push("EvaluationWindow");
|
|
14827
|
+
return keys;
|
|
14828
|
+
}
|
|
14650
14829
|
generatedCreateName(_resourceType, logicalId, properties) {
|
|
14651
14830
|
if (properties["AlarmName"]) return void 0;
|
|
14652
14831
|
return generatedNameFor("AWS::CloudWatch::Alarm", logicalId);
|
|
@@ -15721,6 +15900,7 @@ var EventBridgeRuleProvider = class {
|
|
|
15721
15900
|
if (properties["Tags"]) putRuleParams["Tags"] = desiredTags;
|
|
15722
15901
|
const ruleArn = (await this.eventBridgeClient.send(new PutRuleCommand(putRuleParams))).RuleArn;
|
|
15723
15902
|
this.logger.debug(`Created EventBridge rule: ${ruleName} (${ruleArn})`);
|
|
15903
|
+
if (heldBefore === "free") reportCreatedResource(logicalId, resourceType, ruleArn);
|
|
15724
15904
|
const eventBusName = properties["EventBusName"];
|
|
15725
15905
|
try {
|
|
15726
15906
|
if (targets && targets.length > 0) {
|
|
@@ -15750,6 +15930,7 @@ var EventBridgeRuleProvider = class {
|
|
|
15750
15930
|
Name: ruleName,
|
|
15751
15931
|
EventBusName: eventBusName
|
|
15752
15932
|
}));
|
|
15933
|
+
retractCreatedResource(logicalId, resourceType, ruleArn);
|
|
15753
15934
|
this.logger.debug(`Cleaned up partially-created EventBridge rule ${logicalId} (${ruleName}) after wiring failure`);
|
|
15754
15935
|
} catch (cleanupError) {
|
|
15755
15936
|
leftLiveArn = ruleArn;
|
|
@@ -16122,6 +16303,7 @@ var EventBridgeBusProvider = class {
|
|
|
16122
16303
|
if (properties["LogConfig"] !== void 0) createParams.LogConfig = properties["LogConfig"];
|
|
16123
16304
|
const response = await (await this.getCreateClient()).send(new CreateEventBusCommand(createParams));
|
|
16124
16305
|
busCreated = true;
|
|
16306
|
+
reportCreatedResource(logicalId, resourceType, name);
|
|
16125
16307
|
const policy = policyDocument(properties["Policy"]);
|
|
16126
16308
|
if (policy !== void 0) await this.eventBridgeClient.send(new PutPermissionCommand({
|
|
16127
16309
|
EventBusName: name,
|
|
@@ -17151,6 +17333,7 @@ var EC2Provider = class {
|
|
|
17151
17333
|
}
|
|
17152
17334
|
const vpcId = response.Vpc.VpcId;
|
|
17153
17335
|
ec2IdsCreatedByThisProcess.add(vpcId);
|
|
17336
|
+
reportCreatedResource(logicalId, resourceType, vpcId);
|
|
17154
17337
|
const vpcReplayWindow = replayedSendWindow(response, attemptStartMs);
|
|
17155
17338
|
if (vpcReplayWindow !== void 0) await this.reportPossibleOrphanVpcs(logicalId, cidrBlock, desiredTags, vpcReplayWindow, context);
|
|
17156
17339
|
let defaultSgId;
|
|
@@ -17179,6 +17362,7 @@ var EC2Provider = class {
|
|
|
17179
17362
|
} catch (innerError) {
|
|
17180
17363
|
try {
|
|
17181
17364
|
await this.ec2Client.send(new DeleteVpcCommand({ VpcId: vpcId }));
|
|
17365
|
+
retractCreatedResource(logicalId, resourceType, vpcId);
|
|
17182
17366
|
this.logger.debug(`Cleaned up partially-created VPC ${logicalId} (${vpcId}) after wiring failure`);
|
|
17183
17367
|
} catch (cleanupError) {
|
|
17184
17368
|
leftBehindId = vpcId;
|
|
@@ -17334,6 +17518,7 @@ var EC2Provider = class {
|
|
|
17334
17518
|
}
|
|
17335
17519
|
const subnetId = response.Subnet.SubnetId;
|
|
17336
17520
|
ec2IdsCreatedByThisProcess.add(subnetId);
|
|
17521
|
+
reportCreatedResource(logicalId, resourceType, subnetId);
|
|
17337
17522
|
const subnetReplayWindow = replayedSendWindow(response, attemptStartMs);
|
|
17338
17523
|
if (subnetReplayWindow !== void 0) await this.reportPossibleOrphanSubnets(logicalId, vpcId, cidrBlock, desiredTags, subnetReplayWindow, context);
|
|
17339
17524
|
const availabilityZone = response.Subnet.AvailabilityZone;
|
|
@@ -17350,6 +17535,7 @@ var EC2Provider = class {
|
|
|
17350
17535
|
} catch (innerError) {
|
|
17351
17536
|
try {
|
|
17352
17537
|
await this.ec2Client.send(new DeleteSubnetCommand({ SubnetId: subnetId }));
|
|
17538
|
+
retractCreatedResource(logicalId, resourceType, subnetId);
|
|
17353
17539
|
this.logger.debug(`Cleaned up partially-created Subnet ${logicalId} (${subnetId}) after wiring failure`);
|
|
17354
17540
|
} catch (cleanupError) {
|
|
17355
17541
|
leftBehindId = subnetId;
|
|
@@ -17604,6 +17790,7 @@ var EC2Provider = class {
|
|
|
17604
17790
|
} catch {
|
|
17605
17791
|
createdId = allocationId;
|
|
17606
17792
|
}
|
|
17793
|
+
reportCreatedResource(logicalId, resourceType, createdId);
|
|
17607
17794
|
ec2IdsCreatedByThisProcess.add(allocationId);
|
|
17608
17795
|
const eipReplayWindow = replayedSendWindow(response, attemptStartMs);
|
|
17609
17796
|
if (eipReplayWindow !== void 0) await this.reportPossibleOrphanAddresses(logicalId, input, desiredTags, eipReplayWindow, context);
|
|
@@ -17636,6 +17823,7 @@ var EC2Provider = class {
|
|
|
17636
17823
|
} finally {
|
|
17637
17824
|
watch.dispose();
|
|
17638
17825
|
}
|
|
17826
|
+
retractCreatedResource(logicalId, resourceType, createdId);
|
|
17639
17827
|
createdId = void 0;
|
|
17640
17828
|
this.logger.debug(safeMsg`Released partially-created EIP ${logicalId} (${allocatedId})`);
|
|
17641
17829
|
} catch (cleanupError) {
|
|
@@ -17772,6 +17960,7 @@ var EC2Provider = class {
|
|
|
17772
17960
|
VpnGatewayId: gatewayId
|
|
17773
17961
|
}));
|
|
17774
17962
|
attachSent = true;
|
|
17963
|
+
reportCreatedResource(logicalId, resourceType, physicalId);
|
|
17775
17964
|
await this.waitForVpnGatewayAttachment(gatewayId, vpcId, "attached", logicalId);
|
|
17776
17965
|
}
|
|
17777
17966
|
this.logger.debug(`Successfully created VPCGatewayAttachment ${logicalId}: ${physicalId}`);
|
|
@@ -18068,6 +18257,7 @@ var EC2Provider = class {
|
|
|
18068
18257
|
})));
|
|
18069
18258
|
const natGatewayId = response.NatGateway.NatGatewayId;
|
|
18070
18259
|
createdId = natGatewayId;
|
|
18260
|
+
reportCreatedResource(logicalId, resourceType, natGatewayId);
|
|
18071
18261
|
if (!tagsApplied) await this.applyTags(natGatewayId, desiredTags, logicalId, maskerOrIdentity(context?.maskSecrets));
|
|
18072
18262
|
let described;
|
|
18073
18263
|
if (process.env["CDKD_NO_WAIT"] !== "true") {
|
|
@@ -18465,6 +18655,7 @@ var EC2Provider = class {
|
|
|
18465
18655
|
...TagSpecifications && { TagSpecifications }
|
|
18466
18656
|
})));
|
|
18467
18657
|
const groupId = response.GroupId;
|
|
18658
|
+
reportCreatedResource(logicalId, resourceType, groupId);
|
|
18468
18659
|
try {
|
|
18469
18660
|
const ingressRules = properties["SecurityGroupIngress"];
|
|
18470
18661
|
const egressRules = properties["SecurityGroupEgress"];
|
|
@@ -18481,6 +18672,7 @@ var EC2Provider = class {
|
|
|
18481
18672
|
} catch (innerError) {
|
|
18482
18673
|
try {
|
|
18483
18674
|
await this.ec2Client.send(new DeleteSecurityGroupCommand({ GroupId: groupId }));
|
|
18675
|
+
retractCreatedResource(logicalId, resourceType, groupId);
|
|
18484
18676
|
this.logger.debug(`Cleaned up partially-created SecurityGroup ${logicalId} (${groupId}) after wiring failure`);
|
|
18485
18677
|
} catch (cleanupError) {
|
|
18486
18678
|
leftBehindId = groupId;
|
|
@@ -19027,6 +19219,7 @@ var EC2Provider = class {
|
|
|
19027
19219
|
const instance = response.Instances?.[0];
|
|
19028
19220
|
if (!instance?.InstanceId) throw new Error("No instance ID returned from RunInstances");
|
|
19029
19221
|
const instanceId = instance.InstanceId;
|
|
19222
|
+
reportCreatedResource(logicalId, resourceType, instanceId);
|
|
19030
19223
|
try {
|
|
19031
19224
|
if (!tagsApplied) await this.applyTags(instanceId, desiredTags, logicalId, maskerOrIdentity(context?.maskSecrets));
|
|
19032
19225
|
if (process.env["CDKD_NO_WAIT"] !== "true") {
|
|
@@ -19056,6 +19249,7 @@ var EC2Provider = class {
|
|
|
19056
19249
|
} catch (innerError) {
|
|
19057
19250
|
try {
|
|
19058
19251
|
await this.ec2Client.send(new TerminateInstancesCommand({ InstanceIds: [instanceId] }));
|
|
19252
|
+
retractCreatedResource(logicalId, resourceType, instanceId);
|
|
19059
19253
|
runInstancesToken.release();
|
|
19060
19254
|
this.logger.debug(`Terminate requested for partially-created EC2 Instance ${logicalId} (${instanceId}) after wiring failure (not waiting for terminated state)`);
|
|
19061
19255
|
} catch (cleanupError) {
|
|
@@ -21655,6 +21849,7 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
21655
21849
|
documentationVersion: properties["DocumentationVersion"],
|
|
21656
21850
|
canarySettings: toSdkCanarySettings(properties["CanarySetting"])
|
|
21657
21851
|
}));
|
|
21852
|
+
reportCreatedResource(logicalId, resourceType, stageName);
|
|
21658
21853
|
const methodSettings = properties["MethodSettings"];
|
|
21659
21854
|
const postCreateOps = buildMethodSettingsPatchOps(void 0, methodSettings);
|
|
21660
21855
|
const accessLogSetting = properties["AccessLogSetting"];
|
|
@@ -21688,6 +21883,7 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
21688
21883
|
restApiId,
|
|
21689
21884
|
stageName
|
|
21690
21885
|
}));
|
|
21886
|
+
retractCreatedResource(logicalId, resourceType, stageName);
|
|
21691
21887
|
} catch (cleanupError) {
|
|
21692
21888
|
stageLeftBehind = true;
|
|
21693
21889
|
const cleanupFailure = describeAwsFailure(cleanupError);
|
|
@@ -21945,6 +22141,7 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
21945
22141
|
}
|
|
21946
22142
|
await putMethod();
|
|
21947
22143
|
}
|
|
22144
|
+
reportCreatedResource(logicalId, resourceType, physicalId);
|
|
21948
22145
|
try {
|
|
21949
22146
|
const integration = properties["Integration"];
|
|
21950
22147
|
if (integration) await this.apiGatewayClient.send(new PutIntegrationCommand(putIntegrationInput({
|
|
@@ -21973,6 +22170,7 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
21973
22170
|
resourceId,
|
|
21974
22171
|
httpMethod
|
|
21975
22172
|
}));
|
|
22173
|
+
retractCreatedResource(logicalId, resourceType, physicalId);
|
|
21976
22174
|
log.debug(`Cleaned up partially-created API Gateway Method ${logicalId} (${methodPath}) after wiring failure`);
|
|
21977
22175
|
} catch (cleanupError) {
|
|
21978
22176
|
methodLeftBehind = true;
|
|
@@ -25099,14 +25297,57 @@ function camelToPascalCaseKeys(value, preserveKeys) {
|
|
|
25099
25297
|
//#region src/provisioning/providers/agentcore-runtime-provider.ts
|
|
25100
25298
|
const CFN_MAP_KEYS = /* @__PURE__ */ new Set(["Tags", "AdvertisedScopeMapping"]);
|
|
25101
25299
|
const SDK_MAP_KEYS = /* @__PURE__ */ new Set(["tags", "advertisedScopeMapping"]);
|
|
25300
|
+
const RUNTIME_TAGS_WHAT = "a map of tag keys to scalar values or a list of tags with a non-empty string Key and a scalar Value";
|
|
25301
|
+
function isUserTagKey(key) {
|
|
25302
|
+
return !key.startsWith("aws:");
|
|
25303
|
+
}
|
|
25304
|
+
function desiredRuntimeTags(raw, resourceType, logicalId, physicalId) {
|
|
25305
|
+
const tags = refuseMalformedDesiredTags(tagMapAsList(raw), resourceType, logicalId, physicalId, "Tags", RUNTIME_TAGS_WHAT);
|
|
25306
|
+
if (!tags.every((t) => isUserTagKey(t.Key))) throw markNonRetryable(new ProvisioningError(`${physicalId !== void 0 ? "desired " : ""}Tags of ${resourceType} ${logicalId} holds a reserved aws: key, which AWS does not let a user set — the resource was not ${physicalId !== void 0 ? "updated" : "created"}`, resourceType, logicalId, physicalId));
|
|
25307
|
+
return tags;
|
|
25308
|
+
}
|
|
25309
|
+
const CREATE_TAG_RETRY_DELAYS_MS = [
|
|
25310
|
+
500,
|
|
25311
|
+
1e3,
|
|
25312
|
+
2e3,
|
|
25313
|
+
4e3
|
|
25314
|
+
];
|
|
25315
|
+
function isTransientTagFailure(error) {
|
|
25316
|
+
return isThrottlingError(error) || error instanceof ResourceNotFoundException$6 || error instanceof Error && error.name === "ResourceNotFoundException";
|
|
25317
|
+
}
|
|
25318
|
+
function isNonEmptyObject(value) {
|
|
25319
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length > 0;
|
|
25320
|
+
}
|
|
25321
|
+
function writeSharedRuntimeMembers(input, properties) {
|
|
25322
|
+
const requestHeaders = properties["RequestHeaderConfiguration"];
|
|
25323
|
+
if (isNonEmptyObject(requestHeaders)) input["requestHeaderConfiguration"] = pascalToCamelCaseKeys(requestHeaders, CFN_MAP_KEYS);
|
|
25324
|
+
const filesystems = properties["FilesystemConfigurations"];
|
|
25325
|
+
if (Array.isArray(filesystems) && filesystems.length > 0) input["filesystemConfigurations"] = pascalToCamelCaseKeys(filesystems, CFN_MAP_KEYS);
|
|
25326
|
+
const capacityProvider = properties["CapacityProviderConfiguration"];
|
|
25327
|
+
if (isNonEmptyObject(capacityProvider)) input["capacityProviderConfiguration"] = pascalToCamelCaseKeys(capacityProvider, CFN_MAP_KEYS);
|
|
25328
|
+
const platformVersion = properties["PlatformVersion"];
|
|
25329
|
+
if (platformVersion !== void 0 && platformVersion !== null && platformVersion !== "") input["platformVersion"] = platformVersion;
|
|
25330
|
+
}
|
|
25102
25331
|
var AgentCoreRuntimeProvider = class {
|
|
25103
25332
|
client;
|
|
25104
25333
|
logger = getLogger().child("AgentCoreRuntimeProvider");
|
|
25334
|
+
sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
25335
|
+
async sendCreateTagCall(send) {
|
|
25336
|
+
for (let attempt = 0;; attempt++) try {
|
|
25337
|
+
return await send();
|
|
25338
|
+
} catch (error) {
|
|
25339
|
+
const delay = CREATE_TAG_RETRY_DELAYS_MS[attempt];
|
|
25340
|
+
if (delay === void 0 || !isTransientTagFailure(error)) throw error;
|
|
25341
|
+
this.logger.debug(safeMsg`Post-create tag call failed transiently (${describeAwsFailure(error).summary}); retrying in ${delay}ms`);
|
|
25342
|
+
await this.sleep(delay);
|
|
25343
|
+
}
|
|
25344
|
+
}
|
|
25105
25345
|
wrapCaughtError(mask, error, build) {
|
|
25106
25346
|
const failure = describeAwsFailure(error);
|
|
25107
25347
|
if (!failure.redacted) return wrapMaskedAwsError(mask, error, build);
|
|
25108
25348
|
this.logger.debug(mask(build(mask(failure.detail)).message));
|
|
25109
|
-
const
|
|
25349
|
+
const relay = isAuxiliaryFailure(error) ? "" : relayedNameCollision(failure.detail);
|
|
25350
|
+
const wrapped = build(`${mask(failure.summary)}${relay}`);
|
|
25110
25351
|
return error instanceof Error ? markRedactedCause(wrapped) : wrapped;
|
|
25111
25352
|
}
|
|
25112
25353
|
handledProperties = /* @__PURE__ */ new Map([["AWS::BedrockAgentCore::Runtime", /* @__PURE__ */ new Set([
|
|
@@ -25119,7 +25360,12 @@ var AgentCoreRuntimeProvider = class {
|
|
|
25119
25360
|
"ProtocolConfiguration",
|
|
25120
25361
|
"LifecycleConfiguration",
|
|
25121
25362
|
"EnvironmentVariables",
|
|
25122
|
-
"ClientToken"
|
|
25363
|
+
"ClientToken",
|
|
25364
|
+
"RequestHeaderConfiguration",
|
|
25365
|
+
"FilesystemConfigurations",
|
|
25366
|
+
"CapacityProviderConfiguration",
|
|
25367
|
+
"PlatformVersion",
|
|
25368
|
+
"Tags"
|
|
25123
25369
|
])]]);
|
|
25124
25370
|
constructor() {
|
|
25125
25371
|
const awsClients = getAwsClients();
|
|
@@ -25131,6 +25377,8 @@ var AgentCoreRuntimeProvider = class {
|
|
|
25131
25377
|
if (!agentRuntimeName) throw new ProvisioningError(`AgentRuntimeName is required for ${logicalId}`, resourceType, logicalId);
|
|
25132
25378
|
const roleArn = properties["RoleArn"];
|
|
25133
25379
|
if (!roleArn) throw new ProvisioningError(`RoleArn is required for ${logicalId}`, resourceType, logicalId);
|
|
25380
|
+
const desiredTags = desiredRuntimeTags(properties["Tags"], resourceType, logicalId);
|
|
25381
|
+
let createdRuntimeId;
|
|
25134
25382
|
try {
|
|
25135
25383
|
const input = {
|
|
25136
25384
|
agentRuntimeName,
|
|
@@ -25148,24 +25396,34 @@ var AgentCoreRuntimeProvider = class {
|
|
|
25148
25396
|
if (properties["LifecycleConfiguration"] !== void 0 && typeof properties["LifecycleConfiguration"] === "object" && properties["LifecycleConfiguration"] !== null && Object.keys(properties["LifecycleConfiguration"]).length > 0) input["lifecycleConfiguration"] = pascalToCamelCaseKeys(properties["LifecycleConfiguration"], CFN_MAP_KEYS);
|
|
25149
25397
|
if (properties["EnvironmentVariables"] !== void 0) input["environmentVariables"] = properties["EnvironmentVariables"];
|
|
25150
25398
|
if (properties["ClientToken"] !== void 0) input["clientToken"] = properties["ClientToken"];
|
|
25399
|
+
writeSharedRuntimeMembers(input, properties);
|
|
25400
|
+
if (desiredTags.length > 0) input["tags"] = Object.fromEntries(desiredTags.map((t) => [t.Key, t.Value]));
|
|
25151
25401
|
const response = await this.client.send(new CreateAgentRuntimeCommand(input));
|
|
25152
25402
|
const agentRuntimeId = response.agentRuntimeId;
|
|
25153
25403
|
const agentRuntimeArn = response.agentRuntimeArn;
|
|
25404
|
+
createdRuntimeId = agentRuntimeId;
|
|
25405
|
+
reportCreatedResource(logicalId, resourceType, agentRuntimeId);
|
|
25154
25406
|
this.logger.debug(`Created BedrockAgentCore Runtime: ${agentRuntimeId} (${agentRuntimeArn})`);
|
|
25407
|
+
if (desiredTags.length > 0) await this.ensureCreateTags(agentRuntimeId, agentRuntimeArn, desiredTags);
|
|
25155
25408
|
return {
|
|
25156
25409
|
physicalId: agentRuntimeId,
|
|
25157
25410
|
attributes: this.buildAttributes(response, agentRuntimeName)
|
|
25158
25411
|
};
|
|
25159
25412
|
} catch (error) {
|
|
25413
|
+
if (createdRuntimeId !== void 0) markAuxiliaryFailure(error, logicalId);
|
|
25160
25414
|
const cause = error instanceof Error ? error : void 0;
|
|
25161
|
-
|
|
25415
|
+
const thrown = this.wrapCaughtError(maskerOrIdentity(context?.maskSecrets), error, (text) => new ProvisioningError(`Failed to create BedrockAgentCore Runtime ${logicalId}: ${text}`, resourceType, logicalId, void 0, cause));
|
|
25416
|
+
if (createdRuntimeId !== void 0) markCreatedBeforeFailure(thrown, logicalId, resourceType, createdRuntimeId);
|
|
25417
|
+
throw thrown;
|
|
25162
25418
|
}
|
|
25163
25419
|
}
|
|
25164
|
-
async update(logicalId, physicalId, resourceType, properties,
|
|
25420
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
25165
25421
|
this.logger.debug(`Updating BedrockAgentCore Runtime ${logicalId}: ${physicalId}`);
|
|
25166
25422
|
assertRegionMatch(context?.expectedRegion ? await this.client.config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
25167
25423
|
const roleArn = properties["RoleArn"];
|
|
25168
25424
|
if (!roleArn) throw new ProvisioningError(`RoleArn is required for ${logicalId}`, resourceType, logicalId, physicalId);
|
|
25425
|
+
desiredRuntimeTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
25426
|
+
const mask = maskerOrIdentity(context?.maskSecrets);
|
|
25169
25427
|
try {
|
|
25170
25428
|
const input = {
|
|
25171
25429
|
agentRuntimeId: physicalId,
|
|
@@ -25183,8 +25441,10 @@ var AgentCoreRuntimeProvider = class {
|
|
|
25183
25441
|
if (properties["LifecycleConfiguration"] !== void 0 && typeof properties["LifecycleConfiguration"] === "object" && properties["LifecycleConfiguration"] !== null && Object.keys(properties["LifecycleConfiguration"]).length > 0) input["lifecycleConfiguration"] = pascalToCamelCaseKeys(properties["LifecycleConfiguration"], CFN_MAP_KEYS);
|
|
25184
25442
|
if (properties["EnvironmentVariables"] !== void 0) input["environmentVariables"] = properties["EnvironmentVariables"];
|
|
25185
25443
|
if (properties["ClientToken"] !== void 0) input["clientToken"] = properties["ClientToken"];
|
|
25444
|
+
writeSharedRuntimeMembers(input, properties);
|
|
25186
25445
|
const response = await this.client.send(new UpdateAgentRuntimeCommand(input));
|
|
25187
25446
|
const agentRuntimeId = response.agentRuntimeId;
|
|
25447
|
+
await this.syncTags(logicalId, resourceType, physicalId, response.agentRuntimeArn, previousProperties["Tags"], properties["Tags"], mask);
|
|
25188
25448
|
this.logger.debug(`Successfully updated BedrockAgentCore Runtime ${logicalId}`);
|
|
25189
25449
|
return {
|
|
25190
25450
|
physicalId: agentRuntimeId,
|
|
@@ -25192,10 +25452,44 @@ var AgentCoreRuntimeProvider = class {
|
|
|
25192
25452
|
attributes: this.buildAttributes(response, properties["AgentRuntimeName"])
|
|
25193
25453
|
};
|
|
25194
25454
|
} catch (error) {
|
|
25455
|
+
if (error instanceof CdkdError) throw error;
|
|
25195
25456
|
const cause = error instanceof Error ? error : void 0;
|
|
25196
|
-
throw this.wrapCaughtError(
|
|
25457
|
+
throw this.wrapCaughtError(mask, error, (text) => new ProvisioningError(`Failed to update BedrockAgentCore Runtime ${logicalId}: ${text}`, resourceType, logicalId, physicalId, cause));
|
|
25197
25458
|
}
|
|
25198
25459
|
}
|
|
25460
|
+
async ensureCreateTags(agentRuntimeId, resourceArn, desired) {
|
|
25461
|
+
let live;
|
|
25462
|
+
try {
|
|
25463
|
+
live = (await this.sendCreateTagCall(() => this.client.send(new ListTagsForResourceCommand$6({ resourceArn })))).tags ?? {};
|
|
25464
|
+
} catch (err) {
|
|
25465
|
+
this.logger.debug(safeMsg`Could not read the tags of new runtime ${agentRuntimeId} (${describeAwsFailure(err).detail}); setting every declared tag`);
|
|
25466
|
+
}
|
|
25467
|
+
const missing = Object.fromEntries(desired.filter((t) => live?.[t.Key] !== t.Value).map((t) => [t.Key, t.Value]));
|
|
25468
|
+
if (Object.keys(missing).length === 0) return;
|
|
25469
|
+
if (live !== void 0) this.logger.debug(safeMsg`New runtime ${agentRuntimeId} lacks ${Object.keys(missing).length} of the tag(s) CreateAgentRuntime was sent; setting them with TagResource`);
|
|
25470
|
+
await this.sendCreateTagCall(() => this.client.send(new TagResourceCommand$9({
|
|
25471
|
+
resourceArn,
|
|
25472
|
+
tags: missing
|
|
25473
|
+
})));
|
|
25474
|
+
}
|
|
25475
|
+
async syncTags(logicalId, resourceType, physicalId, responseArn, previousTagsRaw, nextTagsRaw, mask) {
|
|
25476
|
+
const plan = planTagDiff(tagMapAsList(previousTagsRaw), tagMapAsList(nextTagsRaw));
|
|
25477
|
+
const warning = tagPlanWarning(plan, resourceType, logicalId);
|
|
25478
|
+
if (warning !== void 0) this.logger.warn(mask(warning));
|
|
25479
|
+
const remove = plan.remove.filter(isUserTagKey);
|
|
25480
|
+
const set = Object.fromEntries([...plan.set].filter(([k]) => isUserTagKey(k)));
|
|
25481
|
+
if (remove.length === 0 && Object.keys(set).length === 0) return;
|
|
25482
|
+
const resourceArn = responseArn ?? (await this.client.send(new GetAgentRuntimeCommand({ agentRuntimeId: physicalId }))).agentRuntimeArn;
|
|
25483
|
+
if (!resourceArn) throw new ProvisioningError(`Cannot apply the Tags change to ${logicalId}: AWS returned no runtime ARN`, resourceType, logicalId, physicalId);
|
|
25484
|
+
if (remove.length > 0) await this.client.send(new UntagResourceCommand$9({
|
|
25485
|
+
resourceArn,
|
|
25486
|
+
tagKeys: remove
|
|
25487
|
+
}));
|
|
25488
|
+
if (Object.keys(set).length > 0) await this.client.send(new TagResourceCommand$9({
|
|
25489
|
+
resourceArn,
|
|
25490
|
+
tags: set
|
|
25491
|
+
}));
|
|
25492
|
+
}
|
|
25199
25493
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
25200
25494
|
this.logger.debug(`Deleting BedrockAgentCore Runtime ${logicalId}: ${physicalId}`);
|
|
25201
25495
|
try {
|
|
@@ -25263,6 +25557,16 @@ var AgentCoreRuntimeProvider = class {
|
|
|
25263
25557
|
}
|
|
25264
25558
|
if (resp.lifecycleConfiguration !== void 0) result["LifecycleConfiguration"] = camelToPascalCaseKeys(resp.lifecycleConfiguration, SDK_MAP_KEYS);
|
|
25265
25559
|
if (resp.environmentVariables !== void 0) result["EnvironmentVariables"] = resp.environmentVariables;
|
|
25560
|
+
result["RequestHeaderConfiguration"] = resp.requestHeaderConfiguration !== void 0 ? camelToPascalCaseKeys(resp.requestHeaderConfiguration, SDK_MAP_KEYS) : {};
|
|
25561
|
+
result["FilesystemConfigurations"] = resp.filesystemConfigurations !== void 0 ? camelToPascalCaseKeys(resp.filesystemConfigurations, SDK_MAP_KEYS) : [];
|
|
25562
|
+
result["CapacityProviderConfiguration"] = resp.capacityProviderConfiguration !== void 0 ? camelToPascalCaseKeys(resp.capacityProviderConfiguration, SDK_MAP_KEYS) : {};
|
|
25563
|
+
result["PlatformVersion"] = resp.platformVersion ?? "";
|
|
25564
|
+
if (resp.agentRuntimeArn) try {
|
|
25565
|
+
const tagsResp = await this.client.send(new ListTagsForResourceCommand$6({ resourceArn: resp.agentRuntimeArn }));
|
|
25566
|
+
result["Tags"] = Object.fromEntries(Object.entries(tagsResp.tags ?? {}).filter(([k]) => isUserTagKey(k)));
|
|
25567
|
+
} catch (err) {
|
|
25568
|
+
this.logger.debug(safeMsg`Failed to read tags for runtime ${physicalId}: ${describeAwsFailure(err).detail}`);
|
|
25569
|
+
}
|
|
25266
25570
|
return result;
|
|
25267
25571
|
}
|
|
25268
25572
|
async import(input) {
|
|
@@ -26532,6 +26836,7 @@ var ECSProvider = class {
|
|
|
26532
26836
|
}))).service;
|
|
26533
26837
|
if (!service || !service.serviceArn) throw new Error("CreateService did not return service ARN");
|
|
26534
26838
|
log.debug(`Successfully created ECS service ${logicalId}: ${service.serviceArn}`);
|
|
26839
|
+
if (heldBefore === "free") reportCreatedResource(logicalId, resourceType, service.serviceArn);
|
|
26535
26840
|
try {
|
|
26536
26841
|
await this.settleService(logicalId, service.serviceName ?? service.serviceArn, properties["Cluster"], log);
|
|
26537
26842
|
} catch (waitError) {
|
|
@@ -26547,6 +26852,7 @@ var ECSProvider = class {
|
|
|
26547
26852
|
service: service.serviceArn,
|
|
26548
26853
|
force: true
|
|
26549
26854
|
}));
|
|
26855
|
+
retractCreatedResource(logicalId, resourceType, service.serviceArn);
|
|
26550
26856
|
log.warn(`Deleted partially-created ECS service ${logicalId} (${service.serviceArn}) after the steady-state wait failed, so the next deploy's CreateService does not collide on the name. Its stopped tasks remain inspectable for about an hour: ${listStopped.render()}`);
|
|
26551
26857
|
} catch (cleanupError) {
|
|
26552
26858
|
survivorArn = service.serviceArn;
|
|
@@ -27982,6 +28288,7 @@ var ELBv2Provider = class {
|
|
|
27982
28288
|
if (!lb || !lb.LoadBalancerArn) throw new Error("CreateLoadBalancer did not return LoadBalancer ARN");
|
|
27983
28289
|
const lbArn = lb.LoadBalancerArn;
|
|
27984
28290
|
this.logger.debug(`Successfully created LoadBalancer ${logicalId}: ${lbArn}`);
|
|
28291
|
+
if (heldBefore === "free") reportCreatedResource(logicalId, resourceType, lbArn);
|
|
27985
28292
|
try {
|
|
27986
28293
|
if (waitForActive) {
|
|
27987
28294
|
this.logger.debug(`Waiting for LoadBalancer ${logicalId} to reach active state...`);
|
|
@@ -28020,6 +28327,7 @@ var ELBv2Provider = class {
|
|
|
28020
28327
|
if (heldBefore !== "free") this.logger.warn(maskerOrIdentity(maskSecrets)(skippedCleanupText(heldBefore, `LoadBalancer ${logicalId} (${lbArn})`, pasteableAwsCommand(maskSecrets)`aws elbv2 delete-load-balancer --load-balancer-arn ${lbArn}`.render())));
|
|
28021
28328
|
else try {
|
|
28022
28329
|
await this.getClient().send(new DeleteLoadBalancerCommand({ LoadBalancerArn: lbArn }));
|
|
28330
|
+
retractCreatedResource(logicalId, resourceType, lbArn);
|
|
28023
28331
|
this.logger.debug(`Cleaned up partially-created LoadBalancer ${logicalId} (${lbArn}) after wiring failure`);
|
|
28024
28332
|
} catch (cleanupError) {
|
|
28025
28333
|
leftBehindArn = lbArn;
|
|
@@ -28288,6 +28596,7 @@ var ELBv2Provider = class {
|
|
|
28288
28596
|
if (!tg || !tg.TargetGroupArn) throw new Error("CreateTargetGroup did not return TargetGroup ARN");
|
|
28289
28597
|
const tgArn = tg.TargetGroupArn;
|
|
28290
28598
|
this.logger.debug(`Successfully created TargetGroup ${logicalId}: ${tgArn}`);
|
|
28599
|
+
if (heldBefore === "free") reportCreatedResource(logicalId, resourceType, tgArn);
|
|
28291
28600
|
try {
|
|
28292
28601
|
if (tgAttributes.length > 0) {
|
|
28293
28602
|
await this.getClient().send(new ModifyTargetGroupAttributesCommand({
|
|
@@ -28310,6 +28619,7 @@ var ELBv2Provider = class {
|
|
|
28310
28619
|
if (isInterruptedWaitError(innerError)) this.logger.warn(maskerOrIdentity(maskSecrets)(`Interrupted after creating TargetGroup ${logicalId} (${tgArn}) but before its targets were registered. Nothing in cdkd state refers to it, so cdkd is deleting it now. If that delete fails, remove it yourself: ${pasteableAwsCommand(maskSecrets)`aws elbv2 delete-target-group --target-group-arn ${tgArn}`.render()}`));
|
|
28311
28620
|
try {
|
|
28312
28621
|
await this.getClient().send(new DeleteTargetGroupCommand({ TargetGroupArn: tgArn }));
|
|
28622
|
+
retractCreatedResource(logicalId, resourceType, tgArn);
|
|
28313
28623
|
this.logger.debug(`Cleaned up partially-created TargetGroup ${logicalId} (${tgArn}) after wiring failure`);
|
|
28314
28624
|
} catch (cleanupError) {
|
|
28315
28625
|
leftBehindArn = tgArn;
|
|
@@ -28483,6 +28793,7 @@ var ELBv2Provider = class {
|
|
|
28483
28793
|
if (!listener || !listener.ListenerArn) throw new Error("CreateListener did not return Listener ARN");
|
|
28484
28794
|
const listenerArn = listener.ListenerArn;
|
|
28485
28795
|
this.logger.debug(`Successfully created Listener ${logicalId}: ${listenerArn}`);
|
|
28796
|
+
if (heldBefore === "free") reportCreatedResource(logicalId, resourceType, listenerArn);
|
|
28486
28797
|
try {
|
|
28487
28798
|
if (listenerAttributes.length > 0) {
|
|
28488
28799
|
const watch = startInterruptWatch(`ELBv2 Listener ${logicalId} attributes`);
|
|
@@ -28508,6 +28819,7 @@ var ELBv2Provider = class {
|
|
|
28508
28819
|
if (isInterruptedWaitError(innerError)) this.logger.warn(maskerOrIdentity(maskSecrets)(`Interrupted after creating Listener ${logicalId} (${listenerArn}) but before its attributes were applied. Nothing in cdkd state refers to it, so cdkd is deleting it now — left behind it would fail the next deploy with DuplicateListener and destroy could not reach it. If that delete fails, outside a rollback's re-create, the failed deploy's rollback journal records it for \`cdkd rollback --revert-failed\`; otherwise remove it yourself: ${pasteableAwsCommand(maskSecrets)`aws elbv2 delete-listener --listener-arn ${listenerArn}`.render()}`));
|
|
28509
28820
|
try {
|
|
28510
28821
|
await this.getClient().send(new DeleteListenerCommand({ ListenerArn: listenerArn }));
|
|
28822
|
+
retractCreatedResource(logicalId, resourceType, listenerArn);
|
|
28511
28823
|
this.logger.debug(`Cleaned up partially-created Listener ${logicalId} (${listenerArn}) after attributes-wiring failure`);
|
|
28512
28824
|
} catch (cleanupError) {
|
|
28513
28825
|
leftBehindArn = listenerArn;
|
|
@@ -29128,6 +29440,7 @@ var RDSDBProxyProvider = class {
|
|
|
29128
29440
|
} catch (error) {
|
|
29129
29441
|
throw this.wrapCaughtError(error, "CREATE", resourceType, logicalId, void 0, mask);
|
|
29130
29442
|
}
|
|
29443
|
+
reportCreatedResource(logicalId, resourceType, dbProxyName);
|
|
29131
29444
|
let endpoint;
|
|
29132
29445
|
let dbProxyArn;
|
|
29133
29446
|
let vpcId;
|
|
@@ -29457,6 +29770,7 @@ var RDSDBProxyEndpointProvider = class {
|
|
|
29457
29770
|
} catch (error) {
|
|
29458
29771
|
throw this.wrapCaughtError(error, "CREATE", resourceType, logicalId, void 0, mask);
|
|
29459
29772
|
}
|
|
29773
|
+
reportCreatedResource(logicalId, resourceType, dbProxyEndpointName);
|
|
29460
29774
|
let endpoint;
|
|
29461
29775
|
let arn;
|
|
29462
29776
|
let isDefault;
|
|
@@ -29816,6 +30130,7 @@ var RDSDBProxyTargetGroupProvider = class {
|
|
|
29816
30130
|
throw await this.retireRegistrationAfterFailedCreate(this.wrapError(error, "CREATE (describe)", resourceType, logicalId, void 0, mask), dbProxyName, targetGroupName, dbClusterIdentifiers, dbInstanceIdentifiers, context?.maskSecrets);
|
|
29817
30131
|
}
|
|
29818
30132
|
if (!targetGroupArn) throw await this.retireRegistrationAfterFailedCreate(new ProvisioningError(`Failed to recover TargetGroupArn for ${dbProxyName}/${targetGroupName} after create`, resourceType, logicalId), dbProxyName, targetGroupName, dbClusterIdentifiers, dbInstanceIdentifiers, context?.maskSecrets);
|
|
30133
|
+
if (dbClusterIdentifiers.length > 0 || dbInstanceIdentifiers.length > 0) reportCreatedResource(logicalId, resourceType, targetGroupArn);
|
|
29819
30134
|
if (tags.length > 0) try {
|
|
29820
30135
|
await client.send(new AddTagsToResourceCommand$2({
|
|
29821
30136
|
ResourceName: targetGroupArn,
|
|
@@ -30135,6 +30450,7 @@ var RDSDBProxyTargetGroupProvider = class {
|
|
|
30135
30450
|
DBClusterIdentifiers: clusters,
|
|
30136
30451
|
DBInstanceIdentifiers: instances
|
|
30137
30452
|
}));
|
|
30453
|
+
if (leftBehind) retractCreatedResource(leftBehind.logicalId, leftBehind.resourceType, leftBehind.physicalId);
|
|
30138
30454
|
return original;
|
|
30139
30455
|
} catch (cleanupError) {
|
|
30140
30456
|
const aws = pasteableAwsCommand(maskSecrets);
|
|
@@ -30410,6 +30726,7 @@ var DocDBProvider = class {
|
|
|
30410
30726
|
}));
|
|
30411
30727
|
clusterCreated = true;
|
|
30412
30728
|
createdResourceId = response.DBCluster?.DbClusterResourceId;
|
|
30729
|
+
reportCreatedResource(logicalId, resourceType, dbClusterIdentifier, createdResourceId);
|
|
30413
30730
|
if (!response.DBCluster) throw new Error("CreateDBCluster did not return DBCluster");
|
|
30414
30731
|
this.logger.debug(`Successfully created DocDB DBCluster ${logicalId}: ${dbClusterIdentifier}`);
|
|
30415
30732
|
if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForClusterAvailable(logicalId, dbClusterIdentifier);
|
|
@@ -30565,6 +30882,7 @@ var DocDBProvider = class {
|
|
|
30565
30882
|
}));
|
|
30566
30883
|
instanceCreated = true;
|
|
30567
30884
|
createdResourceId = response.DBInstance?.DbiResourceId;
|
|
30885
|
+
reportCreatedResource(logicalId, resourceType, dbInstanceIdentifier, createdResourceId);
|
|
30568
30886
|
if (!response.DBInstance) throw new Error("CreateDBInstance did not return DBInstance");
|
|
30569
30887
|
this.logger.debug(`Successfully created DocDB DBInstance ${logicalId}: ${dbInstanceIdentifier}`);
|
|
30570
30888
|
if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForInstanceAvailable(logicalId, dbInstanceIdentifier);
|
|
@@ -31268,6 +31586,7 @@ var Route53Provider = class {
|
|
|
31268
31586
|
if (!hostedZone?.Id) throw new Error("CreateHostedZone did not return HostedZone.Id");
|
|
31269
31587
|
const zoneId = hostedZone.Id.replace("/hostedzone/", "");
|
|
31270
31588
|
createdZoneId = zoneId;
|
|
31589
|
+
reportCreatedResource(logicalId, resourceType, zoneId);
|
|
31271
31590
|
if (vpcs && vpcs.length > 1) for (let i = 1; i < vpcs.length; i++) {
|
|
31272
31591
|
const additionalVpc = vpcs[i];
|
|
31273
31592
|
this.logger.debug(`Associating additional VPC ${String(additionalVpc["VPCId"])} with hosted zone ${zoneId}`);
|
|
@@ -31293,6 +31612,7 @@ var Route53Provider = class {
|
|
|
31293
31612
|
await this.deleteQueryLoggingConfigForZone(zoneId, logicalId);
|
|
31294
31613
|
await this.getClient().send(new DeleteHostedZoneCommand({ Id: zoneId }));
|
|
31295
31614
|
zoneRolledBack = true;
|
|
31615
|
+
retractCreatedResource(logicalId, resourceType, zoneId);
|
|
31296
31616
|
callerReferenceToken.release();
|
|
31297
31617
|
} catch (deleteError) {
|
|
31298
31618
|
const head = `Best-effort rollback DeleteHostedZone for ${zoneId} also failed: `;
|
|
@@ -32213,6 +32533,27 @@ function sanitizeDescription(value) {
|
|
|
32213
32533
|
function isPlainObject$2(value) {
|
|
32214
32534
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
32215
32535
|
}
|
|
32536
|
+
const DATA_PROTECTION_FALSE_DEFAULTS = ["ExcludeRuleMatchDetails", "ExcludeRateBasedDetails"];
|
|
32537
|
+
function toCfnDataProtectionConfig(config, baseline) {
|
|
32538
|
+
const entries = config["DataProtections"];
|
|
32539
|
+
if (!Array.isArray(entries)) return config;
|
|
32540
|
+
const baseEntries = isPlainObject$2(baseline) && Array.isArray(baseline["DataProtections"]) ? baseline["DataProtections"] : [];
|
|
32541
|
+
return {
|
|
32542
|
+
...config,
|
|
32543
|
+
DataProtections: entries.map((entry, i) => {
|
|
32544
|
+
if (!isPlainObject$2(entry)) return entry;
|
|
32545
|
+
const base = baseEntries[i];
|
|
32546
|
+
const converted = { ...entry };
|
|
32547
|
+
for (const key of DATA_PROTECTION_FALSE_DEFAULTS) if (converted[key] === false && !(isPlainObject$2(base) && key in base)) delete converted[key];
|
|
32548
|
+
return converted;
|
|
32549
|
+
})
|
|
32550
|
+
};
|
|
32551
|
+
}
|
|
32552
|
+
function applicationConfigForUpdate(next, previous) {
|
|
32553
|
+
if (next === void 0 || next === null) return void 0;
|
|
32554
|
+
if (isDeepStrictEqual(next, previous)) return void 0;
|
|
32555
|
+
return next;
|
|
32556
|
+
}
|
|
32216
32557
|
function toSdkByteMatchStatement(byteMatchStatement) {
|
|
32217
32558
|
const encoded = byteMatchStatement["SearchStringBase64"];
|
|
32218
32559
|
if (typeof encoded !== "string") return byteMatchStatement;
|
|
@@ -32391,7 +32732,11 @@ var WAFv2WebACLProvider = class {
|
|
|
32391
32732
|
"CaptchaConfig",
|
|
32392
32733
|
"ChallengeConfig",
|
|
32393
32734
|
"TokenDomains",
|
|
32394
|
-
"AssociationConfig"
|
|
32735
|
+
"AssociationConfig",
|
|
32736
|
+
"DataProtectionConfig",
|
|
32737
|
+
"OnSourceDDoSProtectionConfig",
|
|
32738
|
+
"ApplicationConfig",
|
|
32739
|
+
"MonetizationConfig"
|
|
32395
32740
|
])]]);
|
|
32396
32741
|
getClient() {
|
|
32397
32742
|
if (!this.wafv2Client) {
|
|
@@ -32432,7 +32777,11 @@ var WAFv2WebACLProvider = class {
|
|
|
32432
32777
|
CaptchaConfig: properties["CaptchaConfig"],
|
|
32433
32778
|
ChallengeConfig: properties["ChallengeConfig"],
|
|
32434
32779
|
TokenDomains: properties["TokenDomains"],
|
|
32435
|
-
AssociationConfig: properties["AssociationConfig"]
|
|
32780
|
+
AssociationConfig: properties["AssociationConfig"],
|
|
32781
|
+
DataProtectionConfig: properties["DataProtectionConfig"],
|
|
32782
|
+
OnSourceDDoSProtectionConfig: properties["OnSourceDDoSProtectionConfig"],
|
|
32783
|
+
ApplicationConfig: properties["ApplicationConfig"],
|
|
32784
|
+
MonetizationConfig: properties["MonetizationConfig"]
|
|
32436
32785
|
}))).Summary;
|
|
32437
32786
|
if (!summary?.ARN || !summary?.Id) throw new Error("CreateWebACL did not return Summary with ARN and Id");
|
|
32438
32787
|
this.logger.debug(`Successfully created WAFv2 WebACL ${logicalId}: ${summary.ARN}`);
|
|
@@ -32486,7 +32835,11 @@ var WAFv2WebACLProvider = class {
|
|
|
32486
32835
|
CaptchaConfig: properties["CaptchaConfig"],
|
|
32487
32836
|
ChallengeConfig: properties["ChallengeConfig"],
|
|
32488
32837
|
TokenDomains: properties["TokenDomains"],
|
|
32489
|
-
AssociationConfig: properties["AssociationConfig"]
|
|
32838
|
+
AssociationConfig: properties["AssociationConfig"],
|
|
32839
|
+
DataProtectionConfig: properties["DataProtectionConfig"],
|
|
32840
|
+
OnSourceDDoSProtectionConfig: properties["OnSourceDDoSProtectionConfig"],
|
|
32841
|
+
ApplicationConfig: applicationConfigForUpdate(properties["ApplicationConfig"], previousProperties["ApplicationConfig"]),
|
|
32842
|
+
MonetizationConfig: properties["MonetizationConfig"]
|
|
32490
32843
|
}));
|
|
32491
32844
|
await this.applyTagDiff(physicalId, resourceType, logicalId, previousProperties["Tags"], properties["Tags"]);
|
|
32492
32845
|
this.logger.debug(`Successfully updated WAFv2 WebACL ${logicalId}`);
|
|
@@ -32593,6 +32946,10 @@ var WAFv2WebACLProvider = class {
|
|
|
32593
32946
|
if (webACL.ChallengeConfig) result["ChallengeConfig"] = webACL.ChallengeConfig;
|
|
32594
32947
|
result["TokenDomains"] = webACL.TokenDomains ? [...webACL.TokenDomains] : [];
|
|
32595
32948
|
if (webACL.AssociationConfig) result["AssociationConfig"] = webACL.AssociationConfig;
|
|
32949
|
+
if (webACL.DataProtectionConfig) result["DataProtectionConfig"] = toCfnDataProtectionConfig(webACL.DataProtectionConfig, properties?.["DataProtectionConfig"]);
|
|
32950
|
+
if (webACL.OnSourceDDoSProtectionConfig) result["OnSourceDDoSProtectionConfig"] = webACL.OnSourceDDoSProtectionConfig;
|
|
32951
|
+
if (webACL.ApplicationConfig) result["ApplicationConfig"] = webACL.ApplicationConfig;
|
|
32952
|
+
if (webACL.MonetizationConfig) result["MonetizationConfig"] = webACL.MonetizationConfig;
|
|
32596
32953
|
try {
|
|
32597
32954
|
const tagsResp = await this.getClient().send(new ListTagsForResourceCommand$13({ ResourceARN: physicalId }));
|
|
32598
32955
|
result["Tags"] = normalizeAwsTagsToCfn(tagsResp.TagInfoForResource?.TagList);
|
|
@@ -33068,6 +33425,7 @@ var CognitoUserPoolProvider = class {
|
|
|
33068
33425
|
if (!userPool?.Id) throw new Error("CreateUserPool did not return UserPool.Id");
|
|
33069
33426
|
const userPoolId = userPool.Id;
|
|
33070
33427
|
createdUserPoolId = userPoolId;
|
|
33428
|
+
reportCreatedResource(logicalId, resourceType, userPoolId);
|
|
33071
33429
|
const replayWindow = replayedSendWindow(created, attemptStartMs);
|
|
33072
33430
|
if (replayWindow !== void 0) await this.reportPossibleOrphanPools(logicalId, poolName, replayWindow, createMaskedLogSinks(this.logger, context?.maskSecrets), userPoolId);
|
|
33073
33431
|
const userPoolArn = userPool.Arn;
|
|
@@ -33095,6 +33453,7 @@ var CognitoUserPoolProvider = class {
|
|
|
33095
33453
|
markAuxiliaryFailure(error, logicalId);
|
|
33096
33454
|
try {
|
|
33097
33455
|
await this.getClient().send(new DeleteUserPoolCommand({ UserPoolId: createdUserPoolId }));
|
|
33456
|
+
retractCreatedResource(logicalId, resourceType, createdUserPoolId);
|
|
33098
33457
|
this.logger.debug(`Rolled back partially-created Cognito User Pool ${createdUserPoolId}`);
|
|
33099
33458
|
} catch (rollbackError) {
|
|
33100
33459
|
poolLeftBehind = true;
|
|
@@ -33976,6 +34335,7 @@ var ElastiCacheProvider = class {
|
|
|
33976
34335
|
...tags.length > 0 && { Tags: tags }
|
|
33977
34336
|
}));
|
|
33978
34337
|
clusterCreated = true;
|
|
34338
|
+
reportCreatedResource(logicalId, resourceType, cacheClusterId);
|
|
33979
34339
|
this.logger.debug(`Successfully created CacheCluster ${logicalId}: ${cacheClusterId}`);
|
|
33980
34340
|
if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForClusterAvailable(cacheClusterId);
|
|
33981
34341
|
const described = await this.describeCacheCluster(cacheClusterId);
|
|
@@ -34786,6 +35146,7 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
|
|
|
34786
35146
|
if (!service || !service.Id) throw new Error("CreateService did not return Service ID");
|
|
34787
35147
|
const serviceId = service.Id;
|
|
34788
35148
|
leftBehindServiceId = serviceId;
|
|
35149
|
+
reportCreatedResource(logicalId, resourceType, serviceId);
|
|
34789
35150
|
this.logger.debug(`Successfully created service discovery service ${logicalId}: ${serviceId}`);
|
|
34790
35151
|
try {
|
|
34791
35152
|
const attrs = this.normalizeServiceAttributes(properties["ServiceAttributes"]);
|
|
@@ -34810,6 +35171,7 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
|
|
|
34810
35171
|
try {
|
|
34811
35172
|
await client.send(new DeleteServiceCommand$1({ Id: serviceId }));
|
|
34812
35173
|
leftBehindServiceId = void 0;
|
|
35174
|
+
retractCreatedResource(logicalId, resourceType, serviceId);
|
|
34813
35175
|
this.logger.debug(`Cleaned up partially-created ServiceDiscovery Service ${logicalId} (${serviceId}) after ServiceAttributes wiring failure`);
|
|
34814
35176
|
} catch (cleanupError) {
|
|
34815
35177
|
const cleanupFailure = describeAwsFailure(cleanupError);
|
|
@@ -36234,6 +36596,7 @@ var AppSyncProvider = class {
|
|
|
36234
36596
|
throw error;
|
|
36235
36597
|
}
|
|
36236
36598
|
createdApiId = response.graphqlApi?.apiId;
|
|
36599
|
+
if (createdApiId) reportCreatedResource(logicalId, resourceType, createdApiId);
|
|
36237
36600
|
const apiId = response.graphqlApi.apiId;
|
|
36238
36601
|
const replayWindow = replayedSendWindow(response, attemptStartMs);
|
|
36239
36602
|
if (replayWindow !== void 0) await this.reportPossibleOrphanApis(logicalId, input, replayWindow, maskerOrIdentity(context?.maskSecrets), apiId);
|
|
@@ -36257,6 +36620,7 @@ var AppSyncProvider = class {
|
|
|
36257
36620
|
markAuxiliaryFailure(error, logicalId);
|
|
36258
36621
|
try {
|
|
36259
36622
|
await this.getClient().send(new DeleteGraphqlApiCommand({ apiId: createdApiId }));
|
|
36623
|
+
retractCreatedResource(logicalId, resourceType, createdApiId);
|
|
36260
36624
|
this.logger.debug(`Rolled back partially-created GraphQL API ${createdApiId}`);
|
|
36261
36625
|
} catch (rollbackError) {
|
|
36262
36626
|
apiLeftBehind = true;
|
|
@@ -39391,6 +39755,7 @@ var KMSProvider = class {
|
|
|
39391
39755
|
heldAtMs: Date.now()
|
|
39392
39756
|
});
|
|
39393
39757
|
createdKeyId = keyId;
|
|
39758
|
+
reportCreatedResource(logicalId, resourceType, keyId);
|
|
39394
39759
|
const declinedAtMs = supersededAttempts.get(attemptKey);
|
|
39395
39760
|
supersededAttempts.delete(attemptKey);
|
|
39396
39761
|
supersededPending = declinedAtMs !== void 0 && Date.now() - declinedAtMs <= 18e5;
|
|
@@ -39398,6 +39763,7 @@ var KMSProvider = class {
|
|
|
39398
39763
|
if (replayWindow !== void 0) await this.reportPossibleOrphanKeys(logicalId, input, replayWindow);
|
|
39399
39764
|
}
|
|
39400
39765
|
createdKeyId = keyId;
|
|
39766
|
+
reportCreatedResource(logicalId, resourceType, keyId);
|
|
39401
39767
|
if (enableKeyRotation === true) {
|
|
39402
39768
|
const rotationPeriodInDays = properties["RotationPeriodInDays"];
|
|
39403
39769
|
this.logger.debug(`Enabling key rotation for KMS Key ${logicalId}`);
|
|
@@ -40623,58 +40989,6 @@ var BudgetsBudgetProvider = class {
|
|
|
40623
40989
|
}
|
|
40624
40990
|
};
|
|
40625
40991
|
|
|
40626
|
-
//#endregion
|
|
40627
|
-
//#region src/provisioning/delete-gone-wait.ts
|
|
40628
|
-
async function waitForGoneAfterDelete(opts) {
|
|
40629
|
-
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
40630
|
-
const now = opts.now ?? Date.now;
|
|
40631
|
-
const userTimeoutMs = resolvedResourceTimeoutMs(opts.resourceType);
|
|
40632
|
-
const maxWaitMs = userTimeoutMs === void 0 ? opts.maxWaitMs : Math.min(opts.maxWaitMs, userTimeoutMs / 2);
|
|
40633
|
-
const startedAt = now();
|
|
40634
|
-
const stopped = `${opts.what}: the delete was ACCEPTED by AWS, but cdkd stopped waiting for it to disappear`;
|
|
40635
|
-
const consequence = "AWS finishes the delete on its side; until it does, a create of the same name is refused with \"already exists\".";
|
|
40636
|
-
const watch = startInterruptWatch(`${opts.what} deletion wait`);
|
|
40637
|
-
try {
|
|
40638
|
-
let lastStatus;
|
|
40639
|
-
let sawNonFailedStatus = false;
|
|
40640
|
-
for (;;) {
|
|
40641
|
-
if (watch.isInterrupted()) {
|
|
40642
|
-
opts.logger.warn(safeMsg`${stopped} (interrupted). ${consequence}`);
|
|
40643
|
-
return;
|
|
40644
|
-
}
|
|
40645
|
-
try {
|
|
40646
|
-
const status = await opts.describe();
|
|
40647
|
-
if (status === void 0) {
|
|
40648
|
-
opts.logger.debug(safeMsg`${opts.what} is gone`);
|
|
40649
|
-
return;
|
|
40650
|
-
}
|
|
40651
|
-
const failure = opts.failedStatus?.(status);
|
|
40652
|
-
if (failure !== void 0) {
|
|
40653
|
-
if (sawNonFailedStatus || now() - startedAt >= opts.pollIntervalMs) throw markWaitAbandoned(failure);
|
|
40654
|
-
} else sawNonFailedStatus = true;
|
|
40655
|
-
lastStatus = status;
|
|
40656
|
-
opts.logger.debug(safeMsg`${opts.what} status: ${status}, waiting for it to disappear`);
|
|
40657
|
-
} catch (error) {
|
|
40658
|
-
if (isWaitAbandonedError(error)) throw error;
|
|
40659
|
-
if (!isThrottlingError(error) && !isTransientServerError(error)) {
|
|
40660
|
-
opts.logger.debug(safeMsg`${opts.what}: status read failed: ${describeAwsFailure(error).detail}`);
|
|
40661
|
-
opts.logger.warn(safeMsg`${stopped}: its status could not be read (${describeAwsFailure(error).summary}). ${consequence}`);
|
|
40662
|
-
return;
|
|
40663
|
-
}
|
|
40664
|
-
opts.logger.debug(safeMsg`${opts.what}: status read throttled or failed transiently, re-polling`);
|
|
40665
|
-
}
|
|
40666
|
-
const remainingMs = maxWaitMs - (now() - startedAt);
|
|
40667
|
-
if (remainingMs <= 0) {
|
|
40668
|
-
opts.logger.warn(safeMsg`${stopped} after ${Math.round(maxWaitMs / 1e3)}s` + safeMsg`${lastStatus !== void 0 ? ` (last status: ${lastStatus})` : ""}. ${consequence}`);
|
|
40669
|
-
return;
|
|
40670
|
-
}
|
|
40671
|
-
await sleep(Math.min(opts.pollIntervalMs, remainingMs));
|
|
40672
|
-
}
|
|
40673
|
-
} finally {
|
|
40674
|
-
watch.dispose();
|
|
40675
|
-
}
|
|
40676
|
-
}
|
|
40677
|
-
|
|
40678
40992
|
//#endregion
|
|
40679
40993
|
//#region src/provisioning/providers/kinesis-provider.ts
|
|
40680
40994
|
function isKmsEncryption(value) {
|
|
@@ -40864,6 +41178,7 @@ var KinesisStreamProvider = class {
|
|
|
40864
41178
|
...Object.keys(tags).length > 0 && { Tags: tags }
|
|
40865
41179
|
}));
|
|
40866
41180
|
streamCreated = true;
|
|
41181
|
+
reportCreatedResource(logicalId, resourceType, streamName);
|
|
40867
41182
|
this.logger.debug(`CreateStream initiated for ${streamName}, waiting for ACTIVE status`);
|
|
40868
41183
|
const streamInfo = await this.waitForStreamActive(streamName);
|
|
40869
41184
|
const retentionPeriodHours = retentionRead.kind === "usable" ? retentionRead.hours : void 0;
|
|
@@ -40969,7 +41284,10 @@ var KinesisStreamProvider = class {
|
|
|
40969
41284
|
}
|
|
40970
41285
|
await this.applyTagDiff(physicalId, resourceType, logicalId, previousProperties["Tags"], properties["Tags"], {
|
|
40971
41286
|
forceUpsert: context?.unsettledProperties?.has("Tags") === true,
|
|
40972
|
-
beforeWrite: () => markUnsettled("Tags")
|
|
41287
|
+
beforeWrite: () => markUnsettled("Tags"),
|
|
41288
|
+
afterAdded: (keys) => {
|
|
41289
|
+
if (keys.length > 0) context?.markAttempted?.("Tags", keys);
|
|
41290
|
+
}
|
|
40973
41291
|
});
|
|
40974
41292
|
const newEncryption = properties["StreamEncryption"];
|
|
40975
41293
|
const oldEncryption = previousProperties["StreamEncryption"];
|
|
@@ -41031,10 +41349,13 @@ var KinesisStreamProvider = class {
|
|
|
41031
41349
|
}
|
|
41032
41350
|
if (toEnable.length > 0) {
|
|
41033
41351
|
this.logger.debug(`Enabling ${toEnable.length} shard-level metric(s) on ${physicalId}`);
|
|
41034
|
-
await this.getClient().send(new EnableEnhancedMonitoringCommand({
|
|
41352
|
+
const current = expandShardLevelMetrics((await this.getClient().send(new EnableEnhancedMonitoringCommand({
|
|
41035
41353
|
StreamName: physicalId,
|
|
41036
41354
|
ShardLevelMetrics: toEnable
|
|
41037
|
-
}));
|
|
41355
|
+
})))?.CurrentShardLevelMetrics ?? []);
|
|
41356
|
+
const before = new Set(Array.isArray(current) ? current : []);
|
|
41357
|
+
const added = toEnable.filter((metric) => !before.has(metric));
|
|
41358
|
+
if (added.length > 0) context?.markAttempted?.("DesiredShardLevelMetrics", added);
|
|
41038
41359
|
await this.waitForStreamActive(physicalId);
|
|
41039
41360
|
}
|
|
41040
41361
|
}
|
|
@@ -41201,6 +41522,13 @@ var KinesisStreamProvider = class {
|
|
|
41201
41522
|
StreamName: streamName,
|
|
41202
41523
|
Tags: tagsToAdd
|
|
41203
41524
|
}));
|
|
41525
|
+
let recordedKeys;
|
|
41526
|
+
try {
|
|
41527
|
+
recordedKeys = /* @__PURE__ */ new Set([...planTagDiff(void 0, oldTagsRaw).set.keys()]);
|
|
41528
|
+
} catch {
|
|
41529
|
+
recordedKeys = void 0;
|
|
41530
|
+
}
|
|
41531
|
+
unsettled.afterAdded?.(Object.keys(tagsToAdd).filter((key) => recordedKeys !== void 0 && !recordedKeys.has(key)));
|
|
41204
41532
|
this.logger.debug(`Added/updated ${Object.keys(tagsToAdd).length} tag(s) on Kinesis stream ${streamName}`);
|
|
41205
41533
|
}
|
|
41206
41534
|
}
|
|
@@ -41217,7 +41545,7 @@ var KinesisStreamProvider = class {
|
|
|
41217
41545
|
const secretDerived = mask(physicalId) !== physicalId;
|
|
41218
41546
|
warn(`Kinesis stream ${physicalId} has shard-level metrics enabled that neither cdkd's record nor the template declares (${undeclared.join(", ")}), so cdkd left them enabled while converging the unsettled DesiredShardLevelMetrics (CloudFormation never disables a metric it did not record). Another tool may have enabled them, or an earlier failed cdkd update may have; cdkd cannot tell which. If they should be off, disable them ` + (secretDerived ? `with DisableEnhancedMonitoring for those metrics.` : `with: aws kinesis disable-enhanced-monitoring --stream-name ${physicalId} --shard-level-metrics ${undeclared.join(" ")} (in the stream's region)`));
|
|
41219
41547
|
}
|
|
41220
|
-
async readUnsettled(physicalId, logicalId, resourceType, names, recordedProperties, desiredProperties) {
|
|
41548
|
+
async readUnsettled(physicalId, logicalId, resourceType, names, recordedProperties, desiredProperties, attemptedItems) {
|
|
41221
41549
|
const live = await this.readCurrentState(physicalId, logicalId, resourceType);
|
|
41222
41550
|
if (typeof live !== "object" || live === null) return live;
|
|
41223
41551
|
const out = { ...live };
|
|
@@ -41226,6 +41554,7 @@ var KinesisStreamProvider = class {
|
|
|
41226
41554
|
const expanded = expandShardLevelMetrics(bag?.["DesiredShardLevelMetrics"]);
|
|
41227
41555
|
return isUsableMetricsList(expanded) ? expanded : [];
|
|
41228
41556
|
}));
|
|
41557
|
+
for (const metric of attemptedItems?.get("DesiredShardLevelMetrics") ?? []) if (metric !== "ALL" && isUsableAttemptedName(metric)) named.add(metric);
|
|
41229
41558
|
const liveMetrics = expandShardLevelMetrics(out["DesiredShardLevelMetrics"]);
|
|
41230
41559
|
out["DesiredShardLevelMetrics"] = (Array.isArray(liveMetrics) ? liveMetrics : []).filter((metric) => typeof metric === "string" && named.has(metric));
|
|
41231
41560
|
}
|
|
@@ -41386,6 +41715,7 @@ var KinesisStreamConsumerProvider = class {
|
|
|
41386
41715
|
if (!consumer?.ConsumerARN || !consumer.ConsumerName) throw new ProvisioningError("RegisterStreamConsumer did not return ConsumerARN/ConsumerName", resourceType, logicalId);
|
|
41387
41716
|
const consumerArn = consumer.ConsumerARN;
|
|
41388
41717
|
createdArn = consumerArn;
|
|
41718
|
+
reportCreatedResource(logicalId, resourceType, consumerArn);
|
|
41389
41719
|
await this.waitForConsumerActive(consumerArn);
|
|
41390
41720
|
this.logger.debug(`Successfully registered Kinesis stream consumer ${logicalId}`);
|
|
41391
41721
|
return {
|
|
@@ -42259,6 +42589,7 @@ var PipesPipeProvider = class {
|
|
|
42259
42589
|
...Object.keys(tags).length > 0 && { Tags: tags }
|
|
42260
42590
|
}));
|
|
42261
42591
|
createdIdentity = pipeIdentityToken(name, created?.Arn, created?.CreationTime);
|
|
42592
|
+
reportCreatedResource(logicalId, resourceType, name, createdIdentity);
|
|
42262
42593
|
} catch (error) {
|
|
42263
42594
|
const cause = error instanceof Error ? error : void 0;
|
|
42264
42595
|
throw this.wrapCaughtError(mask, error, (text) => new ProvisioningError(`Failed to create Pipe ${logicalId}: ${text}`, resourceType, logicalId, void 0, cause));
|
|
@@ -42566,7 +42897,10 @@ var PipesPipeProvider = class {
|
|
|
42566
42897
|
try {
|
|
42567
42898
|
await this.getClient().send(new DeletePipeCommand({ Name: name }));
|
|
42568
42899
|
} catch (cleanupError) {
|
|
42569
|
-
if (cleanupError instanceof NotFoundException$6)
|
|
42900
|
+
if (cleanupError instanceof NotFoundException$6) {
|
|
42901
|
+
retractCreatedResource(logicalId, resourceType, name);
|
|
42902
|
+
return original;
|
|
42903
|
+
}
|
|
42570
42904
|
return orphaned(describeAwsFailure(cleanupError).summary);
|
|
42571
42905
|
}
|
|
42572
42906
|
let gone = false;
|
|
@@ -42592,10 +42926,12 @@ var PipesPipeProvider = class {
|
|
|
42592
42926
|
return orphaned("its delete did not complete (AWS reports a failed or rolled-back delete)");
|
|
42593
42927
|
}
|
|
42594
42928
|
if (gone) {
|
|
42929
|
+
retractCreatedResource(logicalId, resourceType, name);
|
|
42595
42930
|
original.message += " (cdkd deleted the pipe it had created, so nothing is left behind)";
|
|
42596
42931
|
return original;
|
|
42597
42932
|
}
|
|
42598
42933
|
if (sawDeleting) {
|
|
42934
|
+
retractCreatedResource(logicalId, resourceType, name);
|
|
42599
42935
|
original.message += " (cdkd started deleting the pipe it had created; a re-deploy may report the name in use until AWS finishes)";
|
|
42600
42936
|
return original;
|
|
42601
42937
|
}
|
|
@@ -42926,6 +43262,7 @@ var EFSProvider = class {
|
|
|
42926
43262
|
}))
|
|
42927
43263
|
});
|
|
42928
43264
|
fileSystemId = created.fileSystemId;
|
|
43265
|
+
reportCreatedResource(logicalId, resourceType, fileSystemId);
|
|
42929
43266
|
const available = await this.waitForFileSystemAvailable(fileSystemId, logicalId, resourceType, log);
|
|
42930
43267
|
const arn = created.arn ?? available.FileSystemArn;
|
|
42931
43268
|
await this.applyLifecyclePolicies(fileSystemId, properties["LifecyclePolicies"], log);
|
|
@@ -42947,6 +43284,7 @@ var EFSProvider = class {
|
|
|
42947
43284
|
try {
|
|
42948
43285
|
await this.getClient().send(new DeleteFileSystemCommand({ FileSystemId: fileSystemId }));
|
|
42949
43286
|
this.unconfirmedCreationTokens.delete(creationToken);
|
|
43287
|
+
retractCreatedResource(logicalId, resourceType, fileSystemId);
|
|
42950
43288
|
log.debug(`Rolled back partially-created EFS FileSystem ${fileSystemId}`);
|
|
42951
43289
|
} catch (cleanupError) {
|
|
42952
43290
|
fileSystemLeftBehind = true;
|
|
@@ -43124,6 +43462,7 @@ var EFSProvider = class {
|
|
|
43124
43462
|
}));
|
|
43125
43463
|
const mountTargetId = response.MountTargetId;
|
|
43126
43464
|
createdMountTargetId = mountTargetId;
|
|
43465
|
+
reportCreatedResource(logicalId, resourceType, mountTargetId);
|
|
43127
43466
|
log.debug(`Created EFS MountTarget ${logicalId}: ${mountTargetId}, waiting for available state`);
|
|
43128
43467
|
await this.waitForMountTargetAvailable(mountTargetId, logicalId, resourceType, log);
|
|
43129
43468
|
log.debug(`Successfully created EFS MountTarget ${logicalId}: ${mountTargetId}`);
|
|
@@ -43775,6 +44114,7 @@ var FSxFileSystemProvider = class {
|
|
|
43775
44114
|
throw markNonRetryable(new ProvisioningError(safeMsg`FSx answered the create of ${logicalId} with file system ${returnedId}, which ${createdAt === void 0 ? "carries no creation time" : "predates this create"}: the create token cdkd derives for this stack's file system is held by it, and it is NOT recorded in cdkd state. It is not one this deploy, or an interrupted earlier deploy of this stack, made: it was created under this token by an earlier cdkd version, or a completed deploy recorded it and cdkd later let go of it, and it may hold data, so cdkd neither records nor deletes it. Inspect it with: ${inspect} --file-system-ids ${returnedId} -- then import it into this stack, or delete it once you are sure its data is not needed, and deploy again.`, resourceType, logicalId));
|
|
43776
44115
|
}
|
|
43777
44116
|
fileSystemId = returnedId;
|
|
44117
|
+
reportCreatedResource(logicalId, resourceType, returnedId);
|
|
43778
44118
|
const fs = await this.waitForFileSystemAvailable(fileSystemId, logicalId, resourceType, context?.maskSecrets);
|
|
43779
44119
|
this.logger.debug(`Successfully created FSx FileSystem ${logicalId}: ${fileSystemId}`);
|
|
43780
44120
|
this.createTokenFirstSentAt.delete(clientRequestToken);
|
|
@@ -43786,6 +44126,7 @@ var FSxFileSystemProvider = class {
|
|
|
43786
44126
|
let survivorId;
|
|
43787
44127
|
if (fileSystemId !== void 0) try {
|
|
43788
44128
|
await this.getClient().send(new DeleteFileSystemCommand$1({ FileSystemId: fileSystemId }));
|
|
44129
|
+
retractCreatedResource(logicalId, resourceType, fileSystemId);
|
|
43789
44130
|
this.createTokenFirstSentAt.delete(clientRequestToken);
|
|
43790
44131
|
this.logger.warn(`Rolled back partially-created FSx FileSystem ${fileSystemId}`);
|
|
43791
44132
|
} catch (cleanupError) {
|
|
@@ -44712,11 +45053,11 @@ var FSxFileSystemProvider = class {
|
|
|
44712
45053
|
|
|
44713
45054
|
//#endregion
|
|
44714
45055
|
//#region src/provisioning/emr-configuration.ts
|
|
44715
|
-
function isRecord(value) {
|
|
45056
|
+
function isRecord$1(value) {
|
|
44716
45057
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
44717
45058
|
}
|
|
44718
45059
|
function toSdkConfiguration(raw) {
|
|
44719
|
-
if (!isRecord(raw)) return raw;
|
|
45060
|
+
if (!isRecord$1(raw)) return raw;
|
|
44720
45061
|
const { ConfigurationProperties, Configurations, ...rest } = raw;
|
|
44721
45062
|
return {
|
|
44722
45063
|
...rest,
|
|
@@ -44733,9 +45074,9 @@ function toSdkStepConfigs(value) {
|
|
|
44733
45074
|
if (value === void 0) return void 0;
|
|
44734
45075
|
if (!Array.isArray(value)) return value;
|
|
44735
45076
|
return value.map((step) => {
|
|
44736
|
-
if (!isRecord(step)) return step;
|
|
45077
|
+
if (!isRecord$1(step)) return step;
|
|
44737
45078
|
const hadoopJarStep = step["HadoopJarStep"];
|
|
44738
|
-
if (!isRecord(hadoopJarStep) || hadoopJarStep["StepProperties"] === void 0) return step;
|
|
45079
|
+
if (!isRecord$1(hadoopJarStep) || hadoopJarStep["StepProperties"] === void 0) return step;
|
|
44739
45080
|
const { StepProperties, ...restHadoopJarStep } = hadoopJarStep;
|
|
44740
45081
|
return {
|
|
44741
45082
|
...step,
|
|
@@ -44750,7 +45091,7 @@ function toSdkInstanceTypeConfigs(value) {
|
|
|
44750
45091
|
if (value === void 0) return void 0;
|
|
44751
45092
|
if (!Array.isArray(value)) return value;
|
|
44752
45093
|
return value.map((instanceTypeConfig) => {
|
|
44753
|
-
if (!isRecord(instanceTypeConfig) || instanceTypeConfig["Configurations"] === void 0) return instanceTypeConfig;
|
|
45094
|
+
if (!isRecord$1(instanceTypeConfig) || instanceTypeConfig["Configurations"] === void 0) return instanceTypeConfig;
|
|
44754
45095
|
return {
|
|
44755
45096
|
...instanceTypeConfig,
|
|
44756
45097
|
Configurations: toSdkConfigurations(instanceTypeConfig["Configurations"])
|
|
@@ -44897,6 +45238,7 @@ var EMRInstanceGroupConfigProvider = class {
|
|
|
44897
45238
|
const groupId = response.InstanceGroupIds?.[0];
|
|
44898
45239
|
if (groupId) groupsCreatedByThisProcess.add(groupId);
|
|
44899
45240
|
createdGroupId = groupId;
|
|
45241
|
+
reportCreatedResource(logicalId, resourceType, groupId ?? "");
|
|
44900
45242
|
const replayWindow = replayedSendWindow(response, attemptStartMs);
|
|
44901
45243
|
if (replayWindow !== void 0 && group.InstanceRole === "TASK") await reportOrphans(replayWindow);
|
|
44902
45244
|
if (!groupId) throw new ProvisioningError(`EMR AddInstanceGroups for ${logicalId} returned no instance group id`, resourceType, logicalId);
|
|
@@ -44923,6 +45265,7 @@ var EMRInstanceGroupConfigProvider = class {
|
|
|
44923
45265
|
}]
|
|
44924
45266
|
}));
|
|
44925
45267
|
log.warn(safeMsg`Scaled partially-created EMR TASK instance group ${logicalId} (${leftBehindGroupId}) to 0; EMR has no delete API, so the empty group stays on cluster ${log.value(jobFlowId)} until it terminates`);
|
|
45268
|
+
retractCreatedResource(logicalId, resourceType, leftBehindGroupId);
|
|
44926
45269
|
leftBehindGroupId = void 0;
|
|
44927
45270
|
} catch (cleanupError) {
|
|
44928
45271
|
const cleanupHead = safeMsg`Failed to scale partially-created EMR TASK instance group ${logicalId} (${leftBehindGroupId}) to 0: `;
|
|
@@ -45272,6 +45615,7 @@ var EMRInstanceFleetConfigProvider = class {
|
|
|
45272
45615
|
const fleetId = response.InstanceFleetId;
|
|
45273
45616
|
if (fleetId) fleetsCreatedByThisProcess.add(fleetId);
|
|
45274
45617
|
createdFleetId = fleetId;
|
|
45618
|
+
reportCreatedResource(logicalId, resourceType, fleetId ?? "");
|
|
45275
45619
|
const replayWindow = replayedSendWindow(response, attemptStartMs);
|
|
45276
45620
|
if (replayWindow !== void 0 && fleet.InstanceFleetType === "TASK") await reportOrphans(replayWindow);
|
|
45277
45621
|
if (!fleetId) throw new ProvisioningError(`EMR AddInstanceFleet for ${logicalId} returned no instance fleet id`, resourceType, logicalId);
|
|
@@ -45763,6 +46107,7 @@ var EMRClusterProvider = class {
|
|
|
45763
46107
|
}
|
|
45764
46108
|
clusterId = response.JobFlowId;
|
|
45765
46109
|
if (clusterId) clustersCreatedByThisProcess.add(clusterId);
|
|
46110
|
+
reportCreatedResource(logicalId, resourceType, clusterId ?? "");
|
|
45766
46111
|
const replayWindow = replayedSendWindow(response, attemptStartMs);
|
|
45767
46112
|
if (replayWindow !== void 0) await reportOrphans(replayWindow);
|
|
45768
46113
|
if (!clusterId) throw new ProvisioningError(`EMR RunJobFlow for ${logicalId} returned no JobFlowId`, resourceType, logicalId);
|
|
@@ -45780,6 +46125,7 @@ var EMRClusterProvider = class {
|
|
|
45780
46125
|
TerminationProtected: false
|
|
45781
46126
|
}));
|
|
45782
46127
|
await this.getClient().send(new TerminateJobFlowsCommand({ JobFlowIds: [clusterId] }));
|
|
46128
|
+
retractCreatedResource(logicalId, resourceType, clusterId);
|
|
45783
46129
|
this.logger.warn(`Rolled back partially-created EMR Cluster ${clusterId}`);
|
|
45784
46130
|
} catch (cleanupError) {
|
|
45785
46131
|
survivorId = clusterId;
|
|
@@ -46521,6 +46867,9 @@ function liveEncryptionAsCfn(live) {
|
|
|
46521
46867
|
}
|
|
46522
46868
|
const ENCRYPTION_POLL_INTERVAL_MS = 5e3;
|
|
46523
46869
|
const ENCRYPTION_POLL_MAX_ATTEMPTS = 120;
|
|
46870
|
+
const ACTIVE_POLL_INTERVAL_MS = 5e3;
|
|
46871
|
+
const ACTIVE_POLL_MAX_ATTEMPTS = 360;
|
|
46872
|
+
const ACTIVE_DEADLINE_MARGIN_MS = 2e3;
|
|
46524
46873
|
const terminalEncryptionFailures = /* @__PURE__ */ new WeakSet();
|
|
46525
46874
|
function isReadableTagList(value) {
|
|
46526
46875
|
if (value === void 0 || value === null) return true;
|
|
@@ -46736,9 +47085,10 @@ var FirehoseProvider = class {
|
|
|
46736
47085
|
const response = await this.getCreateClient().send(new CreateDeliveryStreamCommand(input));
|
|
46737
47086
|
const physicalId = deliveryStreamName || input.DeliveryStreamName || response.DeliveryStreamARN?.split("/").pop() || "";
|
|
46738
47087
|
createdStreamName = physicalId;
|
|
47088
|
+
reportCreatedResource(logicalId, resourceType, physicalId);
|
|
46739
47089
|
const arn = response.DeliveryStreamARN;
|
|
46740
47090
|
this.logger.debug(`Successfully created Firehose delivery stream ${logicalId}: ${physicalId}`);
|
|
46741
|
-
await this.waitForActive(physicalId, logicalId);
|
|
47091
|
+
await this.waitForActive(physicalId, logicalId, resourceType, maskerOrIdentity(context?.maskSecrets));
|
|
46742
47092
|
return {
|
|
46743
47093
|
physicalId,
|
|
46744
47094
|
attributes: { Arn: arn }
|
|
@@ -47437,18 +47787,59 @@ var FirehoseProvider = class {
|
|
|
47437
47787
|
}
|
|
47438
47788
|
return null;
|
|
47439
47789
|
}
|
|
47440
|
-
async waitForActive(streamName, logicalId) {
|
|
47441
|
-
const
|
|
47442
|
-
|
|
47443
|
-
|
|
47444
|
-
|
|
47445
|
-
|
|
47446
|
-
|
|
47790
|
+
async waitForActive(streamName, logicalId, resourceType, mask) {
|
|
47791
|
+
const watch = startInterruptWatch(`Firehose ${logicalId} create`);
|
|
47792
|
+
try {
|
|
47793
|
+
let last;
|
|
47794
|
+
let deadlineNear = false;
|
|
47795
|
+
for (let attempt = 1; attempt <= ACTIVE_POLL_MAX_ATTEMPTS; attempt++) {
|
|
47796
|
+
if (watch.isInterrupted()) throw watch.onInterrupted();
|
|
47797
|
+
if (enclosingDeadlineRemainingMs() <= ACTIVE_DEADLINE_MARGIN_MS) {
|
|
47798
|
+
deadlineNear = true;
|
|
47799
|
+
break;
|
|
47800
|
+
}
|
|
47801
|
+
const resp = await this.describeBeforeDeadline(streamName);
|
|
47802
|
+
if (resp === "deadline") {
|
|
47803
|
+
deadlineNear = true;
|
|
47804
|
+
break;
|
|
47805
|
+
}
|
|
47806
|
+
const description = resp.DeliveryStreamDescription;
|
|
47807
|
+
last = description?.DeliveryStreamStatus;
|
|
47808
|
+
if (last === "ACTIVE") {
|
|
47809
|
+
this.logger.debug(`Firehose ${logicalId} is ACTIVE`);
|
|
47810
|
+
return;
|
|
47811
|
+
}
|
|
47812
|
+
if (last !== void 0 && last.endsWith("_FAILED")) {
|
|
47813
|
+
const failure = description?.FailureDescription;
|
|
47814
|
+
throw markNonRetryable(new ProvisioningError(`Firehose delivery stream ${logicalId} did not become ACTIVE: AWS reports ${last}` + (failure ? ` (${mask(`${failure.Type ?? ""}: ${failure.Details ?? ""}`)})` : ""), resourceType, logicalId, streamName));
|
|
47815
|
+
}
|
|
47816
|
+
this.logger.debug(`Firehose ${logicalId} status: ${last} (attempt ${attempt}/${ACTIVE_POLL_MAX_ATTEMPTS})`);
|
|
47817
|
+
if (watch.isInterrupted()) throw watch.onInterrupted();
|
|
47818
|
+
if (enclosingDeadlineRemainingMs() <= 7e3) {
|
|
47819
|
+
deadlineNear = true;
|
|
47820
|
+
break;
|
|
47821
|
+
}
|
|
47822
|
+
await new Promise((resolve) => setTimeout(resolve, ACTIVE_POLL_INTERVAL_MS));
|
|
47447
47823
|
}
|
|
47448
|
-
|
|
47449
|
-
|
|
47824
|
+
throw markNonRetryable(new ProvisioningError((deadlineNear ? `The resource timeout would expire while waiting for Firehose delivery stream ${logicalId} to become ACTIVE ` : `Timed out waiting for Firehose delivery stream ${logicalId} to become ACTIVE `) + `(last status: ${last ?? "none reported"})`, resourceType, logicalId, streamName));
|
|
47825
|
+
} finally {
|
|
47826
|
+
watch.dispose();
|
|
47827
|
+
}
|
|
47828
|
+
}
|
|
47829
|
+
async describeBeforeDeadline(streamName) {
|
|
47830
|
+
const command = new DescribeDeliveryStreamCommand({ DeliveryStreamName: streamName });
|
|
47831
|
+
const remaining = enclosingDeadlineRemainingMs();
|
|
47832
|
+
if (!Number.isFinite(remaining)) return this.getClient().send(command);
|
|
47833
|
+
const abort = new AbortController();
|
|
47834
|
+
const timer = setTimeout(() => abort.abort(), Math.max(0, remaining - ACTIVE_DEADLINE_MARGIN_MS));
|
|
47835
|
+
try {
|
|
47836
|
+
return await this.getClient().send(command, { abortSignal: abort.signal });
|
|
47837
|
+
} catch (error) {
|
|
47838
|
+
if (abort.signal.aborted) return "deadline";
|
|
47839
|
+
throw error;
|
|
47840
|
+
} finally {
|
|
47841
|
+
clearTimeout(timer);
|
|
47450
47842
|
}
|
|
47451
|
-
this.logger.warn(`Firehose ${logicalId} did not reach ACTIVE after ${maxAttempts} attempts`);
|
|
47452
47843
|
}
|
|
47453
47844
|
};
|
|
47454
47845
|
function pickDefinedDeep(input) {
|
|
@@ -47576,6 +47967,77 @@ function resolveCloudWatchLogsPair(properties) {
|
|
|
47576
47967
|
roleArn: desiredRole
|
|
47577
47968
|
};
|
|
47578
47969
|
}
|
|
47970
|
+
function readListBlock(raw, path) {
|
|
47971
|
+
if (raw == null) return { kind: "absent" };
|
|
47972
|
+
try {
|
|
47973
|
+
return {
|
|
47974
|
+
kind: "list",
|
|
47975
|
+
value: requireConfigArray(raw, path)
|
|
47976
|
+
};
|
|
47977
|
+
} catch (error) {
|
|
47978
|
+
return {
|
|
47979
|
+
kind: "unusable",
|
|
47980
|
+
detail: describeAwsFailure(error).detail
|
|
47981
|
+
};
|
|
47982
|
+
}
|
|
47983
|
+
}
|
|
47984
|
+
function listOf$1(read) {
|
|
47985
|
+
return read.kind === "list" ? read.value : void 0;
|
|
47986
|
+
}
|
|
47987
|
+
function retainPreviousLists(desired, previous, keys, live) {
|
|
47988
|
+
const out = Object.fromEntries(Object.entries(desired).filter(([key]) => !keys.includes(key)));
|
|
47989
|
+
for (const key of keys) {
|
|
47990
|
+
const prev = previous[key];
|
|
47991
|
+
if (Array.isArray(prev)) out[key] = structuredClone(prev);
|
|
47992
|
+
else if (prev != null && Array.isArray(live?.[key])) out[key] = structuredClone(live[key]);
|
|
47993
|
+
}
|
|
47994
|
+
return out;
|
|
47995
|
+
}
|
|
47996
|
+
const UNORDERED_LIST_BLOCKS = ["AdvancedEventSelectors", "AggregationConfigurations"];
|
|
47997
|
+
function setKey(value) {
|
|
47998
|
+
if (value === void 0) return "undefined";
|
|
47999
|
+
if (Array.isArray(value)) return [
|
|
48000
|
+
"[",
|
|
48001
|
+
value.map(setKey).sort().join(","),
|
|
48002
|
+
"]"
|
|
48003
|
+
].join("");
|
|
48004
|
+
if (value !== null && typeof value === "object") {
|
|
48005
|
+
const bag = value;
|
|
48006
|
+
return [
|
|
48007
|
+
"{",
|
|
48008
|
+
Object.keys(bag).filter((k) => bag[k] !== void 0).sort().map((k) => [JSON.stringify(k), setKey(bag[k])].join(":")).join(","),
|
|
48009
|
+
"}"
|
|
48010
|
+
].join("");
|
|
48011
|
+
}
|
|
48012
|
+
return JSON.stringify(value) ?? "null";
|
|
48013
|
+
}
|
|
48014
|
+
function nonEmptyListOf(read) {
|
|
48015
|
+
return read.kind === "list" && read.value.length > 0 ? read.value : void 0;
|
|
48016
|
+
}
|
|
48017
|
+
function eventSelectorRequest(basic, advanced) {
|
|
48018
|
+
const hasBasic = basic !== void 0 && basic.length > 0;
|
|
48019
|
+
if (advanced !== void 0 && advanced.length > 0) return {
|
|
48020
|
+
members: {
|
|
48021
|
+
AdvancedEventSelectors: advanced,
|
|
48022
|
+
...hasBasic ? { EventSelectors: basic } : {}
|
|
48023
|
+
},
|
|
48024
|
+
isReset: false
|
|
48025
|
+
};
|
|
48026
|
+
if (hasBasic) return {
|
|
48027
|
+
members: { EventSelectors: basic },
|
|
48028
|
+
isReset: false
|
|
48029
|
+
};
|
|
48030
|
+
return {
|
|
48031
|
+
members: { EventSelectors: [...DEFAULT_EVENT_SELECTORS] },
|
|
48032
|
+
isReset: true
|
|
48033
|
+
};
|
|
48034
|
+
}
|
|
48035
|
+
function advancedSelectorsToCfn(selectors) {
|
|
48036
|
+
return selectors.map((s) => ({
|
|
48037
|
+
...s.Name !== void 0 && { Name: s.Name },
|
|
48038
|
+
FieldSelectors: (s.FieldSelectors ?? []).map((f) => Object.fromEntries(Object.entries(f).filter(([, v]) => v !== void 0)))
|
|
48039
|
+
}));
|
|
48040
|
+
}
|
|
47579
48041
|
function describeValue(value) {
|
|
47580
48042
|
if (value === null) return "null";
|
|
47581
48043
|
if (value === void 0) return "nothing";
|
|
@@ -47625,7 +48087,9 @@ var CloudTrailProvider = class {
|
|
|
47625
48087
|
"SnsTopicName",
|
|
47626
48088
|
"EventSelectors",
|
|
47627
48089
|
"InsightSelectors",
|
|
47628
|
-
"IsOrganizationTrail"
|
|
48090
|
+
"IsOrganizationTrail",
|
|
48091
|
+
"AdvancedEventSelectors",
|
|
48092
|
+
"AggregationConfigurations"
|
|
47629
48093
|
])]]);
|
|
47630
48094
|
getClient() {
|
|
47631
48095
|
if (!this.client) {
|
|
@@ -47662,6 +48126,9 @@ var CloudTrailProvider = class {
|
|
|
47662
48126
|
const isOrganizationTrail = properties["IsOrganizationTrail"];
|
|
47663
48127
|
const eventSelectors = properties["EventSelectors"];
|
|
47664
48128
|
const insightSelectors = properties["InsightSelectors"];
|
|
48129
|
+
const advancedEventSelectors = properties["AdvancedEventSelectors"] == null ? void 0 : requireConfigArray(properties["AdvancedEventSelectors"], "AWS::CloudTrail::Trail AdvancedEventSelectors", replayWarn(this.logger, context));
|
|
48130
|
+
const aggregationConfigurations = properties["AggregationConfigurations"] == null ? void 0 : requireConfigArray(properties["AggregationConfigurations"], "AWS::CloudTrail::Trail AggregationConfigurations", replayWarn(this.logger, context));
|
|
48131
|
+
const skippedOnReplay = [...properties["AdvancedEventSelectors"] != null && advancedEventSelectors === void 0 ? ["AdvancedEventSelectors"] : [], ...properties["AggregationConfigurations"] != null && aggregationConfigurations === void 0 ? ["AggregationConfigurations"] : []];
|
|
47665
48132
|
let trailCreated = false;
|
|
47666
48133
|
let createdTrailArn;
|
|
47667
48134
|
try {
|
|
@@ -47685,11 +48152,20 @@ var CloudTrailProvider = class {
|
|
|
47685
48152
|
trailCreated = true;
|
|
47686
48153
|
const trailArn = result.TrailARN;
|
|
47687
48154
|
createdTrailArn = result.TrailARN;
|
|
47688
|
-
if (
|
|
48155
|
+
if (createdTrailArn) reportCreatedResource(logicalId, resourceType, createdTrailArn);
|
|
48156
|
+
const basicForCreate = eventSelectors && eventSelectors.length > 0 ? eventSelectors : void 0;
|
|
48157
|
+
if (basicForCreate || advancedEventSelectors && advancedEventSelectors.length > 0) {
|
|
47689
48158
|
this.logger.debug(`Setting event selectors for CloudTrail Trail ${logicalId}`);
|
|
47690
48159
|
await this.getClient().send(new PutEventSelectorsCommand({
|
|
47691
48160
|
TrailName: trailArn,
|
|
47692
|
-
|
|
48161
|
+
...eventSelectorRequest(basicForCreate, advancedEventSelectors).members
|
|
48162
|
+
}));
|
|
48163
|
+
}
|
|
48164
|
+
if (aggregationConfigurations && aggregationConfigurations.length > 0) {
|
|
48165
|
+
this.logger.debug(safeMsg`Setting aggregation configurations for CloudTrail Trail ${logicalId}`);
|
|
48166
|
+
await this.getClient().send(new PutEventConfigurationCommand({
|
|
48167
|
+
TrailName: trailArn,
|
|
48168
|
+
AggregationConfigurations: aggregationConfigurations
|
|
47693
48169
|
}));
|
|
47694
48170
|
}
|
|
47695
48171
|
if (insightSelectors && insightSelectors.length > 0) {
|
|
@@ -47706,7 +48182,8 @@ var CloudTrailProvider = class {
|
|
|
47706
48182
|
this.logger.debug(`Successfully created CloudTrail Trail ${logicalId}: ${trailArn}`);
|
|
47707
48183
|
return {
|
|
47708
48184
|
physicalId: trailArn,
|
|
47709
|
-
attributes: { Arn: trailArn }
|
|
48185
|
+
attributes: { Arn: trailArn },
|
|
48186
|
+
...skippedOnReplay.length > 0 && { effectiveProperties: retainPreviousLists(properties, {}, skippedOnReplay) }
|
|
47710
48187
|
};
|
|
47711
48188
|
} catch (error) {
|
|
47712
48189
|
if (trailCreated) markAuxiliaryFailure(error, logicalId);
|
|
@@ -47717,6 +48194,7 @@ var CloudTrailProvider = class {
|
|
|
47717
48194
|
}
|
|
47718
48195
|
}
|
|
47719
48196
|
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
48197
|
+
const desiredProperties = properties;
|
|
47720
48198
|
properties = withRemovalDefaults(this.removalDefaults, resourceType, properties, previousProperties, context);
|
|
47721
48199
|
this.logger.debug(`Updating CloudTrail Trail ${logicalId}: ${physicalId}`);
|
|
47722
48200
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
@@ -47733,6 +48211,7 @@ var CloudTrailProvider = class {
|
|
|
47733
48211
|
const kmsKeyId = clearOnUpdateRemoval(emptyToUndefined(properties["KMSKeyId"]), emptyToUndefined(previousProperties["KMSKeyId"]), "");
|
|
47734
48212
|
const snsTopicName = clearOnUpdateRemoval(emptyToUndefined(properties["SnsTopicName"]), emptyToUndefined(previousProperties["SnsTopicName"]), "");
|
|
47735
48213
|
const isOrganizationTrail = properties["IsOrganizationTrail"];
|
|
48214
|
+
const appliedBeforeFailure = [];
|
|
47736
48215
|
try {
|
|
47737
48216
|
await this.getClient().send(new UpdateTrailCommand({
|
|
47738
48217
|
Name: physicalId,
|
|
@@ -47747,36 +48226,61 @@ var CloudTrailProvider = class {
|
|
|
47747
48226
|
SnsTopicName: snsTopicName,
|
|
47748
48227
|
IsOrganizationTrail: isOrganizationTrail
|
|
47749
48228
|
}));
|
|
47750
|
-
const
|
|
47751
|
-
|
|
47752
|
-
|
|
47753
|
-
|
|
47754
|
-
|
|
47755
|
-
|
|
47756
|
-
eventSelectorsUnusable = true;
|
|
47757
|
-
this.logger.warn(`${describeAwsFailure(error).detail} The trail's existing event selectors are left untouched for this update rather than reset to the AWS default.`);
|
|
47758
|
-
}
|
|
48229
|
+
const basicRead = readListBlock(properties["EventSelectors"], "AWS::CloudTrail::Trail EventSelectors");
|
|
48230
|
+
const advancedRead = readListBlock(properties["AdvancedEventSelectors"], "AWS::CloudTrail::Trail AdvancedEventSelectors");
|
|
48231
|
+
for (const read of [basicRead, advancedRead]) if (read.kind === "unusable") this.logger.warn(safeMsg`${read.detail} The trail's existing event selectors are left untouched for this update rather than reset to the AWS default.`);
|
|
48232
|
+
const selectorsUnusable = basicRead.kind === "unusable" || advancedRead.kind === "unusable";
|
|
48233
|
+
const newEventSelectors = listOf$1(basicRead);
|
|
48234
|
+
const newAdvancedSelectors = listOf$1(advancedRead);
|
|
47759
48235
|
const oldEventSelectors = previousProperties["EventSelectors"];
|
|
47760
|
-
|
|
47761
|
-
|
|
47762
|
-
|
|
48236
|
+
const oldAdvancedSelectors = previousProperties["AdvancedEventSelectors"];
|
|
48237
|
+
const hadAdvancedSelectors = Array.isArray(oldAdvancedSelectors) && oldAdvancedSelectors.length > 0;
|
|
48238
|
+
const aggregationRead = readListBlock(properties["AggregationConfigurations"], "AWS::CloudTrail::Trail AggregationConfigurations");
|
|
48239
|
+
if (aggregationRead.kind === "unusable") this.logger.warn(safeMsg`${aggregationRead.detail} The trail's existing aggregation configurations are left untouched for this update rather than cleared.`);
|
|
48240
|
+
const newAggregation = listOf$1(aggregationRead);
|
|
48241
|
+
const aggregationChanged = aggregationRead.kind !== "unusable" && setKey(newAggregation) !== setKey(previousProperties["AggregationConfigurations"]);
|
|
48242
|
+
const aggregationCleared = aggregationChanged && nonEmptyListOf(aggregationRead) === void 0;
|
|
48243
|
+
const putAggregation = async () => {
|
|
48244
|
+
this.logger.debug(safeMsg`Updating aggregation configurations for CloudTrail Trail ${logicalId}`);
|
|
48245
|
+
await this.getClient().send(new PutEventConfigurationCommand({
|
|
48246
|
+
TrailName: physicalId,
|
|
48247
|
+
AggregationConfigurations: newAggregation ?? []
|
|
48248
|
+
}));
|
|
48249
|
+
};
|
|
48250
|
+
if (aggregationCleared) {
|
|
48251
|
+
await putAggregation();
|
|
48252
|
+
appliedBeforeFailure.push("AggregationConfigurations was cleared");
|
|
48253
|
+
}
|
|
48254
|
+
if (!selectorsUnusable && (JSON.stringify(newEventSelectors) !== JSON.stringify(oldEventSelectors) || setKey(newAdvancedSelectors) !== setKey(oldAdvancedSelectors))) {
|
|
48255
|
+
let basicToSend = newEventSelectors;
|
|
48256
|
+
let advancedToSend = newAdvancedSelectors;
|
|
48257
|
+
if (context?.desiredFromAwsReadback === true && nonEmptyListOf(basicRead) !== void 0 && nonEmptyListOf(advancedRead) !== void 0) {
|
|
48258
|
+
if (JSON.stringify(newEventSelectors) === JSON.stringify(oldEventSelectors)) basicToSend = void 0;
|
|
48259
|
+
else if (setKey(newAdvancedSelectors) === setKey(oldAdvancedSelectors)) advancedToSend = void 0;
|
|
48260
|
+
}
|
|
48261
|
+
const { members, isReset: isRemoval } = eventSelectorRequest(basicToSend, advancedToSend);
|
|
47763
48262
|
this.logger.debug(isRemoval ? `Resetting event selectors to the AWS default for CloudTrail Trail ${logicalId}` : `Updating event selectors for CloudTrail Trail ${logicalId}`);
|
|
47764
48263
|
try {
|
|
47765
48264
|
await this.getClient().send(new PutEventSelectorsCommand({
|
|
47766
48265
|
TrailName: physicalId,
|
|
47767
|
-
|
|
48266
|
+
...members
|
|
47768
48267
|
}));
|
|
48268
|
+
appliedBeforeFailure.push("the event selectors were updated");
|
|
47769
48269
|
} catch (error) {
|
|
47770
48270
|
const failure = describeAwsFailure(error);
|
|
47771
48271
|
const message = withoutTrailIdentifiers(failure.detail, physicalId);
|
|
47772
48272
|
const errorClass = error instanceof Error ? error.name : "";
|
|
47773
|
-
if (!isRemoval || ACCESS_DENIAL_CLASS.test(errorClass) || !ADVANCED_SELECTOR_PHRASE.test(message)) throw error;
|
|
48273
|
+
if (!isRemoval || hadAdvancedSelectors || ACCESS_DENIAL_CLASS.test(errorClass) || !ADVANCED_SELECTOR_PHRASE.test(message)) throw error;
|
|
47774
48274
|
const m = maskerOrIdentity(context?.maskSecrets);
|
|
47775
48275
|
const head = `CloudTrail Trail ${logicalId}: skipping the EventSelectors reset — the trail is using AdvancedEventSelectors, which AWS manages through a separate API, so there are no basic event selectors to clear (`;
|
|
47776
48276
|
if (failure.redacted) this.logger.debug(m(`${head}${m(failure.detail)})`));
|
|
47777
48277
|
this.logger.warn(m(`${head}${failure.redacted ? failure.summary : failure.detail})`));
|
|
47778
48278
|
}
|
|
47779
48279
|
}
|
|
48280
|
+
if (aggregationChanged && !aggregationCleared) {
|
|
48281
|
+
await putAggregation();
|
|
48282
|
+
appliedBeforeFailure.push("AggregationConfigurations was updated");
|
|
48283
|
+
}
|
|
47780
48284
|
const newInsightSelectors = properties["InsightSelectors"];
|
|
47781
48285
|
const oldInsightSelectors = previousProperties["InsightSelectors"];
|
|
47782
48286
|
if (JSON.stringify(newInsightSelectors) !== JSON.stringify(oldInsightSelectors)) {
|
|
@@ -47798,13 +48302,19 @@ var CloudTrailProvider = class {
|
|
|
47798
48302
|
}
|
|
47799
48303
|
await this.applyTagDiff(physicalId, resourceType, logicalId, previousProperties["Tags"], properties["Tags"]);
|
|
47800
48304
|
this.logger.debug(`Successfully updated CloudTrail Trail ${logicalId}`);
|
|
47801
|
-
|
|
48305
|
+
const skipped = [...selectorsUnusable ? ["EventSelectors", "AdvancedEventSelectors"] : [], ...aggregationRead.kind === "unusable" ? ["AggregationConfigurations"] : []];
|
|
48306
|
+
if (skipped.length === 0) return {
|
|
47802
48307
|
physicalId,
|
|
47803
48308
|
wasReplaced: false
|
|
47804
48309
|
};
|
|
48310
|
+
return {
|
|
48311
|
+
physicalId,
|
|
48312
|
+
wasReplaced: false,
|
|
48313
|
+
effectiveProperties: retainPreviousLists(desiredProperties, previousProperties, skipped, skipped.some((key) => previousProperties[key] != null && !Array.isArray(previousProperties[key])) ? await this.readLiveForRecord(physicalId, resourceType) : void 0)
|
|
48314
|
+
};
|
|
47805
48315
|
} catch (error) {
|
|
47806
48316
|
const cause = error instanceof Error ? error : void 0;
|
|
47807
|
-
throw this.wrapCaughtError(context?.maskSecrets, error, (text) => new ProvisioningError(`Failed to update CloudTrail Trail ${logicalId}: ${text}
|
|
48317
|
+
throw this.wrapCaughtError(context?.maskSecrets, error, (text) => new ProvisioningError(`Failed to update CloudTrail Trail ${logicalId}: ${text}` + (appliedBeforeFailure.length > 0 ? ` (selector/aggregation writes already applied before this failure: ${appliedBeforeFailure.join("; ")})` : ""), resourceType, logicalId, physicalId, cause));
|
|
47808
48318
|
}
|
|
47809
48319
|
}
|
|
47810
48320
|
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
@@ -47834,6 +48344,19 @@ var CloudTrailProvider = class {
|
|
|
47834
48344
|
throw stripped ? markDeleteStarted(notGone) : notGone;
|
|
47835
48345
|
}
|
|
47836
48346
|
}
|
|
48347
|
+
async readLiveForRecord(physicalId, resourceType) {
|
|
48348
|
+
try {
|
|
48349
|
+
const live = await this.readCurrentState(physicalId, "", resourceType);
|
|
48350
|
+
return live !== void 0 && live !== RESOURCE_NOT_FOUND ? live : void 0;
|
|
48351
|
+
} catch (error) {
|
|
48352
|
+
this.logger.debug(safeMsg`CloudTrail read-back for the record failed: ${describeAwsFailure(error).detail}`);
|
|
48353
|
+
return;
|
|
48354
|
+
}
|
|
48355
|
+
}
|
|
48356
|
+
getDriftUnorderedPaths(resourceType) {
|
|
48357
|
+
if (resourceType !== "AWS::CloudTrail::Trail") return [];
|
|
48358
|
+
return [...UNORDERED_LIST_BLOCKS];
|
|
48359
|
+
}
|
|
47837
48360
|
getAttribute(_physicalId, _resourceType, attributeName) {
|
|
47838
48361
|
return Promise.resolve(attributeName);
|
|
47839
48362
|
}
|
|
@@ -47892,7 +48415,9 @@ var CloudTrailProvider = class {
|
|
|
47892
48415
|
} catch {}
|
|
47893
48416
|
try {
|
|
47894
48417
|
const sel = await this.getClient().send(new GetEventSelectorsCommand({ TrailName: physicalId }));
|
|
47895
|
-
|
|
48418
|
+
const hasAdvanced = Array.isArray(sel.AdvancedEventSelectors) && sel.AdvancedEventSelectors.length > 0;
|
|
48419
|
+
if (!hasAdvanced) result["EventSelectors"] = (sel.EventSelectors ?? []).map((es) => es);
|
|
48420
|
+
result["AdvancedEventSelectors"] = hasAdvanced ? advancedSelectorsToCfn(sel.AdvancedEventSelectors ?? []) : [];
|
|
47896
48421
|
} catch {}
|
|
47897
48422
|
let insightSelectors = [];
|
|
47898
48423
|
try {
|
|
@@ -47907,6 +48432,14 @@ var CloudTrailProvider = class {
|
|
|
47907
48432
|
this.logger.debug(`CloudTrail ListTags(${trail.TrailARN}) failed: ${describeAwsFailure(err).detail}`);
|
|
47908
48433
|
}
|
|
47909
48434
|
result["Tags"] = tags;
|
|
48435
|
+
try {
|
|
48436
|
+
result["AggregationConfigurations"] = ((await this.getClient().send(new GetEventConfigurationCommand({ TrailName: physicalId }))).AggregationConfigurations ?? []).map((a) => ({
|
|
48437
|
+
...a.EventCategory !== void 0 && { EventCategory: a.EventCategory },
|
|
48438
|
+
...a.Templates !== void 0 && { Templates: a.Templates }
|
|
48439
|
+
}));
|
|
48440
|
+
} catch (err) {
|
|
48441
|
+
this.logger.debug(safeMsg`CloudTrail GetEventConfiguration(${physicalId}) failed: ${describeAwsFailure(err).detail}`);
|
|
48442
|
+
}
|
|
47910
48443
|
return result;
|
|
47911
48444
|
}
|
|
47912
48445
|
async import(input) {
|
|
@@ -48178,6 +48711,7 @@ var CodeBuildProvider = class {
|
|
|
48178
48711
|
const projectName = result.project.name;
|
|
48179
48712
|
const projectArn = result.project.arn;
|
|
48180
48713
|
createdName = projectName;
|
|
48714
|
+
reportCreatedResource(logicalId, resourceType, createdName);
|
|
48181
48715
|
if (visibilityRead.kind === "usable" && (visibilityRead.visibility !== DEFAULT_PROJECT_VISIBILITY || visibilityRead.resourceAccessRole !== void 0)) await this.applyVisibility(projectArn, visibilityRead);
|
|
48182
48716
|
this.logger.debug(`Successfully created CodeBuild Project ${logicalId}: ${projectName}`);
|
|
48183
48717
|
return {
|
|
@@ -48599,6 +49133,7 @@ var CodeCommitRepositoryProvider = class {
|
|
|
48599
49133
|
if (!metadata?.repositoryName) throw new Error("CreateRepository did not return repository metadata");
|
|
48600
49134
|
const createdName = metadata.repositoryName;
|
|
48601
49135
|
leftLiveName = createdName;
|
|
49136
|
+
reportCreatedResource(logicalId, resourceType, createdName);
|
|
48602
49137
|
try {
|
|
48603
49138
|
const code = properties["Code"];
|
|
48604
49139
|
if (code) await this.seedInitialCommit(createdName, code);
|
|
@@ -48612,7 +49147,10 @@ var CodeCommitRepositoryProvider = class {
|
|
|
48612
49147
|
}
|
|
48613
49148
|
} catch (postCreateError) {
|
|
48614
49149
|
this.logger.warn(`Post-create step failed for CodeCommit Repository ${logicalId}; deleting the just-created repository ${createdName} to avoid an orphan`);
|
|
48615
|
-
if (await this.bestEffortDelete(createdName, maskerOrIdentity(context?.maskSecrets)))
|
|
49150
|
+
if (await this.bestEffortDelete(createdName, maskerOrIdentity(context?.maskSecrets))) {
|
|
49151
|
+
retractCreatedResource(logicalId, resourceType, leftLiveName);
|
|
49152
|
+
leftLiveName = void 0;
|
|
49153
|
+
}
|
|
48616
49154
|
throw markAuxiliaryFailure(postCreateError, logicalId);
|
|
48617
49155
|
}
|
|
48618
49156
|
this.logger.debug(`Successfully created CodeCommit Repository ${logicalId}: ${createdName}`);
|
|
@@ -49472,6 +50010,370 @@ function notEmptyRefusalMessage(bucketName, maskSecrets) {
|
|
|
49472
50010
|
const remedy = command ? `Delete all objects first (e.g. ${command}) and destroy again.` : secretDerived ? "Delete all objects first, via the console, and destroy again: the bucket name is derived from a secret, so cdkd does not print it." : "Delete all objects first, via the console, and destroy again: the bucket name cdkd recorded cannot be reproduced safely on a command line, so any command shown here could act on a different bucket or run part of the name as shell.";
|
|
49473
50011
|
return mask(`bucket ${displayIdent(mask(bucketName))} is not empty. Matching CloudFormation, cdkd does not delete a non-empty directory bucket without an explicit opt-in. ${remedy}`);
|
|
49474
50012
|
}
|
|
50013
|
+
function isRecord(value) {
|
|
50014
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
50015
|
+
}
|
|
50016
|
+
function itemId(item) {
|
|
50017
|
+
if (!isRecord(item)) return void 0;
|
|
50018
|
+
const id = item["Id"];
|
|
50019
|
+
return typeof id === "string" && id !== "" ? id : void 0;
|
|
50020
|
+
}
|
|
50021
|
+
function canonicalJson(value) {
|
|
50022
|
+
const sorted = (v) => {
|
|
50023
|
+
if (Array.isArray(v)) return v.map(sorted);
|
|
50024
|
+
if (isRecord(v)) return Object.fromEntries(Object.keys(v).sort().map((k) => [k, sorted(v[k])]));
|
|
50025
|
+
return v;
|
|
50026
|
+
};
|
|
50027
|
+
return JSON.stringify(sorted(value)) ?? "undefined";
|
|
50028
|
+
}
|
|
50029
|
+
function sameJson(a, b) {
|
|
50030
|
+
return canonicalJson(a) === canonicalJson(b);
|
|
50031
|
+
}
|
|
50032
|
+
function optionalString(value, path, refuse) {
|
|
50033
|
+
if (value === void 0 || value === null) return void 0;
|
|
50034
|
+
if (typeof value !== "string") refuse(path, "a string");
|
|
50035
|
+
return value;
|
|
50036
|
+
}
|
|
50037
|
+
function optionalBoolean(value, path, refuse) {
|
|
50038
|
+
if (value === void 0 || value === null) return void 0;
|
|
50039
|
+
if (typeof value === "boolean") return value;
|
|
50040
|
+
if (value === "true") return true;
|
|
50041
|
+
if (value === "false") return false;
|
|
50042
|
+
return refuse(path, "a boolean");
|
|
50043
|
+
}
|
|
50044
|
+
function optionalInteger(value, path, refuse) {
|
|
50045
|
+
if (value === void 0 || value === null) return void 0;
|
|
50046
|
+
if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) return value;
|
|
50047
|
+
if (typeof value === "string" && /^[0-9]{1,15}$/.test(value)) return Number(value);
|
|
50048
|
+
return refuse(path, "a non-negative integer");
|
|
50049
|
+
}
|
|
50050
|
+
function listOf(value, path, refuse) {
|
|
50051
|
+
if (!Array.isArray(value)) refuse(path, "a list");
|
|
50052
|
+
return value;
|
|
50053
|
+
}
|
|
50054
|
+
function encryptionToSdk(value, refuse) {
|
|
50055
|
+
if (value === void 0 || value === null) return void 0;
|
|
50056
|
+
if (!isRecord(value)) refuse("BucketEncryption", "an object");
|
|
50057
|
+
const rules = listOf(value["ServerSideEncryptionConfiguration"], "BucketEncryption.ServerSideEncryptionConfiguration", refuse);
|
|
50058
|
+
if (rules.length === 0) return void 0;
|
|
50059
|
+
return { Rules: rules.map((rule, i) => {
|
|
50060
|
+
const path = `BucketEncryption.ServerSideEncryptionConfiguration[${i}]`;
|
|
50061
|
+
if (!isRecord(rule)) refuse(path, "an object");
|
|
50062
|
+
const out = {};
|
|
50063
|
+
const byDefault = rule["ServerSideEncryptionByDefault"];
|
|
50064
|
+
if (byDefault !== void 0 && byDefault !== null) {
|
|
50065
|
+
if (!isRecord(byDefault)) refuse(`${path}.ServerSideEncryptionByDefault`, "an object");
|
|
50066
|
+
const algorithm = optionalString(byDefault["SSEAlgorithm"], `${path}.ServerSideEncryptionByDefault.SSEAlgorithm`, refuse);
|
|
50067
|
+
const keyId = optionalString(byDefault["KMSMasterKeyID"], `${path}.ServerSideEncryptionByDefault.KMSMasterKeyID`, refuse);
|
|
50068
|
+
out.ApplyServerSideEncryptionByDefault = {
|
|
50069
|
+
SSEAlgorithm: algorithm,
|
|
50070
|
+
...keyId !== void 0 ? { KMSMasterKeyID: keyId } : {}
|
|
50071
|
+
};
|
|
50072
|
+
}
|
|
50073
|
+
const bucketKey = optionalBoolean(rule["BucketKeyEnabled"], `${path}.BucketKeyEnabled`, refuse);
|
|
50074
|
+
if (bucketKey !== void 0) out.BucketKeyEnabled = bucketKey;
|
|
50075
|
+
return out;
|
|
50076
|
+
}) };
|
|
50077
|
+
}
|
|
50078
|
+
function lifecycleFilterToSdk(rule, path, refuse) {
|
|
50079
|
+
const prefix = optionalString(rule["Prefix"], `${path}.Prefix`, refuse);
|
|
50080
|
+
const greater = optionalInteger(rule["ObjectSizeGreaterThan"], `${path}.ObjectSizeGreaterThan`, refuse);
|
|
50081
|
+
const less = optionalInteger(rule["ObjectSizeLessThan"], `${path}.ObjectSizeLessThan`, refuse);
|
|
50082
|
+
const members = {
|
|
50083
|
+
...prefix !== void 0 ? { Prefix: prefix } : {},
|
|
50084
|
+
...greater !== void 0 ? { ObjectSizeGreaterThan: greater } : {},
|
|
50085
|
+
...less !== void 0 ? { ObjectSizeLessThan: less } : {}
|
|
50086
|
+
};
|
|
50087
|
+
const count = Object.keys(members).length;
|
|
50088
|
+
if (count === 0) return { Prefix: "" };
|
|
50089
|
+
if (count === 1) return members;
|
|
50090
|
+
return { And: members };
|
|
50091
|
+
}
|
|
50092
|
+
function lifecycleToSdk(value, refuse) {
|
|
50093
|
+
if (value === void 0 || value === null) return void 0;
|
|
50094
|
+
if (!isRecord(value)) refuse("LifecycleConfiguration", "an object");
|
|
50095
|
+
const rules = listOf(value["Rules"], "LifecycleConfiguration.Rules", refuse);
|
|
50096
|
+
if (rules.length === 0) return void 0;
|
|
50097
|
+
return { Rules: rules.map((rule, i) => {
|
|
50098
|
+
const path = `LifecycleConfiguration.Rules[${i}]`;
|
|
50099
|
+
if (!isRecord(rule)) refuse(path, "an object");
|
|
50100
|
+
const id = optionalString(rule["Id"], `${path}.Id`, refuse);
|
|
50101
|
+
const status = optionalString(rule["Status"], `${path}.Status`, refuse);
|
|
50102
|
+
const days = optionalInteger(rule["ExpirationInDays"], `${path}.ExpirationInDays`, refuse);
|
|
50103
|
+
const out = {
|
|
50104
|
+
...id !== void 0 ? { ID: id } : {},
|
|
50105
|
+
Status: status,
|
|
50106
|
+
Filter: lifecycleFilterToSdk(rule, path, refuse)
|
|
50107
|
+
};
|
|
50108
|
+
if (days !== void 0) out.Expiration = { Days: days };
|
|
50109
|
+
const abort = rule["AbortIncompleteMultipartUpload"];
|
|
50110
|
+
if (abort !== void 0 && abort !== null) {
|
|
50111
|
+
if (!isRecord(abort)) refuse(`${path}.AbortIncompleteMultipartUpload`, "an object");
|
|
50112
|
+
const after = optionalInteger(abort["DaysAfterInitiation"], `${path}.AbortIncompleteMultipartUpload.DaysAfterInitiation`, refuse);
|
|
50113
|
+
out.AbortIncompleteMultipartUpload = after !== void 0 ? { DaysAfterInitiation: after } : {};
|
|
50114
|
+
}
|
|
50115
|
+
return out;
|
|
50116
|
+
}) };
|
|
50117
|
+
}
|
|
50118
|
+
function keyedItems(value, property, refuse) {
|
|
50119
|
+
const out = /* @__PURE__ */ new Map();
|
|
50120
|
+
if (value === void 0 || value === null) return out;
|
|
50121
|
+
listOf(value, property, refuse).forEach((item, i) => {
|
|
50122
|
+
if (!isRecord(item)) refuse(`${property}[${i}]`, "an object");
|
|
50123
|
+
const id = itemId(item);
|
|
50124
|
+
if (id === void 0) refuse(`${property}[${i}].Id`, "a non-empty string");
|
|
50125
|
+
if (out.has(id)) refuse(`${property}[${i}].Id`, "an Id no other item of the list carries");
|
|
50126
|
+
out.set(id, item);
|
|
50127
|
+
});
|
|
50128
|
+
return out;
|
|
50129
|
+
}
|
|
50130
|
+
function recordedItems(value) {
|
|
50131
|
+
const out = /* @__PURE__ */ new Map();
|
|
50132
|
+
if (!Array.isArray(value)) return out;
|
|
50133
|
+
for (const item of value) {
|
|
50134
|
+
const id = itemId(item);
|
|
50135
|
+
if (id !== void 0 && !out.has(id)) out.set(id, item);
|
|
50136
|
+
}
|
|
50137
|
+
return out;
|
|
50138
|
+
}
|
|
50139
|
+
function metricsItemToSdk(id, item, path, refuse) {
|
|
50140
|
+
const prefix = optionalString(item["Prefix"], `${path}.Prefix`, refuse);
|
|
50141
|
+
const accessPoint = optionalString(item["AccessPointArn"], `${path}.AccessPointArn`, refuse);
|
|
50142
|
+
if (prefix !== void 0 && accessPoint !== void 0) return {
|
|
50143
|
+
Id: id,
|
|
50144
|
+
Filter: { And: {
|
|
50145
|
+
Prefix: prefix,
|
|
50146
|
+
AccessPointArn: accessPoint
|
|
50147
|
+
} }
|
|
50148
|
+
};
|
|
50149
|
+
if (prefix !== void 0) return {
|
|
50150
|
+
Id: id,
|
|
50151
|
+
Filter: { Prefix: prefix }
|
|
50152
|
+
};
|
|
50153
|
+
if (accessPoint !== void 0) return {
|
|
50154
|
+
Id: id,
|
|
50155
|
+
Filter: { AccessPointArn: accessPoint }
|
|
50156
|
+
};
|
|
50157
|
+
return { Id: id };
|
|
50158
|
+
}
|
|
50159
|
+
function inventoryItemToSdk(id, item, path, refuse) {
|
|
50160
|
+
const destination = item["Destination"];
|
|
50161
|
+
if (!isRecord(destination)) refuse(`${path}.Destination`, "an object");
|
|
50162
|
+
const bucketArn = optionalString(destination["BucketArn"], `${path}.Destination.BucketArn`, refuse);
|
|
50163
|
+
const accountId = optionalString(destination["BucketAccountId"], `${path}.Destination.BucketAccountId`, refuse);
|
|
50164
|
+
const format = optionalString(destination["Format"], `${path}.Destination.Format`, refuse);
|
|
50165
|
+
const destPrefix = optionalString(destination["Prefix"], `${path}.Destination.Prefix`, refuse);
|
|
50166
|
+
const enabled = optionalBoolean(item["Enabled"], `${path}.Enabled`, refuse);
|
|
50167
|
+
const versions = optionalString(item["IncludedObjectVersions"], `${path}.IncludedObjectVersions`, refuse);
|
|
50168
|
+
const prefix = optionalString(item["Prefix"], `${path}.Prefix`, refuse);
|
|
50169
|
+
const frequency = optionalString(item["ScheduleFrequency"], `${path}.ScheduleFrequency`, refuse);
|
|
50170
|
+
const fields = item["OptionalFields"];
|
|
50171
|
+
let optionalFields;
|
|
50172
|
+
if (fields !== void 0 && fields !== null) optionalFields = listOf(fields, `${path}.OptionalFields`, refuse).map((f, j) => {
|
|
50173
|
+
if (typeof f !== "string") refuse(`${path}.OptionalFields[${j}]`, "a string");
|
|
50174
|
+
return f;
|
|
50175
|
+
});
|
|
50176
|
+
return {
|
|
50177
|
+
Id: id,
|
|
50178
|
+
Destination: { S3BucketDestination: {
|
|
50179
|
+
Bucket: bucketArn,
|
|
50180
|
+
Format: format,
|
|
50181
|
+
...accountId !== void 0 ? { AccountId: accountId } : {},
|
|
50182
|
+
...destPrefix !== void 0 ? { Prefix: destPrefix } : {}
|
|
50183
|
+
} },
|
|
50184
|
+
IsEnabled: enabled,
|
|
50185
|
+
IncludedObjectVersions: versions,
|
|
50186
|
+
Schedule: { Frequency: frequency },
|
|
50187
|
+
...prefix !== void 0 ? { Filter: { Prefix: prefix } } : {},
|
|
50188
|
+
...optionalFields !== void 0 ? { OptionalFields: optionalFields } : {}
|
|
50189
|
+
};
|
|
50190
|
+
}
|
|
50191
|
+
function desiredConfigurations(properties, refuse, onUnusable) {
|
|
50192
|
+
const warnOut = (error, what) => onUnusable?.(`${error.message.replace(/ — the resource was not created$/, "")}; replaying a recorded state, so the bucket is created without ${what}`);
|
|
50193
|
+
const build = (fallback, what, run) => {
|
|
50194
|
+
if (!onUnusable) return run();
|
|
50195
|
+
try {
|
|
50196
|
+
return run();
|
|
50197
|
+
} catch (error) {
|
|
50198
|
+
if (!(error instanceof ProvisioningError)) throw error;
|
|
50199
|
+
warnOut(error, what);
|
|
50200
|
+
return fallback;
|
|
50201
|
+
}
|
|
50202
|
+
};
|
|
50203
|
+
const buildList = (property, toSdk) => {
|
|
50204
|
+
if (!onUnusable) {
|
|
50205
|
+
const out = /* @__PURE__ */ new Map();
|
|
50206
|
+
let i = 0;
|
|
50207
|
+
for (const [id, item] of keyedItems(properties[property], property, refuse)) out.set(id, toSdk(id, item, `${property}[${i++}]`));
|
|
50208
|
+
return out;
|
|
50209
|
+
}
|
|
50210
|
+
const out = /* @__PURE__ */ new Map();
|
|
50211
|
+
const value = properties[property];
|
|
50212
|
+
if (value === void 0 || value === null) return out;
|
|
50213
|
+
build(void 0, `any ${property} item`, () => listOf(value, property, refuse))?.forEach((item, i) => {
|
|
50214
|
+
const path = `${property}[${i}]`;
|
|
50215
|
+
build(void 0, `${path}`, () => {
|
|
50216
|
+
if (!isRecord(item)) refuse(path, "an object");
|
|
50217
|
+
const id = itemId(item);
|
|
50218
|
+
if (id === void 0) refuse(`${path}.Id`, "a non-empty string");
|
|
50219
|
+
if (out.has(id)) refuse(`${path}.Id`, "an Id no other item of the list carries");
|
|
50220
|
+
out.set(id, toSdk(id, item, path));
|
|
50221
|
+
});
|
|
50222
|
+
});
|
|
50223
|
+
return out;
|
|
50224
|
+
};
|
|
50225
|
+
const metrics = buildList("MetricsConfigurations", (id, item, path) => metricsItemToSdk(id, item, path, refuse));
|
|
50226
|
+
const inventory = buildList("InventoryConfigurations", (id, item, path) => inventoryItemToSdk(id, item, path, refuse));
|
|
50227
|
+
return {
|
|
50228
|
+
encryption: build(void 0, "its BucketEncryption", () => encryptionToSdk(properties["BucketEncryption"], refuse)),
|
|
50229
|
+
lifecycle: build(void 0, "its LifecycleConfiguration", () => lifecycleToSdk(properties["LifecycleConfiguration"], refuse)),
|
|
50230
|
+
metrics,
|
|
50231
|
+
inventory
|
|
50232
|
+
};
|
|
50233
|
+
}
|
|
50234
|
+
function configurationRefuser(resourceType, logicalId, physicalId) {
|
|
50235
|
+
const updating = physicalId !== void 0;
|
|
50236
|
+
return (path, expected) => {
|
|
50237
|
+
throw markNonRetryable(new ProvisioningError(`${updating ? "desired " : ""}${path} of ${resourceType} ${logicalId} is not ${expected} — the resource was not ${updating ? "updated" : "created"}`, resourceType, logicalId, physicalId));
|
|
50238
|
+
};
|
|
50239
|
+
}
|
|
50240
|
+
function encryptionFromSdk(rules) {
|
|
50241
|
+
return { ServerSideEncryptionConfiguration: rules.map((rule) => {
|
|
50242
|
+
const out = {};
|
|
50243
|
+
const byDefault = rule.ApplyServerSideEncryptionByDefault;
|
|
50244
|
+
if (byDefault) out["ServerSideEncryptionByDefault"] = {
|
|
50245
|
+
...byDefault.SSEAlgorithm !== void 0 ? { SSEAlgorithm: byDefault.SSEAlgorithm } : {},
|
|
50246
|
+
...byDefault.KMSMasterKeyID !== void 0 ? { KMSMasterKeyID: byDefault.KMSMasterKeyID } : {}
|
|
50247
|
+
};
|
|
50248
|
+
if (rule.BucketKeyEnabled !== void 0) out["BucketKeyEnabled"] = rule.BucketKeyEnabled;
|
|
50249
|
+
return out;
|
|
50250
|
+
}) };
|
|
50251
|
+
}
|
|
50252
|
+
function lifecycleFromSdk(rules) {
|
|
50253
|
+
return { Rules: rules.map((rule) => {
|
|
50254
|
+
const out = {};
|
|
50255
|
+
if (rule.ID !== void 0) out["Id"] = rule.ID;
|
|
50256
|
+
if (rule.Status !== void 0) out["Status"] = rule.Status;
|
|
50257
|
+
const scope = {
|
|
50258
|
+
...rule.Filter?.And ?? {},
|
|
50259
|
+
...rule.Filter ?? {}
|
|
50260
|
+
};
|
|
50261
|
+
const prefix = scope["Prefix"] ?? rule.Prefix;
|
|
50262
|
+
if (prefix !== void 0 && prefix !== "") out["Prefix"] = prefix;
|
|
50263
|
+
if (typeof scope["ObjectSizeGreaterThan"] === "number") out["ObjectSizeGreaterThan"] = String(scope["ObjectSizeGreaterThan"]);
|
|
50264
|
+
if (typeof scope["ObjectSizeLessThan"] === "number") out["ObjectSizeLessThan"] = String(scope["ObjectSizeLessThan"]);
|
|
50265
|
+
if (rule.Expiration?.Days !== void 0) out["ExpirationInDays"] = rule.Expiration.Days;
|
|
50266
|
+
if (rule.AbortIncompleteMultipartUpload) {
|
|
50267
|
+
const after = rule.AbortIncompleteMultipartUpload.DaysAfterInitiation;
|
|
50268
|
+
out["AbortIncompleteMultipartUpload"] = after !== void 0 ? { DaysAfterInitiation: after } : {};
|
|
50269
|
+
}
|
|
50270
|
+
return out;
|
|
50271
|
+
}) };
|
|
50272
|
+
}
|
|
50273
|
+
function metricsFromSdk(item) {
|
|
50274
|
+
const filter = item.Filter;
|
|
50275
|
+
const scope = filter?.And ?? filter ?? {};
|
|
50276
|
+
return {
|
|
50277
|
+
Id: item.Id,
|
|
50278
|
+
...scope.Prefix !== void 0 ? { Prefix: scope.Prefix } : {},
|
|
50279
|
+
...scope.AccessPointArn !== void 0 ? { AccessPointArn: scope.AccessPointArn } : {}
|
|
50280
|
+
};
|
|
50281
|
+
}
|
|
50282
|
+
function inventoryFromSdk(item) {
|
|
50283
|
+
const dest = item.Destination?.S3BucketDestination;
|
|
50284
|
+
return {
|
|
50285
|
+
Id: item.Id,
|
|
50286
|
+
Destination: {
|
|
50287
|
+
...dest?.Bucket !== void 0 ? { BucketArn: dest.Bucket } : {},
|
|
50288
|
+
...dest?.AccountId !== void 0 ? { BucketAccountId: dest.AccountId } : {},
|
|
50289
|
+
...dest?.Format !== void 0 ? { Format: dest.Format } : {},
|
|
50290
|
+
...dest?.Prefix !== void 0 ? { Prefix: dest.Prefix } : {}
|
|
50291
|
+
},
|
|
50292
|
+
...item.IsEnabled !== void 0 ? { Enabled: item.IsEnabled } : {},
|
|
50293
|
+
...item.IncludedObjectVersions !== void 0 ? { IncludedObjectVersions: item.IncludedObjectVersions } : {},
|
|
50294
|
+
...item.Filter?.Prefix !== void 0 ? { Prefix: item.Filter.Prefix } : {},
|
|
50295
|
+
...item.Schedule?.Frequency !== void 0 ? { ScheduleFrequency: item.Schedule.Frequency } : {},
|
|
50296
|
+
...item.OptionalFields !== void 0 && item.OptionalFields.length > 0 ? { OptionalFields: [...item.OptionalFields] } : {}
|
|
50297
|
+
};
|
|
50298
|
+
}
|
|
50299
|
+
function impliedBucketKey(algorithm) {
|
|
50300
|
+
if (algorithm === "AES256") return false;
|
|
50301
|
+
if (algorithm === "aws:kms") return true;
|
|
50302
|
+
}
|
|
50303
|
+
function canonicalizeConfigurationsForDrift(properties) {
|
|
50304
|
+
let out = properties;
|
|
50305
|
+
const encryption = properties["BucketEncryption"];
|
|
50306
|
+
if (isRecord(encryption) && Array.isArray(encryption["ServerSideEncryptionConfiguration"])) {
|
|
50307
|
+
let changed = false;
|
|
50308
|
+
const rules = encryption["ServerSideEncryptionConfiguration"].map((rule) => {
|
|
50309
|
+
if (!isRecord(rule) || !("BucketKeyEnabled" in rule)) return rule;
|
|
50310
|
+
const byDefault = rule["ServerSideEncryptionByDefault"];
|
|
50311
|
+
const implied = impliedBucketKey(isRecord(byDefault) ? byDefault["SSEAlgorithm"] : void 0);
|
|
50312
|
+
const declared = rule["BucketKeyEnabled"];
|
|
50313
|
+
if (implied === void 0 || (declared === "true" ? true : declared === "false" ? false : declared) !== implied) return rule;
|
|
50314
|
+
changed = true;
|
|
50315
|
+
const { BucketKeyEnabled: _dropped, ...rest } = rule;
|
|
50316
|
+
return rest;
|
|
50317
|
+
});
|
|
50318
|
+
if (changed) out = {
|
|
50319
|
+
...out,
|
|
50320
|
+
BucketEncryption: {
|
|
50321
|
+
...encryption,
|
|
50322
|
+
ServerSideEncryptionConfiguration: rules
|
|
50323
|
+
}
|
|
50324
|
+
};
|
|
50325
|
+
}
|
|
50326
|
+
const lifecycle = properties["LifecycleConfiguration"];
|
|
50327
|
+
if (isRecord(lifecycle) && Array.isArray(lifecycle["Rules"])) {
|
|
50328
|
+
let changed = false;
|
|
50329
|
+
const rules = lifecycle["Rules"].map((rule) => {
|
|
50330
|
+
if (!isRecord(rule) || rule["Prefix"] !== "") return rule;
|
|
50331
|
+
changed = true;
|
|
50332
|
+
const { Prefix: _dropped, ...rest } = rule;
|
|
50333
|
+
return rest;
|
|
50334
|
+
});
|
|
50335
|
+
if (changed) out = {
|
|
50336
|
+
...out,
|
|
50337
|
+
LifecycleConfiguration: {
|
|
50338
|
+
...lifecycle,
|
|
50339
|
+
Rules: rules
|
|
50340
|
+
}
|
|
50341
|
+
};
|
|
50342
|
+
}
|
|
50343
|
+
return out;
|
|
50344
|
+
}
|
|
50345
|
+
function liveMatchesDesired(name, desired, live) {
|
|
50346
|
+
const d = canonicalizeConfigurationsForDrift({ [name]: desired[name] })[name];
|
|
50347
|
+
let l = canonicalizeConfigurationsForDrift({ [name]: live[name] })[name];
|
|
50348
|
+
if (name === "LifecycleConfiguration" && isRecord(d) && isRecord(l)) {
|
|
50349
|
+
const dRules = Array.isArray(d["Rules"]) ? d["Rules"] : [];
|
|
50350
|
+
const lRules = Array.isArray(l["Rules"]) ? l["Rules"] : [];
|
|
50351
|
+
l = {
|
|
50352
|
+
...l,
|
|
50353
|
+
Rules: lRules.map((rule, i) => {
|
|
50354
|
+
const declared = dRules[i];
|
|
50355
|
+
if (!isRecord(rule) || !isRecord(declared) || "Id" in declared) return rule;
|
|
50356
|
+
const { Id: _assigned, ...rest } = rule;
|
|
50357
|
+
return rest;
|
|
50358
|
+
})
|
|
50359
|
+
};
|
|
50360
|
+
}
|
|
50361
|
+
if (name === "MetricsConfigurations" || name === "InventoryConfigurations") {
|
|
50362
|
+
const withSortedFields = (item) => isRecord(item) && Array.isArray(item["OptionalFields"]) ? {
|
|
50363
|
+
...item,
|
|
50364
|
+
OptionalFields: [...item["OptionalFields"]].map(String).sort()
|
|
50365
|
+
} : item;
|
|
50366
|
+
const asSet = (v) => Array.isArray(v) ? v.map((item) => canonicalJson(withSortedFields(item))).sort() : [canonicalJson(v)];
|
|
50367
|
+
return sameJson(asSet(d), asSet(l));
|
|
50368
|
+
}
|
|
50369
|
+
return sameJson(d, l);
|
|
50370
|
+
}
|
|
50371
|
+
const CONFIGURATION_READ_ACTIONS = {
|
|
50372
|
+
BucketEncryption: "s3express:GetEncryptionConfiguration",
|
|
50373
|
+
LifecycleConfiguration: "s3express:GetLifecycleConfiguration",
|
|
50374
|
+
MetricsConfigurations: "s3express:GetMetricsConfiguration",
|
|
50375
|
+
InventoryConfigurations: "s3express:GetInventoryConfiguration"
|
|
50376
|
+
};
|
|
49475
50377
|
var S3DirectoryBucketProvider = class {
|
|
49476
50378
|
s3Client;
|
|
49477
50379
|
createClient;
|
|
@@ -49489,8 +50391,44 @@ var S3DirectoryBucketProvider = class {
|
|
|
49489
50391
|
"DataRedundancy",
|
|
49490
50392
|
"LocationName",
|
|
49491
50393
|
"BucketName",
|
|
49492
|
-
"Tags"
|
|
50394
|
+
"Tags",
|
|
50395
|
+
"BucketEncryption",
|
|
50396
|
+
"LifecycleConfiguration",
|
|
50397
|
+
"MetricsConfigurations",
|
|
50398
|
+
"InventoryConfigurations"
|
|
49493
50399
|
])]]);
|
|
50400
|
+
async readUnsettled(physicalId, _logicalId, _resourceType, names, recordedProperties, desiredProperties) {
|
|
50401
|
+
const live = await this.readState(physicalId);
|
|
50402
|
+
if (live === RESOURCE_NOT_FOUND) return live;
|
|
50403
|
+
const desired = desiredProperties ?? recordedProperties ?? {};
|
|
50404
|
+
const out = {};
|
|
50405
|
+
for (const name of names) {
|
|
50406
|
+
if (!Object.hasOwn(live, name)) continue;
|
|
50407
|
+
if (desired[name] !== void 0 && liveMatchesDesired(name, desired, live)) {
|
|
50408
|
+
out[name] = desired[name];
|
|
50409
|
+
continue;
|
|
50410
|
+
}
|
|
50411
|
+
if (name === "MetricsConfigurations" || name === "InventoryConfigurations") {
|
|
50412
|
+
const named = /* @__PURE__ */ new Set([...recordedItems(recordedProperties?.[name]).keys(), ...recordedItems(desiredProperties?.[name]).keys()]);
|
|
50413
|
+
const items = live[name];
|
|
50414
|
+
out[name] = Array.isArray(items) ? items.filter((item) => {
|
|
50415
|
+
const id = itemId(item);
|
|
50416
|
+
return id !== void 0 && named.has(id);
|
|
50417
|
+
}) : items;
|
|
50418
|
+
continue;
|
|
50419
|
+
}
|
|
50420
|
+
out[name] = live[name];
|
|
50421
|
+
}
|
|
50422
|
+
return out;
|
|
50423
|
+
}
|
|
50424
|
+
getDriftUnorderedPaths(resourceType) {
|
|
50425
|
+
if (resourceType !== "AWS::S3Express::DirectoryBucket") return [];
|
|
50426
|
+
return ["MetricsConfigurations", "InventoryConfigurations"];
|
|
50427
|
+
}
|
|
50428
|
+
canonicalizeDriftProperties(resourceType, properties) {
|
|
50429
|
+
if (resourceType !== "AWS::S3Express::DirectoryBucket") return properties;
|
|
50430
|
+
return canonicalizeConfigurationsForDrift(properties);
|
|
50431
|
+
}
|
|
49494
50432
|
ec2Client;
|
|
49495
50433
|
s3ControlClient;
|
|
49496
50434
|
providerRegion = ambientRegion();
|
|
@@ -49554,6 +50492,7 @@ var S3DirectoryBucketProvider = class {
|
|
|
49554
50492
|
async create(logicalId, resourceType, properties, context) {
|
|
49555
50493
|
this.logger.debug(`Creating S3 Express Directory Bucket ${logicalId}`);
|
|
49556
50494
|
const desiredTags = refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId);
|
|
50495
|
+
const configs = desiredConfigurations(properties, configurationRefuser(resourceType, logicalId), replayWarn(this.logger, context).onUnusable);
|
|
49557
50496
|
const dataRedundancy = requireConfigString(properties["DataRedundancy"], "SingleAvailabilityZone", "AWS::S3Express::DirectoryBucket DataRedundancy", replayWarn(this.logger, context));
|
|
49558
50497
|
const azName = properties["LocationName"]?.replace(/--x-s3$/, "") || "us-east-1a";
|
|
49559
50498
|
const azId = await this.getAzId(azName);
|
|
@@ -49561,6 +50500,7 @@ var S3DirectoryBucketProvider = class {
|
|
|
49561
50500
|
if (!bucketName) bucketName = generatedNameFor("AWS::S3Express::DirectoryBucket", logicalId, { zoneId: azId });
|
|
49562
50501
|
const tags = desiredTags;
|
|
49563
50502
|
const includeTags = tags.length > 0;
|
|
50503
|
+
let bucketCreated = false;
|
|
49564
50504
|
try {
|
|
49565
50505
|
const attributes = await this.buildAttributes(bucketName);
|
|
49566
50506
|
await (await this.getCreateClient()).send(new CreateBucketCommand({
|
|
@@ -49577,19 +50517,112 @@ var S3DirectoryBucketProvider = class {
|
|
|
49577
50517
|
...includeTags ? { Tags: tags } : {}
|
|
49578
50518
|
}
|
|
49579
50519
|
}));
|
|
50520
|
+
bucketCreated = true;
|
|
49580
50521
|
this.logger.debug(`Created S3 Express Directory Bucket: ${bucketName}`);
|
|
50522
|
+
await this.applyConfigurations(bucketName, configs, properties, {}, true);
|
|
49581
50523
|
return {
|
|
49582
50524
|
physicalId: bucketName,
|
|
49583
50525
|
attributes
|
|
49584
50526
|
};
|
|
49585
50527
|
} catch (error) {
|
|
49586
50528
|
const cause = error instanceof Error ? error : void 0;
|
|
49587
|
-
|
|
50529
|
+
const thrown = this.wrapCaughtError(maskerOrIdentity(context?.maskSecrets), error, (text) => new ProvisioningError(`Failed to create S3 Express Directory Bucket ${logicalId}: ${text}`, resourceType, logicalId, bucketName, cause));
|
|
50530
|
+
if (bucketCreated) markCreatedBeforeFailure(thrown, logicalId, resourceType, bucketName);
|
|
50531
|
+
throw thrown;
|
|
50532
|
+
}
|
|
50533
|
+
}
|
|
50534
|
+
async applyConfigurations(bucketName, desired, desiredRaw, previousRaw, creating, markUnsettled = () => {}) {
|
|
50535
|
+
const changed = (desiredValue, previousValue) => creating || !sameJson(desiredValue, previousValue);
|
|
50536
|
+
const holds = (value, toSdk) => {
|
|
50537
|
+
try {
|
|
50538
|
+
return toSdk(value, () => {
|
|
50539
|
+
throw new Error("malformed");
|
|
50540
|
+
}) !== void 0;
|
|
50541
|
+
} catch {
|
|
50542
|
+
return true;
|
|
50543
|
+
}
|
|
50544
|
+
};
|
|
50545
|
+
if (changed(desiredRaw["BucketEncryption"], previousRaw["BucketEncryption"])) {
|
|
50546
|
+
if (desired.encryption) {
|
|
50547
|
+
markUnsettled("BucketEncryption");
|
|
50548
|
+
await this.s3Client.send(new PutBucketEncryptionCommand({
|
|
50549
|
+
Bucket: bucketName,
|
|
50550
|
+
ServerSideEncryptionConfiguration: desired.encryption
|
|
50551
|
+
}));
|
|
50552
|
+
} else if (!creating && holds(previousRaw["BucketEncryption"], encryptionToSdk)) {
|
|
50553
|
+
markUnsettled("BucketEncryption");
|
|
50554
|
+
await this.s3Client.send(new DeleteBucketEncryptionCommand({ Bucket: bucketName }));
|
|
50555
|
+
this.logger.debug("Sent DeleteBucketEncryption: the default encryption is back to SSE-S3");
|
|
50556
|
+
}
|
|
50557
|
+
}
|
|
50558
|
+
if (changed(desiredRaw["LifecycleConfiguration"], previousRaw["LifecycleConfiguration"])) {
|
|
50559
|
+
if (desired.lifecycle) {
|
|
50560
|
+
markUnsettled("LifecycleConfiguration");
|
|
50561
|
+
await this.s3Client.send(new PutBucketLifecycleConfigurationCommand({
|
|
50562
|
+
Bucket: bucketName,
|
|
50563
|
+
LifecycleConfiguration: desired.lifecycle
|
|
50564
|
+
}));
|
|
50565
|
+
} else if (!creating && holds(previousRaw["LifecycleConfiguration"], lifecycleToSdk)) {
|
|
50566
|
+
markUnsettled("LifecycleConfiguration");
|
|
50567
|
+
await this.s3Client.send(new DeleteBucketLifecycleCommand({ Bucket: bucketName }));
|
|
50568
|
+
this.logger.debug("Sent DeleteBucketLifecycle: every lifecycle rule is removed");
|
|
50569
|
+
}
|
|
50570
|
+
}
|
|
50571
|
+
const desiredMetrics = recordedItems(desiredRaw["MetricsConfigurations"]);
|
|
50572
|
+
const previousMetrics = creating ? /* @__PURE__ */ new Map() : recordedItems(previousRaw["MetricsConfigurations"]);
|
|
50573
|
+
for (const [id, config] of desired.metrics) {
|
|
50574
|
+
if (previousMetrics.has(id) && sameJson(previousMetrics.get(id), desiredMetrics.get(id))) continue;
|
|
50575
|
+
markUnsettled("MetricsConfigurations");
|
|
50576
|
+
await this.s3Client.send(new PutBucketMetricsConfigurationCommand({
|
|
50577
|
+
Bucket: bucketName,
|
|
50578
|
+
Id: id,
|
|
50579
|
+
MetricsConfiguration: config
|
|
50580
|
+
}));
|
|
50581
|
+
}
|
|
50582
|
+
for (const id of previousMetrics.keys()) {
|
|
50583
|
+
if (desired.metrics.has(id)) continue;
|
|
50584
|
+
markUnsettled("MetricsConfigurations");
|
|
50585
|
+
await this.deleteItemIdempotently(new DeleteBucketMetricsConfigurationCommand({
|
|
50586
|
+
Bucket: bucketName,
|
|
50587
|
+
Id: id
|
|
50588
|
+
}));
|
|
50589
|
+
}
|
|
50590
|
+
const desiredInventory = recordedItems(desiredRaw["InventoryConfigurations"]);
|
|
50591
|
+
const previousInventory = creating ? /* @__PURE__ */ new Map() : recordedItems(previousRaw["InventoryConfigurations"]);
|
|
50592
|
+
for (const [id, config] of desired.inventory) {
|
|
50593
|
+
if (previousInventory.has(id) && sameJson(previousInventory.get(id), desiredInventory.get(id))) continue;
|
|
50594
|
+
markUnsettled("InventoryConfigurations");
|
|
50595
|
+
await this.s3Client.send(new PutBucketInventoryConfigurationCommand({
|
|
50596
|
+
Bucket: bucketName,
|
|
50597
|
+
Id: id,
|
|
50598
|
+
InventoryConfiguration: config
|
|
50599
|
+
}));
|
|
50600
|
+
}
|
|
50601
|
+
for (const id of previousInventory.keys()) {
|
|
50602
|
+
if (desired.inventory.has(id)) continue;
|
|
50603
|
+
markUnsettled("InventoryConfigurations");
|
|
50604
|
+
await this.deleteItemIdempotently(new DeleteBucketInventoryConfigurationCommand({
|
|
50605
|
+
Bucket: bucketName,
|
|
50606
|
+
Id: id
|
|
50607
|
+
}));
|
|
50608
|
+
}
|
|
50609
|
+
}
|
|
50610
|
+
async deleteItemIdempotently(command) {
|
|
50611
|
+
try {
|
|
50612
|
+
if (command instanceof DeleteBucketMetricsConfigurationCommand) await this.s3Client.send(command);
|
|
50613
|
+
else await this.s3Client.send(command);
|
|
50614
|
+
} catch (error) {
|
|
50615
|
+
if (error instanceof Error && error.name === "NoSuchConfiguration") {
|
|
50616
|
+
this.logger.debug("A configuration this update deletes is already gone");
|
|
50617
|
+
return;
|
|
50618
|
+
}
|
|
50619
|
+
throw error;
|
|
49588
50620
|
}
|
|
49589
50621
|
}
|
|
49590
50622
|
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
49591
50623
|
if (context?.expectedRegion) for (const clientRegion of [await this.s3Client.config.region(), await this.getS3ControlClient().config.region()]) assertRegionMatch(clientRegion, context.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
49592
50624
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
50625
|
+
const configs = desiredConfigurations(properties, configurationRefuser(resourceType, logicalId, physicalId));
|
|
49593
50626
|
try {
|
|
49594
50627
|
const plan = planTagDiff(previousProperties["Tags"], properties["Tags"]);
|
|
49595
50628
|
const tagWarning = tagPlanWarning(plan, resourceType, logicalId);
|
|
@@ -49602,18 +50635,25 @@ var S3DirectoryBucketProvider = class {
|
|
|
49602
50635
|
if (removedKeys.length > 0 || tagsToApply.length > 0) {
|
|
49603
50636
|
const accountId = await this.getAccountId();
|
|
49604
50637
|
const resourceArn = await this.buildBucketArn(physicalId, accountId);
|
|
49605
|
-
if (removedKeys.length > 0)
|
|
49606
|
-
|
|
49607
|
-
|
|
49608
|
-
|
|
49609
|
-
|
|
49610
|
-
|
|
49611
|
-
|
|
49612
|
-
|
|
49613
|
-
|
|
49614
|
-
|
|
50638
|
+
if (removedKeys.length > 0) {
|
|
50639
|
+
context?.markUnsettled?.("Tags");
|
|
50640
|
+
await this.getS3ControlClient().send(new UntagResourceCommand$29({
|
|
50641
|
+
AccountId: accountId,
|
|
50642
|
+
ResourceArn: resourceArn,
|
|
50643
|
+
TagKeys: removedKeys
|
|
50644
|
+
}));
|
|
50645
|
+
}
|
|
50646
|
+
if (tagsToApply.length > 0) {
|
|
50647
|
+
context?.markUnsettled?.("Tags");
|
|
50648
|
+
await this.getS3ControlClient().send(new TagResourceCommand$28({
|
|
50649
|
+
AccountId: accountId,
|
|
50650
|
+
ResourceArn: resourceArn,
|
|
50651
|
+
Tags: tagsToApply
|
|
50652
|
+
}));
|
|
50653
|
+
}
|
|
49615
50654
|
this.logger.debug(`Updated tags for S3 Express Directory Bucket ${physicalId}`);
|
|
49616
|
-
}
|
|
50655
|
+
}
|
|
50656
|
+
await this.applyConfigurations(physicalId, configs, properties, previousProperties, false, (key) => context?.markUnsettled?.(key));
|
|
49617
50657
|
return {
|
|
49618
50658
|
physicalId,
|
|
49619
50659
|
wasReplaced: false
|
|
@@ -49686,6 +50726,9 @@ var S3DirectoryBucketProvider = class {
|
|
|
49686
50726
|
} while (continuationToken);
|
|
49687
50727
|
}
|
|
49688
50728
|
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
50729
|
+
return this.readState(physicalId);
|
|
50730
|
+
}
|
|
50731
|
+
async readState(physicalId) {
|
|
49689
50732
|
let locationType;
|
|
49690
50733
|
try {
|
|
49691
50734
|
locationType = (await this.s3Client.send(new HeadBucketCommand({ Bucket: physicalId })))?.BucketLocationType;
|
|
@@ -49697,8 +50740,63 @@ var S3DirectoryBucketProvider = class {
|
|
|
49697
50740
|
const result = { BucketName: physicalId };
|
|
49698
50741
|
if (physicalId.endsWith("--x-s3")) result["DataRedundancy"] = locationType === "LocalZone" ? "SingleLocalZone" : "SingleAvailabilityZone";
|
|
49699
50742
|
result["Tags"] = await this.readTags(physicalId);
|
|
50743
|
+
const reads = [
|
|
50744
|
+
["BucketEncryption", () => this.readEncryption(physicalId)],
|
|
50745
|
+
["LifecycleConfiguration", () => this.readLifecycle(physicalId)],
|
|
50746
|
+
["MetricsConfigurations", () => this.readMetrics(physicalId)],
|
|
50747
|
+
["InventoryConfigurations", () => this.readInventory(physicalId)]
|
|
50748
|
+
];
|
|
50749
|
+
(await Promise.all(reads.map(([key, read]) => read().catch((error) => {
|
|
50750
|
+
const name = error?.name;
|
|
50751
|
+
if (name === "AccessDenied" || name === "AccessDeniedException") throw new Error(`Reading ${key} of an S3 Express directory bucket needs ${CONFIGURATION_READ_ACTIONS[key]}: grant it to read the bucket back`, { cause: error });
|
|
50752
|
+
throw error;
|
|
50753
|
+
})))).forEach((value, i) => {
|
|
50754
|
+
result[reads[i][0]] = value;
|
|
50755
|
+
});
|
|
49700
50756
|
return result;
|
|
49701
50757
|
}
|
|
50758
|
+
async readEncryption(bucket) {
|
|
50759
|
+
try {
|
|
50760
|
+
return encryptionFromSdk((await this.s3Client.send(new GetBucketEncryptionCommand({ Bucket: bucket }))).ServerSideEncryptionConfiguration?.Rules ?? []);
|
|
50761
|
+
} catch (err) {
|
|
50762
|
+
if (err.name === "ServerSideEncryptionConfigurationNotFoundError") return { ServerSideEncryptionConfiguration: [] };
|
|
50763
|
+
throw err;
|
|
50764
|
+
}
|
|
50765
|
+
}
|
|
50766
|
+
async readLifecycle(bucket) {
|
|
50767
|
+
try {
|
|
50768
|
+
return lifecycleFromSdk((await this.s3Client.send(new GetBucketLifecycleConfigurationCommand({ Bucket: bucket }))).Rules ?? []);
|
|
50769
|
+
} catch (err) {
|
|
50770
|
+
if (err.name === "NoSuchLifecycleConfiguration") return { Rules: [] };
|
|
50771
|
+
throw err;
|
|
50772
|
+
}
|
|
50773
|
+
}
|
|
50774
|
+
async readMetrics(bucket) {
|
|
50775
|
+
const out = [];
|
|
50776
|
+
let token;
|
|
50777
|
+
do {
|
|
50778
|
+
const resp = await this.s3Client.send(new ListBucketMetricsConfigurationsCommand({
|
|
50779
|
+
Bucket: bucket,
|
|
50780
|
+
ContinuationToken: token
|
|
50781
|
+
}));
|
|
50782
|
+
for (const item of resp.MetricsConfigurationList ?? []) out.push(metricsFromSdk(item));
|
|
50783
|
+
token = resp.IsTruncated ? resp.NextContinuationToken : void 0;
|
|
50784
|
+
} while (token);
|
|
50785
|
+
return out;
|
|
50786
|
+
}
|
|
50787
|
+
async readInventory(bucket) {
|
|
50788
|
+
const out = [];
|
|
50789
|
+
let token;
|
|
50790
|
+
do {
|
|
50791
|
+
const resp = await this.s3Client.send(new ListBucketInventoryConfigurationsCommand({
|
|
50792
|
+
Bucket: bucket,
|
|
50793
|
+
ContinuationToken: token
|
|
50794
|
+
}));
|
|
50795
|
+
for (const item of resp.InventoryConfigurationList ?? []) out.push(inventoryFromSdk(item));
|
|
50796
|
+
token = resp.IsTruncated ? resp.NextContinuationToken : void 0;
|
|
50797
|
+
} while (token);
|
|
50798
|
+
return out;
|
|
50799
|
+
}
|
|
49702
50800
|
async readTags(bucketName) {
|
|
49703
50801
|
const accountId = await this.getAccountId();
|
|
49704
50802
|
const resourceArn = await this.buildBucketArn(bucketName, accountId);
|
|
@@ -50055,6 +51153,7 @@ var S3TablesProvider = class {
|
|
|
50055
51153
|
...tags !== void 0 && { tags }
|
|
50056
51154
|
}));
|
|
50057
51155
|
tableCreated = true;
|
|
51156
|
+
reportCreatedResource(logicalId, resourceType, physicalId);
|
|
50058
51157
|
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);
|
|
50059
51158
|
const tableARN = response.tableARN;
|
|
50060
51159
|
this.logger.debug(`Successfully created S3 Tables Table ${logicalId}: ${physicalId}`);
|
|
@@ -50582,6 +51681,7 @@ var ECRProvider = class {
|
|
|
50582
51681
|
...tags ? { tags } : {}
|
|
50583
51682
|
}));
|
|
50584
51683
|
repositoryCreated = true;
|
|
51684
|
+
reportCreatedResource(logicalId, resourceType, repositoryName);
|
|
50585
51685
|
const repo = response.repository;
|
|
50586
51686
|
if (!repo?.repositoryName) throw new Error("CreateRepository did not return repository name");
|
|
50587
51687
|
const lifecyclePolicy = properties["LifecyclePolicy"];
|
|
@@ -51310,6 +52410,7 @@ var ACMCertificateProvider = class {
|
|
|
51310
52410
|
const certificateArn = (await this.acmClient.send(new RequestCertificateCommand(input))).CertificateArn;
|
|
51311
52411
|
if (!certificateArn) throw new ProvisioningError(`RequestCertificate succeeded but no CertificateArn returned for ${logicalId}`, resourceType, logicalId);
|
|
51312
52412
|
requestedArn = certificateArn;
|
|
52413
|
+
reportCreatedResource(logicalId, resourceType, certificateArn);
|
|
51313
52414
|
this.logger.debug(`Requested ACM certificate: ${certificateArn}`);
|
|
51314
52415
|
if (!(process.env["CDKD_NO_WAIT"] === "true")) await this.waitForCertificateIssued(certificateArn, logicalId, resourceType, dnsValidationZones(properties));
|
|
51315
52416
|
else this.logger.warn(`Skipping wait for ACM certificate ${logicalId} (CDKD_NO_WAIT=true). Downstream consumers (CloudFront / ALB) will fail until the cert reaches ISSUED.`);
|
|
@@ -51323,6 +52424,7 @@ var ACMCertificateProvider = class {
|
|
|
51323
52424
|
};
|
|
51324
52425
|
} catch (error) {
|
|
51325
52426
|
const survivorNote = requestedArn ? await this.cleanupRequestedCertificate(requestedArn, logicalId, idempotencyToken, context?.maskSecrets) : void 0;
|
|
52427
|
+
if (requestedArn && survivorNote === void 0) retractCreatedResource(logicalId, resourceType, requestedArn);
|
|
51326
52428
|
if (error instanceof CdkdError) {
|
|
51327
52429
|
if (survivorNote === void 0) throw error;
|
|
51328
52430
|
const thrown = new ProvisioningError(`${error.message} ${survivorNote}`, resourceType, logicalId, requestedArn, error);
|
|
@@ -51611,4 +52713,4 @@ var ACMCertificateProvider = class {
|
|
|
51611
52713
|
|
|
51612
52714
|
//#endregion
|
|
51613
52715
|
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 };
|
|
51614
|
-
//# sourceMappingURL=provider-classes-
|
|
52716
|
+
//# sourceMappingURL=provider-classes-DktsDsTf.js.map
|