@go-to-k/cdkd 0.222.0 → 0.223.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { A as withErrorHandling, B as generateResourceNameWithFallback, C as StackHasActiveImportsError, F as getLiveRenderer, H as withStackName, I as PATTERN_B_NAME_PROPERTIES, L as PATTERN_B_RESOURCE_TYPES, M as getLogger, P as runStackBuffered, S as ResourceUpdateNotSupportedError, V as withSkipPrefix, _ as MissingCdkCliError, a as assertRegionMatch, b as ProvisioningError, f as LocalInvokeBuildError$1, i as resolveExplicitPhysicalId, k as normalizeAwsError, l as CdkdError, m as LocalStartServiceError, n as matchesCdkPath, o as disableInstanceApiTermination, p as LocalMigrateError, r as normalizeAwsTagsToCfn, s as isTerminationProtectionPropagationError, t as CDK_PATH_TAG, v as NestedStackChildDirectDestroyError, w as StackTerminationProtectionError, x as ResourceTimeoutError, y as PartialFailureError, z as generateResourceName } from "./import-helpers-wLipXr5g.js";
|
|
3
3
|
import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-pjPwZz1r.js";
|
|
4
|
-
import { $ as AssemblyReader, A as shouldRetainResource, B as getDefaultStateBucketName, C as applyRoleArnIfSet, D as LockManager, E as TemplateParser, F as formatDockerLoginError, G as resolveStateBucketWithDefault, H as resolveApp, I as getDockerCmd, J as CFN_TEMPLATE_BODY_LIMIT, K as resolveStateBucketWithDefaultAndSource, L as runDockerForeground, M as stringifyValue, N as WorkGraph, O as S3StateBackend, P as buildDockerImage, Q as uploadCfnTemplate, R as runDockerStreaming, S as IntrinsicFunctionResolver, T as DagBuilder, U as resolveCaptureObservedState, V as getLegacyStateBucketName, W as resolveSkipPrefix, X as MIGRATE_TMP_PREFIX, Y as CFN_TEMPLATE_URL_LIMIT, Z as findLargeInlineResources, _ as IAMRoleProvider, a as withRetry, b as findActionableSilentDrops, c as computeImplicitDeleteEdges, d as bold, f as cyan, g as yellow, h as red, i as withResourceDeadline, j as AssetPublisher, k as rebuildClientForBucketRegion, l as extractDeploymentEventError, m as green, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as isRetryableTransientError, p as gray, q as warnDeprecatedNoPrefixCliFlag, r as DeployEngine, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as resolveBucketRegion, u as formatResourceLine, v as collectInlinePolicyNamesManagedBySiblings, w as DiffCalculator, x as CloudControlProvider, y as ProviderRegistry, z as Synthesizer } from "./deploy-engine-
|
|
4
|
+
import { $ as AssemblyReader, A as shouldRetainResource, B as getDefaultStateBucketName, C as applyRoleArnIfSet, D as LockManager, E as TemplateParser, F as formatDockerLoginError, G as resolveStateBucketWithDefault, H as resolveApp, I as getDockerCmd, J as CFN_TEMPLATE_BODY_LIMIT, K as resolveStateBucketWithDefaultAndSource, L as runDockerForeground, M as stringifyValue, N as WorkGraph, O as S3StateBackend, P as buildDockerImage, Q as uploadCfnTemplate, R as runDockerStreaming, S as IntrinsicFunctionResolver, T as DagBuilder, U as resolveCaptureObservedState, V as getLegacyStateBucketName, W as resolveSkipPrefix, X as MIGRATE_TMP_PREFIX, Y as CFN_TEMPLATE_URL_LIMIT, Z as findLargeInlineResources, _ as IAMRoleProvider, a as withRetry, b as findActionableSilentDrops, c as computeImplicitDeleteEdges, d as bold, f as cyan, g as yellow, h as red, i as withResourceDeadline, j as AssetPublisher, k as rebuildClientForBucketRegion, l as extractDeploymentEventError, m as green, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as isRetryableTransientError, p as gray, q as warnDeprecatedNoPrefixCliFlag, r as DeployEngine, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as resolveBucketRegion, u as formatResourceLine, v as collectInlinePolicyNamesManagedBySiblings, w as DiffCalculator, x as CloudControlProvider, y as ProviderRegistry, z as Synthesizer } from "./deploy-engine-CmN65bEv.js";
|
|
5
5
|
import { t as ASGProvider } from "./asg-provider-B_hrCxRx.js";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
7
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
@@ -53,7 +53,7 @@ import { CognitoIdentityProviderClient, CreateUserPoolCommand, DeleteUserPoolCom
|
|
|
53
53
|
import { CreatePrivateDnsNamespaceCommand, CreateServiceCommand as CreateServiceCommand$1, DeleteNamespaceCommand, DeleteServiceCommand as DeleteServiceCommand$1, GetNamespaceCommand, GetOperationCommand, GetServiceCommand, ListNamespacesCommand, ListServicesCommand as ListServicesCommand$1, ListTagsForResourceCommand as ListTagsForResourceCommand$16, NamespaceNotFound, ServiceDiscoveryClient, ServiceNotFound, UpdatePrivateDnsNamespaceCommand, UpdateServiceCommand as UpdateServiceCommand$1 } from "@aws-sdk/client-servicediscovery";
|
|
54
54
|
import { AppSyncClient, CreateApiKeyCommand, CreateDataSourceCommand, CreateGraphqlApiCommand, CreateResolverCommand, DeleteApiKeyCommand, DeleteDataSourceCommand, DeleteGraphqlApiCommand, DeleteResolverCommand, GetDataSourceCommand, GetGraphqlApiCommand, GetIntrospectionSchemaCommand, GetResolverCommand, ListApiKeysCommand, ListGraphqlApisCommand, NotFoundException as NotFoundException$4, StartSchemaCreationCommand, TagResourceCommand as TagResourceCommand$14, UntagResourceCommand as UntagResourceCommand$13, UpdateApiKeyCommand, UpdateDataSourceCommand, UpdateGraphqlApiCommand, UpdateResolverCommand } from "@aws-sdk/client-appsync";
|
|
55
55
|
import { parse, print } from "graphql";
|
|
56
|
-
import { CreateConnectionCommand, CreateCrawlerCommand, CreateDatabaseCommand, CreateJobCommand, CreateSecurityConfigurationCommand, CreateTableCommand as CreateTableCommand$1, CreateTriggerCommand, CreateWorkflowCommand, DeleteConnectionCommand, DeleteCrawlerCommand, DeleteDatabaseCommand, DeleteJobCommand, DeleteSecurityConfigurationCommand, DeleteTableCommand as DeleteTableCommand$1, DeleteTriggerCommand, DeleteWorkflowCommand, EntityNotFoundException, GetConnectionCommand, GetCrawlerCommand, GetDatabaseCommand, GetDatabasesCommand, GetJobCommand, GetSecurityConfigurationCommand, GetSecurityConfigurationsCommand, GetTableCommand, GetTablesCommand, GetTagsCommand, GetTriggerCommand, GetWorkflowCommand, GlueClient, ListWorkflowsCommand, StartCrawlerScheduleCommand, StartTriggerCommand, StopCrawlerScheduleCommand, StopTriggerCommand, UpdateConnectionCommand, UpdateCrawlerCommand, UpdateDatabaseCommand, UpdateJobCommand, UpdateTableCommand as UpdateTableCommand$1, UpdateTriggerCommand, UpdateWorkflowCommand } from "@aws-sdk/client-glue";
|
|
56
|
+
import { CrawlerRunningException, CreateConnectionCommand, CreateCrawlerCommand, CreateDatabaseCommand, CreateJobCommand, CreateSecurityConfigurationCommand, CreateTableCommand as CreateTableCommand$1, CreateTriggerCommand, CreateWorkflowCommand, DeleteConnectionCommand, DeleteCrawlerCommand, DeleteDatabaseCommand, DeleteJobCommand, DeleteSecurityConfigurationCommand, DeleteTableCommand as DeleteTableCommand$1, DeleteTriggerCommand, DeleteWorkflowCommand, EntityNotFoundException, GetConnectionCommand, GetCrawlerCommand, GetDatabaseCommand, GetDatabasesCommand, GetJobCommand, GetSecurityConfigurationCommand, GetSecurityConfigurationsCommand, GetTableCommand, GetTablesCommand, GetTagsCommand, GetTriggerCommand, GetWorkflowCommand, GlueClient, ListWorkflowsCommand, StartCrawlerScheduleCommand, StartTriggerCommand, StopCrawlerCommand, StopCrawlerScheduleCommand, StopTriggerCommand, UpdateConnectionCommand, UpdateCrawlerCommand, UpdateDatabaseCommand, UpdateJobCommand, UpdateTableCommand as UpdateTableCommand$1, UpdateTriggerCommand, UpdateWorkflowCommand } from "@aws-sdk/client-glue";
|
|
57
57
|
import { AddTagsToStreamCommand, CreateStreamCommand, DecreaseStreamRetentionPeriodCommand, DeleteStreamCommand, DeregisterStreamConsumerCommand, DescribeStreamCommand, DescribeStreamConsumerCommand, IncreaseStreamRetentionPeriodCommand, KinesisClient, ListStreamsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$17, ListTagsForStreamCommand, RegisterStreamConsumerCommand, RemoveTagsFromStreamCommand, ResourceNotFoundException as ResourceNotFoundException$8, StartStreamEncryptionCommand, StopStreamEncryptionCommand, TagResourceCommand as TagResourceCommand$15, UntagResourceCommand as UntagResourceCommand$14, UpdateShardCountCommand } from "@aws-sdk/client-kinesis";
|
|
58
58
|
import { AccessPointNotFound, CreateAccessPointCommand, CreateFileSystemCommand, CreateMountTargetCommand, DeleteAccessPointCommand, DeleteFileSystemCommand, DeleteMountTargetCommand, DescribeAccessPointsCommand, DescribeBackupPolicyCommand, DescribeFileSystemPolicyCommand, DescribeFileSystemsCommand, DescribeLifecycleConfigurationCommand, DescribeMountTargetSecurityGroupsCommand, DescribeMountTargetsCommand, EFSClient, FileSystemNotFound, ModifyMountTargetSecurityGroupsCommand, MountTargetNotFound, PutBackupPolicyCommand, PutFileSystemPolicyCommand, PutLifecycleConfigurationCommand, UpdateFileSystemCommand, UpdateFileSystemProtectionCommand } from "@aws-sdk/client-efs";
|
|
59
59
|
import { CreateDeliveryStreamCommand, DeleteDeliveryStreamCommand, DescribeDeliveryStreamCommand, FirehoseClient, ListDeliveryStreamsCommand, ListTagsForDeliveryStreamCommand, ResourceNotFoundException as ResourceNotFoundException$9, TagDeliveryStreamCommand, UntagDeliveryStreamCommand, UpdateDestinationCommand } from "@aws-sdk/client-firehose";
|
|
@@ -1553,7 +1553,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
1553
1553
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
1554
1554
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
1555
1555
|
function getCdkdVersion() {
|
|
1556
|
-
return "0.
|
|
1556
|
+
return "0.223.0";
|
|
1557
1557
|
}
|
|
1558
1558
|
/**
|
|
1559
1559
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -18384,6 +18384,88 @@ var CloudFrontDistributionProvider = class {
|
|
|
18384
18384
|
}
|
|
18385
18385
|
}
|
|
18386
18386
|
/**
|
|
18387
|
+
* Read the AWS-current `DistributionConfig` for drift detection.
|
|
18388
|
+
*
|
|
18389
|
+
* Calls the read-only `GetDistributionConfigCommand` and inverts the
|
|
18390
|
+
* provider's own `convertToSdkFormat` (the CFn-shape → SDK-shape
|
|
18391
|
+
* `{ Quantity, Items }` mapping the create / update path applies) back
|
|
18392
|
+
* into the CloudFormation `DistributionConfig` shape that cdkd state
|
|
18393
|
+
* stores — so the drift comparator sees the same structure on both
|
|
18394
|
+
* the deploy-time observed snapshot and a later drift read.
|
|
18395
|
+
*
|
|
18396
|
+
* The comparator only descends into keys present in cdkd state (or the
|
|
18397
|
+
* union of state + AWS when an observed baseline exists), so this does
|
|
18398
|
+
* not need to surface every AWS-injected field; it returns the same
|
|
18399
|
+
* `DistributionConfig` / `Tags` keys the provider manages.
|
|
18400
|
+
*
|
|
18401
|
+
* `CallerReference` (a create-time idempotency token AWS echoes back
|
|
18402
|
+
* but CDK never templates) is dropped so it cannot fire phantom drift.
|
|
18403
|
+
* The remaining write-only / never-readable sub-fields are declared in
|
|
18404
|
+
* `getDriftUnknownPaths`.
|
|
18405
|
+
*/
|
|
18406
|
+
async readCurrentState(physicalId, _logicalId, resourceType, _properties) {
|
|
18407
|
+
if (resourceType !== "AWS::CloudFront::Distribution") return void 0;
|
|
18408
|
+
let config;
|
|
18409
|
+
try {
|
|
18410
|
+
config = (await this.cloudFrontClient.send(new GetDistributionConfigCommand({ Id: physicalId }))).DistributionConfig;
|
|
18411
|
+
} catch (error) {
|
|
18412
|
+
if (error instanceof NoSuchDistribution) return void 0;
|
|
18413
|
+
throw error;
|
|
18414
|
+
}
|
|
18415
|
+
if (!config) return void 0;
|
|
18416
|
+
const result = { DistributionConfig: this.convertToCfnFormat(config) };
|
|
18417
|
+
try {
|
|
18418
|
+
const arn = (await this.cloudFrontClient.send(new GetDistributionCommand({ Id: physicalId }))).Distribution?.ARN;
|
|
18419
|
+
if (arn) {
|
|
18420
|
+
const cfnTags = ((await this.cloudFrontClient.send(new ListTagsForResourceCommand$3({ Resource: arn }))).Tags?.Items ?? []).filter((t) => typeof t.Key === "string" && !t.Key.startsWith("aws:cdk:")).map((t) => ({
|
|
18421
|
+
Key: t.Key,
|
|
18422
|
+
Value: t.Value ?? ""
|
|
18423
|
+
}));
|
|
18424
|
+
if (cfnTags.length > 0) result["Tags"] = cfnTags;
|
|
18425
|
+
}
|
|
18426
|
+
} catch (error) {
|
|
18427
|
+
this.logger.debug(`Tag read for CloudFront Distribution ${physicalId} failed during drift read: ${error instanceof Error ? error.message : String(error)}`);
|
|
18428
|
+
}
|
|
18429
|
+
return result;
|
|
18430
|
+
}
|
|
18431
|
+
/**
|
|
18432
|
+
* State property paths cdkd cannot read back faithfully from AWS, so
|
|
18433
|
+
* the drift comparator skips them rather than firing a guaranteed
|
|
18434
|
+
* false positive every run (mirrors the Lambda `Code.S3*` precedent).
|
|
18435
|
+
*
|
|
18436
|
+
* - `DistributionConfig.CallerReference`: a create-time idempotency
|
|
18437
|
+
* token. cdkd generates it internally (`<ts>-<logicalId>-<rand>`);
|
|
18438
|
+
* AWS echoes it back, but it is never templated by CDK, so comparing
|
|
18439
|
+
* it would diff cdkd's generated value on every run. `convertToCfnFormat`
|
|
18440
|
+
* already drops it from the AWS side; declaring it here also excludes
|
|
18441
|
+
* it from the observed-baseline side.
|
|
18442
|
+
* - `DistributionConfig.Logging.Bucket`: CloudFront normalizes the S3
|
|
18443
|
+
* logging bucket to its `<bucket>.s3.amazonaws.com` regional domain on
|
|
18444
|
+
* read, which never matches the bare bucket domain a template may
|
|
18445
|
+
* carry; treat it as drift-unknown to avoid a guaranteed mismatch.
|
|
18446
|
+
* - `DistributionConfig.OriginGroups`: each origin group carries its own
|
|
18447
|
+
* inner `{ Quantity, Items }` wrappers (`Members`,
|
|
18448
|
+
* `FailoverCriteria.StatusCodes`) that `convertToCfnFormat` does not yet
|
|
18449
|
+
* unwrap symmetrically (only the top-level OriginGroups list is unwrapped;
|
|
18450
|
+
* there is no `revertOriginGroup` pass, and `convertToSdkFormat` likewise
|
|
18451
|
+
* does not descend into them). Against the observed baseline both sides go
|
|
18452
|
+
* through the same `readCurrentState` so this never false-positives on a
|
|
18453
|
+
* normal deploy, but against the `properties`-fallback baseline (older
|
|
18454
|
+
* state without `observedProperties`) the raw `{ Quantity, Items }` shape
|
|
18455
|
+
* would diff the bare-array template form. Suppress it until a dedicated
|
|
18456
|
+
* fix lands a `revertOriginGroup` + a real OriginGroups integ fixture
|
|
18457
|
+
* (there is no OriginGroups fixture to verify the inner shape today). See
|
|
18458
|
+
* the PR #871 review thread.
|
|
18459
|
+
*/
|
|
18460
|
+
getDriftUnknownPaths(resourceType) {
|
|
18461
|
+
if (resourceType !== "AWS::CloudFront::Distribution") return [];
|
|
18462
|
+
return [
|
|
18463
|
+
"DistributionConfig.CallerReference",
|
|
18464
|
+
"DistributionConfig.Logging.Bucket",
|
|
18465
|
+
"DistributionConfig.OriginGroups"
|
|
18466
|
+
];
|
|
18467
|
+
}
|
|
18468
|
+
/**
|
|
18387
18469
|
* Get resource attribute (for Fn::GetAtt resolution)
|
|
18388
18470
|
*/
|
|
18389
18471
|
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
@@ -18462,6 +18544,105 @@ var CloudFrontDistributionProvider = class {
|
|
|
18462
18544
|
return result;
|
|
18463
18545
|
}
|
|
18464
18546
|
/**
|
|
18547
|
+
* Invert {@link convertToSdkFormat}: map an AWS-returned SDK-shape
|
|
18548
|
+
* `DistributionConfig` ({@link GetDistributionConfigCommand} output) back
|
|
18549
|
+
* into the CloudFormation `DistributionConfig` shape cdkd state stores.
|
|
18550
|
+
*
|
|
18551
|
+
* The inversion is the mirror image of the create / update conversion:
|
|
18552
|
+
* every `{ Quantity, Items }` wrapper becomes its bare `Items` array
|
|
18553
|
+
* (top-level list fields + the nested cache-behavior / origin fields),
|
|
18554
|
+
* and `CallerReference` is dropped (a create-time idempotency token CDK
|
|
18555
|
+
* never templates — see `getDriftUnknownPaths`).
|
|
18556
|
+
*
|
|
18557
|
+
* Lossiness note: the conversion is NOT perfectly lossless because
|
|
18558
|
+
* `convertToSdkFormat` injects SDK-required defaults the CFn template may
|
|
18559
|
+
* omit (`Comment: ''`, `Logging.{Enabled,IncludeCookies,Prefix}`,
|
|
18560
|
+
* `CustomOriginConfig.HTTP{,S}Port`). Those defaults are preserved on the
|
|
18561
|
+
* inverted side, which is correct for the drift comparator: the
|
|
18562
|
+
* deploy-time observed baseline (also produced by THIS method) carries the
|
|
18563
|
+
* same defaults, so they compare equal. They would only matter against the
|
|
18564
|
+
* `properties` fallback baseline (resources with no observedProperties),
|
|
18565
|
+
* where an AWS-injected default the template omitted is legitimately a
|
|
18566
|
+
* key cdkd never set — but the comparator's state-keys-only walk in that
|
|
18567
|
+
* mode never descends into a key absent from the template, so the extra
|
|
18568
|
+
* defaults cannot fire false drift there either.
|
|
18569
|
+
*/
|
|
18570
|
+
convertToCfnFormat(config) {
|
|
18571
|
+
const result = { ...config };
|
|
18572
|
+
delete result["CallerReference"];
|
|
18573
|
+
for (const field of QUANTITY_ITEM_FIELDS) if (result[field] !== void 0) result[field] = this.unwrapQuantity(result[field]);
|
|
18574
|
+
if (result["DefaultCacheBehavior"] && typeof result["DefaultCacheBehavior"] === "object") result["DefaultCacheBehavior"] = this.revertCacheBehavior(result["DefaultCacheBehavior"]);
|
|
18575
|
+
if (Array.isArray(result["CacheBehaviors"])) result["CacheBehaviors"] = result["CacheBehaviors"].map((cb) => this.revertCacheBehavior(cb));
|
|
18576
|
+
if (Array.isArray(result["Origins"])) result["Origins"] = result["Origins"].map((origin) => this.revertOrigin(origin));
|
|
18577
|
+
return result;
|
|
18578
|
+
}
|
|
18579
|
+
/**
|
|
18580
|
+
* Inverse of {@link wrapWithQuantity}: a `{ Quantity, Items }` object
|
|
18581
|
+
* becomes its bare `Items` array; anything else is returned unchanged.
|
|
18582
|
+
*/
|
|
18583
|
+
unwrapQuantity(value) {
|
|
18584
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
18585
|
+
const obj = value;
|
|
18586
|
+
if (Array.isArray(obj["Items"])) return obj["Items"];
|
|
18587
|
+
}
|
|
18588
|
+
return value;
|
|
18589
|
+
}
|
|
18590
|
+
/**
|
|
18591
|
+
* Inverse of {@link convertCacheBehavior}: unwrap the Quantity + Items
|
|
18592
|
+
* fields nested inside a CacheBehavior back to bare arrays.
|
|
18593
|
+
*/
|
|
18594
|
+
revertCacheBehavior(behavior) {
|
|
18595
|
+
const result = { ...behavior };
|
|
18596
|
+
if (result["AllowedMethods"] && typeof result["AllowedMethods"] === "object") {
|
|
18597
|
+
const allowed = result["AllowedMethods"];
|
|
18598
|
+
if (allowed["CachedMethods"] !== void 0 && result["CachedMethods"] === void 0) {
|
|
18599
|
+
result["CachedMethods"] = allowed["CachedMethods"];
|
|
18600
|
+
const allowedCopy = { ...allowed };
|
|
18601
|
+
delete allowedCopy["CachedMethods"];
|
|
18602
|
+
result["AllowedMethods"] = allowedCopy;
|
|
18603
|
+
}
|
|
18604
|
+
}
|
|
18605
|
+
for (const fieldPath of CACHE_BEHAVIOR_QUANTITY_FIELDS) {
|
|
18606
|
+
const parts = fieldPath.split(".");
|
|
18607
|
+
this.unwrapQuantityAtPath(result, parts);
|
|
18608
|
+
}
|
|
18609
|
+
return result;
|
|
18610
|
+
}
|
|
18611
|
+
/**
|
|
18612
|
+
* Inverse of {@link convertOrigin}: unwrap CustomHeaders and
|
|
18613
|
+
* CustomOriginConfig.OriginSslProtocols back to bare arrays.
|
|
18614
|
+
*/
|
|
18615
|
+
revertOrigin(origin) {
|
|
18616
|
+
const result = { ...origin };
|
|
18617
|
+
if (result["CustomHeaders"] !== void 0) result["CustomHeaders"] = this.unwrapQuantity(result["CustomHeaders"]);
|
|
18618
|
+
if (result["CustomOriginConfig"] && typeof result["CustomOriginConfig"] === "object") {
|
|
18619
|
+
const customOriginConfig = { ...result["CustomOriginConfig"] };
|
|
18620
|
+
if (customOriginConfig["OriginSslProtocols"] !== void 0) customOriginConfig["OriginSslProtocols"] = this.unwrapQuantity(customOriginConfig["OriginSslProtocols"]);
|
|
18621
|
+
result["CustomOriginConfig"] = customOriginConfig;
|
|
18622
|
+
}
|
|
18623
|
+
return result;
|
|
18624
|
+
}
|
|
18625
|
+
/**
|
|
18626
|
+
* Inverse of {@link applyQuantityAtPath}: unwrap a `{ Quantity, Items }`
|
|
18627
|
+
* value at a nested path (e.g. "ForwardedValues.Headers") back to a bare
|
|
18628
|
+
* array.
|
|
18629
|
+
*/
|
|
18630
|
+
unwrapQuantityAtPath(obj, path) {
|
|
18631
|
+
if (path.length === 0) return;
|
|
18632
|
+
if (path.length === 1) {
|
|
18633
|
+
const key = path[0];
|
|
18634
|
+
if (obj[key] !== void 0) obj[key] = this.unwrapQuantity(obj[key]);
|
|
18635
|
+
return;
|
|
18636
|
+
}
|
|
18637
|
+
const [head, ...rest] = path;
|
|
18638
|
+
const headKey = head;
|
|
18639
|
+
if (obj[headKey] && typeof obj[headKey] === "object") {
|
|
18640
|
+
const nested = { ...obj[headKey] };
|
|
18641
|
+
obj[headKey] = nested;
|
|
18642
|
+
this.unwrapQuantityAtPath(nested, rest);
|
|
18643
|
+
}
|
|
18644
|
+
}
|
|
18645
|
+
/**
|
|
18465
18646
|
* Wrap a value with the Quantity + Items pattern if needed.
|
|
18466
18647
|
*
|
|
18467
18648
|
* Handles three cases:
|
|
@@ -28173,12 +28354,13 @@ var GlueWorkflowProvider = class {
|
|
|
28173
28354
|
const name = properties["Name"];
|
|
28174
28355
|
if (!name) throw new ProvisioningError(`Name is required for Glue Workflow ${logicalId}`, resourceType, logicalId);
|
|
28175
28356
|
try {
|
|
28176
|
-
const
|
|
28357
|
+
const tagsMap = cfnTagsToMap(properties["Tags"]);
|
|
28358
|
+
const tags = tagsMap && Object.keys(tagsMap).length > 0 ? tagsMap : void 0;
|
|
28177
28359
|
await this.getClient().send(new CreateWorkflowCommand({
|
|
28178
28360
|
Name: name,
|
|
28179
28361
|
...properties["Description"] !== void 0 && { Description: properties["Description"] },
|
|
28180
28362
|
...properties["DefaultRunProperties"] !== void 0 && { DefaultRunProperties: properties["DefaultRunProperties"] },
|
|
28181
|
-
...properties["MaxConcurrentRuns"] !== void 0 && { MaxConcurrentRuns: properties["MaxConcurrentRuns"] },
|
|
28363
|
+
...properties["MaxConcurrentRuns"] !== void 0 && { MaxConcurrentRuns: coerceNumber(properties["MaxConcurrentRuns"]) },
|
|
28182
28364
|
...tags && { Tags: tags }
|
|
28183
28365
|
}));
|
|
28184
28366
|
this.logger.debug(`Successfully created Glue Workflow ${logicalId}: ${name}`);
|
|
@@ -28198,7 +28380,7 @@ var GlueWorkflowProvider = class {
|
|
|
28198
28380
|
Name: physicalId,
|
|
28199
28381
|
...properties["Description"] !== void 0 && { Description: properties["Description"] },
|
|
28200
28382
|
...properties["DefaultRunProperties"] !== void 0 && { DefaultRunProperties: properties["DefaultRunProperties"] },
|
|
28201
|
-
...properties["MaxConcurrentRuns"] !== void 0 && { MaxConcurrentRuns: properties["MaxConcurrentRuns"] }
|
|
28383
|
+
...properties["MaxConcurrentRuns"] !== void 0 && { MaxConcurrentRuns: coerceNumber(properties["MaxConcurrentRuns"]) }
|
|
28202
28384
|
}));
|
|
28203
28385
|
this.logger.debug(`Successfully updated Glue Workflow ${logicalId}`);
|
|
28204
28386
|
return {
|
|
@@ -28432,22 +28614,17 @@ var GlueSecurityConfigurationProvider = class {
|
|
|
28432
28614
|
return null;
|
|
28433
28615
|
}
|
|
28434
28616
|
};
|
|
28435
|
-
/**
|
|
28436
|
-
|
|
28437
|
-
|
|
28438
|
-
|
|
28439
|
-
*/
|
|
28440
|
-
|
|
28441
|
-
|
|
28442
|
-
|
|
28443
|
-
|
|
28444
|
-
|
|
28445
|
-
|
|
28446
|
-
const v = typeof obj["Value"] === "string" ? obj["Value"] : "";
|
|
28447
|
-
if (!k) continue;
|
|
28448
|
-
out[k] = v;
|
|
28449
|
-
}
|
|
28450
|
-
return Object.keys(out).length > 0 ? out : void 0;
|
|
28617
|
+
/** Max GetCrawler polls while waiting for a stopped crawler to settle. */
|
|
28618
|
+
const CRAWLER_STOP_MAX_ATTEMPTS = 30;
|
|
28619
|
+
/** Delay between GetCrawler polls while waiting for a crawler to stop. */
|
|
28620
|
+
const CRAWLER_STOP_POLL_INTERVAL_MS = 2e3;
|
|
28621
|
+
/** Max GetTrigger polls while waiting for a trigger to reach DEACTIVATED. */
|
|
28622
|
+
const TRIGGER_DEACTIVATE_MAX_ATTEMPTS = 30;
|
|
28623
|
+
/** Delay between GetTrigger polls while waiting for a trigger to deactivate. */
|
|
28624
|
+
const TRIGGER_DEACTIVATE_POLL_INTERVAL_MS = 1e3;
|
|
28625
|
+
/** Promise-based sleep used by the crawler / trigger state-machine waiters. */
|
|
28626
|
+
function sleep$1(ms) {
|
|
28627
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
28451
28628
|
}
|
|
28452
28629
|
/**
|
|
28453
28630
|
* Build the SDK `EncryptionConfiguration` from the CFn-shape input
|
|
@@ -28768,24 +28945,51 @@ function buildJobCommonFields(p) {
|
|
|
28768
28945
|
"LogUri",
|
|
28769
28946
|
"DefaultArguments",
|
|
28770
28947
|
"NonOverridableArguments",
|
|
28771
|
-
"MaxRetries",
|
|
28772
|
-
"AllocatedCapacity",
|
|
28773
|
-
"Timeout",
|
|
28774
|
-
"MaxCapacity",
|
|
28775
28948
|
"WorkerType",
|
|
28776
|
-
"NumberOfWorkers",
|
|
28777
28949
|
"SecurityConfiguration",
|
|
28778
28950
|
"GlueVersion",
|
|
28779
28951
|
"ExecutionClass",
|
|
28780
28952
|
"MaintenanceWindow"
|
|
28781
28953
|
]) if (p[k] !== void 0) r[k] = p[k];
|
|
28782
|
-
|
|
28954
|
+
for (const k of [
|
|
28955
|
+
"MaxRetries",
|
|
28956
|
+
"AllocatedCapacity",
|
|
28957
|
+
"Timeout",
|
|
28958
|
+
"MaxCapacity",
|
|
28959
|
+
"NumberOfWorkers"
|
|
28960
|
+
]) {
|
|
28961
|
+
const v = p[k];
|
|
28962
|
+
if (v !== void 0) r[k] = coerceNumber(v);
|
|
28963
|
+
}
|
|
28964
|
+
if (p["ExecutionProperty"] !== void 0) {
|
|
28965
|
+
const ep = { ...p["ExecutionProperty"] };
|
|
28966
|
+
if (ep["MaxConcurrentRuns"] !== void 0) ep["MaxConcurrentRuns"] = coerceNumber(ep["MaxConcurrentRuns"]);
|
|
28967
|
+
r.ExecutionProperty = ep;
|
|
28968
|
+
}
|
|
28783
28969
|
if (p["Connections"] !== void 0) r.Connections = { Connections: p["Connections"]["Connections"] ?? [] };
|
|
28784
|
-
if (p["NotificationProperty"] !== void 0)
|
|
28970
|
+
if (p["NotificationProperty"] !== void 0) {
|
|
28971
|
+
const np = { ...p["NotificationProperty"] };
|
|
28972
|
+
if (np["NotifyDelayAfter"] !== void 0) np["NotifyDelayAfter"] = coerceNumber(np["NotifyDelayAfter"]);
|
|
28973
|
+
r.NotificationProperty = np;
|
|
28974
|
+
}
|
|
28785
28975
|
if (p["SourceControlDetails"] !== void 0) r.SourceControlDetails = p["SourceControlDetails"];
|
|
28786
28976
|
return r;
|
|
28787
28977
|
}
|
|
28788
28978
|
/**
|
|
28979
|
+
* Coerce a CFn-delivered numeric property (often a string like `"10"`) to a
|
|
28980
|
+
* JS number at the SDK wire boundary. Non-finite / unparseable inputs are
|
|
28981
|
+
* returned unchanged so AWS surfaces a clear validation error rather than
|
|
28982
|
+
* silently sending `NaN`.
|
|
28983
|
+
*/
|
|
28984
|
+
function coerceNumber(value) {
|
|
28985
|
+
if (typeof value === "number") return value;
|
|
28986
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
28987
|
+
const n = Number(value);
|
|
28988
|
+
if (Number.isFinite(n)) return n;
|
|
28989
|
+
}
|
|
28990
|
+
return value;
|
|
28991
|
+
}
|
|
28992
|
+
/**
|
|
28789
28993
|
* Convert CFn `Tags: [{Key,Value}]` (or a tag map) to AWS Glue's
|
|
28790
28994
|
* `Record<string,string>` shape used by Create commands and TagResource. Returns
|
|
28791
28995
|
* `undefined` when the input is undefined so callers can elide the key.
|
|
@@ -28894,12 +29098,21 @@ var GlueCrawlerProvider = class {
|
|
|
28894
29098
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
28895
29099
|
this.logger.debug(`Updating Glue Crawler ${logicalId}: ${physicalId}`);
|
|
28896
29100
|
try {
|
|
28897
|
-
|
|
29101
|
+
const updateInput = {
|
|
28898
29102
|
Name: physicalId,
|
|
28899
29103
|
...properties["Role"] !== void 0 && { Role: properties["Role"] },
|
|
28900
29104
|
...properties["Targets"] !== void 0 && { Targets: properties["Targets"] },
|
|
28901
29105
|
...buildCrawlerCommonFields(properties)
|
|
28902
|
-
}
|
|
29106
|
+
};
|
|
29107
|
+
try {
|
|
29108
|
+
await this.getClient().send(new UpdateCrawlerCommand(updateInput));
|
|
29109
|
+
} catch (err) {
|
|
29110
|
+
if (err instanceof CrawlerRunningException) {
|
|
29111
|
+
this.logger.debug(`Glue Crawler ${physicalId} is running; stopping before update and retrying`);
|
|
29112
|
+
await this.stopCrawlerAndWait(physicalId);
|
|
29113
|
+
await this.getClient().send(new UpdateCrawlerCommand(updateInput));
|
|
29114
|
+
} else throw err;
|
|
29115
|
+
}
|
|
28903
29116
|
const oldTags = cfnTagsToMap(previousProperties["Tags"]) ?? {};
|
|
28904
29117
|
const newTags = cfnTagsToMap(properties["Tags"]) ?? {};
|
|
28905
29118
|
await this.applyTagDiff(physicalId, oldTags, newTags);
|
|
@@ -28922,10 +29135,39 @@ var GlueCrawlerProvider = class {
|
|
|
28922
29135
|
this.logger.debug(`Glue Crawler ${physicalId} does not exist, skipping deletion`);
|
|
28923
29136
|
return;
|
|
28924
29137
|
}
|
|
29138
|
+
if (error instanceof CrawlerRunningException) {
|
|
29139
|
+
this.logger.debug(`Glue Crawler ${physicalId} is running; stopping before delete and retrying`);
|
|
29140
|
+
await this.stopCrawlerAndWait(physicalId);
|
|
29141
|
+
await this.getClient().send(new DeleteCrawlerCommand({ Name: physicalId }));
|
|
29142
|
+
return;
|
|
29143
|
+
}
|
|
28925
29144
|
const cause = error instanceof Error ? error : void 0;
|
|
28926
29145
|
throw new ProvisioningError(`Failed to delete Glue Crawler ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
28927
29146
|
}
|
|
28928
29147
|
}
|
|
29148
|
+
/**
|
|
29149
|
+
* Stop a running crawler and poll until it leaves the RUNNING / STOPPING
|
|
29150
|
+
* state (or until {@link CRAWLER_STOP_MAX_ATTEMPTS} is exhausted). Tolerates a
|
|
29151
|
+
* CrawlerStoppingException / "not running" race (the crawler may have just
|
|
29152
|
+
* finished on its own) so callers can unconditionally retry their delete /
|
|
29153
|
+
* update afterwards.
|
|
29154
|
+
*/
|
|
29155
|
+
async stopCrawlerAndWait(physicalId) {
|
|
29156
|
+
try {
|
|
29157
|
+
await this.getClient().send(new StopCrawlerCommand({ Name: physicalId }));
|
|
29158
|
+
} catch (err) {
|
|
29159
|
+
this.logger.debug(`StopCrawler for ${physicalId} returned ${err instanceof Error ? err.name : String(err)}; continuing to wait`);
|
|
29160
|
+
}
|
|
29161
|
+
for (let attempt = 0; attempt < CRAWLER_STOP_MAX_ATTEMPTS; attempt++) {
|
|
29162
|
+
try {
|
|
29163
|
+
const state = (await this.getClient().send(new GetCrawlerCommand({ Name: physicalId }))).Crawler?.State;
|
|
29164
|
+
if (state !== "RUNNING" && state !== "STOPPING") return;
|
|
29165
|
+
} catch (err) {
|
|
29166
|
+
if (err instanceof EntityNotFoundException) return;
|
|
29167
|
+
}
|
|
29168
|
+
await sleep$1(CRAWLER_STOP_POLL_INTERVAL_MS);
|
|
29169
|
+
}
|
|
29170
|
+
}
|
|
28929
29171
|
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
28930
29172
|
if (attributeName === "Id" || attributeName === "Ref" || attributeName === "Name") return physicalId;
|
|
28931
29173
|
}
|
|
@@ -29248,6 +29490,7 @@ var GlueTriggerProvider = class {
|
|
|
29248
29490
|
if ((await this.getClient().send(new GetTriggerCommand({ Name: physicalId }))).Trigger?.State === "ACTIVATED") {
|
|
29249
29491
|
restart = true;
|
|
29250
29492
|
await this.getClient().send(new StopTriggerCommand({ Name: physicalId }));
|
|
29493
|
+
await this.waitForTriggerDeactivated(physicalId);
|
|
29251
29494
|
}
|
|
29252
29495
|
} catch (err) {
|
|
29253
29496
|
if (!(err instanceof EntityNotFoundException)) this.logger.debug(`GetTrigger pre-check failed for ${physicalId}; continuing anyway: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -29259,11 +29502,22 @@ var GlueTriggerProvider = class {
|
|
|
29259
29502
|
...properties["Predicate"] !== void 0 && { Predicate: properties["Predicate"] },
|
|
29260
29503
|
...properties["EventBatchingCondition"] !== void 0 && { EventBatchingCondition: properties["EventBatchingCondition"] }
|
|
29261
29504
|
};
|
|
29262
|
-
|
|
29263
|
-
|
|
29264
|
-
|
|
29265
|
-
|
|
29266
|
-
|
|
29505
|
+
let updateError;
|
|
29506
|
+
try {
|
|
29507
|
+
await this.getClient().send(new UpdateTriggerCommand({
|
|
29508
|
+
Name: physicalId,
|
|
29509
|
+
TriggerUpdate: update
|
|
29510
|
+
}));
|
|
29511
|
+
} catch (err) {
|
|
29512
|
+
updateError = err;
|
|
29513
|
+
}
|
|
29514
|
+
if (restart) try {
|
|
29515
|
+
await this.getClient().send(new StartTriggerCommand({ Name: physicalId }));
|
|
29516
|
+
} catch (restartError) {
|
|
29517
|
+
if (updateError === void 0) throw restartError;
|
|
29518
|
+
this.logger.warn(`Failed to re-activate Glue Trigger ${physicalId} after a failed update: ${restartError.message}`);
|
|
29519
|
+
}
|
|
29520
|
+
if (updateError !== void 0) throw updateError;
|
|
29267
29521
|
const oldTags = cfnTagsToMap(previousProperties["Tags"]) ?? {};
|
|
29268
29522
|
const newTags = cfnTagsToMap(properties["Tags"]) ?? {};
|
|
29269
29523
|
await this.applyTagDiff(physicalId, oldTags, newTags);
|
|
@@ -29276,9 +29530,34 @@ var GlueTriggerProvider = class {
|
|
|
29276
29530
|
throw new ProvisioningError(`Failed to update Glue Trigger ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
29277
29531
|
}
|
|
29278
29532
|
}
|
|
29533
|
+
/**
|
|
29534
|
+
* Poll GetTrigger until the trigger leaves the ACTIVATED / ACTIVATING state
|
|
29535
|
+
* (StopTrigger is async). Returns once DEACTIVATED (or any non-active state)
|
|
29536
|
+
* is observed, the trigger is gone, or the attempt budget is exhausted —
|
|
29537
|
+
* callers then proceed with UpdateTrigger / DeleteTrigger.
|
|
29538
|
+
*/
|
|
29539
|
+
async waitForTriggerDeactivated(physicalId) {
|
|
29540
|
+
for (let attempt = 0; attempt < TRIGGER_DEACTIVATE_MAX_ATTEMPTS; attempt++) {
|
|
29541
|
+
try {
|
|
29542
|
+
const state = (await this.getClient().send(new GetTriggerCommand({ Name: physicalId }))).Trigger?.State;
|
|
29543
|
+
if (state !== "ACTIVATED" && state !== "ACTIVATING") return;
|
|
29544
|
+
} catch (err) {
|
|
29545
|
+
if (err instanceof EntityNotFoundException) return;
|
|
29546
|
+
}
|
|
29547
|
+
await sleep$1(TRIGGER_DEACTIVATE_POLL_INTERVAL_MS);
|
|
29548
|
+
}
|
|
29549
|
+
}
|
|
29279
29550
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
29280
29551
|
this.logger.debug(`Deleting Glue Trigger ${logicalId}: ${physicalId}`);
|
|
29281
29552
|
try {
|
|
29553
|
+
try {
|
|
29554
|
+
if ((await this.getClient().send(new GetTriggerCommand({ Name: physicalId }))).Trigger?.State === "ACTIVATED") {
|
|
29555
|
+
await this.getClient().send(new StopTriggerCommand({ Name: physicalId }));
|
|
29556
|
+
await this.waitForTriggerDeactivated(physicalId);
|
|
29557
|
+
}
|
|
29558
|
+
} catch (err) {
|
|
29559
|
+
if (!(err instanceof EntityNotFoundException)) this.logger.debug(`GetTrigger pre-delete check failed for ${physicalId}; continuing: ${err instanceof Error ? err.message : String(err)}`);
|
|
29560
|
+
}
|
|
29282
29561
|
await this.getClient().send(new DeleteTriggerCommand({ Name: physicalId }));
|
|
29283
29562
|
} catch (error) {
|
|
29284
29563
|
if (error instanceof EntityNotFoundException) {
|
|
@@ -54100,7 +54379,7 @@ function reorderArgs(argv) {
|
|
|
54100
54379
|
async function main() {
|
|
54101
54380
|
installPipeCloseHandler();
|
|
54102
54381
|
const program = new Command();
|
|
54103
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
54382
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.223.0");
|
|
54104
54383
|
program.addCommand(createBootstrapCommand());
|
|
54105
54384
|
program.addCommand(createSynthCommand());
|
|
54106
54385
|
program.addCommand(createListCommand());
|