@stacksjs/ts-cloud 0.9.3 → 0.9.4

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.
Files changed (143) hide show
  1. package/dist/aws/index.js +1 -269
  2. package/dist/bin/chunk-00kg80qg.js +1 -0
  3. package/dist/bin/{chunk-hzqw8xm5.js → chunk-1k5kszjp.js} +1 -1
  4. package/dist/bin/{chunk-9v39615t.js → chunk-21e0mavm.js} +1 -1
  5. package/dist/bin/{chunk-waayf9ay.js → chunk-2empps47.js} +1 -1
  6. package/dist/bin/{chunk-14cwr6eh.js → chunk-3vqfexc4.js} +1 -1
  7. package/dist/bin/chunk-5ectjq0b.js +1 -0
  8. package/dist/bin/{chunk-b5gd39s8.js → chunk-5erkxpt7.js} +4 -4
  9. package/dist/bin/{chunk-41x17hw1.js → chunk-5mrtzemj.js} +1 -1
  10. package/dist/bin/{chunk-p8q9bq9g.js → chunk-5n9fmabb.js} +1 -1
  11. package/dist/bin/{chunk-gqf6jsmy.js → chunk-9knpg30y.js} +1 -1
  12. package/dist/bin/{chunk-r3kv0vm9.js → chunk-ddk4rt4j.js} +1 -1
  13. package/dist/bin/{chunk-avm7tnwe.js → chunk-e0rkrq70.js} +1 -1
  14. package/dist/bin/{chunk-ry030a6b.js → chunk-etrb03mt.js} +1 -1
  15. package/dist/bin/{chunk-8v7ddyvf.js → chunk-k9t9wvms.js} +1 -1
  16. package/dist/bin/{chunk-92mea34a.js → chunk-m7dgskt1.js} +1 -1
  17. package/dist/bin/{chunk-3r4fb59r.js → chunk-mz0wbbsj.js} +1 -1
  18. package/dist/bin/{chunk-b9qbp8j1.js → chunk-qk9qgepa.js} +1 -1
  19. package/dist/bin/chunk-rxcvf10f.js +7364 -0
  20. package/dist/bin/{chunk-r9hjwcj9.js → chunk-tga3hhwk.js} +1 -1
  21. package/dist/bin/{chunk-ynjvbphf.js → chunk-tx0tqq2k.js} +1 -1
  22. package/dist/bin/{chunk-57y1zxbf.js → chunk-vm3q5gf2.js} +1 -1
  23. package/dist/bin/{chunk-bz828v8q.js → chunk-y7s5r8y6.js} +1 -1
  24. package/dist/bin/{chunk-sgyffpgm.js → chunk-zmegvjp8.js} +1 -1
  25. package/dist/bin/cli.js +14 -14
  26. package/dist/bin/dashboard-server.js +1 -1
  27. package/dist/chunk-0ccta6z6.js +6 -0
  28. package/dist/chunk-0k1cs6pp.js +1 -0
  29. package/dist/chunk-1egjn203.js +704 -0
  30. package/dist/chunk-2wx29qga.js +5 -0
  31. package/dist/chunk-5m5rqmv7.js +1 -0
  32. package/dist/chunk-8ea5022g.js +114 -0
  33. package/dist/chunk-8xqn3c0w.js +2 -0
  34. package/dist/chunk-b4esxhmw.js +2 -0
  35. package/dist/chunk-b8e5wzwn.js +44 -0
  36. package/dist/chunk-bggt4n6e.js +2 -0
  37. package/dist/chunk-cwkg37rs.js +37 -0
  38. package/dist/chunk-dskvqt67.js +7355 -0
  39. package/dist/chunk-gahsdmxf.js +1617 -0
  40. package/dist/chunk-gnv3r2jg.js +1 -0
  41. package/dist/chunk-hg3c48cp.js +34 -0
  42. package/dist/chunk-m5azeva3.js +2 -0
  43. package/dist/chunk-r3qf56b3.js +92 -0
  44. package/dist/chunk-sdqa9ghv.js +141 -0
  45. package/dist/chunk-svrvvcm7.js +1 -0
  46. package/dist/chunk-v0p3hpc3.js +60 -0
  47. package/dist/chunk-wdzjbecg.js +50 -0
  48. package/dist/chunk-ww8k3g7j.js +1 -0
  49. package/dist/chunk-xmqfc62w.js +1 -0
  50. package/dist/chunk-xrebj679.js +435 -0
  51. package/dist/chunk-xt3s24vr.js +2 -0
  52. package/dist/chunk-y21zk0pn.js +4 -0
  53. package/dist/deploy/index.js +1 -168
  54. package/dist/dns/index.js +1 -41
  55. package/dist/drivers/index.js +1 -154
  56. package/dist/index.js +100 -6129
  57. package/dist/protection/index.js +1 -89
  58. package/dist/push/index.js +1 -509
  59. package/dist/spend/index.js +1 -173
  60. package/dist/ui/404.html +1 -1
  61. package/dist/ui/accept-invitation.html +1 -1
  62. package/dist/ui/access-denied.html +1 -1
  63. package/dist/ui/account/automation.html +6 -6
  64. package/dist/ui/account/security.html +2 -2
  65. package/dist/ui/applications/compose.html +6 -6
  66. package/dist/ui/applications/new.html +2 -2
  67. package/dist/ui/data/backups.html +5 -5
  68. package/dist/ui/data/services.html +5 -5
  69. package/dist/ui/data/volumes.html +6 -6
  70. package/dist/ui/index.html +6 -6
  71. package/dist/ui/infrastructure/topology.html +5 -5
  72. package/dist/ui/integrations.html +1 -1
  73. package/dist/ui/operations/alerts.html +5 -5
  74. package/dist/ui/operations/configuration.html +5 -5
  75. package/dist/ui/operations/jobs.html +5 -5
  76. package/dist/ui/operations/maintenance.html +5 -5
  77. package/dist/ui/operations/observability.html +6 -6
  78. package/dist/ui/operations/previews.html +6 -6
  79. package/dist/ui/operations/queue.html +6 -6
  80. package/dist/ui/operations/regions.html +6 -6
  81. package/dist/ui/operations/releases.html +6 -6
  82. package/dist/ui/operations/spend.html +6 -6
  83. package/dist/ui/operations/workloads.html +6 -6
  84. package/dist/ui/security.html +1 -1
  85. package/dist/ui/server/actions.html +5 -5
  86. package/dist/ui/server/activity.html +1 -1
  87. package/dist/ui/server/capacity.html +6 -6
  88. package/dist/ui/server/database.html +6 -6
  89. package/dist/ui/server/deployments.html +6 -6
  90. package/dist/ui/server/diagnostics.html +2 -2
  91. package/dist/ui/server/firewall.html +6 -6
  92. package/dist/ui/server/fleet.html +6 -6
  93. package/dist/ui/server/logs.html +6 -6
  94. package/dist/ui/server/metrics.html +6 -6
  95. package/dist/ui/server/security.html +2 -2
  96. package/dist/ui/server/services.html +1 -1
  97. package/dist/ui/server/sites.html +6 -6
  98. package/dist/ui/server/ssh-keys.html +6 -6
  99. package/dist/ui/server/team.html +6 -6
  100. package/dist/ui/server/terminal.html +1 -1
  101. package/dist/ui/serverless/alarms.html +5 -5
  102. package/dist/ui/serverless/assets.html +2 -2
  103. package/dist/ui/serverless/cost.html +1 -1
  104. package/dist/ui/serverless/data.html +6 -6
  105. package/dist/ui/serverless/deployments.html +2 -2
  106. package/dist/ui/serverless/firewall.html +1 -1
  107. package/dist/ui/serverless/functions.html +6 -6
  108. package/dist/ui/serverless/logs.html +6 -6
  109. package/dist/ui/serverless/metrics.html +2 -2
  110. package/dist/ui/serverless/queues.html +6 -6
  111. package/dist/ui/serverless/secrets.html +6 -6
  112. package/dist/ui/serverless/traces.html +6 -6
  113. package/dist/ui/serverless.html +5 -5
  114. package/package.json +3 -3
  115. package/dist/bin/chunk-jpjamjey.js +0 -6935
  116. package/dist/bin/chunk-m2zwtapr.js +0 -1
  117. package/dist/bin/chunk-rtczra13.js +0 -1
  118. package/dist/chunk-01d86gt1.js +0 -1324
  119. package/dist/chunk-050r7ycy.js +0 -46516
  120. package/dist/chunk-1c8dbv57.js +0 -7278
  121. package/dist/chunk-29rse4p1.js +0 -12203
  122. package/dist/chunk-32e7ya18.js +0 -642
  123. package/dist/chunk-4cjrg98a.js +0 -597
  124. package/dist/chunk-50jpda9q.js +0 -371
  125. package/dist/chunk-6a1t7fnq.js +0 -12121
  126. package/dist/chunk-728jvrr0.js +0 -1701
  127. package/dist/chunk-7m60qnc8.js +0 -1762
  128. package/dist/chunk-aa2dkn7b.js +0 -205
  129. package/dist/chunk-d48vtdj4.js +0 -433
  130. package/dist/chunk-f55nkpvb.js +0 -8
  131. package/dist/chunk-fgk8cqew.js +0 -152
  132. package/dist/chunk-he9a874b.js +0 -769
  133. package/dist/chunk-k2yyatfw.js +0 -10
  134. package/dist/chunk-k4px0bnv.js +0 -23
  135. package/dist/chunk-nsgqsmrh.js +0 -1779
  136. package/dist/chunk-q0st3se8.js +0 -42033
  137. package/dist/chunk-qr803fye.js +0 -2122
  138. package/dist/chunk-rds0sy87.js +0 -1771
  139. package/dist/chunk-ttz2ra5j.js +0 -12
  140. package/dist/chunk-v0bahtg2.js +0 -4
  141. package/dist/chunk-va2yd85b.js +0 -200
  142. package/dist/chunk-x9s0cqfx.js +0 -13
  143. package/dist/chunk-zqtpg06c.js +0 -1752
@@ -1,1762 +0,0 @@
1
- import {
2
- AWSClient
3
- } from "./chunk-zqtpg06c.js";
4
-
5
- // src/aws/ec2.ts
6
- class EC2Client {
7
- client;
8
- region;
9
- constructor(region = "us-east-1") {
10
- this.region = region;
11
- this.client = new AWSClient;
12
- }
13
- async describeInstances(options) {
14
- const params = {
15
- Action: "DescribeInstances",
16
- Version: "2016-11-15"
17
- };
18
- if (options?.InstanceIds) {
19
- options.InstanceIds.forEach((id, i) => {
20
- params[`InstanceId.${i + 1}`] = id;
21
- });
22
- }
23
- if (options?.Filters) {
24
- options.Filters.forEach((filter, i) => {
25
- params[`Filter.${i + 1}.Name`] = filter.Name;
26
- filter.Values.forEach((val, j) => {
27
- params[`Filter.${i + 1}.Value.${j + 1}`] = val;
28
- });
29
- });
30
- }
31
- if (options?.MaxResults) {
32
- params.MaxResults = String(options.MaxResults);
33
- }
34
- if (options?.NextToken) {
35
- params.NextToken = options.NextToken;
36
- }
37
- const result = await this.client.request({
38
- service: "ec2",
39
- region: this.region,
40
- method: "POST",
41
- path: "/",
42
- headers: {
43
- "Content-Type": "application/x-www-form-urlencoded"
44
- },
45
- body: new URLSearchParams(params).toString()
46
- });
47
- const response = result.DescribeInstancesResponse || result;
48
- return {
49
- Reservations: this.parseReservations(response.reservationSet?.item),
50
- NextToken: response.nextToken
51
- };
52
- }
53
- async getInstance(instanceId) {
54
- const result = await this.describeInstances({ InstanceIds: [instanceId] });
55
- return result.Reservations?.[0]?.Instances?.[0];
56
- }
57
- async getConsoleOutput(instanceId, latest) {
58
- const params = {
59
- Action: "GetConsoleOutput",
60
- Version: "2016-11-15",
61
- InstanceId: instanceId
62
- };
63
- if (latest) {
64
- params.Latest = "true";
65
- }
66
- const result = await this.client.request({
67
- service: "ec2",
68
- region: this.region,
69
- method: "POST",
70
- path: "/",
71
- headers: {
72
- "Content-Type": "application/x-www-form-urlencoded"
73
- },
74
- body: new URLSearchParams(params).toString()
75
- });
76
- const response = result.GetConsoleOutputResponse || result;
77
- return {
78
- InstanceId: response.instanceId,
79
- Output: response.output,
80
- Timestamp: response.timestamp
81
- };
82
- }
83
- async getConsoleOutputDecoded(instanceId, options) {
84
- const result = await this.getConsoleOutput(instanceId, options?.latest);
85
- if (!result.Output) {
86
- return "No console output available yet";
87
- }
88
- const decoded = Buffer.from(result.Output, "base64").toString("utf-8");
89
- if (options?.tailLines) {
90
- const lines = decoded.split(`
91
- `);
92
- return lines.slice(-options.tailLines).join(`
93
- `);
94
- }
95
- return decoded;
96
- }
97
- async describeInstanceStatus(options) {
98
- const params = {
99
- Action: "DescribeInstanceStatus",
100
- Version: "2016-11-15"
101
- };
102
- if (options?.InstanceIds) {
103
- options.InstanceIds.forEach((id, i) => {
104
- params[`InstanceId.${i + 1}`] = id;
105
- });
106
- }
107
- if (options?.IncludeAllInstances) {
108
- params.IncludeAllInstances = "true";
109
- }
110
- if (options?.Filters) {
111
- options.Filters.forEach((filter, i) => {
112
- params[`Filter.${i + 1}.Name`] = filter.Name;
113
- filter.Values.forEach((val, j) => {
114
- params[`Filter.${i + 1}.Value.${j + 1}`] = val;
115
- });
116
- });
117
- }
118
- const result = await this.client.request({
119
- service: "ec2",
120
- region: this.region,
121
- method: "POST",
122
- path: "/",
123
- headers: {
124
- "Content-Type": "application/x-www-form-urlencoded"
125
- },
126
- body: new URLSearchParams(params).toString()
127
- });
128
- return {
129
- InstanceStatuses: this.parseArray(result.instanceStatusSet?.item).map((item) => ({
130
- InstanceId: item.instanceId,
131
- InstanceState: item.instanceState ? {
132
- Code: Number.parseInt(item.instanceState.code),
133
- Name: item.instanceState.name
134
- } : undefined,
135
- InstanceStatus: item.instanceStatus ? {
136
- Status: item.instanceStatus.status,
137
- Details: this.parseArray(item.instanceStatus.details?.item).map((d) => ({
138
- Name: d.name,
139
- Status: d.status
140
- }))
141
- } : undefined,
142
- SystemStatus: item.systemStatus ? {
143
- Status: item.systemStatus.status,
144
- Details: this.parseArray(item.systemStatus.details?.item).map((d) => ({
145
- Name: d.name,
146
- Status: d.status
147
- }))
148
- } : undefined
149
- }))
150
- };
151
- }
152
- async startInstances(instanceIds) {
153
- const params = {
154
- Action: "StartInstances",
155
- Version: "2016-11-15"
156
- };
157
- instanceIds.forEach((id, i) => {
158
- params[`InstanceId.${i + 1}`] = id;
159
- });
160
- const result = await this.client.request({
161
- service: "ec2",
162
- region: this.region,
163
- method: "POST",
164
- path: "/",
165
- headers: {
166
- "Content-Type": "application/x-www-form-urlencoded"
167
- },
168
- body: new URLSearchParams(params).toString()
169
- });
170
- return {
171
- StartingInstances: this.parseArray(result.instancesSet?.item).map((item) => ({
172
- InstanceId: item.instanceId,
173
- CurrentState: item.currentState ? { Name: item.currentState.name } : undefined,
174
- PreviousState: item.previousState ? { Name: item.previousState.name } : undefined
175
- }))
176
- };
177
- }
178
- async stopInstances(instanceIds, force) {
179
- const params = {
180
- Action: "StopInstances",
181
- Version: "2016-11-15"
182
- };
183
- instanceIds.forEach((id, i) => {
184
- params[`InstanceId.${i + 1}`] = id;
185
- });
186
- if (force) {
187
- params.Force = "true";
188
- }
189
- const result = await this.client.request({
190
- service: "ec2",
191
- region: this.region,
192
- method: "POST",
193
- path: "/",
194
- headers: {
195
- "Content-Type": "application/x-www-form-urlencoded"
196
- },
197
- body: new URLSearchParams(params).toString()
198
- });
199
- return {
200
- StoppingInstances: this.parseArray(result.instancesSet?.item).map((item) => ({
201
- InstanceId: item.instanceId,
202
- CurrentState: item.currentState ? { Name: item.currentState.name } : undefined,
203
- PreviousState: item.previousState ? { Name: item.previousState.name } : undefined
204
- }))
205
- };
206
- }
207
- async rebootInstances(instanceIds) {
208
- const params = {
209
- Action: "RebootInstances",
210
- Version: "2016-11-15"
211
- };
212
- instanceIds.forEach((id, i) => {
213
- params[`InstanceId.${i + 1}`] = id;
214
- });
215
- await this.client.request({
216
- service: "ec2",
217
- region: this.region,
218
- method: "POST",
219
- path: "/",
220
- headers: {
221
- "Content-Type": "application/x-www-form-urlencoded"
222
- },
223
- body: new URLSearchParams(params).toString()
224
- });
225
- }
226
- async terminateInstances(instanceIds) {
227
- const params = {
228
- Action: "TerminateInstances",
229
- Version: "2016-11-15"
230
- };
231
- instanceIds.forEach((id, i) => {
232
- params[`InstanceId.${i + 1}`] = id;
233
- });
234
- const result = await this.client.request({
235
- service: "ec2",
236
- region: this.region,
237
- method: "POST",
238
- path: "/",
239
- headers: {
240
- "Content-Type": "application/x-www-form-urlencoded"
241
- },
242
- body: new URLSearchParams(params).toString()
243
- });
244
- return {
245
- TerminatingInstances: this.parseArray(result.instancesSet?.item).map((item) => ({
246
- InstanceId: item.instanceId,
247
- CurrentState: item.currentState ? { Name: item.currentState.name } : undefined,
248
- PreviousState: item.previousState ? { Name: item.previousState.name } : undefined
249
- }))
250
- };
251
- }
252
- async createImage(options) {
253
- const params = {
254
- Action: "CreateImage",
255
- Version: "2016-11-15",
256
- InstanceId: options.InstanceId,
257
- Name: options.Name
258
- };
259
- if (options.Description)
260
- params.Description = options.Description;
261
- if (options.NoReboot !== undefined)
262
- params.NoReboot = String(options.NoReboot);
263
- if (options.TagSpecifications) {
264
- options.TagSpecifications.forEach((spec, i) => {
265
- params[`TagSpecification.${i + 1}.ResourceType`] = spec.ResourceType;
266
- spec.Tags.forEach((tag, j) => {
267
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Key`] = tag.Key;
268
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Value`] = tag.Value;
269
- });
270
- });
271
- }
272
- const result = await this.client.request({
273
- service: "ec2",
274
- region: this.region,
275
- method: "POST",
276
- path: "/",
277
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
278
- body: new URLSearchParams(params).toString()
279
- });
280
- const response = result.CreateImageResponse || result;
281
- return { ImageId: response.imageId };
282
- }
283
- async deregisterImage(imageId) {
284
- await this.client.request({
285
- service: "ec2",
286
- region: this.region,
287
- method: "POST",
288
- path: "/",
289
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
290
- body: new URLSearchParams({ Action: "DeregisterImage", Version: "2016-11-15", ImageId: imageId }).toString()
291
- });
292
- }
293
- async describeVpcs(options) {
294
- const params = {
295
- Action: "DescribeVpcs",
296
- Version: "2016-11-15"
297
- };
298
- if (options?.VpcIds) {
299
- options.VpcIds.forEach((id, i) => {
300
- params[`VpcId.${i + 1}`] = id;
301
- });
302
- }
303
- if (options?.Filters) {
304
- options.Filters.forEach((filter, i) => {
305
- params[`Filter.${i + 1}.Name`] = filter.Name;
306
- filter.Values.forEach((val, j) => {
307
- params[`Filter.${i + 1}.Value.${j + 1}`] = val;
308
- });
309
- });
310
- }
311
- const result = await this.client.request({
312
- service: "ec2",
313
- region: this.region,
314
- method: "POST",
315
- path: "/",
316
- headers: {
317
- "Content-Type": "application/x-www-form-urlencoded"
318
- },
319
- body: new URLSearchParams(params).toString()
320
- });
321
- return {
322
- Vpcs: this.parseArray(result.vpcSet?.item).map((item) => ({
323
- VpcId: item.vpcId,
324
- CidrBlock: item.cidrBlock,
325
- State: item.state,
326
- DhcpOptionsId: item.dhcpOptionsId,
327
- InstanceTenancy: item.instanceTenancy,
328
- IsDefault: item.isDefault === "true",
329
- Tags: this.parseTags(item.tagSet?.item)
330
- }))
331
- };
332
- }
333
- async describeSubnets(options) {
334
- const params = {
335
- Action: "DescribeSubnets",
336
- Version: "2016-11-15"
337
- };
338
- if (options?.SubnetIds) {
339
- options.SubnetIds.forEach((id, i) => {
340
- params[`SubnetId.${i + 1}`] = id;
341
- });
342
- }
343
- if (options?.Filters) {
344
- options.Filters.forEach((filter, i) => {
345
- params[`Filter.${i + 1}.Name`] = filter.Name;
346
- filter.Values.forEach((val, j) => {
347
- params[`Filter.${i + 1}.Value.${j + 1}`] = val;
348
- });
349
- });
350
- }
351
- const result = await this.client.request({
352
- service: "ec2",
353
- region: this.region,
354
- method: "POST",
355
- path: "/",
356
- headers: {
357
- "Content-Type": "application/x-www-form-urlencoded"
358
- },
359
- body: new URLSearchParams(params).toString()
360
- });
361
- return {
362
- Subnets: this.parseArray(result.subnetSet?.item).map((item) => ({
363
- SubnetId: item.subnetId,
364
- VpcId: item.vpcId,
365
- CidrBlock: item.cidrBlock,
366
- AvailabilityZone: item.availabilityZone,
367
- AvailableIpAddressCount: Number.parseInt(item.availableIpAddressCount),
368
- State: item.state,
369
- MapPublicIpOnLaunch: item.mapPublicIpOnLaunch === "true",
370
- Tags: this.parseTags(item.tagSet?.item)
371
- }))
372
- };
373
- }
374
- async describeSecurityGroups(options) {
375
- const params = {
376
- Action: "DescribeSecurityGroups",
377
- Version: "2016-11-15"
378
- };
379
- if (options?.GroupIds) {
380
- options.GroupIds.forEach((id, i) => {
381
- params[`GroupId.${i + 1}`] = id;
382
- });
383
- }
384
- if (options?.GroupNames) {
385
- options.GroupNames.forEach((name, i) => {
386
- params[`GroupName.${i + 1}`] = name;
387
- });
388
- }
389
- if (options?.Filters) {
390
- options.Filters.forEach((filter, i) => {
391
- params[`Filter.${i + 1}.Name`] = filter.Name;
392
- filter.Values.forEach((val, j) => {
393
- params[`Filter.${i + 1}.Value.${j + 1}`] = val;
394
- });
395
- });
396
- }
397
- const result = await this.client.request({
398
- service: "ec2",
399
- region: this.region,
400
- method: "POST",
401
- path: "/",
402
- headers: {
403
- "Content-Type": "application/x-www-form-urlencoded"
404
- },
405
- body: new URLSearchParams(params).toString()
406
- });
407
- return {
408
- SecurityGroups: this.parseArray(result.securityGroupInfo?.item).map((item) => ({
409
- GroupId: item.groupId,
410
- GroupName: item.groupName,
411
- Description: item.groupDescription,
412
- VpcId: item.vpcId,
413
- IpPermissions: this.parseIpPermissions(item.ipPermissions?.item),
414
- IpPermissionsEgress: this.parseIpPermissions(item.ipPermissionsEgress?.item),
415
- Tags: this.parseTags(item.tagSet?.item)
416
- }))
417
- };
418
- }
419
- async describeInternetGateways(options) {
420
- const params = {
421
- Action: "DescribeInternetGateways",
422
- Version: "2016-11-15"
423
- };
424
- if (options?.InternetGatewayIds) {
425
- options.InternetGatewayIds.forEach((id, i) => {
426
- params[`InternetGatewayId.${i + 1}`] = id;
427
- });
428
- }
429
- if (options?.Filters) {
430
- options.Filters.forEach((filter, i) => {
431
- params[`Filter.${i + 1}.Name`] = filter.Name;
432
- filter.Values.forEach((val, j) => {
433
- params[`Filter.${i + 1}.Value.${j + 1}`] = val;
434
- });
435
- });
436
- }
437
- const result = await this.client.request({
438
- service: "ec2",
439
- region: this.region,
440
- method: "POST",
441
- path: "/",
442
- headers: {
443
- "Content-Type": "application/x-www-form-urlencoded"
444
- },
445
- body: new URLSearchParams(params).toString()
446
- });
447
- return {
448
- InternetGateways: this.parseArray(result.internetGatewaySet?.item).map((item) => ({
449
- InternetGatewayId: item.internetGatewayId,
450
- Attachments: this.parseArray(item.attachmentSet?.item).map((a) => ({
451
- VpcId: a.vpcId,
452
- State: a.state
453
- })),
454
- Tags: this.parseTags(item.tagSet?.item)
455
- }))
456
- };
457
- }
458
- async describeAddresses(options) {
459
- const params = {
460
- Action: "DescribeAddresses",
461
- Version: "2016-11-15"
462
- };
463
- if (options?.AllocationIds) {
464
- options.AllocationIds.forEach((id, i) => {
465
- params[`AllocationId.${i + 1}`] = id;
466
- });
467
- }
468
- if (options?.PublicIps) {
469
- options.PublicIps.forEach((ip, i) => {
470
- params[`PublicIp.${i + 1}`] = ip;
471
- });
472
- }
473
- if (options?.Filters) {
474
- options.Filters.forEach((filter, i) => {
475
- params[`Filter.${i + 1}.Name`] = filter.Name;
476
- filter.Values.forEach((val, j) => {
477
- params[`Filter.${i + 1}.Value.${j + 1}`] = val;
478
- });
479
- });
480
- }
481
- const result = await this.client.request({
482
- service: "ec2",
483
- region: this.region,
484
- method: "POST",
485
- path: "/",
486
- headers: {
487
- "Content-Type": "application/x-www-form-urlencoded"
488
- },
489
- body: new URLSearchParams(params).toString()
490
- });
491
- return {
492
- Addresses: this.parseArray(result.addressesSet?.item).map((item) => ({
493
- PublicIp: item.publicIp,
494
- AllocationId: item.allocationId,
495
- AssociationId: item.associationId,
496
- InstanceId: item.instanceId,
497
- NetworkInterfaceId: item.networkInterfaceId,
498
- PrivateIpAddress: item.privateIpAddress,
499
- Domain: item.domain,
500
- Tags: this.parseTags(item.tagSet?.item)
501
- }))
502
- };
503
- }
504
- async allocateAddress(options) {
505
- const params = {
506
- Action: "AllocateAddress",
507
- Version: "2016-11-15"
508
- };
509
- if (options?.Domain) {
510
- params.Domain = options.Domain;
511
- }
512
- if (options?.TagSpecifications) {
513
- options.TagSpecifications.forEach((spec, i) => {
514
- params[`TagSpecification.${i + 1}.ResourceType`] = spec.ResourceType;
515
- spec.Tags.forEach((tag, j) => {
516
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Key`] = tag.Key;
517
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Value`] = tag.Value;
518
- });
519
- });
520
- }
521
- const result = await this.client.request({
522
- service: "ec2",
523
- region: this.region,
524
- method: "POST",
525
- path: "/",
526
- headers: {
527
- "Content-Type": "application/x-www-form-urlencoded"
528
- },
529
- body: new URLSearchParams(params).toString()
530
- });
531
- return {
532
- AllocationId: result.allocationId,
533
- PublicIp: result.publicIp,
534
- Domain: result.domain
535
- };
536
- }
537
- async associateAddress(options) {
538
- const params = {
539
- Action: "AssociateAddress",
540
- Version: "2016-11-15"
541
- };
542
- if (options.AllocationId) {
543
- params.AllocationId = options.AllocationId;
544
- }
545
- if (options.PublicIp) {
546
- params.PublicIp = options.PublicIp;
547
- }
548
- if (options.InstanceId) {
549
- params.InstanceId = options.InstanceId;
550
- }
551
- if (options.NetworkInterfaceId) {
552
- params.NetworkInterfaceId = options.NetworkInterfaceId;
553
- }
554
- if (options.PrivateIpAddress) {
555
- params.PrivateIpAddress = options.PrivateIpAddress;
556
- }
557
- if (options.AllowReassociation) {
558
- params.AllowReassociation = "true";
559
- }
560
- const result = await this.client.request({
561
- service: "ec2",
562
- region: this.region,
563
- method: "POST",
564
- path: "/",
565
- headers: {
566
- "Content-Type": "application/x-www-form-urlencoded"
567
- },
568
- body: new URLSearchParams(params).toString()
569
- });
570
- return {
571
- AssociationId: result.associationId
572
- };
573
- }
574
- async createTags(options) {
575
- const params = {
576
- Action: "CreateTags",
577
- Version: "2016-11-15"
578
- };
579
- options.Resources.forEach((id, i) => {
580
- params[`ResourceId.${i + 1}`] = id;
581
- });
582
- options.Tags.forEach((tag, i) => {
583
- params[`Tag.${i + 1}.Key`] = tag.Key;
584
- params[`Tag.${i + 1}.Value`] = tag.Value;
585
- });
586
- await this.client.request({
587
- service: "ec2",
588
- region: this.region,
589
- method: "POST",
590
- path: "/",
591
- headers: {
592
- "Content-Type": "application/x-www-form-urlencoded"
593
- },
594
- body: new URLSearchParams(params).toString()
595
- });
596
- }
597
- async waitForInstanceState(instanceId, targetState, options) {
598
- const maxWait = options?.maxWaitMs || 300000;
599
- const pollInterval = options?.pollIntervalMs || 5000;
600
- const startTime = Date.now();
601
- while (Date.now() - startTime < maxWait) {
602
- let instance;
603
- try {
604
- instance = await this.getInstance(instanceId);
605
- } catch {
606
- instance = undefined;
607
- }
608
- if (instance?.State?.Name === targetState) {
609
- return instance;
610
- }
611
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
612
- }
613
- return;
614
- }
615
- async createVpc(options) {
616
- const params = {
617
- Action: "CreateVpc",
618
- Version: "2016-11-15",
619
- CidrBlock: options.CidrBlock
620
- };
621
- if (options.InstanceTenancy) {
622
- params.InstanceTenancy = options.InstanceTenancy;
623
- }
624
- if (options.TagSpecifications) {
625
- options.TagSpecifications.forEach((spec, i) => {
626
- params[`TagSpecification.${i + 1}.ResourceType`] = spec.ResourceType;
627
- spec.Tags.forEach((tag, j) => {
628
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Key`] = tag.Key;
629
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Value`] = tag.Value;
630
- });
631
- });
632
- }
633
- const result = await this.client.request({
634
- service: "ec2",
635
- region: this.region,
636
- method: "POST",
637
- path: "/",
638
- headers: {
639
- "Content-Type": "application/x-www-form-urlencoded"
640
- },
641
- body: new URLSearchParams(params).toString()
642
- });
643
- const response = result.CreateVpcResponse || result;
644
- const vpc = response.vpc;
645
- return {
646
- Vpc: vpc ? {
647
- VpcId: vpc.vpcId,
648
- CidrBlock: vpc.cidrBlock,
649
- State: vpc.state,
650
- DhcpOptionsId: vpc.dhcpOptionsId,
651
- InstanceTenancy: vpc.instanceTenancy,
652
- IsDefault: vpc.isDefault === "true",
653
- Tags: this.parseTags(vpc.tagSet?.item)
654
- } : undefined
655
- };
656
- }
657
- async createSubnet(options) {
658
- const params = {
659
- Action: "CreateSubnet",
660
- Version: "2016-11-15",
661
- VpcId: options.VpcId,
662
- CidrBlock: options.CidrBlock
663
- };
664
- if (options.AvailabilityZone) {
665
- params.AvailabilityZone = options.AvailabilityZone;
666
- }
667
- if (options.TagSpecifications) {
668
- options.TagSpecifications.forEach((spec, i) => {
669
- params[`TagSpecification.${i + 1}.ResourceType`] = spec.ResourceType;
670
- spec.Tags.forEach((tag, j) => {
671
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Key`] = tag.Key;
672
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Value`] = tag.Value;
673
- });
674
- });
675
- }
676
- const result = await this.client.request({
677
- service: "ec2",
678
- region: this.region,
679
- method: "POST",
680
- path: "/",
681
- headers: {
682
- "Content-Type": "application/x-www-form-urlencoded"
683
- },
684
- body: new URLSearchParams(params).toString()
685
- });
686
- const response = result.CreateSubnetResponse || result;
687
- const subnet = response.subnet;
688
- return {
689
- Subnet: subnet ? {
690
- SubnetId: subnet.subnetId,
691
- VpcId: subnet.vpcId,
692
- CidrBlock: subnet.cidrBlock,
693
- AvailabilityZone: subnet.availabilityZone,
694
- AvailableIpAddressCount: subnet.availableIpAddressCount ? Number.parseInt(subnet.availableIpAddressCount) : undefined,
695
- State: subnet.state,
696
- MapPublicIpOnLaunch: subnet.mapPublicIpOnLaunch === "true",
697
- Tags: this.parseTags(subnet.tagSet?.item)
698
- } : undefined
699
- };
700
- }
701
- async modifySubnetAttribute(options) {
702
- const params = {
703
- Action: "ModifySubnetAttribute",
704
- Version: "2016-11-15",
705
- SubnetId: options.SubnetId
706
- };
707
- if (options.MapPublicIpOnLaunch !== undefined) {
708
- params["MapPublicIpOnLaunch.Value"] = String(options.MapPublicIpOnLaunch.Value);
709
- }
710
- await this.client.request({
711
- service: "ec2",
712
- region: this.region,
713
- method: "POST",
714
- path: "/",
715
- headers: {
716
- "Content-Type": "application/x-www-form-urlencoded"
717
- },
718
- body: new URLSearchParams(params).toString()
719
- });
720
- }
721
- async createSecurityGroup(options) {
722
- const params = {
723
- Action: "CreateSecurityGroup",
724
- Version: "2016-11-15",
725
- GroupName: options.GroupName,
726
- GroupDescription: options.Description
727
- };
728
- if (options.VpcId) {
729
- params.VpcId = options.VpcId;
730
- }
731
- if (options.TagSpecifications) {
732
- options.TagSpecifications.forEach((spec, i) => {
733
- params[`TagSpecification.${i + 1}.ResourceType`] = spec.ResourceType;
734
- spec.Tags.forEach((tag, j) => {
735
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Key`] = tag.Key;
736
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Value`] = tag.Value;
737
- });
738
- });
739
- }
740
- const result = await this.client.request({
741
- service: "ec2",
742
- region: this.region,
743
- method: "POST",
744
- path: "/",
745
- headers: {
746
- "Content-Type": "application/x-www-form-urlencoded"
747
- },
748
- body: new URLSearchParams(params).toString()
749
- });
750
- const response = result.CreateSecurityGroupResponse || result;
751
- return {
752
- GroupId: response.groupId
753
- };
754
- }
755
- async authorizeSecurityGroupIngress(options) {
756
- const params = {
757
- Action: "AuthorizeSecurityGroupIngress",
758
- Version: "2016-11-15",
759
- GroupId: options.GroupId
760
- };
761
- this.encodeIpPermissions(params, options.IpPermissions);
762
- await this.client.request({
763
- service: "ec2",
764
- region: this.region,
765
- method: "POST",
766
- path: "/",
767
- headers: {
768
- "Content-Type": "application/x-www-form-urlencoded"
769
- },
770
- body: new URLSearchParams(params).toString()
771
- });
772
- }
773
- async authorizeSecurityGroupEgress(options) {
774
- const params = {
775
- Action: "AuthorizeSecurityGroupEgress",
776
- Version: "2016-11-15",
777
- GroupId: options.GroupId
778
- };
779
- this.encodeIpPermissions(params, options.IpPermissions);
780
- await this.client.request({
781
- service: "ec2",
782
- region: this.region,
783
- method: "POST",
784
- path: "/",
785
- headers: {
786
- "Content-Type": "application/x-www-form-urlencoded"
787
- },
788
- body: new URLSearchParams(params).toString()
789
- });
790
- }
791
- async describeRouteTables(options) {
792
- const params = {
793
- Action: "DescribeRouteTables",
794
- Version: "2016-11-15"
795
- };
796
- if (options?.RouteTableIds) {
797
- options.RouteTableIds.forEach((id, i) => {
798
- params[`RouteTableId.${i + 1}`] = id;
799
- });
800
- }
801
- if (options?.Filters) {
802
- options.Filters.forEach((filter, i) => {
803
- params[`Filter.${i + 1}.Name`] = filter.Name;
804
- filter.Values.forEach((val, j) => {
805
- params[`Filter.${i + 1}.Value.${j + 1}`] = val;
806
- });
807
- });
808
- }
809
- const result = await this.client.request({
810
- service: "ec2",
811
- region: this.region,
812
- method: "POST",
813
- path: "/",
814
- headers: {
815
- "Content-Type": "application/x-www-form-urlencoded"
816
- },
817
- body: new URLSearchParams(params).toString()
818
- });
819
- const response = result.DescribeRouteTablesResponse || result;
820
- return {
821
- RouteTables: this.parseArray(response.routeTableSet?.item).map((item) => ({
822
- RouteTableId: item.routeTableId,
823
- VpcId: item.vpcId,
824
- Routes: this.parseArray(item.routeSet?.item).map((r) => ({
825
- DestinationCidrBlock: r.destinationCidrBlock,
826
- GatewayId: r.gatewayId,
827
- NatGatewayId: r.natGatewayId,
828
- State: r.state
829
- })),
830
- Associations: this.parseArray(item.associationSet?.item).map((a) => ({
831
- RouteTableAssociationId: a.routeTableAssociationId,
832
- SubnetId: a.subnetId,
833
- Main: a.main === "true" || a.main === true
834
- })),
835
- Tags: this.parseTags(item.tagSet?.item)
836
- }))
837
- };
838
- }
839
- async deleteVpc(vpcId) {
840
- const params = {
841
- Action: "DeleteVpc",
842
- Version: "2016-11-15",
843
- VpcId: vpcId
844
- };
845
- await this.client.request({
846
- service: "ec2",
847
- region: this.region,
848
- method: "POST",
849
- path: "/",
850
- headers: {
851
- "Content-Type": "application/x-www-form-urlencoded"
852
- },
853
- body: new URLSearchParams(params).toString()
854
- });
855
- }
856
- async deleteSubnet(subnetId) {
857
- const params = {
858
- Action: "DeleteSubnet",
859
- Version: "2016-11-15",
860
- SubnetId: subnetId
861
- };
862
- await this.client.request({
863
- service: "ec2",
864
- region: this.region,
865
- method: "POST",
866
- path: "/",
867
- headers: {
868
- "Content-Type": "application/x-www-form-urlencoded"
869
- },
870
- body: new URLSearchParams(params).toString()
871
- });
872
- }
873
- async deleteSecurityGroup(groupId) {
874
- await this.client.request({
875
- service: "ec2",
876
- region: this.region,
877
- method: "POST",
878
- path: "/",
879
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
880
- body: new URLSearchParams({ Action: "DeleteSecurityGroup", Version: "2016-11-15", GroupId: groupId }).toString()
881
- });
882
- }
883
- async describeNetworkInterfaces(options) {
884
- const params = {
885
- Action: "DescribeNetworkInterfaces",
886
- Version: "2016-11-15"
887
- };
888
- if (options?.NetworkInterfaceIds) {
889
- options.NetworkInterfaceIds.forEach((id, i) => {
890
- params[`NetworkInterfaceId.${i + 1}`] = id;
891
- });
892
- }
893
- if (options?.Filters) {
894
- options.Filters.forEach((filter, i) => {
895
- params[`Filter.${i + 1}.Name`] = filter.Name;
896
- filter.Values.forEach((val, j) => {
897
- params[`Filter.${i + 1}.Value.${j + 1}`] = val;
898
- });
899
- });
900
- }
901
- const result = await this.client.request({
902
- service: "ec2",
903
- region: this.region,
904
- method: "POST",
905
- path: "/",
906
- headers: {
907
- "Content-Type": "application/x-www-form-urlencoded"
908
- },
909
- body: new URLSearchParams(params).toString()
910
- });
911
- const response = result.DescribeNetworkInterfacesResponse || result;
912
- return {
913
- NetworkInterfaces: this.parseArray(response.networkInterfaceSet?.item).map((ni) => ({
914
- NetworkInterfaceId: ni.networkInterfaceId,
915
- SubnetId: ni.subnetId,
916
- VpcId: ni.vpcId,
917
- Status: ni.status,
918
- Attachment: ni.attachment ? {
919
- AttachmentId: ni.attachment.attachmentId,
920
- InstanceId: ni.attachment.instanceId,
921
- Status: ni.attachment.status
922
- } : undefined
923
- }))
924
- };
925
- }
926
- async detachNetworkInterface(attachmentId, force) {
927
- const params = {
928
- Action: "DetachNetworkInterface",
929
- Version: "2016-11-15",
930
- AttachmentId: attachmentId
931
- };
932
- if (force) {
933
- params.Force = "true";
934
- }
935
- await this.client.request({
936
- service: "ec2",
937
- region: this.region,
938
- method: "POST",
939
- path: "/",
940
- headers: {
941
- "Content-Type": "application/x-www-form-urlencoded"
942
- },
943
- body: new URLSearchParams(params).toString()
944
- });
945
- }
946
- async deleteNetworkInterface(networkInterfaceId) {
947
- const params = {
948
- Action: "DeleteNetworkInterface",
949
- Version: "2016-11-15",
950
- NetworkInterfaceId: networkInterfaceId
951
- };
952
- await this.client.request({
953
- service: "ec2",
954
- region: this.region,
955
- method: "POST",
956
- path: "/",
957
- headers: {
958
- "Content-Type": "application/x-www-form-urlencoded"
959
- },
960
- body: new URLSearchParams(params).toString()
961
- });
962
- }
963
- async describeRegions() {
964
- const params = {
965
- Action: "DescribeRegions",
966
- Version: "2016-11-15"
967
- };
968
- const result = await this.client.request({
969
- service: "ec2",
970
- region: this.region,
971
- method: "POST",
972
- path: "/",
973
- headers: {
974
- "Content-Type": "application/x-www-form-urlencoded"
975
- },
976
- body: new URLSearchParams(params).toString()
977
- });
978
- const response = result.DescribeRegionsResponse || result;
979
- return {
980
- Regions: this.parseArray(response.regionInfo?.item).map((r) => ({
981
- RegionName: r.regionName,
982
- Endpoint: r.regionEndpoint
983
- }))
984
- };
985
- }
986
- async runInstances(options) {
987
- const params = {
988
- Action: "RunInstances",
989
- Version: "2016-11-15",
990
- ImageId: options.ImageId,
991
- InstanceType: options.InstanceType,
992
- MinCount: String(options.MinCount),
993
- MaxCount: String(options.MaxCount)
994
- };
995
- if (options.SecurityGroupIds) {
996
- options.SecurityGroupIds.forEach((id, i) => {
997
- params[`SecurityGroupId.${i + 1}`] = id;
998
- });
999
- }
1000
- if (options.SubnetId) {
1001
- params.SubnetId = options.SubnetId;
1002
- }
1003
- if (options.UserData) {
1004
- params.UserData = options.UserData;
1005
- }
1006
- if (options.IamInstanceProfile) {
1007
- if (options.IamInstanceProfile.Name) {
1008
- params["IamInstanceProfile.Name"] = options.IamInstanceProfile.Name;
1009
- }
1010
- if (options.IamInstanceProfile.Arn) {
1011
- params["IamInstanceProfile.Arn"] = options.IamInstanceProfile.Arn;
1012
- }
1013
- }
1014
- if (options.TagSpecifications) {
1015
- options.TagSpecifications.forEach((spec, i) => {
1016
- params[`TagSpecification.${i + 1}.ResourceType`] = spec.ResourceType;
1017
- spec.Tags.forEach((tag, j) => {
1018
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Key`] = tag.Key;
1019
- params[`TagSpecification.${i + 1}.Tag.${j + 1}.Value`] = tag.Value;
1020
- });
1021
- });
1022
- }
1023
- const result = await this.client.request({
1024
- service: "ec2",
1025
- region: this.region,
1026
- method: "POST",
1027
- path: "/",
1028
- headers: {
1029
- "Content-Type": "application/x-www-form-urlencoded"
1030
- },
1031
- body: new URLSearchParams(params).toString()
1032
- });
1033
- const response = result.RunInstancesResponse || result;
1034
- return {
1035
- Instances: this.parseInstances(response.instancesSet?.item || response.instancesSet)
1036
- };
1037
- }
1038
- encodeIpPermissions(params, permissions) {
1039
- permissions.forEach((perm, i) => {
1040
- const prefix = `IpPermissions.${i + 1}`;
1041
- if (perm.IpProtocol !== undefined) {
1042
- params[`${prefix}.IpProtocol`] = perm.IpProtocol;
1043
- }
1044
- if (perm.FromPort !== undefined) {
1045
- params[`${prefix}.FromPort`] = String(perm.FromPort);
1046
- }
1047
- if (perm.ToPort !== undefined) {
1048
- params[`${prefix}.ToPort`] = String(perm.ToPort);
1049
- }
1050
- if (perm.IpRanges) {
1051
- perm.IpRanges.forEach((range, j) => {
1052
- if (range.CidrIp) {
1053
- params[`${prefix}.IpRanges.${j + 1}.CidrIp`] = range.CidrIp;
1054
- }
1055
- if (range.Description) {
1056
- params[`${prefix}.IpRanges.${j + 1}.Description`] = range.Description;
1057
- }
1058
- });
1059
- }
1060
- if (perm.Ipv6Ranges) {
1061
- perm.Ipv6Ranges.forEach((range, j) => {
1062
- if (range.CidrIpv6) {
1063
- params[`${prefix}.Ipv6Ranges.${j + 1}.CidrIpv6`] = range.CidrIpv6;
1064
- }
1065
- if (range.Description) {
1066
- params[`${prefix}.Ipv6Ranges.${j + 1}.Description`] = range.Description;
1067
- }
1068
- });
1069
- }
1070
- if (perm.UserIdGroupPairs) {
1071
- perm.UserIdGroupPairs.forEach((pair, j) => {
1072
- if (pair.GroupId) {
1073
- params[`${prefix}.Groups.${j + 1}.GroupId`] = pair.GroupId;
1074
- }
1075
- if (pair.UserId) {
1076
- params[`${prefix}.Groups.${j + 1}.UserId`] = pair.UserId;
1077
- }
1078
- if (pair.Description) {
1079
- params[`${prefix}.Groups.${j + 1}.Description`] = pair.Description;
1080
- }
1081
- });
1082
- }
1083
- });
1084
- }
1085
- parseArray(item) {
1086
- if (!item)
1087
- return [];
1088
- return Array.isArray(item) ? item : [item];
1089
- }
1090
- parseFirstIpv6Address(item) {
1091
- for (const eni of this.parseArray(item)) {
1092
- for (const entry of this.parseArray(eni?.ipv6AddressesSet?.item)) {
1093
- if (entry?.ipv6Address)
1094
- return entry.ipv6Address;
1095
- }
1096
- }
1097
- return;
1098
- }
1099
- parseTags(item) {
1100
- return this.parseArray(item).map((t) => ({
1101
- Key: t.key,
1102
- Value: t.value
1103
- }));
1104
- }
1105
- parseReservations(item) {
1106
- return this.parseArray(item).map((r) => ({
1107
- ReservationId: r.reservationId,
1108
- Instances: this.parseInstances(r.instancesSet?.item || r.instancesSet)
1109
- }));
1110
- }
1111
- parseInstances(item) {
1112
- return this.parseArray(item).map((i) => ({
1113
- InstanceId: i.instanceId,
1114
- ImageId: i.imageId,
1115
- InstanceType: i.instanceType,
1116
- State: i.instanceState ? {
1117
- Code: Number.parseInt(i.instanceState.code),
1118
- Name: i.instanceState.name
1119
- } : undefined,
1120
- PrivateIpAddress: i.privateIpAddress,
1121
- PublicIpAddress: i.ipAddress,
1122
- Ipv6Address: this.parseFirstIpv6Address(i.networkInterfaceSet?.item),
1123
- SubnetId: i.subnetId,
1124
- VpcId: i.vpcId,
1125
- SecurityGroups: this.parseArray(i.groupSet?.item).map((g) => ({
1126
- GroupId: g.groupId,
1127
- GroupName: g.groupName
1128
- })),
1129
- Tags: this.parseTags(i.tagSet?.item),
1130
- LaunchTime: i.launchTime,
1131
- Placement: i.placement ? {
1132
- AvailabilityZone: i.placement.availabilityZone,
1133
- Tenancy: i.placement.tenancy
1134
- } : undefined,
1135
- Architecture: i.architecture,
1136
- RootDeviceType: i.rootDeviceType,
1137
- RootDeviceName: i.rootDeviceName,
1138
- BlockDeviceMappings: this.parseArray(i.blockDeviceMapping?.item).map((b) => ({
1139
- DeviceName: b.deviceName,
1140
- Ebs: b.ebs ? {
1141
- VolumeId: b.ebs.volumeId,
1142
- Status: b.ebs.status,
1143
- AttachTime: b.ebs.attachTime,
1144
- DeleteOnTermination: b.ebs.deleteOnTermination === "true"
1145
- } : undefined
1146
- })),
1147
- IamInstanceProfile: i.iamInstanceProfile ? {
1148
- Arn: i.iamInstanceProfile.arn,
1149
- Id: i.iamInstanceProfile.id
1150
- } : undefined
1151
- }));
1152
- }
1153
- parseIpPermissions(item) {
1154
- return this.parseArray(item).map((p) => ({
1155
- IpProtocol: p.ipProtocol,
1156
- FromPort: p.fromPort ? Number.parseInt(p.fromPort) : undefined,
1157
- ToPort: p.toPort ? Number.parseInt(p.toPort) : undefined,
1158
- IpRanges: this.parseArray(p.ipRanges?.item).map((r) => ({
1159
- CidrIp: r.cidrIp,
1160
- Description: r.description
1161
- })),
1162
- Ipv6Ranges: this.parseArray(p.ipv6Ranges?.item).map((r) => ({
1163
- CidrIpv6: r.cidrIpv6,
1164
- Description: r.description
1165
- })),
1166
- UserIdGroupPairs: this.parseArray(p.groups?.item).map((g) => ({
1167
- GroupId: g.groupId,
1168
- UserId: g.userId,
1169
- Description: g.description
1170
- }))
1171
- }));
1172
- }
1173
- }
1174
-
1175
- // src/aws/ssm.ts
1176
- class SSMClient {
1177
- client;
1178
- region;
1179
- constructor(region = "us-east-1", profile) {
1180
- this.region = region;
1181
- this.client = new AWSClient;
1182
- }
1183
- async putParameter(options) {
1184
- const params = {
1185
- Name: options.Name,
1186
- Value: options.Value
1187
- };
1188
- if (options.Type) {
1189
- params.Type = options.Type;
1190
- }
1191
- if (options.Description) {
1192
- params.Description = options.Description;
1193
- }
1194
- if (options.KeyId) {
1195
- params.KeyId = options.KeyId;
1196
- }
1197
- if (options.Overwrite !== undefined) {
1198
- params.Overwrite = options.Overwrite;
1199
- }
1200
- if (options.AllowedPattern) {
1201
- params.AllowedPattern = options.AllowedPattern;
1202
- }
1203
- if (options.Tags && options.Tags.length > 0) {
1204
- params.Tags = options.Tags;
1205
- }
1206
- if (options.Tier) {
1207
- params.Tier = options.Tier;
1208
- }
1209
- if (options.DataType) {
1210
- params.DataType = options.DataType;
1211
- }
1212
- const result = await this.client.request({
1213
- service: "ssm",
1214
- region: this.region,
1215
- method: "POST",
1216
- path: "/",
1217
- headers: {
1218
- "X-Amz-Target": "AmazonSSM.PutParameter",
1219
- "Content-Type": "application/x-amz-json-1.1"
1220
- },
1221
- body: JSON.stringify(params)
1222
- });
1223
- return {
1224
- Version: result.Version,
1225
- Tier: result.Tier
1226
- };
1227
- }
1228
- async getParameter(options) {
1229
- const params = {
1230
- Name: options.Name
1231
- };
1232
- if (options.WithDecryption !== undefined) {
1233
- params.WithDecryption = options.WithDecryption;
1234
- }
1235
- const result = await this.client.request({
1236
- service: "ssm",
1237
- region: this.region,
1238
- method: "POST",
1239
- path: "/",
1240
- headers: {
1241
- "X-Amz-Target": "AmazonSSM.GetParameter",
1242
- "Content-Type": "application/x-amz-json-1.1"
1243
- },
1244
- body: JSON.stringify(params)
1245
- });
1246
- return {
1247
- Parameter: result.Parameter ? this.parseParameter(result.Parameter) : undefined
1248
- };
1249
- }
1250
- async getParameters(options) {
1251
- const params = {
1252
- Names: options.Names
1253
- };
1254
- if (options.WithDecryption !== undefined) {
1255
- params.WithDecryption = options.WithDecryption;
1256
- }
1257
- const result = await this.client.request({
1258
- service: "ssm",
1259
- region: this.region,
1260
- method: "POST",
1261
- path: "/",
1262
- headers: {
1263
- "X-Amz-Target": "AmazonSSM.GetParameters",
1264
- "Content-Type": "application/x-amz-json-1.1"
1265
- },
1266
- body: JSON.stringify(params)
1267
- });
1268
- return {
1269
- Parameters: result.Parameters?.map((p) => this.parseParameter(p)),
1270
- InvalidParameters: result.InvalidParameters
1271
- };
1272
- }
1273
- async getParametersByPath(options) {
1274
- const params = {
1275
- Path: options.Path
1276
- };
1277
- if (options.Recursive !== undefined) {
1278
- params.Recursive = options.Recursive;
1279
- }
1280
- if (options.WithDecryption !== undefined) {
1281
- params.WithDecryption = options.WithDecryption;
1282
- }
1283
- if (options.MaxResults) {
1284
- params.MaxResults = options.MaxResults;
1285
- }
1286
- if (options.NextToken) {
1287
- params.NextToken = options.NextToken;
1288
- }
1289
- if (options.ParameterFilters && options.ParameterFilters.length > 0) {
1290
- params.ParameterFilters = options.ParameterFilters;
1291
- }
1292
- const result = await this.client.request({
1293
- service: "ssm",
1294
- region: this.region,
1295
- method: "POST",
1296
- path: "/",
1297
- headers: {
1298
- "X-Amz-Target": "AmazonSSM.GetParametersByPath",
1299
- "Content-Type": "application/x-amz-json-1.1"
1300
- },
1301
- body: JSON.stringify(params)
1302
- });
1303
- return {
1304
- Parameters: result.Parameters?.map((p) => this.parseParameter(p)),
1305
- NextToken: result.NextToken
1306
- };
1307
- }
1308
- async deleteParameter(options) {
1309
- const params = {
1310
- Name: options.Name
1311
- };
1312
- await this.client.request({
1313
- service: "ssm",
1314
- region: this.region,
1315
- method: "POST",
1316
- path: "/",
1317
- headers: {
1318
- "X-Amz-Target": "AmazonSSM.DeleteParameter",
1319
- "Content-Type": "application/x-amz-json-1.1"
1320
- },
1321
- body: JSON.stringify(params)
1322
- });
1323
- }
1324
- async deleteParameters(names) {
1325
- const params = {
1326
- Names: names
1327
- };
1328
- const result = await this.client.request({
1329
- service: "ssm",
1330
- region: this.region,
1331
- method: "POST",
1332
- path: "/",
1333
- headers: {
1334
- "X-Amz-Target": "AmazonSSM.DeleteParameters",
1335
- "Content-Type": "application/x-amz-json-1.1"
1336
- },
1337
- body: JSON.stringify(params)
1338
- });
1339
- return {
1340
- DeletedParameters: result.DeletedParameters,
1341
- InvalidParameters: result.InvalidParameters
1342
- };
1343
- }
1344
- async describeParameters(options) {
1345
- const params = {};
1346
- if (options?.Filters && options.Filters.length > 0) {
1347
- params.Filters = options.Filters;
1348
- }
1349
- if (options?.ParameterFilters && options.ParameterFilters.length > 0) {
1350
- params.ParameterFilters = options.ParameterFilters;
1351
- }
1352
- if (options?.MaxResults) {
1353
- params.MaxResults = options.MaxResults;
1354
- }
1355
- if (options?.NextToken) {
1356
- params.NextToken = options.NextToken;
1357
- }
1358
- const result = await this.client.request({
1359
- service: "ssm",
1360
- region: this.region,
1361
- method: "POST",
1362
- path: "/",
1363
- headers: {
1364
- "X-Amz-Target": "AmazonSSM.DescribeParameters",
1365
- "Content-Type": "application/x-amz-json-1.1"
1366
- },
1367
- body: JSON.stringify(params)
1368
- });
1369
- return {
1370
- Parameters: result.Parameters?.map((p) => this.parseParameter(p)),
1371
- NextToken: result.NextToken
1372
- };
1373
- }
1374
- async getParameterHistory(options) {
1375
- const params = {
1376
- Name: options.Name
1377
- };
1378
- if (options.WithDecryption !== undefined) {
1379
- params.WithDecryption = options.WithDecryption;
1380
- }
1381
- if (options.MaxResults) {
1382
- params.MaxResults = options.MaxResults;
1383
- }
1384
- if (options.NextToken) {
1385
- params.NextToken = options.NextToken;
1386
- }
1387
- const result = await this.client.request({
1388
- service: "ssm",
1389
- region: this.region,
1390
- method: "POST",
1391
- path: "/",
1392
- headers: {
1393
- "X-Amz-Target": "AmazonSSM.GetParameterHistory",
1394
- "Content-Type": "application/x-amz-json-1.1"
1395
- },
1396
- body: JSON.stringify(params)
1397
- });
1398
- return {
1399
- Parameters: result.Parameters?.map((p) => ({
1400
- Name: p.Name,
1401
- Type: p.Type,
1402
- KeyId: p.KeyId,
1403
- LastModifiedDate: p.LastModifiedDate,
1404
- LastModifiedUser: p.LastModifiedUser,
1405
- Description: p.Description,
1406
- Value: p.Value,
1407
- Version: p.Version,
1408
- Labels: p.Labels,
1409
- Tier: p.Tier
1410
- })),
1411
- NextToken: result.NextToken
1412
- };
1413
- }
1414
- async labelParameterVersion(options) {
1415
- const params = {
1416
- Name: options.Name,
1417
- Labels: options.Labels
1418
- };
1419
- if (options.ParameterVersion !== undefined) {
1420
- params.ParameterVersion = options.ParameterVersion;
1421
- }
1422
- const result = await this.client.request({
1423
- service: "ssm",
1424
- region: this.region,
1425
- method: "POST",
1426
- path: "/",
1427
- headers: {
1428
- "X-Amz-Target": "AmazonSSM.LabelParameterVersion",
1429
- "Content-Type": "application/x-amz-json-1.1"
1430
- },
1431
- body: JSON.stringify(params)
1432
- });
1433
- return {
1434
- InvalidLabels: result.InvalidLabels,
1435
- ParameterVersion: result.ParameterVersion
1436
- };
1437
- }
1438
- async addTagsToResource(options) {
1439
- const params = {
1440
- ResourceType: options.ResourceType,
1441
- ResourceId: options.ResourceId,
1442
- Tags: options.Tags
1443
- };
1444
- await this.client.request({
1445
- service: "ssm",
1446
- region: this.region,
1447
- method: "POST",
1448
- path: "/",
1449
- headers: {
1450
- "X-Amz-Target": "AmazonSSM.AddTagsToResource",
1451
- "Content-Type": "application/x-amz-json-1.1"
1452
- },
1453
- body: JSON.stringify(params)
1454
- });
1455
- }
1456
- async removeTagsFromResource(options) {
1457
- const params = {
1458
- ResourceType: options.ResourceType,
1459
- ResourceId: options.ResourceId,
1460
- TagKeys: options.TagKeys
1461
- };
1462
- await this.client.request({
1463
- service: "ssm",
1464
- region: this.region,
1465
- method: "POST",
1466
- path: "/",
1467
- headers: {
1468
- "X-Amz-Target": "AmazonSSM.RemoveTagsFromResource",
1469
- "Content-Type": "application/x-amz-json-1.1"
1470
- },
1471
- body: JSON.stringify(params)
1472
- });
1473
- }
1474
- async listTagsForResource(options) {
1475
- const params = {
1476
- ResourceType: options.ResourceType,
1477
- ResourceId: options.ResourceId
1478
- };
1479
- const result = await this.client.request({
1480
- service: "ssm",
1481
- region: this.region,
1482
- method: "POST",
1483
- path: "/",
1484
- headers: {
1485
- "X-Amz-Target": "AmazonSSM.ListTagsForResource",
1486
- "Content-Type": "application/x-amz-json-1.1"
1487
- },
1488
- body: JSON.stringify(params)
1489
- });
1490
- return {
1491
- TagList: result.TagList
1492
- };
1493
- }
1494
- async setString(name, value, options) {
1495
- return this.putParameter({
1496
- Name: name,
1497
- Value: value,
1498
- Type: "String",
1499
- Description: options?.description,
1500
- Overwrite: options?.overwrite ?? true,
1501
- Tags: options?.tags
1502
- });
1503
- }
1504
- async setSecureString(name, value, options) {
1505
- return this.putParameter({
1506
- Name: name,
1507
- Value: value,
1508
- Type: "SecureString",
1509
- Description: options?.description,
1510
- Overwrite: options?.overwrite ?? true,
1511
- KeyId: options?.kmsKeyId,
1512
- Tags: options?.tags
1513
- });
1514
- }
1515
- async getValue(name) {
1516
- const result = await this.getParameter({
1517
- Name: name,
1518
- WithDecryption: true
1519
- });
1520
- return result.Parameter?.Value;
1521
- }
1522
- async getAllByPath(path, recursive = true) {
1523
- const allParams = [];
1524
- let nextToken;
1525
- do {
1526
- const result = await this.getParametersByPath({
1527
- Path: path,
1528
- Recursive: recursive,
1529
- WithDecryption: true,
1530
- NextToken: nextToken
1531
- });
1532
- if (result.Parameters) {
1533
- allParams.push(...result.Parameters);
1534
- }
1535
- nextToken = result.NextToken;
1536
- } while (nextToken);
1537
- return allParams;
1538
- }
1539
- parseParameter(p) {
1540
- return {
1541
- Name: p.Name,
1542
- Type: p.Type,
1543
- Value: p.Value,
1544
- Version: p.Version,
1545
- LastModifiedDate: p.LastModifiedDate,
1546
- ARN: p.ARN,
1547
- DataType: p.DataType,
1548
- Description: p.Description,
1549
- AllowedPattern: p.AllowedPattern,
1550
- KeyId: p.KeyId,
1551
- Tier: p.Tier
1552
- };
1553
- }
1554
- async sendCommand(options) {
1555
- if (!options.InstanceIds && !options.Targets) {
1556
- throw new Error("SendCommand requires either InstanceIds or Targets");
1557
- }
1558
- const params = {
1559
- DocumentName: options.DocumentName
1560
- };
1561
- if (options.InstanceIds) {
1562
- params.InstanceIds = options.InstanceIds;
1563
- }
1564
- if (options.Targets) {
1565
- params.Targets = options.Targets;
1566
- }
1567
- if (options.Parameters) {
1568
- params.Parameters = options.Parameters;
1569
- }
1570
- if (options.TimeoutSeconds) {
1571
- params.TimeoutSeconds = options.TimeoutSeconds;
1572
- }
1573
- if (options.Comment) {
1574
- params.Comment = options.Comment;
1575
- }
1576
- if (options.OutputS3BucketName) {
1577
- params.OutputS3BucketName = options.OutputS3BucketName;
1578
- }
1579
- if (options.OutputS3KeyPrefix) {
1580
- params.OutputS3KeyPrefix = options.OutputS3KeyPrefix;
1581
- }
1582
- const result = await this.client.request({
1583
- service: "ssm",
1584
- region: this.region,
1585
- method: "POST",
1586
- path: "/",
1587
- headers: {
1588
- "X-Amz-Target": "AmazonSSM.SendCommand",
1589
- "Content-Type": "application/x-amz-json-1.1"
1590
- },
1591
- body: JSON.stringify(params)
1592
- });
1593
- return {
1594
- CommandId: result.Command?.CommandId,
1595
- Status: result.Command?.Status,
1596
- StatusDetails: result.Command?.StatusDetails
1597
- };
1598
- }
1599
- async getCommandInvocation(options) {
1600
- const params = {
1601
- CommandId: options.CommandId,
1602
- InstanceId: options.InstanceId
1603
- };
1604
- const result = await this.client.request({
1605
- service: "ssm",
1606
- region: this.region,
1607
- method: "POST",
1608
- path: "/",
1609
- headers: {
1610
- "X-Amz-Target": "AmazonSSM.GetCommandInvocation",
1611
- "Content-Type": "application/x-amz-json-1.1"
1612
- },
1613
- body: JSON.stringify(params)
1614
- });
1615
- return {
1616
- Status: result.Status,
1617
- StatusDetails: result.StatusDetails,
1618
- StandardOutputContent: result.StandardOutputContent,
1619
- StandardErrorContent: result.StandardErrorContent,
1620
- ResponseCode: result.ResponseCode
1621
- };
1622
- }
1623
- async runShellCommand(instanceId, commands, options) {
1624
- const sendResult = await this.sendCommand({
1625
- InstanceIds: [instanceId],
1626
- DocumentName: "AWS-RunShellScript",
1627
- Parameters: {
1628
- commands
1629
- },
1630
- TimeoutSeconds: options?.timeoutSeconds || 600
1631
- });
1632
- if (!sendResult.CommandId) {
1633
- return { success: false, error: "Failed to send command" };
1634
- }
1635
- if (options?.waitForCompletion === false) {
1636
- return { success: true, status: "Pending" };
1637
- }
1638
- const pollInterval = options?.pollIntervalMs || 2000;
1639
- const maxWait = options?.maxWaitMs || 300000;
1640
- const startTime = Date.now();
1641
- while (Date.now() - startTime < maxWait) {
1642
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
1643
- try {
1644
- const invocation = await this.getCommandInvocation({
1645
- CommandId: sendResult.CommandId,
1646
- InstanceId: instanceId
1647
- });
1648
- if (invocation.Status === "Success") {
1649
- return {
1650
- success: true,
1651
- output: invocation.StandardOutputContent,
1652
- error: invocation.StandardErrorContent,
1653
- status: invocation.Status
1654
- };
1655
- }
1656
- if (invocation.Status === "Failed" || invocation.Status === "Cancelled" || invocation.Status === "TimedOut") {
1657
- return {
1658
- success: false,
1659
- output: invocation.StandardOutputContent,
1660
- error: invocation.StandardErrorContent || invocation.StatusDetails,
1661
- status: invocation.Status
1662
- };
1663
- }
1664
- } catch (e) {
1665
- if (!e.message?.includes("InvocationDoesNotExist")) {
1666
- return { success: false, error: e.message };
1667
- }
1668
- }
1669
- }
1670
- return { success: false, error: "Command timed out waiting for completion" };
1671
- }
1672
- async listCommandInvocations(options) {
1673
- const params = {
1674
- CommandId: options.CommandId
1675
- };
1676
- if (options.Details) {
1677
- params.Details = true;
1678
- }
1679
- const result = await this.client.request({
1680
- service: "ssm",
1681
- region: this.region,
1682
- method: "POST",
1683
- path: "/",
1684
- headers: {
1685
- "X-Amz-Target": "AmazonSSM.ListCommandInvocations",
1686
- "Content-Type": "application/x-amz-json-1.1"
1687
- },
1688
- body: JSON.stringify(params)
1689
- });
1690
- const invocations = result.CommandInvocations || [];
1691
- return invocations.map((inv) => ({
1692
- InstanceId: inv.InstanceId,
1693
- Status: inv.Status,
1694
- StatusDetails: inv.StatusDetails,
1695
- StandardOutputContent: inv.CommandPlugins?.[0]?.Output,
1696
- StandardErrorContent: inv.CommandPlugins?.[0]?.StandardErrorUrl
1697
- }));
1698
- }
1699
- async sendCommandByTags(options) {
1700
- const targets = Object.entries(options.tags).map(([key, value]) => ({
1701
- Key: `tag:${key}`,
1702
- Values: [value]
1703
- }));
1704
- const sendResult = await this.sendCommand({
1705
- Targets: targets,
1706
- DocumentName: "AWS-RunShellScript",
1707
- Parameters: { commands: options.commands },
1708
- TimeoutSeconds: options.timeoutSeconds || 600,
1709
- Comment: options.comment
1710
- });
1711
- if (!sendResult.CommandId) {
1712
- return { success: false, instanceCount: 0, perInstance: [], error: "Failed to send command" };
1713
- }
1714
- const pollInterval = options.pollIntervalMs || 3000;
1715
- const maxWait = options.maxWaitMs || 600000;
1716
- const startTime = Date.now();
1717
- const terminalStatuses = new Set(["Success", "Failed", "Cancelled", "TimedOut"]);
1718
- let lastInvocations = [];
1719
- while (Date.now() - startTime < maxWait) {
1720
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
1721
- try {
1722
- lastInvocations = await this.listCommandInvocations({
1723
- CommandId: sendResult.CommandId,
1724
- Details: true
1725
- });
1726
- if (lastInvocations.length === 0)
1727
- continue;
1728
- const allDone = lastInvocations.every((inv) => terminalStatuses.has(inv.Status || ""));
1729
- if (allDone) {
1730
- const perInstance = lastInvocations.map((inv) => ({
1731
- instanceId: inv.InstanceId,
1732
- status: inv.Status || "Unknown",
1733
- output: inv.StandardOutputContent,
1734
- error: inv.StandardErrorContent || inv.StatusDetails
1735
- }));
1736
- const allSucceeded = lastInvocations.every((inv) => inv.Status === "Success");
1737
- return {
1738
- success: allSucceeded,
1739
- instanceCount: lastInvocations.length,
1740
- perInstance,
1741
- error: allSucceeded ? undefined : "One or more instances reported a non-success status"
1742
- };
1743
- }
1744
- } catch (e) {
1745
- if (!e.message?.includes("InvocationDoesNotExist")) {
1746
- return { success: false, instanceCount: 0, perInstance: [], error: e.message };
1747
- }
1748
- }
1749
- }
1750
- return {
1751
- success: false,
1752
- instanceCount: lastInvocations.length,
1753
- perInstance: lastInvocations.map((inv) => ({
1754
- instanceId: inv.InstanceId,
1755
- status: inv.Status || "Unknown"
1756
- })),
1757
- error: "Command timed out waiting for all instances to complete"
1758
- };
1759
- }
1760
- }
1761
-
1762
- export { EC2Client, SSMClient };