@go-to-k/cdkd 0.289.3 → 0.289.5
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-rQ1BW281.js → asg-provider-DD_xuWE3.js} +3 -3
- package/dist/{asg-provider-rQ1BW281.js.map → asg-provider-DD_xuWE3.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-DAykhfpV.js → deploy-engine-Dhgm0r8o.js} +537 -129
- package/dist/deploy-engine-Dhgm0r8o.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/{logger-D2Md1kTq.js → logger-CecsQ1UT.js} +53 -3
- package/dist/logger-CecsQ1UT.js.map +1 -0
- package/dist/{program-DLd8dIyf.js → program-CgSZ7WgF.js} +235 -51
- package/dist/{program-DLd8dIyf.js.map → program-CgSZ7WgF.js.map} +1 -1
- package/dist/{version-DPykgdNN.js → version-DMsY_Ble.js} +2 -2
- package/dist/{version-DPykgdNN.js.map → version-DMsY_Ble.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-DAykhfpV.js.map +0 -1
- package/dist/logger-D2Md1kTq.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $ as collectInlinePolicyNamesManagedBySiblings, $n as
|
|
2
|
-
import { _ as withSkipPrefix, c as PATTERN_B_NAME_OPTIONS, f as explicitNamePropertyFor, h as getCurrentStackName, i as reserveStdoutForPayload, l as PATTERN_B_NAME_PROPERTIES, m as generateResourceNameWithFallback, n as getLogger, o as runStackBuffered, p as generateResourceName, s as getLiveRenderer, u as PATTERN_B_RESOURCE_TYPES, v as withStackName } from "./logger-
|
|
1
|
+
import { $ as collectInlinePolicyNamesManagedBySiblings, $n as buildDenyExternalAccessPolicy, $r as DynamicReferenceRegionAmbiguousError, $t as describeTypeWithThrottleRetry, A as isStatefulRecreateTargetForReplace, An as exportNamesCarriedFrom, Ar as CFN_TEMPLATE_URL_LIMIT, At as coerceCfnBoolean, B as gray, Bn as createAssetRedirectResolver, Br as processStackMessages, Bt as classifyReplaySecretRegion, C as refusesFinalSnapshot, Ci as retryClassificationText, Cn as UNRENDERABLE, Cr as resolveSkipPrefix, Ct as isUnboundTemplateParameter, D as makeSiblingClaimReader, Dn as shellQuote, Dr as stateBucketExistenceConfirmed, Dt as normalizeAwsTagsToCfn, E as extractDeploymentEventError, En as forceQuitRecoveryClause, Er as resolveUseCdkBootstrapAssets, Et as WAFv2WebACLProvider, F as isWarmThroughputDecrease, Fn as shouldRetainResource, Fr as expectedOwnerParam, Ft as readConfigString, G as collectPublishedOutputNames, Gn as assertAssetBucketRegion, Gr as resetAwsClients, Gt as s3BucketDualStackDomainName, H as red, Hn as rewriteTemplateAssetReferences, Hr as resolveBucketRegion, Ht as withSharedDrainBudget, I as toFiniteNumber, In as AssetPublisher, Ir as PARTITION_TABLE, It as replayWarn, J as secretBearing, Jn as isCrossRegionRedirect, Jr as CdkdError, Jt as applyRoleArnIfSet, K as exportAliasCollisionScrubWarning, Kn as ensureAssetStorage, Kr as setAwsClients, Kt as s3BucketRegionalDomainName, L as formatResourceLine, Ln as stringifyValue, Lr as canonicalizeRegion, Lt as requireConfigArray, M as renderStatefulReason, Mn as importableOutputs, Mr as findLargeInlineResources, Mt as configBooleanRefusal, N as WARM_THROUGHPUT_MEMBERS, Nn as orphansAfterRollback, Nr as uploadCfnTemplate, Nt as configIntegerRefusal, O as planOrphanAdoption, On as CUSTOM_RESOURCE_RESPONSE_PREFIX, Or as warnDeprecatedNoPrefixCliFlag, Ot as resolveExplicitPhysicalId, P as coerceWarmThroughput$1, Pn as orphansCarriedFrom, Pr as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, Pt as configStringRefusal, Q as IAMRoleProvider, Qn as validateContainerRepoName, Qr as DeployCancelledError, Qt as findSilentDropProperties, R as bold, Rn as WorkGraph, Rr as derivePartitionAndUrlSuffix, Rt as requireConfigObject, S as isFinalSnapshotError, Si as markRedactedCause, Sn as rebuildClientForBucketRegion, Sr as resolveCaptureObservedState, St as getAccountInfo, T as makeCanonicalizePropertiesFn, Tn as buildLockContentionMessage, Tr as resolveStateBucketWithDefaultAndSource, Tt as refStateLookupFromResource, U as yellow, Un as AssetModeResolver, Ur as AwsClients, Ut as s3BucketArn, V as green, Vn as loadPublishableAssetManifest, Vt as producerRegionsFromState, W as collectDeclaredOutputNames, Wn as BOOTSTRAP_MARKER_PREFIX, Wr as getAwsClients, Wt as s3BucketDomainName, X as secretSafeKeyDisplay, Xn as readBootstrapMarkerBody, Xr as CrossAccountSecretRefusalError, Xt as INTRINSIC_KEYS, Y as secretBearingStateKeyWarning, Yn as parseBootstrapMarker, Yt as DiffCalculator, Z as getCurrentResourceSecrets, Zn as validateAssetBucketName, Zt as findActionableSilentDrops, _ as ATOMIC_FINAL_SNAPSHOT_TYPES, _i as isMarkedNonRetryable, _n as recoverMaskedOutput, _r as synthesisStatusMessage, _t as isTerminationProtectionPropagationError, a as DeploymentEventsStore, ai as PartialFailureError, an as STATE_SOURCED_READBACK_RULES, ar as dockerSpawnEnvWithSensitive, at as maskerOrIdentity, b as ccRoutedFinalSnapshotError, bi as isTransientServerError, bn as LockManager, br as resolveApp, bt as cfnRefValueFromPhysicalId, c as replayFailedOperations, ci as ResourceUpdateNotSupportedError, cn as createSecretMasker, cr as partitionSensitiveEnv, ct as interruptWatchListenerCount, d as updatePartialReason, dn as identityKeyFor, dr as runDockerStreaming, dt as CloudControlProvider, ei as IntrinsicResolutionRefusalError, en as withRetry, er as describeAwsFailure, et as clearOnUpdateRemoval, f as withResourceDeadline, fn as isSingleDynamicReferenceToken, fr as escapeRegExp, ft as slowCcOperationTimeoutMs, g as bindingSkippedOutputs, gi as withErrorHandling, gn as recordMaskOnlyValue, gr as Synthesizer, gt as disableInstanceApiTermination, h as computeImplicitDeleteEdges, hi as normalizeAwsError, hn as maskSecretsInText, hr as getDockerImageBySourceHash, ht as deleteSkipReason, i as DeploymentEventsReader, ii as NestedStackChildDirectDestroyError, in as STATE_SOURCED_CROSS_GENERATION_RULES, ir as describeDockerFailure, it as maskDeep, j as isStatefulRecreateTargetSync, jn as importableOutputKeys, jr as MIGRATE_TMP_PREFIX, jt as coerceCfnInteger, k as MULTI_REGION_RECREATE_BLOCKED_TYPES, kn as DEFAULT_STATE_PREFIX, kr as CFN_TEMPLATE_BODY_LIMIT, kt as assertRegionMatch, l as replayRollback, li as StackHasActiveImportsError, ln as dynamicReferenceTokens, lr as redactDockerArgvValues, lt as isInterruptedWaitError, m as IMPLICIT_DELETE_DEPENDENCIES, mn as maskSecretsInError, mr as AssetManifestLoader, mt as deleteIndeterminateGuards, n as DEFAULT_RESOURCE_WARN_AFTER_MS, ni as LocalStartServiceError, nn as TemplateParser, nr as describeDockerCapturedOutput, nt as wouldReturnToSdkProvider, o as planFailedOps, oi as ProvisioningError, on as TEMPLATE_SOURCED_RULES, or as formatDockerLoginError, ot as beginCommandInterruptScope, p as maskingRetryLogger, pn as markSameGenerationBag, pr as stripControlChars, pt as UNSPECIFIED_SKIP_REASON, q as isExportAliasCollision, qn as getBootstrapMarkerKey, qt as s3BucketWebsiteUrl, r as DeployEngine, rn as STATE_SOURCED_BASELINE_RULES, rr as describeDockerExecFailure, rt as createMaskedRetryLogger, s as planRollback, si as ResourceTimeoutError, sn as carriesSecretMask, sr as getDockerCmd, st as endCommandInterruptScope, t as DEFAULT_RESOURCE_TIMEOUT_MS, ti as LocalInvokeBuildError$1, tn as DagBuilder, tr as buildDockerImage, tt as ProviderRegistry, u as updatePartialMessage, ui as StackTerminationProtectionError, un as errorCauseChain, ur as runDockerForeground, ut as startInterruptWatch, v as PRE_DELETE_SNAPSHOT_TYPES, vi as isRetryableTransientError, vn as redactSecretsForState, vr as getDefaultStateBucketName, vt as IntrinsicFunctionResolver, w as unsupportedFinalSnapshotError, wn as buildForceUnlockCommand, wr as resolveStateBucketWithDefault, wt as parameterTypeMayLoseSecretIdentity, x as createPreDeleteFinalSnapshot, xi as markNonRetryable, xn as S3StateBackend, xr as resolveAutoAssetStorage, xt as coerceParameterTypedValue, y as buildFinalSnapshotIdentifier, yi as isThrottlingError, yn as scrubResourceRecord, yr as getLegacyStateBucketName, yt as carriesDynamicReference, z as cyan, zn as buildAssetRedirectMap, zr as AssemblyReader, zt as requireConfigString } from "./deploy-engine-Dhgm0r8o.js";
|
|
2
|
+
import { _ as withSkipPrefix, c as PATTERN_B_NAME_OPTIONS, f as explicitNamePropertyFor, h as getCurrentStackName, i as reserveStdoutForPayload, l as PATTERN_B_NAME_PROPERTIES, m as generateResourceNameWithFallback, n as getLogger, o as runStackBuffered, p as generateResourceName, s as getLiveRenderer, u as PATTERN_B_RESOURCE_TYPES, v as withStackName, y as displaySafe } from "./logger-CecsQ1UT.js";
|
|
3
3
|
import { t as awsClientDefaults } from "./aws-client-defaults-D-iYiIJ6.js";
|
|
4
|
-
import { t as getCdkdVersion } from "./version-
|
|
5
|
-
import { r as protectedReplacementAdvice, t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as getCdkdVersion } from "./version-DMsY_Ble.js";
|
|
5
|
+
import { r as protectedReplacementAdvice, t as ASGProvider } from "./asg-provider-DD_xuWE3.js";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
7
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
8
8
|
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, NotFound, 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";
|
|
@@ -24300,6 +24300,50 @@ function requireSecretStringShape(literal) {
|
|
|
24300
24300
|
throw new Error(`SecretString must be a string, got ${literal === null ? "null" : Array.isArray(literal) ? "array" : typeof literal}`);
|
|
24301
24301
|
}
|
|
24302
24302
|
/**
|
|
24303
|
+
* The refusal for the MEMBERS of a `GenerateSecretString` block whose container
|
|
24304
|
+
* has already passed `requireConfigObject` (issue #3056), or `undefined` when
|
|
24305
|
+
* every member is usable. ONE predicate for two readers — the generator, which
|
|
24306
|
+
* mints from the block, and `retainPreviousGenerateBlock`, which decides
|
|
24307
|
+
* whether the PREVIOUS block is worth recording — per the #1653 rule that the
|
|
24308
|
+
* retention runs the same predicate the wire does. A module-level function
|
|
24309
|
+
* rather than a method so the recording helper can call it without reaching
|
|
24310
|
+
* `this`, which the #2212 fence confines to one logger call.
|
|
24311
|
+
*
|
|
24312
|
+
* Per member, the shared `config-shape.ts` predicate for its type: CFn is
|
|
24313
|
+
* stringly typed, so `PasswordLength: "32"` and `ExcludePunctuation: "true"`
|
|
24314
|
+
* coerce, while `null`, a blank, a non-numeric string, an object or an
|
|
24315
|
+
* unresolved intrinsic refuse. `PasswordLength` is capped at 4096, the
|
|
24316
|
+
* service's documented maximum, so a runaway length is refused before
|
|
24317
|
+
* `new Uint8Array` allocates it. `GenerateStringKey` / `SecretStringTemplate`
|
|
24318
|
+
* must be declared TOGETHER — the docs pin only key -> template; measured on
|
|
24319
|
+
* CloudFormation (us-east-1, 2026-09-13), a template with
|
|
24320
|
+
* `SecretStringTemplate` alone fails with `SecretStringTemplate and
|
|
24321
|
+
* GenerateStringKey must both be set or removed`, the service's own message
|
|
24322
|
+
* naming both directions (only that one was exercised) — the template must
|
|
24323
|
+
* parse to a JSON OBJECT (an array or a scalar parses and cannot take a key),
|
|
24324
|
+
* and the key may not be `__proto__`, which `template[key] = password` would
|
|
24325
|
+
* hand to the prototype setter, silently dropping the password from the
|
|
24326
|
+
* document. The messages name shapes only, never a value: the template can
|
|
24327
|
+
* carry a secret.
|
|
24328
|
+
*/
|
|
24329
|
+
function generateMemberRefusal(config) {
|
|
24330
|
+
const P = "AWS::SecretsManager::Secret GenerateSecretString";
|
|
24331
|
+
const shape = configIntegerRefusal(config, "PasswordLength", P, 1, 4096) ?? configBooleanRefusal(config, "ExcludeUppercase", P) ?? configBooleanRefusal(config, "ExcludeLowercase", P) ?? configBooleanRefusal(config, "ExcludeNumbers", P) ?? configBooleanRefusal(config, "ExcludePunctuation", P) ?? configStringRefusal(config, "ExcludeCharacters", "", P) ?? configStringRefusal(config, "GenerateStringKey", "required", P) ?? configStringRefusal(config, "SecretStringTemplate", "required", P);
|
|
24332
|
+
if (shape !== void 0) return shape;
|
|
24333
|
+
const key = config["GenerateStringKey"];
|
|
24334
|
+
const template = config["SecretStringTemplate"];
|
|
24335
|
+
if (key === void 0 && template === void 0) return void 0;
|
|
24336
|
+
if (key === void 0 || template === void 0) return `${P}.GenerateStringKey and ${P}.SecretStringTemplate must be declared together (got only ${key === void 0 ? "SecretStringTemplate" : "GenerateStringKey"})`;
|
|
24337
|
+
if (key === "__proto__") return `${P}.GenerateStringKey must not be __proto__ (the password would be written to the prototype, not the document)`;
|
|
24338
|
+
let parsed;
|
|
24339
|
+
try {
|
|
24340
|
+
parsed = JSON.parse(template);
|
|
24341
|
+
} catch {
|
|
24342
|
+
return `${P}.SecretStringTemplate must be a JSON object (got a string that does not parse as JSON)`;
|
|
24343
|
+
}
|
|
24344
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return `${P}.SecretStringTemplate must be a JSON object (got JSON that is not an object)`;
|
|
24345
|
+
}
|
|
24346
|
+
/**
|
|
24303
24347
|
* AWS Secrets Manager Secret Provider
|
|
24304
24348
|
*
|
|
24305
24349
|
* Implements resource provisioning for AWS::SecretsManager::Secret using the Secrets Manager SDK.
|
|
@@ -24334,9 +24378,12 @@ var SecretsManagerSecretProvider = class {
|
|
|
24334
24378
|
});
|
|
24335
24379
|
try {
|
|
24336
24380
|
let secretString;
|
|
24337
|
-
const
|
|
24338
|
-
if (
|
|
24339
|
-
|
|
24381
|
+
const rawGenerate = properties["GenerateSecretString"];
|
|
24382
|
+
if (rawGenerate != null) {
|
|
24383
|
+
const generateConfig = requireConfigObject(rawGenerate, "AWS::SecretsManager::Secret GenerateSecretString");
|
|
24384
|
+
secretString = this.generateSecretString(generateConfig);
|
|
24385
|
+
} else if (properties["SecretString"] !== void 0 && properties["SecretString"] !== "") secretString = requireSecretStringShape(properties["SecretString"]);
|
|
24386
|
+
if (secretString === void 0) this.logger.warn(`AWS::SecretsManager::Secret ${logicalId} declares no secret value (neither GenerateSecretString nor a non-empty SecretString); the secret is created with NO version. Consumers reading it will fail until a value is set.`);
|
|
24340
24387
|
const createParams = { Name: name };
|
|
24341
24388
|
if (secretString) createParams.SecretString = secretString;
|
|
24342
24389
|
if (properties["Description"]) createParams.Description = properties["Description"];
|
|
@@ -24365,7 +24412,7 @@ var SecretsManagerSecretProvider = class {
|
|
|
24365
24412
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
24366
24413
|
this.logger.debug(`Updating secret ${logicalId}: ${physicalId}`);
|
|
24367
24414
|
try {
|
|
24368
|
-
const secretString = this.changedSecretValue(properties, previousProperties);
|
|
24415
|
+
const { value: secretString, skippedGenerate } = this.changedSecretValue(properties, previousProperties);
|
|
24369
24416
|
const updateParams = { SecretId: physicalId };
|
|
24370
24417
|
if (secretString !== void 0) updateParams.SecretString = secretString;
|
|
24371
24418
|
const description = clearOnUpdateRemoval(properties["Description"], previousProperties["Description"], "");
|
|
@@ -24420,7 +24467,8 @@ var SecretsManagerSecretProvider = class {
|
|
|
24420
24467
|
return {
|
|
24421
24468
|
physicalId,
|
|
24422
24469
|
wasReplaced: false,
|
|
24423
|
-
attributes: { Id: physicalId }
|
|
24470
|
+
attributes: { Id: physicalId },
|
|
24471
|
+
effectiveProperties: skippedGenerate ? this.retainPreviousGenerateBlock(logicalId, properties, previousProperties) : void 0
|
|
24424
24472
|
};
|
|
24425
24473
|
} catch (error) {
|
|
24426
24474
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -24450,8 +24498,51 @@ var SecretsManagerSecretProvider = class {
|
|
|
24450
24498
|
}
|
|
24451
24499
|
}
|
|
24452
24500
|
/**
|
|
24453
|
-
* The
|
|
24454
|
-
*
|
|
24501
|
+
* The bag to RECORD when the generate block was skipped: the desired
|
|
24502
|
+
* properties with `GenerateSecretString` restored to the previously-applied
|
|
24503
|
+
* value, or with the key dropped when the previous side cannot be vouched
|
|
24504
|
+
* for either.
|
|
24505
|
+
*
|
|
24506
|
+
* Validated through `requireConfigObject` AND `generateMemberRefusal` — the
|
|
24507
|
+
* same two predicates the wire read runs, container then members — rather
|
|
24508
|
+
* than a hand-written twin, so the two cannot disagree about a blank string,
|
|
24509
|
+
* an explicit null, an intrinsic, or (since issue #3056) a malformed member
|
|
24510
|
+
* inside a well-formed block: a pre-#3056 record holding
|
|
24511
|
+
* `PasswordLength: 'abc'` is dropped, not retained. The retained block is
|
|
24512
|
+
* COPIED, not aliased: both engine consumers spread the answer one level
|
|
24513
|
+
* deep only (the #1653 review rule).
|
|
24514
|
+
*
|
|
24515
|
+
* The DROP is announced rather than silent (the #1654 rule: dropping a key
|
|
24516
|
+
* moves a hazard unless something still says so). A record carrying
|
|
24517
|
+
* neither value source later reaches the reverse-replacement replay-create,
|
|
24518
|
+
* where `create()` — which cannot see the record's history — would create
|
|
24519
|
+
* the secret with NO version; the warning here is what makes that record
|
|
24520
|
+
* diagnosable, and `create()` warns again when it meets one.
|
|
24521
|
+
*
|
|
24522
|
+
* One shape is announced rather than reconciled: a secret created from a
|
|
24523
|
+
* LITERAL whose template then switches to a malformed generate block. The
|
|
24524
|
+
* previous side has no block, so the key is dropped, and the record then
|
|
24525
|
+
* carries neither source while AWS still holds the literal. Restoring the
|
|
24526
|
+
* previous `SecretString` would be the #1612 answer, but it re-records a
|
|
24527
|
+
* literal the template has REMOVED; the drop keeps the next deploy of the
|
|
24528
|
+
* same template an announced UPDATE (desired block vs absent), which is the
|
|
24529
|
+
* loud outcome this arm exists for.
|
|
24530
|
+
*/
|
|
24531
|
+
retainPreviousGenerateBlock(logicalId, properties, previousProperties) {
|
|
24532
|
+
const usableContainer = requireConfigObject(previousProperties["GenerateSecretString"], "AWS::SecretsManager::Secret GenerateSecretString", { onUnusable: () => {} });
|
|
24533
|
+
const usablePrevious = usableContainer !== void 0 && generateMemberRefusal(usableContainer) === void 0 ? usableContainer : void 0;
|
|
24534
|
+
const effective = { ...properties };
|
|
24535
|
+
if (usablePrevious === void 0) {
|
|
24536
|
+
delete effective["GenerateSecretString"];
|
|
24537
|
+
this.logger.warn(`AWS::SecretsManager::Secret ${logicalId}: GenerateSecretString is dropped from the recorded properties. The desired block is unusable and the previously recorded one is absent or unusable, so the record now carries no GenerateSecretString; fix the template so the next deploy records one.`);
|
|
24538
|
+
} else effective["GenerateSecretString"] = { ...usablePrevious };
|
|
24539
|
+
return effective;
|
|
24540
|
+
}
|
|
24541
|
+
/**
|
|
24542
|
+
* The `SecretString` an in-place update must send (as `value`), or
|
|
24543
|
+
* `undefined` when the value's SOURCE is unchanged (issue #2472) or when a
|
|
24544
|
+
* malformed `GenerateSecretString` block was SKIPPED (issue #3048,
|
|
24545
|
+
* `skippedGenerate: true` — the caller records the previous block instead).
|
|
24455
24546
|
*
|
|
24456
24547
|
* The source is `GenerateSecretString` when present (CloudFormation gives it
|
|
24457
24548
|
* precedence over a literal) and `SecretString` otherwise. A generated value
|
|
@@ -24524,15 +24615,38 @@ var SecretsManagerSecretProvider = class {
|
|
|
24524
24615
|
* template.
|
|
24525
24616
|
*/
|
|
24526
24617
|
changedSecretValue(properties, previousProperties) {
|
|
24527
|
-
const
|
|
24528
|
-
if (
|
|
24618
|
+
const rawGenerate = properties["GenerateSecretString"];
|
|
24619
|
+
if (rawGenerate != null) {
|
|
24620
|
+
const generateConfig = rawGenerate;
|
|
24529
24621
|
const previous = previousProperties["GenerateSecretString"];
|
|
24530
|
-
|
|
24622
|
+
if (isDeepStrictEqual(asJson(generateConfig), asJson(previous)) || isDeepStrictEqual(asJson(this.asPersisted(generateConfig)), asJson(previous))) return {
|
|
24623
|
+
value: void 0,
|
|
24624
|
+
skippedGenerate: false
|
|
24625
|
+
};
|
|
24626
|
+
const skip = (m) => this.logger.warn(`${m} No new secret value is generated; the secret keeps the value AWS currently holds.`);
|
|
24627
|
+
const usable = requireConfigObject(generateConfig, "AWS::SecretsManager::Secret GenerateSecretString", { onUnusable: skip });
|
|
24628
|
+
const generated = usable === void 0 ? void 0 : this.generateSecretString(usable, { onUnusable: skip });
|
|
24629
|
+
return generated === void 0 ? {
|
|
24630
|
+
value: void 0,
|
|
24631
|
+
skippedGenerate: true
|
|
24632
|
+
} : {
|
|
24633
|
+
value: generated,
|
|
24634
|
+
skippedGenerate: false
|
|
24635
|
+
};
|
|
24531
24636
|
}
|
|
24532
24637
|
const literal = properties["SecretString"];
|
|
24533
|
-
if (literal === void 0) return
|
|
24534
|
-
|
|
24535
|
-
|
|
24638
|
+
if (literal === void 0) return {
|
|
24639
|
+
value: void 0,
|
|
24640
|
+
skippedGenerate: false
|
|
24641
|
+
};
|
|
24642
|
+
if (isDeepStrictEqual(asJson(literal), asJson(previousProperties["SecretString"]))) return {
|
|
24643
|
+
value: void 0,
|
|
24644
|
+
skippedGenerate: false
|
|
24645
|
+
};
|
|
24646
|
+
return {
|
|
24647
|
+
value: requireSecretStringShape(literal),
|
|
24648
|
+
skippedGenerate: false
|
|
24649
|
+
};
|
|
24536
24650
|
}
|
|
24537
24651
|
/**
|
|
24538
24652
|
* `bag` as the state writer would persist it: every plaintext this
|
|
@@ -24548,17 +24662,49 @@ var SecretsManagerSecretProvider = class {
|
|
|
24548
24662
|
return secrets !== void 0 && secrets.size > 0 ? redactSecretsForState(bag, secrets) : bag;
|
|
24549
24663
|
}
|
|
24550
24664
|
/**
|
|
24551
|
-
* Generate a secret string from GenerateSecretString
|
|
24552
|
-
*
|
|
24553
|
-
*
|
|
24554
|
-
|
|
24555
|
-
|
|
24556
|
-
|
|
24557
|
-
|
|
24558
|
-
|
|
24559
|
-
|
|
24560
|
-
|
|
24561
|
-
|
|
24665
|
+
* Generate a secret string from a USABLE `GenerateSecretString` block (the
|
|
24666
|
+
* caller has already run `requireConfigObject` on the container).
|
|
24667
|
+
*
|
|
24668
|
+
* Every MEMBER is read through the shared `config-shape.ts` predicate for
|
|
24669
|
+
* its type (issue #3056) rather than a cast: CFn is stringly typed, so
|
|
24670
|
+
* `PasswordLength: "32"` and `ExcludePunctuation: "true"` are legitimate
|
|
24671
|
+
* and coerce, while a malformed member — `null`, a blank, a non-numeric
|
|
24672
|
+
* string, an object, an unresolved intrinsic — REFUSES instead of taking a
|
|
24673
|
+
* default. The defaults it used to take were not inert: `(x as number) || 32`
|
|
24674
|
+
* read `PasswordLength: 'abc'` as a truthy string and `new Uint8Array('abc')`
|
|
24675
|
+
* minted an EMPTY password; a truthy `'false'` EXCLUDED punctuation; and a
|
|
24676
|
+
* malformed `SecretStringTemplate` fell into the `catch` and returned the
|
|
24677
|
+
* bare password RAW where the template declared a JSON document — as the
|
|
24678
|
+
* new `AWSCURRENT`.
|
|
24679
|
+
*
|
|
24680
|
+
* The member rules themselves live in `generateMemberRefusal` (shared with
|
|
24681
|
+
* the recording helper); both present means the key is written into the
|
|
24682
|
+
* parsed template, both absent means a bare password, which is what the
|
|
24683
|
+
* service does.
|
|
24684
|
+
*
|
|
24685
|
+
* With no `onUnusable` a refusal THROWS (the create path, where the block
|
|
24686
|
+
* is template-borne). With one, the message is handed over and `undefined`
|
|
24687
|
+
* is returned — the update path's SKIP, decided by the caller, so that this
|
|
24688
|
+
* function never mints from a block it could not read. The two members the
|
|
24689
|
+
* schema declares that this recipe does not implement, `IncludeSpace` and
|
|
24690
|
+
* `RequireEachIncludedType`, are a separate fidelity gap (issue #3068), not
|
|
24691
|
+
* a shape question.
|
|
24692
|
+
*/
|
|
24693
|
+
generateSecretString(config, options) {
|
|
24694
|
+
const refusal = generateMemberRefusal(config);
|
|
24695
|
+
if (refusal !== void 0) {
|
|
24696
|
+
if (options?.onUnusable) {
|
|
24697
|
+
options.onUnusable(`${refusal}. Leaving this configuration unapplied here; the same value is REFUSED on a template-path create.`);
|
|
24698
|
+
return;
|
|
24699
|
+
}
|
|
24700
|
+
throw new Error(refusal);
|
|
24701
|
+
}
|
|
24702
|
+
const length = coerceCfnInteger(config["PasswordLength"]) ?? 32;
|
|
24703
|
+
const excludeUppercase = coerceCfnBoolean(config["ExcludeUppercase"]) ?? false;
|
|
24704
|
+
const excludeLowercase = coerceCfnBoolean(config["ExcludeLowercase"]) ?? false;
|
|
24705
|
+
const excludeNumbers = coerceCfnBoolean(config["ExcludeNumbers"]) ?? false;
|
|
24706
|
+
const excludePunctuation = coerceCfnBoolean(config["ExcludePunctuation"]) ?? false;
|
|
24707
|
+
const excludeCharacters = config["ExcludeCharacters"] ?? "";
|
|
24562
24708
|
let chars = "";
|
|
24563
24709
|
if (!excludeUppercase) chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
24564
24710
|
if (!excludeLowercase) chars += "abcdefghijklmnopqrstuvwxyz";
|
|
@@ -24572,14 +24718,10 @@ var SecretsManagerSecretProvider = class {
|
|
|
24572
24718
|
for (let i = 0; i < length; i++) password += chars[bytes[i] % chars.length];
|
|
24573
24719
|
const generateStringKey = config["GenerateStringKey"];
|
|
24574
24720
|
const secretStringTemplate = config["SecretStringTemplate"];
|
|
24575
|
-
if (generateStringKey
|
|
24576
|
-
|
|
24577
|
-
|
|
24578
|
-
|
|
24579
|
-
} catch {
|
|
24580
|
-
return password;
|
|
24581
|
-
}
|
|
24582
|
-
return password;
|
|
24721
|
+
if (generateStringKey === void 0 || secretStringTemplate === void 0) return password;
|
|
24722
|
+
const template = JSON.parse(secretStringTemplate);
|
|
24723
|
+
template[generateStringKey] = password;
|
|
24724
|
+
return JSON.stringify(template);
|
|
24583
24725
|
}
|
|
24584
24726
|
/**
|
|
24585
24727
|
* Read the AWS-current secret configuration in CFn-property shape.
|
|
@@ -74401,6 +74543,22 @@ function isPhase2CreatableType(resourceType) {
|
|
|
74401
74543
|
return isCustomResourceType(resourceType);
|
|
74402
74544
|
}
|
|
74403
74545
|
/**
|
|
74546
|
+
* One spelling of "this value came from an S3 key or a state record, and is
|
|
74547
|
+
* about to be interpolated into a message a terminal will render" (issue
|
|
74548
|
+
* #3003). `cdkd state show --show-nested` reaches the walker's refusals below,
|
|
74549
|
+
* and cdkd's output is line-oriented, so an unsanitized value invents a line
|
|
74550
|
+
* that reads like a row. A `logicalId` is a KEY of the record body -- CloudFormation
|
|
74551
|
+
* constrains a logical id, but nothing enforces that on a record read back
|
|
74552
|
+
* from S3, and it is half of the child stack name derived from it.
|
|
74553
|
+
*
|
|
74554
|
+
* Module-scoped rather than local to the walker: the first cut of this change
|
|
74555
|
+
* guarded the walker's two refusals and left the root one, which is the shape
|
|
74556
|
+
* the issue is about.
|
|
74557
|
+
*/
|
|
74558
|
+
function safeSegment(value) {
|
|
74559
|
+
return displaySafe(value, { asciiOnly: true }) || "<unrenderable>";
|
|
74560
|
+
}
|
|
74561
|
+
/**
|
|
74404
74562
|
* Recursively load the cdkd-state tree rooted at `(rootStackName, region)`.
|
|
74405
74563
|
* For every `AWS::CloudFormation::Stack` row in each level's
|
|
74406
74564
|
* `state.resources`, derives the child's v6 state key
|
|
@@ -74436,7 +74594,7 @@ async function buildCdkdStateStackTree(rootStackName, region, stateBackend, pref
|
|
|
74436
74594
|
if (prefetchedRootState !== void 0) rootState = prefetchedRootState;
|
|
74437
74595
|
else {
|
|
74438
74596
|
const rootResult = await stateBackend.getState(rootStackName, region);
|
|
74439
|
-
if (!rootResult) throw new Error(`No cdkd state found for stack '${rootStackName}' (${region}). Cannot build nested-stack tree.`);
|
|
74597
|
+
if (!rootResult) throw new Error(`No cdkd state found for stack '${safeSegment(rootStackName)}' (${safeSegment(region)}). Cannot build nested-stack tree.`);
|
|
74440
74598
|
rootState = rootResult.state;
|
|
74441
74599
|
}
|
|
74442
74600
|
return walkCdkdStateStackTree(rootStackName, region, rootState, stateBackend);
|
|
@@ -74447,8 +74605,8 @@ async function walkCdkdStateStackTree(stackName, region, state, stateBackend) {
|
|
|
74447
74605
|
if (resource.resourceType !== "AWS::CloudFormation::Stack") continue;
|
|
74448
74606
|
const childStackName = `${stackName}~${logicalId}`;
|
|
74449
74607
|
const childResult = await stateBackend.getState(childStackName, region);
|
|
74450
|
-
if (!childResult) throw new Error(`cdkd state is missing nested-child '${childStackName}' (${region}). Parent stack '${stackName}' lists '${logicalId}' as an ${NESTED_STACK_RESOURCE_TYPE} row but no child state file exists at 'cdkd/${childStackName}/${region}/state.json'. The cdkd state tree is inconsistent — re-deploy the parent stack to refresh, or run 'cdkd state orphan ${stackName}' and re-import.`);
|
|
74451
|
-
if (childResult.state.region !== void 0 && childResult.state.region !== region) throw new Error(`cdkd state region mismatch: nested-child '${childStackName}' has state.region='${childResult.state.region}' but its parent '${stackName}' is being walked against region='${region}'. AWS does not support cross-region nested stacks; the state tree appears corrupt — re-deploy the parent stack to refresh.`);
|
|
74608
|
+
if (!childResult) throw new Error(`cdkd state is missing nested-child '${safeSegment(childStackName)}' (${safeSegment(region)}). Parent stack '${safeSegment(stackName)}' lists '${safeSegment(logicalId)}' as an ${NESTED_STACK_RESOURCE_TYPE} row but no child state file exists at 'cdkd/${safeSegment(childStackName)}/${safeSegment(region)}/state.json'. The cdkd state tree is inconsistent — re-deploy the parent stack to refresh, or run 'cdkd state orphan ${safeSegment(stackName)}' and re-import.`);
|
|
74609
|
+
if (childResult.state.region !== void 0 && childResult.state.region !== region) throw new Error(`cdkd state region mismatch: nested-child '${safeSegment(childStackName)}' has state.region='${safeSegment(childResult.state.region)}' but its parent '${safeSegment(stackName)}' is being walked against region='${safeSegment(region)}'. AWS does not support cross-region nested stacks; the state tree appears corrupt — re-deploy the parent stack to refresh.`);
|
|
74452
74610
|
nestedChildren.set(logicalId, await walkCdkdStateStackTree(childStackName, region, childResult.state, stateBackend));
|
|
74453
74611
|
}
|
|
74454
74612
|
return {
|
|
@@ -76501,8 +76659,34 @@ function formatStackRef(ref) {
|
|
|
76501
76659
|
* `()` would read as "no region" rather than "a region cdkd will not print".
|
|
76502
76660
|
*/
|
|
76503
76661
|
function formatStackRefSafe(ref) {
|
|
76504
|
-
|
|
76505
|
-
|
|
76662
|
+
return ref.region ? `${safe(ref.stackName)} (${safe(ref.region)})` : safe(ref.stackName);
|
|
76663
|
+
}
|
|
76664
|
+
/**
|
|
76665
|
+
* One spelling of "this value came from an S3 key or a state record, and is
|
|
76666
|
+
* about to be interpolated into a message a terminal will render".
|
|
76667
|
+
*
|
|
76668
|
+
* Call it for a stack name or a region. NOT every refusal in this file goes
|
|
76669
|
+
* through it, and this comment does not say which do -- `grep safe(` answers
|
|
76670
|
+
* it exactly. The sentence that used to sit here claimed all of them, and
|
|
76671
|
+
* three sites in `state destroy` / `state refresh-observed` disprove it by
|
|
76672
|
+
* interpolating a `listStacks()` region raw (go-to-k/cdkd#3027). That is the
|
|
76673
|
+
* same over-claiming shape `lock-manager.ts`'s twin helper records having got
|
|
76674
|
+
* wrong three times.
|
|
76675
|
+
*
|
|
76676
|
+
* It exists as one function rather than the expression repeated per site
|
|
76677
|
+
* because the failure this closes WAS the repeated form: issue #2772 guarded
|
|
76678
|
+
* the rendered rows and left the refusals, and the first cut of #3003 guarded
|
|
76679
|
+
* three refusals and left four more in these same two commands. A value
|
|
76680
|
+
* reaching a message is the population, not a list of call sites.
|
|
76681
|
+
*
|
|
76682
|
+
* `asciiOnly` because the population has a known charset — CloudFormation
|
|
76683
|
+
* constrains a stack name and AWS constrains a region, so the allowlist is a
|
|
76684
|
+
* no-op on every legitimate input while an S3 key admits any UTF-8. Free-form
|
|
76685
|
+
* text (a parser's own message, an AWS error) takes the denylist class
|
|
76686
|
+
* instead; `display-safe.ts`'s header draws that line.
|
|
76687
|
+
*/
|
|
76688
|
+
function safe(value) {
|
|
76689
|
+
return displaySafe(value, { asciiOnly: true }) || "<unrenderable>";
|
|
76506
76690
|
}
|
|
76507
76691
|
/**
|
|
76508
76692
|
* Resolve a stack name + optional region flag against the `listStacks` index
|
|
@@ -76512,18 +76696,18 @@ function formatStackRefSafe(ref) {
|
|
|
76512
76696
|
*/
|
|
76513
76697
|
function resolveSingleRegion(stackName, refs, requestedRegion) {
|
|
76514
76698
|
const matches = refs.filter((r) => r.stackName === stackName);
|
|
76515
|
-
if (matches.length === 0) throw new Error(`No state found for stack '${stackName}'. Run 'cdkd state list' to see available stacks.`);
|
|
76699
|
+
if (matches.length === 0) throw new Error(`No state found for stack '${safe(stackName)}'. Run 'cdkd state list' to see available stacks.`);
|
|
76516
76700
|
if (requestedRegion) {
|
|
76517
76701
|
const ref = matches.find((r) => r.region === requestedRegion);
|
|
76518
76702
|
if (!ref) {
|
|
76519
|
-
const seen = matches.map((r) => r.region
|
|
76520
|
-
throw new Error(`No state found for stack '${stackName}' in region '${requestedRegion}'. Available regions: ${seen}.`);
|
|
76703
|
+
const seen = matches.map((r) => r.region === void 0 ? "(legacy)" : safe(r.region));
|
|
76704
|
+
throw new Error(`No state found for stack '${safe(stackName)}' in region '${safe(requestedRegion)}'. Available regions: ${seen.join(", ")}.`);
|
|
76521
76705
|
}
|
|
76522
76706
|
return ref;
|
|
76523
76707
|
}
|
|
76524
76708
|
if (matches.length === 1) return matches[0];
|
|
76525
|
-
const regions = matches.map((r) => r.region
|
|
76526
|
-
throw new Error(`Stack '${stackName}' has state in multiple regions: ${regions}. Re-run with --stack-region <region> to disambiguate.`);
|
|
76709
|
+
const regions = matches.map((r) => r.region === void 0 ? "(legacy)" : safe(r.region));
|
|
76710
|
+
throw new Error(`Stack '${safe(stackName)}' has state in multiple regions: ${regions.join(", ")}. Re-run with --stack-region <region> to disambiguate.`);
|
|
76527
76711
|
}
|
|
76528
76712
|
/**
|
|
76529
76713
|
* Shared bootstrap for every `state` subcommand: build the AWS clients,
|
|
@@ -76744,9 +76928,9 @@ async function stateResourcesCommand(stackName, options) {
|
|
|
76744
76928
|
const setup = await setupStateBackend(options);
|
|
76745
76929
|
try {
|
|
76746
76930
|
const ref = resolveSingleRegion(stackName, await setup.stateBackend.listStacks(), options.stackRegion);
|
|
76747
|
-
if (!ref.region) throw new Error(`Stack '${stackName}' has only a legacy state record without a region. Run 'cdkd deploy ${stackName}' (or any cdkd write) to migrate it to the region-scoped layout, then re-run this command.`);
|
|
76931
|
+
if (!ref.region) throw new Error(`Stack '${safe(stackName)}' has only a legacy state record without a region. Run 'cdkd deploy ${safe(stackName)}' (or any cdkd write) to migrate it to the region-scoped layout, then re-run this command.`);
|
|
76748
76932
|
const stateResult = await setup.stateBackend.getState(stackName, ref.region);
|
|
76749
|
-
if (!stateResult) throw new Error(`No state found for stack '${stackName}' (${ref.region}) in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`);
|
|
76933
|
+
if (!stateResult) throw new Error(`No state found for stack '${safe(stackName)}' (${safe(ref.region)}) in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`);
|
|
76750
76934
|
const resources = stateResult.state.resources ?? {};
|
|
76751
76935
|
const details = Object.entries(resources).map(([logicalId, resource]) => ({
|
|
76752
76936
|
logicalId,
|
|
@@ -76951,9 +77135,9 @@ async function stateShowCommand(stackName, options) {
|
|
|
76951
77135
|
const setup = await setupStateBackend(options);
|
|
76952
77136
|
try {
|
|
76953
77137
|
const ref = resolveSingleRegion(stackName, await setup.stateBackend.listStacks(), options.stackRegion);
|
|
76954
|
-
if (!ref.region) throw new Error(`Stack '${stackName}' has only a legacy state record without a region. Run 'cdkd deploy ${stackName}' (or any cdkd write) to migrate it to the region-scoped layout, then re-run this command.`);
|
|
77138
|
+
if (!ref.region) throw new Error(`Stack '${safe(stackName)}' has only a legacy state record without a region. Run 'cdkd deploy ${safe(stackName)}' (or any cdkd write) to migrate it to the region-scoped layout, then re-run this command.`);
|
|
76955
77139
|
const [stateResult, lockInfo] = await Promise.all([setup.stateBackend.getState(stackName, ref.region), setup.lockManager.getLockInfo(stackName, ref.region)]);
|
|
76956
|
-
if (!stateResult) throw new Error(`No state found for stack '${stackName}' (${ref.region}) in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`);
|
|
77140
|
+
if (!stateResult) throw new Error(`No state found for stack '${safe(stackName)}' (${safe(ref.region)}) in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`);
|
|
76957
77141
|
if (options.showNested) {
|
|
76958
77142
|
const treeWithLocks = await loadLocksForTree(await buildCdkdStateStackTree(stackName, ref.region, setup.stateBackend, stateResult.state), setup.lockManager, lockInfo);
|
|
76959
77143
|
if (options.json) {
|
|
@@ -91753,4 +91937,4 @@ function buildProgram() {
|
|
|
91753
91937
|
|
|
91754
91938
|
//#endregion
|
|
91755
91939
|
export { buildProgram };
|
|
91756
|
-
//# sourceMappingURL=program-
|
|
91940
|
+
//# sourceMappingURL=program-CgSZ7WgF.js.map
|