@go-to-k/cdkd 0.165.0 → 0.166.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 +111 -23
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-DEbogepd.js → deploy-engine-BQkk03hJ.js} +14 -7
- package/dist/{deploy-engine-DEbogepd.js.map → deploy-engine-BQkk03hJ.js.map} +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { _ as withSkipPrefix, a as runDockerStreaming, c as getLogger, d as getLiveRenderer, f as PATTERN_B_NAME_PROPERTIES, g as generateResourceNameWithFallback, h as generateResourceName, i as runDockerForeground, n as formatDockerLoginError, p as PATTERN_B_RESOURCE_TYPES, r as getDockerCmd, u as runStackBuffered, v as withStackName } from "./docker-cmd-iDMcWcre.js";
|
|
3
|
-
import { A as S3StateBackend, B as resolveCaptureObservedState, C as assertRegionMatch, D as DagBuilder, E as DiffCalculator, F as buildDockerImage, G as CFN_TEMPLATE_BODY_LIMIT, H as resolveStateBucketWithDefault, I as Synthesizer, J as findLargeInlineResources, K as CFN_TEMPLATE_URL_LIMIT, L as getDefaultStateBucketName, M as AssetPublisher, N as stringifyValue, O as TemplateParser, P as WorkGraph, Q as resolveBucketRegion, R as getLegacyStateBucketName, S as CloudControlProvider, T as applyRoleArnIfSet, U as resolveStateBucketWithDefaultAndSource, V as resolveSkipPrefix, W as warnDeprecatedNoPrefixCliFlag, X as AssemblyReader, Y as uploadCfnTemplate, _ as matchesCdkPath, a as withRetry, at as LocalStartServiceError, b as ProviderRegistry, bt as normalizeAwsError, c as bold, ct as NestedStackChildDirectDestroyError, d as green, dt as ResourceTimeoutError, et as CdkdError, f as red, ft as ResourceUpdateNotSupportedError, g as CDK_PATH_TAG, h as collectInlinePolicyNamesManagedBySiblings, ht as StackTerminationProtectionError, i as withResourceDeadline, it as LocalMigrateError, j as shouldRetainResource, k as LockManager, l as cyan, lt as PartialFailureError, m as IAMRoleProvider, mt as StackHasActiveImportsError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as IMPLICIT_DELETE_DEPENDENCIES, p as yellow, pt as RouteDiscoveryError, q as MIGRATE_TMP_PREFIX, r as DeployEngine, rt as LocalInvokeBuildError, s as formatResourceLine, st as MissingCdkCliError, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as gray, ut as ProvisioningError, v as normalizeAwsTagsToCfn, w as IntrinsicFunctionResolver, x as findActionableSilentDrops, xt as withErrorHandling, y as resolveExplicitPhysicalId, z as resolveApp } from "./deploy-engine-
|
|
3
|
+
import { A as S3StateBackend, B as resolveCaptureObservedState, C as assertRegionMatch, D as DagBuilder, E as DiffCalculator, F as buildDockerImage, G as CFN_TEMPLATE_BODY_LIMIT, H as resolveStateBucketWithDefault, I as Synthesizer, J as findLargeInlineResources, K as CFN_TEMPLATE_URL_LIMIT, L as getDefaultStateBucketName, M as AssetPublisher, N as stringifyValue, O as TemplateParser, P as WorkGraph, Q as resolveBucketRegion, R as getLegacyStateBucketName, S as CloudControlProvider, T as applyRoleArnIfSet, U as resolveStateBucketWithDefaultAndSource, V as resolveSkipPrefix, W as warnDeprecatedNoPrefixCliFlag, X as AssemblyReader, Y as uploadCfnTemplate, _ as matchesCdkPath, a as withRetry, at as LocalStartServiceError, b as ProviderRegistry, bt as normalizeAwsError, c as bold, ct as NestedStackChildDirectDestroyError, d as green, dt as ResourceTimeoutError, et as CdkdError, f as red, ft as ResourceUpdateNotSupportedError, g as CDK_PATH_TAG, h as collectInlinePolicyNamesManagedBySiblings, ht as StackTerminationProtectionError, i as withResourceDeadline, it as LocalMigrateError, j as shouldRetainResource, k as LockManager, l as cyan, lt as PartialFailureError, m as IAMRoleProvider, mt as StackHasActiveImportsError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as IMPLICIT_DELETE_DEPENDENCIES, p as yellow, pt as RouteDiscoveryError, q as MIGRATE_TMP_PREFIX, r as DeployEngine, rt as LocalInvokeBuildError, s as formatResourceLine, st as MissingCdkCliError, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as gray, ut as ProvisioningError, v as normalizeAwsTagsToCfn, w as IntrinsicFunctionResolver, x as findActionableSilentDrops, xt as withErrorHandling, y as resolveExplicitPhysicalId, z as resolveApp } from "./deploy-engine-BQkk03hJ.js";
|
|
4
4
|
import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-B15NAPbL.js";
|
|
5
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
6
|
import { createHash, createHmac, createPublicKey, createVerify, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
@@ -449,6 +449,27 @@ function parseRecreateViaCcApiToken(value, previous) {
|
|
|
449
449
|
}
|
|
450
450
|
const recreateViaCcApiOption = new Option("--recreate-via-cc-api <logicalId>", "Destroy + recreate the named resource (by CloudFormation logical id) via Cloud Control API in this deploy, so a top-level CFn property cdkd would otherwise silently drop reaches AWS via CC. Repeatable — pass the flag once per resource. Per-resource opt-in (no bulk / no per-stack shortcut) so the destroy-and-recreate cost is acknowledged for each target. Stateful resource types (RDS, DynamoDB, S3, EFS, ...) refuse unless --force-stateful-recreation is ALSO passed (two-flag protection). Cannot be combined with --allow-unsupported-properties on the same resource type and property.").argParser(parseRecreateViaCcApiToken);
|
|
451
451
|
/**
|
|
452
|
+
* Issue [#651] — `--recreate-via-sdk-provider <LogicalId>` is the reverse
|
|
453
|
+
* direction of `--recreate-via-cc-api`. Once a resource is sticky on
|
|
454
|
+
* `provisionedBy: 'cc-api'` (e.g. after a #615 SDK→CC migration, or
|
|
455
|
+
* because cdkd auto-routed it via the #614 default-on Cloud Control
|
|
456
|
+
* fallback on a fresh deploy), subsequent SDK Provider backfills
|
|
457
|
+
* (issue #609) do NOT auto-migrate it back — sticky semantics avoid
|
|
458
|
+
* SDK↔CC ping-pong on every backfill release. This flag is the
|
|
459
|
+
* user-initiated CC → SDK migration: destroy + recreate the named
|
|
460
|
+
* resource so the new copy is `provisionedBy: 'sdk'`.
|
|
461
|
+
*
|
|
462
|
+
* Symmetric to `--recreate-via-cc-api`: same per-resource explicit
|
|
463
|
+
* opt-in, same destroy-then-create ordering, same stateful guard,
|
|
464
|
+
* same multi-region refusal, same `Continue? (y/N)` interactive prompt.
|
|
465
|
+
*/
|
|
466
|
+
function parseRecreateViaSdkProviderToken(value, previous) {
|
|
467
|
+
const token = value.trim();
|
|
468
|
+
if (!LOGICAL_ID_FORMAT.test(token)) throw new Error(`Invalid --recreate-via-sdk-provider value "${value}": expected a CloudFormation logical id (alphanumeric, starts with a letter, max 255 chars). One --recreate-via-sdk-provider flag per resource — repeat the flag for additional targets.`);
|
|
469
|
+
return [...previous ?? [], token];
|
|
470
|
+
}
|
|
471
|
+
const recreateViaSdkProviderOption = new Option("--recreate-via-sdk-provider <logicalId>", "Destroy + recreate the named resource (by CloudFormation logical id) via cdkd's SDK Provider in this deploy, so a resource currently sticky on provisionedBy: cc-api flips back to provisionedBy: sdk. Used after a #609 backfill release adds SDK coverage for a type the user originally needed CC for (e.g. Lambda LoggingConfig). Repeatable — pass the flag once per resource. Per-resource opt-in. Stateful resource types refuse unless --force-stateful-recreation is ALSO passed.").argParser(parseRecreateViaSdkProviderToken);
|
|
472
|
+
/**
|
|
452
473
|
* Issue [#615] — `--force-stateful-recreation` (boolean) is the second
|
|
453
474
|
* flag required to allow `--recreate-via-cc-api` to operate on a
|
|
454
475
|
* stateful resource (RDS / DynamoDB / EFS / S3 with data / etc.). Two
|
|
@@ -480,6 +501,7 @@ const deployOptions = [
|
|
|
480
501
|
allowUnsupportedTypesOption,
|
|
481
502
|
allowUnsupportedPropertiesOption,
|
|
482
503
|
recreateViaCcApiOption,
|
|
504
|
+
recreateViaSdkProviderOption,
|
|
483
505
|
forceStatefulRecreationOption,
|
|
484
506
|
...resourceTimeoutOptions
|
|
485
507
|
];
|
|
@@ -1089,16 +1111,31 @@ function renderStatefulReason(reason) {
|
|
|
1089
1111
|
*/
|
|
1090
1112
|
const EMPTY_ALLOW_SET$1 = /* @__PURE__ */ new Set();
|
|
1091
1113
|
function validateRecreateTargets(input) {
|
|
1114
|
+
const seenCcApi = new Set(input.recreateViaCcApi);
|
|
1115
|
+
const seenSdk = new Set(input.recreateViaSdkProvider ?? []);
|
|
1116
|
+
const conflictingDirections = [...seenCcApi].filter((id) => seenSdk.has(id));
|
|
1092
1117
|
const seen = /* @__PURE__ */ new Set();
|
|
1093
1118
|
const targets = [];
|
|
1094
1119
|
const unknownLogicalIds = [];
|
|
1095
1120
|
const missingFromState = [];
|
|
1096
1121
|
const ambiguousIntent = [];
|
|
1122
|
+
const ambiguousIntentSdk = [];
|
|
1097
1123
|
const blockedStatefulTargets = [];
|
|
1098
1124
|
const blockedMultiRegionTargets = [];
|
|
1099
|
-
|
|
1125
|
+
const blockedAlreadySdk = [];
|
|
1126
|
+
const blockedNoSdkProvider = [];
|
|
1127
|
+
const conflictSet = new Set(conflictingDirections);
|
|
1128
|
+
const namedTargets = [...input.recreateViaCcApi.map((id) => ({
|
|
1129
|
+
logicalId: id,
|
|
1130
|
+
direction: "to-cc-api"
|
|
1131
|
+
})), ...(input.recreateViaSdkProvider ?? []).map((id) => ({
|
|
1132
|
+
logicalId: id,
|
|
1133
|
+
direction: "to-sdk"
|
|
1134
|
+
}))];
|
|
1135
|
+
for (const { logicalId, direction } of namedTargets) {
|
|
1100
1136
|
if (seen.has(logicalId)) continue;
|
|
1101
1137
|
seen.add(logicalId);
|
|
1138
|
+
if (conflictSet.has(logicalId)) continue;
|
|
1102
1139
|
const templateResource = input.template.Resources?.[logicalId];
|
|
1103
1140
|
if (!templateResource) {
|
|
1104
1141
|
unknownLogicalIds.push(logicalId);
|
|
@@ -1114,18 +1151,30 @@ function validateRecreateTargets(input) {
|
|
|
1114
1151
|
logicalId,
|
|
1115
1152
|
resourceType,
|
|
1116
1153
|
physicalId: recordedResource.physicalId,
|
|
1117
|
-
statefulReason: isStatefulRecreateTargetSync(resourceType, recordedResource.properties)
|
|
1154
|
+
statefulReason: isStatefulRecreateTargetSync(resourceType, recordedResource.properties),
|
|
1155
|
+
direction
|
|
1118
1156
|
};
|
|
1119
1157
|
targets.push(target);
|
|
1120
1158
|
if (MULTI_REGION_RECREATE_BLOCKED_TYPES.has(resourceType)) blockedMultiRegionTargets.push(target);
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
const
|
|
1124
|
-
|
|
1159
|
+
if (direction === "to-cc-api") {
|
|
1160
|
+
const actionableDrops = findActionableSilentDrops(resourceType, templateResource.Properties, EMPTY_ALLOW_SET$1);
|
|
1161
|
+
for (const { property } of actionableDrops) {
|
|
1162
|
+
const allowKey = `${resourceType}:${property}`;
|
|
1163
|
+
if (input.allowUnsupportedProperties.has(allowKey)) ambiguousIntent.push({
|
|
1164
|
+
logicalId,
|
|
1165
|
+
resourceType,
|
|
1166
|
+
property
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
} else {
|
|
1170
|
+
const actionableDrops = findActionableSilentDrops(resourceType, templateResource.Properties, input.allowUnsupportedProperties);
|
|
1171
|
+
for (const { property } of actionableDrops) ambiguousIntentSdk.push({
|
|
1125
1172
|
logicalId,
|
|
1126
1173
|
resourceType,
|
|
1127
1174
|
property
|
|
1128
1175
|
});
|
|
1176
|
+
if (!(recordedResource.provisionedBy === "cc-api")) blockedAlreadySdk.push(target);
|
|
1177
|
+
if (input.hasSdkProvider && !input.hasSdkProvider(resourceType)) blockedNoSdkProvider.push(target);
|
|
1129
1178
|
}
|
|
1130
1179
|
if (target.statefulReason !== null && !input.forceStatefulRecreation) blockedStatefulTargets.push(target);
|
|
1131
1180
|
}
|
|
@@ -1134,8 +1183,12 @@ function validateRecreateTargets(input) {
|
|
|
1134
1183
|
unknownLogicalIds,
|
|
1135
1184
|
missingFromState,
|
|
1136
1185
|
ambiguousIntent,
|
|
1186
|
+
ambiguousIntentSdk,
|
|
1137
1187
|
blockedStatefulTargets,
|
|
1138
|
-
blockedMultiRegionTargets
|
|
1188
|
+
blockedMultiRegionTargets,
|
|
1189
|
+
blockedAlreadySdk,
|
|
1190
|
+
blockedNoSdkProvider,
|
|
1191
|
+
conflictingDirections
|
|
1139
1192
|
};
|
|
1140
1193
|
}
|
|
1141
1194
|
/**
|
|
@@ -1147,16 +1200,17 @@ function validateRecreateTargets(input) {
|
|
|
1147
1200
|
*/
|
|
1148
1201
|
function renderRecreateTargetsErrors(validation) {
|
|
1149
1202
|
const lines = [];
|
|
1203
|
+
const FLAG_UMBRELLA = "--recreate-via-cc-api / --recreate-via-sdk-provider";
|
|
1150
1204
|
if (validation.unknownLogicalIds.length > 0) {
|
|
1151
|
-
lines.push(
|
|
1205
|
+
lines.push(`${FLAG_UMBRELLA} named ${validation.unknownLogicalIds.length} logical id(s) not present in the synth template:`);
|
|
1152
1206
|
for (const id of validation.unknownLogicalIds) lines.push(` - ${id}`);
|
|
1153
1207
|
lines.push(" Fix: confirm each id exists in the template (CDK display path is the parent; the logical id is the CFn-emitted name, e.g. cdkd synth | jq '.Resources | keys'). Recreate operates on the synth template's logical ids, not CDK display paths.");
|
|
1154
1208
|
}
|
|
1155
1209
|
if (validation.missingFromState.length > 0) {
|
|
1156
1210
|
if (lines.length > 0) lines.push("");
|
|
1157
|
-
lines.push(
|
|
1211
|
+
lines.push(`${FLAG_UMBRELLA} named ${validation.missingFromState.length} logical id(s) the template declares but cdkd state has no record of:`);
|
|
1158
1212
|
for (const id of validation.missingFromState) lines.push(` - ${id}`);
|
|
1159
|
-
lines.push(" These are fresh CREATEs on the next deploy — recreate has nothing to destroy first. Remove the
|
|
1213
|
+
lines.push(" These are fresh CREATEs on the next deploy — recreate has nothing to destroy first. Remove the flag for these resources; the auto-route via Cloud Control (#614) handles fresh deploys for silent-drop properties, and SDK Provider is the default for everything else.");
|
|
1160
1214
|
}
|
|
1161
1215
|
if (validation.ambiguousIntent.length > 0) {
|
|
1162
1216
|
if (lines.length > 0) lines.push("");
|
|
@@ -1166,15 +1220,39 @@ function renderRecreateTargetsErrors(validation) {
|
|
|
1166
1220
|
}
|
|
1167
1221
|
if (validation.blockedStatefulTargets.length > 0) {
|
|
1168
1222
|
if (lines.length > 0) lines.push("");
|
|
1169
|
-
lines.push(
|
|
1223
|
+
lines.push(`${FLAG_UMBRELLA} would destroy + recreate ${validation.blockedStatefulTargets.length} stateful resource(s). Recreate loses ALL data — no automatic data migration. Re-run with --force-stateful-recreation to acknowledge the data-loss footgun.`);
|
|
1170
1224
|
for (const blocked of validation.blockedStatefulTargets) lines.push(` - ${blocked.logicalId} (${blocked.resourceType}) — ${renderStatefulReason(blocked.statefulReason)}`);
|
|
1171
1225
|
}
|
|
1172
1226
|
if (validation.blockedMultiRegionTargets.length > 0) {
|
|
1173
1227
|
if (lines.length > 0) lines.push("");
|
|
1174
|
-
lines.push(`--recreate-via-cc-api refuses to operate on ${validation.blockedMultiRegionTargets.length} multi-region resource(s) — out of scope for v1 of
|
|
1228
|
+
lines.push(`--recreate-via-cc-api / --recreate-via-sdk-provider refuses to operate on ${validation.blockedMultiRegionTargets.length} multi-region resource(s) — out of scope for v1 of these flags (the destroy + recreate cycle across replica regions is more involved than the single-region path):`);
|
|
1175
1229
|
for (const blocked of validation.blockedMultiRegionTargets) lines.push(` - ${blocked.logicalId} (${blocked.resourceType})`);
|
|
1176
1230
|
lines.push(" No --force-stateful-recreation bypass — this category is structurally unsupported in v1. File an issue if you need this path.");
|
|
1177
1231
|
}
|
|
1232
|
+
if (validation.conflictingDirections.length > 0) {
|
|
1233
|
+
if (lines.length > 0) lines.push("");
|
|
1234
|
+
lines.push(`Conflicting recreate direction — ${validation.conflictingDirections.length} logical id(s) named in BOTH --recreate-via-cc-api AND --recreate-via-sdk-provider:`);
|
|
1235
|
+
for (const id of validation.conflictingDirections) lines.push(` - ${id}`);
|
|
1236
|
+
lines.push(" Fix: pick ONE direction per resource. The two flags drive opposite provisionedBy targets ('cc-api' vs 'sdk').");
|
|
1237
|
+
}
|
|
1238
|
+
if (validation.blockedAlreadySdk.length > 0) {
|
|
1239
|
+
if (lines.length > 0) lines.push("");
|
|
1240
|
+
lines.push(`--recreate-via-sdk-provider named ${validation.blockedAlreadySdk.length} resource(s) that are NOT currently sticky on Cloud Control API (the reverse migration is a no-op):`);
|
|
1241
|
+
for (const blocked of validation.blockedAlreadySdk) lines.push(` - ${blocked.logicalId} (${blocked.resourceType})`);
|
|
1242
|
+
lines.push(" Fix: remove --recreate-via-sdk-provider <id> for these resources. They are already SDK-managed (or pre-v7 legacy state, treated as SDK).");
|
|
1243
|
+
}
|
|
1244
|
+
if (validation.blockedNoSdkProvider.length > 0) {
|
|
1245
|
+
if (lines.length > 0) lines.push("");
|
|
1246
|
+
lines.push(`--recreate-via-sdk-provider named ${validation.blockedNoSdkProvider.length} resource(s) of types cdkd has no SDK provider for (Tier 2 CC-only):`);
|
|
1247
|
+
for (const blocked of validation.blockedNoSdkProvider) lines.push(` - ${blocked.logicalId} (${blocked.resourceType})`);
|
|
1248
|
+
lines.push(" Fix: remove --recreate-via-sdk-provider <id> for these resources. The destroy + recreate would route via Cloud Control anyway — there's no SDK alternative available.");
|
|
1249
|
+
}
|
|
1250
|
+
if (validation.ambiguousIntentSdk.length > 0) {
|
|
1251
|
+
if (lines.length > 0) lines.push("");
|
|
1252
|
+
lines.push(`Inverse ambiguous intent — ${validation.ambiguousIntentSdk.length} --recreate-via-sdk-provider target(s) would IMMEDIATELY be re-routed back to Cloud Control after the recreate because their template uses silent-drop properties NOT in --allow-unsupported-properties:`);
|
|
1253
|
+
for (const overlap of validation.ambiguousIntentSdk) lines.push(` - ${overlap.logicalId} (${overlap.resourceType}) — template uses ${overlap.property}; the default-on CC auto-route would re-route the recreated resource back to CC immediately`);
|
|
1254
|
+
lines.push(" Fix: pass --allow-unsupported-properties <Type>:<Prop> for each silent-drop property so the recreated resource stays on SDK with the property explicitly dropped. Or drop --recreate-via-sdk-provider — the resource already routes via CC and honors the property.");
|
|
1255
|
+
}
|
|
1178
1256
|
return lines.length > 0 ? lines.join("\n") : null;
|
|
1179
1257
|
}
|
|
1180
1258
|
/**
|
|
@@ -1225,7 +1303,7 @@ async function probeStatefulRecreateTargetsAsync(targets, s3Client, logger = get
|
|
|
1225
1303
|
});
|
|
1226
1304
|
else promoted.push({ ...target });
|
|
1227
1305
|
} catch (e) {
|
|
1228
|
-
logger.warn(`--recreate-via-cc-api: live S3 probe failed for ${target.logicalId} (bucket ${target.physicalId}); leaving stateful guard at the sync result. If the bucket might be non-empty, re-run with --force-stateful-recreation. Underlying error: ${e instanceof Error ? e.message : String(e)}`);
|
|
1306
|
+
logger.warn(`--recreate-via-cc-api / --recreate-via-sdk-provider: live S3 probe failed for ${target.logicalId} (bucket ${target.physicalId}); leaving stateful guard at the sync result. If the bucket might be non-empty, re-run with --force-stateful-recreation. Underlying error: ${e instanceof Error ? e.message : String(e)}`);
|
|
1229
1307
|
promoted.push({ ...target });
|
|
1230
1308
|
}
|
|
1231
1309
|
}
|
|
@@ -1347,13 +1425,18 @@ function renderDownstreamConsumers(producerStack, consumers) {
|
|
|
1347
1425
|
async function promptRecreateConfirm(input) {
|
|
1348
1426
|
if (input.targets.length === 0) return true;
|
|
1349
1427
|
const logger = getLogger();
|
|
1428
|
+
const toCcCount = input.targets.filter((t) => t.direction === "to-cc-api").length;
|
|
1429
|
+
const toSdkCount = input.targets.filter((t) => t.direction === "to-sdk").length;
|
|
1350
1430
|
logger.warn("");
|
|
1351
|
-
logger.warn(
|
|
1431
|
+
if (toCcCount > 0 && toSdkCount > 0) logger.warn(`recreate-via-cc-api / recreate-via-sdk-provider will destroy + recreate ${input.targets.length} resource(s) on stack ${input.stackName} (${toCcCount} → Cloud Control, ${toSdkCount} → SDK Provider):`);
|
|
1432
|
+
else if (toCcCount > 0) logger.warn(`--recreate-via-cc-api will destroy + recreate ${toCcCount} resource(s) via Cloud Control API on stack ${input.stackName}:`);
|
|
1433
|
+
else logger.warn(`--recreate-via-sdk-provider will destroy + recreate ${toSdkCount} resource(s) via SDK Provider on stack ${input.stackName}:`);
|
|
1352
1434
|
for (const t of input.targets) {
|
|
1353
1435
|
const stateful = t.statefulReason !== null;
|
|
1354
1436
|
const dataLossPrefix = stateful ? "**DATA LOSS** " : "";
|
|
1437
|
+
const directionTag = t.direction === "to-cc-api" ? " [SDK → CC]" : " [CC → SDK]";
|
|
1355
1438
|
const stateNote = stateful ? ` — stateful (${t.statefulReason}); --force-stateful-recreation acknowledged` : "";
|
|
1356
|
-
logger.warn(` - ${dataLossPrefix}${t.logicalId} (${t.resourceType})${stateNote}`);
|
|
1439
|
+
logger.warn(` - ${dataLossPrefix}${t.logicalId} (${t.resourceType})${directionTag}${stateNote}`);
|
|
1357
1440
|
if (stateful) logger.warn(` DATA: all data in ${t.logicalId} will be lost (no automatic data migration)`);
|
|
1358
1441
|
}
|
|
1359
1442
|
if (input.downstreamConsumers && input.downstreamConsumers.length > 0) {
|
|
@@ -33834,7 +33917,8 @@ async function deployCommand(stacks, options) {
|
|
|
33834
33917
|
}
|
|
33835
33918
|
}
|
|
33836
33919
|
let recreateViaCcApiTargets;
|
|
33837
|
-
|
|
33920
|
+
let recreateViaSdkProviderTargets;
|
|
33921
|
+
if (options.recreateViaCcApi?.length || options.recreateViaSdkProvider?.length) {
|
|
33838
33922
|
const stateForRecreateCheck = await stackStateBackend.getState(stackInfo.stackName, stackRegion);
|
|
33839
33923
|
const validation = await probeAndRevalidateStateful({
|
|
33840
33924
|
validation: validateRecreateTargets({
|
|
@@ -33847,17 +33931,20 @@ async function deployCommand(stacks, options) {
|
|
|
33847
33931
|
outputs: {},
|
|
33848
33932
|
lastModified: Date.now()
|
|
33849
33933
|
},
|
|
33850
|
-
recreateViaCcApi: options.recreateViaCcApi,
|
|
33934
|
+
recreateViaCcApi: options.recreateViaCcApi ?? [],
|
|
33935
|
+
recreateViaSdkProvider: options.recreateViaSdkProvider ?? [],
|
|
33851
33936
|
allowUnsupportedProperties: new Set(options.allowUnsupportedProperties ?? []),
|
|
33852
|
-
forceStatefulRecreation: options.forceStatefulRecreation ?? false
|
|
33937
|
+
forceStatefulRecreation: options.forceStatefulRecreation ?? false,
|
|
33938
|
+
hasSdkProvider: (rt) => stackProviderRegistry.getProviderType(rt) === "sdk"
|
|
33853
33939
|
}),
|
|
33854
33940
|
s3Client: stackAwsClients.s3,
|
|
33855
33941
|
forceStatefulRecreation: options.forceStatefulRecreation ?? false
|
|
33856
33942
|
});
|
|
33857
33943
|
const errorBlock = renderRecreateTargetsErrors(validation);
|
|
33858
|
-
if (errorBlock) throw new CdkdError(errorBlock, "
|
|
33859
|
-
recreateViaCcApiTargets = new Set(validation.targets.map((t) => t.logicalId));
|
|
33860
|
-
|
|
33944
|
+
if (errorBlock) throw new CdkdError(errorBlock, "RECREATE_TARGETS_INVALID");
|
|
33945
|
+
recreateViaCcApiTargets = new Set(validation.targets.filter((t) => t.direction === "to-cc-api").map((t) => t.logicalId));
|
|
33946
|
+
recreateViaSdkProviderTargets = new Set(validation.targets.filter((t) => t.direction === "to-sdk").map((t) => t.logicalId));
|
|
33947
|
+
if (recreateViaCcApiTargets.size > 0 || recreateViaSdkProviderTargets.size > 0) {
|
|
33861
33948
|
const downstreamConsumers = await findDownstreamConsumers({
|
|
33862
33949
|
producerStack: stackInfo.stackName,
|
|
33863
33950
|
producerRegion: stackRegion,
|
|
@@ -33877,6 +33964,7 @@ async function deployCommand(stacks, options) {
|
|
|
33877
33964
|
dryRun: options.dryRun,
|
|
33878
33965
|
noRollback: !options.rollback,
|
|
33879
33966
|
...recreateViaCcApiTargets && recreateViaCcApiTargets.size > 0 && { recreateViaCcApiTargets },
|
|
33967
|
+
...recreateViaSdkProviderTargets && recreateViaSdkProviderTargets.size > 0 && { recreateViaSdkProviderTargets },
|
|
33880
33968
|
captureObservedState: resolveCaptureObservedState(options.captureObservedState),
|
|
33881
33969
|
...options.resourceWarnAfter?.globalMs !== void 0 && { resourceWarnAfterMs: options.resourceWarnAfter.globalMs },
|
|
33882
33970
|
...options.resourceTimeout?.globalMs !== void 0 && { resourceTimeoutMs: options.resourceTimeout.globalMs },
|
|
@@ -60619,7 +60707,7 @@ function reorderArgs(argv) {
|
|
|
60619
60707
|
*/
|
|
60620
60708
|
async function main() {
|
|
60621
60709
|
const program = new Command();
|
|
60622
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
60710
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.166.0");
|
|
60623
60711
|
program.addCommand(createBootstrapCommand());
|
|
60624
60712
|
program.addCommand(createSynthCommand());
|
|
60625
60713
|
program.addCommand(createListCommand());
|