@go-to-k/cdkd 0.290.41 → 0.290.43
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-CPWB3m4b.js → asg-provider-C9R-ND4b.js} +2 -2
- package/dist/{asg-provider-CPWB3m4b.js.map → asg-provider-C9R-ND4b.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-RoGuHEgf.js → deploy-engine-Bw8VoyEi.js} +488 -125
- package/dist/deploy-engine-Bw8VoyEi.js.map +1 -0
- package/dist/index.d.ts +36 -34
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-B1JOjOY4.js → program-Bh8a5wjj.js} +169 -54
- package/dist/{program-B1JOjOY4.js.map → program-Bh8a5wjj.js.map} +1 -1
- package/dist/{version-Cxppiepi.js → version-ChfV4K6h.js} +2 -2
- package/dist/{version-Cxppiepi.js.map → version-ChfV4K6h.js.map} +1 -1
- package/package.json +4 -4
- package/dist/deploy-engine-RoGuHEgf.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $ as yellow, $n as STATE_SOURCED_BASELINE_RULES, $r as
|
|
1
|
+
import { $ as yellow, $i as getAwsClients, $n as STATE_SOURCED_BASELINE_RULES, $r as validateContainerRepoName, $t as requireConfigObject, A as createPreDeleteFinalSnapshot, Aa as isTransientServerError, Ai as ssmResolvedValueType, An as malformedResourcePropertiesWarning, Ar as hasUnverifiableParameterRefusal, At as carriesDynamicReference, B as isStatefulRecreateTargetSync, Bi as producerRecordKey, Bn as refuseMalformedState, Br as buildAssetRedirectMap, Bt as isSettledInstanceState, C as namesAnyDeclaredParameter, Ci as resolveCaptureObservedState, Cn as malformedExportSourceWarning, Cr as formatLockExpiry, Ct as slowCcOperationTimeoutMs, D as PRE_DELETE_SNAPSHOT_TYPES, Da as isMarkedNonRetryable, Di as resolveUseCdkBootstrapAssets, Dn as malformedOutputsWarning, Dr as exportNamesCarriedFrom, Dt as disableInstanceApiTermination, E as ATOMIC_FINAL_SNAPSHOT_TYPES, Ea as withErrorHandling, Ei as resolveStateBucketWithDefaultAndSource, En as malformedOutputsRefusalMessage, Er as DEFAULT_STATE_PREFIX, Et as deleteSkipReason, F as extractDeploymentEventError, Fa as safeStringify, Fi as uploadCfnTemplate, Fn as refuseMalformedOutputs, Fr as orphansCarriedFrom, Ft as isImpossibleEmptyStoredAttribute, G as toCfnInteger, Gi as derivePartitionAndUrlSuffix, Gn as safeRegion, Gr as BOOTSTRAP_MARKER_PREFIX, Gt as coerceCfnBoolean, H as WARM_THROUGHPUT_MEMBERS, Hi as expectedOwnerParam, Hn as repairMalformedResourceEntriesForReadOnly, Hr as loadPublishableAssetManifest, Ht as normalizeAwsTagsToCfn, I as makeSiblingClaimReader, Ii as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, In as refuseMalformedOutputsForDestroy, Ir as shouldRetainResource, It as isNamelessDynamicReferenceError, J as bold, Ji as renderAssemblyPathEscape, Jn as findSilentDropProperties, Jr as getBootstrapMarkerKey, Jt as configIntegerRefusal, K as toFiniteNumber, Ki as AssemblyReader, Kn as safeStackName, Kr as assertAssetBucketRegion, Kt as coerceCfnInteger, L as planOrphanAdoption, Li as injectiveKey, Ln as refuseMalformedResourceEntries, Lr as AssetPublisher, Lt as isUnboundTemplateParameter, M as refusesFinalSnapshot, Ma as markRedactedCause, Mi as CFN_TEMPLATE_URL_LIMIT, Mn as malformedStateRefusalMessage, Mr as importableOutputs, Mt as cfnRefValueFromPhysicalId, N as unsupportedFinalSnapshotError, Na as retryClassificationText, Ni as MIGRATE_TMP_PREFIX, Nn as refuseDivergentRecordRegionForDestroy, Nr as isReadableBag, Nt as coerceParameterTypedValue, O as buildFinalSnapshotIdentifier, Oa as isRetryableTransientError, Oi as stateBucketExistenceConfirmed, On as malformedRenderedContainersWarning, Or as hasReadableExportSet, Ot as isTerminationProtectionPropagationError, P as makeCanonicalizePropertiesFn, Pa as describeAwsFailure, Pi as findLargeInlineResources, Pn as refuseMalformedNestedChildOutputs, Pr as orphansAfterRollback, Pt as getAccountInfo, Q as red, Qi as AwsClients, Qn as TemplateParser, Qr as validateAssetBucketName, Qt as requireConfigArray, R as MULTI_REGION_RECREATE_BLOCKED_TYPES, Ri as injectiveKeyPrefix, Rn as refuseMalformedResourcePropertiesForOrphan, Rr as stringifyValue, Rt as parameterTypeMayLoseSecretIdentity, S as computeParameterTaint, Sa as SynthesisError, Si as resolveAutoAssetStorage, Sn as malformedExportNamesWarning, Sr as forceQuitRecoveryClause, St as isWaitAbandonedError, T as resourcesNamingDeclaredParameter, Ta as normalizeAwsError, Ti as resolveStateBucketWithDefault, Tn as malformedOrphanRecordsWarning, Tr as CUSTOM_RESOURCE_RESPONSE_PREFIX, Tt as deleteIndeterminateGuards, U as coerceWarmThroughput$1, Ui as PARTITION_TABLE, Un as repairMalformedResourcePropertiesForReadOnly, Ur as rewriteTemplateAssetReferences, Ut as resolveExplicitPhysicalId, V as renderStatefulReason, Vi as decodeListingKey, Vn as repairMalformedOutputsForReadOnly, Vr as createAssetRedirectResolver, Vt as WAFv2WebACLProvider, W as isWarmThroughputDecrease, Wi as canonicalizeRegion, Wn as repairMalformedResourcesForReadOnly, Wr as AssetModeResolver, Wt as assertRegionMatch, X as gray, Xn as withRetry, Xr as parseBootstrapMarker, Xt as readConfigString, Y as cyan, Yi as resolveAssemblyPath, Yn as describeTypeWithThrottleRetry, Yr as isCrossRegionRedirect, Yt as configStringRefusal, Z as green, Zi as resolveBucketRegion, Zn as DagBuilder, Zr as readBootstrapMarkerBody, Zt as replayWarn, _ as bagHoldsSecretExpression, _a as ResourceTimeoutError, _i as Synthesizer, _n as UNREADABLE_RESOURCES_MAP_ROW, _r as S3StateBackend, _t as endCommandInterruptScope, a as DeploymentEventsStore, aa as CrossAccountSecretRefusalError, ai as describeDockerFailure, an as s3BucketDomainName, ar as dynamicReferenceTokens, at as secretBearingStateKeyWarning, b as mergeNoChangeOutputs, ba as StackTerminationProtectionError, bi as getLegacyStateBucketName, bn as hasReadableResources, br as buildForceUnlockCommand, bt as startInterruptWatch, c as replayFailedOperations, ca as DynamicReferenceRegionAmbiguousError, ci as getDockerCmd, cn as s3BucketWebsiteUrl, cr as isSingleDynamicReferenceToken, ct as IAMRoleProvider, d as updatePartialMessage, da as LocalStartServiceError, di as runDockerForeground, dn as applyCallerIdentityCredentials, dr as maskSecretsInText, dt as ProviderRegistry, ea as resetAwsClients, ei as buildDenyExternalAccessPolicy, en as requireConfigString, er as STATE_SOURCED_CROSS_GENERATION_RULES, et as collectDeclaredOutputNames, f as updatePartialReason, fi as runDockerStreaming, fn as callerEnvCredentials, fr as recordMaskOnlyValue, ft as wouldReturnToSdkProvider, g as computeImplicitDeleteEdges, ga as ProvisioningError, gi as getDockerImageBySourceHash, gn as STATE_RESOURCES_MALFORMED, gr as LockManager, gt as beginCommandInterruptScope, h as IMPLICIT_DELETE_DEPENDENCIES, ha as PartialFailureError, hi as AssetManifestLoader, hn as INTRINSIC_KEYS, hr as scrubResourceRecord, ht as maskerOrIdentity, i as DeploymentEventsReader, ii as describeDockerExecFailure, in as s3BucketArn, ir as createSecretMasker, it as secretBearing, j as isFinalSnapshotError, ja as markNonRetryable, ji as CFN_TEMPLATE_BODY_LIMIT, jn as malformedResourcesWarning, jr as importableOutputKeys, jt as carriesFetchableDynamicReference, k as ccRoutedFinalSnapshotError, ka as isThrottlingError, ki as warnDeprecatedNoPrefixCliFlag, kn as malformedResourceEntriesWarning, kr as hasReasonlessBaselineRefusal, kt as IntrinsicFunctionResolver, l as replayRollback, la as IntrinsicResolutionRefusalError, li as partitionSensitiveEnv, ln as applyRoleArnIfSet, lr as markSameGenerationBag, lt as collectInlinePolicyNamesManagedBySiblings, m as maskingRetryLogger, ma as NestedStackChildDirectDestroyError, mi as stripControlChars, mn as DiffCalculator, mr as redactSecretsForState, mt as maskDeep, n as DEFAULT_RESOURCE_WARN_AFTER_MS, ni as resolveDockerContextDirectory, nn as producerRegionsFromState, nr as TEMPLATE_SOURCED_RULES, nt as exportAliasCollisionScrubWarning, o as planFailedOps, oi as dockerSpawnEnvWithSensitive, on as s3BucketDualStackDomainName, or as errorCauseChain, ot as secretSafeKeyDisplay, p as withResourceDeadline, pa as MalformedProducerRecordRefusalError, pi as escapeRegExp, pn as envCredentialsAreAssumedRole, pr as recoverMaskedOutput, pt as createMaskedRetryLogger, q as formatResourceLine, qi as processStackMessages, qn as findActionableSilentDrops, qr as ensureAssetStorage, qt as configBooleanRefusal, r as DeployEngine, ra as CdkdError, ri as describeDockerCapturedOutput, rn as withSharedDrainBudget, rr as carriesSecretMask, rt as isExportAliasCollision, s as planRollback, sa as DeployCancelledError, si as formatDockerLoginError, sn as s3BucketRegionalDomainName, sr as identityKeyFor, st as getCurrentResourceSecrets, t as DEFAULT_RESOURCE_TIMEOUT_MS, ta as setAwsClients, ti as buildDockerImage, tn as classifyReplaySecretRegion, tr as STATE_SOURCED_READBACK_RULES, tt as collectPublishedOutputNames, u as resolveReplacementOldType, ua as LocalInvokeBuildError$1, ui as redactDockerArgvValues, un as AWS_CREDENTIAL_ENV_KEYS, ur as maskSecretsInError, ut as clearOnUpdateRemoval, v as isSecretBearingReferenceString, va as ResourceUpdateNotSupportedError, vi as synthesisStatusMessage, vn as displayLogicalId, vr as rebuildClientForBucketRegion, vt as interruptWatchListenerCount, w as reachableDivergentParameters, wi as resolveSkipPrefix, wn as malformedLocalOutputsWarning, wr as shellQuote, wt as UNSPECIFIED_SKIP_REASON, x as bindingSkippedOutputs, xi as resolveApp, xn as isReadableResourceEntry, xr as buildLockContentionMessage, xt as CloudControlProvider, y as keptWholeReasonText, ya as StackHasActiveImportsError, yi as getDefaultStateBucketName, yn as hasReadableOutputs, yr as UNREPRODUCIBLE_LOCK_CLAUSE, yt as isInterruptedWaitError, z as isStatefulRecreateTargetForReplace, zi as producerCoordinateKey, zn as refuseMalformedResourcesForDestroy, zr as WorkGraph, zt as refStateLookupFromResource } from "./deploy-engine-Bw8VoyEi.js";
|
|
2
2
|
import { C as displayAwsMessage, D as truncateCodePoints, E as isPasteableIdent, S as UNRENDERABLE, T as displaySafe, _ as withSkipPrefix, b as SECRET_REF_MAX_CODE_POINTS, c as PATTERN_B_NAME_OPTIONS, f as explicitNamePropertyFor, h as getCurrentStackName, i as reserveStdoutForPayload, l as PATTERN_B_NAME_PROPERTIES, m as generateResourceNameWithFallback, n as getLogger, o as runStackBuffered, p as generateResourceName, s as getLiveRenderer, u as PATTERN_B_RESOURCE_TYPES, v as withStackName, w as displayIdent, x as STACK_REF_MAX_CODE_POINTS } from "./logger-D-2HeLmd.js";
|
|
3
3
|
import { n as awsClientDefaults } from "./aws-client-defaults-BoIxyCir.js";
|
|
4
|
-
import { t as getCdkdVersion } from "./version-
|
|
5
|
-
import { a as renderDisableCommand, i as protectedReplacementAdvice, r as UNNAMEABLE_ID_CLAUSE, t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as getCdkdVersion } from "./version-ChfV4K6h.js";
|
|
5
|
+
import { a as renderDisableCommand, i as protectedReplacementAdvice, r as UNNAMEABLE_ID_CLAUSE, t as ASGProvider } from "./asg-provider-C9R-ND4b.js";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
7
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
8
8
|
import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, NotFound, 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";
|
|
@@ -34,7 +34,6 @@ import { tmpdir } from "node:os";
|
|
|
34
34
|
import { AssociateVPCWithHostedZoneCommand, ChangeResourceRecordSetsCommand, ChangeTagsForResourceCommand, CreateHostedZoneCommand, CreateQueryLoggingConfigCommand, DeleteHostedZoneCommand, DeleteQueryLoggingConfigCommand, DisassociateVPCFromHostedZoneCommand, GetHostedZoneCommand, HostedZoneAlreadyExists, ListHostedZonesByNameCommand, ListQueryLoggingConfigsCommand, ListResourceRecordSetsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$8, Route53Client, UpdateHostedZoneCommentCommand, UpdateHostedZoneFeaturesCommand } from "@aws-sdk/client-route-53";
|
|
35
35
|
import { AddTagsCommand, CreateListenerCommand, CreateLoadBalancerCommand, CreateTargetGroupCommand, DeleteListenerCommand, DeleteLoadBalancerCommand, DeleteTargetGroupCommand, DeregisterTargetsCommand, DescribeCapacityReservationCommand, DescribeListenerAttributesCommand, DescribeListenersCommand, DescribeLoadBalancerAttributesCommand, DescribeLoadBalancersCommand, DescribeTagsCommand, DescribeTargetGroupAttributesCommand, DescribeTargetGroupsCommand, DescribeTargetHealthCommand, ElasticLoadBalancingV2Client, ModifyCapacityReservationCommand, ModifyIpPoolsCommand, ModifyListenerAttributesCommand, ModifyListenerCommand, ModifyLoadBalancerAttributesCommand, ModifyTargetGroupAttributesCommand, ModifyTargetGroupCommand, RegisterTargetsCommand, RemoveTagsCommand, SetIpAddressTypeCommand, SetSecurityGroupsCommand, SetSubnetsCommand, waitUntilLoadBalancerAvailable } from "@aws-sdk/client-elastic-load-balancing-v2";
|
|
36
36
|
import { CreateAliasCommand, CreateKeyCommand, DeleteAliasCommand, DescribeKeyCommand, DisableKeyCommand, DisableKeyRotationCommand, EnableKeyCommand, EnableKeyRotationCommand, GetKeyPolicyCommand, GetKeyRotationStatusCommand, KMSClient, ListAliasesCommand, ListResourceTagsCommand, NotFoundException as NotFoundException$2, PutKeyPolicyCommand, ScheduleKeyDeletionCommand, TagResourceCommand as TagResourceCommand$11, UntagResourceCommand as UntagResourceCommand$11, UpdateAliasCommand, UpdateKeyDescriptionCommand } from "@aws-sdk/client-kms";
|
|
37
|
-
import { join as join$1 } from "path";
|
|
38
37
|
import { BatchDeleteImageCommand, CreateRepositoryCommand, DeleteLifecyclePolicyCommand, DeleteRepositoryCommand, DeleteRepositoryPolicyCommand, DescribeImagesCommand as DescribeImagesCommand$1, DescribeRepositoriesCommand, ECRClient, GetAuthorizationTokenCommand, GetLifecyclePolicyCommand, LifecyclePolicyNotFoundException, ListTagsForResourceCommand as ListTagsForResourceCommand$9, PutImageScanningConfigurationCommand, PutImageTagMutabilityCommand, PutLifecyclePolicyCommand, RepositoryNotEmptyException, RepositoryNotFoundException, SetRepositoryPolicyCommand, TagResourceCommand as TagResourceCommand$12, UntagResourceCommand as UntagResourceCommand$12 } from "@aws-sdk/client-ecr";
|
|
39
38
|
import { isDeepStrictEqual, promisify } from "node:util";
|
|
40
39
|
import graphlib from "graphlib";
|
|
@@ -42,7 +41,6 @@ import { AddTagsToResourceCommand as AddTagsToResourceCommand$2, CreateDBCluster
|
|
|
42
41
|
import { Command, InvalidArgumentError, Option } from "commander";
|
|
43
42
|
import * as readline$1 from "node:readline/promises";
|
|
44
43
|
import readline from "node:readline/promises";
|
|
45
|
-
import { writeFileSync as writeFileSync$1 } from "fs";
|
|
46
44
|
import { Document, Pair, Scalar, YAMLMap, YAMLSeq, isScalar, parse, stringify, visit } from "yaml";
|
|
47
45
|
import * as zlib from "node:zlib";
|
|
48
46
|
import { ApplicationAutoScalingClient, DeleteScalingPolicyCommand, DeregisterScalableTargetCommand, DescribeScalableTargetsCommand, DescribeScalingPoliciesCommand, PutScalingPolicyCommand, RegisterScalableTargetCommand } from "@aws-sdk/client-application-auto-scaling";
|
|
@@ -2265,7 +2263,35 @@ function countDeployableResources(template) {
|
|
|
2265
2263
|
return Object.values(template.Resources ?? {}).filter((r) => r.Type !== "AWS::CDK::Metadata").length;
|
|
2266
2264
|
}
|
|
2267
2265
|
/**
|
|
2268
|
-
*
|
|
2266
|
+
* Where `cdkd synth --verbose` writes one stack's template, refusing a path
|
|
2267
|
+
* that leaves `outputDir` (issue
|
|
2268
|
+
* [#3489](https://github.com/go-to-k/cdkd/issues/3489)).
|
|
2269
|
+
*
|
|
2270
|
+
* `stackName` is the assembly manifest's own `properties.stackName`, falling
|
|
2271
|
+
* back to the artifact id, so it is chosen by whoever wrote the assembly — and
|
|
2272
|
+
* this is the ONE place cdkd turns such a string into a path it WRITES. A
|
|
2273
|
+
* `../../../..`-bearing name would put attacker-chosen JSON outside the output
|
|
2274
|
+
* directory, clobbering whatever `<name>.template.json` it can reach.
|
|
2275
|
+
*
|
|
2276
|
+
* Exported for unit testing.
|
|
2277
|
+
*/
|
|
2278
|
+
function resolveVerboseTemplatePath(outputDir, stackName) {
|
|
2279
|
+
const resolved = resolveAssemblyPath(outputDir, `${stackName}.template.json`);
|
|
2280
|
+
if (!resolved.contained) throw new SynthesisError(`Stack '${displaySafe(stackName)}' would write its template to a path that ${renderAssemblyPathEscape(resolved, outputDir, "write it")}`);
|
|
2281
|
+
let linked = false;
|
|
2282
|
+
try {
|
|
2283
|
+
linked = lstatSync(resolved.path).isSymbolicLink();
|
|
2284
|
+
} catch {}
|
|
2285
|
+
if (linked) throw new SynthesisError(`Stack '${displaySafe(stackName)}' would write its template over a symbolic link at '${displaySafe(resolved.path)}'. cdkd writes a stack's template as a regular file beside the assembly; a symbolic link there redirects the write to wherever it points, so this indicates the synth output was hand-modified or generated by a non-CDK toolchain. Refusing to write it.`);
|
|
2286
|
+
return resolved.path;
|
|
2287
|
+
}
|
|
2288
|
+
/**
|
|
2289
|
+
* Synth command implementation.
|
|
2290
|
+
*
|
|
2291
|
+
* Exported for the wiring test that pins `--verbose` writing through
|
|
2292
|
+
* {@link resolveVerboseTemplatePath} rather than a bare `path.join`
|
|
2293
|
+
* (go-to-k/cdkd#3489): the guard has its own cases, but reverting the CALL
|
|
2294
|
+
* SITE left the suite green.
|
|
2269
2295
|
*/
|
|
2270
2296
|
async function synthCommand(options) {
|
|
2271
2297
|
const logger = getLogger();
|
|
@@ -2311,9 +2337,9 @@ async function synthCommand(options) {
|
|
|
2311
2337
|
logger.info(` - Outputs: ${outputCount}`);
|
|
2312
2338
|
logger.info(` - Has assets: ${assemblyReader.hasAssets(stack) ? "Yes" : "No"}`);
|
|
2313
2339
|
if (options.verbose) {
|
|
2314
|
-
const templatePath =
|
|
2315
|
-
writeFileSync
|
|
2316
|
-
logger.debug(` - Template written to: ${templatePath}`);
|
|
2340
|
+
const templatePath = resolveVerboseTemplatePath(options.output, stack.stackName);
|
|
2341
|
+
writeFileSync(templatePath, JSON.stringify(stack.template, null, 2));
|
|
2342
|
+
logger.debug(` - Template written to: ${displaySafe(templatePath)}`);
|
|
2317
2343
|
}
|
|
2318
2344
|
}
|
|
2319
2345
|
logger.info(`\nOutput: ${assemblyDir}`);
|
|
@@ -3444,7 +3470,7 @@ function templateIdentity(templatePath) {
|
|
|
3444
3470
|
const dir = path.dirname(templatePath);
|
|
3445
3471
|
let realDir;
|
|
3446
3472
|
try {
|
|
3447
|
-
realDir = fs.realpathSync(dir);
|
|
3473
|
+
realDir = fs.realpathSync.native(dir);
|
|
3448
3474
|
} catch {
|
|
3449
3475
|
realDir = path.resolve(dir);
|
|
3450
3476
|
}
|
|
@@ -3567,7 +3593,16 @@ function findNestedTemplateTreeDefect(nestedTemplates, ancestorTemplatePaths = [
|
|
|
3567
3593
|
logicalId: row.logicalId,
|
|
3568
3594
|
assetPath: row.assetPath
|
|
3569
3595
|
};
|
|
3570
|
-
const
|
|
3596
|
+
const resolved = resolveAssemblyPath(dir, row.assetPath);
|
|
3597
|
+
if (!resolved.contained) return {
|
|
3598
|
+
kind: "escaping-path",
|
|
3599
|
+
chain: [...chain],
|
|
3600
|
+
logicalId: row.logicalId,
|
|
3601
|
+
assetPath: row.assetPath,
|
|
3602
|
+
escape: resolved,
|
|
3603
|
+
dir
|
|
3604
|
+
};
|
|
3605
|
+
const defect = visit(row.logicalId, resolved.path);
|
|
3571
3606
|
if (defect) return defect;
|
|
3572
3607
|
}
|
|
3573
3608
|
} finally {
|
|
@@ -3626,6 +3661,7 @@ function renderNestedTemplateTreeDefect(defect, stackName, action) {
|
|
|
3626
3661
|
}
|
|
3627
3662
|
if (defect.kind === "too-large") return `The nested template tree under stack '${displaySafe(stackName)}' has more than ${MAX_ROWS_FOLLOWED} nested-stack rows to follow (the walk stopped at ${renderChain(defect.chain)}). That is far beyond any CDK-generated assembly. Symlinked directories can give one template file many paths, which multiplies the tree without ever repeating on one chain. Refusing to ${action}.`;
|
|
3628
3663
|
if (defect.kind === "too-deep") return `The nested template tree under stack '${displaySafe(stackName)}' nests more than ${512} levels deep: ${renderChain(defect.chain)}. No tree that deep can deploy, because each level lengthens the child's state key and S3 caps a key at 1024 bytes. ${provenance}`;
|
|
3664
|
+
if (defect.kind === "escaping-path") return `The nested template tree under stack '${displaySafe(stackName)}' has nested stack '${displaySafe(defect.logicalId)}' (reached through ${renderChain(defect.chain)}) with Metadata['aws:asset:path']='${displaySafe(defect.assetPath)}' which ${renderAssemblyPathEscape(defect.escape, defect.dir, action)}`;
|
|
3629
3665
|
return `The nested template tree under stack '${displaySafe(stackName)}' has nested stack '${displaySafe(defect.logicalId)}' (reached through ${renderChain(defect.chain)}) with Metadata['aws:asset:path']='${displaySafe(defect.assetPath)}' which is absolute. ${provenance}`;
|
|
3630
3666
|
}
|
|
3631
3667
|
|
|
@@ -18131,7 +18167,11 @@ function resolveDynamoDbDeleteBudgetClock() {
|
|
|
18131
18167
|
* the first's spent allowance. In practice `destroy-runner.ts` builds a fresh
|
|
18132
18168
|
* provider (and therefore a fresh registry) per region, so the collision is not
|
|
18133
18169
|
* reachable today — but that is an invariant of the CALLER, enforced nowhere,
|
|
18134
|
-
* and the fix costs one string concat.
|
|
18170
|
+
* and the fix costs one string concat. The key is ENCODED rather than
|
|
18171
|
+
* separated, so it does not rest on what can appear in either component --
|
|
18172
|
+
* both come from a state record, which `parseStateBody` reads as an unchecked
|
|
18173
|
+
* cast, so the claim this sentence used to make was about AWS rather than
|
|
18174
|
+
* about what arrives here (go-to-k/cdkd#3496).
|
|
18135
18175
|
*
|
|
18136
18176
|
* `region` is the STATE's region (`DeleteContext.expectedRegion`), which is
|
|
18137
18177
|
* available synchronously at the top of `delete()` — unlike the client's own
|
|
@@ -18140,7 +18180,7 @@ function resolveDynamoDbDeleteBudgetClock() {
|
|
|
18140
18180
|
* which degrades to the old bare-name key rather than failing.
|
|
18141
18181
|
*/
|
|
18142
18182
|
function deleteBudgetKey(physicalId, region) {
|
|
18143
|
-
return
|
|
18183
|
+
return injectiveKey(region ?? "", physicalId);
|
|
18144
18184
|
}
|
|
18145
18185
|
/**
|
|
18146
18186
|
* The poll cap a wait may actually use: its own constant, or what the shared
|
|
@@ -23397,7 +23437,7 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
23397
23437
|
* repeated `DescribeTable` calls.
|
|
23398
23438
|
*/
|
|
23399
23439
|
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
23400
|
-
const cacheKey =
|
|
23440
|
+
const cacheKey = injectiveKey(physicalId, attributeName);
|
|
23401
23441
|
if (this.attributeCache.has(cacheKey)) return this.attributeCache.get(cacheKey);
|
|
23402
23442
|
try {
|
|
23403
23443
|
const resp = await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: physicalId }));
|
|
@@ -28575,7 +28615,7 @@ const generations = /* @__PURE__ */ new Map();
|
|
|
28575
28615
|
* long-lived process cannot grow the map without bound.
|
|
28576
28616
|
*/
|
|
28577
28617
|
const MAX_TRACKED_GENERATIONS = 1e5;
|
|
28578
|
-
const tokenKey = (scope, logicalId, maxLength, charset) =>
|
|
28618
|
+
const tokenKey = (scope, logicalId, maxLength, charset) => injectiveKey(scope, process.env["AWS_REGION"] ?? "", getCurrentStackName() ?? "", logicalId, maxLength, charset);
|
|
28579
28619
|
const derive = (key, generation, maxLength, charset) => {
|
|
28580
28620
|
const digest = createHash("sha256").update(`${PROCESS_NONCE}\u0000${key}\u0000${generation}`).digest("hex");
|
|
28581
28621
|
return `cdkd${charset === "alphanumeric" ? "" : "-"}${digest}`.slice(0, maxLength);
|
|
@@ -42392,7 +42432,7 @@ var RDSDBProxyProvider = class {
|
|
|
42392
42432
|
throw new ProvisioningError(`Timed out waiting for DBProxy ${physicalId} to fully delete`, resourceType, logicalId, physicalId);
|
|
42393
42433
|
}
|
|
42394
42434
|
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
42395
|
-
const cacheKey =
|
|
42435
|
+
const cacheKey = injectiveKey(physicalId, attributeName);
|
|
42396
42436
|
const cached = this.attributeCache.get(cacheKey);
|
|
42397
42437
|
if (cached !== void 0) return cached;
|
|
42398
42438
|
if (attributeName !== "Endpoint" && attributeName !== "DBProxyArn" && attributeName !== "VpcId") {
|
|
@@ -42467,7 +42507,7 @@ var RDSDBProxyProvider = class {
|
|
|
42467
42507
|
const newMap = this.toTagMap(newTags);
|
|
42468
42508
|
if (oldMap.size === newMap.size && [...oldMap.keys()].every((k) => newMap.has(k)) && [...oldMap.entries()].every(([k, v]) => newMap.get(k) === v)) return;
|
|
42469
42509
|
const client = this.getClient();
|
|
42470
|
-
const arnCacheKey =
|
|
42510
|
+
const arnCacheKey = injectiveKey(physicalId, "DBProxyArn");
|
|
42471
42511
|
let arn = this.attributeCache.get(arnCacheKey);
|
|
42472
42512
|
if (!arn) try {
|
|
42473
42513
|
arn = (await client.send(new DescribeDBProxiesCommand({ DBProxyName: physicalId }))).DBProxies?.[0]?.DBProxyArn;
|
|
@@ -42534,7 +42574,8 @@ var RDSDBProxyProvider = class {
|
|
|
42534
42574
|
}
|
|
42535
42575
|
}
|
|
42536
42576
|
invalidateAttributeCache(physicalId) {
|
|
42537
|
-
|
|
42577
|
+
const encodedPrefix = injectiveKeyPrefix(physicalId);
|
|
42578
|
+
for (const key of this.attributeCache.keys()) if (key.startsWith(encodedPrefix)) this.attributeCache.delete(key);
|
|
42538
42579
|
}
|
|
42539
42580
|
wrapError(error, op, resourceType, logicalId, physicalId) {
|
|
42540
42581
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -42717,7 +42758,7 @@ var RDSDBProxyEndpointProvider = class {
|
|
|
42717
42758
|
throw new ProvisioningError(`Timed out waiting for DBProxyEndpoint ${physicalId} to fully delete`, resourceType, logicalId, physicalId);
|
|
42718
42759
|
}
|
|
42719
42760
|
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
42720
|
-
const cacheKey =
|
|
42761
|
+
const cacheKey = injectiveKey(physicalId, attributeName);
|
|
42721
42762
|
const cached = this.attributeCache.get(cacheKey);
|
|
42722
42763
|
if (cached !== void 0) return cached;
|
|
42723
42764
|
if (attributeName !== "Endpoint" && attributeName !== "DBProxyEndpointArn" && attributeName !== "IsDefault" && attributeName !== "VpcId") {
|
|
@@ -42778,7 +42819,7 @@ var RDSDBProxyEndpointProvider = class {
|
|
|
42778
42819
|
const newMap = this.toTagMap(newTags);
|
|
42779
42820
|
if (oldMap.size === newMap.size && [...oldMap.keys()].every((k) => newMap.has(k)) && [...oldMap.entries()].every(([k, v]) => newMap.get(k) === v)) return;
|
|
42780
42821
|
const client = this.getClient();
|
|
42781
|
-
const arnCacheKey =
|
|
42822
|
+
const arnCacheKey = injectiveKey(physicalId, "DBProxyEndpointArn");
|
|
42782
42823
|
let arn = this.attributeCache.get(arnCacheKey);
|
|
42783
42824
|
if (!arn) try {
|
|
42784
42825
|
arn = (await client.send(new DescribeDBProxyEndpointsCommand({ DBProxyEndpointName: physicalId }))).DBProxyEndpoints?.[0]?.DBProxyEndpointArn;
|
|
@@ -42846,7 +42887,8 @@ var RDSDBProxyEndpointProvider = class {
|
|
|
42846
42887
|
}
|
|
42847
42888
|
}
|
|
42848
42889
|
invalidateAttributeCache(physicalId) {
|
|
42849
|
-
|
|
42890
|
+
const encodedPrefix = injectiveKeyPrefix(physicalId);
|
|
42891
|
+
for (const key of this.attributeCache.keys()) if (key.startsWith(encodedPrefix)) this.attributeCache.delete(key);
|
|
42850
42892
|
}
|
|
42851
42893
|
wrapError(error, op, resourceType, logicalId, physicalId) {
|
|
42852
42894
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -64978,7 +65020,9 @@ var NestedStackProvider = class {
|
|
|
64978
65020
|
const result = Object.create(null);
|
|
64979
65021
|
for (const { logicalId: grandLogicalId, assetPath } of listNestedTemplateRows(childTemplate)) {
|
|
64980
65022
|
if (isAbsoluteCrossPlatform$1(assetPath)) throw markNonRetryable(/* @__PURE__ */ new Error(`NestedStackProvider: nested-stack '${displaySafe(grandLogicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which is absolute. CDK emits relative asset paths for nested templates; an absolute path indicates the synth output was hand-modified or generated by a non-CDK toolchain. Refusing to load.`));
|
|
64981
|
-
|
|
65023
|
+
const resolved = resolveAssemblyPath(dir, assetPath);
|
|
65024
|
+
if (!resolved.contained) throw markNonRetryable(/* @__PURE__ */ new Error(`NestedStackProvider: nested-stack '${displaySafe(grandLogicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which ${renderAssemblyPathEscape(resolved, dir)}`));
|
|
65025
|
+
result[grandLogicalId] = resolved.path;
|
|
64982
65026
|
}
|
|
64983
65027
|
return result;
|
|
64984
65028
|
}
|
|
@@ -66091,7 +66135,8 @@ async function deployCommand(stacks, options) {
|
|
|
66091
66135
|
region: assetRegion,
|
|
66092
66136
|
...options.profile && { profile: options.profile },
|
|
66093
66137
|
nodePrefix: `${stack.stackName}:`,
|
|
66094
|
-
...redirect && { redirect }
|
|
66138
|
+
...redirect && { redirect },
|
|
66139
|
+
...stack.assetOutdir !== void 0 && { assetOutdir: stack.assetOutdir }
|
|
66095
66140
|
});
|
|
66096
66141
|
for (const id of nodeIds) stackDeps.add(id);
|
|
66097
66142
|
}
|
|
@@ -67863,7 +67908,9 @@ function indexNestedChildTemplates(template, templatePath) {
|
|
|
67863
67908
|
const assetPath = resource.Metadata?.["aws:asset:path"];
|
|
67864
67909
|
if (typeof assetPath !== "string" || assetPath.length === 0) continue;
|
|
67865
67910
|
if (isAbsoluteCrossPlatform(assetPath)) throw new Error(`Nested stack '${displaySafe(logicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which is absolute. CDK emits relative asset paths for nested templates; an absolute path indicates the synth output was hand-modified or generated by a non-CDK toolchain. Refusing to load.`);
|
|
67866
|
-
|
|
67911
|
+
const resolved = resolveAssemblyPath(dir, assetPath);
|
|
67912
|
+
if (!resolved.contained) throw new Error(`Nested stack '${displaySafe(logicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which ${renderAssemblyPathEscape(resolved, dir)}`);
|
|
67913
|
+
result[logicalId] = resolved.path;
|
|
67867
67914
|
}
|
|
67868
67915
|
return result;
|
|
67869
67916
|
}
|
|
@@ -78711,8 +78758,13 @@ function readNestedChildTemplateFile(templatePath, childLogicalId) {
|
|
|
78711
78758
|
* non-CDK toolchain — `path.join(dir, '/abs/foo')` would silently bypass
|
|
78712
78759
|
* the `dir` argument).
|
|
78713
78760
|
*
|
|
78761
|
+
* Also refuses a path that RESOLVES outside `templateDir`, which the absolute
|
|
78762
|
+
* check cannot see — `path.join` folds `..`
|
|
78763
|
+
* ([#3489](https://github.com/go-to-k/cdkd/issues/3489)).
|
|
78764
|
+
*
|
|
78714
78765
|
* Sibling of `indexGrandchildTemplatePaths` in `import.ts`. Same rationale
|
|
78715
|
-
* for separate definitions as `readNestedChildTemplateFile` above.
|
|
78766
|
+
* for separate definitions as `readNestedChildTemplateFile` above. Exported
|
|
78767
|
+
* for unit testing.
|
|
78716
78768
|
*/
|
|
78717
78769
|
function indexNestedTemplatePaths(template, templateDir) {
|
|
78718
78770
|
const result = {};
|
|
@@ -78724,8 +78776,10 @@ function indexNestedTemplatePaths(template, templateDir) {
|
|
|
78724
78776
|
if (r.Type !== "AWS::CloudFormation::Stack") continue;
|
|
78725
78777
|
const assetPath = r.Metadata?.["aws:asset:path"];
|
|
78726
78778
|
if (typeof assetPath !== "string" || assetPath.length === 0) continue;
|
|
78727
|
-
if (path.isAbsolute(assetPath)) throw new Error(`cdkd export: nested-stack '${logicalId}' has Metadata['aws:asset:path']='${assetPath}' which is absolute. CDK emits relative asset paths for nested templates.`);
|
|
78728
|
-
|
|
78779
|
+
if (path.isAbsolute(assetPath)) throw new Error(`cdkd export: nested-stack '${displaySafe(logicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which is absolute. CDK emits relative asset paths for nested templates.`);
|
|
78780
|
+
const resolved = resolveAssemblyPath(templateDir, assetPath);
|
|
78781
|
+
if (!resolved.contained) throw new Error(`cdkd export: nested-stack '${displaySafe(logicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which ${renderAssemblyPathEscape(resolved, templateDir)}`);
|
|
78782
|
+
result[logicalId] = resolved.path;
|
|
78729
78783
|
}
|
|
78730
78784
|
return result;
|
|
78731
78785
|
}
|
|
@@ -85003,7 +85057,7 @@ var AttributeFetcher = class {
|
|
|
85003
85057
|
* success path returns `{ ok: true, value, fromCache: true }`.
|
|
85004
85058
|
*/
|
|
85005
85059
|
async getAtt(orphanLogicalId, attribute) {
|
|
85006
|
-
const cacheKey =
|
|
85060
|
+
const cacheKey = injectiveKey(orphanLogicalId, attribute);
|
|
85007
85061
|
if (this.cache.has(cacheKey)) return {
|
|
85008
85062
|
ok: true,
|
|
85009
85063
|
value: this.cache.get(cacheKey)
|
|
@@ -85061,7 +85115,7 @@ var AttributeFetcher = class {
|
|
|
85061
85115
|
this.logger.warn(`--force: live fetch failed for '${orphanLogicalId}.${attribute}' (${reason}); falling back to cached value from state.attributes.`);
|
|
85062
85116
|
if (carriesDynamicReference(cached)) this.logger.warn(`--force: the cached value for '${orphanLogicalId}.${attribute}' is an UNRESOLVED dynamic reference (a nested stack's redacted output, issue #2055). It is being written into the referring resource's state VERBATIM — cdkd cannot re-resolve it from here. Re-run without --force once the live attribute is readable, or fix the referring property by hand.`);
|
|
85063
85117
|
if (carriesSecretMask(cached)) this.logger.warn(`--force: the cached value for '${orphanLogicalId}.${attribute}' is the REDACTION MASK ('${"***"}'), not the attribute's value — cdkd redacted it into state and cannot recover it. It is being written into the referring resource's state VERBATIM, so that row now records a value the live resource does not have: the next 'cdkd diff' / 'cdkd deploy' reports a spurious change there (a REPLACEMENT if the property is create-only), 'cdkd rollback' refuses the record as a replay baseline, and 'cdkd export' blocks it. Re-run without --force once the live attribute is readable, re-import the record that holds the mask, or fix the referring property by hand.`);
|
|
85064
|
-
const cacheKey =
|
|
85118
|
+
const cacheKey = injectiveKey(orphanLogicalId, attribute);
|
|
85065
85119
|
this.cache.set(cacheKey, cached);
|
|
85066
85120
|
return {
|
|
85067
85121
|
ok: true,
|
|
@@ -85775,7 +85829,8 @@ async function publishAssetsCommand(stacks, options) {
|
|
|
85775
85829
|
region: stack.region || baseRegion,
|
|
85776
85830
|
...options.profile && { profile: options.profile },
|
|
85777
85831
|
nodePrefix: `${stack.stackName}:`,
|
|
85778
|
-
...redirect && { redirect }
|
|
85832
|
+
...redirect && { redirect },
|
|
85833
|
+
...stack.assetOutdir !== void 0 && { assetOutdir: stack.assetOutdir }
|
|
85779
85834
|
});
|
|
85780
85835
|
} catch (err) {
|
|
85781
85836
|
if (err.code === "ENOENT") {
|
|
@@ -87591,6 +87646,11 @@ function readNestedChildTemplate(templatePath, childLogicalId) {
|
|
|
87591
87646
|
* does: an absolute path indicates the synth output was hand-modified or
|
|
87592
87647
|
* generated by a non-CDK toolchain — `path.join(dir, '/abs/foo')` would
|
|
87593
87648
|
* silently bypass our `dir` resolution and point outside cdk.out.
|
|
87649
|
+
*
|
|
87650
|
+
* Also refuses a path that RESOLVES outside `dir`, which the absolute check
|
|
87651
|
+
* cannot see — `path.join` folds `..`
|
|
87652
|
+
* ([#3489](https://github.com/go-to-k/cdkd/issues/3489)). Exported for unit
|
|
87653
|
+
* testing.
|
|
87594
87654
|
*/
|
|
87595
87655
|
function indexGrandchildTemplatePaths(childTemplate, childTemplatePath) {
|
|
87596
87656
|
const dir = path.dirname(childTemplatePath);
|
|
@@ -87599,8 +87659,10 @@ function indexGrandchildTemplatePaths(childTemplate, childTemplatePath) {
|
|
|
87599
87659
|
if (resource.Type !== "AWS::CloudFormation::Stack") continue;
|
|
87600
87660
|
const assetPath = resource.Metadata?.["aws:asset:path"];
|
|
87601
87661
|
if (typeof assetPath !== "string" || assetPath.length === 0) continue;
|
|
87602
|
-
if (path.isAbsolute(assetPath)) throw new Error(`cdkd import --migrate-from-cloudformation: grandchild nested-stack '${grandLogicalId}' has Metadata['aws:asset:path']='${assetPath}' which is absolute. CDK emits relative asset paths for nested templates.`);
|
|
87603
|
-
|
|
87662
|
+
if (path.isAbsolute(assetPath)) throw new Error(`cdkd import --migrate-from-cloudformation: grandchild nested-stack '${displaySafe(grandLogicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which is absolute. CDK emits relative asset paths for nested templates.`);
|
|
87663
|
+
const resolved = resolveAssemblyPath(dir, assetPath);
|
|
87664
|
+
if (!resolved.contained) throw new Error(`cdkd import --migrate-from-cloudformation: grandchild nested-stack '${displaySafe(grandLogicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which ${renderAssemblyPathEscape(resolved, dir)}`);
|
|
87665
|
+
result[grandLogicalId] = resolved.path;
|
|
87604
87666
|
}
|
|
87605
87667
|
return result;
|
|
87606
87668
|
}
|
|
@@ -88819,7 +88881,7 @@ function notFoundError$1(target, stack, resources) {
|
|
|
88819
88881
|
*/
|
|
88820
88882
|
function copyLayerTreeLastWins(src, dest) {
|
|
88821
88883
|
mkdirSync(dest, { recursive: true });
|
|
88822
|
-
copyDirLastWins(realpathSync(src), dest);
|
|
88884
|
+
copyDirLastWins(realpathSync.native(src), dest);
|
|
88823
88885
|
}
|
|
88824
88886
|
function copyDirLastWins(fromDir, toDir) {
|
|
88825
88887
|
for (const entry of readdirSync(fromDir, { withFileTypes: true })) {
|
|
@@ -92585,7 +92647,7 @@ function materializeInlineCode$1(handler, source, fileExtension, tmpDirsOut) {
|
|
|
92585
92647
|
const modulePath = handler.substring(0, lastDot);
|
|
92586
92648
|
const dir = mkdtempSync(path.join(tmpdir(), "cdkd-local-start-api-"));
|
|
92587
92649
|
tmpDirsOut.add(dir);
|
|
92588
|
-
const filePath =
|
|
92650
|
+
const filePath = resolveInlineCodeFilePath(dir, modulePath, fileExtension, handler);
|
|
92589
92651
|
mkdirSync(path.dirname(filePath), { recursive: true });
|
|
92590
92652
|
writeFileSync(filePath, source, "utf-8");
|
|
92591
92653
|
return dir;
|
|
@@ -93775,8 +93837,9 @@ async function prepareOneImage(task, container, options) {
|
|
|
93775
93837
|
const tag = `cdkd-local-run-task-${(image.assetHash ?? "single").slice(0, 16)}`;
|
|
93776
93838
|
const actualTag = await buildDockerImage(asset, cdkOutDir, {
|
|
93777
93839
|
tag,
|
|
93840
|
+
...task.stack.assetOutdir !== void 0 && { assetOutdir: task.stack.assetOutdir },
|
|
93778
93841
|
...options.platformOverride !== void 0 && { platform: options.platformOverride },
|
|
93779
|
-
wrapError: (stderr) => new LocalInvokeBuildError$1(`docker build failed for ECS container '${container.name}' (${asset.source.directory
|
|
93842
|
+
wrapError: (stderr) => new LocalInvokeBuildError$1(`docker build failed for ECS container '${displaySafe(container.name)}' (${asset.source.directory !== void 0 ? displaySafe(asset.source.directory) : asset.source.executable ? redactDockerArgvValues(asset.source.executable).join(" ") : void 0}): ${displaySafe(stderr)}`)
|
|
93780
93843
|
});
|
|
93781
93844
|
if (actualTag !== tag) {
|
|
93782
93845
|
const tagArgs = [
|
|
@@ -93787,7 +93850,7 @@ async function prepareOneImage(task, container, options) {
|
|
|
93787
93850
|
try {
|
|
93788
93851
|
await runDockerStreaming(tagArgs);
|
|
93789
93852
|
} catch (err) {
|
|
93790
|
-
throw new LocalInvokeBuildError$1(`docker tag failed re-tagging '${actualTag}' → '${tag}' for ECS container '${container.name}': ${describeDockerFailure(err, tagArgs)}`);
|
|
93853
|
+
throw new LocalInvokeBuildError$1(`docker tag failed re-tagging '${displaySafe(actualTag)}' → '${displaySafe(tag)}' for ECS container '${displaySafe(container.name)}': ${displaySafe(describeDockerFailure(err, tagArgs))}`);
|
|
93791
93854
|
}
|
|
93792
93855
|
}
|
|
93793
93856
|
return tag;
|
|
@@ -94705,13 +94768,16 @@ async function loadAgentCoreAssetContext(args) {
|
|
|
94705
94768
|
const { resolvedTarget, resolved, stacks, cdkOutDir, assetLoader, oldAssetHash } = args;
|
|
94706
94769
|
const newCandidate = pickAgentCoreCandidateStack(resolvedTarget, stacks);
|
|
94707
94770
|
if (!newCandidate) return void 0;
|
|
94771
|
+
const cdkdRecord = stacks.find((s) => s.stackName === newCandidate.stackName);
|
|
94772
|
+
const manifestDir = cdkdRecord?.assetManifestPath ? dirname(cdkdRecord.assetManifestPath) : cdkOutDir;
|
|
94773
|
+
const assetOutdir = cdkdRecord?.assetOutdir ?? manifestDir;
|
|
94708
94774
|
if (resolved.codeArtifact) {
|
|
94709
94775
|
if (resolved.codeArtifact.s3Source) return void 0;
|
|
94710
|
-
const manifest = await assetLoader.loadManifest(
|
|
94776
|
+
const manifest = await assetLoader.loadManifest(manifestDir, newCandidate.stackName);
|
|
94711
94777
|
if (!manifest) return void 0;
|
|
94712
94778
|
const asset = assetLoader.getFileAssets(manifest).get(resolved.codeArtifact.codeAssetHash);
|
|
94713
94779
|
if (!asset) return void 0;
|
|
94714
|
-
const sourceDir = assetLoader.getAssetSourcePath(
|
|
94780
|
+
const sourceDir = assetLoader.getAssetSourcePath(manifestDir, asset, assetOutdir);
|
|
94715
94781
|
return {
|
|
94716
94782
|
...oldAssetHash !== void 0 && { oldAssetHash },
|
|
94717
94783
|
newAssetHash: resolved.codeArtifact.codeAssetHash,
|
|
@@ -94720,13 +94786,13 @@ async function loadAgentCoreAssetContext(args) {
|
|
|
94720
94786
|
};
|
|
94721
94787
|
}
|
|
94722
94788
|
if (resolved.containerUri === void 0) return void 0;
|
|
94723
|
-
const manifest = await assetLoader.loadManifest(
|
|
94789
|
+
const manifest = await assetLoader.loadManifest(manifestDir, newCandidate.stackName);
|
|
94724
94790
|
if (!manifest) return void 0;
|
|
94725
94791
|
const dockerImageEntry = getDockerImageBySourceHash(manifest, resolved.containerUri);
|
|
94726
94792
|
if (!dockerImageEntry) return void 0;
|
|
94727
94793
|
const newDockerImage = dockerImageEntry.asset;
|
|
94728
94794
|
if (!newDockerImage.source.directory) return void 0;
|
|
94729
|
-
const newAssetSourceDir =
|
|
94795
|
+
const newAssetSourceDir = resolveDockerContextDirectory(manifestDir, newDockerImage.source.directory, (message) => new Error(message), assetOutdir);
|
|
94730
94796
|
return {
|
|
94731
94797
|
...oldAssetHash !== void 0 && { oldAssetHash },
|
|
94732
94798
|
newAssetHash: dockerImageEntry.hash,
|
|
@@ -94743,6 +94809,9 @@ async function loadAgentCoreAssetContext(args) {
|
|
|
94743
94809
|
* "force rebuild", which is the conservative default.
|
|
94744
94810
|
*
|
|
94745
94811
|
* NOT exported from `cdk-local/internal`, so copied locally.
|
|
94812
|
+
*
|
|
94813
|
+
* @internal — exported so its manifest lookup can be fenced beside
|
|
94814
|
+
* {@link loadAgentCoreAssetContext}'s, which is its twin.
|
|
94746
94815
|
*/
|
|
94747
94816
|
async function deriveOldAssetHash(args) {
|
|
94748
94817
|
const { resolvedTarget, resolved, stacks, cdkOutDir, assetLoader } = args;
|
|
@@ -94750,7 +94819,9 @@ async function deriveOldAssetHash(args) {
|
|
|
94750
94819
|
if (resolved.containerUri === void 0) return void 0;
|
|
94751
94820
|
const candidate = pickAgentCoreCandidateStack(resolvedTarget, stacks);
|
|
94752
94821
|
if (!candidate) return void 0;
|
|
94753
|
-
const
|
|
94822
|
+
const manifestFile = stacks.find((s) => s.stackName === candidate.stackName)?.assetManifestPath;
|
|
94823
|
+
const manifestDir = manifestFile !== void 0 ? dirname(manifestFile) : cdkOutDir;
|
|
94824
|
+
const manifest = await assetLoader.loadManifest(manifestDir, candidate.stackName);
|
|
94754
94825
|
if (!manifest) return void 0;
|
|
94755
94826
|
return getDockerImageBySourceHash(manifest, resolved.containerUri)?.hash;
|
|
94756
94827
|
}
|
|
@@ -94835,7 +94906,7 @@ async function localInvokeAgentCoreCommand(target, options) {
|
|
|
94835
94906
|
...options.profile && { profile: options.profile },
|
|
94836
94907
|
...Object.keys(context).length > 0 && { context }
|
|
94837
94908
|
};
|
|
94838
|
-
const { stacks } = await synthesizer.synthesize(synthOpts);
|
|
94909
|
+
const { stacks, assemblyDir } = await synthesizer.synthesize(synthOpts);
|
|
94839
94910
|
const resolvedTarget = await resolveSingleTarget(target, {
|
|
94840
94911
|
entries: listTargets(stacks).agentCoreRuntimes,
|
|
94841
94912
|
message: "Select an AgentCore Runtime to invoke",
|
|
@@ -94873,6 +94944,7 @@ async function localInvokeAgentCoreCommand(target, options) {
|
|
|
94873
94944
|
const boot = await bootAgentCoreContainer({
|
|
94874
94945
|
resolved,
|
|
94875
94946
|
options,
|
|
94947
|
+
assemblyDir,
|
|
94876
94948
|
profileCredentials,
|
|
94877
94949
|
profileCredsFile,
|
|
94878
94950
|
stateProvider,
|
|
@@ -95083,9 +95155,9 @@ function isAgentCoreWatchEligible(protocol) {
|
|
|
95083
95155
|
*/
|
|
95084
95156
|
async function bootAgentCoreContainer(args) {
|
|
95085
95157
|
const logger = getLogger();
|
|
95086
|
-
const { resolved, options, profileCredentials, profileCredsFile, stateProvider, loadedState, imageContext, isMcp, isA2a } = args;
|
|
95158
|
+
const { resolved, options, assemblyDir, profileCredentials, profileCredsFile, stateProvider, loadedState, imageContext, isMcp, isA2a } = args;
|
|
95087
95159
|
await resolveFromS3BucketIntrinsic(resolved, stateProvider, loadedState, imageContext);
|
|
95088
|
-
const image = await resolveAgentCoreImage(resolved, options, loadedState);
|
|
95160
|
+
const image = await resolveAgentCoreImage(resolved, options, assemblyDir, loadedState);
|
|
95089
95161
|
const { env: dockerEnv, sensitiveEnvKeys } = await buildContainerEnv(resolved, options, profileCredentials, profileCredsFile, stateProvider, loadedState, imageContext);
|
|
95090
95162
|
const hostPort = await pickFreePort();
|
|
95091
95163
|
const containerHost = options.containerHost;
|
|
@@ -95132,7 +95204,7 @@ async function bootAgentCoreContainer(args) {
|
|
|
95132
95204
|
async function rebuildAgentCoreContainer(args) {
|
|
95133
95205
|
const { cleanupBefore, resolvedTarget, options, synthesizer, synthOpts, profileCredentials, profileCredsFile, stateProvider, isMcp, isA2a } = args;
|
|
95134
95206
|
await cleanupBefore();
|
|
95135
|
-
const { stacks: newStacks } = await synthesizer.synthesize(synthOpts);
|
|
95207
|
+
const { stacks: newStacks, assemblyDir: newAssemblyDir } = await synthesizer.synthesize(synthOpts);
|
|
95136
95208
|
const newCandidate = pickAgentCoreCandidateStack$1(resolvedTarget, newStacks);
|
|
95137
95209
|
const { context: newImageContext, loaded: newLoaded } = stateProvider && newCandidate ? await buildAgentCoreImageContext(newCandidate, stateProvider, options) : {
|
|
95138
95210
|
context: void 0,
|
|
@@ -95142,6 +95214,7 @@ async function rebuildAgentCoreContainer(args) {
|
|
|
95142
95214
|
...await bootAgentCoreContainer({
|
|
95143
95215
|
resolved: resolveAgentCoreTarget(resolvedTarget, newStacks, newImageContext),
|
|
95144
95216
|
options,
|
|
95217
|
+
assemblyDir: newAssemblyDir,
|
|
95145
95218
|
profileCredentials,
|
|
95146
95219
|
profileCredsFile,
|
|
95147
95220
|
stateProvider,
|
|
@@ -95322,11 +95395,18 @@ async function resolveHostCredentialsForSigV4(options, resolved, loaded, region)
|
|
|
95322
95395
|
* `loaded` is the `--from-cfn-stack` state record (when available) — threaded
|
|
95323
95396
|
* through so a bare `--assume-role` can resolve the execution-role ARN from
|
|
95324
95397
|
* state for the fromS3 download.
|
|
95398
|
+
*
|
|
95399
|
+
* `assemblyDir` is the ASSEMBLY ROOT as `Synthesizer.synthesize` reported it,
|
|
95400
|
+
* and is the containment bound for an asset path read out of the manifest
|
|
95401
|
+
* (issue go-to-k/cdkd#3489). It is NOT `options.output`: under
|
|
95402
|
+
* `-a <pre-synthesized dir>` synthesis is skipped and the assembly root is
|
|
95403
|
+
* `resolve(options.app)` while `--output` keeps its `cdk.out` default, so
|
|
95404
|
+
* binding to `--output` would refuse every asset of an untouched assembly.
|
|
95325
95405
|
*/
|
|
95326
|
-
async function resolveAgentCoreImage(resolved, options, loaded) {
|
|
95406
|
+
async function resolveAgentCoreImage(resolved, options, assemblyDir, loaded) {
|
|
95327
95407
|
const logger = getLogger();
|
|
95328
95408
|
const architecture = platformToArchitecture(options.platform);
|
|
95329
|
-
if (resolved.codeArtifact) return resolveAgentCoreCodeImage(resolved, resolved.codeArtifact, options, architecture, loaded);
|
|
95409
|
+
if (resolved.codeArtifact) return resolveAgentCoreCodeImage(resolved, resolved.codeArtifact, options, architecture, assemblyDir, loaded);
|
|
95330
95410
|
const containerUri = resolved.containerUri;
|
|
95331
95411
|
if (containerUri === void 0) throw new CdkdError(`AgentCore Runtime '${resolved.logicalId}' has neither a container image nor a code artifact to run.`, "LOCAL_INVOKE_AGENTCORE_NO_ARTIFACT");
|
|
95332
95412
|
const manifestPath = resolved.stack.assetManifestPath;
|
|
@@ -95362,7 +95442,7 @@ async function resolveAgentCoreImage(resolved, options, loaded) {
|
|
|
95362
95442
|
* run the same from-source build (generated Dockerfile → install deps → run
|
|
95363
95443
|
* EntryPoint).
|
|
95364
95444
|
*/
|
|
95365
|
-
async function resolveAgentCoreCodeImage(resolved, code, options, architecture, loaded) {
|
|
95445
|
+
async function resolveAgentCoreCodeImage(resolved, code, options, architecture, assemblyDir, loaded) {
|
|
95366
95446
|
if (code.s3Source) return resolveAgentCoreCodeImageFromS3(resolved, code, code.s3Source, options, architecture, loaded);
|
|
95367
95447
|
const manifestPath = resolved.stack.assetManifestPath;
|
|
95368
95448
|
if (!manifestPath) throw new CdkdError(`AgentCore Runtime '${resolved.logicalId}' uses a code artifact, but its stack has no asset manifest in cdk.out to read the bundle source from.`, "LOCAL_INVOKE_AGENTCORE_CODE_NO_MANIFEST");
|
|
@@ -95372,8 +95452,8 @@ async function resolveAgentCoreCodeImage(resolved, code, options, architecture,
|
|
|
95372
95452
|
const fileAssets = manifest ? loader.getFileAssets(manifest) : void 0;
|
|
95373
95453
|
const asset = fileAssets ? fileAssets.get(code.codeAssetHash) ?? findFileAssetByObjectKey(fileAssets, code.codeAssetHash) : void 0;
|
|
95374
95454
|
if (!asset) throw new CdkdError(`AgentCore Runtime '${resolved.logicalId}' code bundle (asset ${code.codeAssetHash}) was not found in the cdk.out asset manifest. ${getEmbedConfig().cliName} invoke-agentcore runs a local from-source build of a fromCodeAsset bundle — re-synthesize the app so the asset is staged in cdk.out and retry. (A fromS3 bundle is downloaded from S3 instead; this runtime has no literal Code.S3.Bucket.)`, "LOCAL_INVOKE_AGENTCORE_CODE_ASSET_NOT_FOUND");
|
|
95375
|
-
const sourceDir = loader.getAssetSourcePath(cdkOutDir, asset);
|
|
95376
|
-
if (!existsSync(sourceDir) || !statSync(sourceDir).isDirectory()) throw new CdkdError(`AgentCore Runtime '${resolved.logicalId}' code bundle source '${sourceDir}' does not exist or is not a directory. Re-synthesize the app and retry.`, "LOCAL_INVOKE_AGENTCORE_CODE_SOURCE_MISSING");
|
|
95455
|
+
const sourceDir = loader.getAssetSourcePath(cdkOutDir, asset, assemblyDir);
|
|
95456
|
+
if (!existsSync(sourceDir) || !statSync(sourceDir).isDirectory()) throw new CdkdError(`AgentCore Runtime '${displaySafe(resolved.logicalId)}' code bundle source '${displaySafe(sourceDir)}' does not exist or is not a directory. Re-synthesize the app and retry.`, "LOCAL_INVOKE_AGENTCORE_CODE_SOURCE_MISSING");
|
|
95377
95457
|
return buildAgentCoreCodeImage({
|
|
95378
95458
|
sourceDir,
|
|
95379
95459
|
runtime: code.runtime,
|
|
@@ -97031,6 +97111,31 @@ function applyProfileCredentialsOverlay(env, profileCreds, assumeRoleActive) {
|
|
|
97031
97111
|
else delete env["AWS_SESSION_TOKEN"];
|
|
97032
97112
|
}
|
|
97033
97113
|
/**
|
|
97114
|
+
* Where an inline `Code.ZipFile` body is written inside `dir`, refusing a
|
|
97115
|
+
* `Handler` whose module path escapes it (issue
|
|
97116
|
+
* [#3489](https://github.com/go-to-k/cdkd/issues/3489)).
|
|
97117
|
+
*
|
|
97118
|
+
* `Handler` is template-supplied, and `materializeInlineCode` turned it into a
|
|
97119
|
+
* FILENAME and then `mkdirSync(dirname, { recursive: true })` + `writeFileSync`
|
|
97120
|
+
* — so `Handler: '../../victim/evil.handler'` wrote attacker-chosen JavaScript
|
|
97121
|
+
* to an arbitrary host path. Measured: the file was created outside the temp
|
|
97122
|
+
* directory. That is a write, not the "we run their handler in a container"
|
|
97123
|
+
* trade cdkd already accepts.
|
|
97124
|
+
*
|
|
97125
|
+
* `dir` is a temp directory cdkd just created rather than the assembly, but
|
|
97126
|
+
* the containment question is identical and `resolveAssemblyPath` answers it
|
|
97127
|
+
* unchanged: `mkdtemp` sits under `/var/folders/...`, reached through macOS's
|
|
97128
|
+
* `/var -> /private/var` link, and the helper realpaths BOTH sides so that is
|
|
97129
|
+
* a no-op. Only the refusal's provenance differs, so it is passed explicitly.
|
|
97130
|
+
*
|
|
97131
|
+
* Exported for unit testing.
|
|
97132
|
+
*/
|
|
97133
|
+
function resolveInlineCodeFilePath(dir, modulePath, fileExtension, handler) {
|
|
97134
|
+
const resolved = resolveAssemblyPath(dir, `${modulePath}${fileExtension}`);
|
|
97135
|
+
if (!resolved.contained) throw new Error(`Handler '${displaySafe(handler)}' names a module path that ${renderAssemblyPathEscape(resolved, dir, "materialize it", "A Handler's module path names a file inside the function's own code directory; one that leaves it would write the inline Code.ZipFile body to an arbitrary path on this machine. Refusing to materialize it.")}`);
|
|
97136
|
+
return resolved.path;
|
|
97137
|
+
}
|
|
97138
|
+
/**
|
|
97034
97139
|
* Materialize an inline Lambda body (`Code.ZipFile`) to a tmpdir and
|
|
97035
97140
|
* return the directory the container should mount at /var/task. The
|
|
97036
97141
|
* filename is derived from the function's Handler property and the
|
|
@@ -97052,9 +97157,19 @@ function materializeInlineCode(handler, source, fileExtension) {
|
|
|
97052
97157
|
if (lastDot <= 0) throw new Error(`Handler '${handler}' is malformed: expected '<modulePath>.<exportName>'.`);
|
|
97053
97158
|
const modulePath = handler.substring(0, lastDot);
|
|
97054
97159
|
const dir = mkdtempSync(path.join(tmpdir(), "cdkd-local-invoke-"));
|
|
97055
|
-
|
|
97056
|
-
|
|
97057
|
-
|
|
97160
|
+
try {
|
|
97161
|
+
const filePath = resolveInlineCodeFilePath(dir, modulePath, fileExtension, handler);
|
|
97162
|
+
mkdirSync(path.dirname(filePath), { recursive: true });
|
|
97163
|
+
writeFileSync(filePath, source, "utf-8");
|
|
97164
|
+
} catch (e) {
|
|
97165
|
+
try {
|
|
97166
|
+
rmSync(dir, {
|
|
97167
|
+
recursive: true,
|
|
97168
|
+
force: true
|
|
97169
|
+
});
|
|
97170
|
+
} catch {}
|
|
97171
|
+
throw e;
|
|
97172
|
+
}
|
|
97058
97173
|
return dir;
|
|
97059
97174
|
}
|
|
97060
97175
|
/**
|
|
@@ -97228,4 +97343,4 @@ function buildProgram() {
|
|
|
97228
97343
|
|
|
97229
97344
|
//#endregion
|
|
97230
97345
|
export { buildProgram };
|
|
97231
|
-
//# sourceMappingURL=program-
|
|
97346
|
+
//# sourceMappingURL=program-Bh8a5wjj.js.map
|