@go-to-k/cdkd 0.281.2 → 0.281.4
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-n21zWyH-.js → asg-provider-B1QR4dCd.js} +2 -2
- package/dist/{asg-provider-n21zWyH-.js.map → asg-provider-B1QR4dCd.js.map} +1 -1
- package/dist/cli.js +459 -62
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-drWGPyTA.js → deploy-engine-Di4-1RJP.js} +3 -3
- package/dist/{deploy-engine-drWGPyTA.js.map → deploy-engine-Di4-1RJP.js.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 requireConfigArray, $t as expectedOwnerParam, A as green, An as withErrorHandling, At as getDockerCmd, B as slowCcOperationTimeoutMs, Bt as resolveAutoAssetStorage, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackHasActiveImportsError, Ct as ensureAssetStorage, D as bold, Dt as validateContainerRepoName, E as formatResourceLine, Et as validateAssetBucketName, F as clearOnUpdateRemoval, Ft as Synthesizer, G as refStateLookupFromResource, Gt as resolveUseCdkBootstrapAssets, H as isTerminationProtectionPropagationError, Ht as resolveSkipPrefix, I as ProviderRegistry, It as synthesisStatusMessage, J as resolveExplicitPhysicalId, Jt as CFN_TEMPLATE_BODY_LIMIT, K as WAFv2WebACLProvider, Kt as stateBucketExistenceConfirmed, L as findActionableSilentDrops, Lt as getDefaultStateBucketName, M as yellow, Mt as runDockerStreaming, N as IAMRoleProvider, Nt as AssetManifestLoader, O as cyan, Ot as buildDockerImage, P as collectInlinePolicyNamesManagedBySiblings, Pt as getDockerImageBySourceHash, Q as replayWarn, Qt as uploadCfnTemplate, R as findSilentDropProperties, Rt as getLegacyStateBucketName, S as extractDeploymentEventError, Sn as ResourceUpdateNotSupportedError, St as BOOTSTRAP_MARKER_PREFIX, T as renderStatefulReason, Tt as parseBootstrapMarker, U as IntrinsicFunctionResolver, Ut as resolveStateBucketWithDefault, V as disableInstanceApiTermination, Vt as resolveCaptureObservedState, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefaultAndSource, X as configStringRefusal, Xt as MIGRATE_TMP_PREFIX, Y as assertRegionMatch, Yt as CFN_TEMPLATE_URL_LIMIT, Z as readConfigString, Zt as findLargeInlineResources, _ as createPreDeleteFinalSnapshot, _n as MissingCdkCliError, _t as buildAssetRedirectMap, a as DeploymentEventsStore, an as getAwsClients, at as withRetry, b as unsupportedFinalSnapshotError, bn as ProvisioningError, bt as rewriteTemplateAssetReferences, c as replayFailedOperations, ct as DagBuilder, d as IMPLICIT_DELETE_DEPENDENCIES, dt as S3StateBackend, en as AssemblyReader, et as requireConfigObject, f as computeImplicitDeleteEdges, fn as DeployCancelledError, ft as rebuildClientForBucketRegion, g as ccRoutedFinalSnapshotError, gt as WorkGraph, h as buildFinalSnapshotIdentifier, hn as LocalStartServiceError, ht as stringifyValue, i as DeploymentEventsReader, in as AwsClients, it as describeTypeWithThrottleRetry, j as red, jt as runDockerForeground, k as gray, kn as normalizeAwsError, kt as formatDockerLoginError, l as replayRollback, ln as CdkdError, lt as TemplateParser, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalMigrateError, mt as AssetPublisher, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as applyRoleArnIfSet, o as planFailedOps, on as resetAwsClients, ot as isRetryableTransientError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalInvokeBuildError$1, pt as shouldRetainResource, q as normalizeAwsTagsToCfn, qt as warnDeprecatedNoPrefixCliFlag, r as DeployEngine, rn as resolveBucketRegion, rt as DiffCalculator, s as planRollback, sn as setAwsClients, st as isThrottlingError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as processStackMessages, tt as requireConfigString, u as withResourceDeadline, ut as LockManager, v as isFinalSnapshotError, vn as NestedStackChildDirectDestroyError, vt as createAssetRedirectResolver, w as isStatefulRecreateTargetSync, wn as StackTerminationProtectionError, wt as getBootstrapMarkerKey, x as makeCanonicalizePropertiesFn, xn as ResourceTimeoutError, xt as AssetModeResolver, y as refusesFinalSnapshot, yn as PartialFailureError, yt as loadPublishableAssetManifest, z as CloudControlProvider, zt as resolveApp } from "./deploy-engine-
|
|
2
|
+
import { $ as requireConfigArray, $t as expectedOwnerParam, A as green, An as withErrorHandling, At as getDockerCmd, B as slowCcOperationTimeoutMs, Bt as resolveAutoAssetStorage, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackHasActiveImportsError, Ct as ensureAssetStorage, D as bold, Dt as validateContainerRepoName, E as formatResourceLine, Et as validateAssetBucketName, F as clearOnUpdateRemoval, Ft as Synthesizer, G as refStateLookupFromResource, Gt as resolveUseCdkBootstrapAssets, H as isTerminationProtectionPropagationError, Ht as resolveSkipPrefix, I as ProviderRegistry, It as synthesisStatusMessage, J as resolveExplicitPhysicalId, Jt as CFN_TEMPLATE_BODY_LIMIT, K as WAFv2WebACLProvider, Kt as stateBucketExistenceConfirmed, L as findActionableSilentDrops, Lt as getDefaultStateBucketName, M as yellow, Mt as runDockerStreaming, N as IAMRoleProvider, Nt as AssetManifestLoader, O as cyan, Ot as buildDockerImage, P as collectInlinePolicyNamesManagedBySiblings, Pt as getDockerImageBySourceHash, Q as replayWarn, Qt as uploadCfnTemplate, R as findSilentDropProperties, Rt as getLegacyStateBucketName, S as extractDeploymentEventError, Sn as ResourceUpdateNotSupportedError, St as BOOTSTRAP_MARKER_PREFIX, T as renderStatefulReason, Tt as parseBootstrapMarker, U as IntrinsicFunctionResolver, Ut as resolveStateBucketWithDefault, V as disableInstanceApiTermination, Vt as resolveCaptureObservedState, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefaultAndSource, X as configStringRefusal, Xt as MIGRATE_TMP_PREFIX, Y as assertRegionMatch, Yt as CFN_TEMPLATE_URL_LIMIT, Z as readConfigString, Zt as findLargeInlineResources, _ as createPreDeleteFinalSnapshot, _n as MissingCdkCliError, _t as buildAssetRedirectMap, a as DeploymentEventsStore, an as getAwsClients, at as withRetry, b as unsupportedFinalSnapshotError, bn as ProvisioningError, bt as rewriteTemplateAssetReferences, c as replayFailedOperations, ct as DagBuilder, d as IMPLICIT_DELETE_DEPENDENCIES, dt as S3StateBackend, en as AssemblyReader, et as requireConfigObject, f as computeImplicitDeleteEdges, fn as DeployCancelledError, ft as rebuildClientForBucketRegion, g as ccRoutedFinalSnapshotError, gt as WorkGraph, h as buildFinalSnapshotIdentifier, hn as LocalStartServiceError, ht as stringifyValue, i as DeploymentEventsReader, in as AwsClients, it as describeTypeWithThrottleRetry, j as red, jt as runDockerForeground, k as gray, kn as normalizeAwsError, kt as formatDockerLoginError, l as replayRollback, ln as CdkdError, lt as TemplateParser, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalMigrateError, mt as AssetPublisher, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as applyRoleArnIfSet, o as planFailedOps, on as resetAwsClients, ot as isRetryableTransientError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalInvokeBuildError$1, pt as shouldRetainResource, q as normalizeAwsTagsToCfn, qt as warnDeprecatedNoPrefixCliFlag, r as DeployEngine, rn as resolveBucketRegion, rt as DiffCalculator, s as planRollback, sn as setAwsClients, st as isThrottlingError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as processStackMessages, tt as requireConfigString, u as withResourceDeadline, ut as LockManager, v as isFinalSnapshotError, vn as NestedStackChildDirectDestroyError, vt as createAssetRedirectResolver, w as isStatefulRecreateTargetSync, wn as StackTerminationProtectionError, wt as getBootstrapMarkerKey, x as makeCanonicalizePropertiesFn, xn as ResourceTimeoutError, xt as AssetModeResolver, y as refusesFinalSnapshot, yn as PartialFailureError, yt as loadPublishableAssetManifest, z as CloudControlProvider, zt as resolveApp } from "./deploy-engine-Di4-1RJP.js";
|
|
3
3
|
import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
|
|
4
|
-
import { t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-B1QR4dCd.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, 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, 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";
|
|
@@ -11597,6 +11597,123 @@ var LambdaLayerVersionProvider = class {
|
|
|
11597
11597
|
}
|
|
11598
11598
|
};
|
|
11599
11599
|
|
|
11600
|
+
//#endregion
|
|
11601
|
+
//#region src/provisioning/composite-id.ts
|
|
11602
|
+
/**
|
|
11603
|
+
* Refuse a composite physicalId whose segments would make it ambiguous
|
|
11604
|
+
* (issue [#1672](https://github.com/go-to-k/cdkd/issues/1672)).
|
|
11605
|
+
*
|
|
11606
|
+
* ## Why a composite id exists at all
|
|
11607
|
+
*
|
|
11608
|
+
* `ResourceProvider` passes a SINGLE `physicalId: string` as a resource's
|
|
11609
|
+
* identity, while CloudFormation keeps the physical id and its containing
|
|
11610
|
+
* scope as separate values. So every provider whose type needs more than one
|
|
11611
|
+
* value to address the resource PACKS them into one string joined by
|
|
11612
|
+
* {@link COMPOSITE_ID_SEPARATOR} — `<databaseName>|<tableName>` for
|
|
11613
|
+
* `AWS::Glue::Table`, `<apiId>|<typeName>|<fieldName>` for
|
|
11614
|
+
* `AWS::AppSync::Resolver`, and so on.
|
|
11615
|
+
*
|
|
11616
|
+
* ## Why it has to be guarded
|
|
11617
|
+
*
|
|
11618
|
+
* The separator is NOT escaped, so a segment that itself contains a `|`
|
|
11619
|
+
* produces an id with the wrong arity. Every decode site splits the stored id
|
|
11620
|
+
* back apart and the extra segment shifts everything — for a Glue table named
|
|
11621
|
+
* `a|b` in database `mydb` the recorded id `mydb|a|b` decodes to database
|
|
11622
|
+
* `mydb`, table `a`. Both halves are non-empty, so every existing
|
|
11623
|
+
* "is this id well-formed?" guard passes and the deploy SUCCEEDS. What breaks
|
|
11624
|
+
* is everything afterwards: `cdkd destroy` deletes the WRONG resource if one
|
|
11625
|
+
* exists under the decoded pair (or warn-and-skips, reporting success while
|
|
11626
|
+
* the real resource stays alive and billing), and `cdkd drift` reads back
|
|
11627
|
+
* `undefined` forever.
|
|
11628
|
+
*
|
|
11629
|
+
* AWS itself accepts such a name — verified live us-east-1 2026-08-12,
|
|
11630
|
+
* `glue:CreateTable` with `TableInput.Name: 'a|b'` succeeds — and
|
|
11631
|
+
* CloudFormation manages the resource fine. The limitation is cdkd's own, so
|
|
11632
|
+
* the honest answer is to REFUSE at deploy time with a message that says so,
|
|
11633
|
+
* rather than to record an id that silently names something else. Escaping the
|
|
11634
|
+
* separator, or dropping the packing where the decode sites already receive
|
|
11635
|
+
* the properties bag, are the two real fixes and both remain open on #1672;
|
|
11636
|
+
* this guard is what closes the data-loss path in the meantime.
|
|
11637
|
+
*
|
|
11638
|
+
* ## Two entry points, mirroring `config-shape.ts`
|
|
11639
|
+
*
|
|
11640
|
+
* {@link packCompositeId} is the ACTION (throw, or warn-and-pack under the
|
|
11641
|
+
* replay downgrade) and {@link compositeIdSeparatorRefusal} is the bare
|
|
11642
|
+
* PREDICATE, for a caller whose response is neither — the `import()` paths
|
|
11643
|
+
* warn and return `null` (`skipped-not-found`), which is the idiom those
|
|
11644
|
+
* methods already use for every other unusable id. Both share one message
|
|
11645
|
+
* builder so the two can never drift.
|
|
11646
|
+
*
|
|
11647
|
+
* ## Where to place the call
|
|
11648
|
+
*
|
|
11649
|
+
* Prefer computing the id BEFORE the create call rather than after it. The
|
|
11650
|
+
* refusal is a pre-flight check, and a throw placed after the AWS mutation has
|
|
11651
|
+
* already committed would leave an orphan resource behind with no state
|
|
11652
|
+
* record. Only where a segment is derived from the create RESPONSE (an
|
|
11653
|
+
* AWS-generated id) does the call have to sit after it — and those segments
|
|
11654
|
+
* are structurally incapable of carrying a `|` anyway. A post-call site must
|
|
11655
|
+
* also sit OUTSIDE the `try` whose `catch` re-wraps as
|
|
11656
|
+
* `ProvisioningError('Failed to create …')`, or a refusal would be
|
|
11657
|
+
* mis-reported as an AWS creation failure.
|
|
11658
|
+
*
|
|
11659
|
+
* ## What this does NOT cover
|
|
11660
|
+
*
|
|
11661
|
+
* The claim is "every composite packer this change reaches", not "every `|`
|
|
11662
|
+
* join in the tree". Two deliberate exclusions, recorded so the scope is not
|
|
11663
|
+
* read as wider than it is:
|
|
11664
|
+
*
|
|
11665
|
+
* - **`route53-provider.ts`'s three packers** (`AWS::Route53::RecordSet` and
|
|
11666
|
+
* its siblings) are NOT guarded — the file was owned by a parallel lane when
|
|
11667
|
+
* this shipped. The exposure there is bounded rather than absent:
|
|
11668
|
+
* `parseRecordSetCompositeId` requires EXACTLY three parts, so a four-part
|
|
11669
|
+
* id is REJECTED rather than mis-decoded into a different record. That is
|
|
11670
|
+
* the loud failure mode, not the silent-wrong-resource one this helper
|
|
11671
|
+
* exists for — but the deploy still records an id nothing can decode, so the
|
|
11672
|
+
* type belongs here whenever that lane lands. Tracked in issue
|
|
11673
|
+
* [#1711](https://github.com/go-to-k/cdkd/issues/1711).
|
|
11674
|
+
* - **`intrinsic-function-resolver.ts`'s `|` joins** (the WAFv2 and
|
|
11675
|
+
* `AWS::Events::Rule` arms) are out of scope by KIND, not by ownership: they
|
|
11676
|
+
* build a `Ref` VALUE for the template resolver, never a physicalId cdkd
|
|
11677
|
+
* records and later splits. Nothing decodes them, so an ambiguous join has
|
|
11678
|
+
* no decode site to go wrong at.
|
|
11679
|
+
*/
|
|
11680
|
+
/** The character every composite physicalId in this codebase joins segments with. */
|
|
11681
|
+
const COMPOSITE_ID_SEPARATOR = "|";
|
|
11682
|
+
/** The issue tracking the real fix (escaping, or not packing at all). */
|
|
11683
|
+
const COMPOSITE_ID_ISSUE_URL = "https://github.com/go-to-k/cdkd/issues/1672";
|
|
11684
|
+
/** Render `<a>|<b>|<c>` from the segment names. */
|
|
11685
|
+
function idShape(segments) {
|
|
11686
|
+
return segments.map((segment) => `<${segment.name}>`).join("|");
|
|
11687
|
+
}
|
|
11688
|
+
/**
|
|
11689
|
+
* The refusal sentence for a composite id whose segments carry the separator,
|
|
11690
|
+
* or `undefined` when the id is unambiguous.
|
|
11691
|
+
*
|
|
11692
|
+
* Every offending segment is named, not just the first: a template that
|
|
11693
|
+
* mis-names one value frequently mis-names its sibling too, and reporting them
|
|
11694
|
+
* one deploy at a time is the shape of remedy nobody finishes.
|
|
11695
|
+
*/
|
|
11696
|
+
function compositeIdSeparatorRefusal(resourceType, logicalId, segments) {
|
|
11697
|
+
const offending = segments.filter((segment) => String(segment.value).includes("|"));
|
|
11698
|
+
if (offending.length === 0) return void 0;
|
|
11699
|
+
return `${resourceType} ${logicalId}: ${offending.map((segment) => `${segment.name} '${String(segment.value)}'`).join(" and ")} contains '${"|"}', which cdkd uses as the separator in this type's physical id (${idShape(segments)}). Recording it would produce an id that decodes back to a DIFFERENT resource, so a later cdkd destroy / drift / update would target the wrong one — or silently skip it while the real resource stays alive. AWS accepts the name and CloudFormation manages such a resource fine; this is a cdkd limitation tracked in ${COMPOSITE_ID_ISSUE_URL}. Rename the resource so no segment contains '${"|"}', or manage it outside cdkd.`;
|
|
11700
|
+
}
|
|
11701
|
+
/**
|
|
11702
|
+
* Join the segments into a composite physicalId, REFUSING one that would be
|
|
11703
|
+
* ambiguous.
|
|
11704
|
+
*
|
|
11705
|
+
* @throws ProvisioningError when a segment contains {@link COMPOSITE_ID_SEPARATOR},
|
|
11706
|
+
* unless `options.onRefusal` is supplied — under which the message is handed
|
|
11707
|
+
* to the callback and the ambiguous id is returned, keeping the pre-guard
|
|
11708
|
+
* behavior.
|
|
11709
|
+
*/
|
|
11710
|
+
function packCompositeId(resourceType, logicalId, segments, options) {
|
|
11711
|
+
const refusal = compositeIdSeparatorRefusal(resourceType, logicalId, segments);
|
|
11712
|
+
if (refusal !== void 0) if (options?.onRefusal) options.onRefusal(`${refusal} Continuing with the ambiguous id because the value comes from a cdkd state record, which no template edit can repair; the same value is REFUSED on a template-path create.`);
|
|
11713
|
+
else throw new ProvisioningError(refusal, resourceType, logicalId);
|
|
11714
|
+
return segments.map((segment) => String(segment.value)).join("|");
|
|
11715
|
+
}
|
|
11716
|
+
|
|
11600
11717
|
//#endregion
|
|
11601
11718
|
//#region src/provisioning/providers/lambda-event-invoke-config-provider.ts
|
|
11602
11719
|
/**
|
|
@@ -11640,8 +11757,14 @@ var LambdaEventInvokeConfigProvider = class {
|
|
|
11640
11757
|
/**
|
|
11641
11758
|
* Compose the Cloud-Control-compatible compound physical id.
|
|
11642
11759
|
*/
|
|
11643
|
-
buildPhysicalId(functionName, qualifier) {
|
|
11644
|
-
return
|
|
11760
|
+
buildPhysicalId(logicalId, functionName, qualifier, options) {
|
|
11761
|
+
return packCompositeId("AWS::Lambda::EventInvokeConfig", logicalId, [{
|
|
11762
|
+
name: "functionName",
|
|
11763
|
+
value: functionName
|
|
11764
|
+
}, {
|
|
11765
|
+
name: "qualifier",
|
|
11766
|
+
value: qualifier
|
|
11767
|
+
}], options);
|
|
11645
11768
|
}
|
|
11646
11769
|
/**
|
|
11647
11770
|
* Split a `<FunctionName>|<Qualifier>` physical id back into its parts.
|
|
@@ -11699,9 +11822,9 @@ var LambdaEventInvokeConfigProvider = class {
|
|
|
11699
11822
|
coerceNumber: true,
|
|
11700
11823
|
...replayWarn(this.logger, context)
|
|
11701
11824
|
});
|
|
11825
|
+
const physicalId = this.buildPhysicalId(logicalId, functionName, qualifier, context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
|
|
11702
11826
|
try {
|
|
11703
11827
|
await this.lambdaClient.send(new PutFunctionEventInvokeConfigCommand(this.buildPutInput(properties)));
|
|
11704
|
-
const physicalId = this.buildPhysicalId(functionName, qualifier);
|
|
11705
11828
|
this.logger.debug(`Successfully created Lambda EventInvokeConfig ${logicalId}: ${physicalId}`);
|
|
11706
11829
|
return {
|
|
11707
11830
|
physicalId,
|
|
@@ -18860,7 +18983,7 @@ var EC2Provider = class {
|
|
|
18860
18983
|
case "AWS::EC2::Subnet": return this.createSubnet(logicalId, resourceType, properties);
|
|
18861
18984
|
case "AWS::EC2::InternetGateway": return this.createInternetGateway(logicalId, resourceType, properties);
|
|
18862
18985
|
case "AWS::EC2::EIP": return this.createEip(logicalId, resourceType, properties, context);
|
|
18863
|
-
case "AWS::EC2::VPCGatewayAttachment": return this.createVpcGatewayAttachment(logicalId, resourceType, properties);
|
|
18986
|
+
case "AWS::EC2::VPCGatewayAttachment": return this.createVpcGatewayAttachment(logicalId, resourceType, properties, context);
|
|
18864
18987
|
case "AWS::EC2::NatGateway": return this.createNatGateway(logicalId, resourceType, properties);
|
|
18865
18988
|
case "AWS::EC2::RouteTable": return this.createRouteTable(logicalId, resourceType, properties);
|
|
18866
18989
|
case "AWS::EC2::Route": return this.createRoute(logicalId, resourceType, properties, context?.replayingState === true ? (message) => this.logger.warn(message) : void 0);
|
|
@@ -18869,7 +18992,7 @@ var EC2Provider = class {
|
|
|
18869
18992
|
case "AWS::EC2::SecurityGroupIngress": return this.createSecurityGroupIngress(logicalId, resourceType, properties, context?.replayingState === true ? (message) => this.logger.warn(message) : void 0);
|
|
18870
18993
|
case "AWS::EC2::Instance": return this.createInstance(logicalId, resourceType, properties, context);
|
|
18871
18994
|
case "AWS::EC2::NetworkAcl": return this.createNetworkAcl(logicalId, resourceType, properties);
|
|
18872
|
-
case "AWS::EC2::NetworkAclEntry": return this.createNetworkAclEntry(logicalId, resourceType, properties);
|
|
18995
|
+
case "AWS::EC2::NetworkAclEntry": return this.createNetworkAclEntry(logicalId, resourceType, properties, context);
|
|
18873
18996
|
case "AWS::EC2::SubnetNetworkAclAssociation": return this.createSubnetNetworkAclAssociation(logicalId, resourceType, properties);
|
|
18874
18997
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
|
|
18875
18998
|
}
|
|
@@ -19301,8 +19424,24 @@ var EC2Provider = class {
|
|
|
19301
19424
|
throw new ProvisioningError(`Failed to delete InternetGateway ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
19302
19425
|
}
|
|
19303
19426
|
}
|
|
19304
|
-
|
|
19305
|
-
|
|
19427
|
+
/**
|
|
19428
|
+
* Both segments are AWS-generated (a dotted-quad address and an
|
|
19429
|
+
* `eipalloc-...` id), so neither can carry cdkd's `|` separator and the
|
|
19430
|
+
* refusal below is a fence rather than a live guard (issue #1672). It is
|
|
19431
|
+
* applied uniformly with the rest of the composite-packing sites so a future
|
|
19432
|
+
* id-shape change cannot quietly reintroduce the ambiguity; for the same
|
|
19433
|
+
* reason it is safe on BOTH callers — `createEip` (post-`AllocateAddress`)
|
|
19434
|
+
* and `import()` (post-`DescribeAddresses`) — even though a throw on either
|
|
19435
|
+
* would arrive after the AWS call.
|
|
19436
|
+
*/
|
|
19437
|
+
eipPhysicalId(logicalId, publicIp, allocationId, options) {
|
|
19438
|
+
return packCompositeId("AWS::EC2::EIP", logicalId, [{
|
|
19439
|
+
name: "publicIp",
|
|
19440
|
+
value: publicIp
|
|
19441
|
+
}, {
|
|
19442
|
+
name: "allocationId",
|
|
19443
|
+
value: allocationId
|
|
19444
|
+
}], options);
|
|
19306
19445
|
}
|
|
19307
19446
|
parseEipPhysicalId(physicalId) {
|
|
19308
19447
|
if (physicalId.includes("|")) {
|
|
@@ -19317,14 +19456,16 @@ var EC2Provider = class {
|
|
|
19317
19456
|
}
|
|
19318
19457
|
async createEip(logicalId, resourceType, properties, context) {
|
|
19319
19458
|
this.logger.debug(`Creating EIP ${logicalId}`);
|
|
19459
|
+
let allocationId;
|
|
19460
|
+
let publicIp;
|
|
19320
19461
|
try {
|
|
19321
19462
|
const response = await this.ec2Client.send(new AllocateAddressCommand({
|
|
19322
19463
|
Domain: requireConfigString(properties["Domain"], "vpc", "AWS::EC2::EIP Domain", replayWarn(this.logger, context)),
|
|
19323
19464
|
NetworkBorderGroup: properties["NetworkBorderGroup"],
|
|
19324
19465
|
PublicIpv4Pool: properties["PublicIpv4Pool"]
|
|
19325
19466
|
}));
|
|
19326
|
-
|
|
19327
|
-
|
|
19467
|
+
allocationId = response.AllocationId;
|
|
19468
|
+
publicIp = response.PublicIp;
|
|
19328
19469
|
await this.applyTags(allocationId, properties, logicalId);
|
|
19329
19470
|
const instanceId = properties["InstanceId"];
|
|
19330
19471
|
if (instanceId) if (process.env["CDKD_NO_WAIT"] === "true") this.logger.warn(`EIP ${logicalId} (${allocationId}) was NOT associated with ${instanceId}: --no-wait skips the instance running-state wait, and AssociateAddress rejects an instance that is not yet running. Verify and associate once the instance is running: aws ec2 describe-instances --instance-ids ${instanceId} --query 'Reservations[].Instances[].State.Name' && aws ec2 associate-address --allocation-id ${allocationId} --instance-id ${instanceId}`);
|
|
@@ -19336,17 +19477,17 @@ var EC2Provider = class {
|
|
|
19336
19477
|
this.logger.debug(`Associated EIP ${logicalId} (${allocationId}) to ${instanceId}`);
|
|
19337
19478
|
}
|
|
19338
19479
|
this.logger.debug(`Successfully created EIP ${logicalId}: ${allocationId} (${publicIp})`);
|
|
19339
|
-
return {
|
|
19340
|
-
physicalId: this.eipPhysicalId(publicIp, allocationId),
|
|
19341
|
-
attributes: {
|
|
19342
|
-
AllocationId: allocationId,
|
|
19343
|
-
PublicIp: publicIp
|
|
19344
|
-
}
|
|
19345
|
-
};
|
|
19346
19480
|
} catch (error) {
|
|
19347
19481
|
const cause = error instanceof Error ? error : void 0;
|
|
19348
19482
|
throw new ProvisioningError(`Failed to create EIP ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
19349
19483
|
}
|
|
19484
|
+
return {
|
|
19485
|
+
physicalId: this.eipPhysicalId(logicalId, publicIp, allocationId, context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0),
|
|
19486
|
+
attributes: {
|
|
19487
|
+
AllocationId: allocationId,
|
|
19488
|
+
PublicIp: publicIp
|
|
19489
|
+
}
|
|
19490
|
+
};
|
|
19350
19491
|
}
|
|
19351
19492
|
async updateEip(logicalId, physicalId, properties, previousProperties) {
|
|
19352
19493
|
this.logger.debug(`Updating EIP ${logicalId}: ${physicalId}`);
|
|
@@ -19412,17 +19553,23 @@ var EC2Provider = class {
|
|
|
19412
19553
|
default: return;
|
|
19413
19554
|
}
|
|
19414
19555
|
}
|
|
19415
|
-
async createVpcGatewayAttachment(logicalId, resourceType, properties) {
|
|
19556
|
+
async createVpcGatewayAttachment(logicalId, resourceType, properties, context) {
|
|
19416
19557
|
this.logger.debug(`Creating VPCGatewayAttachment ${logicalId}`);
|
|
19417
19558
|
const vpcId = properties["VpcId"];
|
|
19418
19559
|
const internetGatewayId = properties["InternetGatewayId"];
|
|
19419
19560
|
if (!vpcId || !internetGatewayId) throw new ProvisioningError(`VpcId and InternetGatewayId are required for VPCGatewayAttachment ${logicalId}`, resourceType, logicalId);
|
|
19561
|
+
const physicalId = packCompositeId(resourceType, logicalId, [{
|
|
19562
|
+
name: "internetGatewayId",
|
|
19563
|
+
value: internetGatewayId
|
|
19564
|
+
}, {
|
|
19565
|
+
name: "vpcId",
|
|
19566
|
+
value: vpcId
|
|
19567
|
+
}], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
|
|
19420
19568
|
try {
|
|
19421
19569
|
await this.ec2Client.send(new AttachInternetGatewayCommand({
|
|
19422
19570
|
VpcId: vpcId,
|
|
19423
19571
|
InternetGatewayId: internetGatewayId
|
|
19424
19572
|
}));
|
|
19425
|
-
const physicalId = `${internetGatewayId}|${vpcId}`;
|
|
19426
19573
|
this.logger.debug(`Successfully created VPCGatewayAttachment ${logicalId}: ${physicalId}`);
|
|
19427
19574
|
return {
|
|
19428
19575
|
physicalId,
|
|
@@ -19574,6 +19721,13 @@ var EC2Provider = class {
|
|
|
19574
19721
|
onMultipleDestinations(`${message} Continuing with ${usedKey} and ignoring the rest.`);
|
|
19575
19722
|
} else throw new ProvisioningError(message, resourceType, logicalId);
|
|
19576
19723
|
}
|
|
19724
|
+
const physicalId = packCompositeId(resourceType, logicalId, [{
|
|
19725
|
+
name: "routeTableId",
|
|
19726
|
+
value: routeTableId
|
|
19727
|
+
}, {
|
|
19728
|
+
name: "destination",
|
|
19729
|
+
value: destination
|
|
19730
|
+
}], onMultipleDestinations ? { onRefusal: onMultipleDestinations } : void 0);
|
|
19577
19731
|
try {
|
|
19578
19732
|
await this.ec2Client.send(new CreateRouteCommand({
|
|
19579
19733
|
RouteTableId: routeTableId,
|
|
@@ -19590,7 +19744,6 @@ var EC2Provider = class {
|
|
|
19590
19744
|
VpcEndpointId: properties["VpcEndpointId"] ?? void 0,
|
|
19591
19745
|
VpcPeeringConnectionId: properties["VpcPeeringConnectionId"] ?? void 0
|
|
19592
19746
|
}));
|
|
19593
|
-
const physicalId = `${routeTableId}|${destination}`;
|
|
19594
19747
|
this.logger.debug(`Successfully created Route ${logicalId}: ${physicalId}`);
|
|
19595
19748
|
return {
|
|
19596
19749
|
physicalId,
|
|
@@ -19901,6 +20054,24 @@ var EC2Provider = class {
|
|
|
19901
20054
|
const effectiveProperties = narrowed === properties ? void 0 : narrowed;
|
|
19902
20055
|
const fromPort = properties["FromPort"];
|
|
19903
20056
|
const toPort = properties["ToPort"];
|
|
20057
|
+
const physicalId = packCompositeId(resourceType, logicalId, [
|
|
20058
|
+
{
|
|
20059
|
+
name: "groupId",
|
|
20060
|
+
value: groupId
|
|
20061
|
+
},
|
|
20062
|
+
{
|
|
20063
|
+
name: "ipProtocol",
|
|
20064
|
+
value: ipProtocol
|
|
20065
|
+
},
|
|
20066
|
+
{
|
|
20067
|
+
name: "fromPort",
|
|
20068
|
+
value: fromPort ?? "-1"
|
|
20069
|
+
},
|
|
20070
|
+
{
|
|
20071
|
+
name: "toPort",
|
|
20072
|
+
value: toPort ?? "-1"
|
|
20073
|
+
}
|
|
20074
|
+
], onUnusableProtocol ? { onRefusal: onUnusableProtocol } : void 0);
|
|
19904
20075
|
try {
|
|
19905
20076
|
await this.ec2Client.send(new AuthorizeSecurityGroupIngressCommand({
|
|
19906
20077
|
GroupId: groupId,
|
|
@@ -19909,7 +20080,6 @@ var EC2Provider = class {
|
|
|
19909
20080
|
IpProtocol: ipProtocol
|
|
19910
20081
|
}]
|
|
19911
20082
|
}));
|
|
19912
|
-
const physicalId = `${groupId}|${ipProtocol}|${fromPort ?? "-1"}|${toPort ?? "-1"}`;
|
|
19913
20083
|
this.logger.debug(`Successfully created SecurityGroupIngress ${logicalId}: ${physicalId}`);
|
|
19914
20084
|
return {
|
|
19915
20085
|
physicalId,
|
|
@@ -19918,7 +20088,6 @@ var EC2Provider = class {
|
|
|
19918
20088
|
};
|
|
19919
20089
|
} catch (error) {
|
|
19920
20090
|
if (error instanceof Error && error.message.includes("already exists")) {
|
|
19921
|
-
const physicalId = `${groupId}|${ipProtocol}|${fromPort ?? "-1"}|${toPort ?? "-1"}`;
|
|
19922
20091
|
this.logger.debug(`SecurityGroupIngress ${logicalId} already exists, treating as success`);
|
|
19923
20092
|
return {
|
|
19924
20093
|
physicalId,
|
|
@@ -20586,7 +20755,7 @@ var EC2Provider = class {
|
|
|
20586
20755
|
throw new ProvisioningError(`Failed to delete NetworkAcl ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
20587
20756
|
}
|
|
20588
20757
|
}
|
|
20589
|
-
async createNetworkAclEntry(logicalId, resourceType, properties) {
|
|
20758
|
+
async createNetworkAclEntry(logicalId, resourceType, properties, context) {
|
|
20590
20759
|
this.logger.debug(`Creating NetworkAclEntry ${logicalId}`);
|
|
20591
20760
|
const networkAclId = properties["NetworkAclId"];
|
|
20592
20761
|
const ruleNumber = properties["RuleNumber"];
|
|
@@ -20594,6 +20763,20 @@ var EC2Provider = class {
|
|
|
20594
20763
|
const ruleAction = properties["RuleAction"];
|
|
20595
20764
|
const egress = properties["Egress"] ?? false;
|
|
20596
20765
|
if (!networkAclId || ruleNumber === void 0 || protocol === void 0 || !ruleAction) throw new ProvisioningError(`NetworkAclId, RuleNumber, Protocol, and RuleAction are required for NetworkAclEntry ${logicalId}`, resourceType, logicalId);
|
|
20766
|
+
const physicalId = packCompositeId(resourceType, logicalId, [
|
|
20767
|
+
{
|
|
20768
|
+
name: "networkAclId",
|
|
20769
|
+
value: networkAclId
|
|
20770
|
+
},
|
|
20771
|
+
{
|
|
20772
|
+
name: "ruleNumber",
|
|
20773
|
+
value: ruleNumber
|
|
20774
|
+
},
|
|
20775
|
+
{
|
|
20776
|
+
name: "egress",
|
|
20777
|
+
value: egress
|
|
20778
|
+
}
|
|
20779
|
+
], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
|
|
20597
20780
|
try {
|
|
20598
20781
|
const cidrBlock = properties["CidrBlock"];
|
|
20599
20782
|
const ipv6CidrBlock = properties["Ipv6CidrBlock"];
|
|
@@ -20616,7 +20799,6 @@ var EC2Provider = class {
|
|
|
20616
20799
|
Type: icmpTypeCode["Type"]
|
|
20617
20800
|
} : void 0
|
|
20618
20801
|
}));
|
|
20619
|
-
const physicalId = `${networkAclId}|${ruleNumber}|${egress}`;
|
|
20620
20802
|
this.logger.debug(`Successfully created NetworkAclEntry ${logicalId}: ${physicalId}`);
|
|
20621
20803
|
return {
|
|
20622
20804
|
physicalId,
|
|
@@ -20875,7 +21057,7 @@ var EC2Provider = class {
|
|
|
20875
21057
|
* physical-name property instead.
|
|
20876
21058
|
*/
|
|
20877
21059
|
async import(input) {
|
|
20878
|
-
if (input.knownPhysicalId) return this.verifyExplicit(input.resourceType, input.knownPhysicalId);
|
|
21060
|
+
if (input.knownPhysicalId) return this.verifyExplicit(input.logicalId, input.resourceType, input.knownPhysicalId);
|
|
20879
21061
|
return null;
|
|
20880
21062
|
}
|
|
20881
21063
|
/**
|
|
@@ -21436,7 +21618,7 @@ var EC2Provider = class {
|
|
|
21436
21618
|
}
|
|
21437
21619
|
}
|
|
21438
21620
|
}
|
|
21439
|
-
async verifyExplicit(resourceType, physicalId) {
|
|
21621
|
+
async verifyExplicit(logicalId, resourceType, physicalId) {
|
|
21440
21622
|
try {
|
|
21441
21623
|
switch (resourceType) {
|
|
21442
21624
|
case "AWS::EC2::VPC": return (await this.ec2Client.send(new DescribeVpcsCommand({ VpcIds: [physicalId] }))).Vpcs?.[0] ? {
|
|
@@ -21460,8 +21642,19 @@ var EC2Provider = class {
|
|
|
21460
21642
|
const filter = allocationId ? { AllocationIds: [allocationId] } : { PublicIps: publicIp ? [publicIp] : [] };
|
|
21461
21643
|
const addr = (await this.ec2Client.send(new DescribeAddressesCommand(filter))).Addresses?.[0];
|
|
21462
21644
|
if (!addr?.AllocationId || !addr.PublicIp) return null;
|
|
21645
|
+
const eipRefusal = compositeIdSeparatorRefusal("AWS::EC2::EIP", logicalId, [{
|
|
21646
|
+
name: "publicIp",
|
|
21647
|
+
value: addr.PublicIp
|
|
21648
|
+
}, {
|
|
21649
|
+
name: "allocationId",
|
|
21650
|
+
value: addr.AllocationId
|
|
21651
|
+
}]);
|
|
21652
|
+
if (eipRefusal !== void 0) {
|
|
21653
|
+
this.logger.warn(`${eipRefusal} Skipping import.`);
|
|
21654
|
+
return null;
|
|
21655
|
+
}
|
|
21463
21656
|
return {
|
|
21464
|
-
physicalId: this.eipPhysicalId(addr.PublicIp, addr.AllocationId),
|
|
21657
|
+
physicalId: this.eipPhysicalId(logicalId, addr.PublicIp, addr.AllocationId),
|
|
21465
21658
|
attributes: {
|
|
21466
21659
|
AllocationId: addr.AllocationId,
|
|
21467
21660
|
PublicIp: addr.PublicIp
|
|
@@ -22468,6 +22661,20 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
22468
22661
|
const requestValidatorId = properties["RequestValidatorId"];
|
|
22469
22662
|
const authorizationScopes = properties["AuthorizationScopes"];
|
|
22470
22663
|
if (!restApiId || !resourceId || !httpMethod) throw new ProvisioningError(`RestApiId, ResourceId, and HttpMethod are required for API Gateway Method ${logicalId}`, resourceType, logicalId);
|
|
22664
|
+
const physicalId = packCompositeId(resourceType, logicalId, [
|
|
22665
|
+
{
|
|
22666
|
+
name: "restApiId",
|
|
22667
|
+
value: restApiId
|
|
22668
|
+
},
|
|
22669
|
+
{
|
|
22670
|
+
name: "resourceId",
|
|
22671
|
+
value: resourceId
|
|
22672
|
+
},
|
|
22673
|
+
{
|
|
22674
|
+
name: "httpMethod",
|
|
22675
|
+
value: httpMethod
|
|
22676
|
+
}
|
|
22677
|
+
], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
|
|
22471
22678
|
try {
|
|
22472
22679
|
await this.apiGatewayClient.send(new PutMethodCommand({
|
|
22473
22680
|
restApiId,
|
|
@@ -22545,7 +22752,6 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
22545
22752
|
}
|
|
22546
22753
|
throw innerError;
|
|
22547
22754
|
}
|
|
22548
|
-
const physicalId = `${restApiId}|${resourceId}|${httpMethod}`;
|
|
22549
22755
|
this.logger.debug(`Successfully created API Gateway Method ${logicalId}: ${physicalId}`);
|
|
22550
22756
|
return {
|
|
22551
22757
|
physicalId,
|
|
@@ -33306,6 +33512,47 @@ function normalizeRecordName(name) {
|
|
|
33306
33512
|
return lowered.endsWith(".") ? lowered : `${lowered}.`;
|
|
33307
33513
|
}
|
|
33308
33514
|
/**
|
|
33515
|
+
* Is this value ONLY an unresolved intrinsic — `{Ref: …}` / `{Fn::If: […]}` —
|
|
33516
|
+
* rather than a real object with members?
|
|
33517
|
+
*
|
|
33518
|
+
* `import.ts` substitutes only single-key `{Ref}` before calling a provider,
|
|
33519
|
+
* so an element behind a condition reaches `import()` in this shape.
|
|
33520
|
+
*/
|
|
33521
|
+
function isIntrinsicOnly(value) {
|
|
33522
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
33523
|
+
const keys = Object.keys(value);
|
|
33524
|
+
return keys.length === 1 && (keys[0] === "Ref" || (keys[0] ?? "").startsWith("Fn::"));
|
|
33525
|
+
}
|
|
33526
|
+
/**
|
|
33527
|
+
* Read a hosted zone's PUBLIC-vs-PRIVATE visibility off its own template
|
|
33528
|
+
* properties (issue #1702), for the `import()` name lookup's zone filter.
|
|
33529
|
+
*
|
|
33530
|
+
* CloudFormation has no `PrivateZone` property — visibility is implied by
|
|
33531
|
+
* `VPCs`: a zone associated with at least one VPC is private, one with none is
|
|
33532
|
+
* public. So:
|
|
33533
|
+
*
|
|
33534
|
+
* - `VPCs` ABSENT -> `false` (public). This is the CDK `PublicHostedZone`
|
|
33535
|
+
* shape and by far the common one.
|
|
33536
|
+
* - an array carrying at least one element that is NOT purely an unresolved
|
|
33537
|
+
* intrinsic -> `true` (private). Such an element proves the template
|
|
33538
|
+
* attaches a VPC unconditionally, even when the `VPCId` inside it is itself
|
|
33539
|
+
* a `Ref` this provider cannot resolve.
|
|
33540
|
+
* - anything else -> `undefined` (do not narrow), and the caller's ambiguity
|
|
33541
|
+
* guard then refuses rather than adopting the wrong zone. Three shapes land
|
|
33542
|
+
* here and each would otherwise be a GUESS: a non-array (an unresolved
|
|
33543
|
+
* intrinsic is a truthy OBJECT); an EMPTY array (more likely a
|
|
33544
|
+
* condition-collapsed value than a deliberate "public"); and — the one that
|
|
33545
|
+
* is easy to miss — an array whose every element is intrinsic-only
|
|
33546
|
+
* (`[{Ref: 'AWS::NoValue'}]`, the CFn spelling of a conditionally-absent
|
|
33547
|
+
* element), which is non-empty yet may resolve to a PUBLIC zone.
|
|
33548
|
+
*/
|
|
33549
|
+
function templateZoneVisibility(properties) {
|
|
33550
|
+
const vpcs = properties["VPCs"];
|
|
33551
|
+
if (vpcs == null) return false;
|
|
33552
|
+
if (!Array.isArray(vpcs)) return void 0;
|
|
33553
|
+
return vpcs.some((v) => typeof v === "object" && v !== null && !Array.isArray(v) && !isIntrinsicOnly(v)) ? true : void 0;
|
|
33554
|
+
}
|
|
33555
|
+
/**
|
|
33309
33556
|
* Canonicalize a name for the QUERY side of a Route 53 list call.
|
|
33310
33557
|
*
|
|
33311
33558
|
* `normalizeRecordName` above is the COMPARE-side canonicalizer, and the two
|
|
@@ -34025,12 +34272,33 @@ var Route53Provider = class {
|
|
|
34025
34272
|
* Resolve HostedZoneId from properties.
|
|
34026
34273
|
* If HostedZoneId is provided, use it directly.
|
|
34027
34274
|
* If HostedZoneName is provided, resolve it to a HostedZoneId via ListHostedZonesByName.
|
|
34275
|
+
*
|
|
34276
|
+
* `options.requirePrivateZone` narrows the name match to PRIVATE (`true`) or
|
|
34277
|
+
* PUBLIC (`false`) zones before the ambiguity decision below; leave it
|
|
34278
|
+
* undefined to match either. Split-horizon DNS is exactly a public and a
|
|
34279
|
+
* private zone sharing one name, so a caller that already knows which side
|
|
34280
|
+
* it wants resolves cleanly where the ambiguity guard would otherwise
|
|
34281
|
+
* refuse. `importHostedZone` is the one caller today, deriving the answer
|
|
34282
|
+
* from the template's own `VPCs` (declared = private, absent = public);
|
|
34283
|
+
* every RecordSet caller leaves it undefined, since a record set's template
|
|
34284
|
+
* says nothing about the zone's visibility.
|
|
34285
|
+
*
|
|
34286
|
+
* `options.subject` names what is being resolved FOR in the errors this
|
|
34287
|
+
* raises, and what remedy to point at. It exists because the messages are
|
|
34288
|
+
* user-facing and this helper is no longer RecordSet-only: telling someone
|
|
34289
|
+
* adopting a hosted zone to "pass the '<zoneId>|<name>|<type>' composite"
|
|
34290
|
+
* names a physicalId shape their resource does not have.
|
|
34028
34291
|
*/
|
|
34029
34292
|
async resolveHostedZoneId(properties, logicalId, resourceType, physicalId, options) {
|
|
34293
|
+
const subject = options?.subject ?? {
|
|
34294
|
+
noun: "record set",
|
|
34295
|
+
remedy: "set HostedZoneId explicitly, or pass the '<zoneId>|<name>|<type>' composite via --resource"
|
|
34296
|
+
};
|
|
34030
34297
|
const hostedZoneId = properties["HostedZoneId"];
|
|
34031
34298
|
if (typeof hostedZoneId === "string" && hostedZoneId) return hostedZoneId;
|
|
34032
34299
|
let lookupErrorMessage;
|
|
34033
34300
|
let lookupErrorCause;
|
|
34301
|
+
const narrowing = options?.requirePrivateZone !== void 0;
|
|
34034
34302
|
const hostedZoneName = properties["HostedZoneName"];
|
|
34035
34303
|
if (typeof hostedZoneName === "string" && hostedZoneName) {
|
|
34036
34304
|
let matched = [];
|
|
@@ -34043,18 +34311,26 @@ var Route53Provider = class {
|
|
|
34043
34311
|
const zones = response.HostedZones ?? [];
|
|
34044
34312
|
const normalizedName = normalizeRecordName(hostedZoneName);
|
|
34045
34313
|
matched = zones.filter((z) => normalizeRecordName(z.Name ?? "") === normalizedName);
|
|
34046
|
-
|
|
34314
|
+
if (narrowing) matched = matched.filter((z) => (z.Config?.PrivateZone ?? false) === options?.requirePrivateZone);
|
|
34315
|
+
const sawLaterName = zones.some((z) => normalizeRecordName(z.Name ?? "") !== normalizedName);
|
|
34316
|
+
absenceIsSound = !hostedZoneName.includes("\\") && (narrowing ? sawLaterName || response.IsTruncated !== true : zones.length > 0 || response.IsTruncated !== true);
|
|
34047
34317
|
} catch (error) {
|
|
34048
34318
|
lookupErrorMessage = error instanceof Error ? error.message : String(error);
|
|
34049
34319
|
lookupErrorCause = error instanceof Error ? error : void 0;
|
|
34050
34320
|
this.logger.warn(`Failed to resolve HostedZoneName "${hostedZoneName}" for ${logicalId}: ${lookupErrorMessage}`);
|
|
34051
34321
|
}
|
|
34052
|
-
if (matched.length > 1 && options?.requireUnambiguousZoneName)
|
|
34322
|
+
if (matched.length > 1 && options?.requireUnambiguousZoneName) {
|
|
34323
|
+
const cause = narrowing ? "" : " (split-horizon public/private DNS)";
|
|
34324
|
+
throw new ProvisioningError(`HostedZoneName "${hostedZoneName}" matches ${matched.length} hosted zones for ${logicalId}${cause}. Refusing to guess which one is meant — ${subject.remedy}.`, resourceType, logicalId, physicalId);
|
|
34325
|
+
}
|
|
34053
34326
|
const matchedZone = matched[0];
|
|
34054
34327
|
if (matchedZone?.Id) return matchedZone.Id.replace("/hostedzone/", "");
|
|
34055
|
-
if (absenceIsSound)
|
|
34328
|
+
if (absenceIsSound) {
|
|
34329
|
+
const visibility = options?.requirePrivateZone === void 0 ? "" : options.requirePrivateZone ? "private " : "public ";
|
|
34330
|
+
throw new HostedZoneNameNotFoundError(`HostedZoneName "${hostedZoneName}" matches no ${visibility}hosted zone in this account/region for ${logicalId}`, resourceType, logicalId, physicalId);
|
|
34331
|
+
}
|
|
34056
34332
|
}
|
|
34057
|
-
throw new ProvisioningError(lookupErrorMessage ? `Could not resolve HostedZoneName "${String(hostedZoneName)}" for
|
|
34333
|
+
throw new ProvisioningError(lookupErrorMessage ? `Could not resolve HostedZoneName "${String(hostedZoneName)}" for ${subject.noun} ${logicalId}: ${lookupErrorMessage}` : typeof hostedZoneName === "string" && hostedZoneName ? `Could not determine whether HostedZoneName "${hostedZoneName}" exists for ${subject.noun} ${logicalId} — the hosted-zone listing ended before the name could be resolved either way, so cdkd will not assume it is absent. ${subject.remedy}.` : `Either HostedZoneId or HostedZoneName is required for ${subject.noun} ${logicalId}`, resourceType, logicalId, physicalId, lookupErrorCause);
|
|
34058
34334
|
}
|
|
34059
34335
|
/**
|
|
34060
34336
|
* Recover `(hostedZoneId, name, type)` for a record set from EITHER shape of
|
|
@@ -34232,8 +34508,10 @@ var Route53Provider = class {
|
|
|
34232
34508
|
/**
|
|
34233
34509
|
* Adopt an existing Route 53 resource into cdkd state.
|
|
34234
34510
|
*
|
|
34235
|
-
* Supported types: `AWS::Route53::HostedZone` (
|
|
34236
|
-
* `
|
|
34511
|
+
* Supported types: `AWS::Route53::HostedZone` (AUTO-RESOLVED from the
|
|
34512
|
+
* template's `Name` since issue #1702, with an explicit `--resource`
|
|
34513
|
+
* override still taking precedence);
|
|
34514
|
+
* `AWS::Route53::RecordSet` (override-only — the supplied id is
|
|
34237
34515
|
* CANONICALIZED rather than trusted, using the template's
|
|
34238
34516
|
* `HostedZoneId` / `HostedZoneName` + `Name` + `Type` and verified
|
|
34239
34517
|
* against AWS, but an import with no override still declines because
|
|
@@ -34315,6 +34593,29 @@ var Route53Provider = class {
|
|
|
34315
34593
|
attributes: {}
|
|
34316
34594
|
};
|
|
34317
34595
|
}
|
|
34596
|
+
/**
|
|
34597
|
+
* Adopt an existing hosted zone (issue #1702).
|
|
34598
|
+
*
|
|
34599
|
+
* An explicit `--resource` id is ground truth and is only VERIFIED. With no
|
|
34600
|
+
* override, the zone is resolved from the template's `Name` via
|
|
34601
|
+
* `ListHostedZonesByName` — the physical-name route docs/import.md's
|
|
34602
|
+
* Auto-resolved section documents, which this method declined to take until
|
|
34603
|
+
* now, so a type the table listed as auto-resolved silently reported
|
|
34604
|
+
* `skipped-not-found` and (under `--migrate-from-cloudformation`) was left
|
|
34605
|
+
* out of state after the CloudFormation stack had already been retired.
|
|
34606
|
+
*
|
|
34607
|
+
* Three properties of the lookup matter and none of them is incidental:
|
|
34608
|
+
* the query name is canonicalized to AWS's ordering key
|
|
34609
|
+
* (`canonicalizeQueryName`) so a bounded page cannot skip past the zone; a
|
|
34610
|
+
* name matching MORE than one zone is REFUSED rather than guessed at
|
|
34611
|
+
* (split-horizon DNS), except that the template's own `VPCs` first narrows
|
|
34612
|
+
* the match to the public or private side (`templateZoneVisibility`), which
|
|
34613
|
+
* is what makes the ordinary split-horizon pair resolve cleanly; and the
|
|
34614
|
+
* two ways of failing are kept DISTINCT — a proven absence returns `null`
|
|
34615
|
+
* (`skipped-not-found`, the next deploy creates the zone) while an
|
|
34616
|
+
* ambiguous name or a failed lookup throws, which `importOne` records as
|
|
34617
|
+
* `failed` for this row alone.
|
|
34618
|
+
*/
|
|
34318
34619
|
async importHostedZone(input) {
|
|
34319
34620
|
if (input.knownPhysicalId) try {
|
|
34320
34621
|
await this.getClient().send(new GetHostedZoneCommand({ Id: input.knownPhysicalId }));
|
|
@@ -34326,7 +34627,24 @@ var Route53Provider = class {
|
|
|
34326
34627
|
if (err instanceof Error && err.name === "NoSuchHostedZone") return null;
|
|
34327
34628
|
throw err;
|
|
34328
34629
|
}
|
|
34329
|
-
|
|
34630
|
+
const zoneName = input.properties["Name"];
|
|
34631
|
+
if (typeof zoneName !== "string" || !zoneName) return null;
|
|
34632
|
+
try {
|
|
34633
|
+
return {
|
|
34634
|
+
physicalId: await this.resolveHostedZoneId({ HostedZoneName: zoneName }, input.logicalId, input.resourceType, void 0, {
|
|
34635
|
+
requireUnambiguousZoneName: true,
|
|
34636
|
+
requirePrivateZone: templateZoneVisibility(input.properties),
|
|
34637
|
+
subject: {
|
|
34638
|
+
noun: "hosted zone",
|
|
34639
|
+
remedy: `pass --resource ${input.logicalId}=<hostedZoneId> to adopt it explicitly`
|
|
34640
|
+
}
|
|
34641
|
+
}),
|
|
34642
|
+
attributes: {}
|
|
34643
|
+
};
|
|
34644
|
+
} catch (error) {
|
|
34645
|
+
if (error instanceof HostedZoneNameNotFoundError) return null;
|
|
34646
|
+
throw error;
|
|
34647
|
+
}
|
|
34330
34648
|
}
|
|
34331
34649
|
};
|
|
34332
34650
|
|
|
@@ -36399,9 +36717,9 @@ var AppSyncProvider = class {
|
|
|
36399
36717
|
switch (resourceType) {
|
|
36400
36718
|
case "AWS::AppSync::GraphQLApi": return this.createGraphQLApi(logicalId, resourceType, properties, context);
|
|
36401
36719
|
case "AWS::AppSync::GraphQLSchema": return this.createGraphQLSchema(logicalId, resourceType, properties);
|
|
36402
|
-
case "AWS::AppSync::DataSource": return this.createDataSource(logicalId, resourceType, properties);
|
|
36403
|
-
case "AWS::AppSync::Resolver": return this.createResolver(logicalId, resourceType, properties);
|
|
36404
|
-
case "AWS::AppSync::ApiKey": return this.createApiKey(logicalId, resourceType, properties);
|
|
36720
|
+
case "AWS::AppSync::DataSource": return this.createDataSource(logicalId, resourceType, properties, context);
|
|
36721
|
+
case "AWS::AppSync::Resolver": return this.createResolver(logicalId, resourceType, properties, context);
|
|
36722
|
+
case "AWS::AppSync::ApiKey": return this.createApiKey(logicalId, resourceType, properties, context);
|
|
36405
36723
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
|
|
36406
36724
|
}
|
|
36407
36725
|
}
|
|
@@ -37315,12 +37633,19 @@ var AppSyncProvider = class {
|
|
|
37315
37633
|
throw new ProvisioningError(`Failed to create GraphQL Schema ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
37316
37634
|
}
|
|
37317
37635
|
}
|
|
37318
|
-
async createDataSource(logicalId, resourceType, properties) {
|
|
37636
|
+
async createDataSource(logicalId, resourceType, properties, context) {
|
|
37319
37637
|
this.logger.debug(`Creating DataSource ${logicalId}`);
|
|
37320
37638
|
const apiId = properties["ApiId"];
|
|
37321
37639
|
const name = properties["Name"];
|
|
37322
37640
|
const type = properties["Type"];
|
|
37323
37641
|
if (!apiId || !name || !type) throw new ProvisioningError(`ApiId, Name, and Type are required for DataSource ${logicalId}`, resourceType, logicalId);
|
|
37642
|
+
const physicalId = packCompositeId(resourceType, logicalId, [{
|
|
37643
|
+
name: "apiId",
|
|
37644
|
+
value: apiId
|
|
37645
|
+
}, {
|
|
37646
|
+
name: "name",
|
|
37647
|
+
value: name
|
|
37648
|
+
}], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
|
|
37324
37649
|
try {
|
|
37325
37650
|
const input = {
|
|
37326
37651
|
apiId,
|
|
@@ -37329,7 +37654,6 @@ var AppSyncProvider = class {
|
|
|
37329
37654
|
};
|
|
37330
37655
|
this.applyDataSourceConfig(input, resourceType, logicalId, properties);
|
|
37331
37656
|
await this.getClient().send(new CreateDataSourceCommand(input));
|
|
37332
|
-
const physicalId = `${apiId}|${name}`;
|
|
37333
37657
|
this.logger.debug(`Successfully created DataSource ${logicalId}: ${physicalId}`);
|
|
37334
37658
|
return {
|
|
37335
37659
|
physicalId,
|
|
@@ -37366,12 +37690,26 @@ var AppSyncProvider = class {
|
|
|
37366
37690
|
throw new ProvisioningError(`Failed to delete DataSource ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
37367
37691
|
}
|
|
37368
37692
|
}
|
|
37369
|
-
async createResolver(logicalId, resourceType, properties) {
|
|
37693
|
+
async createResolver(logicalId, resourceType, properties, context) {
|
|
37370
37694
|
this.logger.debug(`Creating Resolver ${logicalId}`);
|
|
37371
37695
|
const apiId = properties["ApiId"];
|
|
37372
37696
|
const typeName = properties["TypeName"];
|
|
37373
37697
|
const fieldName = properties["FieldName"];
|
|
37374
37698
|
if (!apiId || !typeName || !fieldName) throw new ProvisioningError(`ApiId, TypeName, and FieldName are required for Resolver ${logicalId}`, resourceType, logicalId);
|
|
37699
|
+
const physicalId = packCompositeId(resourceType, logicalId, [
|
|
37700
|
+
{
|
|
37701
|
+
name: "apiId",
|
|
37702
|
+
value: apiId
|
|
37703
|
+
},
|
|
37704
|
+
{
|
|
37705
|
+
name: "typeName",
|
|
37706
|
+
value: typeName
|
|
37707
|
+
},
|
|
37708
|
+
{
|
|
37709
|
+
name: "fieldName",
|
|
37710
|
+
value: fieldName
|
|
37711
|
+
}
|
|
37712
|
+
], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
|
|
37375
37713
|
try {
|
|
37376
37714
|
const input = {
|
|
37377
37715
|
apiId,
|
|
@@ -37380,7 +37718,6 @@ var AppSyncProvider = class {
|
|
|
37380
37718
|
};
|
|
37381
37719
|
await this.applyResolverConfig(input, resourceType, logicalId, properties);
|
|
37382
37720
|
await this.getClient().send(new CreateResolverCommand(input));
|
|
37383
|
-
const physicalId = `${apiId}|${typeName}|${fieldName}`;
|
|
37384
37721
|
this.logger.debug(`Successfully created Resolver ${logicalId}: ${physicalId}`);
|
|
37385
37722
|
return {
|
|
37386
37723
|
physicalId,
|
|
@@ -37416,28 +37753,34 @@ var AppSyncProvider = class {
|
|
|
37416
37753
|
throw new ProvisioningError(`Failed to delete Resolver ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
37417
37754
|
}
|
|
37418
37755
|
}
|
|
37419
|
-
async createApiKey(logicalId, resourceType, properties) {
|
|
37756
|
+
async createApiKey(logicalId, resourceType, properties, context) {
|
|
37420
37757
|
this.logger.debug(`Creating ApiKey ${logicalId}`);
|
|
37421
37758
|
const apiId = properties["ApiId"];
|
|
37422
37759
|
if (!apiId) throw new ProvisioningError(`ApiId is required for ApiKey ${logicalId}`, resourceType, logicalId);
|
|
37760
|
+
let apiKeyId;
|
|
37423
37761
|
try {
|
|
37424
37762
|
const input = { apiId };
|
|
37425
37763
|
if (properties["Description"]) input.description = properties["Description"];
|
|
37426
37764
|
if (properties["Expires"]) input.expires = properties["Expires"];
|
|
37427
|
-
|
|
37428
|
-
const apiKeyId = response.apiKey.id;
|
|
37765
|
+
apiKeyId = (await this.getClient().send(new CreateApiKeyCommand(input))).apiKey.id;
|
|
37429
37766
|
this.logger.debug(`Successfully created ApiKey ${logicalId}: ${apiKeyId}`);
|
|
37430
|
-
return {
|
|
37431
|
-
physicalId: `${apiId}|${apiKeyId}`,
|
|
37432
|
-
attributes: {
|
|
37433
|
-
ApiKey: response.apiKey.id,
|
|
37434
|
-
Arn: `arn:aws:appsync:*:*:apis/${apiId}/apikeys/${apiKeyId}`
|
|
37435
|
-
}
|
|
37436
|
-
};
|
|
37437
37767
|
} catch (error) {
|
|
37438
37768
|
const cause = error instanceof Error ? error : void 0;
|
|
37439
37769
|
throw new ProvisioningError(`Failed to create ApiKey ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
37440
37770
|
}
|
|
37771
|
+
return {
|
|
37772
|
+
physicalId: packCompositeId(resourceType, logicalId, [{
|
|
37773
|
+
name: "apiId",
|
|
37774
|
+
value: apiId
|
|
37775
|
+
}, {
|
|
37776
|
+
name: "apiKeyId",
|
|
37777
|
+
value: apiKeyId
|
|
37778
|
+
}], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0),
|
|
37779
|
+
attributes: {
|
|
37780
|
+
ApiKey: apiKeyId,
|
|
37781
|
+
Arn: `arn:aws:appsync:*:*:apis/${apiId}/apikeys/${apiKeyId}`
|
|
37782
|
+
}
|
|
37783
|
+
};
|
|
37441
37784
|
}
|
|
37442
37785
|
async deleteApiKey(logicalId, physicalId, resourceType, context) {
|
|
37443
37786
|
this.logger.debug(`Deleting ApiKey ${logicalId}: ${physicalId}`);
|
|
@@ -38097,6 +38440,13 @@ var GlueProvider = class {
|
|
|
38097
38440
|
replayingState: context?.replayingState === true
|
|
38098
38441
|
});
|
|
38099
38442
|
const openTableFormatInput = properties["OpenTableFormatInput"];
|
|
38443
|
+
const physicalId = packCompositeId(resourceType, logicalId, [{
|
|
38444
|
+
name: "databaseName",
|
|
38445
|
+
value: databaseName
|
|
38446
|
+
}, {
|
|
38447
|
+
name: "tableName",
|
|
38448
|
+
value: tableName
|
|
38449
|
+
}], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
|
|
38100
38450
|
try {
|
|
38101
38451
|
await this.getClient().send(new CreateTableCommand$1({
|
|
38102
38452
|
CatalogId: catalogId,
|
|
@@ -38104,7 +38454,6 @@ var GlueProvider = class {
|
|
|
38104
38454
|
TableInput: this.buildTableInput(tableInput, tableName),
|
|
38105
38455
|
...openTableFormatInput !== void 0 && { OpenTableFormatInput: openTableFormatInput }
|
|
38106
38456
|
}));
|
|
38107
|
-
const physicalId = `${databaseName}|${tableName}`;
|
|
38108
38457
|
this.logger.debug(`Successfully created Glue Table ${logicalId}: ${physicalId}`);
|
|
38109
38458
|
return {
|
|
38110
38459
|
physicalId,
|
|
@@ -49210,11 +49559,11 @@ var S3TablesProvider = class {
|
|
|
49210
49559
|
if (!this.client) this.client = new S3TablesClient(this.providerRegion ? { region: this.providerRegion } : {});
|
|
49211
49560
|
return this.client;
|
|
49212
49561
|
}
|
|
49213
|
-
async create(logicalId, resourceType, properties) {
|
|
49562
|
+
async create(logicalId, resourceType, properties, context) {
|
|
49214
49563
|
switch (resourceType) {
|
|
49215
49564
|
case "AWS::S3Tables::TableBucket": return this.createTableBucket(logicalId, resourceType, properties);
|
|
49216
|
-
case "AWS::S3Tables::Namespace": return this.createNamespace(logicalId, resourceType, properties);
|
|
49217
|
-
case "AWS::S3Tables::Table": return this.createTable(logicalId, resourceType, properties);
|
|
49565
|
+
case "AWS::S3Tables::Namespace": return this.createNamespace(logicalId, resourceType, properties, context);
|
|
49566
|
+
case "AWS::S3Tables::Table": return this.createTable(logicalId, resourceType, properties, context);
|
|
49218
49567
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
|
|
49219
49568
|
}
|
|
49220
49569
|
}
|
|
@@ -49330,7 +49679,7 @@ var S3TablesProvider = class {
|
|
|
49330
49679
|
namespaceContinuationToken = namespacesResult.continuationToken;
|
|
49331
49680
|
} while (namespaceContinuationToken);
|
|
49332
49681
|
}
|
|
49333
|
-
async createNamespace(logicalId, resourceType, properties) {
|
|
49682
|
+
async createNamespace(logicalId, resourceType, properties, context) {
|
|
49334
49683
|
this.logger.debug(`Creating S3 Tables Namespace ${logicalId}`);
|
|
49335
49684
|
const tableBucketARN = properties["TableBucketARN"];
|
|
49336
49685
|
if (!tableBucketARN) throw new ProvisioningError(`TableBucketARN is required for S3 Tables Namespace ${logicalId}`, resourceType, logicalId);
|
|
@@ -49339,12 +49688,18 @@ var S3TablesProvider = class {
|
|
|
49339
49688
|
if (Array.isArray(rawNs) && rawNs.length > 0 && typeof rawNs[0] === "string") namespaceName = rawNs[0];
|
|
49340
49689
|
else if (typeof rawNs === "string" && rawNs.length > 0) namespaceName = rawNs;
|
|
49341
49690
|
if (!namespaceName) throw new ProvisioningError(`Namespace is required for S3 Tables Namespace ${logicalId}`, resourceType, logicalId);
|
|
49691
|
+
const physicalId = packCompositeId(resourceType, logicalId, [{
|
|
49692
|
+
name: "tableBucketARN",
|
|
49693
|
+
value: tableBucketARN
|
|
49694
|
+
}, {
|
|
49695
|
+
name: "namespace",
|
|
49696
|
+
value: namespaceName
|
|
49697
|
+
}], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
|
|
49342
49698
|
try {
|
|
49343
49699
|
await this.getClient().send(new CreateNamespaceCommand({
|
|
49344
49700
|
tableBucketARN,
|
|
49345
49701
|
namespace: [namespaceName]
|
|
49346
49702
|
}));
|
|
49347
|
-
const physicalId = `${tableBucketARN}|${namespaceName}`;
|
|
49348
49703
|
this.logger.debug(`Successfully created S3 Tables Namespace ${logicalId}: ${physicalId}`);
|
|
49349
49704
|
return {
|
|
49350
49705
|
physicalId,
|
|
@@ -49375,7 +49730,7 @@ var S3TablesProvider = class {
|
|
|
49375
49730
|
throw new ProvisioningError(`Failed to delete S3 Tables Namespace ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
49376
49731
|
}
|
|
49377
49732
|
}
|
|
49378
|
-
async createTable(logicalId, resourceType, properties) {
|
|
49733
|
+
async createTable(logicalId, resourceType, properties, context) {
|
|
49379
49734
|
this.logger.debug(`Creating S3 Tables Table ${logicalId}`);
|
|
49380
49735
|
const tableBucketARN = properties["TableBucketARN"];
|
|
49381
49736
|
if (!tableBucketARN) throw new ProvisioningError(`TableBucketARN is required for S3 Tables Table ${logicalId}`, resourceType, logicalId);
|
|
@@ -49386,6 +49741,20 @@ var S3TablesProvider = class {
|
|
|
49386
49741
|
const format = properties["OpenTableFormat"] ?? properties["Format"];
|
|
49387
49742
|
if (!format) throw new ProvisioningError(`OpenTableFormat is required for S3 Tables Table ${logicalId}`, resourceType, logicalId);
|
|
49388
49743
|
const tags = this.cfnTagsToSdkMap(properties["Tags"]);
|
|
49744
|
+
const physicalId = packCompositeId(resourceType, logicalId, [
|
|
49745
|
+
{
|
|
49746
|
+
name: "tableBucketARN",
|
|
49747
|
+
value: tableBucketARN
|
|
49748
|
+
},
|
|
49749
|
+
{
|
|
49750
|
+
name: "namespace",
|
|
49751
|
+
value: namespace
|
|
49752
|
+
},
|
|
49753
|
+
{
|
|
49754
|
+
name: "name",
|
|
49755
|
+
value: name
|
|
49756
|
+
}
|
|
49757
|
+
], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
|
|
49389
49758
|
try {
|
|
49390
49759
|
const response = await this.getClient().send(new CreateTableCommand$2({
|
|
49391
49760
|
tableBucketARN,
|
|
@@ -49394,7 +49763,6 @@ var S3TablesProvider = class {
|
|
|
49394
49763
|
format,
|
|
49395
49764
|
...tags !== void 0 && { tags }
|
|
49396
49765
|
}));
|
|
49397
|
-
const physicalId = `${tableBucketARN}|${namespace}|${name}`;
|
|
49398
49766
|
if (!response.tableARN) throw new ProvisioningError(`CreateTable did not return a tableARN for ${logicalId} (${physicalId}) — refusing to record an empty TableARN attribute`, resourceType, logicalId, physicalId);
|
|
49399
49767
|
const tableARN = response.tableARN;
|
|
49400
49768
|
this.logger.debug(`Successfully created S3 Tables Table ${logicalId}: ${physicalId}`);
|
|
@@ -49614,6 +49982,17 @@ var S3TablesProvider = class {
|
|
|
49614
49982
|
if (err instanceof NotFoundException$6) return null;
|
|
49615
49983
|
throw err;
|
|
49616
49984
|
}
|
|
49985
|
+
const namespaceRefusal = compositeIdSeparatorRefusal("AWS::S3Tables::Namespace", input.logicalId, [{
|
|
49986
|
+
name: "tableBucketARN",
|
|
49987
|
+
value: identity.tableBucketARN
|
|
49988
|
+
}, {
|
|
49989
|
+
name: "namespace",
|
|
49990
|
+
value: identity.namespace
|
|
49991
|
+
}]);
|
|
49992
|
+
if (namespaceRefusal !== void 0) {
|
|
49993
|
+
this.logger.warn(`${namespaceRefusal} Skipping import.`);
|
|
49994
|
+
return null;
|
|
49995
|
+
}
|
|
49617
49996
|
return {
|
|
49618
49997
|
physicalId: `${identity.tableBucketARN}|${identity.namespace}`,
|
|
49619
49998
|
attributes: {}
|
|
@@ -49711,6 +50090,24 @@ var S3TablesProvider = class {
|
|
|
49711
50090
|
attributes: { TableARN: tableARN }
|
|
49712
50091
|
};
|
|
49713
50092
|
}
|
|
50093
|
+
const tableRefusal = compositeIdSeparatorRefusal("AWS::S3Tables::Table", input.logicalId, [
|
|
50094
|
+
{
|
|
50095
|
+
name: "tableBucketARN",
|
|
50096
|
+
value: identity.tableBucketARN
|
|
50097
|
+
},
|
|
50098
|
+
{
|
|
50099
|
+
name: "namespace",
|
|
50100
|
+
value: identity.namespace
|
|
50101
|
+
},
|
|
50102
|
+
{
|
|
50103
|
+
name: "name",
|
|
50104
|
+
value: identity.name
|
|
50105
|
+
}
|
|
50106
|
+
]);
|
|
50107
|
+
if (tableRefusal !== void 0) {
|
|
50108
|
+
this.logger.warn(`${tableRefusal} Skipping import.`);
|
|
50109
|
+
return null;
|
|
50110
|
+
}
|
|
49714
50111
|
return {
|
|
49715
50112
|
physicalId: `${identity.tableBucketARN}|${identity.namespace}|${identity.name}`,
|
|
49716
50113
|
attributes: { TableARN: tableARN }
|
|
@@ -72620,7 +73017,7 @@ function createMigrateCommand() {
|
|
|
72620
73017
|
*/
|
|
72621
73018
|
function buildProgram() {
|
|
72622
73019
|
const program = new Command();
|
|
72623
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.
|
|
73020
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.4");
|
|
72624
73021
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
72625
73022
|
const { profile } = actionCommand.optsWithGlobals();
|
|
72626
73023
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|