@go-to-k/cdkd 0.254.0 → 0.255.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/{asg-provider-BgcH5ymP.js → asg-provider-BPtdM67j.js} +2 -2
- package/dist/{asg-provider-BgcH5ymP.js.map → asg-provider-BPtdM67j.js.map} +1 -1
- package/dist/cli.js +402 -400
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-d-cwg8zS.js → deploy-engine-CFUNbwD1.js} +338 -182
- package/dist/deploy-engine-CFUNbwD1.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-d-cwg8zS.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as BOOTSTRAP_MARKER_PREFIX, A as refStateLookupFromResource, At as AssemblyReader, B as TemplateParser, C as ProviderRegistry, Ct as warnDeprecatedNoPrefixCliFlag, D as isTerminationProtectionPropagationError, Dt as findLargeInlineResources, E as disableInstanceApiTermination, Et as MIGRATE_TMP_PREFIX, F as resolveExplicitPhysicalId, Ft as resetAwsClients, G as AssetPublisher, Gt as MissingCdkCliError, H as S3StateBackend, Ht as LocalMigrateError, I as assertRegionMatch, It as setAwsClients, J as buildAssetRedirectMap, Jt as ProvisioningError, K as stringifyValue, Kt as NestedStackChildDirectDestroyError, L as applyRoleArnIfSet, M as CDK_PATH_TAG, Mt as resolveBucketRegion, N as matchesCdkPath, Nt as AwsClients, O as IntrinsicFunctionResolver, Ot as uploadCfnTemplate, P as normalizeAwsTagsToCfn, Pt as getAwsClients, Q as AssetModeResolver, Qt as StackTerminationProtectionError, R as DiffCalculator, Rt as CdkdError, S as
|
|
2
|
+
import { $ as BOOTSTRAP_MARKER_PREFIX, A as refStateLookupFromResource, At as AssemblyReader, B as TemplateParser, C as ProviderRegistry, Ct as warnDeprecatedNoPrefixCliFlag, D as isTerminationProtectionPropagationError, Dt as findLargeInlineResources, E as disableInstanceApiTermination, Et as MIGRATE_TMP_PREFIX, F as resolveExplicitPhysicalId, Ft as resetAwsClients, G as AssetPublisher, Gt as MissingCdkCliError, H as S3StateBackend, Ht as LocalMigrateError, I as assertRegionMatch, It as setAwsClients, J as buildAssetRedirectMap, Jt as ProvisioningError, K as stringifyValue, Kt as NestedStackChildDirectDestroyError, L as applyRoleArnIfSet, M as CDK_PATH_TAG, Mt as resolveBucketRegion, N as matchesCdkPath, Nt as AwsClients, O as IntrinsicFunctionResolver, Ot as uploadCfnTemplate, P as normalizeAwsTagsToCfn, Pt as getAwsClients, Q as AssetModeResolver, Qt as StackTerminationProtectionError, R as DiffCalculator, Rt as CdkdError, S as isRetryableTransientError, St as resolveUseCdkBootstrapAssets, T as CloudControlProvider, Tt as CFN_TEMPLATE_URL_LIMIT, U as rebuildClientForBucketRegion, Ut as LocalStartServiceError, V as LockManager, Vt as LocalInvokeBuildError$1, W as shouldRetainResource, X as loadPublishableAssetManifest, Xt as ResourceUpdateNotSupportedError, Y as createAssetRedirectResolver, Yt as ResourceTimeoutError, Z as rewriteTemplateAssetReferences, Zt as StackHasActiveImportsError, _ as yellow, _t as resolveAutoAssetStorage, a as IMPLICIT_DELETE_DEPENDENCIES, at as buildDockerImage, b as importTagWalk, bt as resolveStateBucketWithDefault, c as MULTI_REGION_RECREATE_BLOCKED_TYPES, ct as runDockerForeground, d as formatResourceLine, dt as getDockerImageBySourceHash, et as ensureAssetStorage, f as bold, ft as Synthesizer, g as red, gt as resolveApp, h as green, ht as getLegacyStateBucketName, i as withResourceDeadline, in as withErrorHandling, it as validateContainerRepoName, j as WAFv2WebACLProvider, k as cfnRefValueFromPhysicalId, kt as expectedOwnerParam, l as isStatefulRecreateTargetSync, lt as runDockerStreaming, m as gray, mt as getDefaultStateBucketName, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as parseBootstrapMarker, o as computeImplicitDeleteEdges, ot as formatDockerLoginError, p as cyan, pt as synthesisStatusMessage, q as WorkGraph, qt as PartialFailureError, r as DeployEngine, rn as normalizeAwsError, rt as validateAssetBucketName, s as extractDeploymentEventError, st as getDockerCmd, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as getBootstrapMarkerKey, u as renderStatefulReason, ut as AssetManifestLoader, v as IAMRoleProvider, vt as resolveCaptureObservedState, w as findActionableSilentDrops, wt as CFN_TEMPLATE_BODY_LIMIT, x as withRetry, xt as resolveStateBucketWithDefaultAndSource, y as collectInlinePolicyNamesManagedBySiblings, yt as resolveSkipPrefix, z as DagBuilder } from "./deploy-engine-CFUNbwD1.js";
|
|
3
3
|
import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as withSkipPrefix, i as runStackBuffered, n as getLogger, o as PATTERN_B_NAME_OPTIONS, p as withStackName, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-BYMEE-BS.js";
|
|
4
|
-
import { t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-BPtdM67j.js";
|
|
5
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
6
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
7
7
|
import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListBucketsCommand, ListDirectoryBucketsCommand, 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";
|
|
@@ -1888,7 +1888,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
1888
1888
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
1889
1889
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
1890
1890
|
function getCdkdVersion() {
|
|
1891
|
-
return "0.
|
|
1891
|
+
return "0.255.0";
|
|
1892
1892
|
}
|
|
1893
1893
|
/**
|
|
1894
1894
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -3504,28 +3504,36 @@ var IAMManagedPolicyProvider = class {
|
|
|
3504
3504
|
};
|
|
3505
3505
|
return null;
|
|
3506
3506
|
}
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3507
|
+
const match = await importTagWalk({
|
|
3508
|
+
cdkPath: input.cdkPath,
|
|
3509
|
+
logicalId: input.logicalId,
|
|
3510
|
+
listPage: async (marker) => {
|
|
3511
|
+
const list = await this.iamClient.send(new ListPoliciesCommand({
|
|
3512
|
+
Scope: "Local",
|
|
3513
|
+
...marker ? { Marker: marker } : {}
|
|
3514
|
+
}));
|
|
3515
|
+
return {
|
|
3516
|
+
items: list.Policies,
|
|
3517
|
+
nextMarker: list.IsTruncated ? list.Marker : void 0
|
|
3518
|
+
};
|
|
3519
|
+
},
|
|
3520
|
+
describe: async (policy) => {
|
|
3521
|
+
if (!policy.Arn) return void 0;
|
|
3516
3522
|
try {
|
|
3517
|
-
|
|
3518
|
-
physicalId: policy.Arn,
|
|
3519
|
-
attributes: { PolicyArn: policy.Arn }
|
|
3520
|
-
};
|
|
3523
|
+
return await this.iamClient.send(new ListPolicyTagsCommand({ PolicyArn: policy.Arn }));
|
|
3521
3524
|
} catch (err) {
|
|
3522
|
-
if (err instanceof NoSuchEntityException)
|
|
3525
|
+
if (err instanceof NoSuchEntityException) return void 0;
|
|
3523
3526
|
throw err;
|
|
3524
3527
|
}
|
|
3525
|
-
}
|
|
3526
|
-
|
|
3527
|
-
}
|
|
3528
|
-
return null;
|
|
3528
|
+
},
|
|
3529
|
+
tagsOf: (tags) => tags.Tags
|
|
3530
|
+
});
|
|
3531
|
+
if (!match) return null;
|
|
3532
|
+
const arn = match.summary.Arn;
|
|
3533
|
+
return {
|
|
3534
|
+
physicalId: arn,
|
|
3535
|
+
attributes: { PolicyArn: arn }
|
|
3536
|
+
};
|
|
3529
3537
|
}
|
|
3530
3538
|
async attachToPrincipals(policyArn, groups, roles, users) {
|
|
3531
3539
|
if (groups && Array.isArray(groups)) for (const groupName of groups) {
|
|
@@ -6297,22 +6305,32 @@ var S3BucketProvider = class {
|
|
|
6297
6305
|
if (e.name === "NotFound" || e.name === "NoSuchBucket") return null;
|
|
6298
6306
|
throw err;
|
|
6299
6307
|
}
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
attributes: {}
|
|
6308
|
+
const match = await importTagWalk({
|
|
6309
|
+
cdkPath: input.cdkPath,
|
|
6310
|
+
logicalId: input.logicalId,
|
|
6311
|
+
listPage: async () => {
|
|
6312
|
+
return {
|
|
6313
|
+
items: (await this.s3Client.send(new ListBucketsCommand({}))).Buckets,
|
|
6314
|
+
nextMarker: void 0
|
|
6308
6315
|
};
|
|
6309
|
-
}
|
|
6310
|
-
|
|
6311
|
-
if (
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
+
},
|
|
6317
|
+
describe: async (b) => {
|
|
6318
|
+
if (!b.Name) return void 0;
|
|
6319
|
+
try {
|
|
6320
|
+
return await this.s3Client.send(new GetBucketTaggingCommand({ Bucket: b.Name }));
|
|
6321
|
+
} catch (err) {
|
|
6322
|
+
const e = err;
|
|
6323
|
+
if (e.name === "NoSuchTagSet" || e.name === "AccessDenied" || e.$metadata?.httpStatusCode === 301) return;
|
|
6324
|
+
throw err;
|
|
6325
|
+
}
|
|
6326
|
+
},
|
|
6327
|
+
tagsOf: (tagging) => tagging.TagSet
|
|
6328
|
+
});
|
|
6329
|
+
if (!match) return null;
|
|
6330
|
+
return {
|
|
6331
|
+
physicalId: match.summary.Name,
|
|
6332
|
+
attributes: {}
|
|
6333
|
+
};
|
|
6316
6334
|
}
|
|
6317
6335
|
/**
|
|
6318
6336
|
* Delete a bucket, emptying it first if not empty.
|
|
@@ -7156,22 +7174,34 @@ var SQSQueueProvider = class {
|
|
|
7156
7174
|
if (err instanceof QueueDoesNotExist) return null;
|
|
7157
7175
|
throw err;
|
|
7158
7176
|
}
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7177
|
+
const match = await importTagWalk({
|
|
7178
|
+
cdkPath: input.cdkPath,
|
|
7179
|
+
logicalId: input.logicalId,
|
|
7180
|
+
listPage: async (marker) => {
|
|
7181
|
+
const list = await this.sqsClient.send(new ListQueuesCommand({ ...marker && { NextToken: marker } }));
|
|
7182
|
+
return {
|
|
7183
|
+
items: list.QueueUrls,
|
|
7184
|
+
nextMarker: list.NextToken
|
|
7167
7185
|
};
|
|
7168
|
-
}
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7186
|
+
},
|
|
7187
|
+
describe: async (url) => {
|
|
7188
|
+
try {
|
|
7189
|
+
return await this.sqsClient.send(new ListQueueTagsCommand({ QueueUrl: url }));
|
|
7190
|
+
} catch (err) {
|
|
7191
|
+
if (err instanceof QueueDoesNotExist) return void 0;
|
|
7192
|
+
throw err;
|
|
7193
|
+
}
|
|
7194
|
+
},
|
|
7195
|
+
tagsOf: (tagsResp) => Object.entries(tagsResp.Tags ?? {}).map(([Key, Value]) => ({
|
|
7196
|
+
Key,
|
|
7197
|
+
Value
|
|
7198
|
+
}))
|
|
7199
|
+
});
|
|
7200
|
+
if (!match) return null;
|
|
7201
|
+
return {
|
|
7202
|
+
physicalId: match.summary,
|
|
7203
|
+
attributes: {}
|
|
7204
|
+
};
|
|
7175
7205
|
}
|
|
7176
7206
|
};
|
|
7177
7207
|
|
|
@@ -7841,6 +7871,15 @@ var SNSTopicProvider = class {
|
|
|
7841
7871
|
* 1. `--resource` override → trust as ARN, verify via `GetTopicAttributes`.
|
|
7842
7872
|
* 2. `Properties.TopicName` → `ListTopics` to find matching ARN.
|
|
7843
7873
|
* 3. `aws:cdk:path` tag match via `ListTopics` + `ListTagsForResource`.
|
|
7874
|
+
*
|
|
7875
|
+
* Steps 2 and 3 share ONE `ListTopics` walk (per candidate: name check
|
|
7876
|
+
* first, then the tag read — only when a `cdkPath` is present), which runs
|
|
7877
|
+
* through the shared `importTagWalk` helper so the N+1 `ListTagsForResource`
|
|
7878
|
+
* burst is retried with exponential backoff when AWS throttles it instead
|
|
7879
|
+
* of aborting the whole import. The name match is expressed to the walk as
|
|
7880
|
+
* a synthetic `aws:cdk:path` tag carrying the walk's own lookup key, so a
|
|
7881
|
+
* name-only template (no CDK path metadata) still resolves without any tag
|
|
7882
|
+
* API call — matching the previous inline loop.
|
|
7844
7883
|
*/
|
|
7845
7884
|
async import(input) {
|
|
7846
7885
|
if (input.knownPhysicalId) try {
|
|
@@ -7854,28 +7893,40 @@ var SNSTopicProvider = class {
|
|
|
7854
7893
|
throw err;
|
|
7855
7894
|
}
|
|
7856
7895
|
const desiredName = typeof input.properties?.["TopicName"] === "string" ? input.properties["TopicName"] : void 0;
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7896
|
+
const walkCdkPath = input.cdkPath || (desiredName ? `cdkd:sns-topic-name:${desiredName}` : void 0);
|
|
7897
|
+
/** Sentinel detail for a candidate matched by its ARN-tail topic name. */
|
|
7898
|
+
const NAME_MATCH = { nameMatch: true };
|
|
7899
|
+
const match = await importTagWalk({
|
|
7900
|
+
cdkPath: walkCdkPath,
|
|
7901
|
+
logicalId: input.logicalId,
|
|
7902
|
+
listPage: async (marker) => {
|
|
7903
|
+
const list = await this.snsClient.send(new ListTopicsCommand({ ...marker && { NextToken: marker } }));
|
|
7904
|
+
return {
|
|
7905
|
+
items: list.Topics,
|
|
7906
|
+
nextMarker: list.NextToken
|
|
7866
7907
|
};
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7908
|
+
},
|
|
7909
|
+
describe: async (t) => {
|
|
7910
|
+
if (!t.TopicArn) return void 0;
|
|
7911
|
+
const arnTail = t.TopicArn.substring(t.TopicArn.lastIndexOf(":") + 1);
|
|
7912
|
+
if (desiredName && arnTail === desiredName) return NAME_MATCH;
|
|
7913
|
+
if (!input.cdkPath) return void 0;
|
|
7914
|
+
try {
|
|
7915
|
+
return await this.snsClient.send(new ListTagsForResourceCommand({ ResourceArn: t.TopicArn }));
|
|
7872
7916
|
} catch (err) {
|
|
7873
|
-
if (err instanceof NotFoundException)
|
|
7917
|
+
if (err instanceof NotFoundException) return void 0;
|
|
7874
7918
|
throw err;
|
|
7875
7919
|
}
|
|
7876
|
-
}
|
|
7877
|
-
|
|
7878
|
-
|
|
7920
|
+
},
|
|
7921
|
+
tagsOf: (detail) => "nameMatch" in detail ? [{
|
|
7922
|
+
Key: CDK_PATH_TAG,
|
|
7923
|
+
Value: walkCdkPath
|
|
7924
|
+
}] : detail.Tags
|
|
7925
|
+
});
|
|
7926
|
+
if (match?.summary.TopicArn) return {
|
|
7927
|
+
physicalId: match.summary.TopicArn,
|
|
7928
|
+
attributes: {}
|
|
7929
|
+
};
|
|
7879
7930
|
return null;
|
|
7880
7931
|
}
|
|
7881
7932
|
};
|
|
@@ -9232,8 +9283,12 @@ var LambdaFunctionProvider = class {
|
|
|
9232
9283
|
* 2. `ListFunctions` + `ListTags`, match `aws:cdk:path` tag.
|
|
9233
9284
|
*
|
|
9234
9285
|
* Lambda's `ListTags` returns a `Tags` map keyed by tag name (unlike
|
|
9235
|
-
* EC2/S3 which return an array of `{Key, Value}`), so
|
|
9236
|
-
*
|
|
9286
|
+
* EC2/S3 which return an array of `{Key, Value}`), so the map is re-shaped
|
|
9287
|
+
* to `{Key, Value}` entries for the walk's matcher.
|
|
9288
|
+
*
|
|
9289
|
+
* The tag walk runs through the shared `importTagWalk` helper, so the N+1
|
|
9290
|
+
* `ListTags` burst is retried with exponential backoff when AWS throttles
|
|
9291
|
+
* it instead of aborting the whole import.
|
|
9237
9292
|
*/
|
|
9238
9293
|
async import(input) {
|
|
9239
9294
|
const explicit = resolveExplicitPhysicalId(input, "FunctionName");
|
|
@@ -9247,25 +9302,35 @@ var LambdaFunctionProvider = class {
|
|
|
9247
9302
|
if (err instanceof ResourceNotFoundException) return null;
|
|
9248
9303
|
throw err;
|
|
9249
9304
|
}
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9305
|
+
const match = await importTagWalk({
|
|
9306
|
+
cdkPath: input.cdkPath,
|
|
9307
|
+
logicalId: input.logicalId,
|
|
9308
|
+
listPage: async (marker) => {
|
|
9309
|
+
const list = await this.lambdaClient.send(new ListFunctionsCommand({ ...marker && { Marker: marker } }));
|
|
9310
|
+
return {
|
|
9311
|
+
items: list.Functions,
|
|
9312
|
+
nextMarker: list.NextMarker
|
|
9313
|
+
};
|
|
9314
|
+
},
|
|
9315
|
+
describe: async (fn) => {
|
|
9316
|
+
if (!fn.FunctionArn || !fn.FunctionName) return void 0;
|
|
9256
9317
|
try {
|
|
9257
|
-
|
|
9258
|
-
physicalId: fn.FunctionName,
|
|
9259
|
-
attributes: {}
|
|
9260
|
-
};
|
|
9318
|
+
return await this.lambdaClient.send(new ListTagsCommand({ Resource: fn.FunctionArn }));
|
|
9261
9319
|
} catch (err) {
|
|
9262
|
-
if (err instanceof ResourceNotFoundException)
|
|
9320
|
+
if (err instanceof ResourceNotFoundException) return void 0;
|
|
9263
9321
|
throw err;
|
|
9264
9322
|
}
|
|
9265
|
-
}
|
|
9266
|
-
|
|
9267
|
-
|
|
9268
|
-
|
|
9323
|
+
},
|
|
9324
|
+
tagsOf: (tagsResp) => Object.entries(tagsResp.Tags ?? {}).map(([Key, Value]) => ({
|
|
9325
|
+
Key,
|
|
9326
|
+
Value
|
|
9327
|
+
}))
|
|
9328
|
+
});
|
|
9329
|
+
if (!match) return null;
|
|
9330
|
+
return {
|
|
9331
|
+
physicalId: match.summary.FunctionName,
|
|
9332
|
+
attributes: {}
|
|
9333
|
+
};
|
|
9269
9334
|
}
|
|
9270
9335
|
};
|
|
9271
9336
|
|
|
@@ -11404,24 +11469,33 @@ var DynamoDBTableProvider = class {
|
|
|
11404
11469
|
if (err instanceof ResourceNotFoundException$1) return null;
|
|
11405
11470
|
throw err;
|
|
11406
11471
|
}
|
|
11407
|
-
|
|
11408
|
-
|
|
11409
|
-
|
|
11410
|
-
|
|
11411
|
-
|
|
11412
|
-
|
|
11413
|
-
|
|
11414
|
-
|
|
11415
|
-
physicalId: name,
|
|
11416
|
-
attributes: {}
|
|
11472
|
+
const match = await importTagWalk({
|
|
11473
|
+
cdkPath: input.cdkPath,
|
|
11474
|
+
logicalId: input.logicalId,
|
|
11475
|
+
listPage: async (marker) => {
|
|
11476
|
+
const list = await this.dynamoDBClient.send(new ListTablesCommand({ ...marker && { ExclusiveStartTableName: marker } }));
|
|
11477
|
+
return {
|
|
11478
|
+
items: list.TableNames,
|
|
11479
|
+
nextMarker: list.LastEvaluatedTableName
|
|
11417
11480
|
};
|
|
11418
|
-
}
|
|
11419
|
-
|
|
11420
|
-
|
|
11421
|
-
|
|
11422
|
-
|
|
11423
|
-
|
|
11424
|
-
|
|
11481
|
+
},
|
|
11482
|
+
describe: async (name) => {
|
|
11483
|
+
try {
|
|
11484
|
+
const arn = (await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: name }))).Table?.TableArn;
|
|
11485
|
+
if (!arn) return void 0;
|
|
11486
|
+
return await this.dynamoDBClient.send(new ListTagsOfResourceCommand({ ResourceArn: arn }));
|
|
11487
|
+
} catch (err) {
|
|
11488
|
+
if (err instanceof ResourceNotFoundException$1) return void 0;
|
|
11489
|
+
throw err;
|
|
11490
|
+
}
|
|
11491
|
+
},
|
|
11492
|
+
tagsOf: (tagsResp) => tagsResp.Tags
|
|
11493
|
+
});
|
|
11494
|
+
if (!match) return null;
|
|
11495
|
+
return {
|
|
11496
|
+
physicalId: match.summary,
|
|
11497
|
+
attributes: {}
|
|
11498
|
+
};
|
|
11425
11499
|
}
|
|
11426
11500
|
};
|
|
11427
11501
|
|
|
@@ -13197,26 +13271,36 @@ var LogsLogGroupProvider = class {
|
|
|
13197
13271
|
if (err instanceof ResourceNotFoundException$4) return null;
|
|
13198
13272
|
throw err;
|
|
13199
13273
|
}
|
|
13200
|
-
|
|
13201
|
-
|
|
13202
|
-
|
|
13203
|
-
|
|
13204
|
-
|
|
13205
|
-
|
|
13274
|
+
const match = await importTagWalk({
|
|
13275
|
+
cdkPath: input.cdkPath,
|
|
13276
|
+
logicalId: input.logicalId,
|
|
13277
|
+
listPage: async (marker) => {
|
|
13278
|
+
const list = await this.logsClient.send(new DescribeLogGroupsCommand({ ...marker && { nextToken: marker } }));
|
|
13279
|
+
return {
|
|
13280
|
+
items: list.logGroups,
|
|
13281
|
+
nextMarker: list.nextToken
|
|
13282
|
+
};
|
|
13283
|
+
},
|
|
13284
|
+
describe: async (g) => {
|
|
13285
|
+
if (!g.logGroupName || !g.arn) return void 0;
|
|
13206
13286
|
const arnForTags = g.arn.replace(/:\*$/, "");
|
|
13207
13287
|
try {
|
|
13208
|
-
|
|
13209
|
-
physicalId: g.logGroupName,
|
|
13210
|
-
attributes: {}
|
|
13211
|
-
};
|
|
13288
|
+
return await this.logsClient.send(new ListTagsForResourceCommand$5({ resourceArn: arnForTags }));
|
|
13212
13289
|
} catch (err) {
|
|
13213
|
-
if (err instanceof ResourceNotFoundException$4)
|
|
13290
|
+
if (err instanceof ResourceNotFoundException$4) return void 0;
|
|
13214
13291
|
throw err;
|
|
13215
13292
|
}
|
|
13216
|
-
}
|
|
13217
|
-
|
|
13218
|
-
|
|
13219
|
-
|
|
13293
|
+
},
|
|
13294
|
+
tagsOf: (tagsResp) => Object.entries(tagsResp.tags ?? {}).map(([Key, Value]) => ({
|
|
13295
|
+
Key,
|
|
13296
|
+
Value
|
|
13297
|
+
}))
|
|
13298
|
+
});
|
|
13299
|
+
if (!match) return null;
|
|
13300
|
+
return {
|
|
13301
|
+
physicalId: match.summary.logGroupName,
|
|
13302
|
+
attributes: {}
|
|
13303
|
+
};
|
|
13220
13304
|
}
|
|
13221
13305
|
};
|
|
13222
13306
|
|
|
@@ -13533,26 +13617,32 @@ var CloudWatchAlarmProvider = class {
|
|
|
13533
13617
|
if (this.isNotFound(err)) return null;
|
|
13534
13618
|
throw err;
|
|
13535
13619
|
}
|
|
13536
|
-
|
|
13537
|
-
|
|
13538
|
-
|
|
13539
|
-
|
|
13540
|
-
|
|
13541
|
-
|
|
13542
|
-
|
|
13620
|
+
const match = await importTagWalk({
|
|
13621
|
+
cdkPath: input.cdkPath,
|
|
13622
|
+
logicalId: input.logicalId,
|
|
13623
|
+
listPage: async (marker) => {
|
|
13624
|
+
const list = await this.cloudWatchClient.send(new DescribeAlarmsCommand({ ...marker && { NextToken: marker } }));
|
|
13625
|
+
return {
|
|
13626
|
+
items: [...list.MetricAlarms ?? [], ...list.CompositeAlarms ?? []],
|
|
13627
|
+
nextMarker: list.NextToken
|
|
13628
|
+
};
|
|
13629
|
+
},
|
|
13630
|
+
describe: async (a) => {
|
|
13631
|
+
if (!a.AlarmArn || !a.AlarmName) return void 0;
|
|
13543
13632
|
try {
|
|
13544
|
-
|
|
13545
|
-
physicalId: a.AlarmName,
|
|
13546
|
-
attributes: {}
|
|
13547
|
-
};
|
|
13633
|
+
return await this.cloudWatchClient.send(new ListTagsForResourceCommand$4({ ResourceARN: a.AlarmArn }));
|
|
13548
13634
|
} catch (err) {
|
|
13549
|
-
if (this.isNotFound(err))
|
|
13635
|
+
if (this.isNotFound(err)) return void 0;
|
|
13550
13636
|
throw err;
|
|
13551
13637
|
}
|
|
13552
|
-
}
|
|
13553
|
-
|
|
13554
|
-
}
|
|
13555
|
-
return null;
|
|
13638
|
+
},
|
|
13639
|
+
tagsOf: (tagsResp) => tagsResp.Tags
|
|
13640
|
+
});
|
|
13641
|
+
if (!match) return null;
|
|
13642
|
+
return {
|
|
13643
|
+
physicalId: match.summary.AlarmName,
|
|
13644
|
+
attributes: {}
|
|
13645
|
+
};
|
|
13556
13646
|
}
|
|
13557
13647
|
isNotFound(err) {
|
|
13558
13648
|
if (!(err instanceof Error)) return false;
|
|
@@ -14129,28 +14219,35 @@ var SSMParameterProvider = class {
|
|
|
14129
14219
|
if (err instanceof ParameterNotFound) return null;
|
|
14130
14220
|
throw err;
|
|
14131
14221
|
}
|
|
14132
|
-
|
|
14133
|
-
|
|
14134
|
-
|
|
14135
|
-
|
|
14136
|
-
|
|
14137
|
-
|
|
14222
|
+
const match = await importTagWalk({
|
|
14223
|
+
cdkPath: input.cdkPath,
|
|
14224
|
+
logicalId: input.logicalId,
|
|
14225
|
+
listPage: async (marker) => {
|
|
14226
|
+
const list = await this.ssmClient.send(new DescribeParametersCommand({ ...marker && { NextToken: marker } }));
|
|
14227
|
+
return {
|
|
14228
|
+
items: list.Parameters,
|
|
14229
|
+
nextMarker: list.NextToken
|
|
14230
|
+
};
|
|
14231
|
+
},
|
|
14232
|
+
describe: async (p) => {
|
|
14233
|
+
if (!p.Name) return void 0;
|
|
14138
14234
|
try {
|
|
14139
|
-
|
|
14235
|
+
return await this.ssmClient.send(new ListTagsForResourceCommand$2({
|
|
14140
14236
|
ResourceType: "Parameter",
|
|
14141
14237
|
ResourceId: p.Name
|
|
14142
|
-
}))
|
|
14143
|
-
physicalId: p.Name,
|
|
14144
|
-
attributes: {}
|
|
14145
|
-
};
|
|
14238
|
+
}));
|
|
14146
14239
|
} catch (err) {
|
|
14147
|
-
if (err instanceof ParameterNotFound)
|
|
14240
|
+
if (err instanceof ParameterNotFound) return void 0;
|
|
14148
14241
|
throw err;
|
|
14149
14242
|
}
|
|
14150
|
-
}
|
|
14151
|
-
|
|
14152
|
-
}
|
|
14153
|
-
return null;
|
|
14243
|
+
},
|
|
14244
|
+
tagsOf: (tagsResp) => tagsResp.TagList
|
|
14245
|
+
});
|
|
14246
|
+
if (!match) return null;
|
|
14247
|
+
return {
|
|
14248
|
+
physicalId: match.summary.Name,
|
|
14249
|
+
attributes: {}
|
|
14250
|
+
};
|
|
14154
14251
|
}
|
|
14155
14252
|
};
|
|
14156
14253
|
|
|
@@ -25212,155 +25309,6 @@ var RDSDBProxyTargetGroupProvider = class {
|
|
|
25212
25309
|
}
|
|
25213
25310
|
};
|
|
25214
25311
|
|
|
25215
|
-
//#endregion
|
|
25216
|
-
//#region src/provisioning/import-tag-walk.ts
|
|
25217
|
-
/**
|
|
25218
|
-
* Shared, throttle-tolerant `aws:cdk:path` tag walk for `ResourceProvider.import`.
|
|
25219
|
-
*
|
|
25220
|
-
* Providers that adopt a resource without an explicit name property fall back
|
|
25221
|
-
* to step 3 of the lookup order documented in `./import-helpers.ts`: enumerate
|
|
25222
|
-
* the service's `List*`/`Describe*` pages, then issue ONE per-candidate read
|
|
25223
|
-
* (`DescribeX` / `ListTagsForResource`) to obtain the tag set — the list
|
|
25224
|
-
* summaries usually do not carry tags. That is an inherent **N+1** read
|
|
25225
|
-
* pattern: an account with many resources of the type produces one API call
|
|
25226
|
-
* per candidate in a tight loop, which is exactly the shape AWS rate-limits.
|
|
25227
|
-
*
|
|
25228
|
-
* Every provider previously hand-rolled this loop with NO backoff, so a single
|
|
25229
|
-
* throttled `Describe*` aborted the whole `cdkd import` run. This helper
|
|
25230
|
-
* centralises the loop and wraps BOTH the list page fetch and the per-candidate
|
|
25231
|
-
* describe in the deploy engine's `withRetry` with exponential backoff.
|
|
25232
|
-
*
|
|
25233
|
-
* ## Why a narrower classifier than `isRetryableTransientError`
|
|
25234
|
-
*
|
|
25235
|
-
* The deploy engine's classifier is tuned for the WRITE path: it also treats
|
|
25236
|
-
* eventual-consistency phrasings like `does not exist` / `not authorized to
|
|
25237
|
-
* perform` as transient, because a just-created dependency legitimately needs a
|
|
25238
|
-
* moment to propagate. On a read-only import walk those messages mean the
|
|
25239
|
-
* opposite — the candidate really is gone, or the caller's credentials really
|
|
25240
|
-
* lack the permission — and retrying them burns the full backoff budget per
|
|
25241
|
-
* candidate before surfacing the true error.
|
|
25242
|
-
*
|
|
25243
|
-
* So the walk retries throttling ONLY, reusing the deploy engine's throttle
|
|
25244
|
-
* tables verbatim ({@link THROTTLING_ERROR_NAMES} /
|
|
25245
|
-
* {@link RETRYABLE_HTTP_STATUS_CODES}) rather than maintaining a second copy.
|
|
25246
|
-
*
|
|
25247
|
-
* ## Batching
|
|
25248
|
-
*
|
|
25249
|
-
* Batched tag reads are deliberately NOT modelled here: the services this
|
|
25250
|
-
* helper currently serves (EMR `DescribeCluster`, DocDB
|
|
25251
|
-
* `ListTagsForResource`) expose only single-resource reads. A service that
|
|
25252
|
-
* genuinely offers a batch API (e.g. CodeCommit `BatchGetRepositories`) can
|
|
25253
|
-
* satisfy several candidates from one call inside its own `describe` callback,
|
|
25254
|
-
* or bypass the helper entirely.
|
|
25255
|
-
*/
|
|
25256
|
-
/** Max number of retries after the first attempt, per API call in the walk. */
|
|
25257
|
-
const DEFAULT_MAX_RETRIES = 5;
|
|
25258
|
-
/** Initial backoff; each retry doubles it up to {@link DEFAULT_MAX_DELAY_MS}. */
|
|
25259
|
-
const DEFAULT_INITIAL_DELAY_MS = 500;
|
|
25260
|
-
/** Cap for the per-retry delay (0.5s -> 1s -> 2s -> 4s -> 5s, ~12.5s total). */
|
|
25261
|
-
const DEFAULT_MAX_DELAY_MS = 5e3;
|
|
25262
|
-
/**
|
|
25263
|
-
* Wall-clock ceiling for the WHOLE walk (all pages + all candidates), not just
|
|
25264
|
-
* one call. Backoff is per-call, so without this a sustained throttle against a
|
|
25265
|
-
* large account degrades into `(pages + candidates) x ~12.5s` of near-silent
|
|
25266
|
-
* retrying — ~42 minutes for 200 candidates, with no way to tell a slow walk
|
|
25267
|
-
* from a hung one. 10 minutes is generous for a healthy walk (a 200-candidate
|
|
25268
|
-
* DocDB account completes in seconds when AWS is not throttling) and bounds the
|
|
25269
|
-
* pathological case to something a user will wait through.
|
|
25270
|
-
*/
|
|
25271
|
-
const DEFAULT_MAX_WALK_MS = 10 * 6e4;
|
|
25272
|
-
/**
|
|
25273
|
-
* Ceiling on pages fetched. A service that returns a non-advancing pagination
|
|
25274
|
-
* token (a bug, or a marker cdkd echoes back wrongly) would otherwise spin
|
|
25275
|
-
* forever. This is now the shared path every migrated provider runs on, so the
|
|
25276
|
-
* guard belongs here rather than in each caller.
|
|
25277
|
-
*/
|
|
25278
|
-
const DEFAULT_MAX_PAGES = 1e3;
|
|
25279
|
-
/**
|
|
25280
|
-
* Whether an error hit during the read-only tag walk is a rate-limit rejection
|
|
25281
|
-
* worth backing off on.
|
|
25282
|
-
*
|
|
25283
|
-
* Delegates the error + `.cause` chain traversal to the deploy engine's
|
|
25284
|
-
* {@link isThrottlingError} (throttling error names + retryable HTTP statuses,
|
|
25285
|
-
* at every cause depth) and adds the canonical `Rate exceeded` message, which
|
|
25286
|
-
* several services return with an HTTP 400 and a service-specific error name.
|
|
25287
|
-
*
|
|
25288
|
-
* This is deliberately NARROWER than `isRetryableTransientError`: that
|
|
25289
|
-
* classifier also treats write-path eventual-consistency phrasings (`does not
|
|
25290
|
-
* exist`, `not authorized to perform`) as transient, because a just-created
|
|
25291
|
-
* dependency legitimately needs a moment to propagate. On a read-only walk
|
|
25292
|
-
* those mean the candidate really is gone or the credentials really lack the
|
|
25293
|
-
* permission, and retrying them burns the full backoff budget per candidate
|
|
25294
|
-
* before surfacing the true error.
|
|
25295
|
-
*
|
|
25296
|
-
* Exported for direct unit testing and for providers whose tag walk cannot use
|
|
25297
|
-
* {@link importTagWalk} verbatim.
|
|
25298
|
-
*/
|
|
25299
|
-
function isThrottlingLikeError(error, message) {
|
|
25300
|
-
return isThrottlingError(error) || message.includes("Rate exceeded");
|
|
25301
|
-
}
|
|
25302
|
-
/** Thrown when the walk exceeds its wall-clock budget or page ceiling. */
|
|
25303
|
-
var ImportTagWalkLimitError = class extends Error {
|
|
25304
|
-
constructor(message) {
|
|
25305
|
-
super(message);
|
|
25306
|
-
this.name = "ImportTagWalkLimitError";
|
|
25307
|
-
}
|
|
25308
|
-
};
|
|
25309
|
-
/**
|
|
25310
|
-
* Paginate `listPage`, `describe` each candidate, and return the first one
|
|
25311
|
-
* whose tags carry the requested `aws:cdk:path`. Returns `null` when no
|
|
25312
|
-
* candidate matches (or when `cdkPath` is empty).
|
|
25313
|
-
*
|
|
25314
|
-
* Both callbacks are individually retried with exponential backoff on
|
|
25315
|
-
* throttling errors, so one rate-limited call mid-walk no longer aborts the
|
|
25316
|
-
* whole import.
|
|
25317
|
-
*/
|
|
25318
|
-
async function importTagWalk(options) {
|
|
25319
|
-
const { cdkPath, listPage, describe, tagsOf } = options;
|
|
25320
|
-
if (!cdkPath) return null;
|
|
25321
|
-
const logicalId = options.logicalId ?? "import";
|
|
25322
|
-
const logger = options.retry?.logger ?? getLogger();
|
|
25323
|
-
const maxWalkMs = options.retry?.maxWalkMs ?? DEFAULT_MAX_WALK_MS;
|
|
25324
|
-
const maxPages = options.retry?.maxPages ?? DEFAULT_MAX_PAGES;
|
|
25325
|
-
const retryOpts = {
|
|
25326
|
-
maxRetries: options.retry?.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
25327
|
-
initialDelayMs: options.retry?.initialDelayMs ?? DEFAULT_INITIAL_DELAY_MS,
|
|
25328
|
-
maxDelayMs: options.retry?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,
|
|
25329
|
-
isRetryable: (message, error) => isThrottlingLikeError(error, message),
|
|
25330
|
-
logger,
|
|
25331
|
-
...options.retry?.isInterrupted && { isInterrupted: options.retry.isInterrupted },
|
|
25332
|
-
...options.retry?.onInterrupted && { onInterrupted: options.retry.onInterrupted },
|
|
25333
|
-
...options.retry?.sleep && { sleep: options.retry.sleep }
|
|
25334
|
-
};
|
|
25335
|
-
const startedAt = Date.now();
|
|
25336
|
-
const assertWithinBudget = (stage) => {
|
|
25337
|
-
const elapsed = Date.now() - startedAt;
|
|
25338
|
-
if (elapsed >= maxWalkMs) throw new ImportTagWalkLimitError(`Timed out looking up ${logicalId} by its aws:cdk:path tag after ${Math.round(elapsed / 1e3)}s (limit ${Math.round(maxWalkMs / 1e3)}s, while ${stage}). AWS is likely throttling the lookup; retry, or pass an explicit physical id with --resource ${logicalId}=<physicalId>.`);
|
|
25339
|
-
};
|
|
25340
|
-
let marker;
|
|
25341
|
-
let pages = 0;
|
|
25342
|
-
do {
|
|
25343
|
-
assertWithinBudget("listing candidates");
|
|
25344
|
-
if (++pages > maxPages) throw new ImportTagWalkLimitError(`Gave up looking up ${logicalId} by its aws:cdk:path tag after ${maxPages} pages (the service may be returning a non-advancing pagination token). Pass an explicit physical id with --resource ${logicalId}=<physicalId>.`);
|
|
25345
|
-
const currentMarker = marker;
|
|
25346
|
-
const page = await withRetry(() => listPage(currentMarker), logicalId, retryOpts);
|
|
25347
|
-
for (const summary of page.items ?? []) {
|
|
25348
|
-
assertWithinBudget("reading candidate tags");
|
|
25349
|
-
const detail = await withRetry(() => describe(summary), logicalId, retryOpts);
|
|
25350
|
-
if (detail === void 0) {
|
|
25351
|
-
logger.debug(` ↷ Skipped an ${logicalId} import candidate: its detail lookup returned no result`);
|
|
25352
|
-
continue;
|
|
25353
|
-
}
|
|
25354
|
-
if (matchesCdkPath(tagsOf(detail, summary), cdkPath)) return {
|
|
25355
|
-
summary,
|
|
25356
|
-
detail
|
|
25357
|
-
};
|
|
25358
|
-
}
|
|
25359
|
-
marker = page.nextMarker;
|
|
25360
|
-
} while (marker);
|
|
25361
|
-
return null;
|
|
25362
|
-
}
|
|
25363
|
-
|
|
25364
25312
|
//#endregion
|
|
25365
25313
|
//#region src/provisioning/providers/docdb-provider.ts
|
|
25366
25314
|
/**
|
|
@@ -33297,9 +33245,12 @@ var KinesisStreamProvider = class {
|
|
|
33297
33245
|
* with `DescribeStream`.
|
|
33298
33246
|
* 2. Walk `ListStreams` (paged via `ExclusiveStartStreamName`) and
|
|
33299
33247
|
* match the `aws:cdk:path` tag via `ListTagsForStream(StreamName)`.
|
|
33248
|
+
* The walk runs through the shared `importTagWalk` helper, so the N+1
|
|
33249
|
+
* tag-read burst is retried with exponential backoff when AWS
|
|
33250
|
+
* throttles it instead of aborting the whole import.
|
|
33300
33251
|
*
|
|
33301
33252
|
* Kinesis tags use the standard `Tag[]` array shape (`Key`/`Value`),
|
|
33302
|
-
* so `matchesCdkPath`
|
|
33253
|
+
* so the walk's `matchesCdkPath` matcher applies directly.
|
|
33303
33254
|
*/
|
|
33304
33255
|
/**
|
|
33305
33256
|
* Read the AWS-current Kinesis stream configuration in CFn-property shape.
|
|
@@ -33363,19 +33314,25 @@ var KinesisStreamProvider = class {
|
|
|
33363
33314
|
if (err instanceof ResourceNotFoundException$8) return null;
|
|
33364
33315
|
throw err;
|
|
33365
33316
|
}
|
|
33366
|
-
|
|
33367
|
-
|
|
33368
|
-
|
|
33369
|
-
|
|
33370
|
-
|
|
33371
|
-
|
|
33372
|
-
|
|
33373
|
-
|
|
33374
|
-
|
|
33375
|
-
|
|
33376
|
-
|
|
33377
|
-
|
|
33378
|
-
|
|
33317
|
+
const match = await importTagWalk({
|
|
33318
|
+
cdkPath: input.cdkPath,
|
|
33319
|
+
logicalId: input.logicalId,
|
|
33320
|
+
listPage: async (marker) => {
|
|
33321
|
+
const list = await this.getClient().send(new ListStreamsCommand({ ...marker && { ExclusiveStartStreamName: marker } }));
|
|
33322
|
+
const names = list.StreamNames ?? [];
|
|
33323
|
+
return {
|
|
33324
|
+
items: names,
|
|
33325
|
+
nextMarker: list.HasMoreStreams && names.length > 0 ? names[names.length - 1] : void 0
|
|
33326
|
+
};
|
|
33327
|
+
},
|
|
33328
|
+
describe: async (streamName) => await this.getClient().send(new ListTagsForStreamCommand({ StreamName: streamName })),
|
|
33329
|
+
tagsOf: (tagsResp) => tagsResp.Tags
|
|
33330
|
+
});
|
|
33331
|
+
if (!match) return null;
|
|
33332
|
+
return {
|
|
33333
|
+
physicalId: match.summary,
|
|
33334
|
+
attributes: {}
|
|
33335
|
+
};
|
|
33379
33336
|
}
|
|
33380
33337
|
/**
|
|
33381
33338
|
* Poll DescribeStream until the stream reaches ACTIVE status
|
|
@@ -35042,7 +34999,10 @@ var FSxFileSystemProvider = class {
|
|
|
35042
34999
|
diff: {},
|
|
35043
35000
|
hasMutableDiff: false
|
|
35044
35001
|
};
|
|
35045
|
-
const
|
|
35002
|
+
const resolvedStorageCapacity = toNumber$3(properties["StorageCapacity"]);
|
|
35003
|
+
const storageCapacityIsPlaceholder = resolvedStorageCapacity !== void 0 && resolvedStorageCapacity <= 0;
|
|
35004
|
+
if (storageCapacityIsPlaceholder && changed("StorageCapacity")) this.logger.debug(`Suppressing non-positive StorageCapacity (${resolvedStorageCapacity}) for FSx FileSystem ${logicalId}: this is the readCurrentState placeholder for a capacity-less file system (Lustre Intelligent-Tiering), not a desired value.`);
|
|
35005
|
+
const storageCapacityChanged = changed("StorageCapacity") && !storageCapacityIsPlaceholder;
|
|
35046
35006
|
const storageTypeChanged = changed("StorageType");
|
|
35047
35007
|
const typeVersionChanged = changed("FileSystemTypeVersion");
|
|
35048
35008
|
const networkTypeChanged = changed("NetworkType");
|
|
@@ -35430,6 +35390,40 @@ var FSxFileSystemProvider = class {
|
|
|
35430
35390
|
default: return;
|
|
35431
35391
|
}
|
|
35432
35392
|
}
|
|
35393
|
+
/** Map the read-side `LustreConfiguration` back to CFn input shape. */
|
|
35394
|
+
readLustreConfiguration(lustre) {
|
|
35395
|
+
const config = {};
|
|
35396
|
+
putIfDefined(config, "WeeklyMaintenanceStartTime", lustre.WeeklyMaintenanceStartTime);
|
|
35397
|
+
putIfDefined(config, "DeploymentType", lustre.DeploymentType);
|
|
35398
|
+
putIfDefined(config, "PerUnitStorageThroughput", lustre.PerUnitStorageThroughput);
|
|
35399
|
+
putIfDefined(config, "DailyAutomaticBackupStartTime", lustre.DailyAutomaticBackupStartTime);
|
|
35400
|
+
putIfDefined(config, "AutomaticBackupRetentionDays", lustre.AutomaticBackupRetentionDays);
|
|
35401
|
+
putIfDefined(config, "CopyTagsToBackups", lustre.CopyTagsToBackups);
|
|
35402
|
+
putIfDefined(config, "DriveCacheType", lustre.DriveCacheType);
|
|
35403
|
+
putIfDefined(config, "DataCompressionType", lustre.DataCompressionType);
|
|
35404
|
+
putIfDefined(config, "EfaEnabled", lustre.EfaEnabled);
|
|
35405
|
+
putIfDefined(config, "ThroughputCapacity", lustre.ThroughputCapacity);
|
|
35406
|
+
if (lustre.MetadataConfiguration) {
|
|
35407
|
+
const metadata = {};
|
|
35408
|
+
putIfDefined(metadata, "Mode", lustre.MetadataConfiguration.Mode);
|
|
35409
|
+
putIfDefined(metadata, "Iops", lustre.MetadataConfiguration.Iops);
|
|
35410
|
+
if (Object.keys(metadata).length > 0) config["MetadataConfiguration"] = metadata;
|
|
35411
|
+
}
|
|
35412
|
+
if (lustre.DataReadCacheConfiguration) {
|
|
35413
|
+
const readCache = {};
|
|
35414
|
+
putIfDefined(readCache, "SizingMode", lustre.DataReadCacheConfiguration.SizingMode);
|
|
35415
|
+
putIfDefined(readCache, "SizeGiB", lustre.DataReadCacheConfiguration.SizeGiB);
|
|
35416
|
+
if (Object.keys(readCache).length > 0) config["DataReadCacheConfiguration"] = readCache;
|
|
35417
|
+
}
|
|
35418
|
+
const dataRepo = lustre.DataRepositoryConfiguration;
|
|
35419
|
+
if (dataRepo) {
|
|
35420
|
+
putIfDefined(config, "ImportPath", dataRepo.ImportPath);
|
|
35421
|
+
putIfDefined(config, "ExportPath", dataRepo.ExportPath);
|
|
35422
|
+
putIfDefined(config, "AutoImportPolicy", dataRepo.AutoImportPolicy);
|
|
35423
|
+
putIfDefined(config, "ImportedFileChunkSize", dataRepo.ImportedFileChunkSize);
|
|
35424
|
+
}
|
|
35425
|
+
return config;
|
|
35426
|
+
}
|
|
35433
35427
|
/** Map the read-side `WindowsConfiguration` back to CFn input shape. */
|
|
35434
35428
|
readWindowsConfiguration(windows) {
|
|
35435
35429
|
const config = {};
|
|
@@ -35587,8 +35581,14 @@ var FSxFileSystemProvider = class {
|
|
|
35587
35581
|
* mapped back from the nested `DataRepositoryConfiguration` the API
|
|
35588
35582
|
* returns. The Windows / ONTAP / OpenZFS variant blocks are reverse-mapped
|
|
35589
35583
|
* by their respective `read*Configuration` helpers; the few inputs AWS
|
|
35590
|
-
* never returns stay listed in {@link getDriftUnknownPaths}.
|
|
35591
|
-
*
|
|
35584
|
+
* never returns stay listed in {@link getDriftUnknownPaths}.
|
|
35585
|
+
*
|
|
35586
|
+
* Emission follows `docs/provider-development.md` §3b: every top-level
|
|
35587
|
+
* property `update()` can mutate is emitted unconditionally with a
|
|
35588
|
+
* placeholder, registry-createOnly properties keep their guard, and the
|
|
35589
|
+
* `<Variant>Configuration` blocks take the Class 1 type-discriminator
|
|
35590
|
+
* carve-out — exactly the ONE block matching `FileSystemType` is emitted
|
|
35591
|
+
* (at most one is ever legal on AWS), never the other three.
|
|
35592
35592
|
* Returns `undefined` when the file system is gone.
|
|
35593
35593
|
*/
|
|
35594
35594
|
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
@@ -35603,59 +35603,31 @@ var FSxFileSystemProvider = class {
|
|
|
35603
35603
|
if (!fs) return void 0;
|
|
35604
35604
|
const result = {};
|
|
35605
35605
|
putIfDefined(result, "FileSystemType", fs.FileSystemType);
|
|
35606
|
-
putIfDefined(result, "StorageCapacity", fs.StorageCapacity);
|
|
35607
|
-
putIfDefined(result, "StorageType", fs.StorageType);
|
|
35608
35606
|
putIfDefined(result, "SubnetIds", fs.SubnetIds ? [...fs.SubnetIds] : void 0);
|
|
35609
35607
|
putIfDefined(result, "KmsKeyId", fs.KmsKeyId);
|
|
35610
|
-
|
|
35611
|
-
|
|
35612
|
-
|
|
35613
|
-
|
|
35614
|
-
const config = {};
|
|
35615
|
-
putIfDefined(config, "WeeklyMaintenanceStartTime", lustre.WeeklyMaintenanceStartTime);
|
|
35616
|
-
putIfDefined(config, "DeploymentType", lustre.DeploymentType);
|
|
35617
|
-
putIfDefined(config, "PerUnitStorageThroughput", lustre.PerUnitStorageThroughput);
|
|
35618
|
-
putIfDefined(config, "DailyAutomaticBackupStartTime", lustre.DailyAutomaticBackupStartTime);
|
|
35619
|
-
putIfDefined(config, "AutomaticBackupRetentionDays", lustre.AutomaticBackupRetentionDays);
|
|
35620
|
-
putIfDefined(config, "CopyTagsToBackups", lustre.CopyTagsToBackups);
|
|
35621
|
-
putIfDefined(config, "DriveCacheType", lustre.DriveCacheType);
|
|
35622
|
-
putIfDefined(config, "DataCompressionType", lustre.DataCompressionType);
|
|
35623
|
-
putIfDefined(config, "EfaEnabled", lustre.EfaEnabled);
|
|
35624
|
-
putIfDefined(config, "ThroughputCapacity", lustre.ThroughputCapacity);
|
|
35625
|
-
if (lustre.MetadataConfiguration) {
|
|
35626
|
-
const metadata = {};
|
|
35627
|
-
putIfDefined(metadata, "Mode", lustre.MetadataConfiguration.Mode);
|
|
35628
|
-
putIfDefined(metadata, "Iops", lustre.MetadataConfiguration.Iops);
|
|
35629
|
-
if (Object.keys(metadata).length > 0) config["MetadataConfiguration"] = metadata;
|
|
35630
|
-
}
|
|
35631
|
-
if (lustre.DataReadCacheConfiguration) {
|
|
35632
|
-
const readCache = {};
|
|
35633
|
-
putIfDefined(readCache, "SizingMode", lustre.DataReadCacheConfiguration.SizingMode);
|
|
35634
|
-
putIfDefined(readCache, "SizeGiB", lustre.DataReadCacheConfiguration.SizeGiB);
|
|
35635
|
-
if (Object.keys(readCache).length > 0) config["DataReadCacheConfiguration"] = readCache;
|
|
35636
|
-
}
|
|
35637
|
-
const dataRepo = lustre.DataRepositoryConfiguration;
|
|
35638
|
-
if (dataRepo) {
|
|
35639
|
-
putIfDefined(config, "ImportPath", dataRepo.ImportPath);
|
|
35640
|
-
putIfDefined(config, "ExportPath", dataRepo.ExportPath);
|
|
35641
|
-
putIfDefined(config, "AutoImportPolicy", dataRepo.AutoImportPolicy);
|
|
35642
|
-
putIfDefined(config, "ImportedFileChunkSize", dataRepo.ImportedFileChunkSize);
|
|
35643
|
-
}
|
|
35644
|
-
if (Object.keys(config).length > 0) result["LustreConfiguration"] = config;
|
|
35645
|
-
}
|
|
35646
|
-
if (fs.WindowsConfiguration) {
|
|
35647
|
-
const config = this.readWindowsConfiguration(fs.WindowsConfiguration);
|
|
35648
|
-
if (Object.keys(config).length > 0) result["WindowsConfiguration"] = config;
|
|
35649
|
-
}
|
|
35650
|
-
if (fs.OntapConfiguration) {
|
|
35651
|
-
const config = this.readOntapConfiguration(fs.OntapConfiguration);
|
|
35652
|
-
if (Object.keys(config).length > 0) result["OntapConfiguration"] = config;
|
|
35653
|
-
}
|
|
35654
|
-
if (fs.OpenZFSConfiguration) {
|
|
35655
|
-
const config = this.readOpenZFSConfiguration(fs.OpenZFSConfiguration);
|
|
35656
|
-
if (Object.keys(config).length > 0) result["OpenZFSConfiguration"] = config;
|
|
35657
|
-
}
|
|
35608
|
+
result["StorageCapacity"] = fs.StorageCapacity ?? 0;
|
|
35609
|
+
result["StorageType"] = fs.StorageType ?? "SSD";
|
|
35610
|
+
result["FileSystemTypeVersion"] = fs.FileSystemTypeVersion ?? "";
|
|
35611
|
+
result["NetworkType"] = fs.NetworkType ?? "IPV4";
|
|
35658
35612
|
result["Tags"] = normalizeAwsTagsToCfn(fs.Tags);
|
|
35613
|
+
const variantKey = fs.FileSystemType ? VARIANT_CONFIG_KEY[fs.FileSystemType] : void 0;
|
|
35614
|
+
switch (variantKey) {
|
|
35615
|
+
case "LustreConfiguration":
|
|
35616
|
+
result[variantKey] = this.readLustreConfiguration(fs.LustreConfiguration ?? {});
|
|
35617
|
+
break;
|
|
35618
|
+
case "WindowsConfiguration":
|
|
35619
|
+
result[variantKey] = this.readWindowsConfiguration(fs.WindowsConfiguration ?? {});
|
|
35620
|
+
break;
|
|
35621
|
+
case "OntapConfiguration":
|
|
35622
|
+
result[variantKey] = this.readOntapConfiguration(fs.OntapConfiguration ?? {});
|
|
35623
|
+
break;
|
|
35624
|
+
case "OpenZFSConfiguration":
|
|
35625
|
+
result[variantKey] = this.readOpenZFSConfiguration(fs.OpenZFSConfiguration ?? {});
|
|
35626
|
+
break;
|
|
35627
|
+
default:
|
|
35628
|
+
this.logger.warn(`FSx FileSystem ${physicalId} has FileSystemType '${fs.FileSystemType ?? "(unset)"}', which cdkd does not recognize (expected one of ${Object.keys(VARIANT_CONFIG_KEY).join(" / ")}). Its variant configuration is NOT included in the drift snapshot, so drift in that block cannot be detected. Please report this at https://github.com/go-to-k/cdkd/issues`);
|
|
35629
|
+
break;
|
|
35630
|
+
}
|
|
35659
35631
|
return result;
|
|
35660
35632
|
}
|
|
35661
35633
|
/**
|
|
@@ -41422,25 +41394,32 @@ var ECRProvider = class {
|
|
|
41422
41394
|
if (err instanceof RepositoryNotFoundException) return null;
|
|
41423
41395
|
throw err;
|
|
41424
41396
|
}
|
|
41425
|
-
|
|
41426
|
-
|
|
41427
|
-
|
|
41428
|
-
|
|
41429
|
-
|
|
41430
|
-
|
|
41397
|
+
const match = await importTagWalk({
|
|
41398
|
+
cdkPath: input.cdkPath,
|
|
41399
|
+
logicalId: input.logicalId,
|
|
41400
|
+
listPage: async (marker) => {
|
|
41401
|
+
const list = await this.getClient().send(new DescribeRepositoriesCommand({ ...marker && { nextToken: marker } }));
|
|
41402
|
+
return {
|
|
41403
|
+
items: list.repositories,
|
|
41404
|
+
nextMarker: list.nextToken
|
|
41405
|
+
};
|
|
41406
|
+
},
|
|
41407
|
+
describe: async (repo) => {
|
|
41408
|
+
if (!repo.repositoryArn || !repo.repositoryName) return void 0;
|
|
41431
41409
|
try {
|
|
41432
|
-
|
|
41433
|
-
physicalId: repo.repositoryName,
|
|
41434
|
-
attributes: {}
|
|
41435
|
-
};
|
|
41410
|
+
return await this.getClient().send(new ListTagsForResourceCommand$8({ resourceArn: repo.repositoryArn }));
|
|
41436
41411
|
} catch (err) {
|
|
41437
|
-
if (err instanceof RepositoryNotFoundException)
|
|
41412
|
+
if (err instanceof RepositoryNotFoundException) return void 0;
|
|
41438
41413
|
throw err;
|
|
41439
41414
|
}
|
|
41440
|
-
}
|
|
41441
|
-
|
|
41442
|
-
}
|
|
41443
|
-
return null;
|
|
41415
|
+
},
|
|
41416
|
+
tagsOf: (tagsResp) => tagsResp.tags
|
|
41417
|
+
});
|
|
41418
|
+
if (!match) return null;
|
|
41419
|
+
return {
|
|
41420
|
+
physicalId: match.summary.repositoryName,
|
|
41421
|
+
attributes: {}
|
|
41422
|
+
};
|
|
41444
41423
|
}
|
|
41445
41424
|
};
|
|
41446
41425
|
|
|
@@ -62069,6 +62048,47 @@ function createMigrateCommand() {
|
|
|
62069
62048
|
return new Command("migrate").description("Adopt a plain (non-CDK) CloudFormation stack into a cdkd-managed CDK app. Generates new CDK code via upstream `cdk migrate`, builds a logical-ID mapping between the source CFn template and the synth template, writes cdkd state, and (optionally) retires the source CFn stack. AWS resources are never modified.").argument("[stack]", "Source CFn stack name. Alias for --from-cfn-stack.").addOption(new Option("--from-cfn-stack <name>", "Source CloudFormation stack name to adopt. Required (or pass positionally).")).addOption(new Option("--output-dir <dir>", "Directory to write the generated CDK app to. Defaults to <cwd>/<CfnStackName>.")).addOption(new Option("--language <choice>", "Generated code language. v1: typescript only.").choices(["typescript"]).default("typescript")).addOption(new Option("--region <region>", "AWS region. Defaults to AWS_REGION env / profile.")).addOption(new Option("--account <id>", "AWS account ID. Auto-detected via STS when omitted.")).addOption(new Option("--retire-cfn-stack", "After cdkd state is written, inject DeletionPolicy=Retain on every resource in the source CFn stack and DeleteStack. AWS resources stay; the CFn stack record is gone. Off by default.").default(false)).addOption(new Option("--filter <key=value>", "Pass-through to `cdk migrate --filter` for resource subsetting. Repeatable.").argParser((value, previous) => [...previous ?? [], value]).default([])).addOption(new Option("--skip-install", "Skip `npm install` after codegen.").default(false)).addOption(new Option("--skip-synth", "Skip `cdk synth` (does NOT write cdkd state). Mutually exclusive with --retire-cfn-stack.").default(false)).addOption(new Option("--dry-run", "Print the import plan without writing state or retiring the CFn stack. Mutually exclusive with --retire-cfn-stack.").default(false)).addOption(new Option("-y, --yes", "Auto-confirm the import + retirement prompts.").default(false)).addOption(new Option("--cdk-bin <path>", "Override the `cdk` binary path.")).addOption(new Option("--resource-mapping <file>", `Path to a JSON file of {sourceLogicalId: synthLogicalId} overrides. Same shape as the auto-written ${RESOURCE_MAPPING_FILENAME}.`)).addOption(new Option("--state-bucket <name>", "cdkd state bucket. Defaults to cdkd-state-<accountId>.")).addOption(new Option("--state-prefix <prefix>", "cdkd state prefix inside the bucket.").default("cdkd")).addOption(new Option("--profile <name>", "AWS profile name.")).addOption(new Option("--role-arn <arn>", "IAM role to assume before any AWS call.")).addOption(new Option("--verbose", "Enable debug-level logging.").default(false)).action(withErrorHandling(migrateCommandAction));
|
|
62070
62049
|
}
|
|
62071
62050
|
|
|
62051
|
+
//#endregion
|
|
62052
|
+
//#region src/cli/program.ts
|
|
62053
|
+
/**
|
|
62054
|
+
* Builds the full `cdkd` command tree.
|
|
62055
|
+
*
|
|
62056
|
+
* Lives in its own module rather than in `index.ts` because importing
|
|
62057
|
+
* `index.ts` runs `main()` as a side effect — the same reason
|
|
62058
|
+
* `pipe-close-handler.ts` was split out. Tooling can import this one safely.
|
|
62059
|
+
*
|
|
62060
|
+
* The consumer that motivated the split is
|
|
62061
|
+
* `scripts/check-integ-cli-flags.ts`, which validates every CLI invocation in
|
|
62062
|
+
* the integ fixtures against the option set of the subcommand that actually
|
|
62063
|
+
* declares the flag. Reading the real tree matters: `--help` omits hidden
|
|
62064
|
+
* options, and `src/cli/options.ts` is a flat global list with no command
|
|
62065
|
+
* attachment — so a flag declared there but never attached to a given
|
|
62066
|
+
* subcommand (the `cdkd import --region` case, which silently meant an entire
|
|
62067
|
+
* fixture's import round-trip never ran) is invisible to both.
|
|
62068
|
+
*/
|
|
62069
|
+
function buildProgram() {
|
|
62070
|
+
const program = new Command();
|
|
62071
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.255.0");
|
|
62072
|
+
program.addCommand(createBootstrapCommand());
|
|
62073
|
+
program.addCommand(createSynthCommand());
|
|
62074
|
+
program.addCommand(createListCommand());
|
|
62075
|
+
program.addCommand(createDeployCommand());
|
|
62076
|
+
program.addCommand(createDiffCommand());
|
|
62077
|
+
program.addCommand(createDriftCommand());
|
|
62078
|
+
program.addCommand(createDestroyCommand());
|
|
62079
|
+
program.addCommand(createEventsCommand());
|
|
62080
|
+
program.addCommand(createGcCommand());
|
|
62081
|
+
program.addCommand(createOrphanCommand());
|
|
62082
|
+
program.addCommand(createImportCommand());
|
|
62083
|
+
program.addCommand(createPublishAssetsCommand());
|
|
62084
|
+
program.addCommand(createForceUnlockCommand());
|
|
62085
|
+
program.addCommand(createStateCommand());
|
|
62086
|
+
program.addCommand(createLocalCommand());
|
|
62087
|
+
program.addCommand(createExportCommand());
|
|
62088
|
+
program.addCommand(createMigrateCommand());
|
|
62089
|
+
return program;
|
|
62090
|
+
}
|
|
62091
|
+
|
|
62072
62092
|
//#endregion
|
|
62073
62093
|
//#region src/cli/pipe-close-handler.ts
|
|
62074
62094
|
/**
|
|
@@ -62137,25 +62157,7 @@ function reorderArgs(argv) {
|
|
|
62137
62157
|
*/
|
|
62138
62158
|
async function main() {
|
|
62139
62159
|
installPipeCloseHandler();
|
|
62140
|
-
const program =
|
|
62141
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.254.0");
|
|
62142
|
-
program.addCommand(createBootstrapCommand());
|
|
62143
|
-
program.addCommand(createSynthCommand());
|
|
62144
|
-
program.addCommand(createListCommand());
|
|
62145
|
-
program.addCommand(createDeployCommand());
|
|
62146
|
-
program.addCommand(createDiffCommand());
|
|
62147
|
-
program.addCommand(createDriftCommand());
|
|
62148
|
-
program.addCommand(createDestroyCommand());
|
|
62149
|
-
program.addCommand(createEventsCommand());
|
|
62150
|
-
program.addCommand(createGcCommand());
|
|
62151
|
-
program.addCommand(createOrphanCommand());
|
|
62152
|
-
program.addCommand(createImportCommand());
|
|
62153
|
-
program.addCommand(createPublishAssetsCommand());
|
|
62154
|
-
program.addCommand(createForceUnlockCommand());
|
|
62155
|
-
program.addCommand(createStateCommand());
|
|
62156
|
-
program.addCommand(createLocalCommand());
|
|
62157
|
-
program.addCommand(createExportCommand());
|
|
62158
|
-
program.addCommand(createMigrateCommand());
|
|
62160
|
+
const program = buildProgram();
|
|
62159
62161
|
const args = reorderArgs(process.argv);
|
|
62160
62162
|
await program.parseAsync(args);
|
|
62161
62163
|
}
|