@gugananuvem/aws-local-simulator 1.0.34 → 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 (150) hide show
  1. package/README.md +662 -658
  2. package/package.json +11 -4
  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/handler-loader.js +50 -5
  100. package/src/services/lambda/index.js +26 -0
  101. package/src/services/lambda/server.js +18 -12
  102. package/src/services/lambda/simulator.js +73 -17
  103. package/src/services/opensearch/index.js +105 -0
  104. package/src/services/opensearch/models/document.js +115 -0
  105. package/src/services/opensearch/models/index.js +73 -0
  106. package/src/services/opensearch/server.js +310 -0
  107. package/src/services/opensearch/simulator.js +605 -0
  108. package/src/services/opensearch/store.js +162 -0
  109. package/src/services/organizations/control-tower-simulator.js +321 -0
  110. package/src/services/organizations/control-tower-store.js +182 -0
  111. package/src/services/organizations/iam-integration.js +413 -0
  112. package/src/services/organizations/index.js +172 -0
  113. package/src/services/organizations/models/index.js +13 -0
  114. package/src/services/organizations/models/invitation.js +48 -0
  115. package/src/services/organizations/models/organization.js +566 -0
  116. package/src/services/organizations/models/role.js +244 -0
  117. package/src/services/organizations/models/scp.js +131 -0
  118. package/src/services/organizations/server.js +736 -0
  119. package/src/services/organizations/simulator.js +593 -0
  120. package/src/services/organizations/store.js +235 -0
  121. package/src/services/organizations/vpc-integration.js +453 -0
  122. package/src/services/route53/index.js +67 -0
  123. package/src/services/route53/models/healthCheck.js +101 -0
  124. package/src/services/route53/models/hostedZone.js +37 -0
  125. package/src/services/route53/models/resourceRecord.js +106 -0
  126. package/src/services/route53/server.js +841 -0
  127. package/src/services/route53/simulator.js +350 -0
  128. package/src/services/s3/index.js +62 -0
  129. package/src/services/s3/presigned-url-generator.js +337 -0
  130. package/src/services/s3/server.js +231 -0
  131. package/src/services/s3/simulator.js +551 -4
  132. package/src/services/sns/index.js +31 -0
  133. package/src/services/sns/server.js +9 -0
  134. package/src/services/sqs/index.js +38 -0
  135. package/src/services/sqs/server.js +57 -4
  136. package/src/services/sqs/simulator.js +423 -33
  137. package/src/services/sts/simulator.js +209 -17
  138. package/src/services/vpc/README.md +459 -0
  139. package/src/services/vpc/ec2ResponseFormatter.js +431 -0
  140. package/src/services/vpc/index.js +90 -0
  141. package/src/services/vpc/models/internetGateway.js +71 -0
  142. package/src/services/vpc/models/routeTable.js +160 -0
  143. package/src/services/vpc/models/subnet.js +48 -0
  144. package/src/services/vpc/models/vpc.js +37 -0
  145. package/src/services/vpc/models/vpcEndpoint.js +100 -0
  146. package/src/services/vpc/models/vpcGateway.js +134 -0
  147. package/src/services/vpc/server.js +836 -0
  148. package/src/services/vpc/simulator.js +613 -0
  149. package/src/utils/policy-cache.js +215 -0
  150. package/aws-config +0 -154
@@ -0,0 +1,431 @@
1
+ /**
2
+ * EC2ResponseFormatter
3
+ * Converte respostas do VPC Simulator para formato XML compatível com AWS CLI
4
+ */
5
+
6
+ const xml = require('xmlbuilder');
7
+
8
+ class EC2ResponseFormatter {
9
+ /**
10
+ * Formata resposta DescribeVpcs para XML
11
+ */
12
+ static formatDescribeVpcsResponse(vpcs, requestId = 'vpc-request-1') {
13
+ const xmlObj = {
14
+ DescribeVpcsResponse: {
15
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
16
+ requestId: requestId,
17
+ vpcSet: {
18
+ item: vpcs.map(vpc => ({
19
+ vpcId: vpc.VpcId,
20
+ state: vpc.State,
21
+ cidrBlock: vpc.CidrBlock,
22
+ dhcpOptionsId: vpc.DhcpOptionsId || 'dopt-default',
23
+ tagSet: this._formatTags(vpc.Tags),
24
+ isDefault: vpc.IsDefault || false,
25
+ cidrBlockAssociationSet: {
26
+ item: {
27
+ cidrBlock: vpc.CidrBlock,
28
+ cidrBlockState: {
29
+ state: 'associated'
30
+ }
31
+ }
32
+ }
33
+ }))
34
+ }
35
+ }
36
+ };
37
+
38
+ return this._buildXml(xmlObj);
39
+ }
40
+
41
+ /**
42
+ * Formata resposta CreateVpc para XML
43
+ */
44
+ static formatCreateVpcResponse(vpc, requestId = 'vpc-request-1') {
45
+ const xmlObj = {
46
+ CreateVpcResponse: {
47
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
48
+ requestId: requestId,
49
+ vpc: {
50
+ vpcId: vpc.VpcId,
51
+ state: vpc.State,
52
+ cidrBlock: vpc.CidrBlock,
53
+ dhcpOptionsId: vpc.DhcpOptionsId || 'dopt-default',
54
+ tagSet: this._formatTags(vpc.Tags),
55
+ isDefault: vpc.IsDefault || false,
56
+ cidrBlockAssociationSet: {
57
+ item: {
58
+ cidrBlock: vpc.CidrBlock,
59
+ cidrBlockState: {
60
+ state: 'associated'
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+ };
67
+
68
+ return this._buildXml(xmlObj);
69
+ }
70
+
71
+ /**
72
+ * Formata resposta DeleteVpc para XML
73
+ */
74
+ static formatDeleteVpcResponse(requestId = 'vpc-request-1') {
75
+ const xmlObj = {
76
+ DeleteVpcResponse: {
77
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
78
+ requestId: requestId,
79
+ 'return': true
80
+ }
81
+ };
82
+
83
+ return this._buildXml(xmlObj);
84
+ }
85
+
86
+ /**
87
+ * Formata resposta DescribeSubnets para XML
88
+ */
89
+ static formatDescribeSubnetsResponse(subnets, requestId = 'vpc-request-1') {
90
+ const xmlObj = {
91
+ DescribeSubnetsResponse: {
92
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
93
+ requestId: requestId,
94
+ subnetSet: {
95
+ item: subnets.map(subnet => ({
96
+ subnetId: subnet.SubnetId,
97
+ state: subnet.State,
98
+ vpcId: subnet.VpcId,
99
+ cidrBlock: subnet.CidrBlock,
100
+ ipv6CidrBlockAssociationSet: {
101
+ item: []
102
+ },
103
+ availabilityZone: subnet.AvailabilityZone,
104
+ availabilityZoneId: this._getAZId(subnet.AvailabilityZone),
105
+ availableIpAddressCount: subnet.AvailableIpAddressCount || 251,
106
+ defaultForAz: false,
107
+ mapPublicIpOnLaunch: subnet.MapPublicIpOnLaunch || false,
108
+ mapCustomerOwnedIpOnLaunch: false,
109
+ tagSet: this._formatTags(subnet.Tags)
110
+ }))
111
+ }
112
+ }
113
+ };
114
+
115
+ return this._buildXml(xmlObj);
116
+ }
117
+
118
+ /**
119
+ * Formata resposta CreateSubnet para XML
120
+ */
121
+ static formatCreateSubnetResponse(subnet, requestId = 'vpc-request-1') {
122
+ const xmlObj = {
123
+ CreateSubnetResponse: {
124
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
125
+ requestId: requestId,
126
+ subnet: {
127
+ subnetId: subnet.SubnetId,
128
+ state: subnet.State,
129
+ vpcId: subnet.VpcId,
130
+ cidrBlock: subnet.CidrBlock,
131
+ ipv6CidrBlockAssociationSet: {
132
+ item: []
133
+ },
134
+ availabilityZone: subnet.AvailabilityZone,
135
+ availabilityZoneId: this._getAZId(subnet.AvailabilityZone),
136
+ availableIpAddressCount: subnet.AvailableIpAddressCount || 251,
137
+ defaultForAz: false,
138
+ mapPublicIpOnLaunch: subnet.MapPublicIpOnLaunch || false,
139
+ mapCustomerOwnedIpOnLaunch: false,
140
+ tagSet: this._formatTags(subnet.Tags)
141
+ }
142
+ }
143
+ };
144
+
145
+ return this._buildXml(xmlObj);
146
+ }
147
+
148
+ /**
149
+ * Formata resposta DeleteSubnet para XML
150
+ */
151
+ static formatDeleteSubnetResponse(requestId = 'vpc-request-1') {
152
+ const xmlObj = {
153
+ DeleteSubnetResponse: {
154
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
155
+ requestId: requestId,
156
+ 'return': true
157
+ }
158
+ };
159
+
160
+ return this._buildXml(xmlObj);
161
+ }
162
+
163
+ /**
164
+ * Formata resposta DescribeInternetGateways para XML
165
+ */
166
+ static formatDescribeIgwResponse(igws, requestId = 'vpc-request-1') {
167
+ const xmlObj = {
168
+ DescribeInternetGatewaysResponse: {
169
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
170
+ requestId: requestId,
171
+ internetGatewaySet: {
172
+ item: igws.map(igw => ({
173
+ internetGatewayId: igw.InternetGatewayId,
174
+ attachmentSet: {
175
+ item: igw.Attachments.map(att => ({
176
+ vpcId: att.VpcId,
177
+ state: att.State
178
+ }))
179
+ },
180
+ tagSet: this._formatTags(igw.Tags)
181
+ }))
182
+ }
183
+ }
184
+ };
185
+
186
+ return this._buildXml(xmlObj);
187
+ }
188
+
189
+ /**
190
+ * Formata resposta CreateInternetGateway para XML
191
+ */
192
+ static formatCreateIgwResponse(igw, requestId = 'vpc-request-1') {
193
+ const xmlObj = {
194
+ CreateInternetGatewayResponse: {
195
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
196
+ requestId: requestId,
197
+ internetGateway: {
198
+ internetGatewayId: igw.InternetGatewayId,
199
+ attachmentSet: {
200
+ item: igw.Attachments.map(att => ({
201
+ vpcId: att.VpcId,
202
+ state: att.State
203
+ }))
204
+ },
205
+ tagSet: this._formatTags(igw.Tags)
206
+ }
207
+ }
208
+ };
209
+
210
+ return this._buildXml(xmlObj);
211
+ }
212
+
213
+ /**
214
+ * Formata resposta AttachInternetGateway para XML
215
+ */
216
+ static formatAttachIgwResponse(requestId = 'vpc-request-1') {
217
+ const xmlObj = {
218
+ AttachInternetGatewayResponse: {
219
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
220
+ requestId: requestId,
221
+ 'return': true
222
+ }
223
+ };
224
+
225
+ return this._buildXml(xmlObj);
226
+ }
227
+
228
+ /**
229
+ * Formata resposta DetachInternetGateway para XML
230
+ */
231
+ static formatDetachIgwResponse(requestId = 'vpc-request-1') {
232
+ const xmlObj = {
233
+ DetachInternetGatewayResponse: {
234
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
235
+ requestId: requestId,
236
+ 'return': true
237
+ }
238
+ };
239
+
240
+ return this._buildXml(xmlObj);
241
+ }
242
+
243
+ /**
244
+ * Formata resposta DeleteInternetGateway para XML
245
+ */
246
+ static formatDeleteIgwResponse(requestId = 'vpc-request-1') {
247
+ const xmlObj = {
248
+ DeleteInternetGatewayResponse: {
249
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
250
+ requestId: requestId,
251
+ 'return': true
252
+ }
253
+ };
254
+
255
+ return this._buildXml(xmlObj);
256
+ }
257
+
258
+ /**
259
+ * Formata resposta DescribeRouteTables para XML
260
+ */
261
+ static formatDescribeRouteTablesResponse(routeTables, requestId = 'vpc-request-1') {
262
+ const xmlObj = {
263
+ DescribeRouteTablesResponse: {
264
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
265
+ requestId: requestId,
266
+ routeTableSet: {
267
+ item: routeTables.map(rt => ({
268
+ routeTableId: rt.RouteTableId,
269
+ vpcId: rt.VpcId,
270
+ routeSet: {
271
+ item: rt.Routes.map(route => ({
272
+ destinationCidrBlock: route.DestinationCidrBlock,
273
+ target: route.Target,
274
+ state: route.State || 'active',
275
+ origin: route.Origin || 'CreateRouteTable'
276
+ }))
277
+ },
278
+ associationSet: {
279
+ item: rt.Associations.map(assoc => ({
280
+ routeTableAssociationId: assoc.RouteTableAssociationId,
281
+ routeTableId: assoc.RouteTableId,
282
+ subnetId: assoc.SubnetId || '',
283
+ main: assoc.Main || false,
284
+ associationState: {
285
+ state: assoc.State || 'associated'
286
+ }
287
+ }))
288
+ },
289
+ tagSet: this._formatTags(rt.Tags),
290
+ propagatingVgwSet: []
291
+ }))
292
+ }
293
+ }
294
+ };
295
+
296
+ return this._buildXml(xmlObj);
297
+ }
298
+
299
+ /**
300
+ * Formata resposta CreateRouteTable para XML
301
+ */
302
+ static formatCreateRouteTableResponse(routeTable, requestId = 'vpc-request-1') {
303
+ const xmlObj = {
304
+ CreateRouteTableResponse: {
305
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
306
+ requestId: requestId,
307
+ routeTable: {
308
+ routeTableId: routeTable.RouteTableId,
309
+ vpcId: routeTable.VpcId,
310
+ routeSet: {
311
+ item: routeTable.Routes.map(route => ({
312
+ destinationCidrBlock: route.DestinationCidrBlock,
313
+ target: route.Target,
314
+ state: route.State || 'active',
315
+ origin: route.Origin || 'CreateRouteTable'
316
+ }))
317
+ },
318
+ associationSet: {
319
+ item: routeTable.Associations.map(assoc => ({
320
+ routeTableAssociationId: assoc.RouteTableAssociationId,
321
+ routeTableId: assoc.RouteTableId,
322
+ subnetId: assoc.SubnetId || '',
323
+ main: assoc.Main || false,
324
+ associationState: {
325
+ state: assoc.State || 'associated'
326
+ }
327
+ }))
328
+ },
329
+ tagSet: this._formatTags(routeTable.Tags),
330
+ propagatingVgwSet: []
331
+ }
332
+ }
333
+ };
334
+
335
+ return this._buildXml(xmlObj);
336
+ }
337
+
338
+ /**
339
+ * Formata resposta DeleteRouteTable para XML
340
+ */
341
+ static formatDeleteRouteTableResponse(requestId = 'vpc-request-1') {
342
+ const xmlObj = {
343
+ DeleteRouteTableResponse: {
344
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
345
+ requestId: requestId,
346
+ 'return': true
347
+ }
348
+ };
349
+
350
+ return this._buildXml(xmlObj);
351
+ }
352
+
353
+ /**
354
+ * Formata resposta CreateRoute para XML
355
+ */
356
+ static formatCreateRouteResponse(requestId = 'vpc-request-1') {
357
+ const xmlObj = {
358
+ CreateRouteResponse: {
359
+ '@xmlns': 'http://ec2.amazonaws.com/doc/2016-11-15/',
360
+ requestId: requestId,
361
+ 'return': true
362
+ }
363
+ };
364
+
365
+ return this._buildXml(xmlObj);
366
+ }
367
+
368
+ /**
369
+ * Formata erro para XML
370
+ */
371
+ static formatErrorResponse(code, message, requestId = 'vpc-request-1') {
372
+ const xmlObj = {
373
+ Response: {
374
+ Errors: {
375
+ Error: {
376
+ Code: code,
377
+ Message: message
378
+ }
379
+ },
380
+ RequestId: requestId
381
+ }
382
+ };
383
+
384
+ return this._buildXml(xmlObj);
385
+ }
386
+
387
+ /**
388
+ * Helper: formata tags em XML
389
+ */
390
+ static _formatTags(tags = []) {
391
+ if (!tags || tags.length === 0) {
392
+ return { item: [] };
393
+ }
394
+
395
+ return {
396
+ item: tags.map(tag => ({
397
+ key: tag.Key || tag.key,
398
+ value: tag.Value || tag.value
399
+ }))
400
+ };
401
+ }
402
+
403
+ /**
404
+ * Helper: converte zona de disponibilidade para AZ ID
405
+ */
406
+ static _getAZId(availabilityZone) {
407
+ // Exemplo: us-east-1a -> use1-az1
408
+ const azMap = {
409
+ 'us-east-1a': 'use1-az1',
410
+ 'us-east-1b': 'use1-az2',
411
+ 'us-east-1c': 'use1-az4',
412
+ 'us-west-1a': 'usw1-az1',
413
+ 'us-west-1b': 'usw1-az2',
414
+ 'eu-west-1a': 'euw1-az1',
415
+ 'eu-west-1b': 'euw1-az2',
416
+ 'eu-west-1c': 'euw1-az3'
417
+ };
418
+
419
+ return azMap[availabilityZone] || 'use1-az1';
420
+ }
421
+
422
+ /**
423
+ * Helper: constrói XML a partir de objeto
424
+ */
425
+ static _buildXml(obj) {
426
+ const root = xml.create(obj);
427
+ return '<?xml version="1.0" encoding="UTF-8"?>\n' + root.toString();
428
+ }
429
+ }
430
+
431
+ module.exports = EC2ResponseFormatter;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * VPC Service - Ponto de entrada
3
+ * Exporta o serviço principal e seus componentes
4
+ */
5
+
6
+ const VPCServer = require('./server');
7
+ const VPCSimulator = require('./simulator');
8
+
9
+ class VPCService {
10
+ constructor(config) {
11
+ this.config = config;
12
+ this.name = 'vpc';
13
+ this.port = config.ports.vpc || 4014;
14
+ this.server = null;
15
+ this.simulator = null;
16
+ this.isRunning = false;
17
+ }
18
+
19
+ async initialize() {
20
+ const logger = require('../../utils/logger');
21
+ logger.debug(`Inicializando VPC Service na porta ${this.port}...`);
22
+
23
+ this.simulator = new VPCSimulator(this.config.vpc || {});
24
+ await this.simulator.initialize();
25
+
26
+ this.server = new VPCServer(this.port, this.config);
27
+ this.server.simulator = this.simulator;
28
+
29
+ await this.server.initialize();
30
+
31
+ logger.debug('VPC Service inicializado');
32
+ }
33
+
34
+ injectDependencies(server) {
35
+ // Aqui você pode injetar dependências de outros serviços se necessário
36
+ // Por exemplo, para integração com CloudFormation
37
+ }
38
+
39
+ async start() {
40
+ const logger = require('../../utils/logger');
41
+
42
+ if (this.isRunning) {
43
+ logger.warn('VPC Service já está em execução');
44
+ return;
45
+ }
46
+
47
+ try {
48
+ await this.server.start();
49
+ this.isRunning = true;
50
+ logger.info('VPC Service iniciado com sucesso');
51
+ } catch (error) {
52
+ logger.error(`Erro ao iniciar VPC Service: ${error.message}`);
53
+ throw error;
54
+ }
55
+ }
56
+
57
+ async stop() {
58
+ const logger = require('../../utils/logger');
59
+
60
+ if (!this.isRunning) {
61
+ logger.warn('VPC Service não está em execução');
62
+ return;
63
+ }
64
+
65
+ try {
66
+ await this.server.stop();
67
+ this.isRunning = false;
68
+ logger.info('VPC Service parado com sucesso');
69
+ } catch (error) {
70
+ logger.error(`Erro ao parar VPC Service: ${error.message}`);
71
+ throw error;
72
+ }
73
+ }
74
+
75
+ getSimulator() {
76
+ return this.simulator;
77
+ }
78
+
79
+ getStatus() {
80
+ return {
81
+ name: this.name,
82
+ running: this.isRunning,
83
+ port: this.port,
84
+ endpoint: `http://localhost:${this.port}`,
85
+ resources: this.simulator.getAllResources()
86
+ };
87
+ }
88
+ }
89
+
90
+ module.exports = VPCService;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Internet Gateway Model
3
+ */
4
+
5
+ const { v4: uuidv4 } = require('uuid');
6
+
7
+ class InternetGatewayAttachment {
8
+ constructor(vpcId) {
9
+ this.VpcId = vpcId;
10
+ this.State = 'available';
11
+ this.CreatedAt = new Date().toISOString();
12
+ }
13
+
14
+ toJSON() {
15
+ return {
16
+ VpcId: this.VpcId,
17
+ State: this.State
18
+ };
19
+ }
20
+ }
21
+
22
+ class InternetGateway {
23
+ constructor(tags = []) {
24
+ this.InternetGatewayId = `igw-${uuidv4().substring(0, 8)}`;
25
+ this.Attachments = [];
26
+ this.Tags = tags;
27
+ this.State = 'available';
28
+ this.OwnerId = '123456789012';
29
+ this.CreatedAt = new Date().toISOString();
30
+ }
31
+
32
+ attach(vpcId) {
33
+ // Verificar se já está anexado a esta VPC
34
+ const exists = this.Attachments.some(a => a.VpcId === vpcId);
35
+ if (exists) {
36
+ throw new Error(`IGW already attached to VPC ${vpcId}`);
37
+ }
38
+
39
+ const attachment = new InternetGatewayAttachment(vpcId);
40
+ this.Attachments.push(attachment);
41
+ return attachment;
42
+ }
43
+
44
+ detach(vpcId) {
45
+ const index = this.Attachments.findIndex(a => a.VpcId === vpcId);
46
+ if (index === -1) {
47
+ throw new Error(`IGW not attached to VPC ${vpcId}`);
48
+ }
49
+
50
+ const attachment = this.Attachments[index];
51
+ this.Attachments.splice(index, 1);
52
+ return attachment;
53
+ }
54
+
55
+ isAttachedTo(vpcId) {
56
+ return this.Attachments.some(a => a.VpcId === vpcId);
57
+ }
58
+
59
+ toJSON() {
60
+ return {
61
+ InternetGatewayId: this.InternetGatewayId,
62
+ Attachments: this.Attachments.map(a => a.toJSON()),
63
+ Tags: this.Tags,
64
+ State: this.State,
65
+ OwnerId: this.OwnerId,
66
+ CreatedAt: this.CreatedAt
67
+ };
68
+ }
69
+ }
70
+
71
+ module.exports = { InternetGateway, InternetGatewayAttachment };