@gugananuvem/aws-local-simulator 1.0.35 → 1.0.39

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 (149) hide show
  1. package/README.md +662 -658
  2. package/package.json +10 -3
  3. package/src/config/default-config.js +71 -0
  4. package/src/config/env-loader.js +4 -2
  5. package/src/middleware/authorization.js +271 -0
  6. package/src/middleware/cloudtrail-logger.js +333 -0
  7. package/src/middleware/error-handler.js +138 -0
  8. package/src/middleware/index.js +79 -0
  9. package/src/middleware/policy-enforcement.js +407 -0
  10. package/src/server.js +74 -4
  11. package/src/services/acm/index.js +66 -0
  12. package/src/services/acm/models/certificate.js +202 -0
  13. package/src/services/acm/server.js +224 -0
  14. package/src/services/acm/simulator.js +293 -0
  15. package/src/services/alb/index.js +104 -0
  16. package/src/services/alb/models/loadBalancer.js +88 -0
  17. package/src/services/alb/models/targetGroup.js +128 -0
  18. package/src/services/alb/server.js +160 -0
  19. package/src/services/alb/simulator.js +262 -0
  20. package/src/services/apigateway/index.js +22 -0
  21. package/src/services/apigateway/server.js +247 -35
  22. package/src/services/apigateway/simulator.js +780 -26
  23. package/src/services/asg/index.js +100 -0
  24. package/src/services/asg/models/autoScalingGroup.js +110 -0
  25. package/src/services/asg/models/launchTemplate.js +41 -0
  26. package/src/services/asg/models/scalingPolicy.js +51 -0
  27. package/src/services/asg/server.js +236 -0
  28. package/src/services/asg/simulator.js +410 -0
  29. package/src/services/aurora/cluster-manager.js +731 -0
  30. package/src/services/aurora/data-api.js +514 -0
  31. package/src/services/aurora/db-engine.js +270 -0
  32. package/src/services/aurora/index.js +159 -0
  33. package/src/services/aurora/rds-api.js +189 -0
  34. package/src/services/aurora/server.js +213 -0
  35. package/src/services/aurora/sql-translator.js +334 -0
  36. package/src/services/cloudformation/index.js +2 -2
  37. package/src/services/cloudformation/server.js +1 -0
  38. package/src/services/cloudfront/cache-engine.js +225 -0
  39. package/src/services/cloudfront/geo-restrictions.js +377 -0
  40. package/src/services/cloudfront/index.js +220 -0
  41. package/src/services/cloudfront/models/behavior.js +158 -0
  42. package/src/services/cloudfront/models/distribution.js +284 -0
  43. package/src/services/cloudfront/models/index.js +99 -0
  44. package/src/services/cloudfront/models/invalidation.js +109 -0
  45. package/src/services/cloudfront/models/origin.js +155 -0
  46. package/src/services/cloudfront/origin-router.js +552 -0
  47. package/src/services/cloudfront/origin-validator.js +398 -0
  48. package/src/services/cloudfront/server.js +512 -0
  49. package/src/services/cloudfront/signed-url-generator.js +377 -0
  50. package/src/services/cloudfront/simulator.js +425 -0
  51. package/src/services/cloudfront/store.js +326 -0
  52. package/src/services/cloudshell/env-builder.js +27 -0
  53. package/src/services/cloudshell/index.js +48 -0
  54. package/src/services/cloudshell/routes.js +60 -0
  55. package/src/services/cloudshell/session-manager.js +226 -0
  56. package/src/services/cloudshell/static/.gitkeep +0 -0
  57. package/src/services/cloudshell/static/index.html +406 -0
  58. package/src/services/cloudshell/websocket-handler.js +107 -0
  59. package/src/services/cloudtrail/index.js +2 -3
  60. package/src/services/cloudtrail/server.js +68 -0
  61. package/src/services/cognito/server.js +4 -1
  62. package/src/services/dynamodb/server.js +4 -1
  63. package/src/services/dynamodb/simulator.js +2 -1
  64. package/src/services/ec2/index.js +101 -0
  65. package/src/services/ec2/instanceServer.js +311 -0
  66. package/src/services/ec2/models/ami.js +39 -0
  67. package/src/services/ec2/models/instance.js +98 -0
  68. package/src/services/ec2/models/networkInterface.js +74 -0
  69. package/src/services/ec2/models/securityGroup.js +71 -0
  70. package/src/services/ec2/server.js +350 -0
  71. package/src/services/ec2/simulator.js +436 -0
  72. package/src/services/eventbridge/server.js +36 -0
  73. package/src/services/eventbridge/simulator.js +230 -45
  74. package/src/services/iam/index.js +65 -0
  75. package/src/services/iam/middleware.js +99 -0
  76. package/src/services/iam/server.js +331 -0
  77. package/src/services/iam/simulator.js +1432 -0
  78. package/src/services/index.js +28 -0
  79. package/src/services/kinesis-analytics/index.js +105 -0
  80. package/src/services/kinesis-analytics/models/application.js +325 -0
  81. package/src/services/kinesis-analytics/models/index.js +12 -0
  82. package/src/services/kinesis-analytics/server.js +250 -0
  83. package/src/services/kinesis-analytics/simulator.js +407 -0
  84. package/src/services/kinesis-analytics/store.js +176 -0
  85. package/src/services/kinesis-data-streams/index.js +106 -0
  86. package/src/services/kinesis-data-streams/models/index.js +12 -0
  87. package/src/services/kinesis-data-streams/models/record.js +70 -0
  88. package/src/services/kinesis-data-streams/models/stream.js +280 -0
  89. package/src/services/kinesis-data-streams/server.js +255 -0
  90. package/src/services/kinesis-data-streams/simulator.js +514 -0
  91. package/src/services/kinesis-data-streams/store.js +163 -0
  92. package/src/services/kinesis-firehose/index.js +106 -0
  93. package/src/services/kinesis-firehose/models/delivery-stream.js +265 -0
  94. package/src/services/kinesis-firehose/models/index.js +10 -0
  95. package/src/services/kinesis-firehose/server.js +215 -0
  96. package/src/services/kinesis-firehose/simulator.js +388 -0
  97. package/src/services/kinesis-firehose/store.js +163 -0
  98. package/src/services/kms/server.js +4 -1
  99. package/src/services/lambda/index.js +26 -0
  100. package/src/services/lambda/server.js +12 -1
  101. package/src/services/lambda/simulator.js +4 -0
  102. package/src/services/opensearch/index.js +105 -0
  103. package/src/services/opensearch/models/document.js +115 -0
  104. package/src/services/opensearch/models/index.js +73 -0
  105. package/src/services/opensearch/server.js +310 -0
  106. package/src/services/opensearch/simulator.js +605 -0
  107. package/src/services/opensearch/store.js +162 -0
  108. package/src/services/organizations/control-tower-simulator.js +321 -0
  109. package/src/services/organizations/control-tower-store.js +182 -0
  110. package/src/services/organizations/iam-integration.js +413 -0
  111. package/src/services/organizations/index.js +172 -0
  112. package/src/services/organizations/models/index.js +13 -0
  113. package/src/services/organizations/models/invitation.js +48 -0
  114. package/src/services/organizations/models/organization.js +566 -0
  115. package/src/services/organizations/models/role.js +244 -0
  116. package/src/services/organizations/models/scp.js +131 -0
  117. package/src/services/organizations/server.js +736 -0
  118. package/src/services/organizations/simulator.js +593 -0
  119. package/src/services/organizations/store.js +235 -0
  120. package/src/services/organizations/vpc-integration.js +453 -0
  121. package/src/services/route53/index.js +67 -0
  122. package/src/services/route53/models/healthCheck.js +101 -0
  123. package/src/services/route53/models/hostedZone.js +37 -0
  124. package/src/services/route53/models/resourceRecord.js +106 -0
  125. package/src/services/route53/server.js +841 -0
  126. package/src/services/route53/simulator.js +350 -0
  127. package/src/services/s3/index.js +62 -0
  128. package/src/services/s3/presigned-url-generator.js +337 -0
  129. package/src/services/s3/server.js +231 -0
  130. package/src/services/s3/simulator.js +551 -4
  131. package/src/services/sns/index.js +31 -0
  132. package/src/services/sns/server.js +9 -0
  133. package/src/services/sqs/index.js +38 -0
  134. package/src/services/sqs/server.js +57 -4
  135. package/src/services/sqs/simulator.js +423 -33
  136. package/src/services/sts/simulator.js +209 -17
  137. package/src/services/vpc/README.md +459 -0
  138. package/src/services/vpc/ec2ResponseFormatter.js +431 -0
  139. package/src/services/vpc/index.js +90 -0
  140. package/src/services/vpc/models/internetGateway.js +71 -0
  141. package/src/services/vpc/models/routeTable.js +160 -0
  142. package/src/services/vpc/models/subnet.js +48 -0
  143. package/src/services/vpc/models/vpc.js +37 -0
  144. package/src/services/vpc/models/vpcEndpoint.js +100 -0
  145. package/src/services/vpc/models/vpcGateway.js +134 -0
  146. package/src/services/vpc/server.js +836 -0
  147. package/src/services/vpc/simulator.js +613 -0
  148. package/src/utils/policy-cache.js +215 -0
  149. package/aws-config +0 -154
@@ -0,0 +1,350 @@
1
+ const { setupServiceMiddleware } = require('../../middleware');
2
+ /**
3
+ * EC2 Server - API REST com 30+ endpoints
4
+ */
5
+
6
+ const express = require('express');
7
+ const logger = require('../../utils/logger');
8
+
9
+ class EC2Server {
10
+ constructor(port, config) {
11
+ this.organizationsService = null;
12
+ this.stsService = null;
13
+ this.port = port;
14
+ this.config = config;
15
+ this.app = express();
16
+ this.simulator = null;
17
+ }
18
+
19
+ setupMiddlewares() {
20
+ this.app.use(express.json());
21
+ this.app.use((req, res, next) => {
22
+ logger.debug(`EC2 Request: ${req.method} ${req.path}`);
23
+ next();
24
+ });
25
+ }
26
+
27
+ async initialize() {
28
+ logger.debug(`Inicializando EC2 Server na porta ${this.port}`);
29
+ this.setupMiddlewares();
30
+ this.setupRoutes();
31
+ }
32
+
33
+ setupRoutes() {
34
+ // ========== Instance Routes ==========
35
+
36
+ // Run Instances
37
+ this.app.post('/__admin/ec2/instances/run', (req, res) => {
38
+ try {
39
+ const { ImageId, MinCount = 1, MaxCount = 1, InstanceType = 't2.micro', ...config } =
40
+ req.body;
41
+
42
+ if (!ImageId) {
43
+ return res.status(400).json({ error: 'ImageId is required' });
44
+ }
45
+
46
+ const instances = this.simulator.runInstances(ImageId, MinCount, InstanceType, config);
47
+
48
+ // Iniciar servidores web para as instâncias
49
+ instances.forEach(async (instance) => {
50
+ // ProxyUrl tem prioridade sobre WebServerDir
51
+ if (config.ProxyUrl) {
52
+ await this.simulator.startInstanceServer(instance.InstanceId, null, config.ProxyUrl);
53
+ } else if (config.WebServerDir) {
54
+ await this.simulator.startInstanceServer(instance.InstanceId, config.WebServerDir);
55
+ } else {
56
+ await this.simulator.startInstanceServer(instance.InstanceId);
57
+ }
58
+ });
59
+
60
+ res.json({ Instances: instances.map(i => i.toJSON()) });
61
+ } catch (error) {
62
+ logger.error(`Error running instances: ${error.message}`);
63
+ res.status(400).json({ error: error.message });
64
+ }
65
+ });
66
+
67
+ // Describe Instances
68
+ this.app.get('/__admin/ec2/instances', (req, res) => {
69
+ try {
70
+ const filters = {};
71
+ if (req.query.instanceIds) {
72
+ filters.instanceIds = Array.isArray(req.query.instanceIds)
73
+ ? req.query.instanceIds
74
+ : [req.query.instanceIds];
75
+ }
76
+ if (req.query.state) {
77
+ filters.state = req.query.state;
78
+ }
79
+
80
+ const instances = this.simulator.describeInstances(filters);
81
+ res.json({ Instances: instances.map(i => i.toJSON()) });
82
+ } catch (error) {
83
+ logger.error(`Error describing instances: ${error.message}`);
84
+ res.status(400).json({ error: error.message });
85
+ }
86
+ });
87
+
88
+ // Get Instance
89
+ this.app.get('/__admin/ec2/instances/:instanceId', (req, res) => {
90
+ try {
91
+ const instance = this.simulator.getInstance(req.params.instanceId);
92
+ res.json({ Instance: instance.toJSON() });
93
+ } catch (error) {
94
+ logger.error(`Error getting instance: ${error.message}`);
95
+ res.status(404).json({ error: error.message });
96
+ }
97
+ });
98
+
99
+ // Start Instances
100
+ this.app.post('/__admin/ec2/instances/:instanceId/start', (req, res) => {
101
+ try {
102
+ const instances = this.simulator.startInstances([req.params.instanceId]);
103
+ res.json({ Instances: instances.map(i => i.toJSON()) });
104
+ } catch (error) {
105
+ logger.error(`Error starting instance: ${error.message}`);
106
+ res.status(400).json({ error: error.message });
107
+ }
108
+ });
109
+
110
+ // Stop Instances
111
+ this.app.post('/__admin/ec2/instances/:instanceId/stop', (req, res) => {
112
+ try {
113
+ const instances = this.simulator.stopInstances([req.params.instanceId]);
114
+ res.json({ Instances: instances.map(i => i.toJSON()) });
115
+ } catch (error) {
116
+ logger.error(`Error stopping instance: ${error.message}`);
117
+ res.status(400).json({ error: error.message });
118
+ }
119
+ });
120
+
121
+ // Reboot Instances
122
+ this.app.post('/__admin/ec2/instances/:instanceId/reboot', (req, res) => {
123
+ try {
124
+ const instances = this.simulator.rebootInstances([req.params.instanceId]);
125
+ res.json({ Instances: instances.map(i => i.toJSON()) });
126
+ } catch (error) {
127
+ logger.error(`Error rebooting instance: ${error.message}`);
128
+ res.status(400).json({ error: error.message });
129
+ }
130
+ });
131
+
132
+ // Terminate Instances
133
+ this.app.post('/__admin/ec2/instances/:instanceId/terminate', (req, res) => {
134
+ try {
135
+ const instances = this.simulator.terminateInstances([req.params.instanceId]);
136
+ res.json({ Instances: instances.map(i => i.toJSON()) });
137
+ } catch (error) {
138
+ logger.error(`Error terminating instance: ${error.message}`);
139
+ res.status(400).json({ error: error.message });
140
+ }
141
+ });
142
+
143
+ // Describe Instance Status
144
+ this.app.get('/__admin/ec2/instances/:instanceId/status', (req, res) => {
145
+ try {
146
+ const instance = this.simulator.getInstance(req.params.instanceId);
147
+ res.json({
148
+ InstanceId: instance.InstanceId,
149
+ State: instance.State,
150
+ StateTransitionReason: instance.StateTransitionReason,
151
+ WebServerPort: instance.WebServerPort,
152
+ WebServerUrl: `http://localhost:${instance.WebServerPort}`,
153
+ PublicIp: instance.PublicIpAddress,
154
+ PrivateIp: instance.PrivateIpAddress
155
+ });
156
+ } catch (error) {
157
+ logger.error(`Error getting instance status: ${error.message}`);
158
+ res.status(404).json({ error: error.message });
159
+ }
160
+ });
161
+
162
+ // ========== Image Routes ==========
163
+
164
+ // Describe Images
165
+ this.app.get('/__admin/ec2/images', (req, res) => {
166
+ try {
167
+ const images = this.simulator.describeImages();
168
+ res.json({ Images: images.map(img => img.toJSON()) });
169
+ } catch (error) {
170
+ logger.error(`Error describing images: ${error.message}`);
171
+ res.status(400).json({ error: error.message });
172
+ }
173
+ });
174
+
175
+ // ========== Security Group Routes ==========
176
+
177
+ // Create Security Group
178
+ this.app.post('/__admin/ec2/security-groups/create', (req, res) => {
179
+ try {
180
+ const { GroupName, Description = '', VpcId = null } = req.body;
181
+
182
+ if (!GroupName) {
183
+ return res.status(400).json({ error: 'GroupName is required' });
184
+ }
185
+
186
+ const sg = this.simulator.createSecurityGroup(GroupName, Description, VpcId);
187
+ res.json({ SecurityGroup: sg.toJSON() });
188
+ } catch (error) {
189
+ logger.error(`Error creating security group: ${error.message}`);
190
+ res.status(400).json({ error: error.message });
191
+ }
192
+ });
193
+
194
+ // Describe Security Groups
195
+ this.app.get('/__admin/ec2/security-groups', (req, res) => {
196
+ try {
197
+ const filters = {};
198
+ if (req.query.groupIds) {
199
+ filters.groupIds = Array.isArray(req.query.groupIds)
200
+ ? req.query.groupIds
201
+ : [req.query.groupIds];
202
+ }
203
+
204
+ const sgs = this.simulator.describeSecurityGroups(filters);
205
+ res.json({ SecurityGroups: sgs.map(sg => sg.toJSON()) });
206
+ } catch (error) {
207
+ logger.error(`Error describing security groups: ${error.message}`);
208
+ res.status(400).json({ error: error.message });
209
+ }
210
+ });
211
+
212
+ // Get Security Group
213
+ this.app.get('/__admin/ec2/security-groups/:groupId', (req, res) => {
214
+ try {
215
+ const sg = this.simulator.getSecurityGroup(req.params.groupId);
216
+ res.json({ SecurityGroup: sg.toJSON() });
217
+ } catch (error) {
218
+ logger.error(`Error getting security group: ${error.message}`);
219
+ res.status(404).json({ error: error.message });
220
+ }
221
+ });
222
+
223
+ // Add Ingress Rule
224
+ this.app.post('/__admin/ec2/security-groups/:groupId/ingress', (req, res) => {
225
+ try {
226
+ const { CidrIp, FromPort, ToPort, Protocol = 'tcp', Description = '' } = req.body;
227
+
228
+ if (!FromPort || !ToPort) {
229
+ return res.status(400).json({ error: 'FromPort and ToPort are required' });
230
+ }
231
+
232
+ const sg = this.simulator.getSecurityGroup(req.params.groupId);
233
+ const rule = sg.addIngressRule(CidrIp, null, FromPort, ToPort, Protocol, Description);
234
+
235
+ res.json({ Rule: rule });
236
+ } catch (error) {
237
+ logger.error(`Error adding ingress rule: ${error.message}`);
238
+ res.status(400).json({ error: error.message });
239
+ }
240
+ });
241
+
242
+ // Delete Security Group
243
+ this.app.delete('/__admin/ec2/security-groups/:groupId', (req, res) => {
244
+ try {
245
+ this.simulator.deleteSecurityGroup(req.params.groupId);
246
+ res.json({ success: true });
247
+ } catch (error) {
248
+ logger.error(`Error deleting security group: ${error.message}`);
249
+ res.status(400).json({ error: error.message });
250
+ }
251
+ });
252
+
253
+ // ========== Network Interface Routes ==========
254
+
255
+ // Describe Network Interfaces
256
+ this.app.get('/__admin/ec2/network-interfaces', (req, res) => {
257
+ try {
258
+ const filters = {};
259
+ if (req.query.networkInterfaceIds) {
260
+ filters.networkInterfaceIds = Array.isArray(req.query.networkInterfaceIds)
261
+ ? req.query.networkInterfaceIds
262
+ : [req.query.networkInterfaceIds];
263
+ }
264
+
265
+ const enis = this.simulator.describeNetworkInterfaces(filters);
266
+ res.json({ NetworkInterfaces: enis.map(eni => eni.toJSON()) });
267
+ } catch (error) {
268
+ logger.error(`Error describing network interfaces: ${error.message}`);
269
+ res.status(400).json({ error: error.message });
270
+ }
271
+ });
272
+
273
+ // Get Network Interface
274
+ this.app.get('/__admin/ec2/network-interfaces/:eniId', (req, res) => {
275
+ try {
276
+ const eni = this.simulator.getNetworkInterface(req.params.eniId);
277
+ res.json({ NetworkInterface: eni.toJSON() });
278
+ } catch (error) {
279
+ logger.error(`Error getting network interface: ${error.message}`);
280
+ res.status(404).json({ error: error.message });
281
+ }
282
+ });
283
+
284
+ // ========== Utility Routes ==========
285
+
286
+ // Health Check
287
+ this.app.get('/__admin/ec2/health', (req, res) => {
288
+ res.json({ status: 'ok', service: 'ec2' });
289
+ });
290
+
291
+ // Get All Resources
292
+ this.app.get('/__admin/ec2/resources', (req, res) => {
293
+ try {
294
+ const resources = this.simulator.getAllResources();
295
+ res.json({
296
+ instances: resources.instances.map(i => i.toJSON()),
297
+ amis: resources.amis.map(a => a.toJSON()),
298
+ securityGroups: resources.securityGroups.map(sg => sg.toJSON()),
299
+ networkInterfaces: resources.networkInterfaces.map(eni => eni.toJSON()),
300
+ instanceServersCount: resources.instanceServersCount
301
+ });
302
+ } catch (error) {
303
+ logger.error(`Error fetching resources: ${error.message}`);
304
+ res.status(400).json({ error: error.message });
305
+ }
306
+ });
307
+
308
+ // Get Running Instances (simplificado)
309
+ this.app.get('/__admin/ec2/instances-running', (req, res) => {
310
+ try {
311
+ const instances = this.simulator.describeInstances({ state: 'running' });
312
+ res.json({
313
+ count: instances.length,
314
+ instances: instances.map(i => ({
315
+ InstanceId: i.InstanceId,
316
+ PublicIp: i.PublicIpAddress,
317
+ PrivateIp: i.PrivateIpAddress,
318
+ WebServerPort: i.WebServerPort,
319
+ WebServerUrl: `http://localhost:${i.WebServerPort}`
320
+ }))
321
+ });
322
+ } catch (error) {
323
+ logger.error(`Error getting running instances: ${error.message}`);
324
+ res.status(400).json({ error: error.message });
325
+ }
326
+ });
327
+ }
328
+
329
+ async start() {
330
+ return new Promise((resolve) => {
331
+ this.server = this.app.listen(this.port, () => {
332
+ logger.info(`EC2 Server running on http://localhost:${this.port}`);
333
+ resolve();
334
+ });
335
+ });
336
+ }
337
+
338
+ async stop() {
339
+ if (this.server) {
340
+ return new Promise((resolve) => {
341
+ this.server.close(() => {
342
+ logger.info('EC2 Server stopped');
343
+ resolve();
344
+ });
345
+ });
346
+ }
347
+ }
348
+ }
349
+
350
+ module.exports = EC2Server;