@go-to-k/cdkd 0.267.19 → 0.268.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-C156B4uU.js → asg-provider-ZylgRJOY.js} +2 -2
- package/dist/{asg-provider-C156B4uU.js.map → asg-provider-ZylgRJOY.js.map} +1 -1
- package/dist/cli.js +237 -6
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-CZCV0ofI.js → deploy-engine-B5cRuFij.js} +220 -60
- package/dist/deploy-engine-B5cRuFij.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-CZCV0ofI.js.map +0 -1
|
@@ -977,7 +977,7 @@ function resetAwsClients() {
|
|
|
977
977
|
* request — the second caller awaits the same promise instead of issuing a
|
|
978
978
|
* duplicate API call.
|
|
979
979
|
*/
|
|
980
|
-
const cache
|
|
980
|
+
const cache = /* @__PURE__ */ new Map();
|
|
981
981
|
/**
|
|
982
982
|
* Resolve the AWS region of an S3 bucket via `GetBucketLocation`.
|
|
983
983
|
*
|
|
@@ -1002,7 +1002,7 @@ const cache$1 = /* @__PURE__ */ new Map();
|
|
|
1002
1002
|
* `opts.fallbackRegion` if provided, else `us-east-1`.
|
|
1003
1003
|
*/
|
|
1004
1004
|
async function resolveBucketRegion(bucketName, opts = {}) {
|
|
1005
|
-
const cached = cache
|
|
1005
|
+
const cached = cache.get(bucketName);
|
|
1006
1006
|
if (cached) return cached;
|
|
1007
1007
|
const promise = (async () => {
|
|
1008
1008
|
const client = new S3Client({
|
|
@@ -1022,7 +1022,7 @@ async function resolveBucketRegion(bucketName, opts = {}) {
|
|
|
1022
1022
|
client.destroy();
|
|
1023
1023
|
}
|
|
1024
1024
|
})();
|
|
1025
|
-
cache
|
|
1025
|
+
cache.set(bucketName, promise);
|
|
1026
1026
|
return promise;
|
|
1027
1027
|
}
|
|
1028
1028
|
/**
|
|
@@ -1030,7 +1030,7 @@ async function resolveBucketRegion(bucketName, opts = {}) {
|
|
|
1030
1030
|
* cases — production code never needs to call this.
|
|
1031
1031
|
*/
|
|
1032
1032
|
function clearBucketRegionCache() {
|
|
1033
|
-
cache
|
|
1033
|
+
cache.clear();
|
|
1034
1034
|
}
|
|
1035
1035
|
/**
|
|
1036
1036
|
* Resolve the cdkd state bucket name + region for a sibling AWS account.
|
|
@@ -2359,53 +2359,157 @@ function collectFnTransformNames(value, seen, out) {
|
|
|
2359
2359
|
*/
|
|
2360
2360
|
var expected_bucket_owner_exports = /* @__PURE__ */ __exportAll({
|
|
2361
2361
|
expectedOwnerParam: () => expectedOwnerParam,
|
|
2362
|
+
recordResolvedAccountId: () => recordResolvedAccountId,
|
|
2362
2363
|
resolveExpectedBucketOwner: () => resolveExpectedBucketOwner
|
|
2363
2364
|
});
|
|
2364
|
-
|
|
2365
|
+
/**
|
|
2366
|
+
* Fast path: per-S3-client memoization, so repeated calls on ONE client skip
|
|
2367
|
+
* even the (local) credential resolution.
|
|
2368
|
+
*/
|
|
2369
|
+
const clientCache = /* @__PURE__ */ new WeakMap();
|
|
2370
|
+
/**
|
|
2371
|
+
* Slow path: the actual `sts:GetCallerIdentity`, memoized by the resolved
|
|
2372
|
+
* **access key id** rather than by client identity (issue #1283).
|
|
2373
|
+
*
|
|
2374
|
+
* Why this key is both correct and safe:
|
|
2375
|
+
*
|
|
2376
|
+
* - An AWS access key id belongs to exactly ONE account, so "the account
|
|
2377
|
+
* behind these credentials" is a deterministic function of the credentials.
|
|
2378
|
+
* Keying on it is semantically identical to resolving per client — it is
|
|
2379
|
+
* strictly a better cache key for the same question.
|
|
2380
|
+
* - It cannot leak one identity's account onto another. An assumed-role
|
|
2381
|
+
* session has its own (`ASIA…`) key id, so the cross-account
|
|
2382
|
+
* `Fn::GetStackOutput` `RoleArn` path — whose ephemeral client carries the
|
|
2383
|
+
* ASSUMED credentials and must resolve the PRODUCER account — still misses
|
|
2384
|
+
* the cache and resolves its own account, exactly as before.
|
|
2385
|
+
*
|
|
2386
|
+
* The per-client WeakMap alone could not collapse the calls this cache
|
|
2387
|
+
* collapses: cdkd builds several S3 clients from the SAME credential chain in
|
|
2388
|
+
* one deploy preflight (the bucket-existence probe, the shared
|
|
2389
|
+
* `AwsClients.s3`, and the region-corrected client `ensureClientForBucket`
|
|
2390
|
+
* rebuilds), each of which used to pay its own STS round trip — with a fresh
|
|
2391
|
+
* TLS handshake, since each resolution constructs and destroys its own
|
|
2392
|
+
* `STSClient`.
|
|
2393
|
+
*/
|
|
2394
|
+
const credentialsCache = /* @__PURE__ */ new Map();
|
|
2395
|
+
/**
|
|
2396
|
+
* Resolve (and memoize) the account id behind a specific set of credentials.
|
|
2397
|
+
*
|
|
2398
|
+
* Failures are deliberately NOT cached — a transient STS throttle at process
|
|
2399
|
+
* start must not silently disable the header for the rest of the run (mirrors
|
|
2400
|
+
* write-only-properties.ts's no-failure-caching).
|
|
2401
|
+
*/
|
|
2402
|
+
function resolveAccountIdForCredentials(region, credentials) {
|
|
2403
|
+
const key = credentials.accessKeyId;
|
|
2404
|
+
const cached = credentialsCache.get(key);
|
|
2405
|
+
if (cached) return cached;
|
|
2406
|
+
const promise = (async () => {
|
|
2407
|
+
const sts = new STSClient({
|
|
2408
|
+
...typeof region === "string" && region ? { region } : {},
|
|
2409
|
+
credentials: {
|
|
2410
|
+
accessKeyId: credentials.accessKeyId,
|
|
2411
|
+
secretAccessKey: credentials.secretAccessKey,
|
|
2412
|
+
...credentials.sessionToken && { sessionToken: credentials.sessionToken }
|
|
2413
|
+
}
|
|
2414
|
+
});
|
|
2415
|
+
try {
|
|
2416
|
+
return (await sts.send(new GetCallerIdentityCommand({}))).Account;
|
|
2417
|
+
} finally {
|
|
2418
|
+
sts.destroy();
|
|
2419
|
+
}
|
|
2420
|
+
})();
|
|
2421
|
+
credentialsCache.set(key, promise);
|
|
2422
|
+
promise.catch(() => {
|
|
2423
|
+
if (credentialsCache.get(key) === promise) credentialsCache.delete(key);
|
|
2424
|
+
});
|
|
2425
|
+
return promise;
|
|
2426
|
+
}
|
|
2427
|
+
/**
|
|
2428
|
+
* Read a client's resolved region + credentials, or `undefined` when the
|
|
2429
|
+
* client is a test double / non-standard object.
|
|
2430
|
+
*/
|
|
2431
|
+
async function readClientIdentity(client) {
|
|
2432
|
+
const config = client.config;
|
|
2433
|
+
if (!config || typeof config.region !== "function" || typeof config.credentials !== "function") return;
|
|
2434
|
+
return {
|
|
2435
|
+
region: await config.region(),
|
|
2436
|
+
credentials: await config.credentials() ?? {}
|
|
2437
|
+
};
|
|
2438
|
+
}
|
|
2365
2439
|
/**
|
|
2366
2440
|
* Resolve the AWS account id of the caller behind an S3 client's
|
|
2367
|
-
* credentials.
|
|
2368
|
-
*
|
|
2369
|
-
* one extra STS call).
|
|
2441
|
+
* credentials. Memoized per client instance AND — for the STS call itself —
|
|
2442
|
+
* per resolved access key id, for the process lifetime.
|
|
2370
2443
|
*
|
|
2371
2444
|
* Works for the cross-account state-read path too (`Fn::GetStackOutput`
|
|
2372
2445
|
* `RoleArn`): the ephemeral backend's client carries the ASSUMED
|
|
2373
|
-
* credentials,
|
|
2374
|
-
* owner
|
|
2446
|
+
* credentials, whose access key id differs from the default chain's, so the
|
|
2447
|
+
* resolved owner is the producer account — exactly the owner its
|
|
2448
|
+
* `cdkd-state-{producerAccountId}` bucket must have.
|
|
2375
2449
|
*/
|
|
2376
2450
|
function resolveExpectedBucketOwner(client) {
|
|
2377
|
-
const cached =
|
|
2451
|
+
const cached = clientCache.get(client);
|
|
2378
2452
|
if (cached) return cached;
|
|
2379
2453
|
const promise = (async () => {
|
|
2380
2454
|
try {
|
|
2381
|
-
const
|
|
2382
|
-
if (!
|
|
2383
|
-
const region =
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
accessKeyId: credentials.accessKeyId,
|
|
2390
|
-
secretAccessKey: credentials.secretAccessKey,
|
|
2391
|
-
...credentials.sessionToken && { sessionToken: credentials.sessionToken }
|
|
2392
|
-
}
|
|
2455
|
+
const identity = await readClientIdentity(client);
|
|
2456
|
+
if (!identity) return;
|
|
2457
|
+
const { region, credentials } = identity;
|
|
2458
|
+
if (!credentials.accessKeyId || !credentials.secretAccessKey) return;
|
|
2459
|
+
return await resolveAccountIdForCredentials(region, {
|
|
2460
|
+
...credentials,
|
|
2461
|
+
accessKeyId: credentials.accessKeyId,
|
|
2462
|
+
secretAccessKey: credentials.secretAccessKey
|
|
2393
2463
|
});
|
|
2394
|
-
try {
|
|
2395
|
-
return (await sts.send(new GetCallerIdentityCommand({}))).Account;
|
|
2396
|
-
} finally {
|
|
2397
|
-
sts.destroy();
|
|
2398
|
-
}
|
|
2399
2464
|
} catch (error) {
|
|
2400
2465
|
getLogger().debug(`ExpectedBucketOwner resolution skipped (header omitted): ${String(error)}`);
|
|
2401
|
-
|
|
2466
|
+
clientCache.delete(client);
|
|
2402
2467
|
return;
|
|
2403
2468
|
}
|
|
2404
2469
|
})();
|
|
2405
|
-
|
|
2470
|
+
clientCache.set(client, promise);
|
|
2406
2471
|
return promise;
|
|
2407
2472
|
}
|
|
2408
2473
|
/**
|
|
2474
|
+
* Record an account id that a `sts:GetCallerIdentity` **already issued with
|
|
2475
|
+
* this client's own credentials** returned, so the next
|
|
2476
|
+
* {@link resolveExpectedBucketOwner} for any client sharing those credentials
|
|
2477
|
+
* is a cache hit instead of a second round trip (issue #1283).
|
|
2478
|
+
*
|
|
2479
|
+
* This is a memoization of a call that just happened, NOT an override:
|
|
2480
|
+
*
|
|
2481
|
+
* - The account is keyed by the credentials THIS client resolves, read from
|
|
2482
|
+
* the client itself. The caller cannot name the key, so it cannot attach
|
|
2483
|
+
* an account to credentials it does not hold.
|
|
2484
|
+
* - Consequently it can never be applied to a client carrying assumed or
|
|
2485
|
+
* foreign credentials on behalf of a different identity: seeding with an
|
|
2486
|
+
* assumed-credentials client records that SESSION's own account, under
|
|
2487
|
+
* that session's `ASIA…` key id, affecting only calls made with those
|
|
2488
|
+
* same credentials. There is deliberately no global "current account"
|
|
2489
|
+
* setter.
|
|
2490
|
+
*
|
|
2491
|
+
* The one real precondition — that `accountId` came from a
|
|
2492
|
+
* `GetCallerIdentity` made with `client`'s credentials — is why the only
|
|
2493
|
+
* caller is the state-bucket default-name resolution, which does exactly
|
|
2494
|
+
* that, on the line above the call.
|
|
2495
|
+
*
|
|
2496
|
+
* Best-effort: a non-standard client (test double) or an unresolvable
|
|
2497
|
+
* credential chain is a silent no-op; a later resolution just pays the round
|
|
2498
|
+
* trip it would have paid anyway.
|
|
2499
|
+
*/
|
|
2500
|
+
async function recordResolvedAccountId(client, accountId) {
|
|
2501
|
+
if (!accountId) return;
|
|
2502
|
+
try {
|
|
2503
|
+
const identity = await readClientIdentity(client);
|
|
2504
|
+
const accessKeyId = identity?.credentials.accessKeyId;
|
|
2505
|
+
if (!accessKeyId || !identity.credentials.secretAccessKey) return;
|
|
2506
|
+
if (credentialsCache.has(accessKeyId)) return;
|
|
2507
|
+
credentialsCache.set(accessKeyId, Promise.resolve(accountId));
|
|
2508
|
+
} catch (error) {
|
|
2509
|
+
getLogger().debug(`ExpectedBucketOwner seed skipped: ${String(error)}`);
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2409
2513
|
* Spread helper: `{...(await expectedOwnerParam(client))}` adds
|
|
2410
2514
|
* `ExpectedBucketOwner` when the owner resolved, nothing otherwise.
|
|
2411
2515
|
*/
|
|
@@ -2903,6 +3007,33 @@ function resolveApp(cliApp) {
|
|
|
2903
3007
|
return loadCdkJson()?.app ?? void 0;
|
|
2904
3008
|
}
|
|
2905
3009
|
/**
|
|
3010
|
+
* Did this resolution already prove the bucket is there AND usable by these
|
|
3011
|
+
* credentials — making the state backend's own `HeadBucket` pure duplication?
|
|
3012
|
+
*
|
|
3013
|
+
* Both conditions matter:
|
|
3014
|
+
*
|
|
3015
|
+
* - The source must be a default-name path.
|
|
3016
|
+
* {@link resolveStateBucketWithDefaultAndSource} picks between
|
|
3017
|
+
* `cdkd-state-{accountId}` and the legacy `cdkd-state-{accountId}-{region}`
|
|
3018
|
+
* by `HeadBucket`-ing both, with the same credentials the state client
|
|
3019
|
+
* will use. An explicitly-specified bucket (`--state-bucket` /
|
|
3020
|
+
* `CDKD_STATE_BUCKET` / `cdk.json`) is taken verbatim and never probed.
|
|
3021
|
+
* - The probe must have come back `'ok'`. A 403 counts as "exists" for
|
|
3022
|
+
* NAME resolution but says nothing good about usability, and it is
|
|
3023
|
+
* precisely the case where a second `HeadBucket` still earns its round
|
|
3024
|
+
* trip — it turns a confusing mid-deploy state-read failure into an
|
|
3025
|
+
* up-front "Access denied" before any asset is published.
|
|
3026
|
+
*
|
|
3027
|
+
* Consumed by `cdkd deploy` to skip the duplicate `HeadBucket` in
|
|
3028
|
+
* `S3StateBackend.verifyBucketExists` (issue
|
|
3029
|
+
* [#1283](https://github.com/go-to-k/cdkd/issues/1283)) — one fewer sequential
|
|
3030
|
+
* round trip on the deploy preflight's critical path.
|
|
3031
|
+
*/
|
|
3032
|
+
function stateBucketExistenceConfirmed(resolved) {
|
|
3033
|
+
if (resolved.source !== "default" && resolved.source !== "default-legacy") return false;
|
|
3034
|
+
return resolved.probe === "ok";
|
|
3035
|
+
}
|
|
3036
|
+
/**
|
|
2906
3037
|
* Resolve the `--capture-observed-state` / `--no-capture-observed-state`
|
|
2907
3038
|
* option's effective value, falling through to `cdk.json
|
|
2908
3039
|
* context.cdkd.captureObservedState` when the CLI flag was not passed.
|
|
@@ -3074,43 +3205,60 @@ async function resolveStateBucketWithDefaultAndSource(cliBucket, region) {
|
|
|
3074
3205
|
const logger = getLogger();
|
|
3075
3206
|
logger.debug("No state bucket specified, resolving default from account...");
|
|
3076
3207
|
const { GetCallerIdentityCommand } = await import("@aws-sdk/client-sts");
|
|
3077
|
-
const { S3Client } = await import("@aws-sdk/client-s3");
|
|
3208
|
+
const { S3Client, HeadBucketCommand, ListObjectsV2Command } = await import("@aws-sdk/client-s3");
|
|
3078
3209
|
const { getAwsClients } = await Promise.resolve().then(() => aws_clients_exports);
|
|
3079
|
-
const
|
|
3210
|
+
const { expectedOwnerParam, recordResolvedAccountId } = await Promise.resolve().then(() => expected_bucket_owner_exports);
|
|
3211
|
+
const probeDeps = {
|
|
3212
|
+
HeadBucketCommand,
|
|
3213
|
+
ListObjectsV2Command,
|
|
3214
|
+
expectedOwnerParam
|
|
3215
|
+
};
|
|
3216
|
+
const stsClient = getAwsClients().sts;
|
|
3217
|
+
const accountId = (await stsClient.send(new GetCallerIdentityCommand({}))).Account;
|
|
3218
|
+
await recordResolvedAccountId(stsClient, accountId);
|
|
3080
3219
|
const newName = getDefaultStateBucketName(accountId);
|
|
3081
3220
|
const legacyName = getLegacyStateBucketName(accountId, region);
|
|
3082
|
-
const
|
|
3221
|
+
const stsCredentials = stsClient.config?.credentials;
|
|
3222
|
+
const probe = new S3Client({
|
|
3223
|
+
region: "us-east-1",
|
|
3224
|
+
...typeof stsCredentials === "function" && { credentials: stsCredentials }
|
|
3225
|
+
});
|
|
3083
3226
|
try {
|
|
3084
|
-
const
|
|
3085
|
-
const
|
|
3227
|
+
const [newProbe, legacyProbe] = await Promise.all([probeBucket(probe, newName, probeDeps), probeBucket(probe, legacyName, probeDeps)]);
|
|
3228
|
+
const newExists = newProbe !== "missing";
|
|
3229
|
+
const legacyExists = legacyProbe !== "missing";
|
|
3086
3230
|
if (newExists && legacyExists) {
|
|
3087
|
-
if (!await bucketHasAnyState(probe, newName)) {
|
|
3088
|
-
if (await bucketHasAnyState(probe, legacyName)) {
|
|
3231
|
+
if (!await bucketHasAnyState(probe, newName, probeDeps)) {
|
|
3232
|
+
if (await bucketHasAnyState(probe, legacyName, probeDeps)) {
|
|
3089
3233
|
logger.warn(`Both '${newName}' (new default) and '${legacyName}' (legacy default) exist, but the new bucket is empty and the legacy one has state. Reading from legacy. Run \`cdkd state migrate --region ${region}\` to copy the state into the new bucket and stop seeing this warning.`);
|
|
3090
3234
|
return {
|
|
3091
3235
|
bucket: legacyName,
|
|
3092
|
-
source: "default-legacy"
|
|
3236
|
+
source: "default-legacy",
|
|
3237
|
+
probe: legacyProbe
|
|
3093
3238
|
};
|
|
3094
3239
|
}
|
|
3095
3240
|
}
|
|
3096
3241
|
logger.debug(`State bucket: ${newName}`);
|
|
3097
3242
|
return {
|
|
3098
3243
|
bucket: newName,
|
|
3099
|
-
source: "default"
|
|
3244
|
+
source: "default",
|
|
3245
|
+
probe: newProbe
|
|
3100
3246
|
};
|
|
3101
3247
|
}
|
|
3102
3248
|
if (newExists) {
|
|
3103
3249
|
logger.debug(`State bucket: ${newName}`);
|
|
3104
3250
|
return {
|
|
3105
3251
|
bucket: newName,
|
|
3106
|
-
source: "default"
|
|
3252
|
+
source: "default",
|
|
3253
|
+
probe: newProbe
|
|
3107
3254
|
};
|
|
3108
3255
|
}
|
|
3109
3256
|
if (legacyExists) {
|
|
3110
3257
|
logger.warn(`Using legacy state bucket name '${legacyName}'. The default has changed to '${newName}'. To migrate, run:\n\n cdkd state migrate --region ${region}\n\n(add --remove-legacy to delete the legacy bucket after a successful copy; legacy support will be dropped in a future release.)`);
|
|
3111
3258
|
return {
|
|
3112
3259
|
bucket: legacyName,
|
|
3113
|
-
source: "default-legacy"
|
|
3260
|
+
source: "default-legacy",
|
|
3261
|
+
probe: legacyProbe
|
|
3114
3262
|
};
|
|
3115
3263
|
}
|
|
3116
3264
|
throw new Error(`No cdkd state bucket found for account ${accountId}. Looked for '${newName}' (current default) and '${legacyName}' (legacy default). Run 'cdkd bootstrap' to create '${newName}'.`);
|
|
@@ -3131,9 +3279,8 @@ async function resolveStateBucketWithDefaultAndSource(cliBucket, region) {
|
|
|
3131
3279
|
* downstream getState call will surface the real read error); a false
|
|
3132
3280
|
* negative would silently route to legacy and be confusing.
|
|
3133
3281
|
*/
|
|
3134
|
-
async function bucketHasAnyState(client, bucketName) {
|
|
3135
|
-
const { ListObjectsV2Command } =
|
|
3136
|
-
const { expectedOwnerParam } = await Promise.resolve().then(() => expected_bucket_owner_exports);
|
|
3282
|
+
async function bucketHasAnyState(client, bucketName, deps) {
|
|
3283
|
+
const { ListObjectsV2Command, expectedOwnerParam } = deps;
|
|
3137
3284
|
try {
|
|
3138
3285
|
return ((await client.send(new ListObjectsV2Command({
|
|
3139
3286
|
Bucket: bucketName,
|
|
@@ -3148,30 +3295,35 @@ async function bucketHasAnyState(client, bucketName) {
|
|
|
3148
3295
|
/**
|
|
3149
3296
|
* Probe whether an S3 bucket exists from this account's perspective.
|
|
3150
3297
|
*
|
|
3151
|
-
* Returns:
|
|
3152
|
-
* - `
|
|
3298
|
+
* Returns a {@link BucketProbeOutcome}:
|
|
3299
|
+
* - `'ok'` for any 2xx (`HeadBucket` succeeded) **or** 301 (the bucket
|
|
3153
3300
|
* exists, just in a different region — we can still use it because the
|
|
3154
3301
|
* real region is resolved later by `resolveBucketRegion`).
|
|
3155
|
-
* - `
|
|
3156
|
-
*
|
|
3157
|
-
*
|
|
3302
|
+
* - `'access-denied'` for 403 (we lack permission to head it, but it
|
|
3303
|
+
* exists; name resolution still picks it and the state backend produces
|
|
3304
|
+
* a more specific error later).
|
|
3305
|
+
* - `'missing'` for 404 / `NotFound` / `NoSuchBucket`.
|
|
3158
3306
|
* - Re-throws anything else so credential / network failures aren't silently
|
|
3159
3307
|
* swallowed by the lookup chain.
|
|
3308
|
+
*
|
|
3309
|
+
* Name resolution only cares about `'missing'` vs. not; the `'ok'` /
|
|
3310
|
+
* `'access-denied'` split exists so `stateBucketExistenceConfirmed` can tell
|
|
3311
|
+
* "already verified" from "merely known to exist" (issue #1283).
|
|
3160
3312
|
*/
|
|
3161
|
-
async function
|
|
3162
|
-
const { HeadBucketCommand } =
|
|
3163
|
-
const { expectedOwnerParam } = await Promise.resolve().then(() => expected_bucket_owner_exports);
|
|
3313
|
+
async function probeBucket(client, bucketName, deps) {
|
|
3314
|
+
const { HeadBucketCommand, expectedOwnerParam } = deps;
|
|
3164
3315
|
try {
|
|
3165
3316
|
await client.send(new HeadBucketCommand({
|
|
3166
3317
|
Bucket: bucketName,
|
|
3167
3318
|
...await expectedOwnerParam(client)
|
|
3168
3319
|
}));
|
|
3169
|
-
return
|
|
3320
|
+
return "ok";
|
|
3170
3321
|
} catch (error) {
|
|
3171
3322
|
const err = error;
|
|
3172
3323
|
const status = err.$metadata?.httpStatusCode;
|
|
3173
|
-
if (err.name === "NotFound" || err.name === "NoSuchBucket" || status === 404) return
|
|
3174
|
-
if (status === 301
|
|
3324
|
+
if (err.name === "NotFound" || err.name === "NoSuchBucket" || status === 404) return "missing";
|
|
3325
|
+
if (status === 301) return "ok";
|
|
3326
|
+
if (status === 403) return "access-denied";
|
|
3175
3327
|
throw error;
|
|
3176
3328
|
}
|
|
3177
3329
|
}
|
|
@@ -5546,8 +5698,12 @@ var S3StateBackend = class {
|
|
|
5546
5698
|
async ownerParam() {
|
|
5547
5699
|
return expectedOwnerParam(this.s3Client);
|
|
5548
5700
|
}
|
|
5549
|
-
async verifyBucketExists() {
|
|
5701
|
+
async verifyBucketExists(options = {}) {
|
|
5550
5702
|
await this.ensureClientForBucket();
|
|
5703
|
+
if (options.existenceAlreadyProbed) {
|
|
5704
|
+
this.logger.debug(`Skipping the redundant HeadBucket on '${this.config.bucket}' — the default-name resolution already confirmed it exists with these credentials (issue #1283).`);
|
|
5705
|
+
return;
|
|
5706
|
+
}
|
|
5551
5707
|
try {
|
|
5552
5708
|
await this.s3Client.send(new HeadBucketCommand({
|
|
5553
5709
|
Bucket: this.config.bucket,
|
|
@@ -11637,7 +11793,7 @@ var CloudControlProvider = class {
|
|
|
11637
11793
|
this.logger.debug(`Deleting resource ${logicalId} (${resourceType}), physical ID: ${physicalId}`);
|
|
11638
11794
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
11639
11795
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
11640
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
11796
|
+
const { ASGProvider } = await import("./asg-provider-ZylgRJOY.js").then((n) => n.n);
|
|
11641
11797
|
await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
|
|
11642
11798
|
return;
|
|
11643
11799
|
}
|
|
@@ -13373,6 +13529,10 @@ const PROPERTY_COVERAGE_BY_TYPE = /* @__PURE__ */ new Map([
|
|
|
13373
13529
|
handled: /* @__PURE__ */ new Set(["DistributionConfig", "Tags"]),
|
|
13374
13530
|
silentDrop: /* @__PURE__ */ new Map()
|
|
13375
13531
|
}],
|
|
13532
|
+
["AWS::CloudFront::OriginAccessControl", {
|
|
13533
|
+
handled: /* @__PURE__ */ new Set(["OriginAccessControlConfig"]),
|
|
13534
|
+
silentDrop: /* @__PURE__ */ new Map()
|
|
13535
|
+
}],
|
|
13376
13536
|
["AWS::CloudTrail::Trail", {
|
|
13377
13537
|
handled: /* @__PURE__ */ new Set([
|
|
13378
13538
|
"CloudWatchLogsLogGroupArn",
|
|
@@ -17345,7 +17505,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
17345
17505
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
17346
17506
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
17347
17507
|
function getCdkdVersion() {
|
|
17348
|
-
return "0.
|
|
17508
|
+
return "0.268.0";
|
|
17349
17509
|
}
|
|
17350
17510
|
/**
|
|
17351
17511
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -19350,5 +19510,5 @@ var DeployEngine = class {
|
|
|
19350
19510
|
};
|
|
19351
19511
|
|
|
19352
19512
|
//#endregion
|
|
19353
|
-
export { WorkGraph as $,
|
|
19354
|
-
//# sourceMappingURL=deploy-engine-
|
|
19513
|
+
export { WorkGraph as $, MissingCdkCliError as $t, slowCcOperationTimeoutMs as A, warnDeprecatedNoPrefixCliFlag as At, applyRoleArnIfSet as B, resolveBucketRegion as Bt, yellow as C, resolveAutoAssetStorage as Ct, ProviderRegistry as D, resolveStateBucketWithDefaultAndSource as Dt, clearOnUpdateRemoval as E, resolveStateBucketWithDefault as Et, refStateLookupFromResource as F, uploadCfnTemplate as Ft, DagBuilder as G, AssetError as Gt, describeTypeWithThrottleRetry as H, getAwsClients as Ht, WAFv2WebACLProvider as I, expectedOwnerParam as It, S3StateBackend as J, DependencyError as Jt, TemplateParser as K, CdkdError as Kt, normalizeAwsTagsToCfn as L, AssemblyReader as Lt, isTerminationProtectionPropagationError as M, CFN_TEMPLATE_URL_LIMIT as Mt, IntrinsicFunctionResolver as N, MIGRATE_TMP_PREFIX as Nt, findActionableSilentDrops as O, resolveUseCdkBootstrapAssets as Ot, cfnRefValueFromPhysicalId as P, findLargeInlineResources as Pt, stringifyValue as Q, LockError as Qt, resolveExplicitPhysicalId as R, processStackMessages as Rt, red as S, resolveApp as St, collectInlinePolicyNamesManagedBySiblings as T, resolveSkipPrefix as Tt, withRetry as U, resetAwsClients as Ut, DiffCalculator as V, AwsClients as Vt, isRetryableTransientError as W, setAwsClients as Wt, shouldRetainResource as X, LocalMigrateError as Xt, rebuildClientForBucketRegion as Y, LocalInvokeBuildError as Yt, AssetPublisher as Z, LocalStartServiceError as Zt, formatResourceLine as _, getDockerImageBySourceHash as _t, DeploymentEventsStore as a, StackHasActiveImportsError as an, BOOTSTRAP_MARKER_PREFIX as at, gray as b, getDefaultStateBucketName as bt, replayFailedOperations as c, SynthesisError as cn, parseBootstrapMarker as ct, IMPLICIT_DELETE_DEPENDENCIES as d, normalizeAwsError as dn, buildDockerImage as dt, NestedStackChildDirectDestroyError as en, buildAssetRedirectMap as et, computeImplicitDeleteEdges as f, withErrorHandling as fn, formatDockerLoginError as ft, renderStatefulReason as g, AssetManifestLoader as gt, isStatefulRecreateTargetSync as h, runDockerStreaming as ht, DeploymentEventsReader as i, ResourceUpdateNotSupportedError as in, AssetModeResolver as it, disableInstanceApiTermination as j, CFN_TEMPLATE_BODY_LIMIT as jt, CloudControlProvider as k, stateBucketExistenceConfirmed as kt, replayRollback as l, formatError as ln, validateAssetBucketName as lt, MULTI_REGION_RECREATE_BLOCKED_TYPES as m, runDockerForeground as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, ProvisioningError as nn, loadPublishableAssetManifest as nt, planFailedOps as o, StackTerminationProtectionError as on, ensureAssetStorage as ot, extractDeploymentEventError as p, __exportAll as pn, getDockerCmd as pt, LockManager as q, ConfigError as qt, DeployEngine as r, ResourceTimeoutError as rn, rewriteTemplateAssetReferences as rt, planRollback as s, StateError as sn, getBootstrapMarkerKey as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, PartialFailureError as tn, createAssetRedirectResolver as tt, withResourceDeadline as u, isCdkdError as un, validateContainerRepoName as ut, bold as v, Synthesizer as vt, IAMRoleProvider as w, resolveCaptureObservedState as wt, green as x, getLegacyStateBucketName as xt, cyan as y, synthesisStatusMessage as yt, assertRegionMatch as z, clearBucketRegionCache as zt };
|
|
19514
|
+
//# sourceMappingURL=deploy-engine-B5cRuFij.js.map
|