@go-to-k/cdkd 0.238.5 → 0.239.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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
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-BzO-joNR.js";
|
|
3
3
|
import { A as withErrorHandling, C as StackHasActiveImportsError, S as ResourceUpdateNotSupportedError, _ as MissingCdkCliError, a as normalizeAwsTagsToCfn, b as ProvisioningError, f as LocalInvokeBuildError$1, i as matchesCdkPath, k as normalizeAwsError, l as CdkdError, m as LocalStartServiceError, n as isTerminationProtectionPropagationError, o as resolveExplicitPhysicalId, p as LocalMigrateError, r as CDK_PATH_TAG, s as assertRegionMatch, t as disableInstanceApiTermination, v as NestedStackChildDirectDestroyError, w as StackTerminationProtectionError, x as ResourceTimeoutError, y as PartialFailureError } from "./ec2-termination-protection-q-WGWgxa.js";
|
|
4
4
|
import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-B15NAPbL.js";
|
|
5
|
-
import { $ as getDockerCmd, A as DiffCalculator, B as buildAssetRedirectMap, C as findActionableSilentDrops, Ct as resolveBucketRegion, D as refStateLookupFromResource, E as cfnRefValueFromPhysicalId, F as rebuildClientForBucketRegion, G as BOOTSTRAP_MARKER_PREFIX, H as loadPublishableAssetManifest, I as shouldRetainResource, J as parseBootstrapMarker, K as ensureAssetStorage, L as AssetPublisher, M as TemplateParser, N as LockManager, O as WAFv2WebACLProvider, P as S3StateBackend, Q as formatDockerLoginError, R as stringifyValue, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as rewriteTemplateAssetReferences, V as createAssetRedirectResolver, W as AssetModeResolver, X as validateContainerRepoName, Y as validateAssetBucketName, Z as buildDockerImage, _ as green, _t as CFN_TEMPLATE_URL_LIMIT, a as withRetry, at as synthesisStatusMessage, b as IAMRoleProvider, bt as uploadCfnTemplate, c as computeImplicitDeleteEdges, ct as resolveApp, d as isStatefulRecreateTargetSync, dt as resolveSkipPrefix, et as runDockerForeground, f as renderStatefulReason, ft as resolveStateBucketWithDefault, g as gray, gt as CFN_TEMPLATE_BODY_LIMIT, h as cyan, ht as warnDeprecatedNoPrefixCliFlag, i as withResourceDeadline, it as Synthesizer, j as DagBuilder, k as applyRoleArnIfSet, l as extractDeploymentEventError, lt as resolveAutoAssetStorage, m as bold, mt as resolveUseCdkBootstrapAssets, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as AssetManifestLoader, o as isRetryableTransientError, ot as getDefaultStateBucketName, p as formatResourceLine, pt as resolveStateBucketWithDefaultAndSource, q as getBootstrapMarkerKey, r as DeployEngine, rt as getDockerImageBySourceHash, s as IMPLICIT_DELETE_DEPENDENCIES, st as getLegacyStateBucketName, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as runDockerStreaming, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, ut as resolveCaptureObservedState, v as red, vt as MIGRATE_TMP_PREFIX, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, xt as AssemblyReader, y as yellow, yt as findLargeInlineResources, z as WorkGraph } from "./deploy-engine-
|
|
5
|
+
import { $ as getDockerCmd, A as DiffCalculator, B as buildAssetRedirectMap, C as findActionableSilentDrops, Ct as resolveBucketRegion, D as refStateLookupFromResource, E as cfnRefValueFromPhysicalId, F as rebuildClientForBucketRegion, G as BOOTSTRAP_MARKER_PREFIX, H as loadPublishableAssetManifest, I as shouldRetainResource, J as parseBootstrapMarker, K as ensureAssetStorage, L as AssetPublisher, M as TemplateParser, N as LockManager, O as WAFv2WebACLProvider, P as S3StateBackend, Q as formatDockerLoginError, R as stringifyValue, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as rewriteTemplateAssetReferences, V as createAssetRedirectResolver, W as AssetModeResolver, X as validateContainerRepoName, Y as validateAssetBucketName, Z as buildDockerImage, _ as green, _t as CFN_TEMPLATE_URL_LIMIT, a as withRetry, at as synthesisStatusMessage, b as IAMRoleProvider, bt as uploadCfnTemplate, c as computeImplicitDeleteEdges, ct as resolveApp, d as isStatefulRecreateTargetSync, dt as resolveSkipPrefix, et as runDockerForeground, f as renderStatefulReason, ft as resolveStateBucketWithDefault, g as gray, gt as CFN_TEMPLATE_BODY_LIMIT, h as cyan, ht as warnDeprecatedNoPrefixCliFlag, i as withResourceDeadline, it as Synthesizer, j as DagBuilder, k as applyRoleArnIfSet, l as extractDeploymentEventError, lt as resolveAutoAssetStorage, m as bold, mt as resolveUseCdkBootstrapAssets, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as AssetManifestLoader, o as isRetryableTransientError, ot as getDefaultStateBucketName, p as formatResourceLine, pt as resolveStateBucketWithDefaultAndSource, q as getBootstrapMarkerKey, r as DeployEngine, rt as getDockerImageBySourceHash, s as IMPLICIT_DELETE_DEPENDENCIES, st as getLegacyStateBucketName, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as runDockerStreaming, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, ut as resolveCaptureObservedState, v as red, vt as MIGRATE_TMP_PREFIX, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, xt as AssemblyReader, y as yellow, yt as findLargeInlineResources, z as WorkGraph } from "./deploy-engine-8lyaaElh.js";
|
|
6
6
|
import { t as expectedOwnerParam } from "./expected-bucket-owner-BjEfUnkA.js";
|
|
7
7
|
import { t as ASGProvider } from "./asg-provider-Dbl1_mwT.js";
|
|
8
8
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -61,8 +61,9 @@ import { AccessPointNotFound, CreateAccessPointCommand, CreateFileSystemCommand,
|
|
|
61
61
|
import { CreateDeliveryStreamCommand, DeleteDeliveryStreamCommand, DescribeDeliveryStreamCommand, FirehoseClient, ListDeliveryStreamsCommand, ListTagsForDeliveryStreamCommand, ResourceNotFoundException as ResourceNotFoundException$10, TagDeliveryStreamCommand, UntagDeliveryStreamCommand, UpdateDestinationCommand } from "@aws-sdk/client-firehose";
|
|
62
62
|
import { AddTagsCommand as AddTagsCommand$1, CloudTrailClient, CreateTrailCommand, DeleteTrailCommand, GetEventSelectorsCommand, GetInsightSelectorsCommand, GetTrailCommand, GetTrailStatusCommand, ListTagsCommand as ListTagsCommand$1, ListTrailsCommand, PutEventSelectorsCommand, PutInsightSelectorsCommand, RemoveTagsCommand as RemoveTagsCommand$1, StartLoggingCommand, StopLoggingCommand, TrailNotFoundException, UpdateTrailCommand } from "@aws-sdk/client-cloudtrail";
|
|
63
63
|
import { BatchGetProjectsCommand, CodeBuildClient, CreateProjectCommand, DeleteProjectCommand, ListProjectsCommand, ResourceNotFoundException as ResourceNotFoundException$11, UpdateProjectCommand } from "@aws-sdk/client-codebuild";
|
|
64
|
-
import {
|
|
65
|
-
import {
|
|
64
|
+
import { CreateLifecyclePolicyCommand, DLMClient, DeleteLifecyclePolicyCommand as DeleteLifecyclePolicyCommand$1, GetLifecyclePoliciesCommand, GetLifecyclePolicyCommand as GetLifecyclePolicyCommand$1, ResourceNotFoundException as ResourceNotFoundException$12, TagResourceCommand as TagResourceCommand$15, UntagResourceCommand as UntagResourceCommand$15, UpdateLifecyclePolicyCommand } from "@aws-sdk/client-dlm";
|
|
65
|
+
import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$17, ListVectorBucketsCommand, S3VectorsClient, TagResourceCommand as TagResourceCommand$16, UntagResourceCommand as UntagResourceCommand$16 } from "@aws-sdk/client-s3vectors";
|
|
66
|
+
import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableCommand as DeleteTableCommand$2, GetTableBucketCommand, GetTableCommand as GetTableCommand$1, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand as ListTablesCommand$1, ListTagsForResourceCommand as ListTagsForResourceCommand$18, NotFoundException as NotFoundException$5, S3TablesClient, TagResourceCommand as TagResourceCommand$17, UntagResourceCommand as UntagResourceCommand$17 } from "@aws-sdk/client-s3tables";
|
|
66
67
|
import { Document, Pair, Scalar, YAMLMap, YAMLSeq, parse as parse$1, stringify } from "yaml";
|
|
67
68
|
import { createLocalStartAgentCoreCommand, createLocalStartCloudFrontCommand, createLocalStateProvider, getEmbedConfig, isCfnFlagPresent, listTargets, rejectExplicitCfnStackWithMultipleStacks, resolveCfnFallbackRegion, setEmbedConfig, substituteAgainstState, substituteAgainstStateAsync, substituteEnvVarsFromState, substituteEnvVarsFromStateAsync } from "cdk-local";
|
|
68
69
|
import { A2A_CONTAINER_PORT, A2A_PATH, AGENTCORE_A2A_PROTOCOL, AGENTCORE_AGUI_PROTOCOL, AGENTCORE_MCP_PROTOCOL, ConnectionRegistry, EcsTaskResolutionError, HOST_GATEWAY_MIN_VERSION, LocalInvokeBuildError, MCP_CONTAINER_PORT, MCP_PATH, a2aInvokeOnce, addAlbSpecificOptions, addCommonEcsServiceOptions, addStartServiceSpecificOptions, albStrategy, architectureToPlatform, attachAuthorizers, attachStageContext, availableApiIdentifiers, bufferToBody, buildAgentCoreCodeImage, buildCognitoJwksUrl, buildConnectEvent, buildContainerImage, buildCorsConfigByApiId, buildCorsConfigFromCloudFrontChain, buildDisconnectEvent, buildJwksUrlFromIssuer, buildMessageEvent, buildMgmtEndpointEnvUrl, buildStageMap, classifySourceChange, createAuthorizerCache, createFileWatcher, createFileWatcher as createFileWatcher$1, createJwksCache, createWatchPredicates, defaultCredentialsLoader, derivePseudoParametersFromRegion, discoverRoutes, discoverWebSocketApis, downloadAndExtractS3Bundle, filterRoutesByApiIdentifier, groupRoutesByServer, handleConnectionsRequest, invokeAgentCore, invokeAgentCoreWs, materializeLayerFromArn, mcpInvokeOnce, parseConnectionsPath, parseSelectionExpressionPath, pickAgentCoreCandidateStack, pickAgentCoreCandidateStack as pickAgentCoreCandidateStack$1, probeHostGatewaySupport, readMtlsMaterialsFromDisk, resolveAgentCoreTarget, resolveEnvVars, resolveHostGatewayExtraHosts, resolveRuntimeCodeMountPath, resolveRuntimeFileExtension, resolveRuntimeImage, resolveSingleTarget, resolveWatchConfig, runEcsServiceEmulator, signAgentCoreInvocation, startApiServer, substituteImagePlaceholders, tryResolveImageFnJoin, verifyJwtViaDiscovery, waitForAgentCorePing } from "cdk-local/internal";
|
|
@@ -1885,7 +1886,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
1885
1886
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
1886
1887
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
1887
1888
|
function getCdkdVersion() {
|
|
1888
|
-
return "0.
|
|
1889
|
+
return "0.239.0";
|
|
1889
1890
|
}
|
|
1890
1891
|
/**
|
|
1891
1892
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -35162,6 +35163,277 @@ var CodeBuildProvider = class {
|
|
|
35162
35163
|
}
|
|
35163
35164
|
};
|
|
35164
35165
|
|
|
35166
|
+
//#endregion
|
|
35167
|
+
//#region src/provisioning/providers/dlm-lifecycle-policy-provider.ts
|
|
35168
|
+
/**
|
|
35169
|
+
* SDK Provider for AWS::DLM::LifecyclePolicy (Data Lifecycle Manager).
|
|
35170
|
+
*
|
|
35171
|
+
* Why an SDK provider (issue #1040): the type is
|
|
35172
|
+
* `ProvisioningType: NON_PROVISIONABLE`, so cdkd's Cloud Control fallback
|
|
35173
|
+
* cannot handle it and pre-flight rejected it. The DLM API surface is small
|
|
35174
|
+
* and the CFn property shape maps 1:1 onto the SDK's PascalCase inputs; the
|
|
35175
|
+
* only conversion is the CFn `Tags` list <-> DLM tag-map.
|
|
35176
|
+
*
|
|
35177
|
+
* physicalId is the service-generated policy id (`policy-0123456789abcdef0`)
|
|
35178
|
+
* — matches CFn, where `Ref` returns the policy id (`Id` is the
|
|
35179
|
+
* primaryIdentifier). `Fn::GetAtt Arn` returns the policy ARN.
|
|
35180
|
+
*
|
|
35181
|
+
* API mapping:
|
|
35182
|
+
* - create -> CreateLifecyclePolicy (+ GetLifecyclePolicy for the Arn
|
|
35183
|
+
* attribute — the create response only carries PolicyId)
|
|
35184
|
+
* - update -> UpdateLifecyclePolicy for policy fields, plus explicit
|
|
35185
|
+
* TagResource / UntagResource for tag diffs (the update
|
|
35186
|
+
* API has no Tags parameter). Tag removal — including a
|
|
35187
|
+
* FULL `Tags` property removal — is handled explicitly
|
|
35188
|
+
* via UntagResource (the #981 ECR regression class).
|
|
35189
|
+
* - delete -> DeleteLifecyclePolicy (NotFound idempotent, guarded by
|
|
35190
|
+
* assertRegionMatch)
|
|
35191
|
+
* - getAttribute-> GetLifecyclePolicy (`Arn` from Policy.PolicyArn)
|
|
35192
|
+
*
|
|
35193
|
+
* `DefaultPolicy` is create-only at the API level (UpdateLifecyclePolicy has
|
|
35194
|
+
* no such parameter; CFn documents it as "Update requires: Replacement"), so
|
|
35195
|
+
* a change is rejected with `ResourceUpdateNotSupportedError` and the deploy
|
|
35196
|
+
* engine's `--replace` fallback recreates the policy.
|
|
35197
|
+
*/
|
|
35198
|
+
var DLMLifecyclePolicyProvider = class {
|
|
35199
|
+
client;
|
|
35200
|
+
providerRegion = process.env["AWS_REGION"];
|
|
35201
|
+
logger = getLogger().child("DLMLifecyclePolicyProvider");
|
|
35202
|
+
handledProperties = new Map([["AWS::DLM::LifecyclePolicy", new Set([
|
|
35203
|
+
"Description",
|
|
35204
|
+
"ExecutionRoleArn",
|
|
35205
|
+
"State",
|
|
35206
|
+
"PolicyDetails",
|
|
35207
|
+
"Tags",
|
|
35208
|
+
"DefaultPolicy",
|
|
35209
|
+
"CreateInterval",
|
|
35210
|
+
"RetainInterval",
|
|
35211
|
+
"CopyTags",
|
|
35212
|
+
"ExtendDeletion",
|
|
35213
|
+
"CrossRegionCopyTargets",
|
|
35214
|
+
"Exclusions"
|
|
35215
|
+
])]]);
|
|
35216
|
+
getClient() {
|
|
35217
|
+
if (!this.client) this.client = new DLMClient(this.providerRegion ? { region: this.providerRegion } : {});
|
|
35218
|
+
return this.client;
|
|
35219
|
+
}
|
|
35220
|
+
/**
|
|
35221
|
+
* Convert the CFn `Tags` list (`[{ Key, Value }]`) to the DLM tag map
|
|
35222
|
+
* (`Record<string, string>`). Returns `undefined` for an absent / empty
|
|
35223
|
+
* list so callers can omit the field.
|
|
35224
|
+
*/
|
|
35225
|
+
cfnTagsToMap(tags) {
|
|
35226
|
+
if (!Array.isArray(tags)) return void 0;
|
|
35227
|
+
const map = {};
|
|
35228
|
+
for (const t of tags) if (typeof t?.Key === "string" && t.Key.length > 0) map[t.Key] = typeof t.Value === "string" ? t.Value : "";
|
|
35229
|
+
return Object.keys(map).length > 0 ? map : void 0;
|
|
35230
|
+
}
|
|
35231
|
+
/**
|
|
35232
|
+
* Map the CFn property shape to the SDK input shape (shared by create and
|
|
35233
|
+
* update — every field name is PascalCase-identical). `Tags` and
|
|
35234
|
+
* `DefaultPolicy` are intentionally NOT included: create wires them
|
|
35235
|
+
* separately (update has neither parameter).
|
|
35236
|
+
*/
|
|
35237
|
+
toSdkFields(properties) {
|
|
35238
|
+
return {
|
|
35239
|
+
...properties["ExecutionRoleArn"] !== void 0 && { ExecutionRoleArn: properties["ExecutionRoleArn"] },
|
|
35240
|
+
...properties["Description"] !== void 0 && { Description: properties["Description"] },
|
|
35241
|
+
...properties["State"] !== void 0 && { State: properties["State"] },
|
|
35242
|
+
...properties["PolicyDetails"] !== void 0 && { PolicyDetails: properties["PolicyDetails"] },
|
|
35243
|
+
...properties["CreateInterval"] !== void 0 && { CreateInterval: properties["CreateInterval"] },
|
|
35244
|
+
...properties["RetainInterval"] !== void 0 && { RetainInterval: properties["RetainInterval"] },
|
|
35245
|
+
...properties["CopyTags"] !== void 0 && { CopyTags: properties["CopyTags"] },
|
|
35246
|
+
...properties["ExtendDeletion"] !== void 0 && { ExtendDeletion: properties["ExtendDeletion"] },
|
|
35247
|
+
...properties["CrossRegionCopyTargets"] !== void 0 && { CrossRegionCopyTargets: properties["CrossRegionCopyTargets"] },
|
|
35248
|
+
...properties["Exclusions"] !== void 0 && { Exclusions: properties["Exclusions"] }
|
|
35249
|
+
};
|
|
35250
|
+
}
|
|
35251
|
+
/** Fetch the policy ARN (`Fn::GetAtt Arn`) for a policy id. */
|
|
35252
|
+
async fetchPolicyArn(policyId) {
|
|
35253
|
+
return (await this.getClient().send(new GetLifecyclePolicyCommand$1({ PolicyId: policyId }))).Policy?.PolicyArn ?? "";
|
|
35254
|
+
}
|
|
35255
|
+
async create(logicalId, resourceType, properties) {
|
|
35256
|
+
this.logger.debug(`Creating DLM Lifecycle Policy ${logicalId}`);
|
|
35257
|
+
try {
|
|
35258
|
+
const tags = this.cfnTagsToMap(properties["Tags"]);
|
|
35259
|
+
const input = {
|
|
35260
|
+
...this.toSdkFields(properties),
|
|
35261
|
+
...properties["DefaultPolicy"] !== void 0 && { DefaultPolicy: properties["DefaultPolicy"] },
|
|
35262
|
+
...tags && { Tags: tags }
|
|
35263
|
+
};
|
|
35264
|
+
const response = await this.getClient().send(new CreateLifecyclePolicyCommand(input));
|
|
35265
|
+
if (!response.PolicyId) throw new Error("CreateLifecyclePolicy did not return a PolicyId");
|
|
35266
|
+
let arn = "";
|
|
35267
|
+
try {
|
|
35268
|
+
arn = await this.fetchPolicyArn(response.PolicyId);
|
|
35269
|
+
} catch (err) {
|
|
35270
|
+
this.logger.warn(`Created DLM Lifecycle Policy ${response.PolicyId} but could not fetch its ARN: ${err instanceof Error ? err.message : String(err)}`);
|
|
35271
|
+
}
|
|
35272
|
+
this.logger.debug(`Successfully created DLM Lifecycle Policy ${logicalId}: ${response.PolicyId}`);
|
|
35273
|
+
return {
|
|
35274
|
+
physicalId: response.PolicyId,
|
|
35275
|
+
attributes: arn ? { Arn: arn } : {}
|
|
35276
|
+
};
|
|
35277
|
+
} catch (error) {
|
|
35278
|
+
const cause = error instanceof Error ? error : void 0;
|
|
35279
|
+
throw new ProvisioningError(`Failed to create DLM Lifecycle Policy ${logicalId}: ${cause?.message ?? String(error)}`, resourceType, logicalId, void 0, cause);
|
|
35280
|
+
}
|
|
35281
|
+
}
|
|
35282
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
35283
|
+
if (JSON.stringify(properties["DefaultPolicy"]) !== JSON.stringify(previousProperties["DefaultPolicy"])) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, `DefaultPolicy cannot be changed in place; re-run with \`cdkd deploy --replace ${logicalId}\` to recreate the policy`);
|
|
35284
|
+
this.logger.debug(`Updating DLM Lifecycle Policy ${logicalId} (${physicalId})`);
|
|
35285
|
+
try {
|
|
35286
|
+
await this.getClient().send(new UpdateLifecyclePolicyCommand({
|
|
35287
|
+
PolicyId: physicalId,
|
|
35288
|
+
...this.toSdkFields(properties)
|
|
35289
|
+
}));
|
|
35290
|
+
const newTags = this.cfnTagsToMap(properties["Tags"]) ?? {};
|
|
35291
|
+
const oldTags = this.cfnTagsToMap(previousProperties["Tags"]) ?? {};
|
|
35292
|
+
const arn = await this.fetchPolicyArn(physicalId);
|
|
35293
|
+
const tagsChanged = JSON.stringify(newTags) !== JSON.stringify(oldTags);
|
|
35294
|
+
if (tagsChanged && !arn) this.logger.warn(`Skipping tag update for DLM Lifecycle Policy ${physicalId}: GetLifecyclePolicy returned no PolicyArn`);
|
|
35295
|
+
if (tagsChanged && arn) {
|
|
35296
|
+
const removedKeys = Object.keys(oldTags).filter((k) => !(k in newTags));
|
|
35297
|
+
if (removedKeys.length > 0) {
|
|
35298
|
+
await this.getClient().send(new UntagResourceCommand$15({
|
|
35299
|
+
ResourceArn: arn,
|
|
35300
|
+
TagKeys: removedKeys
|
|
35301
|
+
}));
|
|
35302
|
+
this.logger.debug(`Removed ${removedKeys.length} tag(s) from DLM Lifecycle Policy ${physicalId}`);
|
|
35303
|
+
}
|
|
35304
|
+
const tagsToAdd = {};
|
|
35305
|
+
for (const [k, v] of Object.entries(newTags)) if (oldTags[k] !== v) tagsToAdd[k] = v;
|
|
35306
|
+
if (Object.keys(tagsToAdd).length > 0) {
|
|
35307
|
+
await this.getClient().send(new TagResourceCommand$15({
|
|
35308
|
+
ResourceArn: arn,
|
|
35309
|
+
Tags: tagsToAdd
|
|
35310
|
+
}));
|
|
35311
|
+
this.logger.debug(`Added/updated ${Object.keys(tagsToAdd).length} tag(s) on DLM Lifecycle Policy ${physicalId}`);
|
|
35312
|
+
}
|
|
35313
|
+
}
|
|
35314
|
+
return {
|
|
35315
|
+
physicalId,
|
|
35316
|
+
wasReplaced: false,
|
|
35317
|
+
attributes: arn ? { Arn: arn } : {}
|
|
35318
|
+
};
|
|
35319
|
+
} catch (error) {
|
|
35320
|
+
if (error instanceof ResourceUpdateNotSupportedError) throw error;
|
|
35321
|
+
const cause = error instanceof Error ? error : void 0;
|
|
35322
|
+
throw new ProvisioningError(`Failed to update DLM Lifecycle Policy ${logicalId}: ${cause?.message ?? String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
35323
|
+
}
|
|
35324
|
+
}
|
|
35325
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
35326
|
+
this.logger.debug(`Deleting DLM Lifecycle Policy ${logicalId}: ${physicalId}`);
|
|
35327
|
+
try {
|
|
35328
|
+
await this.getClient().send(new DeleteLifecyclePolicyCommand$1({ PolicyId: physicalId }));
|
|
35329
|
+
this.logger.debug(`Successfully deleted DLM Lifecycle Policy ${logicalId}`);
|
|
35330
|
+
} catch (error) {
|
|
35331
|
+
if (error instanceof ResourceNotFoundException$12) {
|
|
35332
|
+
assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
35333
|
+
this.logger.debug(`DLM Lifecycle Policy ${physicalId} does not exist, skipping deletion`);
|
|
35334
|
+
return;
|
|
35335
|
+
}
|
|
35336
|
+
const cause = error instanceof Error ? error : void 0;
|
|
35337
|
+
throw new ProvisioningError(`Failed to delete DLM Lifecycle Policy ${logicalId}: ${cause?.message ?? String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
35338
|
+
}
|
|
35339
|
+
}
|
|
35340
|
+
/**
|
|
35341
|
+
* Attribute fallback. `Arn` is cached in state at create/update time, so
|
|
35342
|
+
* this only fires for imported/degraded records.
|
|
35343
|
+
*/
|
|
35344
|
+
async getAttribute(physicalId, resourceType, attributeName) {
|
|
35345
|
+
if (attributeName === "Id" || attributeName === "PolicyId") return physicalId;
|
|
35346
|
+
if (attributeName !== "Arn") throw new ProvisioningError(`Unknown attribute ${attributeName} for ${resourceType}`, resourceType, physicalId);
|
|
35347
|
+
try {
|
|
35348
|
+
return await this.fetchPolicyArn(physicalId);
|
|
35349
|
+
} catch (error) {
|
|
35350
|
+
const cause = error instanceof Error ? error : void 0;
|
|
35351
|
+
throw new ProvisioningError(`Failed to resolve Arn for DLM Lifecycle Policy ${physicalId}: ${cause?.message ?? String(error)}`, resourceType, physicalId, physicalId, cause);
|
|
35352
|
+
}
|
|
35353
|
+
}
|
|
35354
|
+
/**
|
|
35355
|
+
* Drift read-back. Surfaces `Description`, `State`, `ExecutionRoleArn`,
|
|
35356
|
+
* and `Tags` (DLM tag map -> CFn list via `normalizeAwsTagsToCfn`).
|
|
35357
|
+
*
|
|
35358
|
+
* `PolicyDetails` is intentionally NOT surfaced (see
|
|
35359
|
+
* `getDriftUnknownPaths`): the service normalizes the stored details —
|
|
35360
|
+
* filling `PolicyType` / `ResourceTypes` / per-schedule defaults the
|
|
35361
|
+
* template omitted — and the drift comparator's positional array equality
|
|
35362
|
+
* would flag those AWS-added defaults as phantom drift on every clean run.
|
|
35363
|
+
* The default-policy shorthand fields (`CreateInterval` / `RetainInterval`
|
|
35364
|
+
* / `CopyTags` / `ExtendDeletion` / `CrossRegionCopyTargets` /
|
|
35365
|
+
* `Exclusions`) are folded into the normalized `PolicyDetails` by the
|
|
35366
|
+
* service (GetLifecyclePolicy does not return them at the top level), so
|
|
35367
|
+
* they are excluded for the same reason.
|
|
35368
|
+
*
|
|
35369
|
+
* Returns `undefined` when the policy is gone (ResourceNotFoundException).
|
|
35370
|
+
*/
|
|
35371
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
35372
|
+
try {
|
|
35373
|
+
const policy = (await this.getClient().send(new GetLifecyclePolicyCommand$1({ PolicyId: physicalId }))).Policy;
|
|
35374
|
+
if (!policy) return void 0;
|
|
35375
|
+
return {
|
|
35376
|
+
...policy.Description !== void 0 && { Description: policy.Description },
|
|
35377
|
+
...policy.State !== void 0 && { State: policy.State },
|
|
35378
|
+
...policy.ExecutionRoleArn !== void 0 && { ExecutionRoleArn: policy.ExecutionRoleArn },
|
|
35379
|
+
Tags: normalizeAwsTagsToCfn(policy.Tags)
|
|
35380
|
+
};
|
|
35381
|
+
} catch (error) {
|
|
35382
|
+
if (error instanceof ResourceNotFoundException$12) return;
|
|
35383
|
+
throw error;
|
|
35384
|
+
}
|
|
35385
|
+
}
|
|
35386
|
+
/**
|
|
35387
|
+
* State property paths the provider deliberately does not read back from
|
|
35388
|
+
* AWS — see `readCurrentState` for the rationale.
|
|
35389
|
+
*/
|
|
35390
|
+
getDriftUnknownPaths(_resourceType) {
|
|
35391
|
+
return [
|
|
35392
|
+
"PolicyDetails",
|
|
35393
|
+
"CreateInterval",
|
|
35394
|
+
"RetainInterval",
|
|
35395
|
+
"CopyTags",
|
|
35396
|
+
"ExtendDeletion",
|
|
35397
|
+
"CrossRegionCopyTargets",
|
|
35398
|
+
"Exclusions",
|
|
35399
|
+
"DefaultPolicy"
|
|
35400
|
+
];
|
|
35401
|
+
}
|
|
35402
|
+
/**
|
|
35403
|
+
* Adopt an existing lifecycle policy into cdkd state.
|
|
35404
|
+
*
|
|
35405
|
+
* Lookup order:
|
|
35406
|
+
* 1. `--resource` override (`knownPhysicalId`) -> verify via
|
|
35407
|
+
* GetLifecyclePolicy. There is no template name property — the policy
|
|
35408
|
+
* id is service-generated — so no name fallback applies.
|
|
35409
|
+
* 2. Tag-based lookup: GetLifecyclePolicies returns every policy summary
|
|
35410
|
+
* WITH its tag map in a single unpaginated call, so the `aws:cdk:path`
|
|
35411
|
+
* match needs no per-policy follow-up.
|
|
35412
|
+
*/
|
|
35413
|
+
async import(input) {
|
|
35414
|
+
if (input.knownPhysicalId) try {
|
|
35415
|
+
const response = await this.getClient().send(new GetLifecyclePolicyCommand$1({ PolicyId: input.knownPhysicalId }));
|
|
35416
|
+
return response.Policy?.PolicyId ? {
|
|
35417
|
+
physicalId: input.knownPhysicalId,
|
|
35418
|
+
attributes: { Arn: response.Policy.PolicyArn ?? "" }
|
|
35419
|
+
} : null;
|
|
35420
|
+
} catch (err) {
|
|
35421
|
+
if (err instanceof ResourceNotFoundException$12) return null;
|
|
35422
|
+
throw err;
|
|
35423
|
+
}
|
|
35424
|
+
if (!input.cdkPath) return null;
|
|
35425
|
+
const list = await this.getClient().send(new GetLifecyclePoliciesCommand({}));
|
|
35426
|
+
for (const policy of list.Policies ?? []) {
|
|
35427
|
+
if (!policy.PolicyId) continue;
|
|
35428
|
+
if (policy.Tags?.["aws:cdk:path"] === input.cdkPath) return {
|
|
35429
|
+
physicalId: policy.PolicyId,
|
|
35430
|
+
attributes: {}
|
|
35431
|
+
};
|
|
35432
|
+
}
|
|
35433
|
+
return null;
|
|
35434
|
+
}
|
|
35435
|
+
};
|
|
35436
|
+
|
|
35165
35437
|
//#endregion
|
|
35166
35438
|
//#region src/provisioning/providers/s3-vectors-provider.ts
|
|
35167
35439
|
/**
|
|
@@ -35235,11 +35507,11 @@ var S3VectorsProvider = class {
|
|
|
35235
35507
|
}
|
|
35236
35508
|
if (!resourceArn) throw new ProvisioningError(`Could not resolve ARN for S3 VectorBucket ${logicalId} (${physicalId}); cannot apply tag update.`, resourceType, logicalId, physicalId);
|
|
35237
35509
|
try {
|
|
35238
|
-
if (Object.keys(toSet).length > 0) await this.getClient().send(new TagResourceCommand$
|
|
35510
|
+
if (Object.keys(toSet).length > 0) await this.getClient().send(new TagResourceCommand$16({
|
|
35239
35511
|
resourceArn,
|
|
35240
35512
|
tags: toSet
|
|
35241
35513
|
}));
|
|
35242
|
-
if (toRemove.length > 0) await this.getClient().send(new UntagResourceCommand$
|
|
35514
|
+
if (toRemove.length > 0) await this.getClient().send(new UntagResourceCommand$16({
|
|
35243
35515
|
resourceArn,
|
|
35244
35516
|
tagKeys: toRemove
|
|
35245
35517
|
}));
|
|
@@ -36230,7 +36502,7 @@ var S3TablesProvider = class {
|
|
|
36230
36502
|
const resourceArn = await this.lookupTableArn(tableBucketARN, namespace, name);
|
|
36231
36503
|
if (!resourceArn) throw new ProvisioningError(`applyTableTagsDiff: GetTable returned no tableARN for ${physicalId} — table is gone or state is out-of-sync. Refusing to silently drop the tag update (run 'cdkd state orphan ${logicalId}' to clean up if the table was deleted out-of-band).`, resourceType, logicalId, physicalId);
|
|
36232
36504
|
if (removedKeys.length > 0) try {
|
|
36233
|
-
await this.getClient().send(new UntagResourceCommand$
|
|
36505
|
+
await this.getClient().send(new UntagResourceCommand$17({
|
|
36234
36506
|
resourceArn,
|
|
36235
36507
|
tagKeys: removedKeys
|
|
36236
36508
|
}));
|
|
@@ -36239,7 +36511,7 @@ var S3TablesProvider = class {
|
|
|
36239
36511
|
throw new ProvisioningError(`applyTableTagsDiff: UntagResource failed for ${resourceArn} (keys: ${removedKeys.join(", ")}): ${err instanceof Error ? err.message : String(err)}. State has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
|
|
36240
36512
|
}
|
|
36241
36513
|
if (Object.keys(upserts).length > 0) try {
|
|
36242
|
-
await this.getClient().send(new TagResourceCommand$
|
|
36514
|
+
await this.getClient().send(new TagResourceCommand$17({
|
|
36243
36515
|
resourceArn,
|
|
36244
36516
|
tags: upserts
|
|
36245
36517
|
}));
|
|
@@ -36271,7 +36543,7 @@ var S3TablesProvider = class {
|
|
|
36271
36543
|
if (removedKeys.length === 0 && Object.keys(upserts).length === 0) return;
|
|
36272
36544
|
const resourceArn = physicalId;
|
|
36273
36545
|
if (removedKeys.length > 0) try {
|
|
36274
|
-
await this.getClient().send(new UntagResourceCommand$
|
|
36546
|
+
await this.getClient().send(new UntagResourceCommand$17({
|
|
36275
36547
|
resourceArn,
|
|
36276
36548
|
tagKeys: removedKeys
|
|
36277
36549
|
}));
|
|
@@ -36280,7 +36552,7 @@ var S3TablesProvider = class {
|
|
|
36280
36552
|
throw new ProvisioningError(`applyTableBucketTagsDiff: UntagResource failed for ${resourceArn} (keys: ${removedKeys.join(", ")}): ${err instanceof Error ? err.message : String(err)}. State has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
|
|
36281
36553
|
}
|
|
36282
36554
|
if (Object.keys(upserts).length > 0) try {
|
|
36283
|
-
await this.getClient().send(new TagResourceCommand$
|
|
36555
|
+
await this.getClient().send(new TagResourceCommand$17({
|
|
36284
36556
|
resourceArn,
|
|
36285
36557
|
tags: upserts
|
|
36286
36558
|
}));
|
|
@@ -37927,6 +38199,7 @@ function registerAllProviders(registry) {
|
|
|
37927
38199
|
registry.register("AWS::KinesisFirehose::DeliveryStream", new FirehoseProvider());
|
|
37928
38200
|
registry.register("AWS::CloudTrail::Trail", new CloudTrailProvider());
|
|
37929
38201
|
registry.register("AWS::CodeBuild::Project", new CodeBuildProvider());
|
|
38202
|
+
registry.register("AWS::DLM::LifecyclePolicy", new DLMLifecyclePolicyProvider());
|
|
37930
38203
|
registry.register("AWS::S3Vectors::VectorBucket", new S3VectorsProvider());
|
|
37931
38204
|
registry.register("AWS::ECR::Repository", new ECRProvider());
|
|
37932
38205
|
registry.register("AWS::AutoScaling::AutoScalingGroup", new ASGProvider());
|
|
@@ -46316,12 +46589,18 @@ function formatBucketSource(source) {
|
|
|
46316
46589
|
* not-yet-bootstrapped bucket. (Bucket existence is verified separately
|
|
46317
46590
|
* via {@link setupStateBackend}, so getting here implies the bucket is
|
|
46318
46591
|
* reachable; `GetBucketLocation` failing is most often a permissions gap.)
|
|
46592
|
+
*
|
|
46593
|
+
* Takes the (region-corrected) S3 client directly — see the issue #1054 note
|
|
46594
|
+
* in {@link stateInfoCommand}. Before that fix this call was made with the
|
|
46595
|
+
* ambient-region client, so a cross-region state bucket silently degraded to
|
|
46596
|
+
* `undefined` ("Region: unknown") here; with the corrected client it now
|
|
46597
|
+
* succeeds and reports the bucket's actual region.
|
|
46319
46598
|
*/
|
|
46320
|
-
async function detectBucketRegion(
|
|
46599
|
+
async function detectBucketRegion(s3, bucket) {
|
|
46321
46600
|
try {
|
|
46322
|
-
const constraint = (await
|
|
46601
|
+
const constraint = (await s3.send(new GetBucketLocationCommand({
|
|
46323
46602
|
Bucket: bucket,
|
|
46324
|
-
...await expectedOwnerParam(
|
|
46603
|
+
...await expectedOwnerParam(s3)
|
|
46325
46604
|
}))).LocationConstraint;
|
|
46326
46605
|
if (!constraint) return "us-east-1";
|
|
46327
46606
|
if (constraint === "EU") return "eu-west-1";
|
|
@@ -46342,12 +46621,12 @@ async function detectBucketRegion(awsClients, bucket) {
|
|
|
46342
46621
|
* Returns the full set of state-file keys; the count is the unique-stacks
|
|
46343
46622
|
* tally we want for the `Stacks:` line.
|
|
46344
46623
|
*/
|
|
46345
|
-
async function listStateFileKeys(
|
|
46624
|
+
async function listStateFileKeys(s3, bucket, prefix) {
|
|
46346
46625
|
const keys = [];
|
|
46347
46626
|
let continuationToken;
|
|
46348
46627
|
const searchPrefix = `${prefix}/`;
|
|
46349
46628
|
do {
|
|
46350
|
-
const resp = await
|
|
46629
|
+
const resp = await s3.send(new ListObjectsV2Command({
|
|
46351
46630
|
Bucket: bucket,
|
|
46352
46631
|
Prefix: searchPrefix,
|
|
46353
46632
|
...continuationToken && { ContinuationToken: continuationToken }
|
|
@@ -46365,13 +46644,13 @@ async function listStateFileKeys(awsClients, bucket, prefix) {
|
|
|
46365
46644
|
* Returns `'unknown'` when no state files exist or parsing fails — we don't
|
|
46366
46645
|
* want a cosmetic command to crash on an unexpected payload.
|
|
46367
46646
|
*/
|
|
46368
|
-
async function readSchemaVersion(
|
|
46647
|
+
async function readSchemaVersion(s3, bucket, keys) {
|
|
46369
46648
|
if (keys.length === 0) return "unknown";
|
|
46370
46649
|
try {
|
|
46371
|
-
const resp = await
|
|
46650
|
+
const resp = await s3.send(new GetObjectCommand({
|
|
46372
46651
|
Bucket: bucket,
|
|
46373
46652
|
Key: keys[0],
|
|
46374
|
-
...await expectedOwnerParam(
|
|
46653
|
+
...await expectedOwnerParam(s3)
|
|
46375
46654
|
}));
|
|
46376
46655
|
if (!resp.Body) return "unknown";
|
|
46377
46656
|
const body = await resp.Body.transformToString();
|
|
@@ -46387,13 +46666,13 @@ async function readSchemaVersion(awsClients, bucket, keys) {
|
|
|
46387
46666
|
* cosmetic command and should not crash on an unexpected payload (deploy
|
|
46388
46667
|
* hard-errors on the same marker instead).
|
|
46389
46668
|
*/
|
|
46390
|
-
async function listAssetStorageMarkers(
|
|
46669
|
+
async function listAssetStorageMarkers(s3, bucket) {
|
|
46391
46670
|
const logger = getLogger();
|
|
46392
46671
|
const entries = [];
|
|
46393
46672
|
let continuationToken;
|
|
46394
46673
|
const keys = [];
|
|
46395
46674
|
do {
|
|
46396
|
-
const resp = await
|
|
46675
|
+
const resp = await s3.send(new ListObjectsV2Command({
|
|
46397
46676
|
Bucket: bucket,
|
|
46398
46677
|
Prefix: BOOTSTRAP_MARKER_PREFIX,
|
|
46399
46678
|
...continuationToken && { ContinuationToken: continuationToken }
|
|
@@ -46404,10 +46683,10 @@ async function listAssetStorageMarkers(awsClients, bucket) {
|
|
|
46404
46683
|
for (const key of keys) {
|
|
46405
46684
|
const region = key.slice(BOOTSTRAP_MARKER_PREFIX.length, -5);
|
|
46406
46685
|
try {
|
|
46407
|
-
const marker = parseBootstrapMarker(await (await
|
|
46686
|
+
const marker = parseBootstrapMarker(await (await s3.send(new GetObjectCommand({
|
|
46408
46687
|
Bucket: bucket,
|
|
46409
46688
|
Key: key,
|
|
46410
|
-
...await expectedOwnerParam(
|
|
46689
|
+
...await expectedOwnerParam(s3)
|
|
46411
46690
|
}))).Body?.transformToString() ?? "", key);
|
|
46412
46691
|
entries.push({
|
|
46413
46692
|
region,
|
|
@@ -46451,6 +46730,7 @@ async function stateInfoCommand(options) {
|
|
|
46451
46730
|
...options.profile && { profile: options.profile }
|
|
46452
46731
|
});
|
|
46453
46732
|
setAwsClients(awsClients);
|
|
46733
|
+
let regionCorrectedS3 = null;
|
|
46454
46734
|
try {
|
|
46455
46735
|
const region = options.region || process.env["AWS_REGION"] || "us-east-1";
|
|
46456
46736
|
const resolved = await resolveStateBucketWithDefaultAndSource(options.stateBucket, region);
|
|
@@ -46460,10 +46740,18 @@ async function stateInfoCommand(options) {
|
|
|
46460
46740
|
bucket,
|
|
46461
46741
|
prefix
|
|
46462
46742
|
}).verifyBucketExists();
|
|
46463
|
-
|
|
46464
|
-
|
|
46465
|
-
|
|
46466
|
-
|
|
46743
|
+
regionCorrectedS3 = await rebuildClientForBucketRegion(awsClients.s3, bucket, {
|
|
46744
|
+
reuseClientCredentials: true,
|
|
46745
|
+
tolerateNonStandardClient: true,
|
|
46746
|
+
onRebuild: ({ bucketRegion, currentRegion }) => {
|
|
46747
|
+
logger.debug(`State bucket '${bucket}' is in '${bucketRegion}' (state-info client was '${String(currentRegion)}'); building a region-corrected S3 client for info reads.`);
|
|
46748
|
+
}
|
|
46749
|
+
});
|
|
46750
|
+
const infoS3 = regionCorrectedS3 ?? awsClients.s3;
|
|
46751
|
+
const detectedRegion = await detectBucketRegion(infoS3, bucket);
|
|
46752
|
+
const stateFileKeys = await listStateFileKeys(infoS3, bucket, prefix);
|
|
46753
|
+
const schemaVersion = await readSchemaVersion(infoS3, bucket, stateFileKeys);
|
|
46754
|
+
const assetStorage = await listAssetStorageMarkers(infoS3, bucket);
|
|
46467
46755
|
if (options.json) {
|
|
46468
46756
|
const json = {
|
|
46469
46757
|
bucket,
|
|
@@ -46491,6 +46779,7 @@ async function stateInfoCommand(options) {
|
|
|
46491
46779
|
}
|
|
46492
46780
|
process.stdout.write(`${lines.join("\n")}\n`);
|
|
46493
46781
|
} finally {
|
|
46782
|
+
regionCorrectedS3?.destroy();
|
|
46494
46783
|
awsClients.destroy();
|
|
46495
46784
|
}
|
|
46496
46785
|
}
|
|
@@ -57183,7 +57472,7 @@ function reorderArgs(argv) {
|
|
|
57183
57472
|
async function main() {
|
|
57184
57473
|
installPipeCloseHandler();
|
|
57185
57474
|
const program = new Command();
|
|
57186
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
57475
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.239.0");
|
|
57187
57476
|
program.addCommand(createBootstrapCommand());
|
|
57188
57477
|
program.addCommand(createSynthCommand());
|
|
57189
57478
|
program.addCommand(createListCommand());
|