@go-to-k/cdkd 0.46.0 → 0.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +239 -21
- package/dist/cli.js.map +2 -2
- package/dist/go-to-k-cdkd-0.47.0.tgz +0 -0
- package/dist/index.js +107 -4
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.46.0.tgz +0 -0
|
Binary file
|
package/dist/index.js
CHANGED
|
@@ -2922,8 +2922,8 @@ import {
|
|
|
2922
2922
|
} from "@aws-sdk/client-s3";
|
|
2923
2923
|
|
|
2924
2924
|
// src/types/state.ts
|
|
2925
|
-
var
|
|
2926
|
-
var
|
|
2925
|
+
var STATE_SCHEMA_VERSION_CURRENT = 3;
|
|
2926
|
+
var STATE_SCHEMA_VERSIONS_READABLE = [1, 2, 3];
|
|
2927
2927
|
|
|
2928
2928
|
// src/state/s3-state-backend.ts
|
|
2929
2929
|
var LEGACY_KEY_DEPTH = 2;
|
|
@@ -3406,9 +3406,9 @@ var S3StateBackend = class {
|
|
|
3406
3406
|
);
|
|
3407
3407
|
}
|
|
3408
3408
|
const v = parsed.version;
|
|
3409
|
-
if (v !==
|
|
3409
|
+
if (v !== void 0 && !STATE_SCHEMA_VERSIONS_READABLE.includes(v)) {
|
|
3410
3410
|
throw new StateError(
|
|
3411
|
-
`Unsupported state schema version ${String(v)} for stack '${stackName}'. This cdkd binary supports versions ${
|
|
3411
|
+
`Unsupported state schema version ${String(v)} for stack '${stackName}'. This cdkd binary supports versions ${STATE_SCHEMA_VERSIONS_READABLE.join(", ")}. Upgrade cdkd to a version that supports schema ${String(v)}.`
|
|
3412
3412
|
);
|
|
3413
3413
|
}
|
|
3414
3414
|
return parsed;
|
|
@@ -8344,6 +8344,18 @@ var IAMRoleProvider = class {
|
|
|
8344
8344
|
}
|
|
8345
8345
|
return result;
|
|
8346
8346
|
}
|
|
8347
|
+
/**
|
|
8348
|
+
* `Policies` (inline policy bodies) are intentionally omitted from
|
|
8349
|
+
* `readCurrentState`: surfacing the names without bodies would
|
|
8350
|
+
* guarantee a `PolicyDocument`-shaped drift on every role, and
|
|
8351
|
+
* fetching every body costs one extra `GetRolePolicy` per inline
|
|
8352
|
+
* policy. Tell the drift comparator to skip the whole subtree until a
|
|
8353
|
+
* dedicated PR adds proper inline-policy drift via per-name
|
|
8354
|
+
* `GetRolePolicy`.
|
|
8355
|
+
*/
|
|
8356
|
+
getDriftUnknownPaths() {
|
|
8357
|
+
return ["Policies"];
|
|
8358
|
+
}
|
|
8347
8359
|
/**
|
|
8348
8360
|
* Adopt an existing IAM role into cdkd state.
|
|
8349
8361
|
*
|
|
@@ -8715,10 +8727,23 @@ var DeployEngine = class {
|
|
|
8715
8727
|
this.options.noRollback = options.noRollback ?? false;
|
|
8716
8728
|
this.options.resourceWarnAfterMs = options.resourceWarnAfterMs ?? DEFAULT_RESOURCE_WARN_AFTER_MS;
|
|
8717
8729
|
this.options.resourceTimeoutMs = options.resourceTimeoutMs ?? DEFAULT_RESOURCE_TIMEOUT_MS;
|
|
8730
|
+
this.options.captureObservedState = options.captureObservedState ?? true;
|
|
8718
8731
|
}
|
|
8719
8732
|
logger = getLogger().child("DeployEngine");
|
|
8720
8733
|
resolver;
|
|
8721
8734
|
interrupted = false;
|
|
8735
|
+
/**
|
|
8736
|
+
* In-flight `provider.readCurrentState` promises kicked off after a
|
|
8737
|
+
* successful CREATE / UPDATE. The deploy critical path does NOT
|
|
8738
|
+
* `await` these; instead they're drained at the end of `doDeploy`
|
|
8739
|
+
* (success path only) and the resolved values are merged into
|
|
8740
|
+
* `ResourceState.observedProperties` before the final state save.
|
|
8741
|
+
*
|
|
8742
|
+
* Each Promise resolves to the AWS-current snapshot, or `undefined`
|
|
8743
|
+
* if the provider does not implement `readCurrentState` or the call
|
|
8744
|
+
* threw — never rejects, so an unhandled-rejection cannot escape.
|
|
8745
|
+
*/
|
|
8746
|
+
observedCaptureTasks = /* @__PURE__ */ new Map();
|
|
8722
8747
|
/**
|
|
8723
8748
|
* Target region for this stack. Required — load-bearing for the
|
|
8724
8749
|
* region-prefixed S3 state key and recorded in state.json for
|
|
@@ -8731,6 +8756,61 @@ var DeployEngine = class {
|
|
|
8731
8756
|
async deploy(stackName, template) {
|
|
8732
8757
|
return withStackName(stackName, () => this.doDeploy(stackName, template));
|
|
8733
8758
|
}
|
|
8759
|
+
/**
|
|
8760
|
+
* Kick off `provider.readCurrentState` for a freshly-created/updated
|
|
8761
|
+
* resource without blocking the deploy critical path. The promise
|
|
8762
|
+
* lands in `observedCaptureTasks` keyed by `logicalId`; the deploy's
|
|
8763
|
+
* success-path drain (`drainObservedCaptures`) awaits the full set
|
|
8764
|
+
* and merges the resolved values into `ResourceState.observedProperties`
|
|
8765
|
+
* before the final state save.
|
|
8766
|
+
*
|
|
8767
|
+
* Errors are swallowed at the Promise level — readCurrentState
|
|
8768
|
+
* failing must not fail the deploy. The map entry resolves to
|
|
8769
|
+
* `undefined` for failures and for providers without
|
|
8770
|
+
* `readCurrentState`; both translate to "no observedProperties" at
|
|
8771
|
+
* the merge step, which is fine: drift falls back to comparing
|
|
8772
|
+
* against `properties`.
|
|
8773
|
+
*/
|
|
8774
|
+
kickOffObservedCapture(provider, logicalId, physicalId, resourceType, resolvedProps) {
|
|
8775
|
+
if (this.options.captureObservedState !== true)
|
|
8776
|
+
return;
|
|
8777
|
+
if (!provider.readCurrentState)
|
|
8778
|
+
return;
|
|
8779
|
+
const promise = provider.readCurrentState(physicalId, logicalId, resourceType, resolvedProps).catch((err) => {
|
|
8780
|
+
this.logger.debug(
|
|
8781
|
+
`observedProperties capture for ${logicalId} (${resourceType}) failed: ${err instanceof Error ? err.message : String(err)} \u2014 drift will fall back to template properties for this resource until the next successful deploy.`
|
|
8782
|
+
);
|
|
8783
|
+
return void 0;
|
|
8784
|
+
});
|
|
8785
|
+
this.observedCaptureTasks.set(logicalId, promise);
|
|
8786
|
+
}
|
|
8787
|
+
/**
|
|
8788
|
+
* Wait for every in-flight `readCurrentState` promise from the
|
|
8789
|
+
* deploy's success path, then merge each resolved snapshot into the
|
|
8790
|
+
* matching `ResourceState.observedProperties`. After this runs the
|
|
8791
|
+
* map is drained so a subsequent deploy starts fresh.
|
|
8792
|
+
*
|
|
8793
|
+
* Called from `doDeploy` immediately before the final `saveState`.
|
|
8794
|
+
* The rollback / failure paths intentionally do NOT call this — a
|
|
8795
|
+
* failed deploy's partial state is already inconsistent, and waiting
|
|
8796
|
+
* on potentially many in-flight reads would slow down the rollback
|
|
8797
|
+
* itself.
|
|
8798
|
+
*/
|
|
8799
|
+
async drainObservedCaptures(stateResources) {
|
|
8800
|
+
if (this.observedCaptureTasks.size === 0)
|
|
8801
|
+
return;
|
|
8802
|
+
const entries = Array.from(this.observedCaptureTasks.entries());
|
|
8803
|
+
this.observedCaptureTasks.clear();
|
|
8804
|
+
const resolved = await Promise.all(entries.map(([, p]) => p));
|
|
8805
|
+
for (let i = 0; i < entries.length; i++) {
|
|
8806
|
+
const logicalId = entries[i][0];
|
|
8807
|
+
const observed = resolved[i];
|
|
8808
|
+
const target = stateResources[logicalId];
|
|
8809
|
+
if (target && observed !== void 0) {
|
|
8810
|
+
target.observedProperties = observed;
|
|
8811
|
+
}
|
|
8812
|
+
}
|
|
8813
|
+
}
|
|
8734
8814
|
async doDeploy(stackName, template) {
|
|
8735
8815
|
const startTime = Date.now();
|
|
8736
8816
|
this.logger.debug(`Starting deployment for stack: ${stackName}`);
|
|
@@ -8847,6 +8927,7 @@ var DeployEngine = class {
|
|
|
8847
8927
|
progress,
|
|
8848
8928
|
migrationPending
|
|
8849
8929
|
);
|
|
8930
|
+
await this.drainObservedCaptures(newState.resources);
|
|
8850
8931
|
const newEtag = await this.stateBackend.saveState(stackName, this.stackRegion, newState);
|
|
8851
8932
|
this.logger.debug(`State saved (ETag: ${newEtag})`);
|
|
8852
8933
|
const durationMs = Date.now() - startTime;
|
|
@@ -8862,6 +8943,7 @@ var DeployEngine = class {
|
|
|
8862
8943
|
} finally {
|
|
8863
8944
|
renderer.stop();
|
|
8864
8945
|
process.removeListener("SIGINT", sigintHandler);
|
|
8946
|
+
this.observedCaptureTasks.clear();
|
|
8865
8947
|
try {
|
|
8866
8948
|
await this.lockManager.releaseLock(stackName, this.stackRegion);
|
|
8867
8949
|
this.logger.debug("Lock released");
|
|
@@ -9415,6 +9497,13 @@ var DeployEngine = class {
|
|
|
9415
9497
|
...result.attributes && { attributes: result.attributes },
|
|
9416
9498
|
...dependencies && dependencies.length > 0 && { dependencies }
|
|
9417
9499
|
};
|
|
9500
|
+
this.kickOffObservedCapture(
|
|
9501
|
+
provider,
|
|
9502
|
+
logicalId,
|
|
9503
|
+
result.physicalId,
|
|
9504
|
+
resourceType,
|
|
9505
|
+
resolvedProps
|
|
9506
|
+
);
|
|
9418
9507
|
if (counts)
|
|
9419
9508
|
counts.created++;
|
|
9420
9509
|
if (progress)
|
|
@@ -9493,6 +9582,13 @@ var DeployEngine = class {
|
|
|
9493
9582
|
...createResult.attributes && { attributes: createResult.attributes },
|
|
9494
9583
|
...dependencies && dependencies.length > 0 && { dependencies }
|
|
9495
9584
|
};
|
|
9585
|
+
this.kickOffObservedCapture(
|
|
9586
|
+
provider,
|
|
9587
|
+
logicalId,
|
|
9588
|
+
createResult.physicalId,
|
|
9589
|
+
resourceType,
|
|
9590
|
+
resolvedProps
|
|
9591
|
+
);
|
|
9496
9592
|
if (counts)
|
|
9497
9593
|
counts.updated++;
|
|
9498
9594
|
if (progress)
|
|
@@ -9571,6 +9667,13 @@ var DeployEngine = class {
|
|
|
9571
9667
|
...result.attributes && { attributes: result.attributes },
|
|
9572
9668
|
...dependencies && dependencies.length > 0 && { dependencies }
|
|
9573
9669
|
};
|
|
9670
|
+
this.kickOffObservedCapture(
|
|
9671
|
+
provider,
|
|
9672
|
+
logicalId,
|
|
9673
|
+
result.physicalId,
|
|
9674
|
+
resourceType,
|
|
9675
|
+
resolvedProps
|
|
9676
|
+
);
|
|
9574
9677
|
if (counts)
|
|
9575
9678
|
counts.updated++;
|
|
9576
9679
|
if (progress)
|