@go-to-k/cdkd 0.284.40 → 0.284.42
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-BeKDzUe9.js → asg-provider-Dn9oXi9c.js} +2 -2
- package/dist/{asg-provider-BeKDzUe9.js.map → asg-provider-Dn9oXi9c.js.map} +1 -1
- package/dist/cli.js +242 -174
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-B3MQFW1K.js → deploy-engine-8ygMMbQ8.js} +416 -40
- package/dist/deploy-engine-8ygMMbQ8.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-B3MQFW1K.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as startInterruptWatch, $n as CdkdError, $t as WorkGraph, A as renderStatefulReason, An as resolveStateBucketWithDefault, At as redactSecretsForState, B as exportAliasCollisionScrubWarning, Bn as expectedOwnerParam, Bt as DiffCalculator, C as isFinalSnapshotError, Cn as synthesisStatusMessage, Cr as isMarkedNonRetryable, Ct as TEMPLATE_SOURCED_RULES, D as extractDeploymentEventError, Dn as resolveAutoAssetStorage, Dt as isSingleDynamicReferenceToken, E as makeCanonicalizePropertiesFn, En as resolveApp, Er as markNonRetryable, Et as errorCauseChain, F as green, Fn as CFN_TEMPLATE_BODY_LIMIT, Ft as s3BucketDomainName, G as collectInlinePolicyNamesManagedBySiblings, Gn as processStackMessages, Gt as TemplateParser, H as secretBearingStateKeyWarning, Hn as canonicalizeRegion, Ht as describeTypeWithThrottleRetry, I as red, In as CFN_TEMPLATE_URL_LIMIT, It as s3BucketDualStackDomainName, J as findActionableSilentDrops, Jn as AwsClients, Jt as S3StateBackend, K as clearOnUpdateRemoval, Kt as LockManager, L as yellow, Ln as MIGRATE_TMP_PREFIX, Lt as s3BucketRegionalDomainName, M as bold, Mn as resolveUseCdkBootstrapAssets, Mt as classifyReplaySecretRegion, N as cyan, Nn as stateBucketExistenceConfirmed, Nt as producerRegionsFromState, O as MULTI_REGION_RECREATE_BLOCKED_TYPES, On as resolveCaptureObservedState, Ot as maskSecretsInError, P as gray, Pn as warnDeprecatedNoPrefixCliFlag, Pt as s3BucketArn, Q as isInterruptedWaitError, Qt as stringifyValue, R as collectDeclaredOutputNames, Rn as findLargeInlineResources, Rt as s3BucketWebsiteUrl, S as createPreDeleteFinalSnapshot, Sn as Synthesizer, Sr as withErrorHandling, St as STATE_SOURCED_READBACK_RULES, T as unsupportedFinalSnapshotError, Tn as getLegacyStateBucketName, Tr as isThrottlingError, Tt as dynamicReferenceTokens, U as stateKeySecretExposure, Un as derivePartitionAndUrlSuffix, Ut as withRetry, V as isExportAliasCollision, Vn as PARTITION_TABLE, Vt as INTRINSIC_KEYS, W as IAMRoleProvider, Wn as AssemblyReader, Wt as DagBuilder, X as beginCommandInterruptScope, Xn as resetAwsClients, Xt as shouldRetainResource, Y as findSilentDropProperties, Yn as getAwsClients, Yt as rebuildClientForBucketRegion, Z as endCommandInterruptScope, Zn as setAwsClients, Zt as AssetPublisher, _ as computeImplicitDeleteEdges, _n as getDockerCmd, _t as replayWarn, a as DeploymentEventsStore, an as stripControlChars, ar as LocalInvokeBuildError$1, at as carriesDynamicReference, b as buildFinalSnapshotIdentifier, bn as AssetManifestLoader, bt as requireConfigString, c as replayFailedOperations, cn as ensureAssetStorage, ct as refStateLookupFromResource, d as updatePartialReason, dn as readBootstrapMarkerBody, dr as PartialFailureError, dt as resolveExplicitPhysicalId, en as buildAssetRedirectMap, et as CloudControlProvider, f as UNSPECIFIED_SKIP_REASON, fn as validateAssetBucketName, fr as ProvisioningError, ft as assertRegionMatch, g as IMPLICIT_DELETE_DEPENDENCIES, gn as formatDockerLoginError, gr as StackTerminationProtectionError, gt as readConfigString, h as maskingRetryLogger, hn as buildDockerImage, hr as StackHasActiveImportsError, ht as configStringRefusal, i as DeploymentEventsReader, in as escapeRegExp, ir as DynamicReferenceRegionAmbiguousError, it as IntrinsicFunctionResolver, j as formatResourceLine, jn as resolveStateBucketWithDefaultAndSource, jt as scrubResourceRecord, k as isStatefulRecreateTargetSync, kn as resolveSkipPrefix, kt as maskSecretsInText, l as replayRollback, ln as getBootstrapMarkerKey, lr as MissingCdkCliError, lt as WAFv2WebACLProvider, m as withResourceDeadline, mn as buildDenyExternalAccessPolicy, mr as ResourceUpdateNotSupportedError, mt as configBooleanRefusal, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as loadPublishableAssetManifest, nt as disableInstanceApiTermination, o as planFailedOps, on as AssetModeResolver, or as LocalMigrateError, ot as cfnRefValueFromPhysicalId, p as deleteSkipReason, pn as validateContainerRepoName, pr as ResourceTimeoutError, pt as coerceCfnBoolean, q as ProviderRegistry, qn as resolveBucketRegion, qt as displaySafe, r as DeployEngine, rn as rewriteTemplateAssetReferences, rr as DeployCancelledError, rt as isTerminationProtectionPropagationError, s as planRollback, sn as BOOTSTRAP_MARKER_PREFIX, sr as LocalStartServiceError, st as getAccountInfo, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as createAssetRedirectResolver, tr as CrossAccountSecretRefusalError, tt as slowCcOperationTimeoutMs, u as updatePartialMessage, un as parseBootstrapMarker, ur as NestedStackChildDirectDestroyError, ut as normalizeAwsTagsToCfn, v as ATOMIC_FINAL_SNAPSHOT_TYPES, vn as runDockerForeground, vt as requireConfigArray, w as refusesFinalSnapshot, wn as getDefaultStateBucketName, wr as isRetryableTransientError, wt as createSecretMasker, x as ccRoutedFinalSnapshotError, xn as getDockerImageBySourceHash, xr as normalizeAwsError, xt as STATE_SOURCED_CROSS_GENERATION_RULES, y as PRE_DELETE_SNAPSHOT_TYPES, yn as runDockerStreaming, yt as requireConfigObject, z as collectPublishedOutputNames, zn as uploadCfnTemplate, zt as applyRoleArnIfSet } from "./deploy-engine-
|
|
2
|
+
import { $ as startInterruptWatch, $n as CdkdError, $t as WorkGraph, A as renderStatefulReason, An as resolveStateBucketWithDefault, At as redactSecretsForState, B as exportAliasCollisionScrubWarning, Bn as expectedOwnerParam, Bt as DiffCalculator, C as isFinalSnapshotError, Cn as synthesisStatusMessage, Cr as isMarkedNonRetryable, Ct as TEMPLATE_SOURCED_RULES, D as extractDeploymentEventError, Dn as resolveAutoAssetStorage, Dt as isSingleDynamicReferenceToken, E as makeCanonicalizePropertiesFn, En as resolveApp, Er as markNonRetryable, Et as errorCauseChain, F as green, Fn as CFN_TEMPLATE_BODY_LIMIT, Ft as s3BucketDomainName, G as collectInlinePolicyNamesManagedBySiblings, Gn as processStackMessages, Gt as TemplateParser, H as secretBearingStateKeyWarning, Hn as canonicalizeRegion, Ht as describeTypeWithThrottleRetry, I as red, In as CFN_TEMPLATE_URL_LIMIT, It as s3BucketDualStackDomainName, J as findActionableSilentDrops, Jn as AwsClients, Jt as S3StateBackend, K as clearOnUpdateRemoval, Kt as LockManager, L as yellow, Ln as MIGRATE_TMP_PREFIX, Lt as s3BucketRegionalDomainName, M as bold, Mn as resolveUseCdkBootstrapAssets, Mt as classifyReplaySecretRegion, N as cyan, Nn as stateBucketExistenceConfirmed, Nt as producerRegionsFromState, O as MULTI_REGION_RECREATE_BLOCKED_TYPES, On as resolveCaptureObservedState, Ot as maskSecretsInError, P as gray, Pn as warnDeprecatedNoPrefixCliFlag, Pt as s3BucketArn, Q as isInterruptedWaitError, Qt as stringifyValue, R as collectDeclaredOutputNames, Rn as findLargeInlineResources, Rt as s3BucketWebsiteUrl, S as createPreDeleteFinalSnapshot, Sn as Synthesizer, Sr as withErrorHandling, St as STATE_SOURCED_READBACK_RULES, T as unsupportedFinalSnapshotError, Tn as getLegacyStateBucketName, Tr as isThrottlingError, Tt as dynamicReferenceTokens, U as stateKeySecretExposure, Un as derivePartitionAndUrlSuffix, Ut as withRetry, V as isExportAliasCollision, Vn as PARTITION_TABLE, Vt as INTRINSIC_KEYS, W as IAMRoleProvider, Wn as AssemblyReader, Wt as DagBuilder, X as beginCommandInterruptScope, Xn as resetAwsClients, Xt as shouldRetainResource, Y as findSilentDropProperties, Yn as getAwsClients, Yt as rebuildClientForBucketRegion, Z as endCommandInterruptScope, Zn as setAwsClients, Zt as AssetPublisher, _ as computeImplicitDeleteEdges, _n as getDockerCmd, _t as replayWarn, a as DeploymentEventsStore, an as stripControlChars, ar as LocalInvokeBuildError$1, at as carriesDynamicReference, b as buildFinalSnapshotIdentifier, bn as AssetManifestLoader, bt as requireConfigString, c as replayFailedOperations, cn as ensureAssetStorage, ct as refStateLookupFromResource, d as updatePartialReason, dn as readBootstrapMarkerBody, dr as PartialFailureError, dt as resolveExplicitPhysicalId, en as buildAssetRedirectMap, et as CloudControlProvider, f as UNSPECIFIED_SKIP_REASON, fn as validateAssetBucketName, fr as ProvisioningError, ft as assertRegionMatch, g as IMPLICIT_DELETE_DEPENDENCIES, gn as formatDockerLoginError, gr as StackTerminationProtectionError, gt as readConfigString, h as maskingRetryLogger, hn as buildDockerImage, hr as StackHasActiveImportsError, ht as configStringRefusal, i as DeploymentEventsReader, in as escapeRegExp, ir as DynamicReferenceRegionAmbiguousError, it as IntrinsicFunctionResolver, j as formatResourceLine, jn as resolveStateBucketWithDefaultAndSource, jt as scrubResourceRecord, k as isStatefulRecreateTargetSync, kn as resolveSkipPrefix, kt as maskSecretsInText, l as replayRollback, ln as getBootstrapMarkerKey, lr as MissingCdkCliError, lt as WAFv2WebACLProvider, m as withResourceDeadline, mn as buildDenyExternalAccessPolicy, mr as ResourceUpdateNotSupportedError, mt as configBooleanRefusal, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as loadPublishableAssetManifest, nt as disableInstanceApiTermination, o as planFailedOps, on as AssetModeResolver, or as LocalMigrateError, ot as cfnRefValueFromPhysicalId, p as deleteSkipReason, pn as validateContainerRepoName, pr as ResourceTimeoutError, pt as coerceCfnBoolean, q as ProviderRegistry, qn as resolveBucketRegion, qt as displaySafe, r as DeployEngine, rn as rewriteTemplateAssetReferences, rr as DeployCancelledError, rt as isTerminationProtectionPropagationError, s as planRollback, sn as BOOTSTRAP_MARKER_PREFIX, sr as LocalStartServiceError, st as getAccountInfo, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as createAssetRedirectResolver, tr as CrossAccountSecretRefusalError, tt as slowCcOperationTimeoutMs, u as updatePartialMessage, un as parseBootstrapMarker, ur as NestedStackChildDirectDestroyError, ut as normalizeAwsTagsToCfn, v as ATOMIC_FINAL_SNAPSHOT_TYPES, vn as runDockerForeground, vt as requireConfigArray, w as refusesFinalSnapshot, wn as getDefaultStateBucketName, wr as isRetryableTransientError, wt as createSecretMasker, x as ccRoutedFinalSnapshotError, xn as getDockerImageBySourceHash, xr as normalizeAwsError, xt as STATE_SOURCED_CROSS_GENERATION_RULES, y as PRE_DELETE_SNAPSHOT_TYPES, yn as runDockerStreaming, yt as requireConfigObject, z as collectPublishedOutputNames, zn as uploadCfnTemplate, zt as applyRoleArnIfSet } from "./deploy-engine-8ygMMbQ8.js";
|
|
3
3
|
import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as getCurrentStackName, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
|
|
4
|
-
import { t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-Dn9oXi9c.js";
|
|
5
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
6
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
7
7
|
import { CopyObjectCommand, 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, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -10324,6 +10324,121 @@ function isSqsQueueUrl(value) {
|
|
|
10324
10324
|
return value.startsWith("https://sqs.") && value.includes("/");
|
|
10325
10325
|
}
|
|
10326
10326
|
|
|
10327
|
+
//#endregion
|
|
10328
|
+
//#region src/provisioning/masked-retry-logger.ts
|
|
10329
|
+
/**
|
|
10330
|
+
* The masker a caller supplied, or the identity function when it supplied
|
|
10331
|
+
* none.
|
|
10332
|
+
*
|
|
10333
|
+
* ABSENT MEANS UNMASKED, and that is the back-compatible default the contract
|
|
10334
|
+
* mandates — `create()` / `update()` are also reached from the import path,
|
|
10335
|
+
* from `cdkd drift --revert`, and from tests, and a provider must not care
|
|
10336
|
+
* which caller it got. Centralised here so no call site re-spells the `??`
|
|
10337
|
+
* and accidentally makes the capability required.
|
|
10338
|
+
*/
|
|
10339
|
+
function maskerOrIdentity(maskSecrets) {
|
|
10340
|
+
return maskSecrets ?? ((text) => text);
|
|
10341
|
+
}
|
|
10342
|
+
/**
|
|
10343
|
+
* A {@link RetryLogger} whose every line is routed through `maskSecrets`.
|
|
10344
|
+
*
|
|
10345
|
+
* `warn` is ALWAYS provided, never omitted. It is optional on `RetryLogger`,
|
|
10346
|
+
* and dropping it would silence the give-up summary on the calling path only —
|
|
10347
|
+
* trading a disclosure for the reporting hole issue #2018 closed. It goes
|
|
10348
|
+
* through the SAME mask as `debug` precisely because it is the line that
|
|
10349
|
+
* survives a run without `--verbose`; forwarding it unmasked would defeat the
|
|
10350
|
+
* fence at a HIGHER log level than the one the fence was written for.
|
|
10351
|
+
*
|
|
10352
|
+
* `logger` is typed structurally rather than as the concrete `Logger` so this
|
|
10353
|
+
* module stays a leaf and a test can pass two spies. That matches the
|
|
10354
|
+
* precedent already in the tree (`buildMfaConfigRequest` in
|
|
10355
|
+
* `cognito-provider.ts` takes an injected `logger?: { warn }`).
|
|
10356
|
+
*/
|
|
10357
|
+
function createMaskedRetryLogger(logger, maskSecrets) {
|
|
10358
|
+
const mask = maskerOrIdentity(maskSecrets);
|
|
10359
|
+
return {
|
|
10360
|
+
debug: (message) => logger.debug(mask(message)),
|
|
10361
|
+
warn: (message) => logger.warn(mask(message))
|
|
10362
|
+
};
|
|
10363
|
+
}
|
|
10364
|
+
/**
|
|
10365
|
+
* Depth cap for {@link maskDeep}.
|
|
10366
|
+
*
|
|
10367
|
+
* What it actually bounds is unbounded WORK on a pathologically deep bag — see
|
|
10368
|
+
* the rationale at the cap itself, which is the authority. It is NOT primarily
|
|
10369
|
+
* a cycle guard: a template-derived bag cannot be cyclic, so that justification
|
|
10370
|
+
* over-claims (issue #2176 security review). It does still terminate one, which
|
|
10371
|
+
* is why the walk is safe to share with a caller that might hand it something
|
|
10372
|
+
* other than a template bag.
|
|
10373
|
+
*
|
|
10374
|
+
* Deliberately generous. Every shape these warnings exist to describe is a
|
|
10375
|
+
* scalar, a list of scalars, or a small record, so the walk does not reach
|
|
10376
|
+
* depth 2 in practice.
|
|
10377
|
+
*/
|
|
10378
|
+
const MASK_WALK_MAX_DEPTH = 8;
|
|
10379
|
+
/**
|
|
10380
|
+
* What {@link maskDeep} substitutes for a subtree it declines to descend into.
|
|
10381
|
+
*
|
|
10382
|
+
* MUST equal `SECRET_MASK` in `src/deployment/secret-redaction.ts`. It is
|
|
10383
|
+
* spelled here rather than imported so this module keeps its single-import leaf
|
|
10384
|
+
* property (see the module note above); the two are fenced against drift by a
|
|
10385
|
+
* test that imports both.
|
|
10386
|
+
*/
|
|
10387
|
+
const MASK_WALK_DEPTH_CAP_MARKER = "***";
|
|
10388
|
+
/**
|
|
10389
|
+
* Mask every string LEAF and KEY of an arbitrary value, returning a structure
|
|
10390
|
+
* safe to `JSON.stringify` into a log line or an error message (issue
|
|
10391
|
+
* [#2176](https://github.com/go-to-k/cdkd/issues/2176)).
|
|
10392
|
+
*
|
|
10393
|
+
* THE ORDERING IS THE WHOLE POINT, and it is why masking the finished message
|
|
10394
|
+
* is not a substitute. `maskSecretsInText` matches by literal occurrence, so:
|
|
10395
|
+
*
|
|
10396
|
+
* 1. ESCAPING. `JSON.stringify` escapes `"`, `\` and newlines, so a secret
|
|
10397
|
+
* containing any of them no longer OCCURS in the stringified text and a
|
|
10398
|
+
* mask applied afterwards cannot find it. That is not an exotic case — it
|
|
10399
|
+
* is every Secrets Manager JSON document, the commonest real secret shape.
|
|
10400
|
+
* Measured on the pre-fix tree for #2176: a plaintext of
|
|
10401
|
+
* `{"user":"admin","pw":"hunter2"}` interpolated as
|
|
10402
|
+
* `${JSON.stringify(value)}` came through a message-level mask COMPLETELY
|
|
10403
|
+
* unchanged, while masking the leaves first rendered it `"***"`.
|
|
10404
|
+
* 2. LENGTH. A finished message is always longer than the value inside it, so
|
|
10405
|
+
* it can only ever reach `maskSecretsInText`'s SUBSTRING arm, which ignores
|
|
10406
|
+
* needles below `MIN_NEEDLE_LENGTH` (4). Handing the masker each RAW leaf
|
|
10407
|
+
* reaches the WHOLE-VALUE arm, which has no floor. Measured the same way: a
|
|
10408
|
+
* 3-character secret survived `Value 'abc' at 'pin' failed ...` intact.
|
|
10409
|
+
*
|
|
10410
|
+
* Neither pass subsumes the other, so providers do BOTH — this walk on the
|
|
10411
|
+
* value, and the assembled message through the masker as well. The masker is
|
|
10412
|
+
* idempotent, so the overlap is free.
|
|
10413
|
+
*
|
|
10414
|
+
* Keys are masked as well as values: `JSON.stringify` renders them into the
|
|
10415
|
+
* same line, so a resolved secret used as a map key would otherwise escape.
|
|
10416
|
+
*
|
|
10417
|
+
* WHY THIS LIVES HERE rather than as a private walk per provider. SIX
|
|
10418
|
+
* hand-rolled copies had already accumulated — `elbv2-provider.ts`,
|
|
10419
|
+
* `cognito-provider.ts`, `sns-topic-provider.ts`, `dynamodb-table-provider.ts`,
|
|
10420
|
+
* `dynamodb-globaltable-provider.ts` and `apigatewayv2-provider.ts` — and
|
|
10421
|
+
* `elbv2-provider.ts` carried the standing instruction that "a THIRD site is
|
|
10422
|
+
* the point at which this should move into `../masked-retry-logger.ts` ... and
|
|
10423
|
+
* all three converge on it". That trigger had fired and been missed twice over,
|
|
10424
|
+
* and the copies had already diverged exactly as predicted: FOUR of the six
|
|
10425
|
+
* carried NO depth cap at all.
|
|
10426
|
+
*
|
|
10427
|
+
* Worth recording how the last two were nearly missed AGAIN, because it is the
|
|
10428
|
+
* same failure one level up: the first sweep for this issue grepped for
|
|
10429
|
+
* `maskDeep` / `MASK_WALK_MAX_DEPTH` — the SPELLINGS the known copies used —
|
|
10430
|
+
* and the two survivors spell it `maskLeaf` / `maskLeafValue` with no named
|
|
10431
|
+
* constant. Grep for the SHAPE, not the name. These copies encode a security
|
|
10432
|
+
* contract, and a hardening applied to one silently leaves the others behind.
|
|
10433
|
+
*/
|
|
10434
|
+
function maskDeep(value, mask, depth = 0) {
|
|
10435
|
+
if (typeof value === "string") return mask(value);
|
|
10436
|
+
if (depth >= 8) return "***";
|
|
10437
|
+
if (Array.isArray(value)) return value.map((entry) => maskDeep(entry, mask, depth + 1));
|
|
10438
|
+
if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([k, v]) => [mask(k), maskDeep(v, mask, depth + 1)]));
|
|
10439
|
+
return value;
|
|
10440
|
+
}
|
|
10441
|
+
|
|
10327
10442
|
//#endregion
|
|
10328
10443
|
//#region src/provisioning/providers/sns-topic-provider.ts
|
|
10329
10444
|
/**
|
|
@@ -10979,12 +11094,7 @@ function buildDeliveryStatusAttributeMap(logging, logicalId, onMalformed, maskSe
|
|
|
10979
11094
|
const warn = (message) => {
|
|
10980
11095
|
getLogger().child("SNSTopicProvider").warn(maskSecrets(message));
|
|
10981
11096
|
};
|
|
10982
|
-
const maskLeaf = (value) =>
|
|
10983
|
-
if (typeof value === "string") return maskSecrets(value);
|
|
10984
|
-
if (Array.isArray(value)) return value.map(maskLeaf);
|
|
10985
|
-
if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([k, v]) => [maskSecrets(k), maskLeaf(v)]));
|
|
10986
|
-
return value;
|
|
10987
|
-
};
|
|
11097
|
+
const maskLeaf = (value) => maskDeep(value, maskSecrets);
|
|
10988
11098
|
const seenProtocols = /* @__PURE__ */ new Set();
|
|
10989
11099
|
if (!Array.isArray(logging)) {
|
|
10990
11100
|
if (onMalformed === "throw") throw new Error(`SNS topic ${logicalId}: DeliveryStatusLogging must be an array of {Protocol, ...} objects, got ${JSON.stringify(maskLeaf(logging))}`);
|
|
@@ -13955,10 +14065,11 @@ function idShape(segments) {
|
|
|
13955
14065
|
* mis-names one value frequently mis-names its sibling too, and reporting them
|
|
13956
14066
|
* one deploy at a time is the shape of remedy nobody finishes.
|
|
13957
14067
|
*/
|
|
13958
|
-
function compositeIdSeparatorRefusal(resourceType, logicalId, segments) {
|
|
14068
|
+
function compositeIdSeparatorRefusal(resourceType, logicalId, segments, maskSecrets) {
|
|
13959
14069
|
const offending = segments.filter((segment) => String(segment.value).includes("|"));
|
|
13960
14070
|
if (offending.length === 0) return void 0;
|
|
13961
|
-
|
|
14071
|
+
const mask = maskerOrIdentity(maskSecrets);
|
|
14072
|
+
return `${resourceType} ${logicalId}: ${offending.map((segment) => `${segment.name} '${mask(String(segment.value))}'`).join(" and ")} contains '${"|"}', which cdkd uses as the separator in this type's physical id (${idShape(segments)}). Recording it would produce an id that decodes back to a DIFFERENT resource, so a later cdkd destroy / drift / update would target the wrong one — or silently skip it while the real resource stays alive. AWS accepts the name and CloudFormation manages such a resource fine; this is a cdkd limitation tracked in ${COMPOSITE_ID_ISSUE_URL}. Rename the resource so no segment contains '${"|"}', or manage it outside cdkd.`;
|
|
13962
14073
|
}
|
|
13963
14074
|
/**
|
|
13964
14075
|
* Join the segments into a composite physicalId, REFUSING one that would be
|
|
@@ -13970,7 +14081,7 @@ function compositeIdSeparatorRefusal(resourceType, logicalId, segments) {
|
|
|
13970
14081
|
* behavior.
|
|
13971
14082
|
*/
|
|
13972
14083
|
function packCompositeId(resourceType, logicalId, segments, options) {
|
|
13973
|
-
const refusal = compositeIdSeparatorRefusal(resourceType, logicalId, segments);
|
|
14084
|
+
const refusal = compositeIdSeparatorRefusal(resourceType, logicalId, segments, options?.maskSecrets);
|
|
13974
14085
|
if (refusal !== void 0) if (options?.onRefusal) options.onRefusal(`${refusal} Continuing with the ambiguous id because the value comes from a cdkd state record, which no template edit can repair; the same value is REFUSED on a template-path create.`);
|
|
13975
14086
|
else throw new ProvisioningError(refusal, resourceType, logicalId);
|
|
13976
14087
|
return segments.map((segment) => String(segment.value)).join("|");
|
|
@@ -14163,7 +14274,10 @@ var LambdaEventInvokeConfigProvider = class {
|
|
|
14163
14274
|
coerceNumber: true,
|
|
14164
14275
|
...replayWarn(this.logger, context)
|
|
14165
14276
|
});
|
|
14166
|
-
const physicalId = this.buildPhysicalId(logicalId, functionName, qualifier,
|
|
14277
|
+
const physicalId = this.buildPhysicalId(logicalId, functionName, qualifier, {
|
|
14278
|
+
maskSecrets: context?.maskSecrets,
|
|
14279
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
14280
|
+
});
|
|
14167
14281
|
try {
|
|
14168
14282
|
await this.lambdaClient.send(new PutFunctionEventInvokeConfigCommand(this.buildPutInput(properties)));
|
|
14169
14283
|
this.logger.debug(`Successfully created Lambda EventInvokeConfig ${logicalId}: ${physicalId}`);
|
|
@@ -16333,10 +16447,7 @@ const deleteTableRetryDelays$1 = {};
|
|
|
16333
16447
|
* leaf is stringified — and escaped — identically.
|
|
16334
16448
|
*/
|
|
16335
16449
|
function maskLeafValue$1(value, maskSecrets) {
|
|
16336
|
-
|
|
16337
|
-
if (Array.isArray(value)) return value.map((v) => maskLeafValue$1(v, maskSecrets));
|
|
16338
|
-
if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([k, v]) => [maskSecrets(k), maskLeafValue$1(v, maskSecrets)]));
|
|
16339
|
-
return value;
|
|
16450
|
+
return maskDeep(value, maskSecrets);
|
|
16340
16451
|
}
|
|
16341
16452
|
var DynamoDBTableProvider = class {
|
|
16342
16453
|
dynamoDBClient;
|
|
@@ -17245,7 +17356,7 @@ var DynamoDBTableProvider = class {
|
|
|
17245
17356
|
const warn = (message) => this.logger.warn(maskSecrets(message));
|
|
17246
17357
|
const coerced = coerceWarmThroughput(value);
|
|
17247
17358
|
if (coerced === void 0) return void 0;
|
|
17248
|
-
if (coerced.dropped.length > 0) warn(`${scope}: WarmThroughput member(s) ${coerced.dropped.join(", ")} in ${JSON.stringify(maskLeafValue$1(value, maskSecrets))} are not a number DynamoDB accepts, so they were dropped from the request, which leaves ${JSON.stringify(coerced.spec)}. Check for an unresolved intrinsic or a non-numeric value.`);
|
|
17359
|
+
if (coerced.dropped.length > 0) warn(`${scope}: WarmThroughput member(s) ${coerced.dropped.join(", ")} in ${JSON.stringify(maskLeafValue$1(value, maskSecrets))} are not a number DynamoDB accepts, so they were dropped from the request, which leaves ${JSON.stringify(maskLeafValue$1(coerced.spec, maskSecrets))}. Check for an unresolved intrinsic or a non-numeric value.`);
|
|
17249
17360
|
return coerced.spec;
|
|
17250
17361
|
}
|
|
17251
17362
|
/**
|
|
@@ -17895,18 +18006,17 @@ const DRIFT_STRIPPED_INDEX_MEMBERS = [{
|
|
|
17895
18006
|
* by value rather than by position, so the two layers compose.
|
|
17896
18007
|
*
|
|
17897
18008
|
* Walks rather than testing the top level, because a secret nested in an object
|
|
17898
|
-
* or array leaf is stringified — and escaped — identically.
|
|
17899
|
-
*
|
|
17900
|
-
*
|
|
17901
|
-
*
|
|
17902
|
-
*
|
|
17903
|
-
*
|
|
18009
|
+
* or array leaf is stringified — and escaped — identically.
|
|
18010
|
+
*
|
|
18011
|
+
* Issue #2176 hoisted the walk into `../masked-retry-logger.js`. The previous
|
|
18012
|
+
* note here said the helper was "duplicated rather than shared because these two
|
|
18013
|
+
* files deliberately hold no common module today" — that rationale expired the
|
|
18014
|
+
* moment a shared LEAF module existed for exactly this, and it had already cost
|
|
18015
|
+
* something: this copy carried NO depth cap, so it was one of SIX copies that
|
|
18016
|
+
* had drifted apart on the one property that matters.
|
|
17904
18017
|
*/
|
|
17905
18018
|
function maskLeafValue(value, maskSecrets) {
|
|
17906
|
-
|
|
17907
|
-
if (Array.isArray(value)) return value.map((v) => maskLeafValue(v, maskSecrets));
|
|
17908
|
-
if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([k, v]) => [maskSecrets(k), maskLeafValue(v, maskSecrets)]));
|
|
17909
|
-
return value;
|
|
18019
|
+
return maskDeep(value, maskSecrets);
|
|
17910
18020
|
}
|
|
17911
18021
|
var DynamoDBGlobalTableProvider = class {
|
|
17912
18022
|
dynamoDBClient;
|
|
@@ -22786,11 +22896,11 @@ var SSMParameterProvider = class {
|
|
|
22786
22896
|
* whole body is wrapped: an unexpected failure degrades to "no Arn recorded"
|
|
22787
22897
|
* exactly as the fabricated-account arm does.
|
|
22788
22898
|
*/
|
|
22789
|
-
async buildParameterArn(name) {
|
|
22899
|
+
async buildParameterArn(name, mask) {
|
|
22790
22900
|
try {
|
|
22791
|
-
return await this.buildParameterArnUnguarded(name);
|
|
22901
|
+
return await this.buildParameterArnUnguarded(name, mask);
|
|
22792
22902
|
} catch (error) {
|
|
22793
|
-
this.logger.warn(`Could not build the Arn attribute for SSM parameter ${name}: ${error instanceof Error ? error.message : String(error)}. The parameter itself is unaffected; the Arn is NOT recorded, so an Fn::GetAtt on it will fail until a later deploy records it.`);
|
|
22903
|
+
this.logger.warn(mask(`Could not build the Arn attribute for SSM parameter ${name}: ${error instanceof Error ? error.message : String(error)}. The parameter itself is unaffected; the Arn is NOT recorded, so an Fn::GetAtt on it will fail until a later deploy records it.`));
|
|
22794
22904
|
return;
|
|
22795
22905
|
}
|
|
22796
22906
|
}
|
|
@@ -22810,10 +22920,10 @@ var SSMParameterProvider = class {
|
|
|
22810
22920
|
* import RECORDED it, so the fix belongs at the import boundary — where
|
|
22811
22921
|
* `import()` now refuses it — and not here. Do not re-add it.
|
|
22812
22922
|
*/
|
|
22813
|
-
async buildParameterArnUnguarded(name) {
|
|
22923
|
+
async buildParameterArnUnguarded(name, mask) {
|
|
22814
22924
|
const accountInfo = await getAccountInfo(await this.ssmClient.config.region());
|
|
22815
22925
|
if (accountInfo.fabricated) {
|
|
22816
|
-
this.logger.warn(`Cannot determine the AWS account (STS is unreachable, and the resolved account id is a placeholder), so the Arn attribute for SSM parameter ${name} would be fabricated and is NOT recorded. An Fn::GetAtt on it will fail until a later deploy resolves the account.`);
|
|
22926
|
+
this.logger.warn(mask(`Cannot determine the AWS account (STS is unreachable, and the resolved account id is a placeholder), so the Arn attribute for SSM parameter ${name} would be fabricated and is NOT recorded. An Fn::GetAtt on it will fail until a later deploy resolves the account.`));
|
|
22817
22927
|
return;
|
|
22818
22928
|
}
|
|
22819
22929
|
const { partition } = derivePartitionAndUrlSuffix(accountInfo.region);
|
|
@@ -22823,8 +22933,11 @@ var SSMParameterProvider = class {
|
|
|
22823
22933
|
/**
|
|
22824
22934
|
* Create an SSM parameter
|
|
22825
22935
|
*/
|
|
22826
|
-
async create(logicalId, resourceType, properties) {
|
|
22827
|
-
|
|
22936
|
+
async create(logicalId, resourceType, properties, context) {
|
|
22937
|
+
const mask = maskerOrIdentity(context?.maskSecrets);
|
|
22938
|
+
const warn = (message) => this.logger.warn(mask(message));
|
|
22939
|
+
const debug = (message) => this.logger.debug(mask(message));
|
|
22940
|
+
debug(`Creating SSM parameter ${logicalId}`);
|
|
22828
22941
|
const name = properties["Name"] || `/${generateResourceName(logicalId, {
|
|
22829
22942
|
maxLength: 1023,
|
|
22830
22943
|
allowedPattern: /[^a-zA-Z0-9-/_]/g
|
|
@@ -22855,14 +22968,14 @@ var SSMParameterProvider = class {
|
|
|
22855
22968
|
} catch (innerError) {
|
|
22856
22969
|
try {
|
|
22857
22970
|
await this.ssmClient.send(new DeleteParameterCommand({ Name: name }));
|
|
22858
|
-
|
|
22971
|
+
debug(`Cleaned up partially-created SSM parameter ${logicalId} (${name}) after wiring failure`);
|
|
22859
22972
|
} catch (cleanupError) {
|
|
22860
|
-
|
|
22973
|
+
warn(`Failed to clean up partially-created SSM parameter ${logicalId} (${name}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws ssm delete-parameter --name '${name}'`);
|
|
22861
22974
|
}
|
|
22862
22975
|
throw innerError;
|
|
22863
22976
|
}
|
|
22864
|
-
|
|
22865
|
-
const arn = await this.buildParameterArn(name);
|
|
22977
|
+
debug(`Successfully created SSM parameter ${logicalId}: ${name}`);
|
|
22978
|
+
const arn = await this.buildParameterArn(name, mask);
|
|
22866
22979
|
return {
|
|
22867
22980
|
physicalId: name,
|
|
22868
22981
|
attributes: {
|
|
@@ -22873,14 +22986,16 @@ var SSMParameterProvider = class {
|
|
|
22873
22986
|
};
|
|
22874
22987
|
} catch (error) {
|
|
22875
22988
|
const cause = error instanceof Error ? error : void 0;
|
|
22876
|
-
throw new ProvisioningError(`Failed to create SSM parameter ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
22989
|
+
throw new ProvisioningError(`Failed to create SSM parameter ${logicalId}: ${mask(error instanceof Error ? error.message : String(error))}`, resourceType, logicalId, void 0, cause);
|
|
22877
22990
|
}
|
|
22878
22991
|
}
|
|
22879
22992
|
/**
|
|
22880
22993
|
* Update an SSM parameter
|
|
22881
22994
|
*/
|
|
22882
|
-
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
22883
|
-
|
|
22995
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
22996
|
+
const mask = maskerOrIdentity(context?.maskSecrets);
|
|
22997
|
+
const debug = (message) => this.logger.debug(mask(message));
|
|
22998
|
+
debug(`Updating SSM parameter ${logicalId}: ${physicalId}`);
|
|
22884
22999
|
const type = properties["Type"] || "String";
|
|
22885
23000
|
const value = properties["Value"];
|
|
22886
23001
|
if (!value) throw new ProvisioningError(`Value is required for SSM parameter ${logicalId}`, resourceType, logicalId, physicalId);
|
|
@@ -22912,10 +23027,10 @@ var SSMParameterProvider = class {
|
|
|
22912
23027
|
ResourceId: physicalId,
|
|
22913
23028
|
Tags: newTags
|
|
22914
23029
|
}));
|
|
22915
|
-
|
|
23030
|
+
debug(`Updated tags for SSM parameter ${physicalId}`);
|
|
22916
23031
|
}
|
|
22917
|
-
|
|
22918
|
-
const arn = await this.buildParameterArn(physicalId);
|
|
23032
|
+
debug(`Successfully updated SSM parameter ${logicalId}`);
|
|
23033
|
+
const arn = await this.buildParameterArn(physicalId, mask);
|
|
22919
23034
|
return {
|
|
22920
23035
|
physicalId,
|
|
22921
23036
|
wasReplaced: false,
|
|
@@ -22927,7 +23042,7 @@ var SSMParameterProvider = class {
|
|
|
22927
23042
|
};
|
|
22928
23043
|
} catch (error) {
|
|
22929
23044
|
const cause = error instanceof Error ? error : void 0;
|
|
22930
|
-
throw new ProvisioningError(`Failed to update SSM parameter ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
23045
|
+
throw new ProvisioningError(`Failed to update SSM parameter ${logicalId}: ${mask(error instanceof Error ? error.message : String(error))}`, resourceType, logicalId, physicalId, cause);
|
|
22931
23046
|
}
|
|
22932
23047
|
}
|
|
22933
23048
|
/**
|
|
@@ -24402,10 +24517,10 @@ var EC2Provider = class {
|
|
|
24402
24517
|
case "AWS::EC2::VPCGatewayAttachment": return this.createVpcGatewayAttachment(logicalId, resourceType, properties, context);
|
|
24403
24518
|
case "AWS::EC2::NatGateway": return this.createNatGateway(logicalId, resourceType, properties);
|
|
24404
24519
|
case "AWS::EC2::RouteTable": return this.createRouteTable(logicalId, resourceType, properties);
|
|
24405
|
-
case "AWS::EC2::Route": return this.createRoute(logicalId, resourceType, properties, context?.replayingState === true ? (message) => this.logger.warn(message) : void 0);
|
|
24520
|
+
case "AWS::EC2::Route": return this.createRoute(logicalId, resourceType, properties, context?.replayingState === true ? (message) => this.logger.warn(message) : void 0, context?.maskSecrets);
|
|
24406
24521
|
case "AWS::EC2::SubnetRouteTableAssociation": return this.createSubnetRouteTableAssociation(logicalId, resourceType, properties);
|
|
24407
24522
|
case "AWS::EC2::SecurityGroup": return this.createSecurityGroup(logicalId, resourceType, properties);
|
|
24408
|
-
case "AWS::EC2::SecurityGroupIngress": return this.createSecurityGroupIngress(logicalId, resourceType, properties, context?.replayingState === true ? (message) => this.logger.warn(message) : void 0);
|
|
24523
|
+
case "AWS::EC2::SecurityGroupIngress": return this.createSecurityGroupIngress(logicalId, resourceType, properties, context?.replayingState === true ? (message) => this.logger.warn(message) : void 0, context?.maskSecrets);
|
|
24409
24524
|
case "AWS::EC2::Instance": return this.createInstance(logicalId, resourceType, properties, context);
|
|
24410
24525
|
case "AWS::EC2::NetworkAcl": return this.createNetworkAcl(logicalId, resourceType, properties);
|
|
24411
24526
|
case "AWS::EC2::NetworkAclEntry": return this.createNetworkAclEntry(logicalId, resourceType, properties, context);
|
|
@@ -24413,16 +24528,16 @@ var EC2Provider = class {
|
|
|
24413
24528
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
|
|
24414
24529
|
}
|
|
24415
24530
|
}
|
|
24416
|
-
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
24531
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
24417
24532
|
try {
|
|
24418
|
-
return await this.applyUpdate(logicalId, physicalId, resourceType, properties, previousProperties);
|
|
24533
|
+
return await this.applyUpdate(logicalId, physicalId, resourceType, properties, previousProperties, context);
|
|
24419
24534
|
} catch (error) {
|
|
24420
24535
|
if (error instanceof CdkdError) throw error;
|
|
24421
24536
|
const cause = error instanceof Error ? error : void 0;
|
|
24422
24537
|
throw new ProvisioningError(`Failed to update EC2 resource ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
24423
24538
|
}
|
|
24424
24539
|
}
|
|
24425
|
-
async applyUpdate(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
24540
|
+
async applyUpdate(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
24426
24541
|
switch (resourceType) {
|
|
24427
24542
|
case "AWS::EC2::VPC": return this.updateVpc(logicalId, physicalId, resourceType, properties, previousProperties);
|
|
24428
24543
|
case "AWS::EC2::Subnet": return this.updateSubnet(logicalId, physicalId, resourceType, properties, previousProperties);
|
|
@@ -24431,10 +24546,10 @@ var EC2Provider = class {
|
|
|
24431
24546
|
case "AWS::EC2::VPCGatewayAttachment": return this.updateVpcGatewayAttachment(logicalId, physicalId);
|
|
24432
24547
|
case "AWS::EC2::NatGateway": return this.updateNatGateway(logicalId, physicalId);
|
|
24433
24548
|
case "AWS::EC2::RouteTable": return this.updateRouteTable(logicalId, physicalId);
|
|
24434
|
-
case "AWS::EC2::Route": return this.updateRoute(logicalId, physicalId, resourceType, properties, previousProperties);
|
|
24549
|
+
case "AWS::EC2::Route": return this.updateRoute(logicalId, physicalId, resourceType, properties, previousProperties, context?.maskSecrets);
|
|
24435
24550
|
case "AWS::EC2::SubnetRouteTableAssociation": return this.updateSubnetRouteTableAssociation(logicalId, physicalId);
|
|
24436
24551
|
case "AWS::EC2::SecurityGroup": return this.updateSecurityGroup(logicalId, physicalId, resourceType, properties, previousProperties);
|
|
24437
|
-
case "AWS::EC2::SecurityGroupIngress": return this.updateSecurityGroupIngress(logicalId, physicalId, resourceType, properties, previousProperties);
|
|
24552
|
+
case "AWS::EC2::SecurityGroupIngress": return this.updateSecurityGroupIngress(logicalId, physicalId, resourceType, properties, previousProperties, context?.maskSecrets);
|
|
24438
24553
|
case "AWS::EC2::Instance": return this.updateInstance(logicalId, physicalId, resourceType, properties, previousProperties);
|
|
24439
24554
|
case "AWS::EC2::NetworkAcl":
|
|
24440
24555
|
case "AWS::EC2::NetworkAclEntry":
|
|
@@ -24898,7 +25013,10 @@ var EC2Provider = class {
|
|
|
24898
25013
|
throw new ProvisioningError(`Failed to create EIP ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
24899
25014
|
}
|
|
24900
25015
|
return {
|
|
24901
|
-
physicalId: this.eipPhysicalId(logicalId, publicIp, allocationId,
|
|
25016
|
+
physicalId: this.eipPhysicalId(logicalId, publicIp, allocationId, {
|
|
25017
|
+
maskSecrets: context?.maskSecrets,
|
|
25018
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
25019
|
+
}),
|
|
24902
25020
|
attributes: {
|
|
24903
25021
|
AllocationId: allocationId,
|
|
24904
25022
|
PublicIp: publicIp
|
|
@@ -24980,7 +25098,10 @@ var EC2Provider = class {
|
|
|
24980
25098
|
}, {
|
|
24981
25099
|
name: "vpcId",
|
|
24982
25100
|
value: vpcId
|
|
24983
|
-
}],
|
|
25101
|
+
}], {
|
|
25102
|
+
maskSecrets: context?.maskSecrets,
|
|
25103
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
25104
|
+
});
|
|
24984
25105
|
try {
|
|
24985
25106
|
await this.ec2Client.send(new AttachInternetGatewayCommand({
|
|
24986
25107
|
VpcId: vpcId,
|
|
@@ -25133,7 +25254,7 @@ var EC2Provider = class {
|
|
|
25133
25254
|
throw new ProvisioningError(`Failed to delete RouteTable ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
25134
25255
|
}
|
|
25135
25256
|
}
|
|
25136
|
-
async createRoute(logicalId, resourceType, properties, onMultipleDestinations) {
|
|
25257
|
+
async createRoute(logicalId, resourceType, properties, onMultipleDestinations, maskSecrets) {
|
|
25137
25258
|
this.logger.debug(`Creating Route ${logicalId}`);
|
|
25138
25259
|
const routeTableId = properties["RouteTableId"];
|
|
25139
25260
|
const destinationCidrBlock = properties["DestinationCidrBlock"];
|
|
@@ -25157,7 +25278,10 @@ var EC2Provider = class {
|
|
|
25157
25278
|
}, {
|
|
25158
25279
|
name: "destination",
|
|
25159
25280
|
value: destination
|
|
25160
|
-
}],
|
|
25281
|
+
}], {
|
|
25282
|
+
maskSecrets,
|
|
25283
|
+
...onMultipleDestinations && { onRefusal: onMultipleDestinations }
|
|
25284
|
+
});
|
|
25161
25285
|
try {
|
|
25162
25286
|
await this.ec2Client.send(new CreateRouteCommand({
|
|
25163
25287
|
RouteTableId: routeTableId,
|
|
@@ -25185,7 +25309,7 @@ var EC2Provider = class {
|
|
|
25185
25309
|
throw new ProvisioningError(`Failed to create Route ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
25186
25310
|
}
|
|
25187
25311
|
}
|
|
25188
|
-
async updateRoute(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
25312
|
+
async updateRoute(logicalId, physicalId, resourceType, properties, previousProperties, maskSecrets) {
|
|
25189
25313
|
this.logger.debug(`Updating Route ${logicalId}: ${physicalId}`);
|
|
25190
25314
|
if (JSON.stringify(properties) === JSON.stringify(previousProperties)) return {
|
|
25191
25315
|
physicalId,
|
|
@@ -25193,7 +25317,7 @@ var EC2Provider = class {
|
|
|
25193
25317
|
};
|
|
25194
25318
|
try {
|
|
25195
25319
|
await this.deleteRoute(logicalId, physicalId, resourceType);
|
|
25196
|
-
const createResult = await this.createRoute(logicalId, resourceType, properties, (message) => this.logger.warn(message));
|
|
25320
|
+
const createResult = await this.createRoute(logicalId, resourceType, properties, (message) => this.logger.warn(message), maskSecrets);
|
|
25197
25321
|
return {
|
|
25198
25322
|
physicalId: createResult.physicalId,
|
|
25199
25323
|
wasReplaced: true,
|
|
@@ -25476,7 +25600,7 @@ var EC2Provider = class {
|
|
|
25476
25600
|
* and on a rollback replay the value comes from a STATE record, which no
|
|
25477
25601
|
* template edit can fix. Absent (the plain CREATE dispatch) it throws.
|
|
25478
25602
|
*/
|
|
25479
|
-
async createSecurityGroupIngress(logicalId, resourceType, properties, onUnusableProtocol) {
|
|
25603
|
+
async createSecurityGroupIngress(logicalId, resourceType, properties, onUnusableProtocol, maskSecrets) {
|
|
25480
25604
|
this.logger.debug(`Creating SecurityGroupIngress ${logicalId}`);
|
|
25481
25605
|
const groupId = properties["GroupId"];
|
|
25482
25606
|
if (!groupId) throw new ProvisioningError(`GroupId is required for SecurityGroupIngress ${logicalId}`, resourceType, logicalId);
|
|
@@ -25501,7 +25625,10 @@ var EC2Provider = class {
|
|
|
25501
25625
|
name: "toPort",
|
|
25502
25626
|
value: toPort ?? "-1"
|
|
25503
25627
|
}
|
|
25504
|
-
],
|
|
25628
|
+
], {
|
|
25629
|
+
maskSecrets,
|
|
25630
|
+
...onUnusableProtocol && { onRefusal: onUnusableProtocol }
|
|
25631
|
+
});
|
|
25505
25632
|
try {
|
|
25506
25633
|
const ruleId = singleSecurityGroupRuleId((await this.ec2Client.send(new AuthorizeSecurityGroupIngressCommand({
|
|
25507
25634
|
GroupId: groupId,
|
|
@@ -25597,7 +25724,7 @@ var EC2Provider = class {
|
|
|
25597
25724
|
return;
|
|
25598
25725
|
}
|
|
25599
25726
|
}
|
|
25600
|
-
async updateSecurityGroupIngress(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
25727
|
+
async updateSecurityGroupIngress(logicalId, physicalId, resourceType, properties, previousProperties, maskSecrets) {
|
|
25601
25728
|
this.logger.debug(`Updating SecurityGroupIngress ${logicalId}: ${physicalId}`);
|
|
25602
25729
|
if (JSON.stringify(properties) === JSON.stringify(previousProperties)) return {
|
|
25603
25730
|
physicalId,
|
|
@@ -25605,7 +25732,7 @@ var EC2Provider = class {
|
|
|
25605
25732
|
};
|
|
25606
25733
|
try {
|
|
25607
25734
|
await this.deleteSecurityGroupIngress(logicalId, physicalId, resourceType, previousProperties);
|
|
25608
|
-
const createResult = await this.createSecurityGroupIngress(logicalId, resourceType, properties, (message) => this.logger.warn(message));
|
|
25735
|
+
const createResult = await this.createSecurityGroupIngress(logicalId, resourceType, properties, (message) => this.logger.warn(message), maskSecrets);
|
|
25609
25736
|
return {
|
|
25610
25737
|
physicalId: createResult.physicalId,
|
|
25611
25738
|
wasReplaced: true,
|
|
@@ -26289,7 +26416,10 @@ var EC2Provider = class {
|
|
|
26289
26416
|
name: "egress",
|
|
26290
26417
|
value: egress
|
|
26291
26418
|
}
|
|
26292
|
-
],
|
|
26419
|
+
], {
|
|
26420
|
+
maskSecrets: context?.maskSecrets,
|
|
26421
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
26422
|
+
});
|
|
26293
26423
|
try {
|
|
26294
26424
|
const cidrBlock = properties["CidrBlock"];
|
|
26295
26425
|
const ipv6CidrBlock = properties["Ipv6CidrBlock"];
|
|
@@ -28338,7 +28468,10 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
28338
28468
|
name: "httpMethod",
|
|
28339
28469
|
value: httpMethod
|
|
28340
28470
|
}
|
|
28341
|
-
],
|
|
28471
|
+
], {
|
|
28472
|
+
maskSecrets: context?.maskSecrets,
|
|
28473
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
28474
|
+
});
|
|
28342
28475
|
try {
|
|
28343
28476
|
await this.apiGatewayClient.send(new PutMethodCommand({
|
|
28344
28477
|
restApiId,
|
|
@@ -30382,12 +30515,7 @@ var ApiGatewayV2Provider = class {
|
|
|
30382
30515
|
*/
|
|
30383
30516
|
toSdkResponseParameters(value, maskSecrets = (text) => text) {
|
|
30384
30517
|
const warn = (message) => this.logger.warn(maskSecrets(message));
|
|
30385
|
-
const maskLeaf = (value) =>
|
|
30386
|
-
if (typeof value === "string") return maskSecrets(value);
|
|
30387
|
-
if (Array.isArray(value)) return value.map(maskLeaf);
|
|
30388
|
-
if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([k, v]) => [maskSecrets(k), maskLeaf(v)]));
|
|
30389
|
-
return value;
|
|
30390
|
-
};
|
|
30518
|
+
const maskLeaf = (value) => maskDeep(value, maskSecrets);
|
|
30391
30519
|
if (value == null) return void 0;
|
|
30392
30520
|
if (typeof value !== "object" || Array.isArray(value)) return value;
|
|
30393
30521
|
const out = {};
|
|
@@ -34956,44 +35084,6 @@ var ECSProvider = class {
|
|
|
34956
35084
|
}
|
|
34957
35085
|
};
|
|
34958
35086
|
|
|
34959
|
-
//#endregion
|
|
34960
|
-
//#region src/provisioning/masked-retry-logger.ts
|
|
34961
|
-
/**
|
|
34962
|
-
* The masker a caller supplied, or the identity function when it supplied
|
|
34963
|
-
* none.
|
|
34964
|
-
*
|
|
34965
|
-
* ABSENT MEANS UNMASKED, and that is the back-compatible default the contract
|
|
34966
|
-
* mandates — `create()` / `update()` are also reached from the import path,
|
|
34967
|
-
* from `cdkd drift --revert`, and from tests, and a provider must not care
|
|
34968
|
-
* which caller it got. Centralised here so no call site re-spells the `??`
|
|
34969
|
-
* and accidentally makes the capability required.
|
|
34970
|
-
*/
|
|
34971
|
-
function maskerOrIdentity(maskSecrets) {
|
|
34972
|
-
return maskSecrets ?? ((text) => text);
|
|
34973
|
-
}
|
|
34974
|
-
/**
|
|
34975
|
-
* A {@link RetryLogger} whose every line is routed through `maskSecrets`.
|
|
34976
|
-
*
|
|
34977
|
-
* `warn` is ALWAYS provided, never omitted. It is optional on `RetryLogger`,
|
|
34978
|
-
* and dropping it would silence the give-up summary on the calling path only —
|
|
34979
|
-
* trading a disclosure for the reporting hole issue #2018 closed. It goes
|
|
34980
|
-
* through the SAME mask as `debug` precisely because it is the line that
|
|
34981
|
-
* survives a run without `--verbose`; forwarding it unmasked would defeat the
|
|
34982
|
-
* fence at a HIGHER log level than the one the fence was written for.
|
|
34983
|
-
*
|
|
34984
|
-
* `logger` is typed structurally rather than as the concrete `Logger` so this
|
|
34985
|
-
* module stays a leaf and a test can pass two spies. That matches the
|
|
34986
|
-
* precedent already in the tree (`buildMfaConfigRequest` in
|
|
34987
|
-
* `cognito-provider.ts` takes an injected `logger?: { warn }`).
|
|
34988
|
-
*/
|
|
34989
|
-
function createMaskedRetryLogger(logger, maskSecrets) {
|
|
34990
|
-
const mask = maskerOrIdentity(maskSecrets);
|
|
34991
|
-
return {
|
|
34992
|
-
debug: (message) => logger.debug(mask(message)),
|
|
34993
|
-
warn: (message) => logger.warn(mask(message))
|
|
34994
|
-
};
|
|
34995
|
-
}
|
|
34996
|
-
|
|
34997
35087
|
//#endregion
|
|
34998
35088
|
//#region src/provisioning/providers/elbv2-provider.ts
|
|
34999
35089
|
/**
|
|
@@ -35003,41 +35093,6 @@ function createMaskedRetryLogger(logger, maskSecrets) {
|
|
|
35003
35093
|
*/
|
|
35004
35094
|
const capacityReservationDelays = { sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)) };
|
|
35005
35095
|
/**
|
|
35006
|
-
* Depth cap for {@link maskDeep}. Bounds a self-referential bag rather than
|
|
35007
|
-
* hanging; `JSON.stringify` would throw on one anyway, and a throw is the
|
|
35008
|
-
* better failure of the two.
|
|
35009
|
-
*/
|
|
35010
|
-
const MASK_WALK_MAX_DEPTH$1 = 8;
|
|
35011
|
-
/**
|
|
35012
|
-
* Mask every string LEAF and KEY of an arbitrary value, returning a structure
|
|
35013
|
-
* safe to `JSON.stringify` into a log line (issue #2050).
|
|
35014
|
-
*
|
|
35015
|
-
* The ordering is the whole point. `maskSecretsInText` matches by literal
|
|
35016
|
-
* occurrence, and `JSON.stringify` escapes `"`, `\` and newlines — so a Secrets
|
|
35017
|
-
* Manager JSON document (the commonest real secret shape) does not occur in the
|
|
35018
|
-
* stringified text and survives a mask applied afterwards. Masking the leaves
|
|
35019
|
-
* first also hands the masker each RAW value, which reaches
|
|
35020
|
-
* `maskSecretsInText`'s whole-value arm at any length instead of only the
|
|
35021
|
-
* substring arm's 4-character floor. See the "three gaps" note in
|
|
35022
|
-
* `src/deployment/secret-redaction.ts`.
|
|
35023
|
-
*
|
|
35024
|
-
* Keys are masked as well as values: `JSON.stringify` renders them into the
|
|
35025
|
-
* same line, so a resolved secret used as a map key would otherwise escape.
|
|
35026
|
-
*
|
|
35027
|
-
* `cognito-provider.ts` carries an equivalent private walk for its own
|
|
35028
|
-
* stringified warnings. Two copies is the current cost of keeping this a leaf;
|
|
35029
|
-
* a THIRD site is the point at which this should move into
|
|
35030
|
-
* `../masked-retry-logger.ts` (already the shared provider-side masking module)
|
|
35031
|
-
* and all three converge on it.
|
|
35032
|
-
*/
|
|
35033
|
-
function maskDeep(value, mask, depth = 0) {
|
|
35034
|
-
if (typeof value === "string") return mask(value);
|
|
35035
|
-
if (depth >= MASK_WALK_MAX_DEPTH$1) return value;
|
|
35036
|
-
if (Array.isArray(value)) return value.map((entry) => maskDeep(entry, mask, depth + 1));
|
|
35037
|
-
if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([k, v]) => [mask(k), maskDeep(v, mask, depth + 1)]));
|
|
35038
|
-
return value;
|
|
35039
|
-
}
|
|
35040
|
-
/**
|
|
35041
35096
|
* Documented AWS defaults for TargetGroup attributes, used to reset a
|
|
35042
35097
|
* removed `TargetGroupAttributes` entry. Unlike ModifyLoadBalancerAttributes
|
|
35043
35098
|
* / ModifyListenerAttributes, ModifyTargetGroupAttributes REJECTS an empty
|
|
@@ -39581,10 +39636,10 @@ var Route53Provider = class {
|
|
|
39581
39636
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
|
|
39582
39637
|
}
|
|
39583
39638
|
}
|
|
39584
|
-
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
39639
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
39585
39640
|
switch (resourceType) {
|
|
39586
39641
|
case "AWS::Route53::HostedZone": return this.updateHostedZone(logicalId, physicalId, resourceType, properties, previousProperties);
|
|
39587
|
-
case "AWS::Route53::RecordSet": return this.updateRecordSet(logicalId, physicalId, resourceType, properties);
|
|
39642
|
+
case "AWS::Route53::RecordSet": return this.updateRecordSet(logicalId, physicalId, resourceType, properties, context);
|
|
39588
39643
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId, physicalId);
|
|
39589
39644
|
}
|
|
39590
39645
|
}
|
|
@@ -39902,7 +39957,10 @@ var Route53Provider = class {
|
|
|
39902
39957
|
name: "recordType",
|
|
39903
39958
|
value: recordType
|
|
39904
39959
|
}
|
|
39905
|
-
],
|
|
39960
|
+
], {
|
|
39961
|
+
maskSecrets: context?.maskSecrets,
|
|
39962
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
39963
|
+
});
|
|
39906
39964
|
try {
|
|
39907
39965
|
const resourceRecordSet = this.buildResourceRecordSet(properties);
|
|
39908
39966
|
const comment = properties["Comment"];
|
|
@@ -39927,7 +39985,7 @@ var Route53Provider = class {
|
|
|
39927
39985
|
throw new ProvisioningError(`Failed to create record set ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
39928
39986
|
}
|
|
39929
39987
|
}
|
|
39930
|
-
async updateRecordSet(logicalId, physicalId, resourceType, properties) {
|
|
39988
|
+
async updateRecordSet(logicalId, physicalId, resourceType, properties, context) {
|
|
39931
39989
|
this.logger.debug(`Updating Route 53 record set ${logicalId}: ${physicalId}`);
|
|
39932
39990
|
const hostedZoneId = await this.resolveHostedZoneId(properties, logicalId, resourceType, physicalId);
|
|
39933
39991
|
const recordName = properties["Name"];
|
|
@@ -39945,7 +40003,10 @@ var Route53Provider = class {
|
|
|
39945
40003
|
name: "recordType",
|
|
39946
40004
|
value: recordType
|
|
39947
40005
|
}
|
|
39948
|
-
], {
|
|
40006
|
+
], {
|
|
40007
|
+
onRefusal: (message) => this.logger.warn(message),
|
|
40008
|
+
maskSecrets: context?.maskSecrets
|
|
40009
|
+
});
|
|
39949
40010
|
try {
|
|
39950
40011
|
const resourceRecordSet = this.buildResourceRecordSet(properties);
|
|
39951
40012
|
const comment = properties["Comment"];
|
|
@@ -40978,15 +41039,6 @@ function readDeclaredMfaConfiguration(raw, options) {
|
|
|
40978
41039
|
return value.trim() === "" ? "" : value;
|
|
40979
41040
|
}
|
|
40980
41041
|
/**
|
|
40981
|
-
* Depth cap for the pre-stringify secret walk in {@link buildMfaConfigRequest}.
|
|
40982
|
-
*
|
|
40983
|
-
* Only a guard against a self-referential bag, not a real bound: a resolved
|
|
40984
|
-
* `EnabledMfas` is a list of factor-name scalars, so the walk never reaches
|
|
40985
|
-
* depth 2 on any shape this warning exists to describe. Deliberately generous
|
|
40986
|
-
* so no plausible mis-shape is left unmasked by it.
|
|
40987
|
-
*/
|
|
40988
|
-
const MASK_WALK_MAX_DEPTH = 8;
|
|
40989
|
-
/**
|
|
40990
41042
|
* Read `EnabledMfas` as the pair (recognized list, "the template asked for a
|
|
40991
41043
|
* factor at all").
|
|
40992
41044
|
*
|
|
@@ -41120,15 +41172,9 @@ function buildMfaConfigRequest(physicalId, properties, logger, declaredMfaConfig
|
|
|
41120
41172
|
request.MfaConfiguration = declaredMfaConfiguration || (enablesMfaFactor ? "OPTIONAL" : "OFF");
|
|
41121
41173
|
if (enabledMfasBlank) warn(`UserPool ${physicalId}: EnabledMfas is an empty string, which declares no MFA factor and is treated as absent — a mangled Fn::Join or an empty String parameter collapses to this shape. Nothing is enabled from it and MfaConfiguration is ${request.MfaConfiguration}; declare the factor names as a list (e.g. ["${MFA_FACTOR_SOFTWARE_TOKEN}"]) if a factor was intended.`);
|
|
41122
41174
|
const anyFactorBlock = hasAnyMfaFactorBlock(request);
|
|
41123
|
-
const
|
|
41124
|
-
|
|
41125
|
-
|
|
41126
|
-
if (Array.isArray(v)) return v.map((e) => maskDeep(e, depth + 1));
|
|
41127
|
-
if (v !== null && typeof v === "object") return Object.fromEntries(Object.entries(v).map(([k, x]) => [maskSecrets(k), maskDeep(x, depth + 1)]));
|
|
41128
|
-
return v;
|
|
41129
|
-
};
|
|
41130
|
-
const dropped = unrecognizedFactors.map((f) => JSON.stringify(maskDeep(f)) ?? String(f));
|
|
41131
|
-
if (enabledMfasMalformed) dropped.push(`${JSON.stringify(maskDeep(properties["EnabledMfas"]))} (not a list)`);
|
|
41175
|
+
const maskLeaves = (v) => maskDeep(v, maskSecrets);
|
|
41176
|
+
const dropped = unrecognizedFactors.map((f) => JSON.stringify(maskLeaves(f)) ?? String(f));
|
|
41177
|
+
if (enabledMfasMalformed) dropped.push(`${JSON.stringify(maskLeaves(properties["EnabledMfas"]))} (not a list)`);
|
|
41132
41178
|
if (dropped.length > 0) {
|
|
41133
41179
|
const consequence = request.MfaConfiguration === "OFF" ? `MfaConfiguration is OFF, so this pool deploys with MFA DISABLED` : anyFactorBlock ? `MfaConfiguration is ${request.MfaConfiguration} and another factor block IS sent, so these entries are silently ignored rather than failing the call on their own` : `MfaConfiguration is ${request.MfaConfiguration} with no factor enabled, so AWS rejects this call rather than deploying the pool with MFA disabled`;
|
|
41134
41180
|
warn(`UserPool ${physicalId}: EnabledMfas entries ${dropped.join(", ")} do not map to an MFA factor block (known: ${MFA_FACTOR_SMS}, ${MFA_FACTOR_SOFTWARE_TOKEN}, ${MFA_FACTOR_EMAIL_OTP}); no factor is enabled from them. ${consequence}.`);
|
|
@@ -44886,7 +44932,10 @@ var AppSyncProvider = class {
|
|
|
44886
44932
|
}, {
|
|
44887
44933
|
name: "name",
|
|
44888
44934
|
value: name
|
|
44889
|
-
}],
|
|
44935
|
+
}], {
|
|
44936
|
+
maskSecrets: context?.maskSecrets,
|
|
44937
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
44938
|
+
});
|
|
44890
44939
|
let reportedArn;
|
|
44891
44940
|
try {
|
|
44892
44941
|
const input = {
|
|
@@ -44952,7 +45001,10 @@ var AppSyncProvider = class {
|
|
|
44952
45001
|
name: "fieldName",
|
|
44953
45002
|
value: fieldName
|
|
44954
45003
|
}
|
|
44955
|
-
],
|
|
45004
|
+
], {
|
|
45005
|
+
maskSecrets: context?.maskSecrets,
|
|
45006
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
45007
|
+
});
|
|
44956
45008
|
let reportedArn;
|
|
44957
45009
|
try {
|
|
44958
45010
|
const input = {
|
|
@@ -45019,7 +45071,10 @@ var AppSyncProvider = class {
|
|
|
45019
45071
|
}, {
|
|
45020
45072
|
name: "apiKeyId",
|
|
45021
45073
|
value: apiKeyId
|
|
45022
|
-
}],
|
|
45074
|
+
}], {
|
|
45075
|
+
maskSecrets: context?.maskSecrets,
|
|
45076
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
45077
|
+
});
|
|
45023
45078
|
const apiKeyArn = await this.buildAppSyncArnOrWarn(`apis/${apiId}/apikey/${apiKeyId}`, logicalId, physicalId);
|
|
45024
45079
|
return {
|
|
45025
45080
|
physicalId,
|
|
@@ -45705,7 +45760,10 @@ var GlueProvider = class {
|
|
|
45705
45760
|
}, {
|
|
45706
45761
|
name: "tableName",
|
|
45707
45762
|
value: tableName
|
|
45708
|
-
}],
|
|
45763
|
+
}], {
|
|
45764
|
+
maskSecrets: context?.maskSecrets,
|
|
45765
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
45766
|
+
});
|
|
45709
45767
|
try {
|
|
45710
45768
|
await this.getClient().send(new CreateTableCommand$1({
|
|
45711
45769
|
CatalogId: catalogId,
|
|
@@ -57185,7 +57243,10 @@ var S3TablesProvider = class {
|
|
|
57185
57243
|
}, {
|
|
57186
57244
|
name: "namespace",
|
|
57187
57245
|
value: namespaceName
|
|
57188
|
-
}],
|
|
57246
|
+
}], {
|
|
57247
|
+
maskSecrets: context?.maskSecrets,
|
|
57248
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
57249
|
+
});
|
|
57189
57250
|
try {
|
|
57190
57251
|
await this.getClient().send(new CreateNamespaceCommand({
|
|
57191
57252
|
tableBucketARN,
|
|
@@ -57245,7 +57306,10 @@ var S3TablesProvider = class {
|
|
|
57245
57306
|
name: "name",
|
|
57246
57307
|
value: name
|
|
57247
57308
|
}
|
|
57248
|
-
],
|
|
57309
|
+
], {
|
|
57310
|
+
maskSecrets: context?.maskSecrets,
|
|
57311
|
+
...context?.replayingState === true && { onRefusal: (message) => this.logger.warn(message) }
|
|
57312
|
+
});
|
|
57249
57313
|
try {
|
|
57250
57314
|
const response = await this.getClient().send(new CreateTableCommand$2({
|
|
57251
57315
|
tableBucketARN,
|
|
@@ -58883,7 +58947,11 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
58883
58947
|
}
|
|
58884
58948
|
await saveChain;
|
|
58885
58949
|
logger.debug("Releasing lock...");
|
|
58886
|
-
|
|
58950
|
+
try {
|
|
58951
|
+
await ctx.lockManager.releaseLock(stackName, regionForState);
|
|
58952
|
+
} catch (releaseErr) {
|
|
58953
|
+
logger.warn(`Failed to release lock for stack '${stackName}': ${releaseErr instanceof Error ? releaseErr.message : String(releaseErr)}`);
|
|
58954
|
+
}
|
|
58887
58955
|
} finally {
|
|
58888
58956
|
process.removeListener("SIGINT", sigintHandler);
|
|
58889
58957
|
restoreBaseRegionAndClients();
|
|
@@ -86555,7 +86623,7 @@ function createMigrateCommand() {
|
|
|
86555
86623
|
*/
|
|
86556
86624
|
function buildProgram() {
|
|
86557
86625
|
const program = new Command();
|
|
86558
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.284.
|
|
86626
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.284.42");
|
|
86559
86627
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
86560
86628
|
const { profile } = actionCommand.optsWithGlobals();
|
|
86561
86629
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|