@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.
- package/LICENSE +21 -0
- package/README.md +189 -0
- package/dist/accountCreation.js +135 -0
- package/dist/applyLogic.js +1203 -0
- package/dist/awsClientConfig.js +26 -0
- package/dist/awsConfig.js +1365 -0
- package/dist/cli.js +201 -0
- package/dist/commands/graveyard.js +46 -0
- package/dist/commands/regenerate.js +17 -0
- package/dist/commands/remote.js +925 -0
- package/dist/diff.js +1012 -0
- package/dist/error.js +66 -0
- package/dist/helpers.js +21 -0
- package/dist/lambda/handler.js +375 -0
- package/dist/lambdaClient.js +220 -0
- package/dist/logger.js +26 -0
- package/dist/operations.js +218 -0
- package/dist/remoteStateCache.js +38 -0
- package/dist/reservedOuDeletion.js +46 -0
- package/dist/scanLogic.js +456 -0
- package/dist/state.js +618 -0
- package/dist/tags.js +14 -0
- package/dist-lambda/handler.mjs +3558 -0
- package/dist-lambda/lambda.zip +0 -0
- package/package.json +59 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ListGroupMembershipsCommand,
|
|
3
|
+
ListGroupsCommand,
|
|
4
|
+
ListUsersCommand
|
|
5
|
+
} from "@aws-sdk/client-identitystore";
|
|
6
|
+
import {
|
|
7
|
+
ListAccountsCommand,
|
|
8
|
+
ListOrganizationalUnitsForParentCommand,
|
|
9
|
+
ListParentsCommand,
|
|
10
|
+
ListRootsCommand,
|
|
11
|
+
ListTagsForResourceCommand
|
|
12
|
+
} from "@aws-sdk/client-organizations";
|
|
13
|
+
import {
|
|
14
|
+
DescribePermissionSetCommand,
|
|
15
|
+
GetInlinePolicyForPermissionSetCommand,
|
|
16
|
+
ListAccountAssignmentsCommand,
|
|
17
|
+
ListAccountsForProvisionedPermissionSetCommand,
|
|
18
|
+
ListCustomerManagedPolicyReferencesInPermissionSetCommand,
|
|
19
|
+
ListInstancesCommand,
|
|
20
|
+
ListManagedPoliciesInPermissionSetCommand,
|
|
21
|
+
ListPermissionSetsCommand
|
|
22
|
+
} from "@aws-sdk/client-sso-admin";
|
|
23
|
+
import {
|
|
24
|
+
createAccessRoleName
|
|
25
|
+
} from "./state.js";
|
|
26
|
+
async function scanOrganization(props) {
|
|
27
|
+
const roots = await props.organizationsClient.send(new ListRootsCommand({}));
|
|
28
|
+
const root = roots.Roots?.[0];
|
|
29
|
+
if (root?.Id == null) {
|
|
30
|
+
throw new Error("No organization root found.");
|
|
31
|
+
}
|
|
32
|
+
const organizationalUnits = await collectOrganizationalUnits({
|
|
33
|
+
organizationsClient: props.organizationsClient,
|
|
34
|
+
parentId: root.Id
|
|
35
|
+
});
|
|
36
|
+
const accounts = [];
|
|
37
|
+
let nextToken;
|
|
38
|
+
do {
|
|
39
|
+
const response = await props.organizationsClient.send(
|
|
40
|
+
new ListAccountsCommand({ NextToken: nextToken })
|
|
41
|
+
);
|
|
42
|
+
for (const account of response.Accounts ?? []) {
|
|
43
|
+
if (account.Id == null || account.Arn == null || account.Name == null || account.Email == null || account.Status == null) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const parents = await props.organizationsClient.send(
|
|
47
|
+
new ListParentsCommand({ ChildId: account.Id })
|
|
48
|
+
);
|
|
49
|
+
const parentId = parents.Parents?.[0]?.Id ?? root.Id;
|
|
50
|
+
const tagsResponse = await props.organizationsClient.send(
|
|
51
|
+
new ListTagsForResourceCommand({
|
|
52
|
+
ResourceId: account.Id
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
accounts.push({
|
|
56
|
+
id: account.Id,
|
|
57
|
+
arn: account.Arn,
|
|
58
|
+
name: account.Name,
|
|
59
|
+
email: account.Email,
|
|
60
|
+
status: account.Status,
|
|
61
|
+
parentId,
|
|
62
|
+
tags: (tagsResponse.Tags ?? []).flatMap((tag) => {
|
|
63
|
+
if (tag.Key == null) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
return [
|
|
67
|
+
{
|
|
68
|
+
key: tag.Key,
|
|
69
|
+
value: tag.Value ?? ""
|
|
70
|
+
}
|
|
71
|
+
];
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
nextToken = response.NextToken;
|
|
76
|
+
} while (nextToken != null);
|
|
77
|
+
return {
|
|
78
|
+
rootId: root.Id,
|
|
79
|
+
organizationalUnits,
|
|
80
|
+
accounts
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async function collectOrganizationalUnits(props) {
|
|
84
|
+
const children = [];
|
|
85
|
+
let nextToken;
|
|
86
|
+
do {
|
|
87
|
+
const response = await props.organizationsClient.send(
|
|
88
|
+
new ListOrganizationalUnitsForParentCommand({
|
|
89
|
+
ParentId: props.parentId,
|
|
90
|
+
NextToken: nextToken
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
for (const ou of response.OrganizationalUnits ?? []) {
|
|
94
|
+
if (ou.Id == null || ou.Arn == null || ou.Name == null) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
children.push({
|
|
98
|
+
id: ou.Id,
|
|
99
|
+
parentId: props.parentId,
|
|
100
|
+
arn: ou.Arn,
|
|
101
|
+
name: ou.Name
|
|
102
|
+
});
|
|
103
|
+
const descendants = await collectOrganizationalUnits({
|
|
104
|
+
organizationsClient: props.organizationsClient,
|
|
105
|
+
parentId: ou.Id
|
|
106
|
+
});
|
|
107
|
+
children.push(...descendants);
|
|
108
|
+
}
|
|
109
|
+
nextToken = response.NextToken;
|
|
110
|
+
} while (nextToken != null);
|
|
111
|
+
return children;
|
|
112
|
+
}
|
|
113
|
+
async function scanIdentityCenter(props) {
|
|
114
|
+
const instancesResponse = await props.ssoAdminClient.send(
|
|
115
|
+
new ListInstancesCommand({})
|
|
116
|
+
);
|
|
117
|
+
const instances = instancesResponse.Instances ?? [];
|
|
118
|
+
if (instances.length === 0) {
|
|
119
|
+
throw new Error("No IAM Identity Center instance found.");
|
|
120
|
+
}
|
|
121
|
+
const instance = selectIdentityCenterInstance({
|
|
122
|
+
instances,
|
|
123
|
+
requestedInstanceArn: props.requestedInstanceArn
|
|
124
|
+
});
|
|
125
|
+
const [users, groups, permissionSets] = await Promise.all([
|
|
126
|
+
listIdentityStoreUsers({
|
|
127
|
+
identityStoreClient: props.identityStoreClient,
|
|
128
|
+
identityStoreId: instance.identityStoreId
|
|
129
|
+
}),
|
|
130
|
+
listIdentityStoreGroups({
|
|
131
|
+
identityStoreClient: props.identityStoreClient,
|
|
132
|
+
identityStoreId: instance.identityStoreId
|
|
133
|
+
}),
|
|
134
|
+
listPermissionSets({
|
|
135
|
+
ssoAdminClient: props.ssoAdminClient,
|
|
136
|
+
instanceArn: instance.instanceArn
|
|
137
|
+
})
|
|
138
|
+
]);
|
|
139
|
+
const groupMemberships = await listGroupMemberships({
|
|
140
|
+
identityStoreClient: props.identityStoreClient,
|
|
141
|
+
identityStoreId: instance.identityStoreId,
|
|
142
|
+
groups
|
|
143
|
+
});
|
|
144
|
+
const accountAssignments = await listAccountAssignments({
|
|
145
|
+
ssoAdminClient: props.ssoAdminClient,
|
|
146
|
+
instanceArn: instance.instanceArn,
|
|
147
|
+
permissionSets
|
|
148
|
+
});
|
|
149
|
+
const accessRoles = accountAssignments.map((assignment) => ({
|
|
150
|
+
...assignment,
|
|
151
|
+
roleName: createAccessRoleName(assignment)
|
|
152
|
+
}));
|
|
153
|
+
return {
|
|
154
|
+
instanceArn: instance.instanceArn,
|
|
155
|
+
identityStoreId: instance.identityStoreId,
|
|
156
|
+
users,
|
|
157
|
+
groups,
|
|
158
|
+
groupMemberships,
|
|
159
|
+
permissionSets,
|
|
160
|
+
accountAssignments,
|
|
161
|
+
accessRoles
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function selectIdentityCenterInstance(props) {
|
|
165
|
+
if (props.requestedInstanceArn != null) {
|
|
166
|
+
const selected2 = props.instances.find(
|
|
167
|
+
(instance) => instance.InstanceArn === props.requestedInstanceArn
|
|
168
|
+
);
|
|
169
|
+
if (selected2?.InstanceArn == null || selected2.IdentityStoreId == null) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
`Identity Center instance not found for --instance-arn: ${props.requestedInstanceArn}`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
instanceArn: selected2.InstanceArn,
|
|
176
|
+
identityStoreId: selected2.IdentityStoreId
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
if (props.instances.length > 1) {
|
|
180
|
+
const knownArns = props.instances.map((instance) => instance.InstanceArn).filter((value) => value != null).join(", ");
|
|
181
|
+
throw new Error(
|
|
182
|
+
`Multiple IAM Identity Center instances found. Re-run scan with --instance-arn. Available: ${knownArns}`
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
const selected = props.instances[0];
|
|
186
|
+
if (selected?.InstanceArn == null || selected.IdentityStoreId == null) {
|
|
187
|
+
throw new Error("IAM Identity Center instance is missing required fields.");
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
instanceArn: selected.InstanceArn,
|
|
191
|
+
identityStoreId: selected.IdentityStoreId
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async function listIdentityStoreUsers(props) {
|
|
195
|
+
const users = [];
|
|
196
|
+
let nextToken;
|
|
197
|
+
do {
|
|
198
|
+
const response = await props.identityStoreClient.send(
|
|
199
|
+
new ListUsersCommand({
|
|
200
|
+
IdentityStoreId: props.identityStoreId,
|
|
201
|
+
NextToken: nextToken
|
|
202
|
+
})
|
|
203
|
+
);
|
|
204
|
+
for (const user of response.Users ?? []) {
|
|
205
|
+
if (user.UserId == null || user.UserName == null) {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
users.push({
|
|
209
|
+
userId: user.UserId,
|
|
210
|
+
userName: user.UserName,
|
|
211
|
+
displayName: user.DisplayName ?? "",
|
|
212
|
+
email: resolveIdentityStoreUserEmail({
|
|
213
|
+
emails: user.Emails ?? []
|
|
214
|
+
})
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
nextToken = response.NextToken;
|
|
218
|
+
} while (nextToken != null);
|
|
219
|
+
return users;
|
|
220
|
+
}
|
|
221
|
+
async function listIdentityStoreGroups(props) {
|
|
222
|
+
const groups = [];
|
|
223
|
+
let nextToken;
|
|
224
|
+
do {
|
|
225
|
+
const response = await props.identityStoreClient.send(
|
|
226
|
+
new ListGroupsCommand({
|
|
227
|
+
IdentityStoreId: props.identityStoreId,
|
|
228
|
+
NextToken: nextToken
|
|
229
|
+
})
|
|
230
|
+
);
|
|
231
|
+
for (const group of response.Groups ?? []) {
|
|
232
|
+
if (group.GroupId == null || group.DisplayName == null) {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
groups.push({
|
|
236
|
+
groupId: group.GroupId,
|
|
237
|
+
displayName: group.DisplayName,
|
|
238
|
+
description: group.Description ?? ""
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
nextToken = response.NextToken;
|
|
242
|
+
} while (nextToken != null);
|
|
243
|
+
return groups;
|
|
244
|
+
}
|
|
245
|
+
async function listGroupMemberships(props) {
|
|
246
|
+
const groupMemberships = [];
|
|
247
|
+
for (const group of props.groups) {
|
|
248
|
+
let nextToken;
|
|
249
|
+
do {
|
|
250
|
+
const response = await props.identityStoreClient.send(
|
|
251
|
+
new ListGroupMembershipsCommand({
|
|
252
|
+
IdentityStoreId: props.identityStoreId,
|
|
253
|
+
GroupId: group.groupId,
|
|
254
|
+
NextToken: nextToken
|
|
255
|
+
})
|
|
256
|
+
);
|
|
257
|
+
for (const groupMembership of response.GroupMemberships ?? []) {
|
|
258
|
+
const userId = groupMembership.MemberId?.UserId;
|
|
259
|
+
if (groupMembership.MembershipId == null || groupMembership.GroupId == null || userId == null) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
groupMemberships.push({
|
|
263
|
+
membershipId: groupMembership.MembershipId,
|
|
264
|
+
groupId: groupMembership.GroupId,
|
|
265
|
+
userId
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
nextToken = response.NextToken;
|
|
269
|
+
} while (nextToken != null);
|
|
270
|
+
}
|
|
271
|
+
return groupMemberships;
|
|
272
|
+
}
|
|
273
|
+
function resolveIdentityStoreUserEmail(props) {
|
|
274
|
+
const primaryEmail = props.emails.find(
|
|
275
|
+
(email) => email.Primary === true && email.Value != null && email.Value.length > 0
|
|
276
|
+
);
|
|
277
|
+
if (primaryEmail?.Value != null) {
|
|
278
|
+
return primaryEmail.Value;
|
|
279
|
+
}
|
|
280
|
+
return props.emails.find((email) => email.Value != null && email.Value.length > 0)?.Value ?? "";
|
|
281
|
+
}
|
|
282
|
+
async function listPermissionSets(props) {
|
|
283
|
+
const permissionSetArns = [];
|
|
284
|
+
let nextToken;
|
|
285
|
+
do {
|
|
286
|
+
const response = await props.ssoAdminClient.send(
|
|
287
|
+
new ListPermissionSetsCommand({
|
|
288
|
+
InstanceArn: props.instanceArn,
|
|
289
|
+
NextToken: nextToken
|
|
290
|
+
})
|
|
291
|
+
);
|
|
292
|
+
permissionSetArns.push(...response.PermissionSets ?? []);
|
|
293
|
+
nextToken = response.NextToken;
|
|
294
|
+
} while (nextToken != null);
|
|
295
|
+
const describeResponses = await Promise.all(
|
|
296
|
+
permissionSetArns.map(
|
|
297
|
+
(permissionSetArn) => props.ssoAdminClient.send(
|
|
298
|
+
new DescribePermissionSetCommand({
|
|
299
|
+
InstanceArn: props.instanceArn,
|
|
300
|
+
PermissionSetArn: permissionSetArn
|
|
301
|
+
})
|
|
302
|
+
)
|
|
303
|
+
)
|
|
304
|
+
);
|
|
305
|
+
const permissionSets = await Promise.all(
|
|
306
|
+
describeResponses.map(async (response) => {
|
|
307
|
+
const permissionSet = response.PermissionSet;
|
|
308
|
+
if (permissionSet?.PermissionSetArn == null || permissionSet.Name == null) {
|
|
309
|
+
return void 0;
|
|
310
|
+
}
|
|
311
|
+
const [
|
|
312
|
+
inlinePolicy,
|
|
313
|
+
awsManagedPolicies,
|
|
314
|
+
customerManagedPolicies
|
|
315
|
+
] = await Promise.all([
|
|
316
|
+
getInlinePolicyForPermissionSet({
|
|
317
|
+
ssoAdminClient: props.ssoAdminClient,
|
|
318
|
+
instanceArn: props.instanceArn,
|
|
319
|
+
permissionSetArn: permissionSet.PermissionSetArn
|
|
320
|
+
}),
|
|
321
|
+
listManagedPoliciesInPermissionSet({
|
|
322
|
+
ssoAdminClient: props.ssoAdminClient,
|
|
323
|
+
instanceArn: props.instanceArn,
|
|
324
|
+
permissionSetArn: permissionSet.PermissionSetArn
|
|
325
|
+
}),
|
|
326
|
+
listCustomerManagedPoliciesInPermissionSet({
|
|
327
|
+
ssoAdminClient: props.ssoAdminClient,
|
|
328
|
+
instanceArn: props.instanceArn,
|
|
329
|
+
permissionSetArn: permissionSet.PermissionSetArn
|
|
330
|
+
})
|
|
331
|
+
]);
|
|
332
|
+
return {
|
|
333
|
+
permissionSetArn: permissionSet.PermissionSetArn,
|
|
334
|
+
name: permissionSet.Name,
|
|
335
|
+
description: permissionSet.Description ?? "",
|
|
336
|
+
inlinePolicy,
|
|
337
|
+
awsManagedPolicies,
|
|
338
|
+
customerManagedPolicies
|
|
339
|
+
};
|
|
340
|
+
})
|
|
341
|
+
);
|
|
342
|
+
return permissionSets.filter(
|
|
343
|
+
(permissionSet) => permissionSet != null
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
async function getInlinePolicyForPermissionSet(props) {
|
|
347
|
+
const response = await props.ssoAdminClient.send(
|
|
348
|
+
new GetInlinePolicyForPermissionSetCommand({
|
|
349
|
+
InstanceArn: props.instanceArn,
|
|
350
|
+
PermissionSetArn: props.permissionSetArn
|
|
351
|
+
})
|
|
352
|
+
);
|
|
353
|
+
const inlinePolicy = response.InlinePolicy?.trim();
|
|
354
|
+
return inlinePolicy != null && inlinePolicy.length > 0 ? inlinePolicy : null;
|
|
355
|
+
}
|
|
356
|
+
async function listManagedPoliciesInPermissionSet(props) {
|
|
357
|
+
const managedPolicies = [];
|
|
358
|
+
let nextToken;
|
|
359
|
+
do {
|
|
360
|
+
const response = await props.ssoAdminClient.send(
|
|
361
|
+
new ListManagedPoliciesInPermissionSetCommand({
|
|
362
|
+
InstanceArn: props.instanceArn,
|
|
363
|
+
PermissionSetArn: props.permissionSetArn,
|
|
364
|
+
NextToken: nextToken
|
|
365
|
+
})
|
|
366
|
+
);
|
|
367
|
+
for (const attachedManagedPolicy of response.AttachedManagedPolicies ?? []) {
|
|
368
|
+
if (attachedManagedPolicy.Arn == null) {
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
managedPolicies.push(attachedManagedPolicy.Arn);
|
|
372
|
+
}
|
|
373
|
+
nextToken = response.NextToken;
|
|
374
|
+
} while (nextToken != null);
|
|
375
|
+
return managedPolicies;
|
|
376
|
+
}
|
|
377
|
+
async function listCustomerManagedPoliciesInPermissionSet(props) {
|
|
378
|
+
const customerManagedPolicies = [];
|
|
379
|
+
let nextToken;
|
|
380
|
+
do {
|
|
381
|
+
const response = await props.ssoAdminClient.send(
|
|
382
|
+
new ListCustomerManagedPolicyReferencesInPermissionSetCommand({
|
|
383
|
+
InstanceArn: props.instanceArn,
|
|
384
|
+
PermissionSetArn: props.permissionSetArn,
|
|
385
|
+
NextToken: nextToken
|
|
386
|
+
})
|
|
387
|
+
);
|
|
388
|
+
for (const customerManagedPolicyReference of response.CustomerManagedPolicyReferences ?? []) {
|
|
389
|
+
if (customerManagedPolicyReference.Name == null || customerManagedPolicyReference.Path == null) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
customerManagedPolicies.push({
|
|
393
|
+
name: customerManagedPolicyReference.Name,
|
|
394
|
+
path: customerManagedPolicyReference.Path
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
nextToken = response.NextToken;
|
|
398
|
+
} while (nextToken != null);
|
|
399
|
+
return customerManagedPolicies;
|
|
400
|
+
}
|
|
401
|
+
async function listAccountAssignments(props) {
|
|
402
|
+
const assignments = [];
|
|
403
|
+
for (const permissionSet of props.permissionSets) {
|
|
404
|
+
const accountIds = await listAccountsForPermissionSet({
|
|
405
|
+
ssoAdminClient: props.ssoAdminClient,
|
|
406
|
+
instanceArn: props.instanceArn,
|
|
407
|
+
permissionSetArn: permissionSet.permissionSetArn
|
|
408
|
+
});
|
|
409
|
+
for (const accountId of accountIds) {
|
|
410
|
+
let nextToken;
|
|
411
|
+
do {
|
|
412
|
+
const response = await props.ssoAdminClient.send(
|
|
413
|
+
new ListAccountAssignmentsCommand({
|
|
414
|
+
InstanceArn: props.instanceArn,
|
|
415
|
+
AccountId: accountId,
|
|
416
|
+
PermissionSetArn: permissionSet.permissionSetArn,
|
|
417
|
+
NextToken: nextToken
|
|
418
|
+
})
|
|
419
|
+
);
|
|
420
|
+
for (const assignment of response.AccountAssignments ?? []) {
|
|
421
|
+
if (assignment.AccountId == null || assignment.PermissionSetArn == null || assignment.PrincipalId == null || assignment.PrincipalType == null) {
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
assignments.push({
|
|
425
|
+
accountId: assignment.AccountId,
|
|
426
|
+
permissionSetArn: assignment.PermissionSetArn,
|
|
427
|
+
principalId: assignment.PrincipalId,
|
|
428
|
+
principalType: assignment.PrincipalType
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
nextToken = response.NextToken;
|
|
432
|
+
} while (nextToken != null);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return assignments;
|
|
436
|
+
}
|
|
437
|
+
async function listAccountsForPermissionSet(props) {
|
|
438
|
+
const accountIds = [];
|
|
439
|
+
let nextToken;
|
|
440
|
+
do {
|
|
441
|
+
const response = await props.ssoAdminClient.send(
|
|
442
|
+
new ListAccountsForProvisionedPermissionSetCommand({
|
|
443
|
+
InstanceArn: props.instanceArn,
|
|
444
|
+
PermissionSetArn: props.permissionSetArn,
|
|
445
|
+
NextToken: nextToken
|
|
446
|
+
})
|
|
447
|
+
);
|
|
448
|
+
accountIds.push(...response.AccountIds ?? []);
|
|
449
|
+
nextToken = response.NextToken;
|
|
450
|
+
} while (nextToken != null);
|
|
451
|
+
return accountIds;
|
|
452
|
+
}
|
|
453
|
+
export {
|
|
454
|
+
scanIdentityCenter,
|
|
455
|
+
scanOrganization
|
|
456
|
+
};
|