@go-to-k/cdkd 0.9.0 → 0.11.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/README.md +3 -3
- package/dist/cli.js +233 -34
- package/dist/cli.js.map +4 -4
- package/dist/go-to-k-cdkd-0.11.0.tgz +0 -0
- package/dist/index.js +163 -15
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.9.0.tgz +0 -0
package/README.md
CHANGED
|
@@ -95,7 +95,7 @@ Reproduce with `./tests/benchmark/run-benchmark.sh all`. See [tests/benchmark/RE
|
|
|
95
95
|
```
|
|
96
96
|
1. CLI Layer
|
|
97
97
|
├── Resolve --app (CLI > CDKD_APP env > cdk.json "app")
|
|
98
|
-
├── Resolve --state-bucket (CLI > env > cdk.json > auto: cdkd-state-{accountId}-{region})
|
|
98
|
+
├── Resolve --state-bucket (CLI > env > cdk.json > auto: cdkd-state-{accountId}, with legacy fallback to cdkd-state-{accountId}-{region})
|
|
99
99
|
└── Initialize AWS clients
|
|
100
100
|
|
|
101
101
|
2. Synthesis (self-implemented, no CDK CLI dependency)
|
|
@@ -355,7 +355,7 @@ cdkd diff
|
|
|
355
355
|
cdkd destroy
|
|
356
356
|
```
|
|
357
357
|
|
|
358
|
-
That's it. cdkd reads `--app` from `cdk.json` and auto-resolves the state bucket from your AWS account ID (`cdkd-state-{accountId}-{region}`).
|
|
358
|
+
That's it. cdkd reads `--app` from `cdk.json` and auto-resolves the state bucket from your AWS account ID (`cdkd-state-{accountId}`). If you bootstrapped under a previous cdkd version, the legacy region-suffixed name (`cdkd-state-{accountId}-{region}`) is still picked up automatically with a deprecation warning.
|
|
359
359
|
|
|
360
360
|
## Usage
|
|
361
361
|
|
|
@@ -547,7 +547,7 @@ s3://{state-bucket}/
|
|
|
547
547
|
|
|
548
548
|
| Setting | CLI | cdk.json | Env var | Default |
|
|
549
549
|
|---------|-----|----------|---------|---------|
|
|
550
|
-
| Bucket | `--state-bucket` | `context.cdkd.stateBucket` | `CDKD_STATE_BUCKET` | `cdkd-state-{accountId}-{region}` |
|
|
550
|
+
| Bucket | `--state-bucket` | `context.cdkd.stateBucket` | `CDKD_STATE_BUCKET` | `cdkd-state-{accountId}` (legacy `cdkd-state-{accountId}-{region}` is still read with a deprecation warning) |
|
|
551
551
|
| Prefix | `--state-prefix` | - | - | `cdkd` |
|
|
552
552
|
|
|
553
553
|
### Multi-app isolation
|
package/dist/cli.js
CHANGED
|
@@ -885,6 +885,40 @@ function withErrorHandling(fn) {
|
|
|
885
885
|
}
|
|
886
886
|
};
|
|
887
887
|
}
|
|
888
|
+
function normalizeAwsError(err, context = {}) {
|
|
889
|
+
if (!(err instanceof Error)) {
|
|
890
|
+
return new Error(String(err));
|
|
891
|
+
}
|
|
892
|
+
const isUnknown = err.name === "Unknown" || err.message === "UnknownError";
|
|
893
|
+
if (!isUnknown)
|
|
894
|
+
return err;
|
|
895
|
+
const meta = err.$metadata;
|
|
896
|
+
const status = meta?.httpStatusCode;
|
|
897
|
+
const bucket = context.bucket ?? "<unknown bucket>";
|
|
898
|
+
const operation = context.operation ?? "operation";
|
|
899
|
+
switch (status) {
|
|
900
|
+
case 301: {
|
|
901
|
+
const responseHeaders = err.$response?.headers;
|
|
902
|
+
const region = responseHeaders?.["x-amz-bucket-region"] ?? responseHeaders?.["X-Amz-Bucket-Region"];
|
|
903
|
+
const where = region ? ` (in ${region})` : "";
|
|
904
|
+
return new Error(
|
|
905
|
+
`Bucket '${bucket}'${where} is in a different region than the client. cdkd resolves this automatically; if you see this message, please report it.`
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
case 403:
|
|
909
|
+
return new Error(
|
|
910
|
+
`Access denied to bucket '${bucket}'. Verify credentials and bucket policy.`
|
|
911
|
+
);
|
|
912
|
+
case 404:
|
|
913
|
+
return new Error(`Bucket '${bucket}' does not exist.`);
|
|
914
|
+
default: {
|
|
915
|
+
const statusStr = status !== void 0 ? `HTTP ${status}` : "unknown HTTP status";
|
|
916
|
+
return new Error(
|
|
917
|
+
`S3 error during ${operation} on '${bucket}' (${statusStr}). See CloudTrail for details.`
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
888
922
|
|
|
889
923
|
// src/cli/commands/bootstrap.ts
|
|
890
924
|
init_aws_clients();
|
|
@@ -937,7 +971,10 @@ function resolveStateBucket(cliBucket) {
|
|
|
937
971
|
const bucket = cdkdContext?.["stateBucket"];
|
|
938
972
|
return typeof bucket === "string" ? bucket : void 0;
|
|
939
973
|
}
|
|
940
|
-
function getDefaultStateBucketName(accountId
|
|
974
|
+
function getDefaultStateBucketName(accountId) {
|
|
975
|
+
return `cdkd-state-${accountId}`;
|
|
976
|
+
}
|
|
977
|
+
function getLegacyStateBucketName(accountId, region) {
|
|
941
978
|
return `cdkd-state-${accountId}-${region}`;
|
|
942
979
|
}
|
|
943
980
|
async function resolveStateBucketWithDefault(cliBucket, region) {
|
|
@@ -947,13 +984,48 @@ async function resolveStateBucketWithDefault(cliBucket, region) {
|
|
|
947
984
|
const logger = getLogger();
|
|
948
985
|
logger.debug("No state bucket specified, resolving default from account...");
|
|
949
986
|
const { GetCallerIdentityCommand: GetCallerIdentityCommand8 } = await import("@aws-sdk/client-sts");
|
|
987
|
+
const { S3Client: S3Client10 } = await import("@aws-sdk/client-s3");
|
|
950
988
|
const { getAwsClients: getAwsClients2 } = await Promise.resolve().then(() => (init_aws_clients(), aws_clients_exports));
|
|
951
989
|
const awsClients = getAwsClients2();
|
|
952
990
|
const identity = await awsClients.sts.send(new GetCallerIdentityCommand8({}));
|
|
953
991
|
const accountId = identity.Account;
|
|
954
|
-
const
|
|
955
|
-
|
|
956
|
-
|
|
992
|
+
const newName = getDefaultStateBucketName(accountId);
|
|
993
|
+
const legacyName = getLegacyStateBucketName(accountId, region);
|
|
994
|
+
const probe = new S3Client10({ region: "us-east-1" });
|
|
995
|
+
try {
|
|
996
|
+
if (await bucketExists(probe, newName)) {
|
|
997
|
+
logger.info(`State bucket: ${newName}`);
|
|
998
|
+
return newName;
|
|
999
|
+
}
|
|
1000
|
+
if (await bucketExists(probe, legacyName)) {
|
|
1001
|
+
logger.warn(
|
|
1002
|
+
`Using legacy state bucket name '${legacyName}'. The default has changed to '${newName}'. Future cdkd versions will drop legacy support; consider migrating with cdkd state migrate-bucket (coming in a future release).`
|
|
1003
|
+
);
|
|
1004
|
+
return legacyName;
|
|
1005
|
+
}
|
|
1006
|
+
throw new Error(
|
|
1007
|
+
`No cdkd state bucket found for account ${accountId}. Looked for '${newName}' (current default) and '${legacyName}' (legacy default). Run 'cdkd bootstrap' to create '${newName}'.`
|
|
1008
|
+
);
|
|
1009
|
+
} finally {
|
|
1010
|
+
probe.destroy();
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
async function bucketExists(client, bucketName) {
|
|
1014
|
+
const { HeadBucketCommand: HeadBucketCommand3 } = await import("@aws-sdk/client-s3");
|
|
1015
|
+
try {
|
|
1016
|
+
await client.send(new HeadBucketCommand3({ Bucket: bucketName }));
|
|
1017
|
+
return true;
|
|
1018
|
+
} catch (error) {
|
|
1019
|
+
const err = error;
|
|
1020
|
+
const status = err.$metadata?.httpStatusCode;
|
|
1021
|
+
if (err.name === "NotFound" || err.name === "NoSuchBucket" || status === 404) {
|
|
1022
|
+
return false;
|
|
1023
|
+
}
|
|
1024
|
+
if (status === 301 || status === 403) {
|
|
1025
|
+
return true;
|
|
1026
|
+
}
|
|
1027
|
+
throw error;
|
|
1028
|
+
}
|
|
957
1029
|
}
|
|
958
1030
|
|
|
959
1031
|
// src/cli/commands/bootstrap.ts
|
|
@@ -981,24 +1053,24 @@ async function bootstrapCommand(options) {
|
|
|
981
1053
|
logger.info("No --state-bucket specified, resolving default bucket name...");
|
|
982
1054
|
const identity = await awsClients.sts.send(new GetCallerIdentityCommand({}));
|
|
983
1055
|
accountId = identity.Account;
|
|
984
|
-
bucketName = getDefaultStateBucketName(accountId
|
|
1056
|
+
bucketName = getDefaultStateBucketName(accountId);
|
|
985
1057
|
logger.info(`Using default state bucket: ${bucketName}`);
|
|
986
1058
|
}
|
|
987
1059
|
try {
|
|
988
|
-
let
|
|
1060
|
+
let bucketExists2 = false;
|
|
989
1061
|
try {
|
|
990
1062
|
await s3Client.send(new HeadBucketCommand({ Bucket: bucketName }));
|
|
991
|
-
|
|
1063
|
+
bucketExists2 = true;
|
|
992
1064
|
logger.info(`Bucket ${bucketName} already exists`);
|
|
993
1065
|
} catch (error) {
|
|
994
1066
|
const err = error;
|
|
995
1067
|
if (err.name === "NotFound" || err.name === "NoSuchBucket") {
|
|
996
1068
|
logger.debug(`Bucket ${bucketName} does not exist, will create`);
|
|
997
1069
|
} else {
|
|
998
|
-
throw error;
|
|
1070
|
+
throw normalizeAwsError(error, { bucket: bucketName, operation: "HeadBucket" });
|
|
999
1071
|
}
|
|
1000
1072
|
}
|
|
1001
|
-
if (
|
|
1073
|
+
if (bucketExists2) {
|
|
1002
1074
|
if (!options.force) {
|
|
1003
1075
|
logger.warn(
|
|
1004
1076
|
`Bucket ${bucketName} already exists. Use --force to reconfigure (this will not delete existing state)`
|
|
@@ -1085,7 +1157,7 @@ State bucket: ${bucketName}`);
|
|
|
1085
1157
|
function createBootstrapCommand() {
|
|
1086
1158
|
const cmd = new Command("bootstrap").description("Bootstrap cdkd by creating required S3 bucket for state management").option(
|
|
1087
1159
|
"--state-bucket <bucket>",
|
|
1088
|
-
"Name of S3 bucket to create for state storage (default: cdkd-state-{accountId}
|
|
1160
|
+
"Name of S3 bucket to create for state storage (default: cdkd-state-{accountId})"
|
|
1089
1161
|
).option("--force", "Force reconfiguration of existing bucket", false).action(withErrorHandling(bootstrapCommand));
|
|
1090
1162
|
commonOptions.forEach((opt) => cmd.addOption(opt));
|
|
1091
1163
|
return cmd;
|
|
@@ -3197,6 +3269,7 @@ var AssetPublisher = class {
|
|
|
3197
3269
|
|
|
3198
3270
|
// src/state/s3-state-backend.ts
|
|
3199
3271
|
import {
|
|
3272
|
+
S3Client as S3Client4,
|
|
3200
3273
|
GetObjectCommand,
|
|
3201
3274
|
PutObjectCommand as PutObjectCommand2,
|
|
3202
3275
|
DeleteObjectCommand,
|
|
@@ -3210,15 +3283,44 @@ import {
|
|
|
3210
3283
|
var STATE_SCHEMA_VERSION_LEGACY = 1;
|
|
3211
3284
|
var STATE_SCHEMA_VERSION_CURRENT = 2;
|
|
3212
3285
|
|
|
3286
|
+
// src/utils/aws-region-resolver.ts
|
|
3287
|
+
import { GetBucketLocationCommand, S3Client as S3Client3 } from "@aws-sdk/client-s3";
|
|
3288
|
+
var cache = /* @__PURE__ */ new Map();
|
|
3289
|
+
async function resolveBucketRegion(bucketName, opts = {}) {
|
|
3290
|
+
const cached = cache.get(bucketName);
|
|
3291
|
+
if (cached)
|
|
3292
|
+
return cached;
|
|
3293
|
+
const promise = (async () => {
|
|
3294
|
+
const client = new S3Client3({
|
|
3295
|
+
region: "us-east-1",
|
|
3296
|
+
...opts.profile && { profile: opts.profile },
|
|
3297
|
+
...opts.credentials && { credentials: opts.credentials }
|
|
3298
|
+
});
|
|
3299
|
+
try {
|
|
3300
|
+
const response = await client.send(new GetBucketLocationCommand({ Bucket: bucketName }));
|
|
3301
|
+
return response.LocationConstraint || "us-east-1";
|
|
3302
|
+
} catch {
|
|
3303
|
+
return opts.fallbackRegion ?? "us-east-1";
|
|
3304
|
+
} finally {
|
|
3305
|
+
client.destroy();
|
|
3306
|
+
}
|
|
3307
|
+
})();
|
|
3308
|
+
cache.set(bucketName, promise);
|
|
3309
|
+
return promise;
|
|
3310
|
+
}
|
|
3311
|
+
|
|
3213
3312
|
// src/state/s3-state-backend.ts
|
|
3214
3313
|
var LEGACY_KEY_DEPTH = 2;
|
|
3215
3314
|
var NEW_KEY_DEPTH = 3;
|
|
3216
3315
|
var S3StateBackend = class {
|
|
3217
|
-
constructor(s3Client, config) {
|
|
3316
|
+
constructor(s3Client, config, clientOpts = {}) {
|
|
3218
3317
|
this.s3Client = s3Client;
|
|
3219
3318
|
this.config = config;
|
|
3319
|
+
this.clientOpts = clientOpts;
|
|
3220
3320
|
}
|
|
3221
3321
|
logger = getLogger().child("S3StateBackend");
|
|
3322
|
+
clientResolved = false;
|
|
3323
|
+
resolveInFlight = null;
|
|
3222
3324
|
/**
|
|
3223
3325
|
* Get the new (region-scoped) S3 key for a stack's state file.
|
|
3224
3326
|
*/
|
|
@@ -3232,13 +3334,73 @@ var S3StateBackend = class {
|
|
|
3232
3334
|
getLegacyStateKey(stackName) {
|
|
3233
3335
|
return `${this.config.prefix}/${stackName}/state.json`;
|
|
3234
3336
|
}
|
|
3337
|
+
/**
|
|
3338
|
+
* Resolve the state bucket's actual region and, if it differs from the
|
|
3339
|
+
* client's currently-configured region, replace the S3Client with one
|
|
3340
|
+
* pointed at the bucket's region.
|
|
3341
|
+
*
|
|
3342
|
+
* This is idempotent: subsequent calls return immediately. Concurrent
|
|
3343
|
+
* callers (e.g. when several public methods race during a parallel deploy)
|
|
3344
|
+
* share a single in-flight resolution promise so we never issue more than
|
|
3345
|
+
* one `GetBucketLocation` per backend.
|
|
3346
|
+
*
|
|
3347
|
+
* Errors from `GetBucketLocation` are deliberately swallowed by
|
|
3348
|
+
* `resolveBucketRegion` — the resolver returns `fallbackRegion` so the
|
|
3349
|
+
* caller can surface the more actionable downstream error (e.g. the
|
|
3350
|
+
* `HeadBucket` 404 routed via `normalizeAwsError`).
|
|
3351
|
+
*/
|
|
3352
|
+
async ensureClientForBucket() {
|
|
3353
|
+
if (this.clientResolved)
|
|
3354
|
+
return;
|
|
3355
|
+
if (this.resolveInFlight)
|
|
3356
|
+
return this.resolveInFlight;
|
|
3357
|
+
this.resolveInFlight = (async () => {
|
|
3358
|
+
try {
|
|
3359
|
+
const currentRegion = await this.s3Client.config.region();
|
|
3360
|
+
const fallbackRegion = typeof currentRegion === "string" ? currentRegion : void 0;
|
|
3361
|
+
const bucketRegion = await resolveBucketRegion(this.config.bucket, {
|
|
3362
|
+
...this.clientOpts.profile && { profile: this.clientOpts.profile },
|
|
3363
|
+
...this.clientOpts.credentials && { credentials: this.clientOpts.credentials },
|
|
3364
|
+
...fallbackRegion && { fallbackRegion }
|
|
3365
|
+
});
|
|
3366
|
+
if (bucketRegion !== currentRegion) {
|
|
3367
|
+
this.logger.debug(
|
|
3368
|
+
`State bucket '${this.config.bucket}' is in '${bucketRegion}' (client was '${currentRegion}'); rebuilding S3 client.`
|
|
3369
|
+
);
|
|
3370
|
+
const oldClient = this.s3Client;
|
|
3371
|
+
this.s3Client = new S3Client4({
|
|
3372
|
+
region: bucketRegion,
|
|
3373
|
+
...this.clientOpts.profile && { profile: this.clientOpts.profile },
|
|
3374
|
+
...this.clientOpts.credentials && { credentials: this.clientOpts.credentials },
|
|
3375
|
+
// Suppress "Are you using a Stream of unknown length" warning,
|
|
3376
|
+
// matching the suppression in AwsClients.
|
|
3377
|
+
logger: { debug: () => {
|
|
3378
|
+
}, info: () => {
|
|
3379
|
+
}, warn: () => {
|
|
3380
|
+
}, error: () => {
|
|
3381
|
+
} }
|
|
3382
|
+
});
|
|
3383
|
+
oldClient.destroy();
|
|
3384
|
+
}
|
|
3385
|
+
this.clientResolved = true;
|
|
3386
|
+
} finally {
|
|
3387
|
+
this.resolveInFlight = null;
|
|
3388
|
+
}
|
|
3389
|
+
})();
|
|
3390
|
+
return this.resolveInFlight;
|
|
3391
|
+
}
|
|
3235
3392
|
/**
|
|
3236
3393
|
* Verify that the configured state bucket exists.
|
|
3237
3394
|
*
|
|
3238
3395
|
* Called early in deploy/destroy to fail fast before expensive work
|
|
3239
3396
|
* (asset publishing, Docker builds) runs against a missing bucket.
|
|
3397
|
+
*
|
|
3398
|
+
* Errors are routed through {@link normalizeAwsError} so the AWS SDK v3
|
|
3399
|
+
* synthetic `UnknownError` (e.g. cross-region HEAD) becomes a concrete
|
|
3400
|
+
* "Bucket does not exist" / "Access denied" / "different region" message.
|
|
3240
3401
|
*/
|
|
3241
3402
|
async verifyBucketExists() {
|
|
3403
|
+
await this.ensureClientForBucket();
|
|
3242
3404
|
try {
|
|
3243
3405
|
await this.s3Client.send(new HeadBucketCommand2({ Bucket: this.config.bucket }));
|
|
3244
3406
|
} catch (error) {
|
|
@@ -3248,9 +3410,13 @@ var S3StateBackend = class {
|
|
|
3248
3410
|
`State bucket '${this.config.bucket}' does not exist. Run 'cdkd bootstrap' to create it, or specify an existing bucket via --state-bucket, CDKD_STATE_BUCKET, or cdk.json context.cdkd.stateBucket.`
|
|
3249
3411
|
);
|
|
3250
3412
|
}
|
|
3413
|
+
const normalized = normalizeAwsError(error, {
|
|
3414
|
+
bucket: this.config.bucket,
|
|
3415
|
+
operation: "HeadBucket"
|
|
3416
|
+
});
|
|
3251
3417
|
throw new StateError(
|
|
3252
|
-
`Failed to verify state bucket '${this.config.bucket}': ${
|
|
3253
|
-
|
|
3418
|
+
`Failed to verify state bucket '${this.config.bucket}': ${normalized.message}`,
|
|
3419
|
+
normalized
|
|
3254
3420
|
);
|
|
3255
3421
|
}
|
|
3256
3422
|
}
|
|
@@ -3263,6 +3429,7 @@ var S3StateBackend = class {
|
|
|
3263
3429
|
* state without forcing a write-through migration first.
|
|
3264
3430
|
*/
|
|
3265
3431
|
async stateExists(stackName, region) {
|
|
3432
|
+
await this.ensureClientForBucket();
|
|
3266
3433
|
const newKey = this.getStateKey(stackName, region);
|
|
3267
3434
|
if (await this.headObject(newKey)) {
|
|
3268
3435
|
return true;
|
|
@@ -3285,6 +3452,7 @@ var S3StateBackend = class {
|
|
|
3285
3452
|
* preserve the quotes — they are required for `IfMatch` conditions.
|
|
3286
3453
|
*/
|
|
3287
3454
|
async getState(stackName, region) {
|
|
3455
|
+
await this.ensureClientForBucket();
|
|
3288
3456
|
const newKey = this.getStateKey(stackName, region);
|
|
3289
3457
|
try {
|
|
3290
3458
|
this.logger.debug(`Getting state for stack: ${stackName} (${region})`);
|
|
@@ -3344,6 +3512,7 @@ var S3StateBackend = class {
|
|
|
3344
3512
|
* @returns New ETag (with quotes, e.g., `"abc123"`)
|
|
3345
3513
|
*/
|
|
3346
3514
|
async saveState(stackName, region, state, options = {}) {
|
|
3515
|
+
await this.ensureClientForBucket();
|
|
3347
3516
|
const newKey = this.getStateKey(stackName, region);
|
|
3348
3517
|
const { expectedEtag, migrateLegacy } = options;
|
|
3349
3518
|
const body = {
|
|
@@ -3399,9 +3568,13 @@ var S3StateBackend = class {
|
|
|
3399
3568
|
`State has been modified by another process. Expected ETag: ${expectedEtag}, but state has changed.`
|
|
3400
3569
|
);
|
|
3401
3570
|
}
|
|
3571
|
+
const normalized = normalizeAwsError(error, {
|
|
3572
|
+
bucket: this.config.bucket,
|
|
3573
|
+
operation: "PutObject"
|
|
3574
|
+
});
|
|
3402
3575
|
throw new StateError(
|
|
3403
|
-
`Failed to save state for stack '${stackName}' (${region}): ${
|
|
3404
|
-
|
|
3576
|
+
`Failed to save state for stack '${stackName}' (${region}): ${normalized.message}`,
|
|
3577
|
+
normalized
|
|
3405
3578
|
);
|
|
3406
3579
|
}
|
|
3407
3580
|
}
|
|
@@ -3413,6 +3586,7 @@ var S3StateBackend = class {
|
|
|
3413
3586
|
* field is left alone.
|
|
3414
3587
|
*/
|
|
3415
3588
|
async deleteState(stackName, region) {
|
|
3589
|
+
await this.ensureClientForBucket();
|
|
3416
3590
|
try {
|
|
3417
3591
|
this.logger.debug(`Deleting state: ${stackName} (${region})`);
|
|
3418
3592
|
await this.s3Client.send(
|
|
@@ -3432,9 +3606,13 @@ var S3StateBackend = class {
|
|
|
3432
3606
|
}
|
|
3433
3607
|
this.logger.debug(`State deleted: ${stackName} (${region})`);
|
|
3434
3608
|
} catch (error) {
|
|
3609
|
+
const normalized = normalizeAwsError(error, {
|
|
3610
|
+
bucket: this.config.bucket,
|
|
3611
|
+
operation: "DeleteObject"
|
|
3612
|
+
});
|
|
3435
3613
|
throw new StateError(
|
|
3436
|
-
`Failed to delete state for stack '${stackName}' (${region}): ${
|
|
3437
|
-
|
|
3614
|
+
`Failed to delete state for stack '${stackName}' (${region}): ${normalized.message}`,
|
|
3615
|
+
normalized
|
|
3438
3616
|
);
|
|
3439
3617
|
}
|
|
3440
3618
|
}
|
|
@@ -3453,6 +3631,7 @@ var S3StateBackend = class {
|
|
|
3453
3631
|
* shows up exactly once.
|
|
3454
3632
|
*/
|
|
3455
3633
|
async listStacks() {
|
|
3634
|
+
await this.ensureClientForBucket();
|
|
3456
3635
|
try {
|
|
3457
3636
|
this.logger.debug("Listing all stacks");
|
|
3458
3637
|
const prefix = `${this.config.prefix}/`;
|
|
@@ -3503,10 +3682,11 @@ var S3StateBackend = class {
|
|
|
3503
3682
|
this.logger.debug(`Found ${refs.length} stack(s) across regions`);
|
|
3504
3683
|
return refs;
|
|
3505
3684
|
} catch (error) {
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
);
|
|
3685
|
+
const normalized = normalizeAwsError(error, {
|
|
3686
|
+
bucket: this.config.bucket,
|
|
3687
|
+
operation: "ListObjectsV2"
|
|
3688
|
+
});
|
|
3689
|
+
throw new StateError(`Failed to list stacks: ${normalized.message}`, normalized);
|
|
3510
3690
|
}
|
|
3511
3691
|
}
|
|
3512
3692
|
/**
|
|
@@ -6804,7 +6984,7 @@ Error: ${err.message || "Unknown error"}`,
|
|
|
6804
6984
|
import { InvokeCommand } from "@aws-sdk/client-lambda";
|
|
6805
6985
|
import { PublishCommand } from "@aws-sdk/client-sns";
|
|
6806
6986
|
import {
|
|
6807
|
-
S3Client as
|
|
6987
|
+
S3Client as S3Client6,
|
|
6808
6988
|
PutObjectCommand as PutObjectCommand4,
|
|
6809
6989
|
GetObjectCommand as GetObjectCommand3,
|
|
6810
6990
|
DeleteObjectCommand as DeleteObjectCommand3
|
|
@@ -6873,7 +7053,7 @@ var CustomResourceProvider = class _CustomResourceProvider {
|
|
|
6873
7053
|
setResponseBucket(bucket, bucketRegion) {
|
|
6874
7054
|
this.responseBucket = bucket;
|
|
6875
7055
|
if (bucketRegion) {
|
|
6876
|
-
this.s3Client = new
|
|
7056
|
+
this.s3Client = new S3Client6(bucketRegion ? { region: bucketRegion } : {});
|
|
6877
7057
|
}
|
|
6878
7058
|
}
|
|
6879
7059
|
/**
|
|
@@ -25798,7 +25978,7 @@ var CodeBuildProvider = class {
|
|
|
25798
25978
|
const tags = properties["Tags"];
|
|
25799
25979
|
const envVars = environment?.["EnvironmentVariables"];
|
|
25800
25980
|
const cfnCache = properties["Cache"];
|
|
25801
|
-
const
|
|
25981
|
+
const cache2 = cfnCache ? {
|
|
25802
25982
|
type: cfnCache["Type"],
|
|
25803
25983
|
location: cfnCache["Location"],
|
|
25804
25984
|
modes: cfnCache["Modes"]
|
|
@@ -25885,7 +26065,7 @@ var CodeBuildProvider = class {
|
|
|
25885
26065
|
timeoutInMinutes: properties["TimeoutInMinutes"],
|
|
25886
26066
|
queuedTimeoutInMinutes: properties["QueuedTimeoutInMinutes"],
|
|
25887
26067
|
encryptionKey: properties["EncryptionKey"],
|
|
25888
|
-
cache,
|
|
26068
|
+
cache: cache2,
|
|
25889
26069
|
vpcConfig,
|
|
25890
26070
|
logsConfig,
|
|
25891
26071
|
concurrentBuildLimit: properties["ConcurrentBuildLimit"],
|
|
@@ -28429,10 +28609,17 @@ async function deployCommand(stacks, options) {
|
|
|
28429
28609
|
...options.profile && { profile: options.profile }
|
|
28430
28610
|
});
|
|
28431
28611
|
setAwsClients(awsClients);
|
|
28432
|
-
const preflightStateBackend = new S3StateBackend(
|
|
28433
|
-
|
|
28434
|
-
|
|
28435
|
-
|
|
28612
|
+
const preflightStateBackend = new S3StateBackend(
|
|
28613
|
+
awsClients.s3,
|
|
28614
|
+
{
|
|
28615
|
+
bucket: stateBucket,
|
|
28616
|
+
prefix: options.statePrefix
|
|
28617
|
+
},
|
|
28618
|
+
{
|
|
28619
|
+
region,
|
|
28620
|
+
...options.profile && { profile: options.profile }
|
|
28621
|
+
}
|
|
28622
|
+
);
|
|
28436
28623
|
await preflightStateBackend.verifyBucketExists();
|
|
28437
28624
|
let deployInterrupted = false;
|
|
28438
28625
|
const topLevelSigintHandler = () => {
|
|
@@ -28583,7 +28770,10 @@ Deploying stack: ${stackInfo.stackName}${stackRegion !== baseRegion ? ` (region:
|
|
|
28583
28770
|
region: baseRegion,
|
|
28584
28771
|
...options.profile && { profile: options.profile }
|
|
28585
28772
|
});
|
|
28586
|
-
const stackStateBackend = new S3StateBackend(stateS3Client.s3, stateConfig
|
|
28773
|
+
const stackStateBackend = new S3StateBackend(stateS3Client.s3, stateConfig, {
|
|
28774
|
+
region: baseRegion,
|
|
28775
|
+
...options.profile && { profile: options.profile }
|
|
28776
|
+
});
|
|
28587
28777
|
const stackLockManager = new LockManager(stateS3Client.s3, stateConfig);
|
|
28588
28778
|
const stackProviderRegistry = new ProviderRegistry();
|
|
28589
28779
|
registerAllProviders(stackProviderRegistry);
|
|
@@ -28764,7 +28954,10 @@ async function diffCommand(stacks, options) {
|
|
|
28764
28954
|
bucket: stateBucket,
|
|
28765
28955
|
prefix: options.statePrefix
|
|
28766
28956
|
};
|
|
28767
|
-
const stateBackend = new S3StateBackend(awsClients.s3, stateConfig
|
|
28957
|
+
const stateBackend = new S3StateBackend(awsClients.s3, stateConfig, {
|
|
28958
|
+
region,
|
|
28959
|
+
...options.profile && { profile: options.profile }
|
|
28960
|
+
});
|
|
28768
28961
|
const diffCalculator = new DiffCalculator();
|
|
28769
28962
|
const intrinsicResolver = new IntrinsicFunctionResolver(region);
|
|
28770
28963
|
for (const stackInfo of targetStacks) {
|
|
@@ -28884,7 +29077,10 @@ async function destroyCommand(stackArgs, options) {
|
|
|
28884
29077
|
bucket: stateBucket,
|
|
28885
29078
|
prefix: options.statePrefix
|
|
28886
29079
|
};
|
|
28887
|
-
const stateBackend = new S3StateBackend(awsClients.s3, stateConfig
|
|
29080
|
+
const stateBackend = new S3StateBackend(awsClients.s3, stateConfig, {
|
|
29081
|
+
...options.region && { region: options.region },
|
|
29082
|
+
...options.profile && { profile: options.profile }
|
|
29083
|
+
});
|
|
28888
29084
|
await stateBackend.verifyBucketExists();
|
|
28889
29085
|
const lockManager = new LockManager(awsClients.s3, stateConfig);
|
|
28890
29086
|
const dagBuilder = new DagBuilder();
|
|
@@ -29333,7 +29529,10 @@ async function setupStateBackend(options) {
|
|
|
29333
29529
|
const bucket = await resolveStateBucketWithDefault(options.stateBucket, region);
|
|
29334
29530
|
const prefix = options.statePrefix;
|
|
29335
29531
|
const stateConfig = { bucket, prefix };
|
|
29336
|
-
const stateBackend = new S3StateBackend(awsClients.s3, stateConfig
|
|
29532
|
+
const stateBackend = new S3StateBackend(awsClients.s3, stateConfig, {
|
|
29533
|
+
region,
|
|
29534
|
+
...options.profile && { profile: options.profile }
|
|
29535
|
+
});
|
|
29337
29536
|
const lockManager = new LockManager(awsClients.s3, stateConfig);
|
|
29338
29537
|
await stateBackend.verifyBucketExists();
|
|
29339
29538
|
return {
|
|
@@ -29737,7 +29936,7 @@ function reorderArgs(argv) {
|
|
|
29737
29936
|
}
|
|
29738
29937
|
async function main() {
|
|
29739
29938
|
const program = new Command10();
|
|
29740
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
29939
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.11.0");
|
|
29741
29940
|
program.addCommand(createBootstrapCommand());
|
|
29742
29941
|
program.addCommand(createSynthCommand());
|
|
29743
29942
|
program.addCommand(createListCommand());
|