@go-to-k/cdkd 0.51.0 → 0.51.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/dist/cli.js +431 -111
- package/dist/cli.js.map +3 -3
- package/dist/go-to-k-cdkd-0.51.1.tgz +0 -0
- package/dist/index.js +75 -26
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.51.0.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -8481,6 +8481,7 @@ import {
|
|
|
8481
8481
|
UpdateAssumeRolePolicyCommand,
|
|
8482
8482
|
DeleteRoleCommand,
|
|
8483
8483
|
GetRoleCommand,
|
|
8484
|
+
GetRolePolicyCommand,
|
|
8484
8485
|
PutRolePolicyCommand,
|
|
8485
8486
|
DeleteRolePolicyCommand,
|
|
8486
8487
|
ListRolePoliciesCommand,
|
|
@@ -9093,8 +9094,14 @@ var IAMRoleProvider = class {
|
|
|
9093
9094
|
* against state's already-parsed object.
|
|
9094
9095
|
*
|
|
9095
9096
|
* Coverage and shape decisions:
|
|
9096
|
-
* - `RoleName`, `Description`, `MaxSessionDuration`, `Path
|
|
9097
|
-
*
|
|
9097
|
+
* - `RoleName`, `Description`, `MaxSessionDuration`, `Path` — straight
|
|
9098
|
+
* from `Role.*`.
|
|
9099
|
+
* - `PermissionsBoundary` — emitted as `'' ` placeholder when AWS has
|
|
9100
|
+
* none, so a console-side ADD on a role that was deployed without a
|
|
9101
|
+
* boundary surfaces as drift. (The drift comparator's top-level walk
|
|
9102
|
+
* is state-keys-only; without the always-emit placeholder a fresh
|
|
9103
|
+
* `PermissionsBoundary` on the AWS side would never enter
|
|
9104
|
+
* `observedProperties` and the comparator would silently ignore it.)
|
|
9098
9105
|
* - `AssumeRolePolicyDocument` — `Role.AssumeRolePolicyDocument` is a
|
|
9099
9106
|
* URL-encoded JSON string; we URL-decode + JSON-parse so cdkd state's
|
|
9100
9107
|
* object form compares cleanly. (Both shapes — string and object — are
|
|
@@ -9102,20 +9109,23 @@ var IAMRoleProvider = class {
|
|
|
9102
9109
|
* after intrinsic resolution.)
|
|
9103
9110
|
* - `ManagedPolicyArns` — array of ARN strings from
|
|
9104
9111
|
* `ListAttachedRolePolicies`.
|
|
9105
|
-
* - `Policies`
|
|
9106
|
-
*
|
|
9107
|
-
*
|
|
9108
|
-
*
|
|
9109
|
-
*
|
|
9110
|
-
*
|
|
9112
|
+
* - `Policies` — inline policies surfaced as `[{PolicyName, PolicyDocument}]`.
|
|
9113
|
+
* `ListRolePolicies` for names + `GetRolePolicy` per name for the
|
|
9114
|
+
* body (URL-decoded + JSON-parsed). Ordering is reconciled against
|
|
9115
|
+
* state's `Policies` array (when supplied via the `properties`
|
|
9116
|
+
* parameter) so a state-vs-AWS positional compare doesn't fire false
|
|
9117
|
+
* drift purely from `ListRolePolicies` returning lexicographic order;
|
|
9118
|
+
* AWS-only policies (added via console) are appended at the end so
|
|
9119
|
+
* they still surface as drift via length / content mismatch.
|
|
9111
9120
|
* - `Tags` is surfaced via `ListRoleTags` (paginated). CDK's `aws:*`
|
|
9112
9121
|
* auto-tags are filtered out by `normalizeAwsTagsToCfn` so they don't
|
|
9113
|
-
* fire false-positive drift;
|
|
9114
|
-
*
|
|
9122
|
+
* fire false-positive drift; always emitted (even when empty) so a
|
|
9123
|
+
* console-side tag ADD on an originally-untagged role surfaces as
|
|
9124
|
+
* drift on the v3 observedProperties baseline.
|
|
9115
9125
|
*
|
|
9116
9126
|
* Returns `undefined` when the role is gone (`NoSuchEntityException`).
|
|
9117
9127
|
*/
|
|
9118
|
-
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
9128
|
+
async readCurrentState(physicalId, _logicalId, _resourceType, properties) {
|
|
9119
9129
|
let role;
|
|
9120
9130
|
try {
|
|
9121
9131
|
const resp = await this.iamClient.send(new GetRoleCommand({ RoleName: physicalId }));
|
|
@@ -9136,9 +9146,7 @@ var IAMRoleProvider = class {
|
|
|
9136
9146
|
}
|
|
9137
9147
|
if (role.Path !== void 0)
|
|
9138
9148
|
result["Path"] = role.Path;
|
|
9139
|
-
|
|
9140
|
-
result["PermissionsBoundary"] = role.PermissionsBoundary.PermissionsBoundaryArn;
|
|
9141
|
-
}
|
|
9149
|
+
result["PermissionsBoundary"] = role.PermissionsBoundary?.PermissionsBoundaryArn ?? "";
|
|
9142
9150
|
if (role.AssumeRolePolicyDocument) {
|
|
9143
9151
|
try {
|
|
9144
9152
|
result["AssumeRolePolicyDocument"] = JSON.parse(
|
|
@@ -9158,6 +9166,59 @@ var IAMRoleProvider = class {
|
|
|
9158
9166
|
if (!(err instanceof NoSuchEntityException))
|
|
9159
9167
|
throw err;
|
|
9160
9168
|
}
|
|
9169
|
+
try {
|
|
9170
|
+
const policyNames = [];
|
|
9171
|
+
let policyMarker;
|
|
9172
|
+
while (true) {
|
|
9173
|
+
const listResp = await this.iamClient.send(
|
|
9174
|
+
new ListRolePoliciesCommand({
|
|
9175
|
+
RoleName: physicalId,
|
|
9176
|
+
...policyMarker ? { Marker: policyMarker } : {}
|
|
9177
|
+
})
|
|
9178
|
+
);
|
|
9179
|
+
for (const name of listResp.PolicyNames ?? [])
|
|
9180
|
+
policyNames.push(name);
|
|
9181
|
+
if (!listResp.IsTruncated)
|
|
9182
|
+
break;
|
|
9183
|
+
policyMarker = listResp.Marker;
|
|
9184
|
+
}
|
|
9185
|
+
const bodies = /* @__PURE__ */ new Map();
|
|
9186
|
+
await Promise.all(
|
|
9187
|
+
policyNames.map(async (name) => {
|
|
9188
|
+
const resp = await this.iamClient.send(
|
|
9189
|
+
new GetRolePolicyCommand({ RoleName: physicalId, PolicyName: name })
|
|
9190
|
+
);
|
|
9191
|
+
if (!resp.PolicyDocument)
|
|
9192
|
+
return;
|
|
9193
|
+
let parsed;
|
|
9194
|
+
try {
|
|
9195
|
+
parsed = JSON.parse(decodeURIComponent(resp.PolicyDocument));
|
|
9196
|
+
} catch {
|
|
9197
|
+
parsed = resp.PolicyDocument;
|
|
9198
|
+
}
|
|
9199
|
+
bodies.set(name, parsed);
|
|
9200
|
+
})
|
|
9201
|
+
);
|
|
9202
|
+
const statePolicies = properties?.["Policies"] ?? [];
|
|
9203
|
+
const remaining = new Set(bodies.keys());
|
|
9204
|
+
const inline = [];
|
|
9205
|
+
for (const sp of statePolicies) {
|
|
9206
|
+
const name = sp?.PolicyName;
|
|
9207
|
+
if (typeof name !== "string")
|
|
9208
|
+
continue;
|
|
9209
|
+
if (bodies.has(name)) {
|
|
9210
|
+
inline.push({ PolicyName: name, PolicyDocument: bodies.get(name) });
|
|
9211
|
+
remaining.delete(name);
|
|
9212
|
+
}
|
|
9213
|
+
}
|
|
9214
|
+
for (const name of [...remaining].sort()) {
|
|
9215
|
+
inline.push({ PolicyName: name, PolicyDocument: bodies.get(name) });
|
|
9216
|
+
}
|
|
9217
|
+
result["Policies"] = inline;
|
|
9218
|
+
} catch (err) {
|
|
9219
|
+
if (!(err instanceof NoSuchEntityException))
|
|
9220
|
+
throw err;
|
|
9221
|
+
}
|
|
9161
9222
|
try {
|
|
9162
9223
|
const collected = [];
|
|
9163
9224
|
let marker;
|
|
@@ -9185,18 +9246,6 @@ var IAMRoleProvider = class {
|
|
|
9185
9246
|
}
|
|
9186
9247
|
return result;
|
|
9187
9248
|
}
|
|
9188
|
-
/**
|
|
9189
|
-
* `Policies` (inline policy bodies) are intentionally omitted from
|
|
9190
|
-
* `readCurrentState`: surfacing the names without bodies would
|
|
9191
|
-
* guarantee a `PolicyDocument`-shaped drift on every role, and
|
|
9192
|
-
* fetching every body costs one extra `GetRolePolicy` per inline
|
|
9193
|
-
* policy. Tell the drift comparator to skip the whole subtree until a
|
|
9194
|
-
* dedicated PR adds proper inline-policy drift via per-name
|
|
9195
|
-
* `GetRolePolicy`.
|
|
9196
|
-
*/
|
|
9197
|
-
getDriftUnknownPaths() {
|
|
9198
|
-
return ["Policies"];
|
|
9199
|
-
}
|
|
9200
9249
|
/**
|
|
9201
9250
|
* Adopt an existing IAM role into cdkd state.
|
|
9202
9251
|
*
|
|
@@ -9259,7 +9308,7 @@ import {
|
|
|
9259
9308
|
DeleteGroupPolicyCommand,
|
|
9260
9309
|
PutUserPolicyCommand,
|
|
9261
9310
|
DeleteUserPolicyCommand,
|
|
9262
|
-
GetRolePolicyCommand,
|
|
9311
|
+
GetRolePolicyCommand as GetRolePolicyCommand2,
|
|
9263
9312
|
GetGroupPolicyCommand,
|
|
9264
9313
|
GetUserPolicyCommand,
|
|
9265
9314
|
NoSuchEntityException as NoSuchEntityException2
|
|
@@ -9648,7 +9697,7 @@ var IAMPolicyProvider = class {
|
|
|
9648
9697
|
try {
|
|
9649
9698
|
if (roles && roles.length > 0) {
|
|
9650
9699
|
const resp = await this.iamClient.send(
|
|
9651
|
-
new
|
|
9700
|
+
new GetRolePolicyCommand2({ RoleName: roles[0], PolicyName: policyName })
|
|
9652
9701
|
);
|
|
9653
9702
|
liveDocument = this.decodePolicyDocument(resp.PolicyDocument);
|
|
9654
9703
|
} else if (groups && groups.length > 0) {
|
|
@@ -10023,9 +10072,11 @@ import {
|
|
|
10023
10072
|
PutUserPolicyCommand as PutUserPolicyCommand2,
|
|
10024
10073
|
DeleteUserPolicyCommand as DeleteUserPolicyCommand2,
|
|
10025
10074
|
ListUserPoliciesCommand,
|
|
10075
|
+
GetUserPolicyCommand as GetUserPolicyCommand2,
|
|
10026
10076
|
PutGroupPolicyCommand as PutGroupPolicyCommand2,
|
|
10027
10077
|
DeleteGroupPolicyCommand as DeleteGroupPolicyCommand2,
|
|
10028
10078
|
ListGroupPoliciesCommand,
|
|
10079
|
+
GetGroupPolicyCommand as GetGroupPolicyCommand2,
|
|
10029
10080
|
CreateLoginProfileCommand,
|
|
10030
10081
|
UpdateLoginProfileCommand,
|
|
10031
10082
|
AddUserToGroupCommand,
|
|
@@ -11052,17 +11103,21 @@ var IAMUserGroupProvider = class {
|
|
|
11052
11103
|
* UserToGroupAddition in CFn-property shape.
|
|
11053
11104
|
*
|
|
11054
11105
|
* - **AWS::IAM::User**: `GetUser` for `UserName`, `Path`,
|
|
11055
|
-
* `PermissionsBoundary` (re-shaped from `PermissionsBoundary.Arn
|
|
11106
|
+
* `PermissionsBoundary` (re-shaped from `PermissionsBoundary.Arn`,
|
|
11107
|
+
* always-emit `''` placeholder so console-side ADD on a user
|
|
11108
|
+
* deployed without a boundary surfaces as drift);
|
|
11056
11109
|
* `ListAttachedUserPolicies` for `ManagedPolicyArns`;
|
|
11057
|
-
* `ListGroupsForUser` for `Groups
|
|
11058
|
-
* `
|
|
11059
|
-
*
|
|
11060
|
-
*
|
|
11061
|
-
*
|
|
11110
|
+
* `ListGroupsForUser` for `Groups`; `ListUserPolicies` +
|
|
11111
|
+
* `GetUserPolicy` per name for inline `Policies` (URL-decoded +
|
|
11112
|
+
* JSON-parsed, capped at IAM's documented 10-per-user limit, order
|
|
11113
|
+
* reconciled against state's `Policies` array). `Tags` and
|
|
11114
|
+
* `LoginProfile` remain omitted — Tags will land in a follow-up,
|
|
11115
|
+
* LoginProfile contains a one-time password we never want to surface
|
|
11116
|
+
* through drift.
|
|
11062
11117
|
* - **AWS::IAM::Group**: `GetGroup` for `GroupName`, `Path`;
|
|
11063
|
-
* `ListAttachedGroupPolicies` for `ManagedPolicyArns
|
|
11064
|
-
*
|
|
11065
|
-
*
|
|
11118
|
+
* `ListAttachedGroupPolicies` for `ManagedPolicyArns`;
|
|
11119
|
+
* `ListGroupPolicies` + `GetGroupPolicy` per name for inline
|
|
11120
|
+
* `Policies`.
|
|
11066
11121
|
* - **AWS::IAM::UserToGroupAddition**: SKIPPED — returns `undefined`
|
|
11067
11122
|
* because the resource is metadata-only (group-membership attachments
|
|
11068
11123
|
* written via `AddUserToGroup`). A meaningful drift check would
|
|
@@ -11074,12 +11129,12 @@ var IAMUserGroupProvider = class {
|
|
|
11074
11129
|
* Returns `undefined` when the user / group is gone
|
|
11075
11130
|
* (`NoSuchEntityException`).
|
|
11076
11131
|
*/
|
|
11077
|
-
async readCurrentState(physicalId, logicalId, resourceType) {
|
|
11132
|
+
async readCurrentState(physicalId, logicalId, resourceType, properties) {
|
|
11078
11133
|
switch (resourceType) {
|
|
11079
11134
|
case "AWS::IAM::User":
|
|
11080
|
-
return this.readUserCurrentState(physicalId);
|
|
11135
|
+
return this.readUserCurrentState(physicalId, properties);
|
|
11081
11136
|
case "AWS::IAM::Group":
|
|
11082
|
-
return this.readGroupCurrentState(physicalId);
|
|
11137
|
+
return this.readGroupCurrentState(physicalId, properties);
|
|
11083
11138
|
case "AWS::IAM::UserToGroupAddition":
|
|
11084
11139
|
return void 0;
|
|
11085
11140
|
default:
|
|
@@ -11089,7 +11144,7 @@ var IAMUserGroupProvider = class {
|
|
|
11089
11144
|
return void 0;
|
|
11090
11145
|
}
|
|
11091
11146
|
}
|
|
11092
|
-
async readUserCurrentState(physicalId) {
|
|
11147
|
+
async readUserCurrentState(physicalId, properties) {
|
|
11093
11148
|
let user;
|
|
11094
11149
|
try {
|
|
11095
11150
|
const resp = await this.iamClient.send(new GetUserCommand({ UserName: physicalId }));
|
|
@@ -11106,9 +11161,7 @@ var IAMUserGroupProvider = class {
|
|
|
11106
11161
|
result["UserName"] = user.UserName;
|
|
11107
11162
|
if (user.Path !== void 0)
|
|
11108
11163
|
result["Path"] = user.Path;
|
|
11109
|
-
|
|
11110
|
-
result["PermissionsBoundary"] = user.PermissionsBoundary.PermissionsBoundaryArn;
|
|
11111
|
-
}
|
|
11164
|
+
result["PermissionsBoundary"] = user.PermissionsBoundary?.PermissionsBoundaryArn ?? "";
|
|
11112
11165
|
try {
|
|
11113
11166
|
const attached = await this.iamClient.send(
|
|
11114
11167
|
new ListAttachedUserPoliciesCommand({ UserName: physicalId })
|
|
@@ -11129,9 +11182,20 @@ var IAMUserGroupProvider = class {
|
|
|
11129
11182
|
if (!(err instanceof NoSuchEntityException4))
|
|
11130
11183
|
throw err;
|
|
11131
11184
|
}
|
|
11185
|
+
try {
|
|
11186
|
+
const inline = await this.collectInlinePolicies(
|
|
11187
|
+
"user",
|
|
11188
|
+
physicalId,
|
|
11189
|
+
properties?.["Policies"] ?? []
|
|
11190
|
+
);
|
|
11191
|
+
result["Policies"] = inline;
|
|
11192
|
+
} catch (err) {
|
|
11193
|
+
if (!(err instanceof NoSuchEntityException4))
|
|
11194
|
+
throw err;
|
|
11195
|
+
}
|
|
11132
11196
|
return result;
|
|
11133
11197
|
}
|
|
11134
|
-
async readGroupCurrentState(physicalId) {
|
|
11198
|
+
async readGroupCurrentState(physicalId, properties) {
|
|
11135
11199
|
let group;
|
|
11136
11200
|
try {
|
|
11137
11201
|
const resp = await this.iamClient.send(new GetGroupCommand({ GroupName: physicalId }));
|
|
@@ -11158,8 +11222,83 @@ var IAMUserGroupProvider = class {
|
|
|
11158
11222
|
if (!(err instanceof NoSuchEntityException4))
|
|
11159
11223
|
throw err;
|
|
11160
11224
|
}
|
|
11225
|
+
try {
|
|
11226
|
+
const inline = await this.collectInlinePolicies(
|
|
11227
|
+
"group",
|
|
11228
|
+
physicalId,
|
|
11229
|
+
properties?.["Policies"] ?? []
|
|
11230
|
+
);
|
|
11231
|
+
result["Policies"] = inline;
|
|
11232
|
+
} catch (err) {
|
|
11233
|
+
if (!(err instanceof NoSuchEntityException4))
|
|
11234
|
+
throw err;
|
|
11235
|
+
}
|
|
11161
11236
|
return result;
|
|
11162
11237
|
}
|
|
11238
|
+
/**
|
|
11239
|
+
* Shared inline-policy fetcher for User / Group readCurrentState.
|
|
11240
|
+
* Mirrors `IAMRoleProvider.readCurrentState`'s inline-policy handling:
|
|
11241
|
+
* paginated `List*Policies` for names → parallel `Get*Policy` per name
|
|
11242
|
+
* for bodies (URL-decoded + JSON-parsed) → reconcile order against
|
|
11243
|
+
* `statePolicies` so a positional compare doesn't fire false drift on
|
|
11244
|
+
* the lexicographic order returned by AWS.
|
|
11245
|
+
*/
|
|
11246
|
+
async collectInlinePolicies(kind, physicalId, statePolicies) {
|
|
11247
|
+
const policyNames = [];
|
|
11248
|
+
let marker;
|
|
11249
|
+
while (true) {
|
|
11250
|
+
const listResp = kind === "user" ? await this.iamClient.send(
|
|
11251
|
+
new ListUserPoliciesCommand({
|
|
11252
|
+
UserName: physicalId,
|
|
11253
|
+
...marker ? { Marker: marker } : {}
|
|
11254
|
+
})
|
|
11255
|
+
) : await this.iamClient.send(
|
|
11256
|
+
new ListGroupPoliciesCommand({
|
|
11257
|
+
GroupName: physicalId,
|
|
11258
|
+
...marker ? { Marker: marker } : {}
|
|
11259
|
+
})
|
|
11260
|
+
);
|
|
11261
|
+
for (const name of listResp.PolicyNames ?? [])
|
|
11262
|
+
policyNames.push(name);
|
|
11263
|
+
if (!listResp.IsTruncated)
|
|
11264
|
+
break;
|
|
11265
|
+
marker = listResp.Marker;
|
|
11266
|
+
}
|
|
11267
|
+
const bodies = /* @__PURE__ */ new Map();
|
|
11268
|
+
await Promise.all(
|
|
11269
|
+
policyNames.map(async (name) => {
|
|
11270
|
+
const resp = kind === "user" ? await this.iamClient.send(
|
|
11271
|
+
new GetUserPolicyCommand2({ UserName: physicalId, PolicyName: name })
|
|
11272
|
+
) : await this.iamClient.send(
|
|
11273
|
+
new GetGroupPolicyCommand2({ GroupName: physicalId, PolicyName: name })
|
|
11274
|
+
);
|
|
11275
|
+
if (!resp.PolicyDocument)
|
|
11276
|
+
return;
|
|
11277
|
+
let parsed;
|
|
11278
|
+
try {
|
|
11279
|
+
parsed = JSON.parse(decodeURIComponent(resp.PolicyDocument));
|
|
11280
|
+
} catch {
|
|
11281
|
+
parsed = resp.PolicyDocument;
|
|
11282
|
+
}
|
|
11283
|
+
bodies.set(name, parsed);
|
|
11284
|
+
})
|
|
11285
|
+
);
|
|
11286
|
+
const remaining = new Set(bodies.keys());
|
|
11287
|
+
const inline = [];
|
|
11288
|
+
for (const sp of statePolicies) {
|
|
11289
|
+
const name = sp?.PolicyName;
|
|
11290
|
+
if (typeof name !== "string")
|
|
11291
|
+
continue;
|
|
11292
|
+
if (bodies.has(name)) {
|
|
11293
|
+
inline.push({ PolicyName: name, PolicyDocument: bodies.get(name) });
|
|
11294
|
+
remaining.delete(name);
|
|
11295
|
+
}
|
|
11296
|
+
}
|
|
11297
|
+
for (const name of [...remaining].sort()) {
|
|
11298
|
+
inline.push({ PolicyName: name, PolicyDocument: bodies.get(name) });
|
|
11299
|
+
}
|
|
11300
|
+
return inline;
|
|
11301
|
+
}
|
|
11163
11302
|
// ─── Import dispatch ──────────────────────────────────────────────
|
|
11164
11303
|
/**
|
|
11165
11304
|
* Adopt an existing IAM user / group / user-to-group addition into cdkd state.
|
|
@@ -16867,6 +17006,7 @@ import {
|
|
|
16867
17006
|
CreateLogGroupCommand,
|
|
16868
17007
|
DeleteLogGroupCommand,
|
|
16869
17008
|
DescribeLogGroupsCommand,
|
|
17009
|
+
GetDataProtectionPolicyCommand,
|
|
16870
17010
|
ListTagsForResourceCommand as ListTagsForResourceCommand2,
|
|
16871
17011
|
PutRetentionPolicyCommand,
|
|
16872
17012
|
DeleteRetentionPolicyCommand,
|
|
@@ -17108,19 +17248,6 @@ var LogsLogGroupProvider = class {
|
|
|
17108
17248
|
}
|
|
17109
17249
|
return this.buildArn(physicalId);
|
|
17110
17250
|
}
|
|
17111
|
-
/**
|
|
17112
|
-
* Drift comparator skip-list: properties readCurrentState deliberately
|
|
17113
|
-
* cannot round-trip from AWS yet. `DataProtectionPolicy` lives behind
|
|
17114
|
-
* its own `GetDataProtectionPolicy` API call (not in
|
|
17115
|
-
* `DescribeLogGroups` output) — declaring it here prevents
|
|
17116
|
-
* guaranteed false-positive drift on every clean run for log groups
|
|
17117
|
-
* deployed with a data-protection policy. Lifting this guard requires
|
|
17118
|
-
* a per-group `GetDataProtectionPolicy` round-trip in
|
|
17119
|
-
* `readCurrentState`.
|
|
17120
|
-
*/
|
|
17121
|
-
getDriftUnknownPaths() {
|
|
17122
|
-
return ["DataProtectionPolicy"];
|
|
17123
|
-
}
|
|
17124
17251
|
/**
|
|
17125
17252
|
* Read the AWS-current log group configuration in CFn-property shape.
|
|
17126
17253
|
*
|
|
@@ -17131,10 +17258,16 @@ var LogsLogGroupProvider = class {
|
|
|
17131
17258
|
* `RetentionInDays`).
|
|
17132
17259
|
*
|
|
17133
17260
|
* Coverage: `LogGroupName`, `KmsKeyId`, `RetentionInDays`,
|
|
17134
|
-
* `LogGroupClass`, `Tags
|
|
17135
|
-
* `
|
|
17136
|
-
*
|
|
17137
|
-
*
|
|
17261
|
+
* `LogGroupClass`, `Tags`, plus `DataProtectionPolicy` (via
|
|
17262
|
+
* `GetDataProtectionPolicy`, JSON-parsed back to the object form
|
|
17263
|
+
* cdkd state holds). Still out of scope: `FieldIndexPolicies`
|
|
17264
|
+
* (separate `DescribeFieldIndexPolicies` call, follow-up),
|
|
17265
|
+
* `ResourcePolicyDocument` (managed by the separate
|
|
17266
|
+
* `AWS::Logs::ResourcePolicy` resource type — account-wide, not
|
|
17267
|
+
* per-log-group), `DeletionProtectionEnabled` (not surfaced by
|
|
17268
|
+
* `DescribeLogGroups`; would need a yet-undocumented separate API),
|
|
17269
|
+
* `BearerTokenAuthenticationEnabled` (specialized X-Ray / service-log
|
|
17270
|
+
* endpoint feature, also not in `DescribeLogGroups`).
|
|
17138
17271
|
*
|
|
17139
17272
|
* Tags are read via `ListTagsForResource` (using the log-group ARN from
|
|
17140
17273
|
* the same `DescribeLogGroups` response). CDK's `aws:*` auto-tags are
|
|
@@ -17173,6 +17306,21 @@ var LogsLogGroupProvider = class {
|
|
|
17173
17306
|
}
|
|
17174
17307
|
}
|
|
17175
17308
|
result["Tags"] = tags;
|
|
17309
|
+
let dpp = "";
|
|
17310
|
+
try {
|
|
17311
|
+
const dppResp = await this.logsClient.send(
|
|
17312
|
+
new GetDataProtectionPolicyCommand({ logGroupIdentifier: physicalId })
|
|
17313
|
+
);
|
|
17314
|
+
if (dppResp.policyDocument) {
|
|
17315
|
+
try {
|
|
17316
|
+
dpp = JSON.parse(dppResp.policyDocument);
|
|
17317
|
+
} catch {
|
|
17318
|
+
dpp = dppResp.policyDocument;
|
|
17319
|
+
}
|
|
17320
|
+
}
|
|
17321
|
+
} catch {
|
|
17322
|
+
}
|
|
17323
|
+
result["DataProtectionPolicy"] = dpp;
|
|
17176
17324
|
return result;
|
|
17177
17325
|
} catch (err) {
|
|
17178
17326
|
if (err instanceof ResourceNotFoundException7)
|
|
@@ -26406,6 +26554,7 @@ import {
|
|
|
26406
26554
|
CreateLoadBalancerCommand,
|
|
26407
26555
|
DeleteLoadBalancerCommand,
|
|
26408
26556
|
DescribeLoadBalancersCommand as DescribeLoadBalancersCommand2,
|
|
26557
|
+
DescribeLoadBalancerAttributesCommand,
|
|
26409
26558
|
CreateTargetGroupCommand,
|
|
26410
26559
|
DeleteTargetGroupCommand,
|
|
26411
26560
|
ModifyTargetGroupCommand,
|
|
@@ -26498,7 +26647,13 @@ var ELBv2Provider = class {
|
|
|
26498
26647
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
26499
26648
|
switch (resourceType) {
|
|
26500
26649
|
case "AWS::ElasticLoadBalancingV2::LoadBalancer":
|
|
26501
|
-
return this.updateLoadBalancer(
|
|
26650
|
+
return this.updateLoadBalancer(
|
|
26651
|
+
logicalId,
|
|
26652
|
+
physicalId,
|
|
26653
|
+
resourceType,
|
|
26654
|
+
properties,
|
|
26655
|
+
previousProperties
|
|
26656
|
+
);
|
|
26502
26657
|
case "AWS::ElasticLoadBalancingV2::TargetGroup":
|
|
26503
26658
|
return this.updateTargetGroup(
|
|
26504
26659
|
logicalId,
|
|
@@ -26603,14 +26758,44 @@ var ELBv2Provider = class {
|
|
|
26603
26758
|
);
|
|
26604
26759
|
}
|
|
26605
26760
|
}
|
|
26606
|
-
updateLoadBalancer(logicalId,
|
|
26607
|
-
|
|
26608
|
-
|
|
26761
|
+
async updateLoadBalancer(logicalId, physicalId, _resourceType, properties, previousProperties) {
|
|
26762
|
+
const newAttrs = properties["LoadBalancerAttributes"] ?? [];
|
|
26763
|
+
const oldAttrs = previousProperties["LoadBalancerAttributes"] ?? [];
|
|
26764
|
+
const stripAttrs = (p) => {
|
|
26765
|
+
const { LoadBalancerAttributes: _, ...rest } = p;
|
|
26766
|
+
return rest;
|
|
26767
|
+
};
|
|
26768
|
+
if (JSON.stringify(stripAttrs(properties)) !== JSON.stringify(stripAttrs(previousProperties))) {
|
|
26769
|
+
throw new ResourceUpdateNotSupportedError(
|
|
26609
26770
|
"AWS::ElasticLoadBalancingV2::LoadBalancer",
|
|
26610
26771
|
logicalId,
|
|
26611
|
-
"ELBv2 LoadBalancer in-place updates are
|
|
26612
|
-
)
|
|
26613
|
-
|
|
26772
|
+
"ELBv2 LoadBalancer in-place updates are only supported for LoadBalancerAttributes; for Name / Type / Scheme / Subnets / SecurityGroups / IpAddressType / Tags, re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
26773
|
+
);
|
|
26774
|
+
}
|
|
26775
|
+
const newMap = new Map(newAttrs.map((a) => [a.Key, a.Value]));
|
|
26776
|
+
const oldMap = new Map(oldAttrs.map((a) => [a.Key, a.Value]));
|
|
26777
|
+
const submitted = [];
|
|
26778
|
+
for (const [k, v] of newMap) {
|
|
26779
|
+
if (oldMap.get(k) !== v)
|
|
26780
|
+
submitted.push({ Key: k, Value: v });
|
|
26781
|
+
}
|
|
26782
|
+
for (const [k] of oldMap) {
|
|
26783
|
+
if (!newMap.has(k))
|
|
26784
|
+
submitted.push({ Key: k, Value: "" });
|
|
26785
|
+
}
|
|
26786
|
+
if (submitted.length > 0) {
|
|
26787
|
+
const { ModifyLoadBalancerAttributesCommand } = await import("@aws-sdk/client-elastic-load-balancing-v2");
|
|
26788
|
+
await this.getClient().send(
|
|
26789
|
+
new ModifyLoadBalancerAttributesCommand({
|
|
26790
|
+
LoadBalancerArn: physicalId,
|
|
26791
|
+
Attributes: submitted
|
|
26792
|
+
})
|
|
26793
|
+
);
|
|
26794
|
+
this.logger.debug(
|
|
26795
|
+
`Applied ${submitted.length} LoadBalancerAttributes change(s) for ${logicalId}`
|
|
26796
|
+
);
|
|
26797
|
+
}
|
|
26798
|
+
return { physicalId, wasReplaced: false };
|
|
26614
26799
|
}
|
|
26615
26800
|
async deleteLoadBalancer(logicalId, physicalId, resourceType, context) {
|
|
26616
26801
|
this.logger.debug(`Deleting LoadBalancer ${logicalId}: ${physicalId}`);
|
|
@@ -26956,10 +27141,12 @@ var ELBv2Provider = class {
|
|
|
26956
27141
|
* Dispatch per resource type:
|
|
26957
27142
|
* - `LoadBalancer` → `DescribeLoadBalancers` (Name, Subnets via
|
|
26958
27143
|
* `AvailabilityZones[].SubnetId`, SecurityGroups, Scheme, Type,
|
|
26959
|
-
* IpAddressType)
|
|
26960
|
-
*
|
|
26961
|
-
*
|
|
26962
|
-
*
|
|
27144
|
+
* IpAddressType) plus `DescribeLoadBalancerAttributes` for the full
|
|
27145
|
+
* `LoadBalancerAttributes` `[{Key, Value}]` array (sorted by Key for
|
|
27146
|
+
* stable positional compare). AWS returns every attribute valid for
|
|
27147
|
+
* this LB type including defaults the user did not template; on the
|
|
27148
|
+
* v3 observedProperties baseline that's load-bearing — a console-side
|
|
27149
|
+
* change to ANY attribute (templated or not) surfaces as drift.
|
|
26963
27150
|
* - `TargetGroup` → `DescribeTargetGroups` (Protocol, Port, VpcId,
|
|
26964
27151
|
* TargetType, ProtocolVersion, HealthCheck*, Matcher, Name).
|
|
26965
27152
|
* - `Listener` → `DescribeListeners` (LoadBalancerArn, Certificates,
|
|
@@ -27009,6 +27196,18 @@ var ELBv2Provider = class {
|
|
|
27009
27196
|
result["Type"] = lb.Type;
|
|
27010
27197
|
if (lb.IpAddressType !== void 0)
|
|
27011
27198
|
result["IpAddressType"] = lb.IpAddressType;
|
|
27199
|
+
try {
|
|
27200
|
+
const attrsResp = await this.getClient().send(
|
|
27201
|
+
new DescribeLoadBalancerAttributesCommand({ LoadBalancerArn: physicalId })
|
|
27202
|
+
);
|
|
27203
|
+
const attrs = (attrsResp.Attributes ?? []).filter(
|
|
27204
|
+
(a) => typeof a.Key === "string" && typeof a.Value === "string"
|
|
27205
|
+
).map((a) => ({ Key: a.Key, Value: a.Value })).sort((a, b) => a.Key.localeCompare(b.Key));
|
|
27206
|
+
result["LoadBalancerAttributes"] = attrs;
|
|
27207
|
+
} catch (err) {
|
|
27208
|
+
if (this.isNotFoundError(err))
|
|
27209
|
+
return void 0;
|
|
27210
|
+
}
|
|
27012
27211
|
await this.attachTags(result, physicalId);
|
|
27013
27212
|
return result;
|
|
27014
27213
|
}
|
|
@@ -28889,8 +29088,10 @@ var Route53Provider = class {
|
|
|
28889
29088
|
* PrivateZone}, VPCs from `VPCs[]`, HostedZoneTags via
|
|
28890
29089
|
* `ListTagsForResource(ResourceType=hostedzone, ResourceId=<idTail>)`
|
|
28891
29090
|
* with `aws:*` filtered out and the key omitted when empty).
|
|
28892
|
-
* QueryLoggingConfig is
|
|
28893
|
-
* `ListQueryLoggingConfigs`
|
|
29091
|
+
* QueryLoggingConfig is surfaced via a follow-up
|
|
29092
|
+
* `ListQueryLoggingConfigs(HostedZoneId)` (filter to the one
|
|
29093
|
+
* config per zone — CFn enforces 0 or 1 — and reshape
|
|
29094
|
+
* `CloudWatchLogsLogGroupArn` to match cdkd state).
|
|
28894
29095
|
* - `RecordSet` → `ListResourceRecordSets` filtered to the exact
|
|
28895
29096
|
* `(name, type)` pair from the composite physicalId
|
|
28896
29097
|
* (`{zoneId}|{name}|{type}`). Surfaces TTL, ResourceRecords (with
|
|
@@ -28955,6 +29156,24 @@ var Route53Provider = class {
|
|
|
28955
29156
|
`Route53 ListTagsForResource(${idTail}) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
28956
29157
|
);
|
|
28957
29158
|
}
|
|
29159
|
+
try {
|
|
29160
|
+
const qlcResp = await this.getClient().send(
|
|
29161
|
+
new ListQueryLoggingConfigsCommand({ HostedZoneId: idTail })
|
|
29162
|
+
);
|
|
29163
|
+
const qlc = qlcResp.QueryLoggingConfigs?.[0];
|
|
29164
|
+
if (qlc?.CloudWatchLogsLogGroupArn) {
|
|
29165
|
+
result["QueryLoggingConfig"] = {
|
|
29166
|
+
CloudWatchLogsLogGroupArn: qlc.CloudWatchLogsLogGroupArn
|
|
29167
|
+
};
|
|
29168
|
+
} else {
|
|
29169
|
+
result["QueryLoggingConfig"] = {};
|
|
29170
|
+
}
|
|
29171
|
+
} catch (err) {
|
|
29172
|
+
this.logger.debug(
|
|
29173
|
+
`Route53 ListQueryLoggingConfigs(${idTail}) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
29174
|
+
);
|
|
29175
|
+
result["QueryLoggingConfig"] = {};
|
|
29176
|
+
}
|
|
28958
29177
|
return result;
|
|
28959
29178
|
}
|
|
28960
29179
|
async readRecordSet(physicalId) {
|
|
@@ -32726,6 +32945,8 @@ import {
|
|
|
32726
32945
|
KMSClient as KMSClient2,
|
|
32727
32946
|
CreateKeyCommand,
|
|
32728
32947
|
DescribeKeyCommand,
|
|
32948
|
+
GetKeyPolicyCommand,
|
|
32949
|
+
GetKeyRotationStatusCommand,
|
|
32729
32950
|
ListAliasesCommand as ListAliasesCommand2,
|
|
32730
32951
|
ListKeysCommand,
|
|
32731
32952
|
ListResourceTagsCommand,
|
|
@@ -33193,6 +33414,36 @@ var KMSProvider = class {
|
|
|
33193
33414
|
if (md.Origin !== void 0)
|
|
33194
33415
|
result["Origin"] = md.Origin;
|
|
33195
33416
|
if (md.KeyId) {
|
|
33417
|
+
try {
|
|
33418
|
+
const policyResp = await this.getClient().send(
|
|
33419
|
+
new GetKeyPolicyCommand({ KeyId: md.KeyId, PolicyName: "default" })
|
|
33420
|
+
);
|
|
33421
|
+
if (policyResp.Policy) {
|
|
33422
|
+
try {
|
|
33423
|
+
result["KeyPolicy"] = JSON.parse(policyResp.Policy);
|
|
33424
|
+
} catch {
|
|
33425
|
+
result["KeyPolicy"] = policyResp.Policy;
|
|
33426
|
+
}
|
|
33427
|
+
}
|
|
33428
|
+
} catch (err) {
|
|
33429
|
+
if (err instanceof NotFoundException5)
|
|
33430
|
+
return void 0;
|
|
33431
|
+
}
|
|
33432
|
+
const isSymmetric = md.KeySpec === void 0 || md.KeySpec === "SYMMETRIC_DEFAULT";
|
|
33433
|
+
if (isSymmetric) {
|
|
33434
|
+
try {
|
|
33435
|
+
const rotationResp = await this.getClient().send(
|
|
33436
|
+
new GetKeyRotationStatusCommand({ KeyId: md.KeyId })
|
|
33437
|
+
);
|
|
33438
|
+
result["EnableKeyRotation"] = rotationResp.KeyRotationEnabled ?? false;
|
|
33439
|
+
if (rotationResp.RotationPeriodInDays !== void 0) {
|
|
33440
|
+
result["RotationPeriodInDays"] = rotationResp.RotationPeriodInDays;
|
|
33441
|
+
}
|
|
33442
|
+
} catch (err) {
|
|
33443
|
+
if (err instanceof NotFoundException5)
|
|
33444
|
+
return void 0;
|
|
33445
|
+
}
|
|
33446
|
+
}
|
|
33196
33447
|
try {
|
|
33197
33448
|
const tagsResp = await this.getClient().send(
|
|
33198
33449
|
new ListResourceTagsCommand({ KeyId: md.KeyId })
|
|
@@ -33211,28 +33462,17 @@ var KMSProvider = class {
|
|
|
33211
33462
|
* drift comparator skips them instead of firing guaranteed false-
|
|
33212
33463
|
* positive drift on every clean run.
|
|
33213
33464
|
*
|
|
33214
|
-
* - `KeyPolicy`: cdkd does NOT call `GetKeyPolicy` in `readCurrentState`.
|
|
33215
|
-
* The policy body needs JSON parsing for comparison and a separate
|
|
33216
|
-
* SDK call; deferred to a follow-up. Until then, any user who
|
|
33217
|
-
* templates `KeyPolicy` would see guaranteed drift.
|
|
33218
|
-
* - `EnableKeyRotation` / `RotationPeriodInDays`: cdkd does NOT call
|
|
33219
|
-
* `GetKeyRotationStatus`. Same reason — deferred to a follow-up.
|
|
33220
|
-
* `EnableKeyRotation` is also a Class 1 candidate (only valid for
|
|
33221
|
-
* `KeySpec=SYMMETRIC_DEFAULT`); when we lift this gap the read side
|
|
33222
|
-
* must gate the emit on the discriminator.
|
|
33223
33465
|
* - `BypassPolicyLockoutSafetyCheck` / `PendingWindowInDays`: not part
|
|
33224
33466
|
* of the persisted AWS state visible via `DescribeKey` — both are
|
|
33225
33467
|
* create / delete-time-only inputs.
|
|
33468
|
+
*
|
|
33469
|
+
* `KeyPolicy`, `EnableKeyRotation`, and `RotationPeriodInDays` are now
|
|
33470
|
+
* read by `readCurrentState` (`GetKeyPolicy` and `GetKeyRotationStatus`
|
|
33471
|
+
* respectively), so they no longer need to be declared here.
|
|
33226
33472
|
*/
|
|
33227
33473
|
getDriftUnknownPaths(resourceType) {
|
|
33228
33474
|
if (resourceType === "AWS::KMS::Key") {
|
|
33229
|
-
return [
|
|
33230
|
-
"KeyPolicy",
|
|
33231
|
-
"EnableKeyRotation",
|
|
33232
|
-
"RotationPeriodInDays",
|
|
33233
|
-
"BypassPolicyLockoutSafetyCheck",
|
|
33234
|
-
"PendingWindowInDays"
|
|
33235
|
-
];
|
|
33475
|
+
return ["BypassPolicyLockoutSafetyCheck", "PendingWindowInDays"];
|
|
33236
33476
|
}
|
|
33237
33477
|
return [];
|
|
33238
33478
|
}
|
|
@@ -33821,6 +34061,7 @@ import {
|
|
|
33821
34061
|
DescribeAccessPointsCommand,
|
|
33822
34062
|
DescribeLifecycleConfigurationCommand,
|
|
33823
34063
|
DescribeBackupPolicyCommand,
|
|
34064
|
+
DescribeMountTargetSecurityGroupsCommand,
|
|
33824
34065
|
FileSystemNotFound,
|
|
33825
34066
|
MountTargetNotFound,
|
|
33826
34067
|
AccessPointNotFound
|
|
@@ -34247,8 +34488,10 @@ var EFSProvider = class {
|
|
|
34247
34488
|
* the corresponding key without failing the whole snapshot.
|
|
34248
34489
|
* - `AccessPoint` → `DescribeAccessPoints` filtered by id (PosixUser,
|
|
34249
34490
|
* RootDirectory).
|
|
34250
|
-
* - `MountTarget` → `DescribeMountTargets` (FileSystemId, SubnetId)
|
|
34251
|
-
*
|
|
34491
|
+
* - `MountTarget` → `DescribeMountTargets` (FileSystemId, SubnetId)
|
|
34492
|
+
* plus `DescribeMountTargetSecurityGroups` for the SG list (always-
|
|
34493
|
+
* emit `[]` when AWS reports none so a console-side ADD on a
|
|
34494
|
+
* previously-unconfigured mount target is detectable).
|
|
34252
34495
|
*
|
|
34253
34496
|
* `FileSystemTags` (the CFn property name on `AWS::EFS::FileSystem`) is
|
|
34254
34497
|
* surfaced from the same `DescribeFileSystems` response — `aws:*`
|
|
@@ -34405,6 +34648,17 @@ var EFSProvider = class {
|
|
|
34405
34648
|
result["FileSystemId"] = mt.FileSystemId;
|
|
34406
34649
|
if (mt.SubnetId !== void 0)
|
|
34407
34650
|
result["SubnetId"] = mt.SubnetId;
|
|
34651
|
+
let securityGroups = [];
|
|
34652
|
+
try {
|
|
34653
|
+
const sgResp = await this.getClient().send(
|
|
34654
|
+
new DescribeMountTargetSecurityGroupsCommand({ MountTargetId: physicalId })
|
|
34655
|
+
);
|
|
34656
|
+
securityGroups = (sgResp.SecurityGroups ?? []).filter(
|
|
34657
|
+
(s) => typeof s === "string"
|
|
34658
|
+
);
|
|
34659
|
+
} catch {
|
|
34660
|
+
}
|
|
34661
|
+
result["SecurityGroups"] = securityGroups;
|
|
34408
34662
|
return result;
|
|
34409
34663
|
}
|
|
34410
34664
|
/**
|
|
@@ -35014,6 +35268,7 @@ import {
|
|
|
35014
35268
|
GetTrailCommand,
|
|
35015
35269
|
GetTrailStatusCommand,
|
|
35016
35270
|
GetEventSelectorsCommand,
|
|
35271
|
+
GetInsightSelectorsCommand,
|
|
35017
35272
|
ListTrailsCommand,
|
|
35018
35273
|
ListTagsCommand as ListTagsCommand3,
|
|
35019
35274
|
AddTagsCommand as AddTagsCommand2,
|
|
@@ -35186,15 +35441,13 @@ var CloudTrailProvider = class {
|
|
|
35186
35441
|
const newInsightSelectors = properties["InsightSelectors"];
|
|
35187
35442
|
const oldInsightSelectors = previousProperties["InsightSelectors"];
|
|
35188
35443
|
if (JSON.stringify(newInsightSelectors) !== JSON.stringify(oldInsightSelectors)) {
|
|
35189
|
-
|
|
35190
|
-
|
|
35191
|
-
|
|
35192
|
-
|
|
35193
|
-
|
|
35194
|
-
|
|
35195
|
-
|
|
35196
|
-
);
|
|
35197
|
-
}
|
|
35444
|
+
this.logger.debug(`Updating insight selectors for CloudTrail Trail ${logicalId}`);
|
|
35445
|
+
await this.getClient().send(
|
|
35446
|
+
new PutInsightSelectorsCommand({
|
|
35447
|
+
TrailName: physicalId,
|
|
35448
|
+
InsightSelectors: newInsightSelectors ?? []
|
|
35449
|
+
})
|
|
35450
|
+
);
|
|
35198
35451
|
}
|
|
35199
35452
|
const oldIsLogging = previousProperties["IsLogging"];
|
|
35200
35453
|
if (isLogging !== oldIsLogging) {
|
|
@@ -35327,8 +35580,10 @@ var CloudTrailProvider = class {
|
|
|
35327
35580
|
* auto-tags are filtered out and the result key is omitted when AWS
|
|
35328
35581
|
* reports no user tags.
|
|
35329
35582
|
*
|
|
35330
|
-
* `InsightSelectors` is
|
|
35331
|
-
*
|
|
35583
|
+
* `InsightSelectors` is surfaced via a follow-up `GetInsightSelectors`
|
|
35584
|
+
* call — same shape on both sides (`[{InsightType}]`). The key is
|
|
35585
|
+
* always emitted (`[]` when AWS reports none) so a console-side ADD
|
|
35586
|
+
* is detectable on the v3 observedProperties baseline.
|
|
35332
35587
|
*
|
|
35333
35588
|
* Returns `undefined` when the trail is gone (`TrailNotFoundException`).
|
|
35334
35589
|
*/
|
|
@@ -35377,6 +35632,17 @@ var CloudTrailProvider = class {
|
|
|
35377
35632
|
}
|
|
35378
35633
|
} catch {
|
|
35379
35634
|
}
|
|
35635
|
+
let insightSelectors = [];
|
|
35636
|
+
try {
|
|
35637
|
+
const insight = await this.getClient().send(
|
|
35638
|
+
new GetInsightSelectorsCommand({ TrailName: physicalId })
|
|
35639
|
+
);
|
|
35640
|
+
insightSelectors = (insight.InsightSelectors ?? []).map((s) => ({
|
|
35641
|
+
...s.InsightType !== void 0 && { InsightType: s.InsightType }
|
|
35642
|
+
}));
|
|
35643
|
+
} catch {
|
|
35644
|
+
}
|
|
35645
|
+
result["InsightSelectors"] = insightSelectors;
|
|
35380
35646
|
let tags = [];
|
|
35381
35647
|
if (trail.TrailARN) {
|
|
35382
35648
|
try {
|
|
@@ -35720,12 +35986,21 @@ var CodeBuildProvider = class {
|
|
|
35720
35986
|
*
|
|
35721
35987
|
* Issues `BatchGetProjects` and re-shapes the SDK's camelCase response back
|
|
35722
35988
|
* to CFn's PascalCase shape (the `mapProperties` helper above goes the
|
|
35723
|
-
* other way at create time).
|
|
35724
|
-
*
|
|
35725
|
-
*
|
|
35726
|
-
*
|
|
35727
|
-
* `LogsConfig
|
|
35728
|
-
*
|
|
35989
|
+
* other way at create time). Coverage targets every user-controllable
|
|
35990
|
+
* top-level field via the always-emit pattern (PR #145):
|
|
35991
|
+
* - `Source` / `Artifacts` / `Environment` (with `EnvironmentVariables`
|
|
35992
|
+
* sub-array): full reshape to CFn shape.
|
|
35993
|
+
* - `LogsConfig` (`CloudWatchLogs` + `S3Logs` sub-shapes): always-emit
|
|
35994
|
+
* placeholder so a console-side enable on a previously-default
|
|
35995
|
+
* project surfaces as drift.
|
|
35996
|
+
* - `VpcConfig` (VpcId / Subnets / SecurityGroupIds): always-emit
|
|
35997
|
+
* placeholder.
|
|
35998
|
+
* - `Cache` (Type / Location / Modes): always-emit placeholder.
|
|
35999
|
+
*
|
|
36000
|
+
* Still v1-omitted (known gaps, follow-up): `SecondarySources` /
|
|
36001
|
+
* `SecondaryArtifacts` / `SecondarySourceVersions` / `FileSystemLocations` /
|
|
36002
|
+
* `Triggers` / `BuildBatchConfig` / `ResourceAccessRole`. These are
|
|
36003
|
+
* rarely set in practice and surfacing them with partial shape would
|
|
35729
36004
|
* fire false drift on every project that uses them.
|
|
35730
36005
|
*
|
|
35731
36006
|
* Tags are surfaced from the same `BatchGetProjects` response (CodeBuild
|
|
@@ -35840,6 +36115,51 @@ var CodeBuildProvider = class {
|
|
|
35840
36115
|
});
|
|
35841
36116
|
result["Environment"] = env;
|
|
35842
36117
|
}
|
|
36118
|
+
{
|
|
36119
|
+
const logs = {};
|
|
36120
|
+
const cw = {
|
|
36121
|
+
Status: project.logsConfig?.cloudWatchLogs?.status ?? "ENABLED"
|
|
36122
|
+
};
|
|
36123
|
+
if (project.logsConfig?.cloudWatchLogs?.groupName !== void 0) {
|
|
36124
|
+
cw["GroupName"] = project.logsConfig.cloudWatchLogs.groupName;
|
|
36125
|
+
}
|
|
36126
|
+
if (project.logsConfig?.cloudWatchLogs?.streamName !== void 0) {
|
|
36127
|
+
cw["StreamName"] = project.logsConfig.cloudWatchLogs.streamName;
|
|
36128
|
+
}
|
|
36129
|
+
logs["CloudWatchLogs"] = cw;
|
|
36130
|
+
const s3 = {
|
|
36131
|
+
Status: project.logsConfig?.s3Logs?.status ?? "DISABLED"
|
|
36132
|
+
};
|
|
36133
|
+
if (project.logsConfig?.s3Logs?.location !== void 0) {
|
|
36134
|
+
s3["Location"] = project.logsConfig.s3Logs.location;
|
|
36135
|
+
}
|
|
36136
|
+
if (project.logsConfig?.s3Logs?.encryptionDisabled !== void 0) {
|
|
36137
|
+
s3["EncryptionDisabled"] = project.logsConfig.s3Logs.encryptionDisabled;
|
|
36138
|
+
}
|
|
36139
|
+
if (project.logsConfig?.s3Logs?.bucketOwnerAccess !== void 0) {
|
|
36140
|
+
s3["BucketOwnerAccess"] = project.logsConfig.s3Logs.bucketOwnerAccess;
|
|
36141
|
+
}
|
|
36142
|
+
logs["S3Logs"] = s3;
|
|
36143
|
+
result["LogsConfig"] = logs;
|
|
36144
|
+
}
|
|
36145
|
+
if (project.vpcConfig?.vpcId !== void 0) {
|
|
36146
|
+
const vpc = { VpcId: project.vpcConfig.vpcId };
|
|
36147
|
+
vpc["Subnets"] = project.vpcConfig.subnets ?? [];
|
|
36148
|
+
vpc["SecurityGroupIds"] = project.vpcConfig.securityGroupIds ?? [];
|
|
36149
|
+
result["VpcConfig"] = vpc;
|
|
36150
|
+
} else {
|
|
36151
|
+
result["VpcConfig"] = {};
|
|
36152
|
+
}
|
|
36153
|
+
{
|
|
36154
|
+
const cache2 = {
|
|
36155
|
+
Type: project.cache?.type ?? "NO_CACHE"
|
|
36156
|
+
};
|
|
36157
|
+
if (project.cache?.location !== void 0)
|
|
36158
|
+
cache2["Location"] = project.cache.location;
|
|
36159
|
+
if (project.cache?.modes !== void 0)
|
|
36160
|
+
cache2["Modes"] = project.cache.modes;
|
|
36161
|
+
result["Cache"] = cache2;
|
|
36162
|
+
}
|
|
35843
36163
|
const tags = normalizeAwsTagsToCfn(project.tags);
|
|
35844
36164
|
result["Tags"] = tags;
|
|
35845
36165
|
return result;
|
|
@@ -43979,7 +44299,7 @@ function reorderArgs(argv) {
|
|
|
43979
44299
|
}
|
|
43980
44300
|
async function main() {
|
|
43981
44301
|
const program = new Command14();
|
|
43982
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.51.
|
|
44302
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.51.1");
|
|
43983
44303
|
program.addCommand(createBootstrapCommand());
|
|
43984
44304
|
program.addCommand(createSynthCommand());
|
|
43985
44305
|
program.addCommand(createListCommand());
|