@go-to-k/cdkd 0.278.26 → 0.278.28
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-DLScqiT2.js → asg-provider-BJnh483x.js} +2 -2
- package/dist/{asg-provider-DLScqiT2.js.map → asg-provider-BJnh483x.js.map} +1 -1
- package/dist/cli.js +76 -46
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-BsHkBRtK.js → deploy-engine-Dcg1nH3d.js} +160 -7
- package/dist/deploy-engine-Dcg1nH3d.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-BsHkBRtK.js.map +0 -1
|
@@ -9094,6 +9094,133 @@ async function applyRoleArnIfSet(opts) {
|
|
|
9094
9094
|
}
|
|
9095
9095
|
}
|
|
9096
9096
|
|
|
9097
|
+
//#endregion
|
|
9098
|
+
//#region src/provisioning/config-shape.ts
|
|
9099
|
+
/**
|
|
9100
|
+
* Shape guards for nested CloudFormation config blocks read by SDK providers.
|
|
9101
|
+
*
|
|
9102
|
+
* The bug class this exists for (issue #1471): a provider reads a string out
|
|
9103
|
+
* of a nested block with
|
|
9104
|
+
*
|
|
9105
|
+
* ```ts
|
|
9106
|
+
* const status = (versioningConfig['Status'] as string) || 'Suspended';
|
|
9107
|
+
* ```
|
|
9108
|
+
*
|
|
9109
|
+
* When `versioningConfig` is a STRING / array / number rather than the object
|
|
9110
|
+
* the template was supposed to carry, the index yields `undefined` and the
|
|
9111
|
+
* `||` substitutes the default — which is frequently the OPPOSITE of what the
|
|
9112
|
+
* template declared. `VersioningConfiguration: 'Enabled'` (a hand-written L1
|
|
9113
|
+
* template, or an intrinsic the resolver could not resolve) therefore turned
|
|
9114
|
+
* versioning OFF on a live bucket with no error anywhere. The same shape was
|
|
9115
|
+
* measured at 16 sites across 5 providers.
|
|
9116
|
+
*
|
|
9117
|
+
* `readConfigString` is that read, done safely, in ONE place — so the class is
|
|
9118
|
+
* fixed by construction rather than by 16 hand-written `throw`s that can each
|
|
9119
|
+
* be subtly different.
|
|
9120
|
+
*
|
|
9121
|
+
* Four rules, each of which the versioning case forced (see #1471):
|
|
9122
|
+
*
|
|
9123
|
+
* 1. **An absent container is not an error.** `undefined` / `null` means the
|
|
9124
|
+
* template omitted the block, and the caller's default is the right answer.
|
|
9125
|
+
* 2. **A present-but-non-object container is refused.** This is the headline
|
|
9126
|
+
* bug: a string container silently produced the default.
|
|
9127
|
+
* 3. **An absent KEY is not an error** — `{}` legitimately means "defaulted",
|
|
9128
|
+
* e.g. `VersioningConfiguration: {}` really does mean Suspended.
|
|
9129
|
+
* 4. **A present-but-unusable key is refused.** `{ Status: null }` and
|
|
9130
|
+
* `{ Status: '' }` both pass a `typeof container === 'object'` check and
|
|
9131
|
+
* still fall through to the default, so validating the CONTAINER alone is
|
|
9132
|
+
* not enough — the FIELD has to be validated too.
|
|
9133
|
+
*
|
|
9134
|
+
* **Callers must pass the DESIRED side only.** The previous side comes from
|
|
9135
|
+
* cdkd state, not from the user's template: a stack deployed by an older cdkd
|
|
9136
|
+
* that already recorded a malformed value would otherwise throw on every
|
|
9137
|
+
* subsequent `cdkd deploy`, with no way out except hand-editing the S3 state
|
|
9138
|
+
* file (editing the template does not help, because the previous side stays
|
|
9139
|
+
* malformed until a deploy succeeds). An earlier attempt at this fix guarded
|
|
9140
|
+
* both sides and turned a silent misbehavior into an unrecoverable one; that
|
|
9141
|
+
* is why `KinesisProvider`'s read of `previousProperties.StreamModeDetails`
|
|
9142
|
+
* is deliberately left unguarded.
|
|
9143
|
+
*
|
|
9144
|
+
* This is a provider-layer guard rather than a pre-flight template check
|
|
9145
|
+
* because **rule 4** is only decidable AFTER intrinsic resolution: at pre-flight
|
|
9146
|
+
* time a legitimate `Fn::If`-valued block is an object whose `Status` key does
|
|
9147
|
+
* not exist yet, so a pre-flight field check would reject valid templates.
|
|
9148
|
+
* (Rule 3 is permissive and so cannot false-positive at any layer — it simply
|
|
9149
|
+
* could never be STRENGTHENED at pre-flight, since an absent key there is
|
|
9150
|
+
* indistinguishable from one an intrinsic will supply. Rule 2 alone genuinely
|
|
9151
|
+
* IS pre-flight-able; splitting one guard across two layers for it was judged
|
|
9152
|
+
* not worth the divergence.)
|
|
9153
|
+
*
|
|
9154
|
+
* The trade-off that choice accepts, recorded rather than left implicit: the
|
|
9155
|
+
* issue's pre-flight proposal would have failed BEFORE any AWS mutation,
|
|
9156
|
+
* whereas a provider-layer guard can throw after `CreateBucket` has already
|
|
9157
|
+
* succeeded. `create()` self-heals by deleting the partially-created bucket,
|
|
9158
|
+
* but a downstream refusal can still leave earlier sub-config PUTs applied —
|
|
9159
|
+
* the same exposure the pre-existing `applyOwnershipControls` throw has, and
|
|
9160
|
+
* still strictly better than a silent wrong-direction PUT.
|
|
9161
|
+
*/
|
|
9162
|
+
/**
|
|
9163
|
+
* Read an optional string field out of a nested CFn config block, refusing a
|
|
9164
|
+
* container or a value whose shape would otherwise be silently defaulted away.
|
|
9165
|
+
*
|
|
9166
|
+
* @param container The block the field lives in. Pass the provider's own
|
|
9167
|
+
* `properties` bag directly when the field is top-level.
|
|
9168
|
+
* @param key The CFn field name.
|
|
9169
|
+
* @param fallback The value to use when the container or the key is absent.
|
|
9170
|
+
* @param containerPath CFn path of the CONTAINER, used to build both error
|
|
9171
|
+
* messages, e.g. `AWS::S3::Bucket VersioningConfiguration` (the field is
|
|
9172
|
+
* reported as `<containerPath>.<key>`).
|
|
9173
|
+
* @throws Error when the container is present but not a plain object, or the
|
|
9174
|
+
* key is present but not a non-blank string.
|
|
9175
|
+
*/
|
|
9176
|
+
function readConfigString(container, key, fallback, containerPath) {
|
|
9177
|
+
if (container === void 0 || container === null) return fallback;
|
|
9178
|
+
if (!isPlainObject$1(container)) throw new Error(`${containerPath} must be an object (got ${describe(container)}) — check for an unresolved intrinsic or a mis-nested template value`);
|
|
9179
|
+
return requireConfigString(container[key], fallback, `${containerPath}.${key}`);
|
|
9180
|
+
}
|
|
9181
|
+
/**
|
|
9182
|
+
* The value-level half of {@link readConfigString}, for a value the caller has
|
|
9183
|
+
* ALREADY read out of a container it knows is a plain object — in practice a
|
|
9184
|
+
* TOP-LEVEL property read straight off the provider's `properties` bag, where
|
|
9185
|
+
* only rules 3 and 4 can apply.
|
|
9186
|
+
*
|
|
9187
|
+
* Keep this form at top-level call sites rather than passing `properties` to
|
|
9188
|
+
* {@link readConfigString}: the `handled-property-wiring` critic
|
|
9189
|
+
* (`scripts/gen-handled-property-wiring.ts`) recognises a property as WIRED
|
|
9190
|
+
* from the `properties['X']` element-read at the call site, and deliberately
|
|
9191
|
+
* does not treat a whole-bag forward into a helper as evidence. Hiding the
|
|
9192
|
+
* read inside the helper made `S3DirectoryBucketProvider` and
|
|
9193
|
+
* `WAFv2WebACLProvider` report un-wired — a false handled claim, which is the
|
|
9194
|
+
* exact thing that critic exists to prevent.
|
|
9195
|
+
*
|
|
9196
|
+
* @param value The already-read field value.
|
|
9197
|
+
* @param fallback The value to use when the field is absent.
|
|
9198
|
+
* @param path CFn path used in the error message, e.g. `AWS::WAFv2::WebACL Scope`.
|
|
9199
|
+
* @throws Error when the value is present but not a non-blank string.
|
|
9200
|
+
*/
|
|
9201
|
+
function requireConfigString(value, fallback, path) {
|
|
9202
|
+
if (value === void 0) return fallback;
|
|
9203
|
+
if (fallback === "" && typeof value === "string") return value;
|
|
9204
|
+
if (typeof value !== "string" || value.trim() === "") throw new Error(`${path} must be a non-empty string (got ${describe(value)}) — check for an unresolved intrinsic or a mis-nested template value. Omit the field entirely to use the default` + (fallback === "" ? "" : ` (${fallback})`));
|
|
9205
|
+
return value;
|
|
9206
|
+
}
|
|
9207
|
+
/**
|
|
9208
|
+
* A plain object, i.e. something a CFn config block can legitimately be.
|
|
9209
|
+
* Arrays are excluded on purpose: an array where an object belongs is one of
|
|
9210
|
+
* the malformed shapes this module exists to catch, and `typeof [] === 'object'`
|
|
9211
|
+
* would otherwise wave it through.
|
|
9212
|
+
*/
|
|
9213
|
+
function isPlainObject$1(value) {
|
|
9214
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9215
|
+
}
|
|
9216
|
+
/** Human-readable type for an error message, without dumping user data. */
|
|
9217
|
+
function describe(value) {
|
|
9218
|
+
if (value === null) return "null";
|
|
9219
|
+
if (Array.isArray(value)) return "an array";
|
|
9220
|
+
if (typeof value === "string") return value.trim() === "" ? "a blank string" : "a string";
|
|
9221
|
+
return typeof value === "object" ? "an object" : `a ${typeof value}`;
|
|
9222
|
+
}
|
|
9223
|
+
|
|
9097
9224
|
//#endregion
|
|
9098
9225
|
//#region src/provisioning/region-check.ts
|
|
9099
9226
|
/**
|
|
@@ -9601,7 +9728,7 @@ var WAFv2WebACLProvider = class {
|
|
|
9601
9728
|
async create(logicalId, resourceType, properties) {
|
|
9602
9729
|
this.logger.debug(`Creating WAFv2 WebACL ${logicalId}`);
|
|
9603
9730
|
const name = properties["Name"] || generateResourceName(logicalId, { maxLength: 128 });
|
|
9604
|
-
const scope = properties["Scope"]
|
|
9731
|
+
const scope = requireConfigString(properties["Scope"], "REGIONAL", "AWS::WAFv2::WebACL Scope");
|
|
9605
9732
|
this.warnOnSdkUnsupportedRuleKeys(logicalId, properties["Rules"]);
|
|
9606
9733
|
try {
|
|
9607
9734
|
const tags = [];
|
|
@@ -12430,7 +12557,7 @@ var CloudControlProvider = class {
|
|
|
12430
12557
|
if (context?.finalSnapshotIdentifier !== void 0) throw new ProvisioningError(`${logicalId} (${resourceType}) requires a final snapshot (DeletionPolicy: Snapshot), but the Cloud Control API delete route has no final-snapshot parameter. Re-run with --skip-final-snapshot after snapshotting manually, or retain the resource.`, resourceType, logicalId, physicalId);
|
|
12431
12558
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
12432
12559
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
12433
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
12560
|
+
const { ASGProvider } = await import("./asg-provider-BJnh483x.js").then((n) => n.n);
|
|
12434
12561
|
await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
|
|
12435
12562
|
return;
|
|
12436
12563
|
}
|
|
@@ -18128,6 +18255,32 @@ async function withResourceDeadline(operation, opts) {
|
|
|
18128
18255
|
/** The `--skip-final-snapshot` flag name cited by every refusal below. */
|
|
18129
18256
|
const SKIP_FINAL_SNAPSHOT_FLAG = "--skip-final-snapshot";
|
|
18130
18257
|
/**
|
|
18258
|
+
* The {@link CreateContext} every reverse-replacement re-create passes
|
|
18259
|
+
* (issue #1463). Both arms of that path — the create-first attempt and the
|
|
18260
|
+
* delete-new-first retry — revive the OLD resource from
|
|
18261
|
+
* `previousState.properties`, i.e. from a cdkd STATE record rather than the
|
|
18262
|
+
* template, so a provider pre-flight refusal has no template-side remedy and
|
|
18263
|
+
* must downgrade to a warning. Declared once so the two arms cannot drift.
|
|
18264
|
+
*
|
|
18265
|
+
* These are the only create call sites that can DECLARE a replay. The deploy
|
|
18266
|
+
* engine's five sites (CREATE, the property-driven replacement, the
|
|
18267
|
+
* `--recreate-via-*` destroy-then-create, the `--replace` delete-first
|
|
18268
|
+
* fallback, and the update-failure replacement) are all driven by freshly
|
|
18269
|
+
* resolved TEMPLATE properties, so they deliberately pass no context and the
|
|
18270
|
+
* refusal stands where the user can edit the input.
|
|
18271
|
+
*
|
|
18272
|
+
* The remaining call sites are the providers that re-create inside their own
|
|
18273
|
+
* `update()` (`this.create(...)` in ACM certificate / IAM managed policy / IAM
|
|
18274
|
+
* role / Lambda permission / SNS subscription). Those are NOT template-driven
|
|
18275
|
+
* — this executor's `revert` arm calls `provider.update(...)` with
|
|
18276
|
+
* `previousState.properties`, so they forward a STATE record on a replay — but
|
|
18277
|
+
* they CANNOT receive a context, because `update()` has no context parameter.
|
|
18278
|
+
* The constraint that follows is on providers, not on this constant: a
|
|
18279
|
+
* provider with a create-side pre-flight refusal must not re-create inside
|
|
18280
|
+
* `update()`. See `CreateContext` in `src/types/resource.ts`.
|
|
18281
|
+
*/
|
|
18282
|
+
const REPLAYING_STATE_CREATE_CONTEXT = { replayingState: true };
|
|
18283
|
+
/**
|
|
18131
18284
|
* Which provisioning layer a delete must be judged against: the CURRENT
|
|
18132
18285
|
* state record wins (it is what state says AWS holds right now), with the
|
|
18133
18286
|
* journaled op's routing as the legacy-state fallback. Shared by both
|
|
@@ -18542,7 +18695,7 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
|
|
|
18542
18695
|
let deletedNewFirst = false;
|
|
18543
18696
|
let createResult;
|
|
18544
18697
|
try {
|
|
18545
|
-
createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...prev.properties }), op.logicalId, {
|
|
18698
|
+
createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...prev.properties }, REPLAYING_STATE_CREATE_CONTEXT), op.logicalId, {
|
|
18546
18699
|
...RECREATE_RETRY_SCHEDULE,
|
|
18547
18700
|
logger,
|
|
18548
18701
|
...isInterrupted && {
|
|
@@ -18565,7 +18718,7 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
|
|
|
18565
18718
|
delete stateResources[op.logicalId];
|
|
18566
18719
|
await afterOp?.(op.logicalId);
|
|
18567
18720
|
try {
|
|
18568
|
-
createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...prev.properties }), op.logicalId, {
|
|
18721
|
+
createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...prev.properties }, REPLAYING_STATE_CREATE_CONTEXT), op.logicalId, {
|
|
18569
18722
|
...RECREATE_RETRY_SCHEDULE,
|
|
18570
18723
|
logger,
|
|
18571
18724
|
...isInterrupted && {
|
|
@@ -18898,7 +19051,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
18898
19051
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
18899
19052
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
18900
19053
|
function getCdkdVersion() {
|
|
18901
|
-
return "0.278.
|
|
19054
|
+
return "0.278.28";
|
|
18902
19055
|
}
|
|
18903
19056
|
/**
|
|
18904
19057
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -21009,5 +21162,5 @@ var DeployEngine = class {
|
|
|
21009
21162
|
};
|
|
21010
21163
|
|
|
21011
21164
|
//#endregion
|
|
21012
|
-
export {
|
|
21013
|
-
//# sourceMappingURL=deploy-engine-
|
|
21165
|
+
export { withRetry as $, getAwsClients as $t, red as A, synthesisStatusMessage as At, isTerminationProtectionPropagationError as B, stateBucketExistenceConfirmed as Bt, isStatefulRecreateTargetSync as C, normalizeAwsError as Cn, formatDockerLoginError as Ct, cyan as D, AssetManifestLoader as Dt, bold as E, runDockerStreaming as Et, ProviderRegistry as F, resolveCaptureObservedState as Ft, normalizeAwsTagsToCfn as G, findLargeInlineResources as Gt, cfnRefValueFromPhysicalId as H, CFN_TEMPLATE_BODY_LIMIT as Ht, findActionableSilentDrops as I, resolveSkipPrefix as It, readConfigString as J, AssemblyReader as Jt, resolveExplicitPhysicalId as K, uploadCfnTemplate as Kt, CloudControlProvider as L, resolveStateBucketWithDefault as Lt, IAMRoleProvider as M, getLegacyStateBucketName as Mt, collectInlinePolicyNamesManagedBySiblings as N, resolveApp as Nt, gray as O, getDockerImageBySourceHash as Ot, clearOnUpdateRemoval as P, resolveAutoAssetStorage as Pt, describeTypeWithThrottleRetry as Q, AwsClients as Qt, slowCcOperationTimeoutMs as R, resolveStateBucketWithDefaultAndSource as Rt, MULTI_REGION_RECREATE_BLOCKED_TYPES as S, isCdkdError as Sn, buildDockerImage as St, formatResourceLine as T, __exportAll as Tn, runDockerForeground as Tt, refStateLookupFromResource as U, CFN_TEMPLATE_URL_LIMIT as Ut, IntrinsicFunctionResolver as V, warnDeprecatedNoPrefixCliFlag as Vt, WAFv2WebACLProvider as W, MIGRATE_TMP_PREFIX as Wt, applyRoleArnIfSet as X, clearBucketRegionCache as Xt, requireConfigString as Y, processStackMessages as Yt, DiffCalculator as Z, resolveBucketRegion as Zt, createPreDeleteFinalSnapshot as _, StackHasActiveImportsError as _n, ensureAssetStorage as _t, DeploymentEventsStore as a, DependencyError as an, S3StateBackend as at, unsupportedFinalSnapshotError as b, SynthesisError as bn, validateAssetBucketName as bt, replayFailedOperations as c, LocalMigrateError as cn, AssetPublisher as ct, IMPLICIT_DELETE_DEPENDENCIES as d, MissingCdkCliError as dn, buildAssetRedirectMap as dt, resetAwsClients as en, isRetryableTransientError as et, computeImplicitDeleteEdges as f, NestedStackChildDirectDestroyError as fn, createAssetRedirectResolver as ft, ccRoutedFinalSnapshotError as g, ResourceUpdateNotSupportedError as gn, BOOTSTRAP_MARKER_PREFIX as gt, buildFinalSnapshotIdentifier as h, ResourceTimeoutError as hn, AssetModeResolver as ht, DeploymentEventsReader as i, ConfigError as in, LockManager as it, yellow as j, getDefaultStateBucketName as jt, green as k, Synthesizer as kt, replayRollback as l, LocalStartServiceError as ln, stringifyValue as lt, PRE_DELETE_SNAPSHOT_TYPES as m, ProvisioningError as mn, rewriteTemplateAssetReferences as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, AssetError as nn, DagBuilder as nt, planFailedOps as o, DeployCancelledError as on, rebuildClientForBucketRegion as ot, ATOMIC_FINAL_SNAPSHOT_TYPES as p, PartialFailureError as pn, loadPublishableAssetManifest as pt, assertRegionMatch as q, expectedOwnerParam as qt, DeployEngine as r, CdkdError as rn, TemplateParser as rt, planRollback as s, LocalInvokeBuildError as sn, shouldRetainResource as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, setAwsClients as tn, isThrottlingError as tt, withResourceDeadline as u, LockError as un, WorkGraph as ut, isFinalSnapshotError as v, StackTerminationProtectionError as vn, getBootstrapMarkerKey as vt, renderStatefulReason as w, withErrorHandling as wn, getDockerCmd as wt, extractDeploymentEventError as x, formatError as xn, validateContainerRepoName as xt, refusesFinalSnapshot as y, StateError as yn, parseBootstrapMarker as yt, disableInstanceApiTermination as z, resolveUseCdkBootstrapAssets as zt };
|
|
21166
|
+
//# sourceMappingURL=deploy-engine-Dcg1nH3d.js.map
|