@go-to-k/cdkd 0.310.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-I1bFHVsO.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-DZO2SOQJ.js → deploy-engine-BF5exXUb.js} +617 -113
- package/dist/deploy-engine-BF5exXUb.js.map +1 -0
- package/dist/{iam-role-provider-BWw7I-SZ.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-8kjFmR1l.js → neptune-provider-D9ac71Ca.js} +6 -4
- package/dist/neptune-provider-D9ac71Ca.js.map +1 -0
- package/dist/{program-CS420Kx9.js → program-DbnTHlwR.js} +26 -14
- package/dist/program-DbnTHlwR.js.map +1 -0
- package/dist/{provider-classes-KsrvwO_r.js → provider-classes-DktsDsTf.js} +1063 -146
- package/dist/provider-classes-DktsDsTf.js.map +1 -0
- package/dist/{rds-provider-BqwTQeS-.js → rds-provider-0LUsn9Wl.js} +7 -4
- package/dist/rds-provider-0LUsn9Wl.js.map +1 -0
- package/dist/{version-QOtLxcEo.js → version-BA4rBBLp.js} +2 -2
- package/dist/{version-QOtLxcEo.js.map → version-BA4rBBLp.js.map} +1 -1
- package/package.json +2 -2
- package/dist/asg-provider-I1bFHVsO.js.map +0 -1
- package/dist/deploy-engine-DZO2SOQJ.js.map +0 -1
- package/dist/iam-policy-targets-D94wh05t.js.map +0 -1
- package/dist/iam-role-provider-BWw7I-SZ.js.map +0 -1
- package/dist/neptune-provider-8kjFmR1l.js.map +0 -1
- package/dist/program-CS420Kx9.js.map +0 -1
- package/dist/provider-classes-KsrvwO_r.js.map +0 -1
- package/dist/rds-provider-BqwTQeS-.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";
|
|
@@ -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;
|
|
@@ -46739,6 +47085,7 @@ var FirehoseProvider = class {
|
|
|
46739
47085
|
const response = await this.getCreateClient().send(new CreateDeliveryStreamCommand(input));
|
|
46740
47086
|
const physicalId = deliveryStreamName || input.DeliveryStreamName || response.DeliveryStreamARN?.split("/").pop() || "";
|
|
46741
47087
|
createdStreamName = physicalId;
|
|
47088
|
+
reportCreatedResource(logicalId, resourceType, physicalId);
|
|
46742
47089
|
const arn = response.DeliveryStreamARN;
|
|
46743
47090
|
this.logger.debug(`Successfully created Firehose delivery stream ${logicalId}: ${physicalId}`);
|
|
46744
47091
|
await this.waitForActive(physicalId, logicalId, resourceType, maskerOrIdentity(context?.maskSecrets));
|
|
@@ -47634,7 +47981,7 @@ function readListBlock(raw, path) {
|
|
|
47634
47981
|
};
|
|
47635
47982
|
}
|
|
47636
47983
|
}
|
|
47637
|
-
function listOf(read) {
|
|
47984
|
+
function listOf$1(read) {
|
|
47638
47985
|
return read.kind === "list" ? read.value : void 0;
|
|
47639
47986
|
}
|
|
47640
47987
|
function retainPreviousLists(desired, previous, keys, live) {
|
|
@@ -47805,6 +48152,7 @@ var CloudTrailProvider = class {
|
|
|
47805
48152
|
trailCreated = true;
|
|
47806
48153
|
const trailArn = result.TrailARN;
|
|
47807
48154
|
createdTrailArn = result.TrailARN;
|
|
48155
|
+
if (createdTrailArn) reportCreatedResource(logicalId, resourceType, createdTrailArn);
|
|
47808
48156
|
const basicForCreate = eventSelectors && eventSelectors.length > 0 ? eventSelectors : void 0;
|
|
47809
48157
|
if (basicForCreate || advancedEventSelectors && advancedEventSelectors.length > 0) {
|
|
47810
48158
|
this.logger.debug(`Setting event selectors for CloudTrail Trail ${logicalId}`);
|
|
@@ -47882,14 +48230,14 @@ var CloudTrailProvider = class {
|
|
|
47882
48230
|
const advancedRead = readListBlock(properties["AdvancedEventSelectors"], "AWS::CloudTrail::Trail AdvancedEventSelectors");
|
|
47883
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.`);
|
|
47884
48232
|
const selectorsUnusable = basicRead.kind === "unusable" || advancedRead.kind === "unusable";
|
|
47885
|
-
const newEventSelectors = listOf(basicRead);
|
|
47886
|
-
const newAdvancedSelectors = listOf(advancedRead);
|
|
48233
|
+
const newEventSelectors = listOf$1(basicRead);
|
|
48234
|
+
const newAdvancedSelectors = listOf$1(advancedRead);
|
|
47887
48235
|
const oldEventSelectors = previousProperties["EventSelectors"];
|
|
47888
48236
|
const oldAdvancedSelectors = previousProperties["AdvancedEventSelectors"];
|
|
47889
48237
|
const hadAdvancedSelectors = Array.isArray(oldAdvancedSelectors) && oldAdvancedSelectors.length > 0;
|
|
47890
48238
|
const aggregationRead = readListBlock(properties["AggregationConfigurations"], "AWS::CloudTrail::Trail AggregationConfigurations");
|
|
47891
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.`);
|
|
47892
|
-
const newAggregation = listOf(aggregationRead);
|
|
48240
|
+
const newAggregation = listOf$1(aggregationRead);
|
|
47893
48241
|
const aggregationChanged = aggregationRead.kind !== "unusable" && setKey(newAggregation) !== setKey(previousProperties["AggregationConfigurations"]);
|
|
47894
48242
|
const aggregationCleared = aggregationChanged && nonEmptyListOf(aggregationRead) === void 0;
|
|
47895
48243
|
const putAggregation = async () => {
|
|
@@ -48363,6 +48711,7 @@ var CodeBuildProvider = class {
|
|
|
48363
48711
|
const projectName = result.project.name;
|
|
48364
48712
|
const projectArn = result.project.arn;
|
|
48365
48713
|
createdName = projectName;
|
|
48714
|
+
reportCreatedResource(logicalId, resourceType, createdName);
|
|
48366
48715
|
if (visibilityRead.kind === "usable" && (visibilityRead.visibility !== DEFAULT_PROJECT_VISIBILITY || visibilityRead.resourceAccessRole !== void 0)) await this.applyVisibility(projectArn, visibilityRead);
|
|
48367
48716
|
this.logger.debug(`Successfully created CodeBuild Project ${logicalId}: ${projectName}`);
|
|
48368
48717
|
return {
|
|
@@ -48784,6 +49133,7 @@ var CodeCommitRepositoryProvider = class {
|
|
|
48784
49133
|
if (!metadata?.repositoryName) throw new Error("CreateRepository did not return repository metadata");
|
|
48785
49134
|
const createdName = metadata.repositoryName;
|
|
48786
49135
|
leftLiveName = createdName;
|
|
49136
|
+
reportCreatedResource(logicalId, resourceType, createdName);
|
|
48787
49137
|
try {
|
|
48788
49138
|
const code = properties["Code"];
|
|
48789
49139
|
if (code) await this.seedInitialCommit(createdName, code);
|
|
@@ -48797,7 +49147,10 @@ var CodeCommitRepositoryProvider = class {
|
|
|
48797
49147
|
}
|
|
48798
49148
|
} catch (postCreateError) {
|
|
48799
49149
|
this.logger.warn(`Post-create step failed for CodeCommit Repository ${logicalId}; deleting the just-created repository ${createdName} to avoid an orphan`);
|
|
48800
|
-
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
|
+
}
|
|
48801
49154
|
throw markAuxiliaryFailure(postCreateError, logicalId);
|
|
48802
49155
|
}
|
|
48803
49156
|
this.logger.debug(`Successfully created CodeCommit Repository ${logicalId}: ${createdName}`);
|
|
@@ -49657,6 +50010,370 @@ function notEmptyRefusalMessage(bucketName, maskSecrets) {
|
|
|
49657
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.";
|
|
49658
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}`);
|
|
49659
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
|
+
};
|
|
49660
50377
|
var S3DirectoryBucketProvider = class {
|
|
49661
50378
|
s3Client;
|
|
49662
50379
|
createClient;
|
|
@@ -49674,8 +50391,44 @@ var S3DirectoryBucketProvider = class {
|
|
|
49674
50391
|
"DataRedundancy",
|
|
49675
50392
|
"LocationName",
|
|
49676
50393
|
"BucketName",
|
|
49677
|
-
"Tags"
|
|
50394
|
+
"Tags",
|
|
50395
|
+
"BucketEncryption",
|
|
50396
|
+
"LifecycleConfiguration",
|
|
50397
|
+
"MetricsConfigurations",
|
|
50398
|
+
"InventoryConfigurations"
|
|
49678
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
|
+
}
|
|
49679
50432
|
ec2Client;
|
|
49680
50433
|
s3ControlClient;
|
|
49681
50434
|
providerRegion = ambientRegion();
|
|
@@ -49739,6 +50492,7 @@ var S3DirectoryBucketProvider = class {
|
|
|
49739
50492
|
async create(logicalId, resourceType, properties, context) {
|
|
49740
50493
|
this.logger.debug(`Creating S3 Express Directory Bucket ${logicalId}`);
|
|
49741
50494
|
const desiredTags = refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId);
|
|
50495
|
+
const configs = desiredConfigurations(properties, configurationRefuser(resourceType, logicalId), replayWarn(this.logger, context).onUnusable);
|
|
49742
50496
|
const dataRedundancy = requireConfigString(properties["DataRedundancy"], "SingleAvailabilityZone", "AWS::S3Express::DirectoryBucket DataRedundancy", replayWarn(this.logger, context));
|
|
49743
50497
|
const azName = properties["LocationName"]?.replace(/--x-s3$/, "") || "us-east-1a";
|
|
49744
50498
|
const azId = await this.getAzId(azName);
|
|
@@ -49746,6 +50500,7 @@ var S3DirectoryBucketProvider = class {
|
|
|
49746
50500
|
if (!bucketName) bucketName = generatedNameFor("AWS::S3Express::DirectoryBucket", logicalId, { zoneId: azId });
|
|
49747
50501
|
const tags = desiredTags;
|
|
49748
50502
|
const includeTags = tags.length > 0;
|
|
50503
|
+
let bucketCreated = false;
|
|
49749
50504
|
try {
|
|
49750
50505
|
const attributes = await this.buildAttributes(bucketName);
|
|
49751
50506
|
await (await this.getCreateClient()).send(new CreateBucketCommand({
|
|
@@ -49762,19 +50517,112 @@ var S3DirectoryBucketProvider = class {
|
|
|
49762
50517
|
...includeTags ? { Tags: tags } : {}
|
|
49763
50518
|
}
|
|
49764
50519
|
}));
|
|
50520
|
+
bucketCreated = true;
|
|
49765
50521
|
this.logger.debug(`Created S3 Express Directory Bucket: ${bucketName}`);
|
|
50522
|
+
await this.applyConfigurations(bucketName, configs, properties, {}, true);
|
|
49766
50523
|
return {
|
|
49767
50524
|
physicalId: bucketName,
|
|
49768
50525
|
attributes
|
|
49769
50526
|
};
|
|
49770
50527
|
} catch (error) {
|
|
49771
50528
|
const cause = error instanceof Error ? error : void 0;
|
|
49772
|
-
|
|
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;
|
|
49773
50620
|
}
|
|
49774
50621
|
}
|
|
49775
50622
|
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
49776
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");
|
|
49777
50624
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
50625
|
+
const configs = desiredConfigurations(properties, configurationRefuser(resourceType, logicalId, physicalId));
|
|
49778
50626
|
try {
|
|
49779
50627
|
const plan = planTagDiff(previousProperties["Tags"], properties["Tags"]);
|
|
49780
50628
|
const tagWarning = tagPlanWarning(plan, resourceType, logicalId);
|
|
@@ -49787,18 +50635,25 @@ var S3DirectoryBucketProvider = class {
|
|
|
49787
50635
|
if (removedKeys.length > 0 || tagsToApply.length > 0) {
|
|
49788
50636
|
const accountId = await this.getAccountId();
|
|
49789
50637
|
const resourceArn = await this.buildBucketArn(physicalId, accountId);
|
|
49790
|
-
if (removedKeys.length > 0)
|
|
49791
|
-
|
|
49792
|
-
|
|
49793
|
-
|
|
49794
|
-
|
|
49795
|
-
|
|
49796
|
-
|
|
49797
|
-
|
|
49798
|
-
|
|
49799
|
-
|
|
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
|
+
}
|
|
49800
50654
|
this.logger.debug(`Updated tags for S3 Express Directory Bucket ${physicalId}`);
|
|
49801
|
-
}
|
|
50655
|
+
}
|
|
50656
|
+
await this.applyConfigurations(physicalId, configs, properties, previousProperties, false, (key) => context?.markUnsettled?.(key));
|
|
49802
50657
|
return {
|
|
49803
50658
|
physicalId,
|
|
49804
50659
|
wasReplaced: false
|
|
@@ -49871,6 +50726,9 @@ var S3DirectoryBucketProvider = class {
|
|
|
49871
50726
|
} while (continuationToken);
|
|
49872
50727
|
}
|
|
49873
50728
|
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
50729
|
+
return this.readState(physicalId);
|
|
50730
|
+
}
|
|
50731
|
+
async readState(physicalId) {
|
|
49874
50732
|
let locationType;
|
|
49875
50733
|
try {
|
|
49876
50734
|
locationType = (await this.s3Client.send(new HeadBucketCommand({ Bucket: physicalId })))?.BucketLocationType;
|
|
@@ -49882,8 +50740,63 @@ var S3DirectoryBucketProvider = class {
|
|
|
49882
50740
|
const result = { BucketName: physicalId };
|
|
49883
50741
|
if (physicalId.endsWith("--x-s3")) result["DataRedundancy"] = locationType === "LocalZone" ? "SingleLocalZone" : "SingleAvailabilityZone";
|
|
49884
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
|
+
});
|
|
49885
50756
|
return result;
|
|
49886
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
|
+
}
|
|
49887
50800
|
async readTags(bucketName) {
|
|
49888
50801
|
const accountId = await this.getAccountId();
|
|
49889
50802
|
const resourceArn = await this.buildBucketArn(bucketName, accountId);
|
|
@@ -50240,6 +51153,7 @@ var S3TablesProvider = class {
|
|
|
50240
51153
|
...tags !== void 0 && { tags }
|
|
50241
51154
|
}));
|
|
50242
51155
|
tableCreated = true;
|
|
51156
|
+
reportCreatedResource(logicalId, resourceType, physicalId);
|
|
50243
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);
|
|
50244
51158
|
const tableARN = response.tableARN;
|
|
50245
51159
|
this.logger.debug(`Successfully created S3 Tables Table ${logicalId}: ${physicalId}`);
|
|
@@ -50767,6 +51681,7 @@ var ECRProvider = class {
|
|
|
50767
51681
|
...tags ? { tags } : {}
|
|
50768
51682
|
}));
|
|
50769
51683
|
repositoryCreated = true;
|
|
51684
|
+
reportCreatedResource(logicalId, resourceType, repositoryName);
|
|
50770
51685
|
const repo = response.repository;
|
|
50771
51686
|
if (!repo?.repositoryName) throw new Error("CreateRepository did not return repository name");
|
|
50772
51687
|
const lifecyclePolicy = properties["LifecyclePolicy"];
|
|
@@ -51495,6 +52410,7 @@ var ACMCertificateProvider = class {
|
|
|
51495
52410
|
const certificateArn = (await this.acmClient.send(new RequestCertificateCommand(input))).CertificateArn;
|
|
51496
52411
|
if (!certificateArn) throw new ProvisioningError(`RequestCertificate succeeded but no CertificateArn returned for ${logicalId}`, resourceType, logicalId);
|
|
51497
52412
|
requestedArn = certificateArn;
|
|
52413
|
+
reportCreatedResource(logicalId, resourceType, certificateArn);
|
|
51498
52414
|
this.logger.debug(`Requested ACM certificate: ${certificateArn}`);
|
|
51499
52415
|
if (!(process.env["CDKD_NO_WAIT"] === "true")) await this.waitForCertificateIssued(certificateArn, logicalId, resourceType, dnsValidationZones(properties));
|
|
51500
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.`);
|
|
@@ -51508,6 +52424,7 @@ var ACMCertificateProvider = class {
|
|
|
51508
52424
|
};
|
|
51509
52425
|
} catch (error) {
|
|
51510
52426
|
const survivorNote = requestedArn ? await this.cleanupRequestedCertificate(requestedArn, logicalId, idempotencyToken, context?.maskSecrets) : void 0;
|
|
52427
|
+
if (requestedArn && survivorNote === void 0) retractCreatedResource(logicalId, resourceType, requestedArn);
|
|
51511
52428
|
if (error instanceof CdkdError) {
|
|
51512
52429
|
if (survivorNote === void 0) throw error;
|
|
51513
52430
|
const thrown = new ProvisioningError(`${error.message} ${survivorNote}`, resourceType, logicalId, requestedArn, error);
|
|
@@ -51796,4 +52713,4 @@ var ACMCertificateProvider = class {
|
|
|
51796
52713
|
|
|
51797
52714
|
//#endregion
|
|
51798
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 };
|
|
51799
|
-
//# sourceMappingURL=provider-classes-
|
|
52716
|
+
//# sourceMappingURL=provider-classes-DktsDsTf.js.map
|