@go-to-k/cdkd 0.268.0 → 0.268.2
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-ZylgRJOY.js → asg-provider-gaXfXSH0.js} +2 -2
- package/dist/{asg-provider-ZylgRJOY.js.map → asg-provider-gaXfXSH0.js.map} +1 -1
- package/dist/cli.js +121 -32
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-B5cRuFij.js → deploy-engine-BEjF-h_6.js} +245 -59
- package/dist/{deploy-engine-B5cRuFij.js.map → deploy-engine-BEjF-h_6.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,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as WorkGraph,
|
|
2
|
+
import { $ as WorkGraph, A as slowCcOperationTimeoutMs, At as warnDeprecatedNoPrefixCliFlag, B as applyRoleArnIfSet, Bt as resolveBucketRegion, C as yellow, Ct as resolveAutoAssetStorage, D as ProviderRegistry, Dt as resolveStateBucketWithDefaultAndSource, E as clearOnUpdateRemoval, Et as resolveStateBucketWithDefault, F as refStateLookupFromResource, Ft as uploadCfnTemplate, G as DagBuilder, H as describeTypeWithThrottleRetry, Ht as getAwsClients, I as WAFv2WebACLProvider, It as expectedOwnerParam, J as S3StateBackend, K as TemplateParser, Kt as CdkdError, L as normalizeAwsTagsToCfn, Lt as AssemblyReader, M as isTerminationProtectionPropagationError, Mt as CFN_TEMPLATE_URL_LIMIT, N as IntrinsicFunctionResolver, Nt as MIGRATE_TMP_PREFIX, O as findActionableSilentDrops, Ot as resolveUseCdkBootstrapAssets, P as cfnRefValueFromPhysicalId, Pt as findLargeInlineResources, Q as stringifyValue, Qt as LocalStartServiceError, R as resolveExplicitPhysicalId, Rt as processStackMessages, S as red, St as resolveApp, T as collectInlinePolicyNamesManagedBySiblings, Tt as resolveSkipPrefix, U as withRetry, Ut as resetAwsClients, V as DiffCalculator, Vt as AwsClients, W as isRetryableTransientError, Wt as setAwsClients, X as shouldRetainResource, Xt as LocalInvokeBuildError$1, Y as rebuildClientForBucketRegion, Yt as DeployCancelledError, Z as AssetPublisher, Zt as LocalMigrateError, _ as formatResourceLine, _t as getDockerImageBySourceHash, a as DeploymentEventsStore, an as ResourceUpdateNotSupportedError, at as BOOTSTRAP_MARKER_PREFIX, b as gray, bt as getDefaultStateBucketName, c as replayFailedOperations, ct as parseBootstrapMarker, d as IMPLICIT_DELETE_DEPENDENCIES, dt as buildDockerImage, en as MissingCdkCliError, et as buildAssetRedirectMap, f as computeImplicitDeleteEdges, fn as normalizeAwsError, ft as formatDockerLoginError, g as renderStatefulReason, gt as AssetManifestLoader, h as isStatefulRecreateTargetSync, ht as runDockerStreaming, i as DeploymentEventsReader, in as ResourceTimeoutError, it as AssetModeResolver, j as disableInstanceApiTermination, jt as CFN_TEMPLATE_BODY_LIMIT, k as CloudControlProvider, kt as stateBucketExistenceConfirmed, l as replayRollback, lt as validateAssetBucketName, m as MULTI_REGION_RECREATE_BLOCKED_TYPES, mt as runDockerForeground, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as PartialFailureError, nt as loadPublishableAssetManifest, o as planFailedOps, on as StackHasActiveImportsError, ot as ensureAssetStorage, p as extractDeploymentEventError, pn as withErrorHandling, pt as getDockerCmd, q as LockManager, r as DeployEngine, rn as ProvisioningError, rt as rewriteTemplateAssetReferences, s as planRollback, sn as StackTerminationProtectionError, st as getBootstrapMarkerKey, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as NestedStackChildDirectDestroyError, tt as createAssetRedirectResolver, u as withResourceDeadline, ut as validateContainerRepoName, v as bold, vt as Synthesizer, w as IAMRoleProvider, wt as resolveCaptureObservedState, x as green, xt as getLegacyStateBucketName, y as cyan, yt as synthesisStatusMessage, z as assertRegionMatch } from "./deploy-engine-BEjF-h_6.js";
|
|
3
3
|
import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as withSkipPrefix, i as runStackBuffered, n as getLogger, o as PATTERN_B_NAME_OPTIONS, p as withStackName, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-BYMEE-BS.js";
|
|
4
|
-
import { t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-gaXfXSH0.js";
|
|
5
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
6
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
7
7
|
import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -15617,30 +15617,13 @@ var EC2Provider = class {
|
|
|
15617
15617
|
VpcId: properties["VpcId"] ?? void 0
|
|
15618
15618
|
}))).GroupId;
|
|
15619
15619
|
try {
|
|
15620
|
-
await this.applyTags(groupId, properties, logicalId);
|
|
15621
15620
|
const ingressRules = properties["SecurityGroupIngress"];
|
|
15622
|
-
if (ingressRules && Array.isArray(ingressRules)) for (const rule of ingressRules) await this.ec2Client.send(new AuthorizeSecurityGroupIngressCommand({
|
|
15623
|
-
GroupId: groupId,
|
|
15624
|
-
IpPermissions: [this.buildIpPermission(rule)]
|
|
15625
|
-
}));
|
|
15626
15621
|
const egressRules = properties["SecurityGroupEgress"];
|
|
15627
|
-
|
|
15628
|
-
|
|
15629
|
-
|
|
15630
|
-
|
|
15631
|
-
|
|
15632
|
-
IpProtocol: "-1",
|
|
15633
|
-
IpRanges: [{ CidrIp: "0.0.0.0/0" }]
|
|
15634
|
-
}]
|
|
15635
|
-
}));
|
|
15636
|
-
} catch (error) {
|
|
15637
|
-
if (!this.isNotFoundError(error)) throw error;
|
|
15638
|
-
}
|
|
15639
|
-
for (const rule of egressRules) await this.ec2Client.send(new AuthorizeSecurityGroupEgressCommand({
|
|
15640
|
-
GroupId: groupId,
|
|
15641
|
-
IpPermissions: [this.buildIpPermission(rule, "egress")]
|
|
15642
|
-
}));
|
|
15643
|
-
}
|
|
15622
|
+
await Promise.all([
|
|
15623
|
+
this.applyTags(groupId, properties, logicalId),
|
|
15624
|
+
this.authorizeInlineIngress(groupId, ingressRules),
|
|
15625
|
+
this.applyInlineEgress(groupId, egressRules)
|
|
15626
|
+
]);
|
|
15644
15627
|
} catch (innerError) {
|
|
15645
15628
|
try {
|
|
15646
15629
|
await this.ec2Client.send(new DeleteSecurityGroupCommand({ GroupId: groupId }));
|
|
@@ -15663,6 +15646,79 @@ var EC2Provider = class {
|
|
|
15663
15646
|
throw new ProvisioningError(`Failed to create SecurityGroup ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
15664
15647
|
}
|
|
15665
15648
|
}
|
|
15649
|
+
/**
|
|
15650
|
+
* Authorize a freshly-created security group's inline
|
|
15651
|
+
* `SecurityGroupIngress` rules in a SINGLE `AuthorizeSecurityGroupIngress`
|
|
15652
|
+
* call.
|
|
15653
|
+
*
|
|
15654
|
+
* The API takes an `IpPermissions` ARRAY; the previous per-rule loop paid
|
|
15655
|
+
* one round trip per rule for no benefit. AWS applies the whole list
|
|
15656
|
+
* atomically, so the resulting rule set is byte-identical — the only
|
|
15657
|
+
* behavior difference is that a bad rule now rejects the batch instead of
|
|
15658
|
+
* being preceded by its already-applied siblings, and the caller deletes
|
|
15659
|
+
* the half-wired group in either case.
|
|
15660
|
+
*/
|
|
15661
|
+
async authorizeInlineIngress(groupId, ingressRules) {
|
|
15662
|
+
if (!Array.isArray(ingressRules) || ingressRules.length === 0) return;
|
|
15663
|
+
await this.ec2Client.send(new AuthorizeSecurityGroupIngressCommand({
|
|
15664
|
+
GroupId: groupId,
|
|
15665
|
+
IpPermissions: ingressRules.map((rule) => this.buildIpPermission(rule))
|
|
15666
|
+
}));
|
|
15667
|
+
}
|
|
15668
|
+
/**
|
|
15669
|
+
* Apply a freshly-created security group's inline `SecurityGroupEgress`
|
|
15670
|
+
* rules.
|
|
15671
|
+
*
|
|
15672
|
+
* When a template specifies egress explicitly, CloudFormation replaces the
|
|
15673
|
+
* AWS-default "allow all egress" rule (`-1` / `0.0.0.0/0`) with the
|
|
15674
|
+
* supplied set, so cdkd revokes the default first and then authorizes the
|
|
15675
|
+
* template's rules. Both steps are preserved, including for an EMPTY
|
|
15676
|
+
* `SecurityGroupEgress: []` — that is a deliberate "no egress at all",
|
|
15677
|
+
* which requires the revoke and no authorize.
|
|
15678
|
+
*
|
|
15679
|
+
* Two round trips are saved where they are provably redundant:
|
|
15680
|
+
*
|
|
15681
|
+
* - The whole revoke+authorize pair is SKIPPED when the templated egress
|
|
15682
|
+
* is exactly the rule AWS already created by default. `isDefaultEgressRule`
|
|
15683
|
+
* is the exact comparator (protocol `-1`, `CidrIp 0.0.0.0/0`, no IPv6
|
|
15684
|
+
* range / peer group / prefix list / description, ports absent or `-1`)
|
|
15685
|
+
* and is the SAME predicate the drift reverse-mapper uses to recognize
|
|
15686
|
+
* the AWS default, so the two cannot disagree about what "default" means.
|
|
15687
|
+
* AWS creates exactly ONE default egress rule and it is IPv4-only (there
|
|
15688
|
+
* is no `::/0` default), which is why a single-element match is the right
|
|
15689
|
+
* shape. NOTE this deliberately does NOT fire for the CDK L2
|
|
15690
|
+
* `allowAllOutbound: true` shape, which stamps
|
|
15691
|
+
* `Description: 'Allow all outbound traffic by default'` — the AWS
|
|
15692
|
+
* default rule carries no description, so skipping there would leave the
|
|
15693
|
+
* group in a state CloudFormation would not produce AND would surface as
|
|
15694
|
+
* permanent phantom drift (`readCurrentState` would report no
|
|
15695
|
+
* Description while state records one).
|
|
15696
|
+
* - The remaining authorize is a SINGLE batched call rather than one per
|
|
15697
|
+
* rule (see {@link authorizeInlineIngress}).
|
|
15698
|
+
*/
|
|
15699
|
+
async applyInlineEgress(groupId, egressRules) {
|
|
15700
|
+
if (!Array.isArray(egressRules)) return;
|
|
15701
|
+
if (egressRules.length === 1 && isDefaultEgressRule(egressRules[0])) {
|
|
15702
|
+
this.logger.debug(`SecurityGroup ${groupId} egress equals the AWS default allow-all rule; skipping the redundant revoke + re-authorize`);
|
|
15703
|
+
return;
|
|
15704
|
+
}
|
|
15705
|
+
try {
|
|
15706
|
+
await this.ec2Client.send(new RevokeSecurityGroupEgressCommand({
|
|
15707
|
+
GroupId: groupId,
|
|
15708
|
+
IpPermissions: [{
|
|
15709
|
+
IpProtocol: "-1",
|
|
15710
|
+
IpRanges: [{ CidrIp: "0.0.0.0/0" }]
|
|
15711
|
+
}]
|
|
15712
|
+
}));
|
|
15713
|
+
} catch (error) {
|
|
15714
|
+
if (!this.isNotFoundError(error)) throw error;
|
|
15715
|
+
}
|
|
15716
|
+
if (egressRules.length === 0) return;
|
|
15717
|
+
await this.ec2Client.send(new AuthorizeSecurityGroupEgressCommand({
|
|
15718
|
+
GroupId: groupId,
|
|
15719
|
+
IpPermissions: egressRules.map((rule) => this.buildIpPermission(rule, "egress"))
|
|
15720
|
+
}));
|
|
15721
|
+
}
|
|
15666
15722
|
async updateSecurityGroup(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
15667
15723
|
this.logger.debug(`Updating SecurityGroup ${logicalId}: ${physicalId}`);
|
|
15668
15724
|
try {
|
|
@@ -42953,6 +43009,39 @@ async function promptMigrationConfirm(renames, opts) {
|
|
|
42953
43009
|
rl.close();
|
|
42954
43010
|
}
|
|
42955
43011
|
}
|
|
43012
|
+
/**
|
|
43013
|
+
* Build the `DeployEngineOptions.onCurrentStateLoaded` gate that runs the
|
|
43014
|
+
* prefix-migration check, or `undefined` when the check is inactive
|
|
43015
|
+
* (`skipPrefix === false`, i.e. the user opted back in to legacy prefixing).
|
|
43016
|
+
*
|
|
43017
|
+
* Why a gate rather than a pre-lock `getState`: prefix-skipping has been the
|
|
43018
|
+
* default since v0.94.0, so the previous shape issued an S3 GET on EVERY
|
|
43019
|
+
* deploy of EVERY stack — including brand-new stacks with no state at all —
|
|
43020
|
+
* and the deploy engine then read the very same object again immediately
|
|
43021
|
+
* after taking the lock. Running as the engine's post-lock gate reuses that
|
|
43022
|
+
* read. The contract the check actually depends on ("surface this before any
|
|
43023
|
+
* provider call runs") is preserved: the engine invokes the gate immediately
|
|
43024
|
+
* after loading state and before parsing, diffing, or provisioning anything.
|
|
43025
|
+
* Reading under the lock is also strictly more authoritative — no concurrent
|
|
43026
|
+
* deploy can mutate the state between the check and the diff it predicts.
|
|
43027
|
+
*
|
|
43028
|
+
* Declining the prompt raises {@link DeployCancelledError}, which the deploy
|
|
43029
|
+
* CLI unwinds quietly (no error output, no FAILED run event) — matching the
|
|
43030
|
+
* plain early `return` the pre-lock version used.
|
|
43031
|
+
*
|
|
43032
|
+
* The gate is scoped to `stackName`: nested-stack children inherit the parent
|
|
43033
|
+
* engine's option object, and the check is deliberately top-level-only (it was
|
|
43034
|
+
* never applied to children).
|
|
43035
|
+
*/
|
|
43036
|
+
function createPrefixMigrationGate(opts) {
|
|
43037
|
+
if (!opts.skipPrefix) return void 0;
|
|
43038
|
+
return async (gateStackName, state) => {
|
|
43039
|
+
if (gateStackName !== opts.stackName) return;
|
|
43040
|
+
const pending = findPendingPrefixRenames(opts.stackName, state);
|
|
43041
|
+
if (pending.length === 0) return;
|
|
43042
|
+
if (!await promptMigrationConfirm(pending, { ...opts.yes !== void 0 && { yes: opts.yes } })) throw new DeployCancelledError();
|
|
43043
|
+
};
|
|
43044
|
+
}
|
|
42956
43045
|
|
|
42957
43046
|
//#endregion
|
|
42958
43047
|
//#region src/cli/commands/deploy.ts
|
|
@@ -43190,13 +43279,11 @@ async function deployCommand(stacks, options) {
|
|
|
43190
43279
|
});
|
|
43191
43280
|
let runResult = "SUCCEEDED";
|
|
43192
43281
|
try {
|
|
43193
|
-
|
|
43194
|
-
|
|
43195
|
-
|
|
43196
|
-
|
|
43197
|
-
|
|
43198
|
-
}
|
|
43199
|
-
}
|
|
43282
|
+
const migrationGate = createPrefixMigrationGate({
|
|
43283
|
+
stackName: stackInfo.stackName,
|
|
43284
|
+
skipPrefix,
|
|
43285
|
+
yes: options.yes
|
|
43286
|
+
});
|
|
43200
43287
|
let recreateViaCcApiTargets;
|
|
43201
43288
|
let recreateViaSdkProviderTargets;
|
|
43202
43289
|
if (options.recreateViaCcApi?.length || options.recreateViaSdkProvider?.length) {
|
|
@@ -43248,6 +43335,7 @@ async function deployCommand(stacks, options) {
|
|
|
43248
43335
|
...options.roleArn && { roleArn: options.roleArn },
|
|
43249
43336
|
...assetRedirect && { assetRedirect },
|
|
43250
43337
|
...eventRecorder && { eventRecorder },
|
|
43338
|
+
...migrationGate && { onCurrentStateLoaded: migrationGate },
|
|
43251
43339
|
...recreateViaCcApiTargets && recreateViaCcApiTargets.size > 0 && { recreateViaCcApiTargets },
|
|
43252
43340
|
...recreateViaSdkProviderTargets && recreateViaSdkProviderTargets.size > 0 && { recreateViaSdkProviderTargets },
|
|
43253
43341
|
...options.replace && { replace: true },
|
|
@@ -43296,6 +43384,7 @@ async function deployCommand(stacks, options) {
|
|
|
43296
43384
|
deleted: deployResult.deleted
|
|
43297
43385
|
}, deployResult.durationMs);
|
|
43298
43386
|
} catch (deployError) {
|
|
43387
|
+
if (deployError instanceof DeployCancelledError) return;
|
|
43299
43388
|
runResult = "FAILED";
|
|
43300
43389
|
recordRunFailed(eventRecorder, stackInfo.stackName, deployError);
|
|
43301
43390
|
throw deployError;
|
|
@@ -62613,7 +62702,7 @@ function createMigrateCommand() {
|
|
|
62613
62702
|
*/
|
|
62614
62703
|
function buildProgram() {
|
|
62615
62704
|
const program = new Command();
|
|
62616
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.268.
|
|
62705
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.268.2");
|
|
62617
62706
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
62618
62707
|
const { profile } = actionCommand.optsWithGlobals();
|
|
62619
62708
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|