@go-to-k/cdkd 0.291.18 → 0.291.20
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-DR5gOGbi.js → asg-provider-C0qLsIu5.js} +5 -5
- package/dist/asg-provider-C0qLsIu5.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-BwDlgFRs.js → deploy-engine-CkF6PyFY.js} +382 -213
- package/dist/deploy-engine-CkF6PyFY.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-DxyHPT8E.js → program-CwcF5msU.js} +152 -94
- package/dist/{program-DxyHPT8E.js.map → program-CwcF5msU.js.map} +1 -1
- package/dist/{version-CJkb2usU.js → version-BYrVI73L.js} +2 -2
- package/dist/{version-CJkb2usU.js.map → version-BYrVI73L.js.map} +1 -1
- package/package.json +1 -1
- package/dist/asg-provider-DR5gOGbi.js.map +0 -1
- package/dist/deploy-engine-BwDlgFRs.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as displayAwsMessage, D as isPasteableIdent, E as displayStackName, O as truncateCodePoints, S as UNRENDERABLE, T as displaySafe, d as applyDefaultNameForFallback, f as explicitNamePropertyFor, g as looksLikeCdkdGeneratedName, h as getCurrentStackName, m as generateResourceNameWithFallback, n as getLogger, p as generateResourceName, r as isStdoutReservedForPayload, s as getLiveRenderer, v as withStackName, w as displayIdent, x as STACK_REF_MAX_CODE_POINTS, y as withoutGeneratedFallbackName } from "./logger-Bt0RGDfb.js";
|
|
2
2
|
import { a as setAssumedRoleCredentials, c as currentStackAwsScope, i as getPreAssumeEnvCredentials, l as runInStackAwsScope, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, s as ambientRegion, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-jISU4PHo.js";
|
|
3
|
-
import { t as getCdkdVersion } from "./version-
|
|
3
|
+
import { t as getCdkdVersion } from "./version-BYrVI73L.js";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
5
|
import { createHash, randomUUID } from "node:crypto";
|
|
6
6
|
import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -4120,6 +4120,109 @@ var ContextStore = class {
|
|
|
4120
4120
|
}
|
|
4121
4121
|
};
|
|
4122
4122
|
|
|
4123
|
+
//#endregion
|
|
4124
|
+
//#region src/utils/ambient-client-defaults.ts
|
|
4125
|
+
/**
|
|
4126
|
+
* Client config for an SDK client built OUTSIDE `AwsClients` (issue
|
|
4127
|
+
* [#3588](https://github.com/go-to-k/cdkd/issues/3588)).
|
|
4128
|
+
*
|
|
4129
|
+
* `awsClientDefaults()` alone carries the ambient ENVIRONMENT — `AWS_PROFILE`,
|
|
4130
|
+
* a published `--role-arn` role, the proxy handler, a stack scope's region — but
|
|
4131
|
+
* not an explicit `AwsClientConfig.credentials` object, which has no
|
|
4132
|
+
* environment path at all. A LIBRARY caller that installs
|
|
4133
|
+
* `new AwsClients({ credentials })` (`AwsClients` / `setAwsClients` are public
|
|
4134
|
+
* exports) therefore had every client a provider, context provider,
|
|
4135
|
+
* asset publisher or the cross-account STS hop built for itself signing with
|
|
4136
|
+
* the default credential chain: a different identity from the one it
|
|
4137
|
+
* configured. {@link ambientClientDefaults} closes that for every site at once
|
|
4138
|
+
* by reading the ACTIVE clients' {@link AwsClients.credentialConfig}.
|
|
4139
|
+
*
|
|
4140
|
+
* BOUND: a site that caches its client (every SDK provider's lazy
|
|
4141
|
+
* `getClient()`) captures the identity active at its FIRST call. cdkd builds a
|
|
4142
|
+
* provider registry per stack inside that stack's scope, so this is the stack's
|
|
4143
|
+
* identity; a library caller that reuses one registry across `setAwsClients`
|
|
4144
|
+
* switches keeps the first identity's clients.
|
|
4145
|
+
*
|
|
4146
|
+
* SPREAD IT FIRST, exactly where `awsClientDefaults()` was spread:
|
|
4147
|
+
*
|
|
4148
|
+
* `new GlueClient({ ...ambientClientDefaults(), ...(region && { region }) })`
|
|
4149
|
+
*
|
|
4150
|
+
* The site's own keys still win, so a site that names its own `region` or its
|
|
4151
|
+
* own `credentials` keeps them. `scripts/check-aws-client-defaults.ts` accepts
|
|
4152
|
+
* this helper as the defaults spread (it calls `awsClientDefaults` afresh per
|
|
4153
|
+
* call, so each client still gets its own routing agent), and
|
|
4154
|
+
* `tests/unit/utils/ambient-client-defaults-fence.test.ts` refuses a new
|
|
4155
|
+
* `awsClientDefaults()`-only construction under `src/**`.
|
|
4156
|
+
*
|
|
4157
|
+
* Its own module rather than a member of `aws-clients.ts` so that a test which
|
|
4158
|
+
* `vi.mock`s `aws-clients.js` with a `getAwsClients` double still reaches this
|
|
4159
|
+
* code and degrades, instead of losing the export. It is deliberately OUTSIDE
|
|
4160
|
+
* the literal-`.ts` closure `scripts/audit-provider-coverage.ts` resolves
|
|
4161
|
+
* (nothing in that closure imports it), and neither module it imports imports
|
|
4162
|
+
* it back, so there is no cycle.
|
|
4163
|
+
*/
|
|
4164
|
+
/**
|
|
4165
|
+
* The ACTIVE clients' credential configuration: the stack scope's
|
|
4166
|
+
* `AwsClients` inside `runWithStackAwsClients`, else the process-global one.
|
|
4167
|
+
*
|
|
4168
|
+
* `{}` when those clients carry none (every CLI run passes no explicit
|
|
4169
|
+
* `credentials`, and `--profile` alone yields `{ profile }`), and also for a
|
|
4170
|
+
* test double that has no `credentialConfig` getter — degrading to the plain
|
|
4171
|
+
* `awsClientDefaults()` answer rather than throwing.
|
|
4172
|
+
*
|
|
4173
|
+
* Read through `getAwsClients()`, which creates an unconfigured global on first
|
|
4174
|
+
* use when nothing installed one. That is side-effect free here: its service
|
|
4175
|
+
* clients are lazy, no production call passes `getAwsClients(config)` (so no
|
|
4176
|
+
* later configuration is shadowed), and `setAwsClients` replaces it.
|
|
4177
|
+
*/
|
|
4178
|
+
function ambientCredentialConfig() {
|
|
4179
|
+
return getAwsClients()?.credentialConfig ?? {};
|
|
4180
|
+
}
|
|
4181
|
+
/**
|
|
4182
|
+
* `awsClientDefaults(...)` plus `credentialConfig`, in `AwsClients.clientOptions`'
|
|
4183
|
+
* spread order: the defaults FIRST, so an explicit `credentials` outranks a
|
|
4184
|
+
* published `--role-arn` role, then `profile`, then `credentials`.
|
|
4185
|
+
*
|
|
4186
|
+
* Takes the configuration as an argument for the callers that must key a cache
|
|
4187
|
+
* on the SAME reading they build from ({@link credentialFingerprint}); every
|
|
4188
|
+
* other site calls {@link ambientClientDefaults}.
|
|
4189
|
+
*/
|
|
4190
|
+
function clientDefaultsFor(credentialConfig) {
|
|
4191
|
+
return {
|
|
4192
|
+
...awsClientDefaults({ profile: credentialConfig.profile }),
|
|
4193
|
+
...credentialConfig.profile && { profile: credentialConfig.profile },
|
|
4194
|
+
...credentialConfig.credentials && { credentials: { ...credentialConfig.credentials } }
|
|
4195
|
+
};
|
|
4196
|
+
}
|
|
4197
|
+
/**
|
|
4198
|
+
* The config every SDK client built outside `AwsClients` spreads first: the
|
|
4199
|
+
* proxy / role / scope-region defaults plus the ACTIVE clients' profile and
|
|
4200
|
+
* explicit credentials.
|
|
4201
|
+
*/
|
|
4202
|
+
function ambientClientDefaults() {
|
|
4203
|
+
return clientDefaultsFor(ambientCredentialConfig());
|
|
4204
|
+
}
|
|
4205
|
+
/**
|
|
4206
|
+
* A cache-key component naming WHICH identity a credential configuration
|
|
4207
|
+
* selects, for a cache that holds a client (or credentials) built from it.
|
|
4208
|
+
*
|
|
4209
|
+
* `profile` plus the explicit credentials' ACCESS KEY ID — never the secret
|
|
4210
|
+
* key or the session token. The access key id is an identifier rather than a
|
|
4211
|
+
* secret (`expected-bucket-owner.ts` already keys its account cache on it), and
|
|
4212
|
+
* STS issues a distinct one per session, so two different explicit bags are
|
|
4213
|
+
* told apart. The one collision is two bags sharing an access key id with
|
|
4214
|
+
* different secrets, at most one of which can be valid.
|
|
4215
|
+
*
|
|
4216
|
+
* What it does NOT carry, because it is PROCESS-WIDE rather than per
|
|
4217
|
+
* configuration: a published `--role-arn` role (set once, refused a second
|
|
4218
|
+
* time), the proxy, and `AWS_PROFILE` / the environment chain. Two readings
|
|
4219
|
+
* with equal fingerprints within one process therefore resolve to the same
|
|
4220
|
+
* identity. Do not log it.
|
|
4221
|
+
*/
|
|
4222
|
+
function credentialFingerprint(credentialConfig) {
|
|
4223
|
+
return JSON.stringify([credentialConfig.profile ?? null, credentialConfig.credentials?.accessKeyId ?? null]);
|
|
4224
|
+
}
|
|
4225
|
+
|
|
4123
4226
|
//#endregion
|
|
4124
4227
|
//#region src/synthesis/context-providers/az-provider.ts
|
|
4125
4228
|
/**
|
|
@@ -4138,7 +4241,7 @@ var AZContextProvider = class {
|
|
|
4138
4241
|
const region = props["region"] || this.awsConfig?.region;
|
|
4139
4242
|
this.logger.debug(`Fetching availability zones for region: ${region}`);
|
|
4140
4243
|
const client = new EC2Client({
|
|
4141
|
-
...
|
|
4244
|
+
...ambientClientDefaults(),
|
|
4142
4245
|
...region && { region }
|
|
4143
4246
|
});
|
|
4144
4247
|
try {
|
|
@@ -4171,7 +4274,7 @@ var SSMContextProvider = class {
|
|
|
4171
4274
|
if (!parameterName) throw new Error("SSM context provider requires parameterName property");
|
|
4172
4275
|
this.logger.debug(`Reading SSM parameter: ${parameterName} (region: ${region})`);
|
|
4173
4276
|
const client = new SSMClient({
|
|
4174
|
-
...
|
|
4277
|
+
...ambientClientDefaults(),
|
|
4175
4278
|
...region && { region }
|
|
4176
4279
|
});
|
|
4177
4280
|
try {
|
|
@@ -4213,7 +4316,7 @@ var HostedZoneContextProvider = class {
|
|
|
4213
4316
|
if (!domainName) throw new Error("Hosted zone context provider requires domainName property");
|
|
4214
4317
|
this.logger.debug(`Looking up hosted zone: ${domainName} (private: ${privateZone})`);
|
|
4215
4318
|
const client = new Route53Client({
|
|
4216
|
-
...
|
|
4319
|
+
...ambientClientDefaults(),
|
|
4217
4320
|
...region && { region }
|
|
4218
4321
|
});
|
|
4219
4322
|
try {
|
|
@@ -4267,7 +4370,7 @@ var VpcContextProvider = class {
|
|
|
4267
4370
|
const returnVpnGateways = props["returnVpnGateways"];
|
|
4268
4371
|
this.logger.debug(`Looking up VPC (region: ${region}, filter: ${JSON.stringify(filter)})`);
|
|
4269
4372
|
const client = new EC2Client({
|
|
4270
|
-
...
|
|
4373
|
+
...ambientClientDefaults(),
|
|
4271
4374
|
...region && { region }
|
|
4272
4375
|
});
|
|
4273
4376
|
try {
|
|
@@ -4433,7 +4536,7 @@ var CcApiContextProvider = class {
|
|
|
4433
4536
|
if (!typeName) throw new Error("CC API context provider requires typeName property");
|
|
4434
4537
|
this.logger.debug(`CC API lookup: ${typeName}${exactIdentifier ? ` (id: ${exactIdentifier})` : ""} (region: ${region})`);
|
|
4435
4538
|
const client = new CloudControlClient({
|
|
4436
|
-
...
|
|
4539
|
+
...ambientClientDefaults(),
|
|
4437
4540
|
...region && { region }
|
|
4438
4541
|
});
|
|
4439
4542
|
try {
|
|
@@ -4560,7 +4663,7 @@ var AmiContextProvider = class {
|
|
|
4560
4663
|
const filters = props["filters"];
|
|
4561
4664
|
this.logger.debug(`Looking up AMI (region: ${region})`);
|
|
4562
4665
|
const client = new EC2Client({
|
|
4563
|
-
...
|
|
4666
|
+
...ambientClientDefaults(),
|
|
4564
4667
|
...region && { region }
|
|
4565
4668
|
});
|
|
4566
4669
|
try {
|
|
@@ -4603,7 +4706,7 @@ var SecurityGroupContextProvider = class {
|
|
|
4603
4706
|
const vpcId = props["vpcId"];
|
|
4604
4707
|
this.logger.debug(`Looking up security group (id: ${securityGroupId}, name: ${securityGroupName}, region: ${region})`);
|
|
4605
4708
|
const client = new EC2Client({
|
|
4606
|
-
...
|
|
4709
|
+
...ambientClientDefaults(),
|
|
4607
4710
|
...region && { region }
|
|
4608
4711
|
});
|
|
4609
4712
|
try {
|
|
@@ -4657,7 +4760,7 @@ var LoadBalancerContextProvider = class {
|
|
|
4657
4760
|
const loadBalancerType = props["loadBalancerType"];
|
|
4658
4761
|
this.logger.debug(`Looking up load balancer (arn: ${loadBalancerArn}, region: ${region})`);
|
|
4659
4762
|
const client = new ElasticLoadBalancingV2Client({
|
|
4660
|
-
...
|
|
4763
|
+
...ambientClientDefaults(),
|
|
4661
4764
|
...region && { region }
|
|
4662
4765
|
});
|
|
4663
4766
|
try {
|
|
@@ -4699,7 +4802,7 @@ var LoadBalancerListenerContextProvider = class {
|
|
|
4699
4802
|
const listenerProtocol = props["listenerProtocol"];
|
|
4700
4803
|
this.logger.debug(`Looking up load balancer listener (arn: ${listenerArn}, lb: ${loadBalancerArn}, region: ${region})`);
|
|
4701
4804
|
const client = new ElasticLoadBalancingV2Client({
|
|
4702
|
-
...
|
|
4805
|
+
...ambientClientDefaults(),
|
|
4703
4806
|
...region && { region }
|
|
4704
4807
|
});
|
|
4705
4808
|
try {
|
|
@@ -4743,7 +4846,7 @@ var KeyContextProvider = class {
|
|
|
4743
4846
|
if (!aliasName) throw new Error("Key context provider requires aliasName property");
|
|
4744
4847
|
this.logger.debug(`Looking up KMS key by alias: ${aliasName} (region: ${region})`);
|
|
4745
4848
|
const client = new KMSClient({
|
|
4746
|
-
...
|
|
4849
|
+
...ambientClientDefaults(),
|
|
4747
4850
|
...region && { region }
|
|
4748
4851
|
});
|
|
4749
4852
|
try {
|
|
@@ -6647,7 +6750,7 @@ async function expandMacrosAttempt(template, opts, logger) {
|
|
|
6647
6750
|
const parameters = buildParameterValues(template, logger);
|
|
6648
6751
|
ownsClient = opts.cfnClient === void 0;
|
|
6649
6752
|
cfn = opts.cfnClient ?? new CloudFormationClient({
|
|
6650
|
-
...
|
|
6753
|
+
...ambientClientDefaults(),
|
|
6651
6754
|
region
|
|
6652
6755
|
});
|
|
6653
6756
|
let templateInput;
|
|
@@ -7778,7 +7881,7 @@ var FileAssetPublisher = class {
|
|
|
7778
7881
|
const destRegion = dest.region ? this.resolvePlaceholders(dest.region, accountId, region) : region;
|
|
7779
7882
|
this.logger.debug(`Publishing file asset ${asset.displayName || assetHash} → s3://${bucketName}/${objectKey}`);
|
|
7780
7883
|
const client = new S3Client({
|
|
7781
|
-
...
|
|
7884
|
+
...ambientClientDefaults(),
|
|
7782
7885
|
region: destRegion
|
|
7783
7886
|
});
|
|
7784
7887
|
try {
|
|
@@ -9694,20 +9797,31 @@ function buildDockerBuildCommand(source, tag, platformOverride) {
|
|
|
9694
9797
|
function ecrUrlSuffix(region) {
|
|
9695
9798
|
return derivePartitionAndUrlSuffix(region).urlSuffix;
|
|
9696
9799
|
}
|
|
9800
|
+
/** An AWS account id: exactly twelve digits. */
|
|
9801
|
+
const ACCOUNT_ID = /^\d{12}$/;
|
|
9697
9802
|
/**
|
|
9698
|
-
*
|
|
9699
|
-
*
|
|
9700
|
-
*
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
*
|
|
9803
|
+
* The DNS-label charset a region id is drawn from (a trailing hyphen is not
|
|
9804
|
+
* refused; the host stays under the AWS-owned suffix either way).
|
|
9805
|
+
* `src/utils/ecr-uri.ts` holds the same class for the pull side.
|
|
9806
|
+
*/
|
|
9807
|
+
const REGION_LABEL = /^[A-Za-z0-9][A-Za-z0-9-]*$/;
|
|
9808
|
+
/**
|
|
9809
|
+
* The ECR registry host an asset is pushed to. The push URI AND the
|
|
9810
|
+
* `docker login` endpoint are both built from this one value, so the login
|
|
9811
|
+
* always targets the host the push uses (issue #3681).
|
|
9705
9812
|
*
|
|
9706
|
-
*
|
|
9707
|
-
*
|
|
9708
|
-
*
|
|
9813
|
+
* The region comes from the asset manifest, and the ECR password is sent to
|
|
9814
|
+
* this host, so both halves are charset-gated HERE: a region like
|
|
9815
|
+
* `x.example.com/` would otherwise name a host AWS does not own. The suffix is
|
|
9816
|
+
* the AWS-owned one `derivePartitionAndUrlSuffix` returns. A known-region
|
|
9817
|
+
* check is deliberately absent, so a region cdkd has not heard of yet still
|
|
9818
|
+
* publishes.
|
|
9709
9819
|
*/
|
|
9710
|
-
|
|
9820
|
+
function ecrRegistryHost(accountId, region) {
|
|
9821
|
+
if (typeof accountId !== "string" || !ACCOUNT_ID.test(accountId)) throw new AssetError(`Refusing to publish a Docker image asset: ${displayIdent(accountId)} is not a 12-digit AWS account id`);
|
|
9822
|
+
if (typeof region !== "string" || region.length > 63 || !REGION_LABEL.test(region)) throw new AssetError(`Refusing to publish a Docker image asset: the destination region ${displayIdent(region)} is not a valid AWS region id`);
|
|
9823
|
+
return `${accountId}.dkr.ecr.${region}.${ecrUrlSuffix(region)}`;
|
|
9824
|
+
}
|
|
9711
9825
|
/**
|
|
9712
9826
|
* Whether a `docker push` failure looks like an ECR authentication failure
|
|
9713
9827
|
* (missing / stale / expired credential) rather than a network / repo / other
|
|
@@ -9737,10 +9851,11 @@ var DockerAssetPublisher = class {
|
|
|
9737
9851
|
const repositoryName = this.resolvePlaceholders(dest.repositoryName, accountId, region);
|
|
9738
9852
|
const imageTag = this.resolvePlaceholders(dest.imageTag, accountId, region);
|
|
9739
9853
|
const destRegion = dest.region ? this.resolvePlaceholders(dest.region, accountId, region) : region;
|
|
9740
|
-
const
|
|
9854
|
+
const registryHost = ecrRegistryHost(accountId, destRegion);
|
|
9855
|
+
const ecrUri = `${registryHost}/${repositoryName}:${imageTag}`;
|
|
9741
9856
|
this.logger.debug(`Publishing Docker image ${asset.displayName || assetHash} → ${ecrUri}`);
|
|
9742
9857
|
const client = new ECRClient({
|
|
9743
|
-
...
|
|
9858
|
+
...ambientClientDefaults(),
|
|
9744
9859
|
region: destRegion
|
|
9745
9860
|
});
|
|
9746
9861
|
try {
|
|
@@ -9750,7 +9865,7 @@ var DockerAssetPublisher = class {
|
|
|
9750
9865
|
}
|
|
9751
9866
|
const localTag = `cdkd-asset-${assetHash}`;
|
|
9752
9867
|
await this.buildImage(asset, cdkOutputDir, localTag, cdkOutputDir);
|
|
9753
|
-
await this.tagAndPushWithLazyLogin(client, localTag, ecrUri,
|
|
9868
|
+
await this.tagAndPushWithLazyLogin(client, localTag, ecrUri, registryHost);
|
|
9754
9869
|
this.logger.debug(`✅ Published: ${ecrUri}`);
|
|
9755
9870
|
} finally {
|
|
9756
9871
|
client.destroy();
|
|
@@ -9777,9 +9892,10 @@ var DockerAssetPublisher = class {
|
|
|
9777
9892
|
const repositoryName = this.resolvePlaceholders(dest.repositoryName, accountId, region);
|
|
9778
9893
|
const imageTag = this.resolvePlaceholders(dest.imageTag, accountId, region);
|
|
9779
9894
|
const destRegion = dest.region ? this.resolvePlaceholders(dest.region, accountId, region) : region;
|
|
9780
|
-
const
|
|
9895
|
+
const registryHost = ecrRegistryHost(accountId, destRegion);
|
|
9896
|
+
const ecrUri = `${registryHost}/${repositoryName}:${imageTag}`;
|
|
9781
9897
|
const client = new ECRClient({
|
|
9782
|
-
...
|
|
9898
|
+
...ambientClientDefaults(),
|
|
9783
9899
|
region: destRegion
|
|
9784
9900
|
});
|
|
9785
9901
|
try {
|
|
@@ -9787,7 +9903,7 @@ var DockerAssetPublisher = class {
|
|
|
9787
9903
|
this.logger.debug(`Image already exists, skipping: ${ecrUri}`);
|
|
9788
9904
|
continue;
|
|
9789
9905
|
}
|
|
9790
|
-
await this.tagAndPushWithLazyLogin(client, localTag, ecrUri,
|
|
9906
|
+
await this.tagAndPushWithLazyLogin(client, localTag, ecrUri, registryHost);
|
|
9791
9907
|
this.logger.debug(`✅ Published: ${ecrUri}`);
|
|
9792
9908
|
} finally {
|
|
9793
9909
|
client.destroy();
|
|
@@ -9854,18 +9970,17 @@ var DockerAssetPublisher = class {
|
|
|
9854
9970
|
* round-trip (~3.3s saved). We attempt the push FIRST and only pay the login
|
|
9855
9971
|
* when it is actually needed:
|
|
9856
9972
|
*
|
|
9857
|
-
* 1.
|
|
9858
|
-
*
|
|
9859
|
-
*
|
|
9860
|
-
* 2.
|
|
9861
|
-
*
|
|
9862
|
-
*
|
|
9863
|
-
* login and retry the push ONCE.
|
|
9973
|
+
* 1. Push optimistically. A login earlier in this process (or session)
|
|
9974
|
+
* left a credential in docker's store, so a repeat push to the same
|
|
9975
|
+
* registry needs no new login — docker's store is the only login cache.
|
|
9976
|
+
* 2. On a NON-auth failure (network, repo-not-found, etc.) surface the
|
|
9977
|
+
* error unchanged. On an auth failure (no pre-existing cred, OR a
|
|
9978
|
+
* stale/expired cred), log in to ECR and retry the push ONCE.
|
|
9864
9979
|
*
|
|
9865
9980
|
* A stale cred and a missing cred take the SAME branch, so cdkd never
|
|
9866
9981
|
* fail-hard on an expired credential — it re-logs in and retries.
|
|
9867
9982
|
*/
|
|
9868
|
-
async tagAndPushWithLazyLogin(client, localTag, fullUri,
|
|
9983
|
+
async tagAndPushWithLazyLogin(client, localTag, fullUri, registryHost) {
|
|
9869
9984
|
await this.tagImage(localTag, fullUri);
|
|
9870
9985
|
try {
|
|
9871
9986
|
await this.pushImage(fullUri);
|
|
@@ -9875,34 +9990,23 @@ var DockerAssetPublisher = class {
|
|
|
9875
9990
|
if (!isDockerAuthFailure(e.stderr || e.message || String(err))) throw err;
|
|
9876
9991
|
this.logger.debug(`Docker push to ${fullUri} failed with an auth error; logging in to ECR and retrying`);
|
|
9877
9992
|
}
|
|
9878
|
-
await this.ecrLogin(client,
|
|
9993
|
+
await this.ecrLogin(client, registryHost);
|
|
9879
9994
|
await this.pushImage(fullUri);
|
|
9880
9995
|
}
|
|
9881
9996
|
/**
|
|
9882
|
-
* Authenticate with ECR via `docker login --password-stdin
|
|
9997
|
+
* Authenticate with ECR via `docker login --password-stdin`, against
|
|
9998
|
+
* `registryHost` — the host the push targets (`ecrRegistryHost`).
|
|
9883
9999
|
*
|
|
9884
|
-
*
|
|
9885
|
-
*
|
|
9886
|
-
*
|
|
9887
|
-
* (mirrors `cdk-assets`). ECR tokens are valid ~12h and a deploy process is
|
|
9888
|
-
* short-lived, so this is safe. Keyed per registry so cross-account /
|
|
9889
|
-
* cross-region assets each get their own login.
|
|
9890
|
-
*
|
|
9891
|
-
* `force: true` bypasses the per-process cache short-circuit — used by the
|
|
9892
|
-
* lazy-login retry after a push fails auth, where the cached entry may hold a
|
|
9893
|
-
* token that AWS has already expired.
|
|
10000
|
+
* Called only after a push failed auth, so it always logs in: a repeat push
|
|
10001
|
+
* to a registry already logged in to succeeds on the credential docker
|
|
10002
|
+
* stored and never reaches here (#1193).
|
|
9894
10003
|
*/
|
|
9895
|
-
async ecrLogin(client,
|
|
9896
|
-
const registryKey = `${accountId}.dkr.ecr.${region}.${ecrUrlSuffix(region)}`;
|
|
9897
|
-
if (!options.force && loggedInRegistries.has(registryKey)) {
|
|
9898
|
-
this.logger.debug(`Reusing cached ECR login for ${registryKey}`);
|
|
9899
|
-
return;
|
|
9900
|
-
}
|
|
10004
|
+
async ecrLogin(client, registryHost) {
|
|
9901
10005
|
const authData = (await client.send(new GetAuthorizationTokenCommand({}))).authorizationData?.[0];
|
|
9902
10006
|
if (!authData?.authorizationToken) throw new AssetError("Failed to get ECR authorization token");
|
|
9903
10007
|
const [username, password] = Buffer.from(authData.authorizationToken, "base64").toString().split(":");
|
|
9904
10008
|
if (!username || password === void 0) throw new AssetError("ECR authorization token has unexpected shape (missing username/password)");
|
|
9905
|
-
const endpoint =
|
|
10009
|
+
const endpoint = `https://${registryHost}`;
|
|
9906
10010
|
const loginArgs = [
|
|
9907
10011
|
"login",
|
|
9908
10012
|
"--username",
|
|
@@ -9912,7 +10016,6 @@ var DockerAssetPublisher = class {
|
|
|
9912
10016
|
];
|
|
9913
10017
|
try {
|
|
9914
10018
|
await runDockerStreaming(loginArgs, { input: password });
|
|
9915
|
-
loggedInRegistries.add(registryKey);
|
|
9916
10019
|
} catch (err) {
|
|
9917
10020
|
throw new AssetError(`ECR login failed: ${formatDockerLoginError(describeDockerFailure(err, loginArgs), endpoint)}`, redactedDockerCause(err, loginArgs));
|
|
9918
10021
|
}
|
|
@@ -11322,7 +11425,7 @@ var AssetPublisher = class {
|
|
|
11322
11425
|
if (!accountId) {
|
|
11323
11426
|
const { STSClient, GetCallerIdentityCommand } = await import("@aws-sdk/client-sts");
|
|
11324
11427
|
const stsClient = new STSClient({
|
|
11325
|
-
...
|
|
11428
|
+
...ambientClientDefaults(),
|
|
11326
11429
|
region
|
|
11327
11430
|
});
|
|
11328
11431
|
accountId = (await stsClient.send(new GetCallerIdentityCommand({}))).Account;
|
|
@@ -26557,7 +26660,8 @@ function applyCallerIdentityCredentials(env) {
|
|
|
26557
26660
|
//#endregion
|
|
26558
26661
|
//#region src/utils/role-arn.ts
|
|
26559
26662
|
/**
|
|
26560
|
-
* Process-lifetime cache of assumed credentials keyed by RoleArn
|
|
26663
|
+
* Process-lifetime cache of assumed credentials keyed by RoleArn AND the
|
|
26664
|
+
* SOURCE identity the `sts:AssumeRole` hop runs as.
|
|
26561
26665
|
*
|
|
26562
26666
|
* Storing the in-flight `Promise` (rather than the resolved value) collapses
|
|
26563
26667
|
* concurrent first-time callers into a single `sts:AssumeRole` request. After
|
|
@@ -26565,10 +26669,19 @@ function applyCallerIdentityCredentials(env) {
|
|
|
26565
26669
|
* stack that references the same producer N times via `Fn::GetStackOutput`
|
|
26566
26670
|
* only pays the STS hop once.
|
|
26567
26671
|
*
|
|
26568
|
-
*
|
|
26569
|
-
* credentials
|
|
26570
|
-
*
|
|
26571
|
-
*
|
|
26672
|
+
* Not keyed by region, because STS credentials are global — assumed
|
|
26673
|
+
* credentials work against any region's service endpoint. The downstream S3
|
|
26674
|
+
* client built from these credentials picks its own region via
|
|
26675
|
+
* `GetBucketLocation`.
|
|
26676
|
+
*
|
|
26677
|
+
* KEYED BY THE SOURCE IDENTITY TOO (issue
|
|
26678
|
+
* [#3588](https://github.com/go-to-k/cdkd/issues/3588)): the hop runs as the
|
|
26679
|
+
* ACTIVE `AwsClients`' credential configuration, and a library caller can
|
|
26680
|
+
* install (`setAwsClients`) two different explicit credentials in one process,
|
|
26681
|
+
* as can cdkd's own per-stack scopes. Keyed by RoleArn alone, the second would be handed
|
|
26682
|
+
* credentials the FIRST identity obtained — a role the second one may not even
|
|
26683
|
+
* be trusted to assume. The source half is `credentialFingerprint`'s (profile +
|
|
26684
|
+
* access key id, never secret material).
|
|
26572
26685
|
*
|
|
26573
26686
|
* **Expiration handling**: on every cache hit, the cached credentials'
|
|
26574
26687
|
* `expiration` is compared against `Date.now()` with a 60-second safety
|
|
@@ -26628,7 +26741,7 @@ function parseIamRoleArn(roleArn) {
|
|
|
26628
26741
|
* the consumer account's normal credentials). Threading the credentials
|
|
26629
26742
|
* through a fresh `S3Client` via this helper keeps the scope narrow.
|
|
26630
26743
|
*
|
|
26631
|
-
* **Why cache per
|
|
26744
|
+
* **Why cache per RoleArn (and source identity) for the process lifetime.** A multi-resource
|
|
26632
26745
|
* stack typically references `Fn::GetStackOutput` from many template sites
|
|
26633
26746
|
* (every IAM policy / Lambda env / ALB listener that pulls a shared VPC ID
|
|
26634
26747
|
* from a platform stack). Assuming the role once per deploy is sufficient;
|
|
@@ -26651,17 +26764,19 @@ function parseIamRoleArn(roleArn) {
|
|
|
26651
26764
|
* uniformly), but the next caller after rejection gets a clean slate.
|
|
26652
26765
|
*/
|
|
26653
26766
|
async function assumeRoleForCrossAccountStateRead(roleArn) {
|
|
26654
|
-
const
|
|
26767
|
+
const sourceConfig = ambientCredentialConfig();
|
|
26768
|
+
const cacheKey = JSON.stringify([credentialFingerprint(sourceConfig), roleArn]);
|
|
26769
|
+
const cached = crossAccountCredentialsCache.get(cacheKey);
|
|
26655
26770
|
if (cached) {
|
|
26656
26771
|
const cachedCreds = await cached;
|
|
26657
26772
|
if (!cachedCreds.expiration || Date.now() < cachedCreds.expiration.getTime() - CRED_EXPIRY_SAFETY_MS) return cachedCreds;
|
|
26658
|
-
crossAccountCredentialsCache.delete(
|
|
26773
|
+
crossAccountCredentialsCache.delete(cacheKey);
|
|
26659
26774
|
}
|
|
26660
26775
|
const promise = (async () => {
|
|
26661
26776
|
const logger = getLogger().child("role-arn");
|
|
26662
26777
|
const displayRoleArn = displayIdent(roleArn, { maxCodePoints: 613 });
|
|
26663
26778
|
logger.debug(`Assuming role for cross-account state read: ${displayRoleArn}`);
|
|
26664
|
-
const sts = new STSClient({ ...
|
|
26779
|
+
const sts = new STSClient({ ...clientDefaultsFor(sourceConfig) });
|
|
26665
26780
|
try {
|
|
26666
26781
|
let response;
|
|
26667
26782
|
try {
|
|
@@ -26688,10 +26803,10 @@ async function assumeRoleForCrossAccountStateRead(roleArn) {
|
|
|
26688
26803
|
sts.destroy();
|
|
26689
26804
|
}
|
|
26690
26805
|
})().catch((err) => {
|
|
26691
|
-
if (crossAccountCredentialsCache.get(
|
|
26806
|
+
if (crossAccountCredentialsCache.get(cacheKey) === promise) crossAccountCredentialsCache.delete(cacheKey);
|
|
26692
26807
|
throw err;
|
|
26693
26808
|
});
|
|
26694
|
-
crossAccountCredentialsCache.set(
|
|
26809
|
+
crossAccountCredentialsCache.set(cacheKey, promise);
|
|
26695
26810
|
return promise;
|
|
26696
26811
|
}
|
|
26697
26812
|
/**
|
|
@@ -27485,6 +27600,88 @@ function mergeHealedAttributes(recorded, healed, isStaleValue) {
|
|
|
27485
27600
|
return merged ?? recorded;
|
|
27486
27601
|
}
|
|
27487
27602
|
|
|
27603
|
+
//#endregion
|
|
27604
|
+
//#region src/provisioning/attribute-map.ts
|
|
27605
|
+
/**
|
|
27606
|
+
* The ONE spelling of the attribute-map rule an SDK provider's `create()` /
|
|
27607
|
+
* `update()` / `import()` result follows (issue #3077, closing the `?? ''`
|
|
27608
|
+
* shape `docs/provider-development.md` forbids under "Never store an
|
|
27609
|
+
* empty-string placeholder"):
|
|
27610
|
+
*
|
|
27611
|
+
* an attribute cdkd could not read back is ABSENT from the map — never
|
|
27612
|
+
* recorded as the empty string, and never as a present-but-`undefined` key.
|
|
27613
|
+
*
|
|
27614
|
+
* The consumers of `ResourceState.attributes` all key off exactly that
|
|
27615
|
+
* distinction, and a sentinel puts every one of them on the wrong branch:
|
|
27616
|
+
*
|
|
27617
|
+
* - the deploy engine persists the map as-is, so `''` becomes the recorded
|
|
27618
|
+
* value of a field AWS never assigned;
|
|
27619
|
+
* - the intrinsic resolver serves a stored attribute whenever it is not
|
|
27620
|
+
* `undefined`, so `''` shadows `constructAttribute` forever — the
|
|
27621
|
+
* `AWS::EC2::Instance` IP / DNS / AZ arm re-describes the instance from
|
|
27622
|
+
* AWS only on a MISS, the `Arn` arms of the RDS family rebuild the ARN
|
|
27623
|
+
* only on a MISS;
|
|
27624
|
+
* - the Outputs export pass publishes whatever the resolver returned, so a
|
|
27625
|
+
* stored `''` is exported to every `Fn::ImportValue` consumer.
|
|
27626
|
+
*
|
|
27627
|
+
* It exists as a MODULE rather than a per-provider idiom because the rule was
|
|
27628
|
+
* prose and 96 attribute-position `?? ''` / `|| ''` / bare `''` sites across
|
|
27629
|
+
* 18 providers shipped anyway (measured 2026-09-14 with the TypeScript-compiler
|
|
27630
|
+
* walk that is now `tests/unit/provisioning/attribute-map.test.ts`). A helper
|
|
27631
|
+
* that DROPS the key is the one form a provider cannot spell wrong by habit.
|
|
27632
|
+
*
|
|
27633
|
+
* Two values are treated as "not read back":
|
|
27634
|
+
*
|
|
27635
|
+
* - `undefined`: the SDK's spelling of an unassigned optional member.
|
|
27636
|
+
* - `null`: no AWS SDK v3 read-back reports a scalar attribute as `null`, and
|
|
27637
|
+
* a stored `null` takes the resolver's "not `undefined`" hit branch exactly
|
|
27638
|
+
* like `''` does.
|
|
27639
|
+
*
|
|
27640
|
+
* Every other value is kept verbatim — INCLUDING an empty string AWS itself
|
|
27641
|
+
* reported (`false`, `0`, an empty array and an object likewise). The helper
|
|
27642
|
+
* stops cdkd MANUFACTURING `''` for a field it never read; a `''` that came
|
|
27643
|
+
* off the wire is a known value with a meaning the provider owns. The EC2
|
|
27644
|
+
* Instance provider is where that distinction is load-bearing: a `running`
|
|
27645
|
+
* instance with no public address is described with `PublicDnsName: ''` and
|
|
27646
|
+
* no `PublicIpAddress`, and CloudFormation answers `''` for both — a KNOWN
|
|
27647
|
+
* empty, recorded as such so a reference does not degrade to the instance id
|
|
27648
|
+
* on every resolution — while the same `''` on a `pending` instance means
|
|
27649
|
+
* "not yet", which that provider maps to `undefined` BEFORE calling this
|
|
27650
|
+
* helper (its `describedInstanceAttributes`). A caller that knows a `''`
|
|
27651
|
+
* means "unknown" is the one that must say so; this helper cannot tell.
|
|
27652
|
+
*
|
|
27653
|
+
* Deliberately NOT a general "compact this record" utility: it is scoped to
|
|
27654
|
+
* attribute maps. A property bag keeps its `undefined`-valued keys out by other
|
|
27655
|
+
* means (`.claude/rules/provider-property-fidelity.md`, "Remove the key rather
|
|
27656
|
+
* than setting it to `undefined`").
|
|
27657
|
+
*
|
|
27658
|
+
* A LEAF module (imports nothing) so every provider can take it without adding
|
|
27659
|
+
* an edge to the provider import ring.
|
|
27660
|
+
*/
|
|
27661
|
+
/**
|
|
27662
|
+
* Build an attribute map from read-back values, omitting every key whose value
|
|
27663
|
+
* is `undefined` or `null`.
|
|
27664
|
+
*/
|
|
27665
|
+
function definedAttributes(entries) {
|
|
27666
|
+
const out = {};
|
|
27667
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
27668
|
+
if (value === void 0 || value === null) continue;
|
|
27669
|
+
out[key] = value;
|
|
27670
|
+
}
|
|
27671
|
+
return out;
|
|
27672
|
+
}
|
|
27673
|
+
/**
|
|
27674
|
+
* `String(value)` for a numeric read-back whose CloudFormation attribute is a
|
|
27675
|
+
* string (`Endpoint.Port`), or `undefined` when the field is unassigned — so
|
|
27676
|
+
* `definedAttributes` drops the key instead of recording the literal
|
|
27677
|
+
* `'undefined'`, which is what `String(described?.Port ?? '')` yields once its
|
|
27678
|
+
* `?? ''` is merely deleted.
|
|
27679
|
+
*/
|
|
27680
|
+
function stringifyIfAssigned(value) {
|
|
27681
|
+
if (value === void 0 || value === null) return void 0;
|
|
27682
|
+
return String(value);
|
|
27683
|
+
}
|
|
27684
|
+
|
|
27488
27685
|
//#endregion
|
|
27489
27686
|
//#region src/provisioning/config-shape.ts
|
|
27490
27687
|
/**
|
|
@@ -28588,7 +28785,7 @@ var WAFv2WebACLProvider = class {
|
|
|
28588
28785
|
])]]);
|
|
28589
28786
|
getClient() {
|
|
28590
28787
|
if (!this.wafv2Client) this.wafv2Client = new WAFV2Client({
|
|
28591
|
-
...
|
|
28788
|
+
...ambientClientDefaults(),
|
|
28592
28789
|
...this.providerRegion ? { region: this.providerRegion } : {}
|
|
28593
28790
|
});
|
|
28594
28791
|
return this.wafv2Client;
|
|
@@ -28626,13 +28823,23 @@ var WAFv2WebACLProvider = class {
|
|
|
28626
28823
|
}))).Summary;
|
|
28627
28824
|
if (!summary?.ARN || !summary?.Id) throw new Error("CreateWebACL did not return Summary with ARN and Id");
|
|
28628
28825
|
this.logger.debug(`Successfully created WAFv2 WebACL ${logicalId}: ${summary.ARN}`);
|
|
28826
|
+
let labelNamespace;
|
|
28827
|
+
try {
|
|
28828
|
+
labelNamespace = (await this.getClient().send(new GetWebACLCommand({
|
|
28829
|
+
Id: summary.Id,
|
|
28830
|
+
Name: name,
|
|
28831
|
+
Scope: scope
|
|
28832
|
+
}))).WebACL?.LabelNamespace;
|
|
28833
|
+
} catch (readError) {
|
|
28834
|
+
this.logger.debug(`Could not read the label namespace of ${logicalId} after create: ${describeAwsFailure(readError).detail}`);
|
|
28835
|
+
}
|
|
28629
28836
|
return {
|
|
28630
28837
|
physicalId: summary.ARN,
|
|
28631
|
-
attributes: {
|
|
28838
|
+
attributes: definedAttributes({
|
|
28632
28839
|
Arn: summary.ARN,
|
|
28633
28840
|
Id: summary.Id,
|
|
28634
|
-
LabelNamespace:
|
|
28635
|
-
}
|
|
28841
|
+
LabelNamespace: labelNamespace
|
|
28842
|
+
})
|
|
28636
28843
|
};
|
|
28637
28844
|
} catch (error) {
|
|
28638
28845
|
if (error instanceof ProvisioningError) throw error;
|
|
@@ -28830,19 +29037,33 @@ var WAFv2WebACLProvider = class {
|
|
|
28830
29037
|
*
|
|
28831
29038
|
* Lookup order:
|
|
28832
29039
|
* 1. `--resource <id>=<arn>` override → verify with `GetWebACL` (parses
|
|
28833
|
-
* Name/Id/Scope back out of the ARN).
|
|
29040
|
+
* Name/Id/Scope back out of the ARN). CloudFormation's compound
|
|
29041
|
+
* `name|id|scope` physical id — what `--migrate-from-cloudformation`
|
|
29042
|
+
* passes — is accepted too and recorded under the ARN (issue #3627).
|
|
28834
29043
|
*/
|
|
28835
29044
|
async import(input) {
|
|
28836
29045
|
if (input.knownPhysicalId) try {
|
|
28837
|
-
const
|
|
28838
|
-
|
|
29046
|
+
const compound = /^([^|]+)\|([^|]+)\|(REGIONAL|CLOUDFRONT)$/.exec(input.knownPhysicalId);
|
|
29047
|
+
const { id, name, scope } = compound ? {
|
|
29048
|
+
name: compound[1],
|
|
29049
|
+
id: compound[2],
|
|
29050
|
+
scope: compound[3]
|
|
29051
|
+
} : parseWebACLArn(input.knownPhysicalId);
|
|
29052
|
+
if (!id || !name) return null;
|
|
29053
|
+
const resp = await this.getClient().send(new GetWebACLCommand({
|
|
28839
29054
|
Id: id,
|
|
28840
29055
|
Name: name,
|
|
28841
29056
|
Scope: scope
|
|
28842
29057
|
}));
|
|
29058
|
+
const arn = resp.WebACL?.ARN;
|
|
29059
|
+
if (!arn) return null;
|
|
28843
29060
|
return {
|
|
28844
|
-
physicalId:
|
|
28845
|
-
attributes: {
|
|
29061
|
+
physicalId: arn,
|
|
29062
|
+
attributes: definedAttributes({
|
|
29063
|
+
Arn: arn,
|
|
29064
|
+
Id: resp.WebACL?.Id,
|
|
29065
|
+
LabelNamespace: resp.WebACL?.LabelNamespace
|
|
29066
|
+
})
|
|
28846
29067
|
};
|
|
28847
29068
|
} catch (err) {
|
|
28848
29069
|
if (err instanceof WAFNonexistentItemException) return null;
|
|
@@ -30012,6 +30233,18 @@ async function allSettledKeepingFirstRejection(promises, onAbandoned) {
|
|
|
30012
30233
|
}
|
|
30013
30234
|
}
|
|
30014
30235
|
/**
|
|
30236
|
+
* The key for the resolver's per-region SDK client caches ({@link
|
|
30237
|
+
* IntrinsicFunctionResolver}'s `cfnClients`, `regionScopedClients` and
|
|
30238
|
+
* `serviceDiscoveryClients`): the region PLUS the credential fingerprint of the
|
|
30239
|
+
* configuration the cached client was built from (issue
|
|
30240
|
+
* [#3588](https://github.com/go-to-k/cdkd/issues/3588)). Encoded through
|
|
30241
|
+
* {@link injectiveKey}, so no region or profile spelling can forge another
|
|
30242
|
+
* pair's key.
|
|
30243
|
+
*/
|
|
30244
|
+
function clientCacheKey(region, credentialConfig) {
|
|
30245
|
+
return injectiveKey(region, credentialFingerprint(credentialConfig));
|
|
30246
|
+
}
|
|
30247
|
+
/**
|
|
30015
30248
|
* Is `region` safe to build an AWS SDK client from?
|
|
30016
30249
|
*
|
|
30017
30250
|
* This is a SECURITY gate, not an AWS region registry, and the distinction
|
|
@@ -30493,15 +30726,22 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
30493
30726
|
* foreign region per resolver, versus the ambient clients which are already
|
|
30494
30727
|
* created and destroyed per stack by `deploy.ts`.
|
|
30495
30728
|
*
|
|
30496
|
-
* KEYED BY REGION
|
|
30497
|
-
*
|
|
30498
|
-
*
|
|
30499
|
-
* is process-wide
|
|
30500
|
-
*
|
|
30501
|
-
*
|
|
30502
|
-
*
|
|
30503
|
-
*
|
|
30504
|
-
*
|
|
30729
|
+
* KEYED BY REGION AND CREDENTIAL FINGERPRINT ({@link clientCacheKey}, issue
|
|
30730
|
+
* [#3588](https://github.com/go-to-k/cdkd/issues/3588)). An entry pins the
|
|
30731
|
+
* credential configuration of the ambient instance it was derived from, and
|
|
30732
|
+
* that half is process-wide only for the CLI (one `--profile`, one
|
|
30733
|
+
* `--role-arn`): a LIBRARY caller can drive one resolver across two
|
|
30734
|
+
* `setAwsClients` installs (or cdkd's per-stack scopes) with different
|
|
30735
|
+
* explicit credentials, and keyed by region alone the second's lookups ran under the first's
|
|
30736
|
+
* identity. {@link cfnClients} and {@link serviceDiscoveryClients} share the
|
|
30737
|
+
* key for the same reason, and the two CloudFormation fallback memos
|
|
30738
|
+
* ({@link cfnExportsPromises}, {@link cfnStackOutputsCache}) carry the
|
|
30739
|
+
* fingerprint too.
|
|
30740
|
+
*
|
|
30741
|
+
* THE CLIENT HALF IS CLOSED, NOT THE WHOLE CLASS: {@link cachedDynamicReferences}
|
|
30742
|
+
* (keyed by the expression alone) and the PROCESS-GLOBAL account identity
|
|
30743
|
+
* behind `getAccountInfo` still assume one identity per resolver and per
|
|
30744
|
+
* process respectively — a value one identity read is served to the next.
|
|
30505
30745
|
*/
|
|
30506
30746
|
regionScopedClients = /* @__PURE__ */ new Map();
|
|
30507
30747
|
/**
|
|
@@ -30568,9 +30808,10 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
30568
30808
|
/**
|
|
30569
30809
|
* Per-region CloudFormation clients for the cross-stack fallback
|
|
30570
30810
|
* lookups (issue #1697). Keyed by region because `Fn::GetStackOutput`
|
|
30571
|
-
* may target a region different from the consumer's deploy region
|
|
30811
|
+
* may target a region different from the consumer's deploy region, and by
|
|
30812
|
+
* the credential fingerprint for {@link regionScopedClients}' reason.
|
|
30572
30813
|
*/
|
|
30573
|
-
cfnClients =
|
|
30814
|
+
cfnClients = /* @__PURE__ */ new Map();
|
|
30574
30815
|
/**
|
|
30575
30816
|
* Memoized full `ListExports` listing for the `Fn::ImportValue`
|
|
30576
30817
|
* fallback (issue #1697 review). Without it, EVERY cdkd-miss import
|
|
@@ -30582,14 +30823,18 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
30582
30823
|
* deploys. FAILED fetches are not cached (the rejection handler
|
|
30583
30824
|
* clears the slot) so a transient throttle does not poison the rest
|
|
30584
30825
|
* of the deploy's lookups.
|
|
30826
|
+
*
|
|
30827
|
+
* Keyed by the credential fingerprint (issue #3588): a listing is an answer
|
|
30828
|
+
* one identity was allowed to read, so it is never handed to another.
|
|
30585
30829
|
*/
|
|
30586
|
-
|
|
30830
|
+
cfnExportsPromises = /* @__PURE__ */ new Map();
|
|
30587
30831
|
/**
|
|
30588
30832
|
* Memoized per-(region, stack) `DescribeStacks` outputs for the
|
|
30589
30833
|
* `Fn::GetStackOutput` fallback (issue #1697 review) — a stack
|
|
30590
30834
|
* referencing the same CFn producer N times pays one call. Successful
|
|
30591
30835
|
* lookups (including the definitive "stack does not exist" miss) are
|
|
30592
|
-
* cached; lookup FAILURES are evicted so they are retried.
|
|
30836
|
+
* cached; lookup FAILURES are evicted so they are retried. Keyed by the
|
|
30837
|
+
* credential fingerprint as well, for {@link cfnExportsPromises}' reason.
|
|
30593
30838
|
*/
|
|
30594
30839
|
cfnStackOutputsCache = /* @__PURE__ */ new Map();
|
|
30595
30840
|
/**
|
|
@@ -30821,11 +31066,12 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
30821
31066
|
const loggedTarget = targetLogText ?? (targetRegion === this.explicitRegion ? this.explicitRegionLogText : void 0) ?? target;
|
|
30822
31067
|
if (!isClientSafeRegion(target)) throw markNonRetryable(new IntrinsicResolutionRefusalError(`Refusing to build AWS clients for the region '${displaySafe(stripControlChars(loggedTarget)).slice(0, 64)}': it is not a valid AWS region name, and a region is substituted into the AWS service hostname.`));
|
|
30823
31068
|
if (typeof ambient.withRegion !== "function") return ambient;
|
|
30824
|
-
const
|
|
31069
|
+
const cacheKey = clientCacheKey(target, ambient.credentialConfig ?? {});
|
|
31070
|
+
const cached = this.regionScopedClients.get(cacheKey);
|
|
30825
31071
|
if (cached) return cached;
|
|
30826
31072
|
if (canonicalizeRegion(ambient.configuredRegion) === target) return ambient;
|
|
30827
31073
|
const scoped = ambient.withRegion(target);
|
|
30828
|
-
this.regionScopedClients.set(
|
|
31074
|
+
this.regionScopedClients.set(cacheKey, scoped);
|
|
30829
31075
|
this.logger.debug(`Using region-scoped AWS clients for ${displaySafe(loggedTarget)}`);
|
|
30830
31076
|
return scoped;
|
|
30831
31077
|
}
|
|
@@ -30856,21 +31102,21 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
30856
31102
|
* `getAccountInfo`'s in-flight promise and reach here one at a time, which
|
|
30857
31103
|
* the case says out loud. A REJECTED import is evicted
|
|
30858
31104
|
* so a transient failure does not poison the rest of the deploy, mirroring
|
|
30859
|
-
* `
|
|
31105
|
+
* `cfnExportsPromises`. Lifetime is the resolver's own, like
|
|
30860
31106
|
* {@link regionScopedClients} and {@link cfnClients}: at most one per region
|
|
30861
31107
|
* per resolver, versus the one-per-CALL this replaces.
|
|
30862
31108
|
*/
|
|
30863
31109
|
async serviceDiscoveryClient() {
|
|
30864
31110
|
const scoped = this.clientsForRegion(this.explicitRegion);
|
|
30865
31111
|
const region = scoped.configuredRegion;
|
|
30866
|
-
const
|
|
31112
|
+
const credentialConfig = scoped.credentialConfig ?? {};
|
|
31113
|
+
const key = clientCacheKey(region ?? "", credentialConfig);
|
|
30867
31114
|
const cached = this.serviceDiscoveryClients.get(key);
|
|
30868
31115
|
if (cached) return cached;
|
|
30869
31116
|
const building = (async () => {
|
|
30870
31117
|
const { ServiceDiscoveryClient } = await import("@aws-sdk/client-servicediscovery");
|
|
30871
31118
|
return new ServiceDiscoveryClient({
|
|
30872
|
-
...
|
|
30873
|
-
...scoped.credentialConfig ?? {},
|
|
31119
|
+
...clientDefaultsFor(credentialConfig),
|
|
30874
31120
|
...region ? { region } : {}
|
|
30875
31121
|
});
|
|
30876
31122
|
})();
|
|
@@ -33276,12 +33522,14 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
33276
33522
|
* the same not-found error anyway.
|
|
33277
33523
|
*/
|
|
33278
33524
|
async lookupCfnExport(exportName, context) {
|
|
33279
|
-
|
|
33525
|
+
const listingKey = credentialFingerprint(ambientCredentialConfig());
|
|
33526
|
+
let listing = this.cfnExportsPromises.get(listingKey);
|
|
33280
33527
|
if (!listing) {
|
|
33281
|
-
|
|
33282
|
-
|
|
33283
|
-
|
|
33284
|
-
|
|
33528
|
+
const fetched = this.fetchAllCfnExports();
|
|
33529
|
+
listing = fetched;
|
|
33530
|
+
this.cfnExportsPromises.set(listingKey, fetched);
|
|
33531
|
+
fetched.catch(() => {
|
|
33532
|
+
if (this.cfnExportsPromises.get(listingKey) === fetched) this.cfnExportsPromises.delete(listingKey);
|
|
33285
33533
|
});
|
|
33286
33534
|
}
|
|
33287
33535
|
try {
|
|
@@ -33351,7 +33599,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
33351
33599
|
* contract as {@link lookupCfnExport}.
|
|
33352
33600
|
*/
|
|
33353
33601
|
async lookupCfnStackOutputs(stackName, region, context, loggedRegionText) {
|
|
33354
|
-
const cacheKey = injectiveKey(region, stackName);
|
|
33602
|
+
const cacheKey = injectiveKey(region, stackName, credentialFingerprint(ambientCredentialConfig()));
|
|
33355
33603
|
let fetch = this.cfnStackOutputsCache.get(cacheKey);
|
|
33356
33604
|
if (!fetch) {
|
|
33357
33605
|
fetch = this.fetchCfnStackOutputs(stackName, region);
|
|
@@ -33402,19 +33650,19 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
33402
33650
|
* Not routed through {@link clientsForRegion}: the region here is always
|
|
33403
33651
|
* the one the caller named, never the ambient's, and a test double without
|
|
33404
33652
|
* `credentialConfig` degrades to the default chain rather than throwing.
|
|
33405
|
-
* Keyed by region
|
|
33406
|
-
*
|
|
33653
|
+
* Keyed by region AND credential fingerprint for the reason
|
|
33654
|
+
* {@link regionScopedClients} gives (issue #3588).
|
|
33407
33655
|
*/
|
|
33408
33656
|
getCfnClient(region) {
|
|
33409
|
-
|
|
33657
|
+
const credentialConfig = ambientCredentialConfig();
|
|
33658
|
+
const key = clientCacheKey(region, credentialConfig);
|
|
33659
|
+
let client = this.cfnClients.get(key);
|
|
33410
33660
|
if (!client) {
|
|
33411
|
-
const credentialConfig = getAwsClients().credentialConfig ?? {};
|
|
33412
33661
|
client = new CloudFormationClient({
|
|
33413
|
-
...
|
|
33414
|
-
...credentialConfig,
|
|
33662
|
+
...clientDefaultsFor(credentialConfig),
|
|
33415
33663
|
region
|
|
33416
33664
|
});
|
|
33417
|
-
this.cfnClients
|
|
33665
|
+
this.cfnClients.set(key, client);
|
|
33418
33666
|
}
|
|
33419
33667
|
return client;
|
|
33420
33668
|
}
|
|
@@ -36756,7 +37004,7 @@ var CloudControlProvider = class {
|
|
|
36756
37004
|
const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
36757
37005
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
36758
37006
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
36759
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
37007
|
+
const { ASGProvider } = await import("./asg-provider-C0qLsIu5.js").then((n) => n.n);
|
|
36760
37008
|
const asgProvider = new ASGProvider();
|
|
36761
37009
|
return withIndeterminateGuard(await asgProvider.delete(logicalId, physicalId, resourceType, _properties, context), indeterminateGuard);
|
|
36762
37010
|
}
|
|
@@ -37306,7 +37554,7 @@ var CloudControlProvider = class {
|
|
|
37306
37554
|
break;
|
|
37307
37555
|
case "AWS::RDS::DBCluster":
|
|
37308
37556
|
try {
|
|
37309
|
-
const cluster = (await new RDSClient({ ...
|
|
37557
|
+
const cluster = (await new RDSClient({ ...ambientClientDefaults() }).send(new DescribeDBClustersCommand({ DBClusterIdentifier: physicalId }))).DBClusters?.[0];
|
|
37310
37558
|
if (cluster) {
|
|
37311
37559
|
if (cluster.Endpoint) enriched["Endpoint.Address"] = cluster.Endpoint;
|
|
37312
37560
|
if (cluster.Port !== void 0) enriched["Endpoint.Port"] = String(cluster.Port);
|
|
@@ -37321,7 +37569,7 @@ var CloudControlProvider = class {
|
|
|
37321
37569
|
break;
|
|
37322
37570
|
case "AWS::RDS::DBInstance":
|
|
37323
37571
|
try {
|
|
37324
|
-
const inst = (await new RDSClient({ ...
|
|
37572
|
+
const inst = (await new RDSClient({ ...ambientClientDefaults() }).send(new DescribeDBInstancesCommand({ DBInstanceIdentifier: physicalId }))).DBInstances?.[0];
|
|
37325
37573
|
if (inst) {
|
|
37326
37574
|
if (inst.Endpoint?.Address) enriched["Endpoint.Address"] = inst.Endpoint.Address;
|
|
37327
37575
|
if (inst.Endpoint?.Port !== void 0) enriched["Endpoint.Port"] = String(inst.Endpoint.Port);
|
|
@@ -37475,7 +37723,7 @@ var CloudControlProvider = class {
|
|
|
37475
37723
|
break;
|
|
37476
37724
|
case "AWS::ElastiCache::ReplicationGroup":
|
|
37477
37725
|
try {
|
|
37478
|
-
const rg = (await new ElastiCacheClient({ ...
|
|
37726
|
+
const rg = (await new ElastiCacheClient({ ...ambientClientDefaults() }).send(new DescribeReplicationGroupsCommand({ ReplicationGroupId: physicalId }))).ReplicationGroups?.[0];
|
|
37479
37727
|
if (rg) {
|
|
37480
37728
|
const primaryNode = rg.NodeGroups?.[0];
|
|
37481
37729
|
if (primaryNode?.PrimaryEndpoint?.Address) enriched["PrimaryEndPoint.Address"] = primaryNode.PrimaryEndpoint.Address;
|
|
@@ -37497,7 +37745,7 @@ var CloudControlProvider = class {
|
|
|
37497
37745
|
break;
|
|
37498
37746
|
case "AWS::Redshift::Cluster":
|
|
37499
37747
|
try {
|
|
37500
|
-
const cluster = (await new RedshiftClient({ ...
|
|
37748
|
+
const cluster = (await new RedshiftClient({ ...ambientClientDefaults() }).send(new DescribeClustersCommand({ ClusterIdentifier: physicalId }))).Clusters?.[0];
|
|
37501
37749
|
if (cluster?.Endpoint) {
|
|
37502
37750
|
if (cluster.Endpoint.Address) enriched["Endpoint.Address"] = cluster.Endpoint.Address;
|
|
37503
37751
|
if (cluster.Endpoint.Port !== void 0) enriched["Endpoint.Port"] = String(cluster.Endpoint.Port);
|
|
@@ -37509,7 +37757,7 @@ var CloudControlProvider = class {
|
|
|
37509
37757
|
break;
|
|
37510
37758
|
case "AWS::OpenSearchService::Domain":
|
|
37511
37759
|
try {
|
|
37512
|
-
const domain = (await new OpenSearchClient({ ...
|
|
37760
|
+
const domain = (await new OpenSearchClient({ ...ambientClientDefaults() }).send(new DescribeDomainCommand({ DomainName: physicalId }))).DomainStatus;
|
|
37513
37761
|
if (domain) {
|
|
37514
37762
|
const endpoint = domain.Endpoint ?? domain.Endpoints?.["vpc"];
|
|
37515
37763
|
if (endpoint) enriched["DomainEndpoint"] = endpoint;
|
|
@@ -42359,88 +42607,6 @@ function isCustomResource(resourceType) {
|
|
|
42359
42607
|
return resourceType.startsWith("Custom::") || resourceType === "AWS::CloudFormation::CustomResource";
|
|
42360
42608
|
}
|
|
42361
42609
|
|
|
42362
|
-
//#endregion
|
|
42363
|
-
//#region src/provisioning/attribute-map.ts
|
|
42364
|
-
/**
|
|
42365
|
-
* The ONE spelling of the attribute-map rule an SDK provider's `create()` /
|
|
42366
|
-
* `update()` / `import()` result follows (issue #3077, closing the `?? ''`
|
|
42367
|
-
* shape `docs/provider-development.md` forbids under "Never store an
|
|
42368
|
-
* empty-string placeholder"):
|
|
42369
|
-
*
|
|
42370
|
-
* an attribute cdkd could not read back is ABSENT from the map — never
|
|
42371
|
-
* recorded as the empty string, and never as a present-but-`undefined` key.
|
|
42372
|
-
*
|
|
42373
|
-
* The consumers of `ResourceState.attributes` all key off exactly that
|
|
42374
|
-
* distinction, and a sentinel puts every one of them on the wrong branch:
|
|
42375
|
-
*
|
|
42376
|
-
* - the deploy engine persists the map as-is, so `''` becomes the recorded
|
|
42377
|
-
* value of a field AWS never assigned;
|
|
42378
|
-
* - the intrinsic resolver serves a stored attribute whenever it is not
|
|
42379
|
-
* `undefined`, so `''` shadows `constructAttribute` forever — the
|
|
42380
|
-
* `AWS::EC2::Instance` IP / DNS / AZ arm re-describes the instance from
|
|
42381
|
-
* AWS only on a MISS, the `Arn` arms of the RDS family rebuild the ARN
|
|
42382
|
-
* only on a MISS;
|
|
42383
|
-
* - the Outputs export pass publishes whatever the resolver returned, so a
|
|
42384
|
-
* stored `''` is exported to every `Fn::ImportValue` consumer.
|
|
42385
|
-
*
|
|
42386
|
-
* It exists as a MODULE rather than a per-provider idiom because the rule was
|
|
42387
|
-
* prose and 96 attribute-position `?? ''` / `|| ''` / bare `''` sites across
|
|
42388
|
-
* 18 providers shipped anyway (measured 2026-09-14 with the TypeScript-compiler
|
|
42389
|
-
* walk that is now `tests/unit/provisioning/attribute-map.test.ts`). A helper
|
|
42390
|
-
* that DROPS the key is the one form a provider cannot spell wrong by habit.
|
|
42391
|
-
*
|
|
42392
|
-
* Two values are treated as "not read back":
|
|
42393
|
-
*
|
|
42394
|
-
* - `undefined`: the SDK's spelling of an unassigned optional member.
|
|
42395
|
-
* - `null`: no AWS SDK v3 read-back reports a scalar attribute as `null`, and
|
|
42396
|
-
* a stored `null` takes the resolver's "not `undefined`" hit branch exactly
|
|
42397
|
-
* like `''` does.
|
|
42398
|
-
*
|
|
42399
|
-
* Every other value is kept verbatim — INCLUDING an empty string AWS itself
|
|
42400
|
-
* reported (`false`, `0`, an empty array and an object likewise). The helper
|
|
42401
|
-
* stops cdkd MANUFACTURING `''` for a field it never read; a `''` that came
|
|
42402
|
-
* off the wire is a known value with a meaning the provider owns. The EC2
|
|
42403
|
-
* Instance provider is where that distinction is load-bearing: a `running`
|
|
42404
|
-
* instance with no public address is described with `PublicDnsName: ''` and
|
|
42405
|
-
* no `PublicIpAddress`, and CloudFormation answers `''` for both — a KNOWN
|
|
42406
|
-
* empty, recorded as such so a reference does not degrade to the instance id
|
|
42407
|
-
* on every resolution — while the same `''` on a `pending` instance means
|
|
42408
|
-
* "not yet", which that provider maps to `undefined` BEFORE calling this
|
|
42409
|
-
* helper (its `describedInstanceAttributes`). A caller that knows a `''`
|
|
42410
|
-
* means "unknown" is the one that must say so; this helper cannot tell.
|
|
42411
|
-
*
|
|
42412
|
-
* Deliberately NOT a general "compact this record" utility: it is scoped to
|
|
42413
|
-
* attribute maps. A property bag keeps its `undefined`-valued keys out by other
|
|
42414
|
-
* means (`.claude/rules/provider-property-fidelity.md`, "Remove the key rather
|
|
42415
|
-
* than setting it to `undefined`").
|
|
42416
|
-
*
|
|
42417
|
-
* A LEAF module (imports nothing) so every provider can take it without adding
|
|
42418
|
-
* an edge to the provider import ring.
|
|
42419
|
-
*/
|
|
42420
|
-
/**
|
|
42421
|
-
* Build an attribute map from read-back values, omitting every key whose value
|
|
42422
|
-
* is `undefined` or `null`.
|
|
42423
|
-
*/
|
|
42424
|
-
function definedAttributes(entries) {
|
|
42425
|
-
const out = {};
|
|
42426
|
-
for (const [key, value] of Object.entries(entries)) {
|
|
42427
|
-
if (value === void 0 || value === null) continue;
|
|
42428
|
-
out[key] = value;
|
|
42429
|
-
}
|
|
42430
|
-
return out;
|
|
42431
|
-
}
|
|
42432
|
-
/**
|
|
42433
|
-
* `String(value)` for a numeric read-back whose CloudFormation attribute is a
|
|
42434
|
-
* string (`Endpoint.Port`), or `undefined` when the field is unassigned — so
|
|
42435
|
-
* `definedAttributes` drops the key instead of recording the literal
|
|
42436
|
-
* `'undefined'`, which is what `String(described?.Port ?? '')` yields once its
|
|
42437
|
-
* `?? ''` is merely deleted.
|
|
42438
|
-
*/
|
|
42439
|
-
function stringifyIfAssigned(value) {
|
|
42440
|
-
if (value === void 0 || value === null) return void 0;
|
|
42441
|
-
return String(value);
|
|
42442
|
-
}
|
|
42443
|
-
|
|
42444
42610
|
//#endregion
|
|
42445
42611
|
//#region src/provisioning/update-removal.ts
|
|
42446
42612
|
/**
|
|
@@ -44746,8 +44912,11 @@ async function planOrphanAdoption(params) {
|
|
|
44746
44912
|
const claims = async () => siblingClaims ??= await params.readSiblingClaims();
|
|
44747
44913
|
for (const record of params.records) {
|
|
44748
44914
|
const { logicalId, state } = record;
|
|
44915
|
+
const shownId = displayIdent(logicalId);
|
|
44916
|
+
const shownType = displayIdent(state.resourceType);
|
|
44917
|
+
const shownPhysicalId = displaySafe(state.physicalId);
|
|
44749
44918
|
if (params.managedLogicalIds.has(logicalId)) {
|
|
44750
|
-
params.logger.debug(`orphan ${
|
|
44919
|
+
params.logger.debug(`orphan ${shownId}: already present in state.resources — dropping the stale record`);
|
|
44751
44920
|
continue;
|
|
44752
44921
|
}
|
|
44753
44922
|
let provider;
|
|
@@ -44755,12 +44924,12 @@ async function planOrphanAdoption(params) {
|
|
|
44755
44924
|
provider = params.getProvider(state.resourceType, state.provisionedBy);
|
|
44756
44925
|
} catch (error) {
|
|
44757
44926
|
outcome.remaining.push(record);
|
|
44758
|
-
outcome.notices.push(`${
|
|
44927
|
+
outcome.notices.push(`${shownId} (${shownType}) is still in AWS as ${shownPhysicalId} from an earlier rollback, but this build cannot route that type (${displayAwsMessage(error instanceof Error ? error.message : String(error))}) — cdkd is not adopting it.`);
|
|
44759
44928
|
continue;
|
|
44760
44929
|
}
|
|
44761
44930
|
if (!provider.import) {
|
|
44762
44931
|
outcome.remaining.push(record);
|
|
44763
|
-
outcome.notices.push(`${
|
|
44932
|
+
outcome.notices.push(`${shownId} (${shownType}) was left in AWS by an earlier rollback as ${shownPhysicalId}, but its provider cannot verify it — cdkd is not adopting it.`);
|
|
44764
44933
|
continue;
|
|
44765
44934
|
}
|
|
44766
44935
|
let found;
|
|
@@ -44774,32 +44943,32 @@ async function planOrphanAdoption(params) {
|
|
|
44774
44943
|
knownPhysicalId: state.physicalId
|
|
44775
44944
|
});
|
|
44776
44945
|
} catch (error) {
|
|
44777
|
-
outcome.notices.push(`${
|
|
44946
|
+
outcome.notices.push(`${shownId} (${shownType}) is recorded as left in AWS as ${shownPhysicalId}, but cdkd could not confirm it exists (${displayAwsMessage(error instanceof Error ? error.message : String(error))}) — keeping the record and not adopting it this run.`);
|
|
44778
44947
|
outcome.remaining.push(record);
|
|
44779
44948
|
continue;
|
|
44780
44949
|
}
|
|
44781
44950
|
if (found !== null && found.physicalId !== state.physicalId) {
|
|
44782
44951
|
outcome.remaining.push(record);
|
|
44783
|
-
outcome.notices.push(`${
|
|
44952
|
+
outcome.notices.push(`${shownId} (${shownType}): cdkd asked about ${shownPhysicalId} and its provider answered for ${displaySafe(found.physicalId)} — not adopting.`);
|
|
44784
44953
|
continue;
|
|
44785
44954
|
}
|
|
44786
44955
|
if (found === null) {
|
|
44787
|
-
params.logger.debug(`orphan ${
|
|
44956
|
+
params.logger.debug(`orphan ${shownId}: ${shownPhysicalId} no longer exists in AWS — dropping the record`);
|
|
44788
44957
|
continue;
|
|
44789
44958
|
}
|
|
44790
44959
|
if (params.nameProperties(state.resourceType).length === 0 || ADOPTION_REFUSED_TYPES.has(state.resourceType)) {
|
|
44791
44960
|
outcome.remaining.push(record);
|
|
44792
44961
|
const why = ADOPTION_REFUSED_TYPES.has(state.resourceType) ? "a new deploy of it mints a new resource rather than colliding, and cdkd cannot update one in place — so adopting it would end in a replacement that destroys what DeletionPolicy: Retain preserved" : "cdkd does not derive that resource's physical name, so a new deploy mints a new resource instead of colliding";
|
|
44793
|
-
outcome.notices.push(`${
|
|
44962
|
+
outcome.notices.push(`${shownId} (${shownType}) is still in AWS as ${shownPhysicalId} from an earlier rollback. cdkd does not re-adopt this type: ${why}. Delete it yourself when you no longer need it.`);
|
|
44794
44963
|
continue;
|
|
44795
44964
|
}
|
|
44796
44965
|
if (!templateStillDeclares(params.template, record, params.nameProperties(state.resourceType))) {
|
|
44797
44966
|
outcome.remaining.push(record);
|
|
44798
|
-
outcome.notices.push(`${
|
|
44967
|
+
outcome.notices.push(`${shownId} (${shownType}) is still in AWS as ${shownPhysicalId} from an earlier rollback. This deploy does not create it under that name, so cdkd is leaving it alone.`);
|
|
44799
44968
|
continue;
|
|
44800
44969
|
}
|
|
44801
44970
|
if ((await claims()).has(state.physicalId)) {
|
|
44802
|
-
outcome.refusals.push(`${
|
|
44971
|
+
outcome.refusals.push(`${shownId}: ${shownPhysicalId} is already recorded by another cdkd stack. cdkd will not adopt a resource another stack manages.`);
|
|
44803
44972
|
outcome.remaining.push(record);
|
|
44804
44973
|
continue;
|
|
44805
44974
|
}
|
|
@@ -44852,7 +45021,7 @@ function makeSiblingClaimReader(params) {
|
|
|
44852
45021
|
try {
|
|
44853
45022
|
refs = await stateBackend.listStacks();
|
|
44854
45023
|
} catch (error) {
|
|
44855
|
-
logger.debug(`orphan adoption: could not list sibling stacks — ${error instanceof Error ? error.message : String(error)}`);
|
|
45024
|
+
logger.debug(`orphan adoption: could not list sibling stacks — ${displayAwsMessage(error instanceof Error ? error.message : String(error))}`);
|
|
44856
45025
|
return claimed;
|
|
44857
45026
|
}
|
|
44858
45027
|
for (const ref of refs) {
|
|
@@ -44862,7 +45031,7 @@ function makeSiblingClaimReader(params) {
|
|
|
44862
45031
|
const sibling = await stateBackend.getState(ref.stackName, ref.region);
|
|
44863
45032
|
for (const record of Object.values(sibling?.state.resources ?? {})) claimed.add(record.physicalId);
|
|
44864
45033
|
} catch (error) {
|
|
44865
|
-
logger.debug(`orphan adoption: skipping unreadable state for ${ref.stackName} — ${error instanceof Error ? error.message : String(error)}`);
|
|
45034
|
+
logger.debug(`orphan adoption: skipping unreadable state for ${displayStackName(ref.stackName)} — ${displayAwsMessage(error instanceof Error ? error.message : String(error))}`);
|
|
44866
45035
|
}
|
|
44867
45036
|
}
|
|
44868
45037
|
return claimed;
|
|
@@ -50785,7 +50954,7 @@ var DeployEngine = class DeployEngine {
|
|
|
50785
50954
|
if (plan.refusals.length > 0) throw new Error(`Deploy refused — cdkd left ${plan.refusals.length} resource(s) in AWS that it cannot safely re-adopt:\n ${plan.refusals.join("\n ")}`);
|
|
50786
50955
|
for (const [logicalId, record] of Object.entries(plan.adopted)) {
|
|
50787
50956
|
currentState.resources[logicalId] = record;
|
|
50788
|
-
this.logger.info(`Adopting ${logicalId} (${record.resourceType}) left in AWS by an earlier rollback as ${record.physicalId}`);
|
|
50957
|
+
this.logger.info(`Adopting ${displayIdent(logicalId)} (${displayIdent(record.resourceType)}) left in AWS by an earlier rollback as ${displaySafe(record.physicalId)}`);
|
|
50789
50958
|
}
|
|
50790
50959
|
if (records.length > 0) currentState.orphans = plan.remaining;
|
|
50791
50960
|
return plan;
|
|
@@ -52252,5 +52421,5 @@ var DeployEngine = class DeployEngine {
|
|
|
52252
52421
|
};
|
|
52253
52422
|
|
|
52254
52423
|
//#endregion
|
|
52255
|
-
export { yellow as $, NestedStackChildDirectDestroyError as $a, resolveSkipPrefix as $i, refuseMalformedOutputsForDestroy as $n, hasReadableExportSet as $r, readConfigString as $t, createPreDeleteFinalSnapshot as A, absoluteAssemblyPathEscape as Aa, describeDockerFailure as Ai, malformedExportSourceWarning as An, identityKeyFor as Ar, disableInstanceApiTermination as At, isStatefulRecreateTargetSync as B, setAwsClients as Ba, runDockerStreaming as Bi, malformedResourceEntriesWarning as Bn, redactSecretsForState as Br, isUnboundTemplateParameter as Bt, namesAnyDeclaredParameter as C, globMatches as Ca, validateAssetBucketName as Ci, displayLogicalId as Cn, __exportAll as Co, STATE_SOURCED_CROSS_GENERATION_RULES as Cr, CloudControlProvider as Ct, PRE_DELETE_SNAPSHOT_TYPES as D, hasPlainPrototype$1 as Da, resolveDockerContextDirectory as Di, isReadableOrphanRecord as Dn, createSecretMasker as Dr, deleteIndeterminateGuards as Dt, ATOMIC_FINAL_SNAPSHOT_TYPES as E, hasOwnKey as Ea, buildDockerImage as Ei, hasReadableResources as En, carriesSecretMask as Er, UNSPECIFIED_SKIP_REASON as Et, extractDeploymentEventError as F, resolveBucketRegion as Fa, isDockerClientEnvKey as Fi, malformedOrphansRefusalMessage as Fn, maskSecretsInText as Fr, cfnRefValueFromPhysicalId as Ft, toCfnInteger as G, DependencyError as Ga, getDockerImageBySourceHash as Gi, refuseDivergentRecordRegionForDestroy as Gn, UNREPRODUCIBLE_LOCK_CLAUSE as Gr, normalizeAwsTagsToCfn as Gt, WARM_THROUGHPUT_MEMBERS as H, CdkdError as Ha, escapeRegExp$1 as Hi, malformedResourcesWarning as Hn, LockManager as Hr, refStateLookupFromResource as Ht, makeSiblingClaimReader as I, AwsClients as Ia, isMalformedEnvKey as Ii, malformedOrphansWarning as In, pathCrossesDottedKey as Ir, coerceParameterTypedValue as It, bold as J, IntrinsicResolutionRefusalError as Ja, getDefaultStateBucketName as Ji, refuseMalformedOrphanRecordsForDestroy as Jn, forceQuitRecoveryClause as Jr, coerceCfnBoolean as Jt, toFiniteNumber as K, DeployCancelledError as Ka, Synthesizer as Ki, refuseMalformedNestedChildOutputs as Kn, buildForceUnlockCommand as Kr, resolveExplicitPhysicalId as Kt, planOrphanAdoption as L, getAwsClients as La, partitionSensitiveEnv as Li, malformedOutputsRefusalMessage as Ln, recordMaskOnlyValue as Lr, getAccountInfo as Lt, refusesFinalSnapshot as M, renderAssemblyPathEscape as Ma, finchSecretArgvRefusal as Mi, malformedOrphanRecordsRefusalMessage as Mn, isUncertifiedBaselineMaskPosition as Mr, IntrinsicFunctionResolver as Mt, unsupportedFinalSnapshotError as N, resolveAssemblyPath as Na, formatDockerLoginError as Ni, malformedOrphanRecordsWarning as Nn, markSameGenerationBag as Nr, carriesDynamicReference as Nt, buildFinalSnapshotIdentifier as O, nullPrototypeRecord as Oa, describeDockerCapturedOutput as Oi, isReadableResourceEntry as On, dynamicReferenceTokens as Or, deleteSkipReason as Ot, makeCanonicalizePropertiesFn as P, clearBucketRegionCache as Pa, getDockerCmd as Pi, malformedOrphanRowsKeptWarning as Pn, maskSecretsInError as Pr, carriesFetchableDynamicReference as Pt, red as Q, MalformedProducerRecordRefusalError as Qa, resolveCaptureObservedState as Qi, refuseMalformedOutputs as Qn, exportNamesCarriedFrom as Qr, configStringRefusal as Qt, MULTI_REGION_RECREATE_BLOCKED_TYPES as R, resetAwsClients as Ra, redactDockerArgvValues as Ri, malformedOutputsWarning as Rn, recordMaskOnlyValuesIn as Rr, isImpossibleEmptyStoredAttribute as Rt, computeParameterTaint as S, failedStageNote as Sa, readBootstrapMarkerBody as Si, deployRefusesOrphanRowsReason as Sn, safeStringify$1 as So, STATE_SOURCED_BASELINE_RULES as Sr, startInterruptWatch as St, resourcesNamingDeclaredParameter as T, defineOwnKey as Ta, buildDenyExternalAccessPolicy as Ti, hasReadableOutputs as Tn, TEMPLATE_SOURCED_RULES as Tr, ccProtectionRegistryTypes as Tt, coerceWarmThroughput as U, ConfigError as Ua, stripControlChars as Ui, malformedStateRefusalMessage as Un, S3StateBackend as Ur, isSettledInstanceState as Ut, renderStatefulReason as V, AssetError as Va, warnFinchArgvExposure as Vi, malformedResourcePropertiesWarning as Vn, scrubResourceRecord as Vr, parameterTypeMayLoseSecretIdentity as Vt, isWarmThroughputDecrease as W, CrossAccountSecretRefusalError as Wa, AssetManifestLoader as Wi, previewableOrphanRecords as Wn, rebuildClientForBucketRegion as Wr, WAFv2WebACLProvider as Wt, gray as X, LocalStartServiceError as Xa, resolveApp as Xi, refuseMalformedOrphansForDestroy as Xn, CUSTOM_RESOURCE_RESPONSE_PREFIX as Xr, configBooleanRefusal as Xt, cyan as Y, LocalInvokeBuildError as Ya, getLegacyStateBucketName as Yi, refuseMalformedOrphans as Yn, formatLockExpiry as Yr, coerceCfnInteger as Yt, green as Z, LockError as Za, resolveAutoAssetStorage as Zi, refuseMalformedOrphansForOrphan as Zn, DEFAULT_STATE_PREFIX as Zr, configIntegerRefusal as Zt, bagHoldsSecretExpression as _, expectedOwnerParam as _a, assertAssetBucketRegion as _i, DiffCalculator as _n, isTransientServerError as _o, findSilentDropProperties as _r, maskerOrIdentity as _t, DeploymentEventsStore as a, ssmResolvedValueType as aa, orphansAfterRollback as ai, producerRegionsFromState as an, StackTerminationProtectionError as ao, refuseMalformedState as ar, secretBearingStateKeyWarning as at, mergeNoChangeOutputs as b, derivePartitionAndUrlSuffix as ba, isCrossRegionRedirect as bi, UNREADABLE_ORPHANS_CONTAINER_ROW as bn, retryClassificationText as bo, DagBuilder as br, interruptWatchListenerCount as bt, replayFailedOperations as c, MIGRATE_TMP_PREFIX as ca, AssetPublisher as ci, s3BucketDomainName as cn, formatError as co, repairMalformedOutputsForReadOnly as cr, IAMRoleProvider as ct, updatePartialMessage as d, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as da, buildAssetRedirectMap as di, s3BucketWebsiteUrl as dn, withErrorHandling as do, repairMalformedResourcesForReadOnly as dr, definedAttributes as dt, resolveStateBucketWithDefault as ea, hasReasonlessBaselineRefusal as ei, replayWarn as en, PartialFailureError as eo, refuseMalformedResourceAttributesForOrphan as er, collectDeclaredOutputNames as et, updatePartialReason as f, injectiveKey as fa, createAssetRedirectResolver as fi, applyRoleArnIfSet as fn, pasteableCommand as fo, safeRegion as fr, stringifyIfAssigned as ft, computeImplicitDeleteEdges as g, decodeListingKey as ga, BOOTSTRAP_MARKER_PREFIX as gi, envCredentialsAreAssumedRole as gn, isThrottlingError as go, findActionableSilentDrops as gr, maskDeep as gt, IMPLICIT_DELETE_DEPENDENCIES as h, producerRecordKey as ha, AssetModeResolver as hi, callerEnvCredentials as hn, isRetryableTransientError as ho, unreadableOrphanRecords as hr, createMaskedRetryLogger as ht, DeploymentEventsReader as i, warnDeprecatedNoPrefixCliFlag as ia, isReadableBag as ii, classifyReplaySecretRegion as in, StackHasActiveImportsError as io, refuseMalformedResourcesForDestroy as ir, secretBearing as it, isFinalSnapshotError as j, displayAssemblyPath as ja, dockerSpawnEnvWithSensitive as ji, malformedLocalOutputsWarning as jn, isSingleDynamicReferenceToken as jr, isTerminationProtectionPropagationError as jt, ccRoutedFinalSnapshotError as k, ownValue as ka, describeDockerExecFailure as ki, malformedExportNamesWarning as kn, errorCauseChain as kr, isWaitAbandonedError as kt, replayRollback as l, findLargeInlineResources as la, stringifyValue as li, s3BucketDualStackDomainName as ln, isCdkdError as lo, repairMalformedResourceEntriesForReadOnly as lr, collectInlinePolicyNamesManagedBySiblings as lt, maskingRetryLogger as m, producerCoordinateKey as ma, rewriteTemplateAssetReferences as mi, applyCallerIdentityCredentials as mn, isMarkedNonRetryable as mo, unpreviewableOrphanRecords as mr, wouldReturnToSdkProvider as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, resolveUseCdkBootstrapAssets as na, importableOutputKeys as ni, requireConfigObject as nn, ResourceTimeoutError as no, refuseMalformedResourceEntriesForOrphan as nr, exportAliasCollisionScrubWarning as nt, planFailedOps as o, CFN_TEMPLATE_BODY_LIMIT as oa, orphansCarriedFrom as oi, withSharedDrainBudget as on, StateError as oo, repairMalformedOrphanRecordsForReadOnly as or, secretSafeKeyDisplay as ot, withResourceDeadline as p, injectiveKeyPrefix as pa, loadPublishableAssetManifest as pi, AWS_CREDENTIAL_ENV_KEYS as pn, shellQuote as po, safeStackName as pr, ProviderRegistry as pt, formatResourceLine as q, DynamicReferenceRegionAmbiguousError as qa, synthesisStatusMessage as qi, refuseMalformedOrphanRecords as qn, buildLockContentionMessage as qr, assertRegionMatch as qt, DeployEngine as r, stateBucketExistenceConfirmed as ra, importableOutputs as ri, requireConfigString as rn, ResourceUpdateNotSupportedError as ro, refuseMalformedResourcePropertiesForOrphan as rr, isExportAliasCollision as rt, planRollback as s, CFN_TEMPLATE_URL_LIMIT as sa, shouldRetainResource as si, s3BucketArn as sn, SynthesisError as so, repairMalformedOrphansForReadOnly as sr, getCurrentResourceSecrets as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, resolveStateBucketWithDefaultAndSource as ta, hasUnverifiableParameterRefusal as ti, requireConfigArray as tn, ProvisioningError as to, refuseMalformedResourceEntries as tr, collectPublishedOutputNames as tt, resolveReplacementOldType as u, uploadCfnTemplate as ua, WorkGraph as ui, s3BucketRegionalDomainName as un, normalizeAwsError as uo, repairMalformedResourcePropertiesForReadOnly as ur, clearOnUpdateRemoval as ut, isSecretBearingReferenceString as v, PARTITION_TABLE as va, ensureAssetStorage as vi, INTRINSIC_KEYS as vn, markNonRetryable as vo, describeTypeWithThrottleRetry as vr, beginCommandInterruptScope as vt, reachableDivergentParameters as w, processStackMessages as wa, validateContainerRepoName as wi, hasReadableOrphans as wn, STATE_SOURCED_READBACK_RULES as wr, slowCcOperationTimeoutMs as wt, bindingSkippedOutputs as x, AssemblyReader as xa, parseBootstrapMarker as xi, UNREADABLE_RESOURCES_MAP_ROW as xn, describeAwsFailure as xo, TemplateParser as xr, isInterruptedWaitError as xt, keptWholeReasonText as y, canonicalizeRegion as ya, getBootstrapMarkerKey as yi, STATE_RESOURCES_MALFORMED as yn, markRedactedCause as yo, withRetry as yr, endCommandInterruptScope as yt, isStatefulRecreateTargetForReplace as z, runWithStackAwsClients as za, runDockerForeground as zi, malformedRenderedContainersWarning as zn, recoverMaskedOutput as zr, isNamelessDynamicReferenceError as zt };
|
|
52256
|
-
//# sourceMappingURL=deploy-engine-
|
|
52424
|
+
export { yellow as $, MalformedProducerRecordRefusalError as $a, resolveSkipPrefix as $i, refuseMalformedOutputsForDestroy as $n, hasReadableExportSet as $r, requireConfigArray as $t, createPreDeleteFinalSnapshot as A, ownValue as Aa, describeDockerFailure as Ai, malformedExportSourceWarning as An, identityKeyFor as Ar, IntrinsicFunctionResolver as At, isStatefulRecreateTargetSync as B, runWithStackAwsClients as Ba, runDockerStreaming as Bi, malformedResourceEntriesWarning as Bn, redactSecretsForState as Br, refStateLookupFromResource as Bt, namesAnyDeclaredParameter as C, failedStageNote as Ca, validateAssetBucketName as Ci, displayLogicalId as Cn, safeStringify$1 as Co, STATE_SOURCED_CROSS_GENERATION_RULES as Cr, ccProtectionRegistryTypes as Ct, PRE_DELETE_SNAPSHOT_TYPES as D, hasOwnKey as Da, resolveDockerContextDirectory as Di, isReadableOrphanRecord as Dn, createSecretMasker as Dr, isWaitAbandonedError as Dt, ATOMIC_FINAL_SNAPSHOT_TYPES as E, defineOwnKey as Ea, buildDockerImage as Ei, hasReadableResources as En, carriesSecretMask as Er, deleteSkipReason as Et, extractDeploymentEventError as F, clearBucketRegionCache as Fa, isDockerClientEnvKey as Fi, malformedOrphansRefusalMessage as Fn, maskSecretsInText as Fr, getAccountInfo as Ft, toCfnInteger as G, CrossAccountSecretRefusalError as Ga, getDockerImageBySourceHash as Gi, refuseDivergentRecordRegionForDestroy as Gn, UNREPRODUCIBLE_LOCK_CLAUSE as Gr, assertRegionMatch as Gt, WARM_THROUGHPUT_MEMBERS as H, AssetError as Ha, escapeRegExp$1 as Hi, malformedResourcesWarning as Hn, LockManager as Hr, WAFv2WebACLProvider as Ht, makeSiblingClaimReader as I, resolveBucketRegion as Ia, isMalformedEnvKey as Ii, malformedOrphansWarning as In, pathCrossesDottedKey as Ir, isImpossibleEmptyStoredAttribute as It, bold as J, DynamicReferenceRegionAmbiguousError as Ja, getDefaultStateBucketName as Ji, refuseMalformedOrphanRecordsForDestroy as Jn, forceQuitRecoveryClause as Jr, configBooleanRefusal as Jt, toFiniteNumber as K, DependencyError as Ka, Synthesizer as Ki, refuseMalformedNestedChildOutputs as Kn, buildForceUnlockCommand as Kr, coerceCfnBoolean as Kt, planOrphanAdoption as L, AwsClients as La, partitionSensitiveEnv as Li, malformedOutputsRefusalMessage as Ln, recordMaskOnlyValue as Lr, isNamelessDynamicReferenceError as Lt, refusesFinalSnapshot as M, displayAssemblyPath as Ma, finchSecretArgvRefusal as Mi, malformedOrphanRecordsRefusalMessage as Mn, isUncertifiedBaselineMaskPosition as Mr, carriesFetchableDynamicReference as Mt, unsupportedFinalSnapshotError as N, renderAssemblyPathEscape as Na, formatDockerLoginError as Ni, malformedOrphanRecordsWarning as Nn, markSameGenerationBag as Nr, cfnRefValueFromPhysicalId as Nt, buildFinalSnapshotIdentifier as O, hasPlainPrototype$1 as Oa, describeDockerCapturedOutput as Oi, isReadableResourceEntry as On, dynamicReferenceTokens as Or, disableInstanceApiTermination as Ot, makeCanonicalizePropertiesFn as P, resolveAssemblyPath as Pa, getDockerCmd as Pi, malformedOrphanRowsKeptWarning as Pn, maskSecretsInError as Pr, coerceParameterTypedValue as Pt, red as Q, LockError as Qa, resolveCaptureObservedState as Qi, refuseMalformedOutputs as Qn, exportNamesCarriedFrom as Qr, replayWarn as Qt, MULTI_REGION_RECREATE_BLOCKED_TYPES as R, getAwsClients as Ra, redactDockerArgvValues as Ri, malformedOutputsWarning as Rn, recordMaskOnlyValuesIn as Rr, isUnboundTemplateParameter as Rt, computeParameterTaint as S, AssemblyReader as Sa, readBootstrapMarkerBody as Si, deployRefusesOrphanRowsReason as Sn, describeAwsFailure as So, STATE_SOURCED_BASELINE_RULES as Sr, slowCcOperationTimeoutMs as St, resourcesNamingDeclaredParameter as T, processStackMessages as Ta, buildDenyExternalAccessPolicy as Ti, hasReadableOutputs as Tn, TEMPLATE_SOURCED_RULES as Tr, deleteIndeterminateGuards as Tt, coerceWarmThroughput as U, CdkdError as Ua, stripControlChars as Ui, malformedStateRefusalMessage as Un, S3StateBackend as Ur, normalizeAwsTagsToCfn as Ut, renderStatefulReason as V, setAwsClients as Va, warnFinchArgvExposure as Vi, malformedResourcePropertiesWarning as Vn, scrubResourceRecord as Vr, isSettledInstanceState as Vt, isWarmThroughputDecrease as W, ConfigError as Wa, AssetManifestLoader as Wi, previewableOrphanRecords as Wn, rebuildClientForBucketRegion as Wr, resolveExplicitPhysicalId as Wt, gray as X, LocalInvokeBuildError as Xa, resolveApp as Xi, refuseMalformedOrphansForDestroy as Xn, CUSTOM_RESOURCE_RESPONSE_PREFIX as Xr, configStringRefusal as Xt, cyan as Y, IntrinsicResolutionRefusalError as Ya, getLegacyStateBucketName as Yi, refuseMalformedOrphans as Yn, formatLockExpiry as Yr, configIntegerRefusal as Yt, green as Z, LocalStartServiceError as Za, resolveAutoAssetStorage as Zi, refuseMalformedOrphansForOrphan as Zn, DEFAULT_STATE_PREFIX as Zr, readConfigString as Zt, bagHoldsSecretExpression as _, expectedOwnerParam as _a, assertAssetBucketRegion as _i, DiffCalculator as _n, isThrottlingError as _o, findSilentDropProperties as _r, endCommandInterruptScope as _t, DeploymentEventsStore as a, ssmResolvedValueType as aa, orphansAfterRollback as ai, producerRegionsFromState as an, StackHasActiveImportsError as ao, refuseMalformedState as ar, secretBearingStateKeyWarning as at, mergeNoChangeOutputs as b, derivePartitionAndUrlSuffix as ba, isCrossRegionRedirect as bi, UNREADABLE_ORPHANS_CONTAINER_ROW as bn, markRedactedCause as bo, DagBuilder as br, startInterruptWatch as bt, replayFailedOperations as c, MIGRATE_TMP_PREFIX as ca, AssetPublisher as ci, s3BucketDomainName as cn, SynthesisError as co, repairMalformedOutputsForReadOnly as cr, IAMRoleProvider as ct, updatePartialMessage as d, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as da, buildAssetRedirectMap as di, s3BucketWebsiteUrl as dn, normalizeAwsError as do, repairMalformedResourcesForReadOnly as dr, ProviderRegistry as dt, resolveStateBucketWithDefault as ea, hasReasonlessBaselineRefusal as ei, requireConfigObject as en, NestedStackChildDirectDestroyError as eo, refuseMalformedResourceAttributesForOrphan as er, collectDeclaredOutputNames as et, updatePartialReason as f, injectiveKey as fa, createAssetRedirectResolver as fi, applyRoleArnIfSet as fn, withErrorHandling as fo, safeRegion as fr, wouldReturnToSdkProvider as ft, computeImplicitDeleteEdges as g, decodeListingKey as ga, BOOTSTRAP_MARKER_PREFIX as gi, envCredentialsAreAssumedRole as gn, isRetryableTransientError as go, findActionableSilentDrops as gr, beginCommandInterruptScope as gt, IMPLICIT_DELETE_DEPENDENCIES as h, producerRecordKey as ha, AssetModeResolver as hi, callerEnvCredentials as hn, isMarkedNonRetryable as ho, unreadableOrphanRecords as hr, maskerOrIdentity as ht, DeploymentEventsReader as i, warnDeprecatedNoPrefixCliFlag as ia, isReadableBag as ii, classifyReplaySecretRegion as in, ResourceUpdateNotSupportedError as io, refuseMalformedResourcesForDestroy as ir, secretBearing as it, isFinalSnapshotError as j, absoluteAssemblyPathEscape as ja, dockerSpawnEnvWithSensitive as ji, malformedLocalOutputsWarning as jn, isSingleDynamicReferenceToken as jr, carriesDynamicReference as jt, ccRoutedFinalSnapshotError as k, nullPrototypeRecord as ka, describeDockerExecFailure as ki, malformedExportNamesWarning as kn, errorCauseChain as kr, isTerminationProtectionPropagationError as kt, replayRollback as l, findLargeInlineResources as la, stringifyValue as li, s3BucketDualStackDomainName as ln, formatError as lo, repairMalformedResourceEntriesForReadOnly as lr, collectInlinePolicyNamesManagedBySiblings as lt, maskingRetryLogger as m, producerCoordinateKey as ma, rewriteTemplateAssetReferences as mi, applyCallerIdentityCredentials as mn, shellQuote as mo, unpreviewableOrphanRecords as mr, maskDeep as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, resolveUseCdkBootstrapAssets as na, importableOutputKeys as ni, definedAttributes as nn, ProvisioningError as no, refuseMalformedResourceEntriesForOrphan as nr, exportAliasCollisionScrubWarning as nt, planFailedOps as o, CFN_TEMPLATE_BODY_LIMIT as oa, orphansCarriedFrom as oi, withSharedDrainBudget as on, StackTerminationProtectionError as oo, repairMalformedOrphanRecordsForReadOnly as or, secretSafeKeyDisplay as ot, withResourceDeadline as p, injectiveKeyPrefix as pa, loadPublishableAssetManifest as pi, AWS_CREDENTIAL_ENV_KEYS as pn, pasteableCommand as po, safeStackName as pr, createMaskedRetryLogger as pt, formatResourceLine as q, DeployCancelledError as qa, synthesisStatusMessage as qi, refuseMalformedOrphanRecords as qn, buildLockContentionMessage as qr, coerceCfnInteger as qt, DeployEngine as r, stateBucketExistenceConfirmed as ra, importableOutputs as ri, stringifyIfAssigned as rn, ResourceTimeoutError as ro, refuseMalformedResourcePropertiesForOrphan as rr, isExportAliasCollision as rt, planRollback as s, CFN_TEMPLATE_URL_LIMIT as sa, shouldRetainResource as si, s3BucketArn as sn, StateError as so, repairMalformedOrphansForReadOnly as sr, getCurrentResourceSecrets as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, resolveStateBucketWithDefaultAndSource as ta, hasUnverifiableParameterRefusal as ti, requireConfigString as tn, PartialFailureError as to, refuseMalformedResourceEntries as tr, collectPublishedOutputNames as tt, resolveReplacementOldType as u, uploadCfnTemplate as ua, WorkGraph as ui, s3BucketRegionalDomainName as un, isCdkdError as uo, repairMalformedResourcePropertiesForReadOnly as ur, clearOnUpdateRemoval as ut, isSecretBearingReferenceString as v, PARTITION_TABLE as va, ensureAssetStorage as vi, INTRINSIC_KEYS as vn, isTransientServerError as vo, describeTypeWithThrottleRetry as vr, interruptWatchListenerCount as vt, reachableDivergentParameters as w, globMatches as wa, validateContainerRepoName as wi, hasReadableOrphans as wn, __exportAll as wo, STATE_SOURCED_READBACK_RULES as wr, UNSPECIFIED_SKIP_REASON as wt, bindingSkippedOutputs as x, ambientClientDefaults as xa, parseBootstrapMarker as xi, UNREADABLE_RESOURCES_MAP_ROW as xn, retryClassificationText as xo, TemplateParser as xr, CloudControlProvider as xt, keptWholeReasonText as y, canonicalizeRegion as ya, getBootstrapMarkerKey as yi, STATE_RESOURCES_MALFORMED as yn, markNonRetryable as yo, withRetry as yr, isInterruptedWaitError as yt, isStatefulRecreateTargetForReplace as z, resetAwsClients as za, runDockerForeground as zi, malformedRenderedContainersWarning as zn, recoverMaskedOutput as zr, parameterTypeMayLoseSecretIdentity as zt };
|
|
52425
|
+
//# sourceMappingURL=deploy-engine-CkF6PyFY.js.map
|