@go-to-k/cdkd 0.93.0 → 0.94.1
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/README.md +75 -37
- package/dist/cli.js +152 -33
- package/dist/cli.js.map +2 -2
- package/dist/go-to-k-cdkd-0.94.1.tgz +0 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.93.0.tgz +0 -0
package/README.md
CHANGED
|
@@ -455,44 +455,82 @@ Both `cdkd destroy` (synth-driven) and `cdkd state destroy`
|
|
|
455
455
|
|
|
456
456
|
## Stack-name prefix on physical names
|
|
457
457
|
|
|
458
|
-
cdkd
|
|
459
|
-
code: `new iam.Role(this, 'CRRole', { roleName:
|
|
460
|
-
`
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
the
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
458
|
+
By default cdkd creates AWS resources with the **exact name you
|
|
459
|
+
declared** in CDK code: `new iam.Role(this, 'CRRole', { roleName:
|
|
460
|
+
'my-role' })` in stack `MyStack` produces an AWS resource named
|
|
461
|
+
`my-role`. Consistent across every resource type. This is the
|
|
462
|
+
default since **v0.94.0** (closes [#299](https://github.com/go-to-k/cdkd/issues/299)).
|
|
463
|
+
|
|
464
|
+
Pre-v0.94.0 cdkd prepended the stack name to user-declared physical
|
|
465
|
+
names on a subset of types only (Pattern B providers: IAM Role /
|
|
466
|
+
User / Group / InstanceProfile / ELBv2 LoadBalancer / TargetGroup),
|
|
467
|
+
while Pattern A providers (Lambda, S3, SNS, SQS, DynamoDB, etc.) used
|
|
468
|
+
the user's name as-is. The inconsistency was opaque to users and
|
|
469
|
+
surfaced as failures in `cdkd export` (CFn IMPORT identifier
|
|
470
|
+
mismatch). Flipping the default brings every resource type into line
|
|
471
|
+
out of the box.
|
|
472
|
+
|
|
473
|
+
`cdkd deploy --prefix-user-supplied-names` opts BACK in to the
|
|
474
|
+
legacy prefixing on Pattern B providers (matching pre-v0.94.0 cdkd).
|
|
475
|
+
Useful when migrating an existing stack that was originally deployed
|
|
476
|
+
under the legacy default and you don't want to take a one-time
|
|
477
|
+
replacement on every Pattern B resource.
|
|
478
|
+
|
|
479
|
+
| | Default (no flag) | `--prefix-user-supplied-names` |
|
|
472
480
|
| --- | --- | --- |
|
|
473
|
-
| `new iam.Role({ roleName: 'my-role' })` | `
|
|
474
|
-
| `new s3.Bucket({ bucketName: 'my-bucket' })` | `my-bucket` (
|
|
475
|
-
| `new iam.Role(...)` (no `roleName`) | `MyStack-CRRole-<hash>` (auto-generated
|
|
476
|
-
|
|
477
|
-
Resolution chain (highest wins): `--
|
|
478
|
-
CLI flag → `
|
|
479
|
-
`cdk.json` `context.cdkd.
|
|
480
|
-
`false
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
481
|
+
| `new iam.Role({ roleName: 'my-role' })` | `my-role` | `MyStack-my-role` (legacy) |
|
|
482
|
+
| `new s3.Bucket({ bucketName: 'my-bucket' })` | `my-bucket` (always — Pattern A) | `my-bucket` (unchanged) |
|
|
483
|
+
| `new iam.Role(...)` (no `roleName`) | `MyStack-CRRole-<hash>` (auto-generated; prefix kept for uniqueness) | `MyStack-CRRole-<hash>` (unchanged) |
|
|
484
|
+
|
|
485
|
+
Resolution chain (highest wins): `--prefix-user-supplied-names`
|
|
486
|
+
CLI flag → `CDKD_PREFIX_USER_SUPPLIED_NAMES=true` env var →
|
|
487
|
+
`cdk.json` `context.cdkd.prefixUserSuppliedNames: true` → default
|
|
488
|
+
`false` (skip prefix).
|
|
489
|
+
|
|
490
|
+
The deprecated `--no-prefix-user-supplied-names` flag (plus the
|
|
491
|
+
`CDKD_NO_PREFIX_USER_SUPPLIED_NAMES` env var and `cdk.json
|
|
492
|
+
context.cdkd.noPrefixUserSuppliedNames`) is still accepted but now
|
|
493
|
+
matches the default; setting it emits a deprecation warning and is a
|
|
494
|
+
no-op. Remove it from your CLI invocations and config.
|
|
495
|
+
|
|
496
|
+
### Migration from pre-v0.94.0
|
|
497
|
+
|
|
498
|
+
This is a **breaking change**: upgrading from a pre-v0.94.0 cdkd to
|
|
499
|
+
v0.94.0+ flips the AWS-resource name cdkd produces on Pattern B
|
|
500
|
+
providers (IAM Role / User / Group / InstanceProfile / ELBv2 LB / TG)
|
|
501
|
+
with user-supplied physical names. The next `cdkd deploy` against an
|
|
502
|
+
existing stack will propose REPLACEMENT on every such resource —
|
|
503
|
+
the AWS resource has the prefixed name; the new template intent has
|
|
504
|
+
the un-prefixed name.
|
|
505
|
+
|
|
506
|
+
Pick one of:
|
|
507
|
+
|
|
508
|
+
1. **Accept the one-time replacement** (simplest; only safe when the
|
|
509
|
+
types involved tolerate replacement — IAM Roles get fresh ARNs,
|
|
510
|
+
ELBv2 LBs get fresh DNS names).
|
|
511
|
+
2. **Pin legacy prefixing**: pass `--prefix-user-supplied-names`,
|
|
512
|
+
set `CDKD_PREFIX_USER_SUPPLIED_NAMES=true`, or add
|
|
513
|
+
`"prefixUserSuppliedNames": true` under `cdk.json` `context.cdkd`.
|
|
514
|
+
3. **Drop the explicit physical name** in CDK code where you don't
|
|
515
|
+
actually need a stable name — `new iam.Role(...)` without
|
|
516
|
+
`roleName` always uses the auto-generated `MyStack-CRRole-<hash>`
|
|
517
|
+
form regardless of this flag.
|
|
518
|
+
|
|
519
|
+
A migration helper (`cdkd state rename-strip-prefix <stack>`) that
|
|
520
|
+
would let an existing stack adopt the new default without replacement
|
|
521
|
+
is tracked separately in [#300](https://github.com/go-to-k/cdkd/issues/300).
|
|
522
|
+
|
|
523
|
+
### Effect on `cdkd export`
|
|
524
|
+
|
|
525
|
+
[PR #285 `cdkd export`](https://github.com/go-to-k/cdkd/pull/285)
|
|
526
|
+
surfaced the pre-v0.94.0 inconsistency: the CFn IMPORT changeset's
|
|
527
|
+
identifier check would fail on a synth `RoleName: 'my-role'` vs the
|
|
528
|
+
AWS-deployed `MyStack-my-role`, so the export command overlays
|
|
529
|
+
`ResourceIdentifier` onto `Properties` to bridge the gap. The
|
|
530
|
+
overlay is still needed for stacks deployed under the legacy default
|
|
531
|
+
(or with `--prefix-user-supplied-names`); a fresh stack deployed
|
|
532
|
+
under the v0.94.0 default has matching names and the overlay is a
|
|
533
|
+
no-op for it.
|
|
496
534
|
|
|
497
535
|
## `--remove-protection`: one-shot bypass for protected resources
|
|
498
536
|
|
package/dist/cli.js
CHANGED
|
@@ -23396,9 +23396,20 @@ var deployOptions = [
|
|
|
23396
23396
|
"Skip capturing AWS-current properties after each create/update (adds a fire-and-forget readCurrentState per resource so cdkd drift can compare against the real deploy-time AWS snapshot instead of the template). On by default. Disable when deploy speed matters more than rich drift detection \u2014 falls back to comparing against template properties (the pre-v3 behavior)."
|
|
23397
23397
|
),
|
|
23398
23398
|
new Option(
|
|
23399
|
-
"--
|
|
23400
|
-
'
|
|
23401
|
-
),
|
|
23399
|
+
"--prefix-user-supplied-names",
|
|
23400
|
+
'Opt in to LEGACY behavior: prepend the stack name to physical names the user explicitly supplied in their CDK code (e.g. `new iam.Role(this, "X", { roleName: "my-role" })` \u2192 AWS resource named `MyStack-my-role` instead of `my-role`). Since v0.94.0 the default is to NOT prefix user-supplied names \u2014 this flag restores the pre-v0.94.0 behavior on Pattern B providers (IAM Role / User / Group / InstanceProfile / ELBv2 LoadBalancer / TargetGroup). Enable via this flag, CDKD_PREFIX_USER_SUPPLIED_NAMES=true, or cdk.json context.cdkd.prefixUserSuppliedNames=true. Applies to `cdkd deploy` only.'
|
|
23401
|
+
).default(false),
|
|
23402
|
+
// Note: the deprecated `--no-prefix-user-supplied-names` flag is NOT
|
|
23403
|
+
// declared as a separate Option. Commander's automatic `--no-X`
|
|
23404
|
+
// negation lets users still pass it without error — it negates the
|
|
23405
|
+
// new `--prefix-user-supplied-names` flag, leaving its default
|
|
23406
|
+
// `false` (= skip prefix) unchanged, which matches the v0.94.0
|
|
23407
|
+
// default. Detection of the literal `--no-prefix-user-supplied-names`
|
|
23408
|
+
// flag for the deprecation warning happens via the pre-parse argv
|
|
23409
|
+
// walk in `warnDeprecatedNoPrefixCliFlag` (src/cli/config-loader.ts) —
|
|
23410
|
+
// declaring both Options together would have collapsed both onto a
|
|
23411
|
+
// single Commander key, making `noPrefixUserSuppliedNames` permanently
|
|
23412
|
+
// `undefined` and silencing the warning.
|
|
23402
23413
|
noWaitOption,
|
|
23403
23414
|
aggressiveVpcParallelOption,
|
|
23404
23415
|
new Option(
|
|
@@ -23543,18 +23554,44 @@ function resolveCaptureObservedState(cliValue) {
|
|
|
23543
23554
|
return v;
|
|
23544
23555
|
return true;
|
|
23545
23556
|
}
|
|
23546
|
-
function
|
|
23547
|
-
|
|
23548
|
-
|
|
23549
|
-
|
|
23550
|
-
if (
|
|
23551
|
-
|
|
23557
|
+
function warnDeprecatedNoPrefixCliFlag(argv = process.argv) {
|
|
23558
|
+
const seen = argv.some(
|
|
23559
|
+
(a) => a === "--no-prefix-user-supplied-names" || a.startsWith("--no-prefix-user-supplied-names=")
|
|
23560
|
+
);
|
|
23561
|
+
if (seen) {
|
|
23562
|
+
getLogger().warn(
|
|
23563
|
+
"--no-prefix-user-supplied-names is deprecated since v0.94.0 \u2014 skipping the prefix is now the default. Remove the flag."
|
|
23564
|
+
);
|
|
23565
|
+
}
|
|
23566
|
+
}
|
|
23567
|
+
function resolveSkipPrefix(opts = {}) {
|
|
23568
|
+
const logger = getLogger();
|
|
23569
|
+
if (opts.prefixUserSuppliedNames === true) {
|
|
23570
|
+
return false;
|
|
23571
|
+
}
|
|
23572
|
+
const envPrefix = process.env["CDKD_PREFIX_USER_SUPPLIED_NAMES"];
|
|
23573
|
+
if (envPrefix === "true") {
|
|
23574
|
+
return false;
|
|
23575
|
+
}
|
|
23552
23576
|
const cdkJson = loadCdkJson();
|
|
23553
23577
|
const cdkdContext = cdkJson?.context?.["cdkd"];
|
|
23554
|
-
const v = cdkdContext?.["
|
|
23555
|
-
if (typeof v === "boolean" && v === true)
|
|
23556
|
-
return
|
|
23557
|
-
|
|
23578
|
+
const v = cdkdContext?.["prefixUserSuppliedNames"];
|
|
23579
|
+
if (typeof v === "boolean" && v === true) {
|
|
23580
|
+
return false;
|
|
23581
|
+
}
|
|
23582
|
+
const deprecatedEnv = process.env["CDKD_NO_PREFIX_USER_SUPPLIED_NAMES"];
|
|
23583
|
+
if (deprecatedEnv === "true") {
|
|
23584
|
+
logger.warn(
|
|
23585
|
+
"CDKD_NO_PREFIX_USER_SUPPLIED_NAMES is deprecated since v0.94.0 \u2014 skipping the prefix is now the default. Unset the env var."
|
|
23586
|
+
);
|
|
23587
|
+
}
|
|
23588
|
+
const deprecatedCdkJson = cdkdContext?.["noPrefixUserSuppliedNames"];
|
|
23589
|
+
if (typeof deprecatedCdkJson === "boolean" && deprecatedCdkJson === true) {
|
|
23590
|
+
logger.warn(
|
|
23591
|
+
"cdk.json context.cdkd.noPrefixUserSuppliedNames is deprecated since v0.94.0 \u2014 skipping the prefix is now the default. Remove the entry."
|
|
23592
|
+
);
|
|
23593
|
+
}
|
|
23594
|
+
return true;
|
|
23558
23595
|
}
|
|
23559
23596
|
function resolveStateBucketWithSource(cliBucket) {
|
|
23560
23597
|
if (cliBucket)
|
|
@@ -65557,10 +65594,17 @@ async function deployCommand(stacks, options) {
|
|
|
65557
65594
|
if (!options.wait) {
|
|
65558
65595
|
process.env["CDKD_NO_WAIT"] = "true";
|
|
65559
65596
|
}
|
|
65560
|
-
|
|
65597
|
+
warnDeprecatedNoPrefixCliFlag();
|
|
65598
|
+
const skipPrefix = resolveSkipPrefix({
|
|
65599
|
+
prefixUserSuppliedNames: options.prefixUserSuppliedNames
|
|
65600
|
+
});
|
|
65561
65601
|
if (skipPrefix) {
|
|
65562
65602
|
logger.debug(
|
|
65563
|
-
"Skipping stack-name prefix on user-supplied physical names (
|
|
65603
|
+
"Skipping stack-name prefix on user-supplied physical names (default since v0.94.0)"
|
|
65604
|
+
);
|
|
65605
|
+
} else {
|
|
65606
|
+
logger.debug(
|
|
65607
|
+
"Keeping legacy stack-name prefix on user-supplied physical names (--prefix-user-supplied-names / CDKD_PREFIX_USER_SUPPLIED_NAMES / cdk.json context.cdkd.prefixUserSuppliedNames)"
|
|
65564
65608
|
);
|
|
65565
65609
|
}
|
|
65566
65610
|
const app = resolveApp(options.app);
|
|
@@ -79985,7 +80029,8 @@ var PRIMARY_IDENTIFIER_FALLBACK = {
|
|
|
79985
80029
|
};
|
|
79986
80030
|
var COMPOSITE_ID_SPLITTERS = {
|
|
79987
80031
|
// cdkd stores `restApiId|resourceId|httpMethod` (apigateway-provider.ts);
|
|
79988
|
-
// CFn primary identifier is [RestApiId, ResourceId, HttpMethod] — same
|
|
80032
|
+
// CFn primary identifier is [RestApiId, ResourceId, HttpMethod] — same
|
|
80033
|
+
// order, and all three are writable Properties of AWS::ApiGateway::Method.
|
|
79989
80034
|
"AWS::ApiGateway::Method": (id) => {
|
|
79990
80035
|
const parts = id.split("|");
|
|
79991
80036
|
if (parts.length !== 3) {
|
|
@@ -79993,28 +80038,98 @@ var COMPOSITE_ID_SPLITTERS = {
|
|
|
79993
80038
|
`expected 3 parts (restApiId|resourceId|httpMethod), got ${parts.length}: '${id}'`
|
|
79994
80039
|
);
|
|
79995
80040
|
}
|
|
79996
|
-
|
|
80041
|
+
const map = { RestApiId: parts[0], ResourceId: parts[1], HttpMethod: parts[2] };
|
|
80042
|
+
return { resourceIdentifier: map };
|
|
79997
80043
|
},
|
|
79998
80044
|
// cdkd stores `restApiId|resourceId` (apigateway-provider.ts);
|
|
79999
|
-
// CFn primary identifier is [RestApiId, ResourceId]
|
|
80045
|
+
// CFn primary identifier is [RestApiId, ResourceId] — both are writable
|
|
80046
|
+
// Properties of AWS::ApiGateway::Resource.
|
|
80000
80047
|
"AWS::ApiGateway::Resource": (id) => {
|
|
80001
80048
|
const parts = id.split("|");
|
|
80002
80049
|
if (parts.length !== 2) {
|
|
80003
80050
|
throw new Error(`expected 2 parts (restApiId|resourceId), got ${parts.length}: '${id}'`);
|
|
80004
80051
|
}
|
|
80005
|
-
|
|
80052
|
+
const map = { RestApiId: parts[0], ResourceId: parts[1] };
|
|
80053
|
+
return { resourceIdentifier: map };
|
|
80006
80054
|
},
|
|
80007
80055
|
// cdkd stores `IGW|VpcId` (ec2-provider.ts);
|
|
80008
80056
|
// CFn primary identifier is [VpcId, InternetGatewayId] — DIFFERENT order
|
|
80009
|
-
// from cdkd. Splitter reorders explicitly.
|
|
80057
|
+
// from cdkd. Splitter reorders explicitly. Both are writable Properties.
|
|
80010
80058
|
"AWS::EC2::VPCGatewayAttachment": (id) => {
|
|
80011
80059
|
const parts = id.split("|");
|
|
80012
80060
|
if (parts.length !== 2) {
|
|
80013
80061
|
throw new Error(`expected 2 parts (IGW|VpcId), got ${parts.length}: '${id}'`);
|
|
80014
80062
|
}
|
|
80015
|
-
|
|
80063
|
+
const map = { VpcId: parts[1], InternetGatewayId: parts[0] };
|
|
80064
|
+
return { resourceIdentifier: map };
|
|
80065
|
+
},
|
|
80066
|
+
// cdkd stores just `IntegrationId` (apigatewayv2-provider.ts); the parent
|
|
80067
|
+
// `ApiId` lives in cdkd state's properties (`properties.ApiId`). CFn primary
|
|
80068
|
+
// identifier is [ApiId, IntegrationId]. ApiId IS a writable Property
|
|
80069
|
+
// (already in synth template via Ref); IntegrationId is tagged
|
|
80070
|
+
// `readOnlyProperties: ['/properties/IntegrationId']` in the CFn schema —
|
|
80071
|
+
// exclude it from propertiesOverlay so CFn doesn't reject writing a
|
|
80072
|
+
// read-only property at changeset-create.
|
|
80073
|
+
"AWS::ApiGatewayV2::Integration": (physicalId, properties) => {
|
|
80074
|
+
const apiId = readStringProperty(properties, "ApiId", "AWS::ApiGatewayV2::Integration");
|
|
80075
|
+
return {
|
|
80076
|
+
resourceIdentifier: { ApiId: apiId, IntegrationId: physicalId },
|
|
80077
|
+
propertiesOverlay: { ApiId: apiId }
|
|
80078
|
+
};
|
|
80079
|
+
},
|
|
80080
|
+
// cdkd stores just `RouteId` (apigatewayv2-provider.ts); parent `ApiId`
|
|
80081
|
+
// comes from properties. CFn primary identifier is [ApiId, RouteId]. Same
|
|
80082
|
+
// overlay narrowing as Integration above.
|
|
80083
|
+
"AWS::ApiGatewayV2::Route": (physicalId, properties) => {
|
|
80084
|
+
const apiId = readStringProperty(properties, "ApiId", "AWS::ApiGatewayV2::Route");
|
|
80085
|
+
return {
|
|
80086
|
+
resourceIdentifier: { ApiId: apiId, RouteId: physicalId },
|
|
80087
|
+
propertiesOverlay: { ApiId: apiId }
|
|
80088
|
+
};
|
|
80089
|
+
},
|
|
80090
|
+
// NOTE: `AWS::ApiGatewayV2::Stage` is intentionally NOT in this map.
|
|
80091
|
+
// (1) AWS reports its primaryIdentifier as `['/properties/Id']` (single-key),
|
|
80092
|
+
// so cdkd's single-key resolution path handles it without a splitter.
|
|
80093
|
+
// (2) But AWS CloudFormation does NOT support `AWS::ApiGatewayV2::Stage` in
|
|
80094
|
+
// IMPORT changesets (CreateChangeSet rejects with "ResourceTypes
|
|
80095
|
+
// [AWS::ApiGatewayV2::Stage] are not supported for Import"). This means
|
|
80096
|
+
// `cdkd export` cannot complete on any stack that includes an HttpApi
|
|
80097
|
+
// (CDK auto-creates a `$default` Stage). Tracked in a follow-up issue
|
|
80098
|
+
// (link in PR description); the workaround design is open
|
|
80099
|
+
// (pre-delete + phase-2-CREATE vs hard-block-with-clear-error).
|
|
80100
|
+
// cdkd stores `StatementId` (lambda-permission-provider.ts:124); for state
|
|
80101
|
+
// entries written by the older CC-API path (pre-SDK-provider), physicalId
|
|
80102
|
+
// may instead be the legacy `<functionArn>|<statementId>` shape — the
|
|
80103
|
+
// provider's own delete / update / getAttribute paths normalize via
|
|
80104
|
+
// `physicalId.split('|').pop()` (see lambda-permission-provider.ts:160 /
|
|
80105
|
+
// 222 / 290). Mirror that here so legacy state still produces the
|
|
80106
|
+
// correct CFn Id field; otherwise CFn IMPORT's identifier-match would
|
|
80107
|
+
// compare `Id: '<arn>|<sid>'` against the AWS-current Sid and reject.
|
|
80108
|
+
//
|
|
80109
|
+
// CFn primary identifier is [FunctionName, Id] (note: CFn schema calls
|
|
80110
|
+
// the field `Id`, not `StatementId`). FunctionName IS a writable
|
|
80111
|
+
// Property; `Id` is tagged `readOnlyProperties: ['/properties/Id']` in
|
|
80112
|
+
// the CFn schema (it's set at create time by AWS, not by the user).
|
|
80113
|
+
// Narrow overlay to FunctionName so CFn doesn't reject writing read-only
|
|
80114
|
+
// `Id` at changeset-create.
|
|
80115
|
+
"AWS::Lambda::Permission": (physicalId, properties) => {
|
|
80116
|
+
const functionName = readStringProperty(properties, "FunctionName", "AWS::Lambda::Permission");
|
|
80117
|
+
const statementId = physicalId.includes("|") ? physicalId.split("|").pop() : physicalId;
|
|
80118
|
+
return {
|
|
80119
|
+
resourceIdentifier: { FunctionName: functionName, Id: statementId },
|
|
80120
|
+
propertiesOverlay: { FunctionName: functionName }
|
|
80121
|
+
};
|
|
80016
80122
|
}
|
|
80017
80123
|
};
|
|
80124
|
+
function readStringProperty(properties, key, resourceType) {
|
|
80125
|
+
const v = properties[key];
|
|
80126
|
+
if (typeof v !== "string" || !v) {
|
|
80127
|
+
throw new Error(
|
|
80128
|
+
`cdkd state's properties for ${resourceType} is missing '${key}' (the parent identifier required to build the CFn ResourceIdentifier map). State entry may be corrupt or written by an older cdkd binary; re-deploy the resource to refresh state.`
|
|
80129
|
+
);
|
|
80130
|
+
}
|
|
80131
|
+
return v;
|
|
80132
|
+
}
|
|
80018
80133
|
async function exportCommand(stackArg, options) {
|
|
80019
80134
|
const logger = getLogger();
|
|
80020
80135
|
if (options.verbose) {
|
|
@@ -80392,11 +80507,12 @@ async function buildImportPlan(state, template, cfnClient) {
|
|
|
80392
80507
|
});
|
|
80393
80508
|
continue;
|
|
80394
80509
|
}
|
|
80395
|
-
let
|
|
80510
|
+
let resolved;
|
|
80396
80511
|
try {
|
|
80397
|
-
|
|
80512
|
+
resolved = await resolveResourceIdentifier(
|
|
80398
80513
|
resourceType,
|
|
80399
80514
|
stateEntry.physicalId,
|
|
80515
|
+
stateEntry.properties ?? {},
|
|
80400
80516
|
cfnClient,
|
|
80401
80517
|
identifierCache
|
|
80402
80518
|
);
|
|
@@ -80412,19 +80528,21 @@ async function buildImportPlan(state, template, cfnClient) {
|
|
|
80412
80528
|
logicalId,
|
|
80413
80529
|
resourceType,
|
|
80414
80530
|
physicalId: stateEntry.physicalId,
|
|
80415
|
-
resourceIdentifier
|
|
80531
|
+
resourceIdentifier: resolved.resourceIdentifier,
|
|
80532
|
+
propertiesOverlay: resolved.propertiesOverlay ?? resolved.resourceIdentifier
|
|
80416
80533
|
});
|
|
80417
80534
|
}
|
|
80418
80535
|
return { phase1Imports, phase2Creates, blocked };
|
|
80419
80536
|
}
|
|
80420
|
-
async function resolveResourceIdentifier(resourceType, physicalId, cfnClient, cache2) {
|
|
80537
|
+
async function resolveResourceIdentifier(resourceType, physicalId, properties, cfnClient, cache2) {
|
|
80421
80538
|
let entry = cache2.get(resourceType);
|
|
80422
80539
|
if (entry === void 0) {
|
|
80423
80540
|
entry = await fetchPrimaryIdentifier(resourceType, cfnClient);
|
|
80424
80541
|
cache2.set(resourceType, entry);
|
|
80425
80542
|
}
|
|
80426
80543
|
if (entry.fields.length === 1) {
|
|
80427
|
-
|
|
80544
|
+
const map = { [entry.fields[0]]: physicalId };
|
|
80545
|
+
return { resourceIdentifier: map };
|
|
80428
80546
|
}
|
|
80429
80547
|
const splitter = COMPOSITE_ID_SPLITTERS[resourceType];
|
|
80430
80548
|
if (!splitter) {
|
|
@@ -80432,22 +80550,22 @@ async function resolveResourceIdentifier(resourceType, physicalId, cfnClient, ca
|
|
|
80432
80550
|
`resource type uses a composite primary identifier (${entry.fields.length} fields: ${entry.fields.join(", ")}); add an entry to COMPOSITE_ID_SPLITTERS in src/cli/commands/export.ts that parses cdkd's physicalId for this type, or destroy the resource first and let CFn create it fresh`
|
|
80433
80551
|
);
|
|
80434
80552
|
}
|
|
80435
|
-
let
|
|
80553
|
+
let result;
|
|
80436
80554
|
try {
|
|
80437
|
-
|
|
80555
|
+
result = splitter(physicalId, properties);
|
|
80438
80556
|
} catch (err) {
|
|
80439
80557
|
throw new Error(
|
|
80440
80558
|
`composite-id splitter for ${resourceType} failed: ` + (err instanceof Error ? err.message : String(err))
|
|
80441
80559
|
);
|
|
80442
80560
|
}
|
|
80443
80561
|
for (const f of entry.fields) {
|
|
80444
|
-
if (!(f in
|
|
80562
|
+
if (!(f in result.resourceIdentifier)) {
|
|
80445
80563
|
throw new Error(
|
|
80446
|
-
`composite-id splitter for ${resourceType} did not produce field '${f}' (produced: ${Object.keys(
|
|
80564
|
+
`composite-id splitter for ${resourceType} did not produce field '${f}' (produced: ${Object.keys(result.resourceIdentifier).join(", ")})`
|
|
80447
80565
|
);
|
|
80448
80566
|
}
|
|
80449
80567
|
}
|
|
80450
|
-
return
|
|
80568
|
+
return result;
|
|
80451
80569
|
}
|
|
80452
80570
|
async function fetchPrimaryIdentifier(resourceType, cfnClient) {
|
|
80453
80571
|
try {
|
|
@@ -80570,7 +80688,8 @@ function overlayResourceIdentifierOnProperties(resource, entry) {
|
|
|
80570
80688
|
const r = resource;
|
|
80571
80689
|
const existingProperties = r["Properties"];
|
|
80572
80690
|
const properties = existingProperties && typeof existingProperties === "object" && !Array.isArray(existingProperties) ? { ...existingProperties } : {};
|
|
80573
|
-
|
|
80691
|
+
const overlay = entry.propertiesOverlay ?? entry.resourceIdentifier;
|
|
80692
|
+
for (const [field, value] of Object.entries(overlay)) {
|
|
80574
80693
|
properties[field] = value;
|
|
80575
80694
|
}
|
|
80576
80695
|
return { ...r, Properties: properties };
|
|
@@ -80938,7 +81057,7 @@ function reorderArgs(argv) {
|
|
|
80938
81057
|
}
|
|
80939
81058
|
async function main() {
|
|
80940
81059
|
const program = new Command18();
|
|
80941
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
81060
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.94.1");
|
|
80942
81061
|
program.addCommand(createBootstrapCommand());
|
|
80943
81062
|
program.addCommand(createSynthCommand());
|
|
80944
81063
|
program.addCommand(createListCommand());
|