@go-to-k/cdkd 0.43.0 → 0.44.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 +157 -21
- package/dist/cli.js.map +3 -3
- package/dist/go-to-k-cdkd-0.44.0.tgz +0 -0
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.43.0.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -38050,6 +38050,128 @@ function isPlainObject(value) {
|
|
|
38050
38050
|
return typeof value === "object" && value !== null;
|
|
38051
38051
|
}
|
|
38052
38052
|
|
|
38053
|
+
// src/analyzer/drift-cc-api-deny-list.ts
|
|
38054
|
+
var CC_API_FALLBACK_DENY_LIST = {
|
|
38055
|
+
// AWS::IAM::ManagedPolicy: PolicyDocument round-trips through CC API
|
|
38056
|
+
// URL-encoded; cdkd state stores it as a parsed JSON object. Without
|
|
38057
|
+
// a per-type decoder, every comparison sees a string-vs-object
|
|
38058
|
+
// mismatch and fires drift on every run. The IAM Role provider's
|
|
38059
|
+
// first-class readCurrentState handles its inline AssumeRolePolicy
|
|
38060
|
+
// the same way (URL-decode + JSON-parse); the same fix pattern is
|
|
38061
|
+
// needed for ManagedPolicy when an SDK provider is added.
|
|
38062
|
+
"AWS::IAM::ManagedPolicy": "PolicyDocument is URL-encoded JSON in CC API responses, but cdkd state stores it as a parsed object \u2014 needs per-type decode",
|
|
38063
|
+
// AWS::ApiGateway::RestApi: the `Body` property (OpenAPI spec object
|
|
38064
|
+
// when supplied via `Body` rather than `BodyS3Location`) is write-only
|
|
38065
|
+
// — `GetRestApi` does NOT return it, but cdkd state preserves the
|
|
38066
|
+
// object the user passed in. CC API GetResource inherits this — the
|
|
38067
|
+
// returned shape omits `Body`, so every drift run flags it as
|
|
38068
|
+
// missing-on-AWS. Comparison silently dropping it would also be
|
|
38069
|
+
// wrong; the right move is a dedicated SDK provider that knows to
|
|
38070
|
+
// skip `Body` entirely.
|
|
38071
|
+
"AWS::ApiGateway::RestApi": "Body / BodyS3Location are write-only inputs not returned by CC API GetResource; cdkd state preserves them",
|
|
38072
|
+
// AWS::CloudFormation::Stack: nested stacks aren't supported by cdkd's
|
|
38073
|
+
// provider registry at all; the deploy / destroy paths reject them.
|
|
38074
|
+
// Listing here is defense-in-depth — if a user manually crafts state
|
|
38075
|
+
// with one, drift via CC API would compare CFn-template-input
|
|
38076
|
+
// properties against CC API's stack-output shape (CC API's
|
|
38077
|
+
// `AWS::CloudFormation::Stack` reports outputs / status, not the
|
|
38078
|
+
// template parameters cdkd would have stored).
|
|
38079
|
+
"AWS::CloudFormation::Stack": "CC API returns runtime stack state (outputs/status), not the template parameters cdkd state stores",
|
|
38080
|
+
// AWS::EC2::LaunchTemplate: `LaunchTemplateData` ships with deeply
|
|
38081
|
+
// structured sub-objects that CC API normalizes into a versioned shape
|
|
38082
|
+
// — every UpdateLaunchTemplate (and even GetLaunchTemplate) bumps the
|
|
38083
|
+
// returned default version, and CC API attaches a synthetic
|
|
38084
|
+
// `LatestVersionNumber` / `DefaultVersionNumber` next to the template
|
|
38085
|
+
// data that drift would surface as drift on the parent. Until an SDK
|
|
38086
|
+
// provider strips those, deny.
|
|
38087
|
+
"AWS::EC2::LaunchTemplate": "CC API returns version-bumped LaunchTemplateData with synthetic LatestVersionNumber that diverges from the CFn input shape"
|
|
38088
|
+
};
|
|
38089
|
+
|
|
38090
|
+
// src/analyzer/cc-api-strip.ts
|
|
38091
|
+
var ALWAYS_STRIPPED_FIELDS = /* @__PURE__ */ new Set([
|
|
38092
|
+
// Timestamps — AWS-managed, change on every modification. Names are
|
|
38093
|
+
// unambiguous: no CFn template ever exposes a "CreationDate" /
|
|
38094
|
+
// "LastModifiedTime" as a settable input.
|
|
38095
|
+
"CreationDate",
|
|
38096
|
+
"CreationTime",
|
|
38097
|
+
"CreatedTime",
|
|
38098
|
+
"CreatedDate",
|
|
38099
|
+
"CreatedAt",
|
|
38100
|
+
"LastModifiedDate",
|
|
38101
|
+
"LastModifiedTime",
|
|
38102
|
+
"LastModified",
|
|
38103
|
+
"LastUpdatedTime",
|
|
38104
|
+
"LastUpdatedDate",
|
|
38105
|
+
"UpdatedAt",
|
|
38106
|
+
// Owner / account / principal info — derived from the calling
|
|
38107
|
+
// principal, never user-set in a CFn template. `CreatedBy` /
|
|
38108
|
+
// `OwnerArn` are unique enough that no settable CFn property
|
|
38109
|
+
// collides with them.
|
|
38110
|
+
"OwnerId",
|
|
38111
|
+
"OwnerAccountId",
|
|
38112
|
+
"CreatedBy",
|
|
38113
|
+
"OwnerArn",
|
|
38114
|
+
// Lambda-specific generated identifiers. `RevisionId` rotates on
|
|
38115
|
+
// every operation; `LastUpdateStatus*` mirror runtime state. None
|
|
38116
|
+
// are settable in a CFn template.
|
|
38117
|
+
"RevisionId",
|
|
38118
|
+
"LastUpdateStatus",
|
|
38119
|
+
"LastUpdateStatusReason",
|
|
38120
|
+
"LastUpdateStatusReasonCode",
|
|
38121
|
+
// CloudFormation/Cloud Control passthrough metadata — never
|
|
38122
|
+
// appears as a settable input in a CFn template body.
|
|
38123
|
+
"StackId",
|
|
38124
|
+
"PhysicalResourceId",
|
|
38125
|
+
"LogicalResourceId"
|
|
38126
|
+
// Notes on intentional EXCLUSIONS:
|
|
38127
|
+
//
|
|
38128
|
+
// `State` / `Status` / `StateReason` / `StatusReason` — these
|
|
38129
|
+
// names ARE used by some CFn types as settable nested properties
|
|
38130
|
+
// (e.g. `AWS::ECS::CapacityProvider.AutoScalingGroupProvider.ManagedScaling.Status`,
|
|
38131
|
+
// `AWS::S3::Bucket.VersioningConfiguration.Status`). Stripping them
|
|
38132
|
+
// globally would cause false-positive drift on a clean stack.
|
|
38133
|
+
// The comparator already ignores AWS-only top-level `Status` values
|
|
38134
|
+
// because state doesn't carry them; only the nested-name-collision
|
|
38135
|
+
// cases would have leaked through, and excluding them here protects
|
|
38136
|
+
// those.
|
|
38137
|
+
//
|
|
38138
|
+
// `Arn` — many CFn types accept `Arn` as a settable property and
|
|
38139
|
+
// cdkd state may record it at create time. Drift on `Arn` is
|
|
38140
|
+
// genuine drift the user wants to see.
|
|
38141
|
+
//
|
|
38142
|
+
// `VersionId` / `GenerationId` / `ETag` — narrow utility (only S3
|
|
38143
|
+
// / KMS / ImageBuilder use these in their Get* responses), and at
|
|
38144
|
+
// least `VersionId` IS a settable input on `AWS::S3::Bucket`'s
|
|
38145
|
+
// versioning config. Per-provider readCurrentState handles them.
|
|
38146
|
+
//
|
|
38147
|
+
// `AccountId` / `StackName` — also collide with settable inputs
|
|
38148
|
+
// on a few CFn types (`AWS::CloudWatch::CrossAccountSharingRule.AccountId`,
|
|
38149
|
+
// `AWS::CloudFormation::HookDefaultVersion.StackName`).
|
|
38150
|
+
//
|
|
38151
|
+
// `StartTime` / `EndTime` — used as settable inputs in scheduling
|
|
38152
|
+
// shapes (e.g. `AWS::AutoScaling::ScheduledAction.StartTime`).
|
|
38153
|
+
]);
|
|
38154
|
+
function stripCcApiAwsManagedFields(resourceType, awsProps) {
|
|
38155
|
+
return stripWalk(awsProps);
|
|
38156
|
+
}
|
|
38157
|
+
function stripWalk(value) {
|
|
38158
|
+
if (value === null || value === void 0)
|
|
38159
|
+
return value;
|
|
38160
|
+
if (Array.isArray(value)) {
|
|
38161
|
+
return value.map(stripWalk);
|
|
38162
|
+
}
|
|
38163
|
+
if (typeof value === "object") {
|
|
38164
|
+
const out = {};
|
|
38165
|
+
for (const [key, child] of Object.entries(value)) {
|
|
38166
|
+
if (ALWAYS_STRIPPED_FIELDS.has(key))
|
|
38167
|
+
continue;
|
|
38168
|
+
out[key] = stripWalk(child);
|
|
38169
|
+
}
|
|
38170
|
+
return out;
|
|
38171
|
+
}
|
|
38172
|
+
return value;
|
|
38173
|
+
}
|
|
38174
|
+
|
|
38053
38175
|
// src/cli/commands/drift.ts
|
|
38054
38176
|
var DriftDetectedError = class _DriftDetectedError extends CdkdError {
|
|
38055
38177
|
silent = true;
|
|
@@ -38092,6 +38214,7 @@ async function driftCommand(stacks, options) {
|
|
|
38092
38214
|
const providerRegistry = new ProviderRegistry();
|
|
38093
38215
|
registerAllProviders(providerRegistry);
|
|
38094
38216
|
providerRegistry.setCustomResourceResponseBucket(bucket);
|
|
38217
|
+
const ccApiFallback = new CloudControlProvider();
|
|
38095
38218
|
const stateRefs = await stateBackend.listStacks();
|
|
38096
38219
|
const targetRefs = resolveTargetRefs(stacks, stateRefs, options);
|
|
38097
38220
|
const reports = [];
|
|
@@ -38105,7 +38228,8 @@ async function driftCommand(stacks, options) {
|
|
|
38105
38228
|
ref.stackName,
|
|
38106
38229
|
ref.region,
|
|
38107
38230
|
stateBackend,
|
|
38108
|
-
providerRegistry
|
|
38231
|
+
providerRegistry,
|
|
38232
|
+
ccApiFallback
|
|
38109
38233
|
);
|
|
38110
38234
|
reports.push(report);
|
|
38111
38235
|
}
|
|
@@ -38176,7 +38300,7 @@ function resolveTargetRefs(stacks, stateRefs, options) {
|
|
|
38176
38300
|
}
|
|
38177
38301
|
return out;
|
|
38178
38302
|
}
|
|
38179
|
-
async function runDriftForStack(stackName, region, stateBackend, providerRegistry) {
|
|
38303
|
+
async function runDriftForStack(stackName, region, stateBackend, providerRegistry, ccApiFallback) {
|
|
38180
38304
|
const result = await stateBackend.getState(stackName, region);
|
|
38181
38305
|
if (!result) {
|
|
38182
38306
|
throw new Error(
|
|
@@ -38202,27 +38326,39 @@ async function runDriftForStack(stackName, region, stateBackend, providerRegistr
|
|
|
38202
38326
|
});
|
|
38203
38327
|
continue;
|
|
38204
38328
|
}
|
|
38205
|
-
let
|
|
38206
|
-
if (
|
|
38207
|
-
|
|
38208
|
-
|
|
38209
|
-
|
|
38329
|
+
let aws;
|
|
38330
|
+
if (provider.readCurrentState) {
|
|
38331
|
+
aws = await provider.readCurrentState(
|
|
38332
|
+
resource.physicalId,
|
|
38333
|
+
logicalId,
|
|
38334
|
+
resource.resourceType,
|
|
38335
|
+
resource.properties ?? {}
|
|
38336
|
+
);
|
|
38337
|
+
} else {
|
|
38338
|
+
if (CC_API_FALLBACK_DENY_LIST[resource.resourceType]) {
|
|
38339
|
+
outcomes.push({
|
|
38340
|
+
kind: "unsupported",
|
|
38341
|
+
logicalId,
|
|
38342
|
+
resourceType: resource.resourceType
|
|
38343
|
+
});
|
|
38344
|
+
continue;
|
|
38210
38345
|
}
|
|
38211
|
-
|
|
38212
|
-
|
|
38213
|
-
outcomes.push({
|
|
38214
|
-
kind: "unsupported",
|
|
38346
|
+
const ccApiAws = await ccApiFallback.readCurrentState(
|
|
38347
|
+
resource.physicalId,
|
|
38215
38348
|
logicalId,
|
|
38216
|
-
|
|
38217
|
-
|
|
38218
|
-
|
|
38349
|
+
resource.resourceType,
|
|
38350
|
+
resource.properties ?? {}
|
|
38351
|
+
);
|
|
38352
|
+
if (ccApiAws === void 0) {
|
|
38353
|
+
outcomes.push({
|
|
38354
|
+
kind: "unsupported",
|
|
38355
|
+
logicalId,
|
|
38356
|
+
resourceType: resource.resourceType
|
|
38357
|
+
});
|
|
38358
|
+
continue;
|
|
38359
|
+
}
|
|
38360
|
+
aws = stripCcApiAwsManagedFields(resource.resourceType, ccApiAws);
|
|
38219
38361
|
}
|
|
38220
|
-
const aws = await readCurrentState(
|
|
38221
|
-
resource.physicalId,
|
|
38222
|
-
logicalId,
|
|
38223
|
-
resource.resourceType,
|
|
38224
|
-
resource.properties ?? {}
|
|
38225
|
-
);
|
|
38226
38362
|
if (aws === void 0) {
|
|
38227
38363
|
outcomes.push({
|
|
38228
38364
|
kind: "unsupported",
|
|
@@ -41760,7 +41896,7 @@ function reorderArgs(argv) {
|
|
|
41760
41896
|
}
|
|
41761
41897
|
async function main() {
|
|
41762
41898
|
const program = new Command14();
|
|
41763
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
41899
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.44.0");
|
|
41764
41900
|
program.addCommand(createBootstrapCommand());
|
|
41765
41901
|
program.addCommand(createSynthCommand());
|
|
41766
41902
|
program.addCommand(createListCommand());
|