@stacksjs/ts-cloud 0.9.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/dist/aws/index.js +1 -269
  2. package/dist/bin/chunk-08c0pzkb.js +1 -0
  3. package/dist/bin/chunk-12210qvj.js +1 -0
  4. package/dist/bin/chunk-1v6bt68w.js +6 -0
  5. package/dist/bin/chunk-35ttwn26.js +70 -0
  6. package/dist/bin/chunk-3r3be05z.js +1 -0
  7. package/dist/bin/chunk-41yqpdv7.js +2 -0
  8. package/dist/bin/chunk-5rv31chh.js +1 -0
  9. package/dist/bin/chunk-6eat8ezk.js +2 -0
  10. package/dist/bin/chunk-6gktf2m2.js +1 -0
  11. package/dist/bin/chunk-6zjy949y.js +141 -0
  12. package/dist/bin/chunk-7wzdaqh6.js +2 -0
  13. package/dist/bin/chunk-80ar3aty.js +1 -0
  14. package/dist/bin/chunk-8rwhsp5b.js +2 -0
  15. package/dist/bin/chunk-936vp7dx.js +44 -0
  16. package/dist/bin/chunk-9px3rg4a.js +4 -0
  17. package/dist/bin/chunk-anm3ae6z.js +7364 -0
  18. package/dist/bin/{chunk-ynjvbphf.js → chunk-axvr7dwa.js} +6 -6
  19. package/dist/bin/chunk-b0hj9m5e.js +2 -0
  20. package/dist/bin/{chunk-mh0kdzqp.js → chunk-b2ymh8k0.js} +1 -1
  21. package/dist/bin/chunk-b35989e3.js +50 -0
  22. package/dist/bin/chunk-c2b6nk0q.js +37 -0
  23. package/dist/bin/chunk-ckxpgwxw.js +3 -0
  24. package/dist/bin/chunk-d6zzgvtn.js +92 -0
  25. package/dist/bin/chunk-da8zpf82.js +1 -0
  26. package/dist/bin/chunk-ddmjjstg.js +1 -0
  27. package/dist/bin/chunk-dhhz4zyj.js +1 -0
  28. package/dist/bin/chunk-dj9a67c3.js +9 -0
  29. package/dist/bin/chunk-ds1z880f.js +1 -0
  30. package/dist/bin/chunk-dvkj4k6h.js +111 -0
  31. package/dist/bin/chunk-eh40fpvj.js +1 -0
  32. package/dist/bin/chunk-ey9fagrr.js +6 -0
  33. package/dist/bin/chunk-ezftw2q4.js +1 -0
  34. package/dist/bin/chunk-g6a4n3rh.js +1 -0
  35. package/dist/bin/chunk-g90nqfgv.js +585 -0
  36. package/dist/bin/chunk-gs40j75w.js +1 -0
  37. package/dist/bin/chunk-jjjts1vt.js +1 -0
  38. package/dist/bin/{chunk-ry030a6b.js → chunk-jnsbzqzz.js} +30 -30
  39. package/dist/bin/chunk-jnx4jgw8.js +1 -0
  40. package/dist/bin/chunk-jt1tndm2.js +3 -0
  41. package/dist/bin/chunk-kybdb0ws.js +2 -0
  42. package/dist/bin/chunk-m3nqw76h.js +3 -0
  43. package/dist/bin/chunk-mn6j22zn.js +6 -0
  44. package/dist/bin/chunk-nb0yjkv5.js +2 -0
  45. package/dist/bin/chunk-pjpa4x52.js +2 -0
  46. package/dist/bin/chunk-pkgkfe6s.js +2 -0
  47. package/dist/bin/chunk-pnz5hk8n.js +60 -0
  48. package/dist/bin/chunk-q46zr2tv.js +1 -0
  49. package/dist/bin/chunk-qtdngvs8.js +1 -0
  50. package/dist/bin/chunk-sbejksrh.js +2 -0
  51. package/dist/bin/chunk-svyd4v6c.js +34 -0
  52. package/dist/bin/chunk-tna7ay8d.js +1 -0
  53. package/dist/bin/chunk-tp4c2mv1.js +1 -0
  54. package/dist/bin/chunk-w5d6tr2x.js +1 -0
  55. package/dist/bin/chunk-wewcjam5.js +1 -0
  56. package/dist/bin/chunk-xv4bscrm.js +1 -0
  57. package/dist/bin/chunk-y9eyc5pw.js +1 -0
  58. package/dist/bin/chunk-y9f8649w.js +512 -0
  59. package/dist/bin/cli.js +428 -418
  60. package/dist/bin/dashboard-server.js +1 -1
  61. package/dist/chunk-06jk7ba9.js +7355 -0
  62. package/dist/chunk-0e16qt6k.js +5 -0
  63. package/dist/chunk-13hxhzaz.js +34 -0
  64. package/dist/chunk-2p89vt3b.js +2 -0
  65. package/dist/chunk-77t2ctwn.js +2 -0
  66. package/dist/chunk-88z37ey4.js +114 -0
  67. package/dist/chunk-8c4715hz.js +2 -0
  68. package/dist/chunk-9a22225r.js +60 -0
  69. package/dist/chunk-as6by62d.js +1 -0
  70. package/dist/chunk-cd0zpxhf.js +44 -0
  71. package/dist/chunk-cp54a0qn.js +6 -0
  72. package/dist/chunk-d67xbk4v.js +141 -0
  73. package/dist/chunk-dckz9xve.js +2 -0
  74. package/dist/chunk-e1666vjv.js +2 -0
  75. package/dist/chunk-hhdx5k96.js +442 -0
  76. package/dist/chunk-kv2ztkp4.js +1617 -0
  77. package/dist/chunk-nrz6zypg.js +1 -0
  78. package/dist/chunk-q816js1y.js +1 -0
  79. package/dist/chunk-qh9ep11z.js +704 -0
  80. package/dist/chunk-rg720cqg.js +1 -0
  81. package/dist/chunk-snak8s7m.js +92 -0
  82. package/dist/chunk-vq737g82.js +1 -0
  83. package/dist/chunk-xd6w0c11.js +50 -0
  84. package/dist/chunk-xtwjt370.js +37 -0
  85. package/dist/chunk-y26yh5zp.js +1 -0
  86. package/dist/chunk-zmxffmmq.js +4 -0
  87. package/dist/deploy/attach-credentials.d.ts +4 -8
  88. package/dist/deploy/index.js +1 -168
  89. package/dist/dns/cloudflare.d.ts +27 -0
  90. package/dist/dns/godaddy.d.ts +18 -1
  91. package/dist/dns/index.d.ts +2 -0
  92. package/dist/dns/index.js +1 -41
  93. package/dist/dns/zone-migration.d.ts +92 -0
  94. package/dist/dns/zone-migration.test.d.ts +1 -0
  95. package/dist/drivers/hetzner/driver.d.ts +8 -1
  96. package/dist/drivers/index.js +1 -154
  97. package/dist/drivers/shared/compute-provision.d.ts +14 -2
  98. package/dist/drivers/shared/db-provision.d.ts +3 -2
  99. package/dist/drivers/shared/mail-provision.d.ts +116 -0
  100. package/dist/drivers/shared/mail-provision.test.d.ts +1 -0
  101. package/dist/drivers/shared/managed-services-probe.d.ts +47 -0
  102. package/dist/drivers/shared/managed-services-probe.test.d.ts +1 -0
  103. package/dist/drivers/shared/package-manager.d.ts +1 -0
  104. package/dist/drivers/shared/remote-failure.d.ts +21 -0
  105. package/dist/drivers/shared/remote-failure.test.d.ts +1 -0
  106. package/dist/drivers/shared/sqlite-shared-path.d.ts +50 -0
  107. package/dist/drivers/shared/sqlite-shared-path.test.d.ts +1 -0
  108. package/dist/index.d.ts +2 -0
  109. package/dist/index.js +100 -6129
  110. package/dist/operations/plan.d.ts +136 -0
  111. package/dist/operations/plan.test.d.ts +1 -0
  112. package/dist/operations/server-rename.d.ts +84 -0
  113. package/dist/operations/server-rename.test.d.ts +1 -0
  114. package/dist/operations/site-move.d.ts +263 -0
  115. package/dist/operations/site-move.test.d.ts +1 -0
  116. package/dist/protection/index.js +1 -89
  117. package/dist/push/index.js +1 -509
  118. package/dist/spend/index.js +1 -173
  119. package/dist/ui/404.html +1 -1
  120. package/dist/ui/accept-invitation.html +1 -1
  121. package/dist/ui/access-denied.html +1 -1
  122. package/dist/ui/account/automation.html +5 -5
  123. package/dist/ui/account/security.html +2 -2
  124. package/dist/ui/applications/compose.html +6 -6
  125. package/dist/ui/applications/new.html +2 -2
  126. package/dist/ui/data/backups.html +80 -80
  127. package/dist/ui/data/services.html +78 -78
  128. package/dist/ui/data/volumes.html +50 -50
  129. package/dist/ui/index.html +50 -50
  130. package/dist/ui/infrastructure/topology.html +118 -118
  131. package/dist/ui/integrations.html +1 -1
  132. package/dist/ui/operations/alerts.html +47 -47
  133. package/dist/ui/operations/configuration.html +5 -5
  134. package/dist/ui/operations/jobs.html +76 -76
  135. package/dist/ui/operations/maintenance.html +6 -6
  136. package/dist/ui/operations/observability.html +82 -82
  137. package/dist/ui/operations/previews.html +5 -5
  138. package/dist/ui/operations/queue.html +6 -6
  139. package/dist/ui/operations/regions.html +6 -6
  140. package/dist/ui/operations/releases.html +6 -6
  141. package/dist/ui/operations/spend.html +54 -54
  142. package/dist/ui/operations/workloads.html +104 -104
  143. package/dist/ui/security.html +2 -2
  144. package/dist/ui/server/actions.html +56 -56
  145. package/dist/ui/server/activity.html +1 -1
  146. package/dist/ui/server/capacity.html +6 -6
  147. package/dist/ui/server/database.html +106 -106
  148. package/dist/ui/server/deployments.html +50 -50
  149. package/dist/ui/server/diagnostics.html +2 -2
  150. package/dist/ui/server/firewall.html +76 -76
  151. package/dist/ui/server/fleet.html +34 -34
  152. package/dist/ui/server/logs.html +24 -24
  153. package/dist/ui/server/metrics.html +112 -112
  154. package/dist/ui/server/security.html +1 -1
  155. package/dist/ui/server/services.html +27 -27
  156. package/dist/ui/server/sites.html +120 -120
  157. package/dist/ui/server/ssh-keys.html +51 -51
  158. package/dist/ui/server/team.html +144 -144
  159. package/dist/ui/server/terminal.html +15 -15
  160. package/dist/ui/serverless/alarms.html +52 -52
  161. package/dist/ui/serverless/assets.html +27 -27
  162. package/dist/ui/serverless/cost.html +2 -2
  163. package/dist/ui/serverless/data.html +36 -36
  164. package/dist/ui/serverless/deployments.html +27 -27
  165. package/dist/ui/serverless/firewall.html +1 -1
  166. package/dist/ui/serverless/functions.html +40 -40
  167. package/dist/ui/serverless/logs.html +24 -24
  168. package/dist/ui/serverless/metrics.html +2 -2
  169. package/dist/ui/serverless/queues.html +47 -47
  170. package/dist/ui/serverless/secrets.html +52 -52
  171. package/dist/ui/serverless/traces.html +6 -6
  172. package/dist/ui/serverless.html +54 -54
  173. package/dist/ui-src/src/charts.ts +17499 -12662
  174. package/dist/ui-src/src/topology.ts +2 -2
  175. package/package.json +3 -3
  176. package/dist/bin/chunk-09nwf2gy.js +0 -34
  177. package/dist/bin/chunk-14cwr6eh.js +0 -70
  178. package/dist/bin/chunk-271gk1n2.js +0 -6
  179. package/dist/bin/chunk-38pq971s.js +0 -2
  180. package/dist/bin/chunk-3gykfyq4.js +0 -37
  181. package/dist/bin/chunk-3r4fb59r.js +0 -3
  182. package/dist/bin/chunk-41x17hw1.js +0 -1
  183. package/dist/bin/chunk-4vrqm9h0.js +0 -2
  184. package/dist/bin/chunk-57y1zxbf.js +0 -3
  185. package/dist/bin/chunk-598yf4bs.js +0 -1
  186. package/dist/bin/chunk-8v7ddyvf.js +0 -1
  187. package/dist/bin/chunk-92mea34a.js +0 -1
  188. package/dist/bin/chunk-9pvsff8g.js +0 -1
  189. package/dist/bin/chunk-9v39615t.js +0 -1
  190. package/dist/bin/chunk-avm7tnwe.js +0 -1
  191. package/dist/bin/chunk-ax9mr6wm.js +0 -44
  192. package/dist/bin/chunk-axhnkn5g.js +0 -2
  193. package/dist/bin/chunk-b5gd39s8.js +0 -512
  194. package/dist/bin/chunk-b9qbp8j1.js +0 -1
  195. package/dist/bin/chunk-bz828v8q.js +0 -3
  196. package/dist/bin/chunk-c1vcdgvr.js +0 -1
  197. package/dist/bin/chunk-ctd2vg9w.js +0 -2
  198. package/dist/bin/chunk-dbgffky8.js +0 -1
  199. package/dist/bin/chunk-dwr30vbv.js +0 -1
  200. package/dist/bin/chunk-e3xrwh9z.js +0 -1
  201. package/dist/bin/chunk-fhc6ntvd.js +0 -2
  202. package/dist/bin/chunk-fpm59y25.js +0 -6
  203. package/dist/bin/chunk-fvbxvq6b.js +0 -1
  204. package/dist/bin/chunk-fy8j3y8p.js +0 -92
  205. package/dist/bin/chunk-fz21b57w.js +0 -1
  206. package/dist/bin/chunk-gavvf0pg.js +0 -141
  207. package/dist/bin/chunk-ggn7ax8p.js +0 -4
  208. package/dist/bin/chunk-gpe2prkm.js +0 -1
  209. package/dist/bin/chunk-gqf6jsmy.js +0 -1
  210. package/dist/bin/chunk-h5pa5men.js +0 -2
  211. package/dist/bin/chunk-hm08xdxf.js +0 -2
  212. package/dist/bin/chunk-hzgz13nf.js +0 -1
  213. package/dist/bin/chunk-hzqw8xm5.js +0 -111
  214. package/dist/bin/chunk-j703btc5.js +0 -50
  215. package/dist/bin/chunk-jpjamjey.js +0 -6935
  216. package/dist/bin/chunk-m2zwtapr.js +0 -1
  217. package/dist/bin/chunk-m669wtgr.js +0 -1
  218. package/dist/bin/chunk-mr0atd2s.js +0 -2
  219. package/dist/bin/chunk-ngcyftm2.js +0 -1
  220. package/dist/bin/chunk-p66ptpmr.js +0 -2
  221. package/dist/bin/chunk-p8q9bq9g.js +0 -1
  222. package/dist/bin/chunk-r3kv0vm9.js +0 -6
  223. package/dist/bin/chunk-r9hjwcj9.js +0 -6
  224. package/dist/bin/chunk-rtczra13.js +0 -1
  225. package/dist/bin/chunk-rytk89az.js +0 -60
  226. package/dist/bin/chunk-sgyffpgm.js +0 -581
  227. package/dist/bin/chunk-vek8a0w6.js +0 -1
  228. package/dist/bin/chunk-waayf9ay.js +0 -2
  229. package/dist/bin/chunk-yv9sth30.js +0 -1
  230. package/dist/chunk-01d86gt1.js +0 -1324
  231. package/dist/chunk-050r7ycy.js +0 -46516
  232. package/dist/chunk-1c8dbv57.js +0 -7278
  233. package/dist/chunk-29rse4p1.js +0 -12203
  234. package/dist/chunk-32e7ya18.js +0 -642
  235. package/dist/chunk-4cjrg98a.js +0 -597
  236. package/dist/chunk-50jpda9q.js +0 -371
  237. package/dist/chunk-6a1t7fnq.js +0 -12121
  238. package/dist/chunk-728jvrr0.js +0 -1701
  239. package/dist/chunk-7m60qnc8.js +0 -1762
  240. package/dist/chunk-aa2dkn7b.js +0 -205
  241. package/dist/chunk-d48vtdj4.js +0 -433
  242. package/dist/chunk-f55nkpvb.js +0 -8
  243. package/dist/chunk-fgk8cqew.js +0 -152
  244. package/dist/chunk-he9a874b.js +0 -769
  245. package/dist/chunk-k2yyatfw.js +0 -10
  246. package/dist/chunk-k4px0bnv.js +0 -23
  247. package/dist/chunk-nsgqsmrh.js +0 -1779
  248. package/dist/chunk-q0st3se8.js +0 -42033
  249. package/dist/chunk-qr803fye.js +0 -2122
  250. package/dist/chunk-rds0sy87.js +0 -1771
  251. package/dist/chunk-ttz2ra5j.js +0 -12
  252. package/dist/chunk-v0bahtg2.js +0 -4
  253. package/dist/chunk-va2yd85b.js +0 -200
  254. package/dist/chunk-x9s0cqfx.js +0 -13
  255. 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 };