@stacksjs/ts-cloud 0.1.7 → 0.1.9
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/aws/s3.d.ts +1 -1
- package/dist/bin/cli.js +223 -222
- package/dist/index.js +132 -132
- package/package.json +18 -16
- package/src/aws/acm.ts +768 -0
- package/src/aws/application-autoscaling.ts +845 -0
- package/src/aws/bedrock.ts +4074 -0
- package/src/aws/client.ts +891 -0
- package/src/aws/cloudformation.ts +896 -0
- package/src/aws/cloudfront.ts +1531 -0
- package/src/aws/cloudwatch-logs.ts +154 -0
- package/src/aws/comprehend.ts +839 -0
- package/src/aws/connect.ts +1056 -0
- package/src/aws/deploy-imap.ts +384 -0
- package/src/aws/dynamodb.ts +340 -0
- package/src/aws/ec2.ts +1385 -0
- package/src/aws/ecr.ts +621 -0
- package/src/aws/ecs.ts +615 -0
- package/src/aws/elasticache.ts +301 -0
- package/src/aws/elbv2.ts +942 -0
- package/src/aws/email.ts +928 -0
- package/src/aws/eventbridge.ts +248 -0
- package/src/aws/iam.ts +1689 -0
- package/src/aws/imap-server.ts +2100 -0
- package/src/aws/index.ts +213 -0
- package/src/aws/kendra.ts +1097 -0
- package/src/aws/lambda.ts +786 -0
- package/src/aws/opensearch.ts +158 -0
- package/src/aws/personalize.ts +977 -0
- package/src/aws/polly.ts +559 -0
- package/src/aws/rds.ts +888 -0
- package/src/aws/rekognition.ts +846 -0
- package/src/aws/route53-domains.ts +359 -0
- package/src/aws/route53.ts +1046 -0
- package/src/aws/s3.ts +2334 -0
- package/src/aws/scheduler.ts +571 -0
- package/src/aws/secrets-manager.ts +769 -0
- package/src/aws/ses.ts +1081 -0
- package/src/aws/setup-phone.ts +104 -0
- package/src/aws/setup-sms.ts +580 -0
- package/src/aws/sms.ts +1735 -0
- package/src/aws/smtp-server.ts +531 -0
- package/src/aws/sns.ts +758 -0
- package/src/aws/sqs.ts +382 -0
- package/src/aws/ssm.ts +807 -0
- package/src/aws/sts.ts +92 -0
- package/src/aws/support.ts +391 -0
- package/src/aws/test-imap.ts +86 -0
- package/src/aws/textract.ts +780 -0
- package/src/aws/transcribe.ts +108 -0
- package/src/aws/translate.ts +641 -0
- package/src/aws/voice.ts +1379 -0
- package/src/config.ts +35 -0
- package/src/deploy/index.ts +7 -0
- package/src/deploy/static-site-external-dns.ts +945 -0
- package/src/deploy/static-site.ts +1175 -0
- package/src/dns/cloudflare.ts +548 -0
- package/src/dns/godaddy.ts +412 -0
- package/src/dns/index.ts +205 -0
- package/src/dns/porkbun.ts +362 -0
- package/src/dns/route53-adapter.ts +414 -0
- package/src/dns/types.ts +119 -0
- package/src/dns/validator.ts +369 -0
- package/src/generators/index.ts +5 -0
- package/src/generators/infrastructure.ts +1660 -0
- package/src/index.ts +163 -0
- package/src/push/apns.ts +452 -0
- package/src/push/fcm.ts +506 -0
- package/src/push/index.ts +58 -0
- package/src/security/pre-deploy-scanner.ts +655 -0
- package/src/ssl/acme-client.ts +478 -0
- package/src/ssl/index.ts +7 -0
- package/src/ssl/letsencrypt.ts +747 -0
- package/src/types.ts +2 -0
- package/src/utils/cli.ts +398 -0
- package/src/validation/index.ts +5 -0
- package/src/validation/template.ts +405 -0
package/src/aws/iam.ts
ADDED
|
@@ -0,0 +1,1689 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS IAM (Identity and Access Management) Operations
|
|
3
|
+
* Direct API calls without AWS SDK dependency
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { AWSClient } from './client'
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Types - Users
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
export interface IAMUser {
|
|
13
|
+
UserName: string
|
|
14
|
+
UserId: string
|
|
15
|
+
Arn: string
|
|
16
|
+
Path?: string
|
|
17
|
+
CreateDate?: string
|
|
18
|
+
PasswordLastUsed?: string
|
|
19
|
+
PermissionsBoundary?: {
|
|
20
|
+
PermissionsBoundaryType: string
|
|
21
|
+
PermissionsBoundaryArn: string
|
|
22
|
+
}
|
|
23
|
+
Tags?: Array<{ Key: string; Value: string }>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CreateUserParams {
|
|
27
|
+
UserName: string
|
|
28
|
+
Path?: string
|
|
29
|
+
PermissionsBoundary?: string
|
|
30
|
+
Tags?: Array<{ Key: string; Value: string }>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface GetUserParams {
|
|
34
|
+
UserName?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ListUsersParams {
|
|
38
|
+
PathPrefix?: string
|
|
39
|
+
Marker?: string
|
|
40
|
+
MaxItems?: number
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface UpdateUserParams {
|
|
44
|
+
UserName: string
|
|
45
|
+
NewUserName?: string
|
|
46
|
+
NewPath?: string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface DeleteUserParams {
|
|
50
|
+
UserName: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Types - Groups
|
|
55
|
+
// ============================================================================
|
|
56
|
+
|
|
57
|
+
export interface IAMGroup {
|
|
58
|
+
GroupName: string
|
|
59
|
+
GroupId: string
|
|
60
|
+
Arn: string
|
|
61
|
+
Path?: string
|
|
62
|
+
CreateDate?: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface CreateGroupParams {
|
|
66
|
+
GroupName: string
|
|
67
|
+
Path?: string
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface GetGroupParams {
|
|
71
|
+
GroupName: string
|
|
72
|
+
Marker?: string
|
|
73
|
+
MaxItems?: number
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface ListGroupsParams {
|
|
77
|
+
PathPrefix?: string
|
|
78
|
+
Marker?: string
|
|
79
|
+
MaxItems?: number
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface UpdateGroupParams {
|
|
83
|
+
GroupName: string
|
|
84
|
+
NewGroupName?: string
|
|
85
|
+
NewPath?: string
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface DeleteGroupParams {
|
|
89
|
+
GroupName: string
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface AddUserToGroupParams {
|
|
93
|
+
GroupName: string
|
|
94
|
+
UserName: string
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface RemoveUserFromGroupParams {
|
|
98
|
+
GroupName: string
|
|
99
|
+
UserName: string
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface ListGroupsForUserParams {
|
|
103
|
+
UserName: string
|
|
104
|
+
Marker?: string
|
|
105
|
+
MaxItems?: number
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ============================================================================
|
|
109
|
+
// Types - Roles
|
|
110
|
+
// ============================================================================
|
|
111
|
+
|
|
112
|
+
export interface IAMRole {
|
|
113
|
+
RoleName: string
|
|
114
|
+
RoleId: string
|
|
115
|
+
Arn: string
|
|
116
|
+
Path?: string
|
|
117
|
+
CreateDate?: string
|
|
118
|
+
AssumeRolePolicyDocument?: string
|
|
119
|
+
Description?: string
|
|
120
|
+
MaxSessionDuration?: number
|
|
121
|
+
PermissionsBoundary?: {
|
|
122
|
+
PermissionsBoundaryType: string
|
|
123
|
+
PermissionsBoundaryArn: string
|
|
124
|
+
}
|
|
125
|
+
Tags?: Array<{ Key: string; Value: string }>
|
|
126
|
+
RoleLastUsed?: {
|
|
127
|
+
LastUsedDate?: string
|
|
128
|
+
Region?: string
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface CreateRoleParams {
|
|
133
|
+
RoleName: string
|
|
134
|
+
AssumeRolePolicyDocument: string
|
|
135
|
+
Path?: string
|
|
136
|
+
Description?: string
|
|
137
|
+
MaxSessionDuration?: number
|
|
138
|
+
PermissionsBoundary?: string
|
|
139
|
+
Tags?: Array<{ Key: string; Value: string }>
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface GetRoleParams {
|
|
143
|
+
RoleName: string
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface ListRolesParams {
|
|
147
|
+
PathPrefix?: string
|
|
148
|
+
Marker?: string
|
|
149
|
+
MaxItems?: number
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface UpdateRoleParams {
|
|
153
|
+
RoleName: string
|
|
154
|
+
Description?: string
|
|
155
|
+
MaxSessionDuration?: number
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface UpdateRoleDescriptionParams {
|
|
159
|
+
RoleName: string
|
|
160
|
+
Description: string
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface UpdateAssumeRolePolicyParams {
|
|
164
|
+
RoleName: string
|
|
165
|
+
PolicyDocument: string
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface DeleteRoleParams {
|
|
169
|
+
RoleName: string
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface TagRoleParams {
|
|
173
|
+
RoleName: string
|
|
174
|
+
Tags: Array<{ Key: string; Value: string }>
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface UntagRoleParams {
|
|
178
|
+
RoleName: string
|
|
179
|
+
TagKeys: string[]
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface ListRoleTagsParams {
|
|
183
|
+
RoleName: string
|
|
184
|
+
Marker?: string
|
|
185
|
+
MaxItems?: number
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ============================================================================
|
|
189
|
+
// Types - Policies
|
|
190
|
+
// ============================================================================
|
|
191
|
+
|
|
192
|
+
export interface IAMPolicy {
|
|
193
|
+
PolicyName: string
|
|
194
|
+
PolicyId: string
|
|
195
|
+
Arn: string
|
|
196
|
+
Path?: string
|
|
197
|
+
DefaultVersionId?: string
|
|
198
|
+
AttachmentCount?: number
|
|
199
|
+
PermissionsBoundaryUsageCount?: number
|
|
200
|
+
IsAttachable?: boolean
|
|
201
|
+
Description?: string
|
|
202
|
+
CreateDate?: string
|
|
203
|
+
UpdateDate?: string
|
|
204
|
+
Tags?: Array<{ Key: string; Value: string }>
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface PolicyVersion {
|
|
208
|
+
VersionId: string
|
|
209
|
+
IsDefaultVersion: boolean
|
|
210
|
+
CreateDate?: string
|
|
211
|
+
Document?: string
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export interface CreatePolicyParams {
|
|
215
|
+
PolicyName: string
|
|
216
|
+
PolicyDocument: string
|
|
217
|
+
Path?: string
|
|
218
|
+
Description?: string
|
|
219
|
+
Tags?: Array<{ Key: string; Value: string }>
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export interface GetPolicyParams {
|
|
223
|
+
PolicyArn: string
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export interface GetPolicyVersionParams {
|
|
227
|
+
PolicyArn: string
|
|
228
|
+
VersionId: string
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export interface ListPoliciesParams {
|
|
232
|
+
Scope?: 'All' | 'AWS' | 'Local'
|
|
233
|
+
OnlyAttached?: boolean
|
|
234
|
+
PathPrefix?: string
|
|
235
|
+
PolicyUsageFilter?: 'PermissionsPolicy' | 'PermissionsBoundary'
|
|
236
|
+
Marker?: string
|
|
237
|
+
MaxItems?: number
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export interface ListPolicyVersionsParams {
|
|
241
|
+
PolicyArn: string
|
|
242
|
+
Marker?: string
|
|
243
|
+
MaxItems?: number
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export interface CreatePolicyVersionParams {
|
|
247
|
+
PolicyArn: string
|
|
248
|
+
PolicyDocument: string
|
|
249
|
+
SetAsDefault?: boolean
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export interface DeletePolicyVersionParams {
|
|
253
|
+
PolicyArn: string
|
|
254
|
+
VersionId: string
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export interface SetDefaultPolicyVersionParams {
|
|
258
|
+
PolicyArn: string
|
|
259
|
+
VersionId: string
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export interface DeletePolicyParams {
|
|
263
|
+
PolicyArn: string
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export interface AttachUserPolicyParams {
|
|
267
|
+
UserName: string
|
|
268
|
+
PolicyArn: string
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface DetachUserPolicyParams {
|
|
272
|
+
UserName: string
|
|
273
|
+
PolicyArn: string
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface AttachGroupPolicyParams {
|
|
277
|
+
GroupName: string
|
|
278
|
+
PolicyArn: string
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export interface DetachGroupPolicyParams {
|
|
282
|
+
GroupName: string
|
|
283
|
+
PolicyArn: string
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export interface AttachRolePolicyParams {
|
|
287
|
+
RoleName: string
|
|
288
|
+
PolicyArn: string
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export interface DetachRolePolicyParams {
|
|
292
|
+
RoleName: string
|
|
293
|
+
PolicyArn: string
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export interface ListAttachedUserPoliciesParams {
|
|
297
|
+
UserName: string
|
|
298
|
+
PathPrefix?: string
|
|
299
|
+
Marker?: string
|
|
300
|
+
MaxItems?: number
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export interface ListAttachedGroupPoliciesParams {
|
|
304
|
+
GroupName: string
|
|
305
|
+
PathPrefix?: string
|
|
306
|
+
Marker?: string
|
|
307
|
+
MaxItems?: number
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export interface ListAttachedRolePoliciesParams {
|
|
311
|
+
RoleName: string
|
|
312
|
+
PathPrefix?: string
|
|
313
|
+
Marker?: string
|
|
314
|
+
MaxItems?: number
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export interface ListEntitiesForPolicyParams {
|
|
318
|
+
PolicyArn: string
|
|
319
|
+
EntityFilter?: 'User' | 'Role' | 'Group' | 'LocalManagedPolicy' | 'AWSManagedPolicy'
|
|
320
|
+
PathPrefix?: string
|
|
321
|
+
PolicyUsageFilter?: 'PermissionsPolicy' | 'PermissionsBoundary'
|
|
322
|
+
Marker?: string
|
|
323
|
+
MaxItems?: number
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// ============================================================================
|
|
327
|
+
// Types - Inline Policies
|
|
328
|
+
// ============================================================================
|
|
329
|
+
|
|
330
|
+
export interface PutUserPolicyParams {
|
|
331
|
+
UserName: string
|
|
332
|
+
PolicyName: string
|
|
333
|
+
PolicyDocument: string
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export interface GetUserPolicyParams {
|
|
337
|
+
UserName: string
|
|
338
|
+
PolicyName: string
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export interface DeleteUserPolicyParams {
|
|
342
|
+
UserName: string
|
|
343
|
+
PolicyName: string
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export interface ListUserPoliciesParams {
|
|
347
|
+
UserName: string
|
|
348
|
+
Marker?: string
|
|
349
|
+
MaxItems?: number
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export interface PutGroupPolicyParams {
|
|
353
|
+
GroupName: string
|
|
354
|
+
PolicyName: string
|
|
355
|
+
PolicyDocument: string
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export interface GetGroupPolicyParams {
|
|
359
|
+
GroupName: string
|
|
360
|
+
PolicyName: string
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export interface DeleteGroupPolicyParams {
|
|
364
|
+
GroupName: string
|
|
365
|
+
PolicyName: string
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export interface ListGroupPoliciesParams {
|
|
369
|
+
GroupName: string
|
|
370
|
+
Marker?: string
|
|
371
|
+
MaxItems?: number
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
export interface PutRolePolicyParams {
|
|
375
|
+
RoleName: string
|
|
376
|
+
PolicyName: string
|
|
377
|
+
PolicyDocument: string
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export interface GetRolePolicyParams {
|
|
381
|
+
RoleName: string
|
|
382
|
+
PolicyName: string
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export interface DeleteRolePolicyParams {
|
|
386
|
+
RoleName: string
|
|
387
|
+
PolicyName: string
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export interface ListRolePoliciesParams {
|
|
391
|
+
RoleName: string
|
|
392
|
+
Marker?: string
|
|
393
|
+
MaxItems?: number
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// ============================================================================
|
|
397
|
+
// Types - Access Keys
|
|
398
|
+
// ============================================================================
|
|
399
|
+
|
|
400
|
+
export interface AccessKey {
|
|
401
|
+
UserName: string
|
|
402
|
+
AccessKeyId: string
|
|
403
|
+
Status: 'Active' | 'Inactive'
|
|
404
|
+
CreateDate?: string
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
export interface AccessKeyMetadata {
|
|
408
|
+
UserName?: string
|
|
409
|
+
AccessKeyId: string
|
|
410
|
+
Status: 'Active' | 'Inactive'
|
|
411
|
+
CreateDate?: string
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export interface CreateAccessKeyParams {
|
|
415
|
+
UserName?: string
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export interface CreateAccessKeyResult {
|
|
419
|
+
AccessKey: {
|
|
420
|
+
UserName: string
|
|
421
|
+
AccessKeyId: string
|
|
422
|
+
Status: 'Active' | 'Inactive'
|
|
423
|
+
SecretAccessKey: string
|
|
424
|
+
CreateDate?: string
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
export interface ListAccessKeysParams {
|
|
429
|
+
UserName?: string
|
|
430
|
+
Marker?: string
|
|
431
|
+
MaxItems?: number
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
export interface UpdateAccessKeyParams {
|
|
435
|
+
UserName?: string
|
|
436
|
+
AccessKeyId: string
|
|
437
|
+
Status: 'Active' | 'Inactive'
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
export interface DeleteAccessKeyParams {
|
|
441
|
+
UserName?: string
|
|
442
|
+
AccessKeyId: string
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
export interface GetAccessKeyLastUsedParams {
|
|
446
|
+
AccessKeyId: string
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// ============================================================================
|
|
450
|
+
// Types - Instance Profiles
|
|
451
|
+
// ============================================================================
|
|
452
|
+
|
|
453
|
+
export interface InstanceProfile {
|
|
454
|
+
InstanceProfileName: string
|
|
455
|
+
InstanceProfileId: string
|
|
456
|
+
Arn: string
|
|
457
|
+
Path?: string
|
|
458
|
+
CreateDate?: string
|
|
459
|
+
Roles?: IAMRole[]
|
|
460
|
+
Tags?: Array<{ Key: string; Value: string }>
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
export interface CreateInstanceProfileParams {
|
|
464
|
+
InstanceProfileName: string
|
|
465
|
+
Path?: string
|
|
466
|
+
Tags?: Array<{ Key: string; Value: string }>
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export interface GetInstanceProfileParams {
|
|
470
|
+
InstanceProfileName: string
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
export interface ListInstanceProfilesParams {
|
|
474
|
+
PathPrefix?: string
|
|
475
|
+
Marker?: string
|
|
476
|
+
MaxItems?: number
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
export interface ListInstanceProfilesForRoleParams {
|
|
480
|
+
RoleName: string
|
|
481
|
+
Marker?: string
|
|
482
|
+
MaxItems?: number
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export interface AddRoleToInstanceProfileParams {
|
|
486
|
+
InstanceProfileName: string
|
|
487
|
+
RoleName: string
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
export interface RemoveRoleFromInstanceProfileParams {
|
|
491
|
+
InstanceProfileName: string
|
|
492
|
+
RoleName: string
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
export interface DeleteInstanceProfileParams {
|
|
496
|
+
InstanceProfileName: string
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// ============================================================================
|
|
500
|
+
// Types - Server Certificates
|
|
501
|
+
// ============================================================================
|
|
502
|
+
|
|
503
|
+
export interface ServerCertificate {
|
|
504
|
+
ServerCertificateName: string
|
|
505
|
+
ServerCertificateId: string
|
|
506
|
+
Arn: string
|
|
507
|
+
Path?: string
|
|
508
|
+
UploadDate?: string
|
|
509
|
+
Expiration?: string
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
export interface ServerCertificateMetadata {
|
|
513
|
+
ServerCertificateName: string
|
|
514
|
+
ServerCertificateId: string
|
|
515
|
+
Arn: string
|
|
516
|
+
Path?: string
|
|
517
|
+
UploadDate?: string
|
|
518
|
+
Expiration?: string
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
export interface UploadServerCertificateParams {
|
|
522
|
+
ServerCertificateName: string
|
|
523
|
+
CertificateBody: string
|
|
524
|
+
PrivateKey: string
|
|
525
|
+
CertificateChain?: string
|
|
526
|
+
Path?: string
|
|
527
|
+
Tags?: Array<{ Key: string; Value: string }>
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
export interface GetServerCertificateParams {
|
|
531
|
+
ServerCertificateName: string
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
export interface ListServerCertificatesParams {
|
|
535
|
+
PathPrefix?: string
|
|
536
|
+
Marker?: string
|
|
537
|
+
MaxItems?: number
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
export interface UpdateServerCertificateParams {
|
|
541
|
+
ServerCertificateName: string
|
|
542
|
+
NewServerCertificateName?: string
|
|
543
|
+
NewPath?: string
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
export interface DeleteServerCertificateParams {
|
|
547
|
+
ServerCertificateName: string
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// ============================================================================
|
|
551
|
+
// Types - Account and Password Policy
|
|
552
|
+
// ============================================================================
|
|
553
|
+
|
|
554
|
+
export interface PasswordPolicy {
|
|
555
|
+
MinimumPasswordLength?: number
|
|
556
|
+
RequireSymbols?: boolean
|
|
557
|
+
RequireNumbers?: boolean
|
|
558
|
+
RequireUppercaseCharacters?: boolean
|
|
559
|
+
RequireLowercaseCharacters?: boolean
|
|
560
|
+
AllowUsersToChangePassword?: boolean
|
|
561
|
+
ExpirePasswords?: boolean
|
|
562
|
+
MaxPasswordAge?: number
|
|
563
|
+
PasswordReusePrevention?: number
|
|
564
|
+
HardExpiry?: boolean
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
export interface UpdateAccountPasswordPolicyParams {
|
|
568
|
+
MinimumPasswordLength?: number
|
|
569
|
+
RequireSymbols?: boolean
|
|
570
|
+
RequireNumbers?: boolean
|
|
571
|
+
RequireUppercaseCharacters?: boolean
|
|
572
|
+
RequireLowercaseCharacters?: boolean
|
|
573
|
+
AllowUsersToChangePassword?: boolean
|
|
574
|
+
MaxPasswordAge?: number
|
|
575
|
+
PasswordReusePrevention?: number
|
|
576
|
+
HardExpiry?: boolean
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
export interface AccountSummary {
|
|
580
|
+
Users?: number
|
|
581
|
+
UsersQuota?: number
|
|
582
|
+
Groups?: number
|
|
583
|
+
GroupsQuota?: number
|
|
584
|
+
ServerCertificates?: number
|
|
585
|
+
ServerCertificatesQuota?: number
|
|
586
|
+
UserPolicySizeQuota?: number
|
|
587
|
+
GroupPolicySizeQuota?: number
|
|
588
|
+
GroupsPerUserQuota?: number
|
|
589
|
+
SigningCertificatesPerUserQuota?: number
|
|
590
|
+
AccessKeysPerUserQuota?: number
|
|
591
|
+
MFADevices?: number
|
|
592
|
+
MFADevicesInUse?: number
|
|
593
|
+
AccountMFAEnabled?: number
|
|
594
|
+
AccountAccessKeysPresent?: number
|
|
595
|
+
AccountSigningCertificatesPresent?: number
|
|
596
|
+
AttachedPoliciesPerGroupQuota?: number
|
|
597
|
+
AttachedPoliciesPerRoleQuota?: number
|
|
598
|
+
AttachedPoliciesPerUserQuota?: number
|
|
599
|
+
Policies?: number
|
|
600
|
+
PoliciesQuota?: number
|
|
601
|
+
PolicySizeQuota?: number
|
|
602
|
+
PolicyVersionsInUse?: number
|
|
603
|
+
PolicyVersionsInUseQuota?: number
|
|
604
|
+
VersionsPerPolicyQuota?: number
|
|
605
|
+
GlobalEndpointTokenVersion?: number
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// ============================================================================
|
|
609
|
+
// Types - Policy Simulation
|
|
610
|
+
// ============================================================================
|
|
611
|
+
|
|
612
|
+
export interface SimulatePrincipalPolicyParams {
|
|
613
|
+
PolicySourceArn: string
|
|
614
|
+
ActionNames: string[]
|
|
615
|
+
ResourceArns?: string[]
|
|
616
|
+
ResourcePolicy?: string
|
|
617
|
+
ResourceOwner?: string
|
|
618
|
+
CallerArn?: string
|
|
619
|
+
ContextEntries?: Array<{
|
|
620
|
+
ContextKeyName: string
|
|
621
|
+
ContextKeyValues: string[]
|
|
622
|
+
ContextKeyType: string
|
|
623
|
+
}>
|
|
624
|
+
ResourceHandlingOption?: string
|
|
625
|
+
MaxItems?: number
|
|
626
|
+
Marker?: string
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
export interface EvaluationResult {
|
|
630
|
+
EvalActionName: string
|
|
631
|
+
EvalResourceName?: string
|
|
632
|
+
EvalDecision: string
|
|
633
|
+
MatchedStatements?: Array<{
|
|
634
|
+
SourcePolicyId?: string
|
|
635
|
+
SourcePolicyType?: string
|
|
636
|
+
}>
|
|
637
|
+
MissingContextValues?: string[]
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
export interface SimulatePolicyResponse {
|
|
641
|
+
EvaluationResults: EvaluationResult[]
|
|
642
|
+
IsTruncated: boolean
|
|
643
|
+
Marker?: string
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// ============================================================================
|
|
647
|
+
// Helper Functions
|
|
648
|
+
// ============================================================================
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Build query string from parameters for IAM API
|
|
652
|
+
*/
|
|
653
|
+
function buildQueryParams(action: string, params: Record<string, unknown>): string {
|
|
654
|
+
const queryParams: string[] = [`Action=${action}`, 'Version=2010-05-08']
|
|
655
|
+
|
|
656
|
+
for (const [key, value] of Object.entries(params)) {
|
|
657
|
+
if (value === undefined || value === null) continue
|
|
658
|
+
|
|
659
|
+
if (Array.isArray(value)) {
|
|
660
|
+
// Handle arrays (e.g., Tags, TagKeys)
|
|
661
|
+
value.forEach((item, index) => {
|
|
662
|
+
if (typeof item === 'object' && item !== null) {
|
|
663
|
+
// Handle array of objects (e.g., Tags)
|
|
664
|
+
for (const [subKey, subValue] of Object.entries(item as Record<string, unknown>)) {
|
|
665
|
+
queryParams.push(`${key}.member.${index + 1}.${subKey}=${encodeURIComponent(String(subValue))}`)
|
|
666
|
+
}
|
|
667
|
+
} else {
|
|
668
|
+
queryParams.push(`${key}.member.${index + 1}=${encodeURIComponent(String(item))}`)
|
|
669
|
+
}
|
|
670
|
+
})
|
|
671
|
+
} else if (typeof value === 'object') {
|
|
672
|
+
// Handle nested objects
|
|
673
|
+
for (const [subKey, subValue] of Object.entries(value as Record<string, unknown>)) {
|
|
674
|
+
if (subValue !== undefined && subValue !== null) {
|
|
675
|
+
queryParams.push(`${key}.${subKey}=${encodeURIComponent(String(subValue))}`)
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
} else {
|
|
679
|
+
queryParams.push(`${key}=${encodeURIComponent(String(value))}`)
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
return queryParams.join('&')
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Parse XML response from IAM API
|
|
688
|
+
*/
|
|
689
|
+
function parseXmlValue(xml: string, tag: string): string | undefined {
|
|
690
|
+
const regex = new RegExp(`<${tag}>([^<]*)</${tag}>`)
|
|
691
|
+
const match = xml.match(regex)
|
|
692
|
+
return match ? match[1] : undefined
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Parse XML array from IAM API
|
|
697
|
+
*/
|
|
698
|
+
function parseXmlArray(xml: string, containerTag: string, itemTag: string): string[] {
|
|
699
|
+
const containerRegex = new RegExp(`<${containerTag}>([\\s\\S]*?)</${containerTag}>`)
|
|
700
|
+
const containerMatch = xml.match(containerRegex)
|
|
701
|
+
if (!containerMatch) return []
|
|
702
|
+
|
|
703
|
+
const items: string[] = []
|
|
704
|
+
const itemRegex = new RegExp(`<${itemTag}>([\\s\\S]*?)</${itemTag}>`, 'g')
|
|
705
|
+
let match
|
|
706
|
+
while ((match = itemRegex.exec(containerMatch[1])) !== null) {
|
|
707
|
+
items.push(match[1])
|
|
708
|
+
}
|
|
709
|
+
return items
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// ============================================================================
|
|
713
|
+
// IAM Client
|
|
714
|
+
// ============================================================================
|
|
715
|
+
|
|
716
|
+
export class IAMClient {
|
|
717
|
+
private client: AWSClient
|
|
718
|
+
private region: string
|
|
719
|
+
|
|
720
|
+
constructor(region: string = 'us-east-1') {
|
|
721
|
+
this.client = new AWSClient()
|
|
722
|
+
this.region = region
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Make IAM API request
|
|
727
|
+
*/
|
|
728
|
+
private async request(action: string, params: object = {}): Promise<any> {
|
|
729
|
+
const body = buildQueryParams(action, params as Record<string, unknown>)
|
|
730
|
+
|
|
731
|
+
const response = await this.client.request({
|
|
732
|
+
service: 'iam',
|
|
733
|
+
region: this.region,
|
|
734
|
+
method: 'POST',
|
|
735
|
+
path: '/',
|
|
736
|
+
headers: {
|
|
737
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
738
|
+
},
|
|
739
|
+
body,
|
|
740
|
+
})
|
|
741
|
+
|
|
742
|
+
return response
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// ==========================================================================
|
|
746
|
+
// User Operations
|
|
747
|
+
// ==========================================================================
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Create a new IAM user
|
|
751
|
+
*/
|
|
752
|
+
async createUser(params: CreateUserParams): Promise<IAMUser> {
|
|
753
|
+
const response = await this.request('CreateUser', params)
|
|
754
|
+
return this.parseUser(response)
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Get information about an IAM user
|
|
759
|
+
*/
|
|
760
|
+
async getUser(params: GetUserParams = {}): Promise<IAMUser> {
|
|
761
|
+
const response = await this.request('GetUser', params)
|
|
762
|
+
return this.parseUser(response)
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* List IAM users
|
|
767
|
+
*/
|
|
768
|
+
async listUsers(params: ListUsersParams = {}): Promise<{ Users: IAMUser[]; IsTruncated: boolean; Marker?: string }> {
|
|
769
|
+
const response = await this.request('ListUsers', params)
|
|
770
|
+
const users = this.parseUsers(response)
|
|
771
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
772
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
773
|
+
return { Users: users, IsTruncated: isTruncated, Marker: marker }
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Update an IAM user
|
|
778
|
+
*/
|
|
779
|
+
async updateUser(params: UpdateUserParams): Promise<void> {
|
|
780
|
+
await this.request('UpdateUser', params)
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* Delete an IAM user
|
|
785
|
+
*/
|
|
786
|
+
async deleteUser(params: DeleteUserParams): Promise<void> {
|
|
787
|
+
await this.request('DeleteUser', params)
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* Parse user from XML response
|
|
792
|
+
*/
|
|
793
|
+
private parseUser(xml: string): IAMUser {
|
|
794
|
+
return {
|
|
795
|
+
UserName: parseXmlValue(xml, 'UserName') || '',
|
|
796
|
+
UserId: parseXmlValue(xml, 'UserId') || '',
|
|
797
|
+
Arn: parseXmlValue(xml, 'Arn') || '',
|
|
798
|
+
Path: parseXmlValue(xml, 'Path'),
|
|
799
|
+
CreateDate: parseXmlValue(xml, 'CreateDate'),
|
|
800
|
+
PasswordLastUsed: parseXmlValue(xml, 'PasswordLastUsed'),
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Parse users array from XML response
|
|
806
|
+
*/
|
|
807
|
+
private parseUsers(xml: string): IAMUser[] {
|
|
808
|
+
const memberXmls = parseXmlArray(xml, 'Users', 'member')
|
|
809
|
+
return memberXmls.map((memberXml) => ({
|
|
810
|
+
UserName: parseXmlValue(memberXml, 'UserName') || '',
|
|
811
|
+
UserId: parseXmlValue(memberXml, 'UserId') || '',
|
|
812
|
+
Arn: parseXmlValue(memberXml, 'Arn') || '',
|
|
813
|
+
Path: parseXmlValue(memberXml, 'Path'),
|
|
814
|
+
CreateDate: parseXmlValue(memberXml, 'CreateDate'),
|
|
815
|
+
PasswordLastUsed: parseXmlValue(memberXml, 'PasswordLastUsed'),
|
|
816
|
+
}))
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// ==========================================================================
|
|
820
|
+
// Group Operations
|
|
821
|
+
// ==========================================================================
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Create a new IAM group
|
|
825
|
+
*/
|
|
826
|
+
async createGroup(params: CreateGroupParams): Promise<IAMGroup> {
|
|
827
|
+
const response = await this.request('CreateGroup', params)
|
|
828
|
+
return this.parseGroup(response)
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
/**
|
|
832
|
+
* Get information about an IAM group
|
|
833
|
+
*/
|
|
834
|
+
async getGroup(params: GetGroupParams): Promise<{ Group: IAMGroup; Users: IAMUser[]; IsTruncated: boolean; Marker?: string }> {
|
|
835
|
+
const response = await this.request('GetGroup', params)
|
|
836
|
+
const group = this.parseGroup(response)
|
|
837
|
+
const users = this.parseUsers(response)
|
|
838
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
839
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
840
|
+
return { Group: group, Users: users, IsTruncated: isTruncated, Marker: marker }
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* List IAM groups
|
|
845
|
+
*/
|
|
846
|
+
async listGroups(params: ListGroupsParams = {}): Promise<{ Groups: IAMGroup[]; IsTruncated: boolean; Marker?: string }> {
|
|
847
|
+
const response = await this.request('ListGroups', params)
|
|
848
|
+
const groups = this.parseGroups(response)
|
|
849
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
850
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
851
|
+
return { Groups: groups, IsTruncated: isTruncated, Marker: marker }
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* Update an IAM group
|
|
856
|
+
*/
|
|
857
|
+
async updateGroup(params: UpdateGroupParams): Promise<void> {
|
|
858
|
+
await this.request('UpdateGroup', params)
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* Delete an IAM group
|
|
863
|
+
*/
|
|
864
|
+
async deleteGroup(params: DeleteGroupParams): Promise<void> {
|
|
865
|
+
await this.request('DeleteGroup', params)
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
/**
|
|
869
|
+
* Add a user to a group
|
|
870
|
+
*/
|
|
871
|
+
async addUserToGroup(params: AddUserToGroupParams): Promise<void> {
|
|
872
|
+
await this.request('AddUserToGroup', params)
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* Remove a user from a group
|
|
877
|
+
*/
|
|
878
|
+
async removeUserFromGroup(params: RemoveUserFromGroupParams): Promise<void> {
|
|
879
|
+
await this.request('RemoveUserFromGroup', params)
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* List groups for a user
|
|
884
|
+
*/
|
|
885
|
+
async listGroupsForUser(params: ListGroupsForUserParams): Promise<{ Groups: IAMGroup[]; IsTruncated: boolean; Marker?: string }> {
|
|
886
|
+
const response = await this.request('ListGroupsForUser', params)
|
|
887
|
+
const groups = this.parseGroups(response)
|
|
888
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
889
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
890
|
+
return { Groups: groups, IsTruncated: isTruncated, Marker: marker }
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* Parse group from XML response
|
|
895
|
+
*/
|
|
896
|
+
private parseGroup(xml: string): IAMGroup {
|
|
897
|
+
return {
|
|
898
|
+
GroupName: parseXmlValue(xml, 'GroupName') || '',
|
|
899
|
+
GroupId: parseXmlValue(xml, 'GroupId') || '',
|
|
900
|
+
Arn: parseXmlValue(xml, 'Arn') || '',
|
|
901
|
+
Path: parseXmlValue(xml, 'Path'),
|
|
902
|
+
CreateDate: parseXmlValue(xml, 'CreateDate'),
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Parse groups array from XML response
|
|
908
|
+
*/
|
|
909
|
+
private parseGroups(xml: string): IAMGroup[] {
|
|
910
|
+
const memberXmls = parseXmlArray(xml, 'Groups', 'member')
|
|
911
|
+
return memberXmls.map((memberXml) => ({
|
|
912
|
+
GroupName: parseXmlValue(memberXml, 'GroupName') || '',
|
|
913
|
+
GroupId: parseXmlValue(memberXml, 'GroupId') || '',
|
|
914
|
+
Arn: parseXmlValue(memberXml, 'Arn') || '',
|
|
915
|
+
Path: parseXmlValue(memberXml, 'Path'),
|
|
916
|
+
CreateDate: parseXmlValue(memberXml, 'CreateDate'),
|
|
917
|
+
}))
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
// ==========================================================================
|
|
921
|
+
// Role Operations
|
|
922
|
+
// ==========================================================================
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Create a new IAM role
|
|
926
|
+
*/
|
|
927
|
+
async createRole(params: CreateRoleParams): Promise<IAMRole> {
|
|
928
|
+
const response = await this.request('CreateRole', params)
|
|
929
|
+
return this.parseRole(response)
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* Get information about an IAM role
|
|
934
|
+
*/
|
|
935
|
+
async getRole(params: GetRoleParams): Promise<IAMRole> {
|
|
936
|
+
const response = await this.request('GetRole', params)
|
|
937
|
+
return this.parseRole(response)
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* List IAM roles
|
|
942
|
+
*/
|
|
943
|
+
async listRoles(params: ListRolesParams = {}): Promise<{ Roles: IAMRole[]; IsTruncated: boolean; Marker?: string }> {
|
|
944
|
+
const response = await this.request('ListRoles', params)
|
|
945
|
+
const roles = this.parseRoles(response)
|
|
946
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
947
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
948
|
+
return { Roles: roles, IsTruncated: isTruncated, Marker: marker }
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* Update an IAM role
|
|
953
|
+
*/
|
|
954
|
+
async updateRole(params: UpdateRoleParams): Promise<void> {
|
|
955
|
+
await this.request('UpdateRole', params)
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Update an IAM role description
|
|
960
|
+
*/
|
|
961
|
+
async updateRoleDescription(params: UpdateRoleDescriptionParams): Promise<IAMRole> {
|
|
962
|
+
const response = await this.request('UpdateRoleDescription', params)
|
|
963
|
+
return this.parseRole(response)
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* Update the assume role policy for a role
|
|
968
|
+
*/
|
|
969
|
+
async updateAssumeRolePolicy(params: UpdateAssumeRolePolicyParams): Promise<void> {
|
|
970
|
+
await this.request('UpdateAssumeRolePolicy', params)
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
/**
|
|
974
|
+
* Delete an IAM role
|
|
975
|
+
*/
|
|
976
|
+
async deleteRole(params: DeleteRoleParams): Promise<void> {
|
|
977
|
+
await this.request('DeleteRole', params)
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/**
|
|
981
|
+
* Tag an IAM role
|
|
982
|
+
*/
|
|
983
|
+
async tagRole(params: TagRoleParams): Promise<void> {
|
|
984
|
+
await this.request('TagRole', params)
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* Untag an IAM role
|
|
989
|
+
*/
|
|
990
|
+
async untagRole(params: UntagRoleParams): Promise<void> {
|
|
991
|
+
await this.request('UntagRole', params)
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* List tags for an IAM role
|
|
996
|
+
*/
|
|
997
|
+
async listRoleTags(params: ListRoleTagsParams): Promise<{ Tags: Array<{ Key: string; Value: string }>; IsTruncated: boolean; Marker?: string }> {
|
|
998
|
+
const response = await this.request('ListRoleTags', params)
|
|
999
|
+
const tags = this.parseTags(response)
|
|
1000
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1001
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1002
|
+
return { Tags: tags, IsTruncated: isTruncated, Marker: marker }
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* Parse role from XML response
|
|
1007
|
+
*/
|
|
1008
|
+
private parseRole(xml: string): IAMRole {
|
|
1009
|
+
return {
|
|
1010
|
+
RoleName: parseXmlValue(xml, 'RoleName') || '',
|
|
1011
|
+
RoleId: parseXmlValue(xml, 'RoleId') || '',
|
|
1012
|
+
Arn: parseXmlValue(xml, 'Arn') || '',
|
|
1013
|
+
Path: parseXmlValue(xml, 'Path'),
|
|
1014
|
+
CreateDate: parseXmlValue(xml, 'CreateDate'),
|
|
1015
|
+
AssumeRolePolicyDocument: parseXmlValue(xml, 'AssumeRolePolicyDocument'),
|
|
1016
|
+
Description: parseXmlValue(xml, 'Description'),
|
|
1017
|
+
MaxSessionDuration: parseXmlValue(xml, 'MaxSessionDuration') ? Number.parseInt(parseXmlValue(xml, 'MaxSessionDuration')!, 10) : undefined,
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
* Parse roles array from XML response
|
|
1023
|
+
*/
|
|
1024
|
+
private parseRoles(xml: string): IAMRole[] {
|
|
1025
|
+
const memberXmls = parseXmlArray(xml, 'Roles', 'member')
|
|
1026
|
+
return memberXmls.map((memberXml) => ({
|
|
1027
|
+
RoleName: parseXmlValue(memberXml, 'RoleName') || '',
|
|
1028
|
+
RoleId: parseXmlValue(memberXml, 'RoleId') || '',
|
|
1029
|
+
Arn: parseXmlValue(memberXml, 'Arn') || '',
|
|
1030
|
+
Path: parseXmlValue(memberXml, 'Path'),
|
|
1031
|
+
CreateDate: parseXmlValue(memberXml, 'CreateDate'),
|
|
1032
|
+
AssumeRolePolicyDocument: parseXmlValue(memberXml, 'AssumeRolePolicyDocument'),
|
|
1033
|
+
Description: parseXmlValue(memberXml, 'Description'),
|
|
1034
|
+
MaxSessionDuration: parseXmlValue(memberXml, 'MaxSessionDuration') ? Number.parseInt(parseXmlValue(memberXml, 'MaxSessionDuration')!, 10) : undefined,
|
|
1035
|
+
}))
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/**
|
|
1039
|
+
* Parse tags from XML response
|
|
1040
|
+
*/
|
|
1041
|
+
private parseTags(xml: string): Array<{ Key: string; Value: string }> {
|
|
1042
|
+
const memberXmls = parseXmlArray(xml, 'Tags', 'member')
|
|
1043
|
+
return memberXmls.map((memberXml) => ({
|
|
1044
|
+
Key: parseXmlValue(memberXml, 'Key') || '',
|
|
1045
|
+
Value: parseXmlValue(memberXml, 'Value') || '',
|
|
1046
|
+
}))
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// ==========================================================================
|
|
1050
|
+
// Managed Policy Operations
|
|
1051
|
+
// ==========================================================================
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* Create a new managed policy
|
|
1055
|
+
*/
|
|
1056
|
+
async createPolicy(params: CreatePolicyParams): Promise<IAMPolicy> {
|
|
1057
|
+
const response = await this.request('CreatePolicy', params)
|
|
1058
|
+
return this.parsePolicy(response)
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* Get information about a managed policy
|
|
1063
|
+
*/
|
|
1064
|
+
async getPolicy(params: GetPolicyParams): Promise<IAMPolicy> {
|
|
1065
|
+
const response = await this.request('GetPolicy', params)
|
|
1066
|
+
return this.parsePolicy(response)
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* Get a specific version of a managed policy
|
|
1071
|
+
*/
|
|
1072
|
+
async getPolicyVersion(params: GetPolicyVersionParams): Promise<PolicyVersion> {
|
|
1073
|
+
const response = await this.request('GetPolicyVersion', params)
|
|
1074
|
+
return {
|
|
1075
|
+
VersionId: parseXmlValue(response, 'VersionId') || '',
|
|
1076
|
+
IsDefaultVersion: parseXmlValue(response, 'IsDefaultVersion') === 'true',
|
|
1077
|
+
CreateDate: parseXmlValue(response, 'CreateDate'),
|
|
1078
|
+
Document: parseXmlValue(response, 'Document'),
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/**
|
|
1083
|
+
* List managed policies
|
|
1084
|
+
*/
|
|
1085
|
+
async listPolicies(params: ListPoliciesParams = {}): Promise<{ Policies: IAMPolicy[]; IsTruncated: boolean; Marker?: string }> {
|
|
1086
|
+
const response = await this.request('ListPolicies', params)
|
|
1087
|
+
const policies = this.parsePolicies(response)
|
|
1088
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1089
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1090
|
+
return { Policies: policies, IsTruncated: isTruncated, Marker: marker }
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* List versions of a managed policy
|
|
1095
|
+
*/
|
|
1096
|
+
async listPolicyVersions(params: ListPolicyVersionsParams): Promise<{ Versions: PolicyVersion[]; IsTruncated: boolean; Marker?: string }> {
|
|
1097
|
+
const response = await this.request('ListPolicyVersions', params)
|
|
1098
|
+
const versions = this.parsePolicyVersions(response)
|
|
1099
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1100
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1101
|
+
return { Versions: versions, IsTruncated: isTruncated, Marker: marker }
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
/**
|
|
1105
|
+
* Create a new version of a managed policy
|
|
1106
|
+
*/
|
|
1107
|
+
async createPolicyVersion(params: CreatePolicyVersionParams): Promise<PolicyVersion> {
|
|
1108
|
+
const response = await this.request('CreatePolicyVersion', params)
|
|
1109
|
+
return {
|
|
1110
|
+
VersionId: parseXmlValue(response, 'VersionId') || '',
|
|
1111
|
+
IsDefaultVersion: parseXmlValue(response, 'IsDefaultVersion') === 'true',
|
|
1112
|
+
CreateDate: parseXmlValue(response, 'CreateDate'),
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
/**
|
|
1117
|
+
* Delete a version of a managed policy
|
|
1118
|
+
*/
|
|
1119
|
+
async deletePolicyVersion(params: DeletePolicyVersionParams): Promise<void> {
|
|
1120
|
+
await this.request('DeletePolicyVersion', params)
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
/**
|
|
1124
|
+
* Set the default version of a managed policy
|
|
1125
|
+
*/
|
|
1126
|
+
async setDefaultPolicyVersion(params: SetDefaultPolicyVersionParams): Promise<void> {
|
|
1127
|
+
await this.request('SetDefaultPolicyVersion', params)
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
/**
|
|
1131
|
+
* Delete a managed policy
|
|
1132
|
+
*/
|
|
1133
|
+
async deletePolicy(params: DeletePolicyParams): Promise<void> {
|
|
1134
|
+
await this.request('DeletePolicy', params)
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
/**
|
|
1138
|
+
* Attach a managed policy to a user
|
|
1139
|
+
*/
|
|
1140
|
+
async attachUserPolicy(params: AttachUserPolicyParams): Promise<void> {
|
|
1141
|
+
await this.request('AttachUserPolicy', params)
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/**
|
|
1145
|
+
* Detach a managed policy from a user
|
|
1146
|
+
*/
|
|
1147
|
+
async detachUserPolicy(params: DetachUserPolicyParams): Promise<void> {
|
|
1148
|
+
await this.request('DetachUserPolicy', params)
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
/**
|
|
1152
|
+
* Attach a managed policy to a group
|
|
1153
|
+
*/
|
|
1154
|
+
async attachGroupPolicy(params: AttachGroupPolicyParams): Promise<void> {
|
|
1155
|
+
await this.request('AttachGroupPolicy', params)
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
/**
|
|
1159
|
+
* Detach a managed policy from a group
|
|
1160
|
+
*/
|
|
1161
|
+
async detachGroupPolicy(params: DetachGroupPolicyParams): Promise<void> {
|
|
1162
|
+
await this.request('DetachGroupPolicy', params)
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
/**
|
|
1166
|
+
* Attach a managed policy to a role
|
|
1167
|
+
*/
|
|
1168
|
+
async attachRolePolicy(params: AttachRolePolicyParams): Promise<void> {
|
|
1169
|
+
await this.request('AttachRolePolicy', params)
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
/**
|
|
1173
|
+
* Detach a managed policy from a role
|
|
1174
|
+
*/
|
|
1175
|
+
async detachRolePolicy(params: DetachRolePolicyParams): Promise<void> {
|
|
1176
|
+
await this.request('DetachRolePolicy', params)
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
/**
|
|
1180
|
+
* List managed policies attached to a user
|
|
1181
|
+
*/
|
|
1182
|
+
async listAttachedUserPolicies(params: ListAttachedUserPoliciesParams): Promise<{ AttachedPolicies: Array<{ PolicyName: string; PolicyArn: string }>; IsTruncated: boolean; Marker?: string }> {
|
|
1183
|
+
const response = await this.request('ListAttachedUserPolicies', params)
|
|
1184
|
+
const policies = this.parseAttachedPolicies(response)
|
|
1185
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1186
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1187
|
+
return { AttachedPolicies: policies, IsTruncated: isTruncated, Marker: marker }
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
/**
|
|
1191
|
+
* List managed policies attached to a group
|
|
1192
|
+
*/
|
|
1193
|
+
async listAttachedGroupPolicies(params: ListAttachedGroupPoliciesParams): Promise<{ AttachedPolicies: Array<{ PolicyName: string; PolicyArn: string }>; IsTruncated: boolean; Marker?: string }> {
|
|
1194
|
+
const response = await this.request('ListAttachedGroupPolicies', params)
|
|
1195
|
+
const policies = this.parseAttachedPolicies(response)
|
|
1196
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1197
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1198
|
+
return { AttachedPolicies: policies, IsTruncated: isTruncated, Marker: marker }
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
/**
|
|
1202
|
+
* List managed policies attached to a role
|
|
1203
|
+
*/
|
|
1204
|
+
async listAttachedRolePolicies(params: ListAttachedRolePoliciesParams): Promise<{ AttachedPolicies: Array<{ PolicyName: string; PolicyArn: string }>; IsTruncated: boolean; Marker?: string }> {
|
|
1205
|
+
const response = await this.request('ListAttachedRolePolicies', params)
|
|
1206
|
+
const policies = this.parseAttachedPolicies(response)
|
|
1207
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1208
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1209
|
+
return { AttachedPolicies: policies, IsTruncated: isTruncated, Marker: marker }
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/**
|
|
1213
|
+
* Parse policy from XML response
|
|
1214
|
+
*/
|
|
1215
|
+
private parsePolicy(xml: string): IAMPolicy {
|
|
1216
|
+
return {
|
|
1217
|
+
PolicyName: parseXmlValue(xml, 'PolicyName') || '',
|
|
1218
|
+
PolicyId: parseXmlValue(xml, 'PolicyId') || '',
|
|
1219
|
+
Arn: parseXmlValue(xml, 'Arn') || '',
|
|
1220
|
+
Path: parseXmlValue(xml, 'Path'),
|
|
1221
|
+
DefaultVersionId: parseXmlValue(xml, 'DefaultVersionId'),
|
|
1222
|
+
AttachmentCount: parseXmlValue(xml, 'AttachmentCount') ? Number.parseInt(parseXmlValue(xml, 'AttachmentCount')!, 10) : undefined,
|
|
1223
|
+
PermissionsBoundaryUsageCount: parseXmlValue(xml, 'PermissionsBoundaryUsageCount') ? Number.parseInt(parseXmlValue(xml, 'PermissionsBoundaryUsageCount')!, 10) : undefined,
|
|
1224
|
+
IsAttachable: parseXmlValue(xml, 'IsAttachable') === 'true',
|
|
1225
|
+
Description: parseXmlValue(xml, 'Description'),
|
|
1226
|
+
CreateDate: parseXmlValue(xml, 'CreateDate'),
|
|
1227
|
+
UpdateDate: parseXmlValue(xml, 'UpdateDate'),
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
/**
|
|
1232
|
+
* Parse policies array from XML response
|
|
1233
|
+
*/
|
|
1234
|
+
private parsePolicies(xml: string): IAMPolicy[] {
|
|
1235
|
+
const memberXmls = parseXmlArray(xml, 'Policies', 'member')
|
|
1236
|
+
return memberXmls.map((memberXml) => ({
|
|
1237
|
+
PolicyName: parseXmlValue(memberXml, 'PolicyName') || '',
|
|
1238
|
+
PolicyId: parseXmlValue(memberXml, 'PolicyId') || '',
|
|
1239
|
+
Arn: parseXmlValue(memberXml, 'Arn') || '',
|
|
1240
|
+
Path: parseXmlValue(memberXml, 'Path'),
|
|
1241
|
+
DefaultVersionId: parseXmlValue(memberXml, 'DefaultVersionId'),
|
|
1242
|
+
AttachmentCount: parseXmlValue(memberXml, 'AttachmentCount') ? Number.parseInt(parseXmlValue(memberXml, 'AttachmentCount')!, 10) : undefined,
|
|
1243
|
+
PermissionsBoundaryUsageCount: parseXmlValue(memberXml, 'PermissionsBoundaryUsageCount') ? Number.parseInt(parseXmlValue(memberXml, 'PermissionsBoundaryUsageCount')!, 10) : undefined,
|
|
1244
|
+
IsAttachable: parseXmlValue(memberXml, 'IsAttachable') === 'true',
|
|
1245
|
+
Description: parseXmlValue(memberXml, 'Description'),
|
|
1246
|
+
CreateDate: parseXmlValue(memberXml, 'CreateDate'),
|
|
1247
|
+
UpdateDate: parseXmlValue(memberXml, 'UpdateDate'),
|
|
1248
|
+
}))
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
/**
|
|
1252
|
+
* Parse policy versions from XML response
|
|
1253
|
+
*/
|
|
1254
|
+
private parsePolicyVersions(xml: string): PolicyVersion[] {
|
|
1255
|
+
const memberXmls = parseXmlArray(xml, 'Versions', 'member')
|
|
1256
|
+
return memberXmls.map((memberXml) => ({
|
|
1257
|
+
VersionId: parseXmlValue(memberXml, 'VersionId') || '',
|
|
1258
|
+
IsDefaultVersion: parseXmlValue(memberXml, 'IsDefaultVersion') === 'true',
|
|
1259
|
+
CreateDate: parseXmlValue(memberXml, 'CreateDate'),
|
|
1260
|
+
}))
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
/**
|
|
1264
|
+
* Parse attached policies from XML response
|
|
1265
|
+
*/
|
|
1266
|
+
private parseAttachedPolicies(xml: string): Array<{ PolicyName: string; PolicyArn: string }> {
|
|
1267
|
+
const memberXmls = parseXmlArray(xml, 'AttachedPolicies', 'member')
|
|
1268
|
+
return memberXmls.map((memberXml) => ({
|
|
1269
|
+
PolicyName: parseXmlValue(memberXml, 'PolicyName') || '',
|
|
1270
|
+
PolicyArn: parseXmlValue(memberXml, 'PolicyArn') || '',
|
|
1271
|
+
}))
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
// ==========================================================================
|
|
1275
|
+
// Inline Policy Operations
|
|
1276
|
+
// ==========================================================================
|
|
1277
|
+
|
|
1278
|
+
/**
|
|
1279
|
+
* Add or update an inline policy for a user
|
|
1280
|
+
*/
|
|
1281
|
+
async putUserPolicy(params: PutUserPolicyParams): Promise<void> {
|
|
1282
|
+
await this.request('PutUserPolicy', params)
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
/**
|
|
1286
|
+
* Get an inline policy for a user
|
|
1287
|
+
*/
|
|
1288
|
+
async getUserPolicy(params: GetUserPolicyParams): Promise<{ UserName: string; PolicyName: string; PolicyDocument: string }> {
|
|
1289
|
+
const response = await this.request('GetUserPolicy', params)
|
|
1290
|
+
return {
|
|
1291
|
+
UserName: parseXmlValue(response, 'UserName') || '',
|
|
1292
|
+
PolicyName: parseXmlValue(response, 'PolicyName') || '',
|
|
1293
|
+
PolicyDocument: decodeURIComponent(parseXmlValue(response, 'PolicyDocument') || ''),
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
/**
|
|
1298
|
+
* Delete an inline policy from a user
|
|
1299
|
+
*/
|
|
1300
|
+
async deleteUserPolicy(params: DeleteUserPolicyParams): Promise<void> {
|
|
1301
|
+
await this.request('DeleteUserPolicy', params)
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
/**
|
|
1305
|
+
* List inline policies for a user
|
|
1306
|
+
*/
|
|
1307
|
+
async listUserPolicies(params: ListUserPoliciesParams): Promise<{ PolicyNames: string[]; IsTruncated: boolean; Marker?: string }> {
|
|
1308
|
+
const response = await this.request('ListUserPolicies', params)
|
|
1309
|
+
const policyNames = parseXmlArray(response, 'PolicyNames', 'member')
|
|
1310
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1311
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1312
|
+
return { PolicyNames: policyNames, IsTruncated: isTruncated, Marker: marker }
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
/**
|
|
1316
|
+
* Add or update an inline policy for a group
|
|
1317
|
+
*/
|
|
1318
|
+
async putGroupPolicy(params: PutGroupPolicyParams): Promise<void> {
|
|
1319
|
+
await this.request('PutGroupPolicy', params)
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
/**
|
|
1323
|
+
* Get an inline policy for a group
|
|
1324
|
+
*/
|
|
1325
|
+
async getGroupPolicy(params: GetGroupPolicyParams): Promise<{ GroupName: string; PolicyName: string; PolicyDocument: string }> {
|
|
1326
|
+
const response = await this.request('GetGroupPolicy', params)
|
|
1327
|
+
return {
|
|
1328
|
+
GroupName: parseXmlValue(response, 'GroupName') || '',
|
|
1329
|
+
PolicyName: parseXmlValue(response, 'PolicyName') || '',
|
|
1330
|
+
PolicyDocument: decodeURIComponent(parseXmlValue(response, 'PolicyDocument') || ''),
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
/**
|
|
1335
|
+
* Delete an inline policy from a group
|
|
1336
|
+
*/
|
|
1337
|
+
async deleteGroupPolicy(params: DeleteGroupPolicyParams): Promise<void> {
|
|
1338
|
+
await this.request('DeleteGroupPolicy', params)
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
/**
|
|
1342
|
+
* List inline policies for a group
|
|
1343
|
+
*/
|
|
1344
|
+
async listGroupPolicies(params: ListGroupPoliciesParams): Promise<{ PolicyNames: string[]; IsTruncated: boolean; Marker?: string }> {
|
|
1345
|
+
const response = await this.request('ListGroupPolicies', params)
|
|
1346
|
+
const policyNames = parseXmlArray(response, 'PolicyNames', 'member')
|
|
1347
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1348
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1349
|
+
return { PolicyNames: policyNames, IsTruncated: isTruncated, Marker: marker }
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
/**
|
|
1353
|
+
* Add or update an inline policy for a role
|
|
1354
|
+
*/
|
|
1355
|
+
async putRolePolicy(params: PutRolePolicyParams): Promise<void> {
|
|
1356
|
+
await this.request('PutRolePolicy', params)
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
/**
|
|
1360
|
+
* Get an inline policy for a role
|
|
1361
|
+
*/
|
|
1362
|
+
async getRolePolicy(params: GetRolePolicyParams): Promise<{ RoleName: string; PolicyName: string; PolicyDocument: string }> {
|
|
1363
|
+
const response = await this.request('GetRolePolicy', params)
|
|
1364
|
+
return {
|
|
1365
|
+
RoleName: parseXmlValue(response, 'RoleName') || '',
|
|
1366
|
+
PolicyName: parseXmlValue(response, 'PolicyName') || '',
|
|
1367
|
+
PolicyDocument: decodeURIComponent(parseXmlValue(response, 'PolicyDocument') || ''),
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
/**
|
|
1372
|
+
* Delete an inline policy from a role
|
|
1373
|
+
*/
|
|
1374
|
+
async deleteRolePolicy(params: DeleteRolePolicyParams): Promise<void> {
|
|
1375
|
+
await this.request('DeleteRolePolicy', params)
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
/**
|
|
1379
|
+
* List inline policies for a role
|
|
1380
|
+
*/
|
|
1381
|
+
async listRolePolicies(params: ListRolePoliciesParams): Promise<{ PolicyNames: string[]; IsTruncated: boolean; Marker?: string }> {
|
|
1382
|
+
const response = await this.request('ListRolePolicies', params)
|
|
1383
|
+
const policyNames = parseXmlArray(response, 'PolicyNames', 'member')
|
|
1384
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1385
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1386
|
+
return { PolicyNames: policyNames, IsTruncated: isTruncated, Marker: marker }
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
// ==========================================================================
|
|
1390
|
+
// Access Key Operations
|
|
1391
|
+
// ==========================================================================
|
|
1392
|
+
|
|
1393
|
+
/**
|
|
1394
|
+
* Create an access key for a user
|
|
1395
|
+
*/
|
|
1396
|
+
async createAccessKey(params: CreateAccessKeyParams = {}): Promise<CreateAccessKeyResult> {
|
|
1397
|
+
const response = await this.request('CreateAccessKey', params)
|
|
1398
|
+
|
|
1399
|
+
// Handle both string (XML) and object (parsed) responses
|
|
1400
|
+
if (typeof response === 'object') {
|
|
1401
|
+
const accessKey = (response as any)?.CreateAccessKeyResult?.AccessKey
|
|
1402
|
+
|| (response as any)?.AccessKey
|
|
1403
|
+
if (accessKey) {
|
|
1404
|
+
return {
|
|
1405
|
+
AccessKey: {
|
|
1406
|
+
UserName: accessKey.UserName || '',
|
|
1407
|
+
AccessKeyId: accessKey.AccessKeyId || '',
|
|
1408
|
+
Status: (accessKey.Status as 'Active' | 'Inactive') || 'Active',
|
|
1409
|
+
SecretAccessKey: accessKey.SecretAccessKey || '',
|
|
1410
|
+
CreateDate: accessKey.CreateDate,
|
|
1411
|
+
},
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
// Fallback to XML parsing for string responses
|
|
1417
|
+
return {
|
|
1418
|
+
AccessKey: {
|
|
1419
|
+
UserName: parseXmlValue(response as string, 'UserName') || '',
|
|
1420
|
+
AccessKeyId: parseXmlValue(response as string, 'AccessKeyId') || '',
|
|
1421
|
+
Status: (parseXmlValue(response as string, 'Status') as 'Active' | 'Inactive') || 'Active',
|
|
1422
|
+
SecretAccessKey: parseXmlValue(response as string, 'SecretAccessKey') || '',
|
|
1423
|
+
CreateDate: parseXmlValue(response as string, 'CreateDate'),
|
|
1424
|
+
},
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
/**
|
|
1429
|
+
* List access keys for a user
|
|
1430
|
+
*/
|
|
1431
|
+
async listAccessKeys(params: ListAccessKeysParams = {}): Promise<{ AccessKeyMetadata: AccessKeyMetadata[]; IsTruncated: boolean; Marker?: string }> {
|
|
1432
|
+
const response = await this.request('ListAccessKeys', params)
|
|
1433
|
+
const keys = this.parseAccessKeys(response)
|
|
1434
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1435
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1436
|
+
return { AccessKeyMetadata: keys, IsTruncated: isTruncated, Marker: marker }
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
/**
|
|
1440
|
+
* Update an access key status
|
|
1441
|
+
*/
|
|
1442
|
+
async updateAccessKey(params: UpdateAccessKeyParams): Promise<void> {
|
|
1443
|
+
await this.request('UpdateAccessKey', params)
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
/**
|
|
1447
|
+
* Delete an access key
|
|
1448
|
+
*/
|
|
1449
|
+
async deleteAccessKey(params: DeleteAccessKeyParams): Promise<void> {
|
|
1450
|
+
await this.request('DeleteAccessKey', params)
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
/**
|
|
1454
|
+
* Get information about when an access key was last used
|
|
1455
|
+
*/
|
|
1456
|
+
async getAccessKeyLastUsed(params: GetAccessKeyLastUsedParams): Promise<{ UserName: string; AccessKeyLastUsed: { LastUsedDate?: string; ServiceName?: string; Region?: string } }> {
|
|
1457
|
+
const response = await this.request('GetAccessKeyLastUsed', params)
|
|
1458
|
+
return {
|
|
1459
|
+
UserName: parseXmlValue(response, 'UserName') || '',
|
|
1460
|
+
AccessKeyLastUsed: {
|
|
1461
|
+
LastUsedDate: parseXmlValue(response, 'LastUsedDate'),
|
|
1462
|
+
ServiceName: parseXmlValue(response, 'ServiceName'),
|
|
1463
|
+
Region: parseXmlValue(response, 'Region'),
|
|
1464
|
+
},
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
/**
|
|
1469
|
+
* Parse access keys from XML response
|
|
1470
|
+
*/
|
|
1471
|
+
private parseAccessKeys(xml: string): AccessKeyMetadata[] {
|
|
1472
|
+
const memberXmls = parseXmlArray(xml, 'AccessKeyMetadata', 'member')
|
|
1473
|
+
return memberXmls.map((memberXml) => ({
|
|
1474
|
+
UserName: parseXmlValue(memberXml, 'UserName'),
|
|
1475
|
+
AccessKeyId: parseXmlValue(memberXml, 'AccessKeyId') || '',
|
|
1476
|
+
Status: (parseXmlValue(memberXml, 'Status') as 'Active' | 'Inactive') || 'Active',
|
|
1477
|
+
CreateDate: parseXmlValue(memberXml, 'CreateDate'),
|
|
1478
|
+
}))
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
// ==========================================================================
|
|
1482
|
+
// Instance Profile Operations
|
|
1483
|
+
// ==========================================================================
|
|
1484
|
+
|
|
1485
|
+
/**
|
|
1486
|
+
* Create an instance profile
|
|
1487
|
+
*/
|
|
1488
|
+
async createInstanceProfile(params: CreateInstanceProfileParams): Promise<InstanceProfile> {
|
|
1489
|
+
const response = await this.request('CreateInstanceProfile', params)
|
|
1490
|
+
return this.parseInstanceProfile(response)
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
/**
|
|
1494
|
+
* Get information about an instance profile
|
|
1495
|
+
*/
|
|
1496
|
+
async getInstanceProfile(params: GetInstanceProfileParams): Promise<InstanceProfile> {
|
|
1497
|
+
const response = await this.request('GetInstanceProfile', params)
|
|
1498
|
+
return this.parseInstanceProfile(response)
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
/**
|
|
1502
|
+
* List instance profiles
|
|
1503
|
+
*/
|
|
1504
|
+
async listInstanceProfiles(params: ListInstanceProfilesParams = {}): Promise<{ InstanceProfiles: InstanceProfile[]; IsTruncated: boolean; Marker?: string }> {
|
|
1505
|
+
const response = await this.request('ListInstanceProfiles', params)
|
|
1506
|
+
const profiles = this.parseInstanceProfiles(response)
|
|
1507
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1508
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1509
|
+
return { InstanceProfiles: profiles, IsTruncated: isTruncated, Marker: marker }
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
/**
|
|
1513
|
+
* List instance profiles for a role
|
|
1514
|
+
*/
|
|
1515
|
+
async listInstanceProfilesForRole(params: ListInstanceProfilesForRoleParams): Promise<{ InstanceProfiles: InstanceProfile[]; IsTruncated: boolean; Marker?: string }> {
|
|
1516
|
+
const response = await this.request('ListInstanceProfilesForRole', params)
|
|
1517
|
+
const profiles = this.parseInstanceProfiles(response)
|
|
1518
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1519
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1520
|
+
return { InstanceProfiles: profiles, IsTruncated: isTruncated, Marker: marker }
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
/**
|
|
1524
|
+
* Add a role to an instance profile
|
|
1525
|
+
*/
|
|
1526
|
+
async addRoleToInstanceProfile(params: AddRoleToInstanceProfileParams): Promise<void> {
|
|
1527
|
+
await this.request('AddRoleToInstanceProfile', params)
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
/**
|
|
1531
|
+
* Remove a role from an instance profile
|
|
1532
|
+
*/
|
|
1533
|
+
async removeRoleFromInstanceProfile(params: RemoveRoleFromInstanceProfileParams): Promise<void> {
|
|
1534
|
+
await this.request('RemoveRoleFromInstanceProfile', params)
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
/**
|
|
1538
|
+
* Delete an instance profile
|
|
1539
|
+
*/
|
|
1540
|
+
async deleteInstanceProfile(params: DeleteInstanceProfileParams): Promise<void> {
|
|
1541
|
+
await this.request('DeleteInstanceProfile', params)
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
/**
|
|
1545
|
+
* Parse instance profile from XML response
|
|
1546
|
+
*/
|
|
1547
|
+
private parseInstanceProfile(xml: string): InstanceProfile {
|
|
1548
|
+
return {
|
|
1549
|
+
InstanceProfileName: parseXmlValue(xml, 'InstanceProfileName') || '',
|
|
1550
|
+
InstanceProfileId: parseXmlValue(xml, 'InstanceProfileId') || '',
|
|
1551
|
+
Arn: parseXmlValue(xml, 'Arn') || '',
|
|
1552
|
+
Path: parseXmlValue(xml, 'Path'),
|
|
1553
|
+
CreateDate: parseXmlValue(xml, 'CreateDate'),
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
/**
|
|
1558
|
+
* Parse instance profiles from XML response
|
|
1559
|
+
*/
|
|
1560
|
+
private parseInstanceProfiles(xml: string): InstanceProfile[] {
|
|
1561
|
+
const memberXmls = parseXmlArray(xml, 'InstanceProfiles', 'member')
|
|
1562
|
+
return memberXmls.map((memberXml) => ({
|
|
1563
|
+
InstanceProfileName: parseXmlValue(memberXml, 'InstanceProfileName') || '',
|
|
1564
|
+
InstanceProfileId: parseXmlValue(memberXml, 'InstanceProfileId') || '',
|
|
1565
|
+
Arn: parseXmlValue(memberXml, 'Arn') || '',
|
|
1566
|
+
Path: parseXmlValue(memberXml, 'Path'),
|
|
1567
|
+
CreateDate: parseXmlValue(memberXml, 'CreateDate'),
|
|
1568
|
+
}))
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
// ==========================================================================
|
|
1572
|
+
// Account Operations
|
|
1573
|
+
// ==========================================================================
|
|
1574
|
+
|
|
1575
|
+
/**
|
|
1576
|
+
* Get account password policy
|
|
1577
|
+
*/
|
|
1578
|
+
async getAccountPasswordPolicy(): Promise<PasswordPolicy> {
|
|
1579
|
+
const response = await this.request('GetAccountPasswordPolicy')
|
|
1580
|
+
return {
|
|
1581
|
+
MinimumPasswordLength: parseXmlValue(response, 'MinimumPasswordLength') ? Number.parseInt(parseXmlValue(response, 'MinimumPasswordLength')!, 10) : undefined,
|
|
1582
|
+
RequireSymbols: parseXmlValue(response, 'RequireSymbols') === 'true',
|
|
1583
|
+
RequireNumbers: parseXmlValue(response, 'RequireNumbers') === 'true',
|
|
1584
|
+
RequireUppercaseCharacters: parseXmlValue(response, 'RequireUppercaseCharacters') === 'true',
|
|
1585
|
+
RequireLowercaseCharacters: parseXmlValue(response, 'RequireLowercaseCharacters') === 'true',
|
|
1586
|
+
AllowUsersToChangePassword: parseXmlValue(response, 'AllowUsersToChangePassword') === 'true',
|
|
1587
|
+
ExpirePasswords: parseXmlValue(response, 'ExpirePasswords') === 'true',
|
|
1588
|
+
MaxPasswordAge: parseXmlValue(response, 'MaxPasswordAge') ? Number.parseInt(parseXmlValue(response, 'MaxPasswordAge')!, 10) : undefined,
|
|
1589
|
+
PasswordReusePrevention: parseXmlValue(response, 'PasswordReusePrevention') ? Number.parseInt(parseXmlValue(response, 'PasswordReusePrevention')!, 10) : undefined,
|
|
1590
|
+
HardExpiry: parseXmlValue(response, 'HardExpiry') === 'true',
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
/**
|
|
1595
|
+
* Update account password policy
|
|
1596
|
+
*/
|
|
1597
|
+
async updateAccountPasswordPolicy(params: UpdateAccountPasswordPolicyParams): Promise<void> {
|
|
1598
|
+
await this.request('UpdateAccountPasswordPolicy', params)
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
/**
|
|
1602
|
+
* Delete account password policy
|
|
1603
|
+
*/
|
|
1604
|
+
async deleteAccountPasswordPolicy(): Promise<void> {
|
|
1605
|
+
await this.request('DeleteAccountPasswordPolicy')
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
/**
|
|
1609
|
+
* Get account summary
|
|
1610
|
+
*/
|
|
1611
|
+
async getAccountSummary(): Promise<AccountSummary> {
|
|
1612
|
+
const response = await this.request('GetAccountSummary')
|
|
1613
|
+
const summary: AccountSummary = {}
|
|
1614
|
+
|
|
1615
|
+
// Parse the SummaryMap entries
|
|
1616
|
+
const entries = parseXmlArray(response, 'SummaryMap', 'entry')
|
|
1617
|
+
for (const entry of entries) {
|
|
1618
|
+
const key = parseXmlValue(entry, 'key')
|
|
1619
|
+
const value = parseXmlValue(entry, 'value')
|
|
1620
|
+
if (key && value) {
|
|
1621
|
+
(summary as Record<string, number>)[key] = Number.parseInt(value, 10)
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
return summary
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
/**
|
|
1629
|
+
* Get the account alias
|
|
1630
|
+
*/
|
|
1631
|
+
async listAccountAliases(): Promise<{ AccountAliases: string[]; IsTruncated: boolean; Marker?: string }> {
|
|
1632
|
+
const response = await this.request('ListAccountAliases')
|
|
1633
|
+
const aliases = parseXmlArray(response, 'AccountAliases', 'member')
|
|
1634
|
+
const isTruncated = parseXmlValue(response, 'IsTruncated') === 'true'
|
|
1635
|
+
const marker = parseXmlValue(response, 'Marker')
|
|
1636
|
+
return { AccountAliases: aliases, IsTruncated: isTruncated, Marker: marker }
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
/**
|
|
1640
|
+
* Create an account alias
|
|
1641
|
+
*/
|
|
1642
|
+
async createAccountAlias(params: { AccountAlias: string }): Promise<void> {
|
|
1643
|
+
await this.request('CreateAccountAlias', params)
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
/**
|
|
1647
|
+
* Delete an account alias
|
|
1648
|
+
*/
|
|
1649
|
+
async deleteAccountAlias(params: { AccountAlias: string }): Promise<void> {
|
|
1650
|
+
await this.request('DeleteAccountAlias', params)
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
// ==========================================================================
|
|
1654
|
+
// Policy Simulation Operations
|
|
1655
|
+
// ==========================================================================
|
|
1656
|
+
|
|
1657
|
+
/**
|
|
1658
|
+
* Simulate the effect of policies attached to a principal
|
|
1659
|
+
*/
|
|
1660
|
+
async simulatePrincipalPolicy(params: SimulatePrincipalPolicyParams): Promise<SimulatePolicyResponse> {
|
|
1661
|
+
const response = await this.request('SimulatePrincipalPolicy', params)
|
|
1662
|
+
return this.parseSimulationResults(response)
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
/**
|
|
1666
|
+
* Parse simulation results from XML response
|
|
1667
|
+
*/
|
|
1668
|
+
private parseSimulationResults(xml: string): SimulatePolicyResponse {
|
|
1669
|
+
const resultXmls = parseXmlArray(xml, 'EvaluationResults', 'member')
|
|
1670
|
+
const evaluationResults: EvaluationResult[] = resultXmls.map((resultXml) => {
|
|
1671
|
+
const matchedStatementXmls = parseXmlArray(resultXml, 'MatchedStatements', 'member')
|
|
1672
|
+
const matchedStatements = matchedStatementXmls.map((stmtXml) => ({
|
|
1673
|
+
SourcePolicyId: parseXmlValue(stmtXml, 'SourcePolicyId'),
|
|
1674
|
+
SourcePolicyType: parseXmlValue(stmtXml, 'SourcePolicyType'),
|
|
1675
|
+
}))
|
|
1676
|
+
|
|
1677
|
+
return {
|
|
1678
|
+
EvalActionName: parseXmlValue(resultXml, 'EvalActionName') || '',
|
|
1679
|
+
EvalResourceName: parseXmlValue(resultXml, 'EvalResourceName'),
|
|
1680
|
+
EvalDecision: parseXmlValue(resultXml, 'EvalDecision') || '',
|
|
1681
|
+
MatchedStatements: matchedStatements.length > 0 ? matchedStatements : undefined,
|
|
1682
|
+
}
|
|
1683
|
+
})
|
|
1684
|
+
|
|
1685
|
+
const isTruncated = parseXmlValue(xml, 'IsTruncated') === 'true'
|
|
1686
|
+
const marker = parseXmlValue(xml, 'Marker')
|
|
1687
|
+
return { EvaluationResults: evaluationResults, IsTruncated: isTruncated, Marker: marker }
|
|
1688
|
+
}
|
|
1689
|
+
}
|