@go-to-k/cdkd 0.94.10 → 0.94.12

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.
@@ -5377,6 +5377,11 @@ var IntrinsicFunctionResolver = class {
5377
5377
  case "Arn": return `arn:${partition}:logs:${region}:${accountId}:log-group:${physicalId}:*`;
5378
5378
  default: return physicalId;
5379
5379
  }
5380
+ if (resourceType === "AWS::ECR::Repository") switch (attributeName) {
5381
+ case "Arn": return `arn:${partition}:ecr:${region}:${accountId}:repository/${physicalId}`;
5382
+ case "RepositoryUri": return `${accountId}.dkr.ecr.${region}.amazonaws.com/${physicalId}`;
5383
+ default: return physicalId;
5384
+ }
5380
5385
  if (resourceType === "AWS::ECS::Cluster") switch (attributeName) {
5381
5386
  case "Arn": return `arn:${partition}:ecs:${region}:${accountId}:cluster/${physicalId}`;
5382
5387
  default: return physicalId;
@@ -7698,7 +7703,7 @@ var IAMRoleProvider = class {
7698
7703
  *
7699
7704
  * Returns `undefined` when the role is gone (`NoSuchEntityException`).
7700
7705
  */
7701
- async readCurrentState(physicalId, _logicalId, _resourceType, properties) {
7706
+ async readCurrentState(physicalId, _logicalId, _resourceType, properties, context) {
7702
7707
  let role;
7703
7708
  try {
7704
7709
  role = (await this.iamClient.send(new GetRoleCommand({ RoleName: physicalId }))).Role;
@@ -7735,8 +7740,10 @@ var IAMRoleProvider = class {
7735
7740
  if (!listResp.IsTruncated) break;
7736
7741
  policyMarker = listResp.Marker;
7737
7742
  }
7743
+ const managedByOtherResource = collectInlinePolicyNamesManagedBySiblings(physicalId, context, "Roles");
7744
+ const filteredNames = policyNames.filter((n) => !managedByOtherResource.has(n));
7738
7745
  const bodies = /* @__PURE__ */ new Map();
7739
- await Promise.all(policyNames.map(async (name) => {
7746
+ await Promise.all(filteredNames.map(async (name) => {
7740
7747
  const resp = await this.iamClient.send(new GetRolePolicyCommand({
7741
7748
  RoleName: physicalId,
7742
7749
  PolicyName: name
@@ -7839,6 +7846,49 @@ var IAMRoleProvider = class {
7839
7846
  return null;
7840
7847
  }
7841
7848
  };
7849
+ /**
7850
+ * Issue #323: build the set of inline-policy names that are managed by
7851
+ * a sibling `AWS::IAM::Policy` resource in the same stack via the given
7852
+ * attachment field (`Roles` / `Users` / `Groups`). cdkd's IAM Role /
7853
+ * User / Group `readCurrentState` helpers exclude these from
7854
+ * `ListRolePolicies` / `ListUserPolicies` / `ListGroupPolicies` output
7855
+ * to avoid false drift — the inline policy is faithfully managed by
7856
+ * the sibling `AWS::IAM::Policy` resource, not the role/user/group
7857
+ * itself. The CDK patterns that produce this shape are pervasive:
7858
+ * `role.addToPolicy(...)`, `taskRole.addToPolicy(...)`,
7859
+ * `bucket.grantRead(role)`, `ContainerImage.fromEcrRepository(repo)`'s
7860
+ * execution-role grant, every L2-construct's auto-emitted `Default
7861
+ * Policy*`.
7862
+ *
7863
+ * @param targetPhysicalId The physicalId of the role/user/group being
7864
+ * read (matches values in the sibling's
7865
+ * `Properties.Roles` / `Users` / `Groups`).
7866
+ * @param context Cross-resource context (may be `undefined`
7867
+ * for callers that don't supply it — e.g.
7868
+ * deploy-time observed-capture before state
7869
+ * is complete; the filter then no-ops which
7870
+ * is safe because the sibling's
7871
+ * `PutRolePolicy` hasn't fired yet at that
7872
+ * point).
7873
+ * @param attachmentField Which sibling field to inspect: `'Roles'`,
7874
+ * `'Users'`, or `'Groups'`.
7875
+ * @returns Set of `PolicyName` values to exclude. Empty when no
7876
+ * sibling matches OR when context is undefined.
7877
+ */
7878
+ function collectInlinePolicyNamesManagedBySiblings(targetPhysicalId, context, attachmentField) {
7879
+ const result = /* @__PURE__ */ new Set();
7880
+ const siblings = context?.siblings;
7881
+ if (!siblings) return result;
7882
+ for (const sibling of Object.values(siblings)) {
7883
+ if (sibling.resourceType !== "AWS::IAM::Policy") continue;
7884
+ const attachments = sibling.properties[attachmentField];
7885
+ if (!Array.isArray(attachments)) continue;
7886
+ if (!attachments.some((a) => a === targetPhysicalId)) continue;
7887
+ const name = sibling.properties["PolicyName"];
7888
+ if (typeof name === "string") result.add(name);
7889
+ }
7890
+ return result;
7891
+ }
7842
7892
 
7843
7893
  //#endregion
7844
7894
  //#region src/deployment/dag-executor.ts
@@ -8266,10 +8316,10 @@ var DeployEngine = class {
8266
8316
  * the merge step, which is fine: drift falls back to comparing
8267
8317
  * against `properties`.
8268
8318
  */
8269
- kickOffObservedCapture(provider, logicalId, physicalId, resourceType, resolvedProps) {
8319
+ kickOffObservedCapture(provider, logicalId, physicalId, resourceType, resolvedProps, context) {
8270
8320
  if (this.options.captureObservedState !== true) return;
8271
8321
  if (!provider.readCurrentState) return;
8272
- const promise = provider.readCurrentState(physicalId, logicalId, resourceType, resolvedProps).catch((err) => {
8322
+ const promise = provider.readCurrentState(physicalId, logicalId, resourceType, resolvedProps, context).catch((err) => {
8273
8323
  this.logger.debug(`observedProperties capture for ${logicalId} (${resourceType}) failed: ${err instanceof Error ? err.message : String(err)} — drift will fall back to template properties for this resource until the next successful deploy.`);
8274
8324
  });
8275
8325
  this.observedCaptureTasks.set(logicalId, promise);
@@ -8332,6 +8382,11 @@ var DeployEngine = class {
8332
8382
  });
8333
8383
  }
8334
8384
  if (candidates.length === 0) return;
8385
+ const allSiblings = {};
8386
+ for (const [lid, res] of Object.entries(stateResources)) allSiblings[lid] = {
8387
+ resourceType: res.resourceType,
8388
+ properties: res.properties ?? {}
8389
+ };
8335
8390
  for (const { logicalId, resource } of candidates) {
8336
8391
  let provider;
8337
8392
  try {
@@ -8340,7 +8395,9 @@ var DeployEngine = class {
8340
8395
  continue;
8341
8396
  }
8342
8397
  if (!provider.readCurrentState) continue;
8343
- this.kickOffObservedCapture(provider, logicalId, resource.physicalId, resource.resourceType, resource.properties ?? {});
8398
+ const siblings = { ...allSiblings };
8399
+ delete siblings[logicalId];
8400
+ this.kickOffObservedCapture(provider, logicalId, resource.physicalId, resource.resourceType, resource.properties ?? {}, { siblings });
8344
8401
  toRefresh++;
8345
8402
  }
8346
8403
  if (toRefresh > 0) this.logger.warn(`cdkd state schema upgrade detected — refreshing observed-properties baseline for ${toRefresh} resource(s) (one-time, runs in parallel with deploy)`);
@@ -9179,5 +9236,5 @@ var DeployEngine = class {
9179
9236
  };
9180
9237
 
9181
9238
  //#endregion
9182
- export { normalizeAwsError as $, resolveSkipPrefix as A, DependencyError as B, WorkGraph as C, getLegacyStateBucketName as D, getDefaultStateBucketName as E, clearBucketRegionCache as F, ResourceTimeoutError as G, LockError as H, resolveBucketRegion as I, StackTerminationProtectionError as J, ResourceUpdateNotSupportedError as K, AssetError as L, resolveStateBucketWithDefaultAndSource as M, warnDeprecatedNoPrefixCliFlag as N, resolveApp as O, AssemblyReader as P, isCdkdError as Q, CdkdError as R, stringifyValue as S, Synthesizer as T, PartialFailureError as U, LocalInvokeBuildError as V, ProvisioningError as W, SynthesisError as X, StateError as Y, formatError as Z, DagBuilder as _, withRetry as a, getLiveRenderer as at, S3StateBackend as b, CDK_PATH_TAG as c, generateResourceName as ct, resolveExplicitPhysicalId as d, withStackName as dt, withErrorHandling as et, ProviderRegistry as f, DiffCalculator as g, IntrinsicFunctionResolver as h, withResourceDeadline as i, runStackBuffered as it, resolveStateBucketWithDefault as j, resolveCaptureObservedState as k, matchesCdkPath as l, generateResourceNameWithFallback as lt, assertRegionMatch as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, getLogger as nt, IMPLICIT_DELETE_DEPENDENCIES as o, PATTERN_B_NAME_PROPERTIES as ot, CloudControlProvider as p, RouteDiscoveryError as q, DeployEngine as r, setLogger as rt, IAMRoleProvider as s, PATTERN_B_RESOURCE_TYPES as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, ConsoleLogger as tt, normalizeAwsTagsToCfn as u, withSkipPrefix as ut, TemplateParser as v, buildDockerImage as w, AssetPublisher as x, LockManager as y, ConfigError as z };
9183
- //# sourceMappingURL=deploy-engine-Cg4l-zyr.js.map
9239
+ export { isCdkdError as $, resolveCaptureObservedState as A, ConfigError as B, stringifyValue as C, getDefaultStateBucketName as D, Synthesizer as E, AssemblyReader as F, ProvisioningError as G, LocalInvokeBuildError as H, clearBucketRegionCache as I, RouteDiscoveryError as J, ResourceTimeoutError as K, resolveBucketRegion as L, resolveStateBucketWithDefault as M, resolveStateBucketWithDefaultAndSource as N, getLegacyStateBucketName as O, warnDeprecatedNoPrefixCliFlag as P, formatError as Q, AssetError as R, AssetPublisher as S, buildDockerImage as T, LockError as U, DependencyError as V, PartialFailureError as W, StateError as X, StackTerminationProtectionError as Y, SynthesisError as Z, DiffCalculator as _, withRetry as a, runStackBuffered as at, LockManager as b, collectInlinePolicyNamesManagedBySiblings as c, PATTERN_B_RESOURCE_TYPES as ct, normalizeAwsTagsToCfn as d, withSkipPrefix as dt, normalizeAwsError as et, resolveExplicitPhysicalId as f, withStackName as ft, IntrinsicFunctionResolver as g, assertRegionMatch as h, withResourceDeadline as i, setLogger as it, resolveSkipPrefix as j, resolveApp as k, CDK_PATH_TAG as l, generateResourceName as lt, CloudControlProvider as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, ConsoleLogger as nt, IMPLICIT_DELETE_DEPENDENCIES as o, getLiveRenderer as ot, ProviderRegistry as p, ResourceUpdateNotSupportedError as q, DeployEngine as r, getLogger as rt, IAMRoleProvider as s, PATTERN_B_NAME_PROPERTIES as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, withErrorHandling as tt, matchesCdkPath as u, generateResourceNameWithFallback as ut, DagBuilder as v, WorkGraph as w, S3StateBackend as x, TemplateParser as y, CdkdError as z };
9240
+ //# sourceMappingURL=deploy-engine-SarGY6-L.js.map