@beesolve/aws-accounts 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,218 @@
1
+ import * as v from "valibot";
2
+ const moveAccountOperationSchema = v.strictObject({
3
+ kind: v.literal("moveAccount"),
4
+ accountId: v.string(),
5
+ accountName: v.string(),
6
+ fromOuId: v.string(),
7
+ fromOuName: v.string(),
8
+ toOuId: v.string(),
9
+ toOuName: v.string()
10
+ });
11
+ const createOuOperationSchema = v.strictObject({
12
+ kind: v.literal("createOu"),
13
+ ouName: v.string(),
14
+ parentOuId: v.string(),
15
+ parentOuName: v.string()
16
+ });
17
+ const renameOuOperationSchema = v.strictObject({
18
+ kind: v.literal("renameOu"),
19
+ ouId: v.string(),
20
+ fromOuName: v.string(),
21
+ toOuName: v.string(),
22
+ parentOuId: v.string(),
23
+ parentOuName: v.string()
24
+ });
25
+ const deleteOuOperationSchema = v.strictObject({
26
+ kind: v.literal("deleteOu"),
27
+ ouId: v.string(),
28
+ ouName: v.string(),
29
+ parentOuId: v.string(),
30
+ parentOuName: v.string()
31
+ });
32
+ const createAccountOperationSchema = v.strictObject({
33
+ kind: v.literal("createAccount"),
34
+ accountName: v.string(),
35
+ accountEmail: v.string(),
36
+ targetOuId: v.string(),
37
+ targetOuName: v.string()
38
+ });
39
+ const updateAccountTagsOperationSchema = v.strictObject({
40
+ kind: v.literal("updateAccountTags"),
41
+ accountId: v.string(),
42
+ accountName: v.string(),
43
+ tags: v.record(v.string(), v.string())
44
+ });
45
+ const updateAccountNameOperationSchema = v.strictObject({
46
+ kind: v.literal("updateAccountName"),
47
+ accountId: v.string(),
48
+ fromAccountName: v.string(),
49
+ toAccountName: v.string()
50
+ });
51
+ const removeAccountOperationSchema = v.strictObject({
52
+ kind: v.literal("removeAccount"),
53
+ accountId: v.string(),
54
+ accountName: v.string(),
55
+ fromOuId: v.string(),
56
+ fromOuName: v.string(),
57
+ toOuId: v.string(),
58
+ toOuName: v.string()
59
+ });
60
+ const createIdcUserOperationSchema = v.strictObject({
61
+ kind: v.literal("createIdcUser"),
62
+ userName: v.string(),
63
+ displayName: v.string(),
64
+ email: v.string()
65
+ });
66
+ const updateIdcUserOperationSchema = v.strictObject({
67
+ kind: v.literal("updateIdcUser"),
68
+ userName: v.string(),
69
+ displayName: v.string(),
70
+ email: v.string()
71
+ });
72
+ const deleteIdcUserOperationSchema = v.strictObject({
73
+ kind: v.literal("deleteIdcUser"),
74
+ userName: v.string()
75
+ });
76
+ const createIdcGroupOperationSchema = v.strictObject({
77
+ kind: v.literal("createIdcGroup"),
78
+ groupDisplayName: v.string(),
79
+ description: v.string()
80
+ });
81
+ const updateIdcGroupDescriptionOperationSchema = v.strictObject({
82
+ kind: v.literal("updateIdcGroupDescription"),
83
+ groupDisplayName: v.string(),
84
+ description: v.string()
85
+ });
86
+ const deleteIdcGroupOperationSchema = v.strictObject({
87
+ kind: v.literal("deleteIdcGroup"),
88
+ groupDisplayName: v.string()
89
+ });
90
+ const addIdcGroupMembershipOperationSchema = v.strictObject({
91
+ kind: v.literal("addIdcGroupMembership"),
92
+ groupDisplayName: v.string(),
93
+ userName: v.string()
94
+ });
95
+ const removeIdcGroupMembershipOperationSchema = v.strictObject({
96
+ kind: v.literal("removeIdcGroupMembership"),
97
+ groupDisplayName: v.string(),
98
+ userName: v.string()
99
+ });
100
+ const createIdcPermissionSetOperationSchema = v.strictObject({
101
+ kind: v.literal("createIdcPermissionSet"),
102
+ permissionSetName: v.string(),
103
+ description: v.string()
104
+ });
105
+ const updateIdcPermissionSetDescriptionOperationSchema = v.strictObject({
106
+ kind: v.literal("updateIdcPermissionSetDescription"),
107
+ permissionSetName: v.string(),
108
+ description: v.string()
109
+ });
110
+ const deleteIdcPermissionSetOperationSchema = v.strictObject({
111
+ kind: v.literal("deleteIdcPermissionSet"),
112
+ permissionSetName: v.string()
113
+ });
114
+ const putIdcPermissionSetInlinePolicyOperationSchema = v.strictObject({
115
+ kind: v.literal("putIdcPermissionSetInlinePolicy"),
116
+ permissionSetName: v.string(),
117
+ inlinePolicy: v.string()
118
+ });
119
+ const deleteIdcPermissionSetInlinePolicyOperationSchema = v.strictObject({
120
+ kind: v.literal("deleteIdcPermissionSetInlinePolicy"),
121
+ permissionSetName: v.string()
122
+ });
123
+ const attachIdcManagedPolicyToPermissionSetOperationSchema = v.strictObject({
124
+ kind: v.literal("attachIdcManagedPolicyToPermissionSet"),
125
+ permissionSetName: v.string(),
126
+ managedPolicyArn: v.string()
127
+ });
128
+ const detachIdcManagedPolicyFromPermissionSetOperationSchema = v.strictObject({
129
+ kind: v.literal("detachIdcManagedPolicyFromPermissionSet"),
130
+ permissionSetName: v.string(),
131
+ managedPolicyArn: v.string()
132
+ });
133
+ const attachIdcCustomerManagedPolicyReferenceToPermissionSetOperationSchema = v.strictObject({
134
+ kind: v.literal("attachIdcCustomerManagedPolicyReferenceToPermissionSet"),
135
+ permissionSetName: v.string(),
136
+ customerManagedPolicyName: v.string(),
137
+ customerManagedPolicyPath: v.string()
138
+ });
139
+ const detachIdcCustomerManagedPolicyReferenceFromPermissionSetOperationSchema = v.strictObject({
140
+ kind: v.literal("detachIdcCustomerManagedPolicyReferenceFromPermissionSet"),
141
+ permissionSetName: v.string(),
142
+ customerManagedPolicyName: v.string(),
143
+ customerManagedPolicyPath: v.string()
144
+ });
145
+ const provisionIdcPermissionSetOperationSchema = v.strictObject({
146
+ kind: v.literal("provisionIdcPermissionSet"),
147
+ permissionSetName: v.string(),
148
+ targetScope: v.literal("ALL_PROVISIONED_ACCOUNTS")
149
+ });
150
+ const grantIdcAccountAssignmentOperationSchema = v.strictObject({
151
+ kind: v.literal("grantIdcAccountAssignment"),
152
+ accountName: v.string(),
153
+ permissionSetName: v.string(),
154
+ principalType: v.picklist(["GROUP", "USER"]),
155
+ principalName: v.string()
156
+ });
157
+ const revokeIdcAccountAssignmentOperationSchema = v.strictObject({
158
+ kind: v.literal("revokeIdcAccountAssignment"),
159
+ accountName: v.string(),
160
+ permissionSetName: v.string(),
161
+ principalType: v.picklist(["GROUP", "USER"]),
162
+ principalName: v.string()
163
+ });
164
+ const operationSchema = v.variant("kind", [
165
+ moveAccountOperationSchema,
166
+ createOuOperationSchema,
167
+ renameOuOperationSchema,
168
+ deleteOuOperationSchema,
169
+ createAccountOperationSchema,
170
+ updateAccountTagsOperationSchema,
171
+ updateAccountNameOperationSchema,
172
+ removeAccountOperationSchema,
173
+ createIdcUserOperationSchema,
174
+ updateIdcUserOperationSchema,
175
+ deleteIdcUserOperationSchema,
176
+ createIdcGroupOperationSchema,
177
+ updateIdcGroupDescriptionOperationSchema,
178
+ deleteIdcGroupOperationSchema,
179
+ addIdcGroupMembershipOperationSchema,
180
+ removeIdcGroupMembershipOperationSchema,
181
+ createIdcPermissionSetOperationSchema,
182
+ updateIdcPermissionSetDescriptionOperationSchema,
183
+ deleteIdcPermissionSetOperationSchema,
184
+ putIdcPermissionSetInlinePolicyOperationSchema,
185
+ deleteIdcPermissionSetInlinePolicyOperationSchema,
186
+ attachIdcManagedPolicyToPermissionSetOperationSchema,
187
+ detachIdcManagedPolicyFromPermissionSetOperationSchema,
188
+ attachIdcCustomerManagedPolicyReferenceToPermissionSetOperationSchema,
189
+ detachIdcCustomerManagedPolicyReferenceFromPermissionSetOperationSchema,
190
+ provisionIdcPermissionSetOperationSchema,
191
+ grantIdcAccountAssignmentOperationSchema,
192
+ revokeIdcAccountAssignmentOperationSchema
193
+ ]);
194
+ const unsupportedDiffKindSchema = v.picklist([
195
+ "ambiguousOuRename",
196
+ "reparentedOu",
197
+ "newOuWithUnknownParent",
198
+ "newAccountWithUnknownOu",
199
+ "removedOu"
200
+ ]);
201
+ const unsupportedDiffCategorySchema = v.picklist([
202
+ "destructive",
203
+ "unsupportedMutation"
204
+ ]);
205
+ const unsupportedDiffSchema = v.strictObject({
206
+ kind: unsupportedDiffKindSchema,
207
+ category: unsupportedDiffCategorySchema,
208
+ description: v.string()
209
+ });
210
+ const planSchema = v.strictObject({
211
+ operations: v.array(operationSchema),
212
+ unsupported: v.array(unsupportedDiffSchema)
213
+ });
214
+ export {
215
+ operationSchema,
216
+ planSchema,
217
+ unsupportedDiffSchema
218
+ };
@@ -0,0 +1,38 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import * as v from "valibot";
3
+ import { validateState } from "./state.js";
4
+ const stateCacheSchema = v.strictObject({
5
+ fetchedAt: v.string(),
6
+ state: v.any()
7
+ });
8
+ async function readStateCache(cachePath) {
9
+ try {
10
+ const content = await readFile(cachePath, "utf8");
11
+ const parsed = JSON.parse(content);
12
+ const envelope = v.parse(stateCacheSchema, parsed);
13
+ const state = validateState(envelope.state);
14
+ return { fetchedAt: envelope.fetchedAt, state };
15
+ } catch {
16
+ return null;
17
+ }
18
+ }
19
+ async function writeStateCache(cachePath, state) {
20
+ const cacheFile = {
21
+ fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
22
+ state
23
+ };
24
+ const content = `${JSON.stringify(cacheFile, null, 2)}
25
+ `;
26
+ await writeFile(cachePath, content, "utf8");
27
+ }
28
+ function isCacheFresh(cache, ttlSeconds) {
29
+ const fetchedAt = new Date(cache.fetchedAt).getTime();
30
+ const now = Date.now();
31
+ const elapsedMs = now - fetchedAt;
32
+ return elapsedMs <= ttlSeconds * 1e3;
33
+ }
34
+ export {
35
+ isCacheFresh,
36
+ readStateCache,
37
+ writeStateCache
38
+ };
@@ -0,0 +1,46 @@
1
+ function applyReservedOuDeletionGuard(props) {
2
+ const reservedOuNamesById = /* @__PURE__ */ new Map([
3
+ [props.context.organization.graveyardOuId, "Graveyard"]
4
+ ]);
5
+ const operations = props.plan.operations.filter((operation) => {
6
+ if (operation.kind !== "deleteOu") {
7
+ return true;
8
+ }
9
+ return reservedOuNamesById.has(operation.ouId) === false;
10
+ });
11
+ const reservedOuUnsupported = props.plan.operations.flatMap((operation) => {
12
+ if (operation.kind !== "deleteOu") {
13
+ return [];
14
+ }
15
+ const reservedOuName = reservedOuNamesById.get(operation.ouId);
16
+ if (reservedOuName == null) {
17
+ return [];
18
+ }
19
+ return [
20
+ {
21
+ kind: "removedOu",
22
+ category: "destructive",
23
+ description: `reserved OU "${reservedOuName}" cannot be deleted by this tool; delete it manually in AWS if you really need to remove it`
24
+ }
25
+ ];
26
+ });
27
+ if (reservedOuUnsupported.length === 0) {
28
+ return props.plan;
29
+ }
30
+ const unsupported = [...props.plan.unsupported, ...reservedOuUnsupported].sort(
31
+ (left, right) => {
32
+ const kindComparison = left.kind.localeCompare(right.kind);
33
+ if (kindComparison !== 0) {
34
+ return kindComparison;
35
+ }
36
+ return left.description.localeCompare(right.description);
37
+ }
38
+ );
39
+ return {
40
+ operations,
41
+ unsupported
42
+ };
43
+ }
44
+ export {
45
+ applyReservedOuDeletionGuard
46
+ };