@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.
- package/README.md +662 -658
- package/package.json +11 -4
- package/src/config/default-config.js +71 -0
- package/src/config/env-loader.js +4 -2
- package/src/middleware/authorization.js +271 -0
- package/src/middleware/cloudtrail-logger.js +333 -0
- package/src/middleware/error-handler.js +138 -0
- package/src/middleware/index.js +79 -0
- package/src/middleware/policy-enforcement.js +407 -0
- package/src/server.js +74 -4
- package/src/services/acm/index.js +66 -0
- package/src/services/acm/models/certificate.js +202 -0
- package/src/services/acm/server.js +224 -0
- package/src/services/acm/simulator.js +293 -0
- package/src/services/alb/index.js +104 -0
- package/src/services/alb/models/loadBalancer.js +88 -0
- package/src/services/alb/models/targetGroup.js +128 -0
- package/src/services/alb/server.js +160 -0
- package/src/services/alb/simulator.js +262 -0
- package/src/services/apigateway/index.js +22 -0
- package/src/services/apigateway/server.js +247 -35
- package/src/services/apigateway/simulator.js +780 -26
- package/src/services/asg/index.js +100 -0
- package/src/services/asg/models/autoScalingGroup.js +110 -0
- package/src/services/asg/models/launchTemplate.js +41 -0
- package/src/services/asg/models/scalingPolicy.js +51 -0
- package/src/services/asg/server.js +236 -0
- package/src/services/asg/simulator.js +410 -0
- package/src/services/aurora/cluster-manager.js +731 -0
- package/src/services/aurora/data-api.js +514 -0
- package/src/services/aurora/db-engine.js +270 -0
- package/src/services/aurora/index.js +159 -0
- package/src/services/aurora/rds-api.js +189 -0
- package/src/services/aurora/server.js +213 -0
- package/src/services/aurora/sql-translator.js +334 -0
- package/src/services/cloudformation/index.js +2 -2
- package/src/services/cloudformation/server.js +1 -0
- package/src/services/cloudfront/cache-engine.js +225 -0
- package/src/services/cloudfront/geo-restrictions.js +377 -0
- package/src/services/cloudfront/index.js +220 -0
- package/src/services/cloudfront/models/behavior.js +158 -0
- package/src/services/cloudfront/models/distribution.js +284 -0
- package/src/services/cloudfront/models/index.js +99 -0
- package/src/services/cloudfront/models/invalidation.js +109 -0
- package/src/services/cloudfront/models/origin.js +155 -0
- package/src/services/cloudfront/origin-router.js +552 -0
- package/src/services/cloudfront/origin-validator.js +398 -0
- package/src/services/cloudfront/server.js +512 -0
- package/src/services/cloudfront/signed-url-generator.js +377 -0
- package/src/services/cloudfront/simulator.js +425 -0
- package/src/services/cloudfront/store.js +326 -0
- package/src/services/cloudshell/env-builder.js +27 -0
- package/src/services/cloudshell/index.js +48 -0
- package/src/services/cloudshell/routes.js +60 -0
- package/src/services/cloudshell/session-manager.js +226 -0
- package/src/services/cloudshell/static/.gitkeep +0 -0
- package/src/services/cloudshell/static/index.html +406 -0
- package/src/services/cloudshell/websocket-handler.js +107 -0
- package/src/services/cloudtrail/index.js +2 -3
- package/src/services/cloudtrail/server.js +68 -0
- package/src/services/cognito/server.js +4 -1
- package/src/services/dynamodb/server.js +4 -1
- package/src/services/dynamodb/simulator.js +2 -1
- package/src/services/ec2/index.js +101 -0
- package/src/services/ec2/instanceServer.js +311 -0
- package/src/services/ec2/models/ami.js +39 -0
- package/src/services/ec2/models/instance.js +98 -0
- package/src/services/ec2/models/networkInterface.js +74 -0
- package/src/services/ec2/models/securityGroup.js +71 -0
- package/src/services/ec2/server.js +350 -0
- package/src/services/ec2/simulator.js +436 -0
- package/src/services/eventbridge/server.js +36 -0
- package/src/services/eventbridge/simulator.js +230 -45
- package/src/services/iam/index.js +65 -0
- package/src/services/iam/middleware.js +99 -0
- package/src/services/iam/server.js +331 -0
- package/src/services/iam/simulator.js +1432 -0
- package/src/services/index.js +28 -0
- package/src/services/kinesis-analytics/index.js +105 -0
- package/src/services/kinesis-analytics/models/application.js +325 -0
- package/src/services/kinesis-analytics/models/index.js +12 -0
- package/src/services/kinesis-analytics/server.js +250 -0
- package/src/services/kinesis-analytics/simulator.js +407 -0
- package/src/services/kinesis-analytics/store.js +176 -0
- package/src/services/kinesis-data-streams/index.js +106 -0
- package/src/services/kinesis-data-streams/models/index.js +12 -0
- package/src/services/kinesis-data-streams/models/record.js +70 -0
- package/src/services/kinesis-data-streams/models/stream.js +280 -0
- package/src/services/kinesis-data-streams/server.js +255 -0
- package/src/services/kinesis-data-streams/simulator.js +514 -0
- package/src/services/kinesis-data-streams/store.js +163 -0
- package/src/services/kinesis-firehose/index.js +106 -0
- package/src/services/kinesis-firehose/models/delivery-stream.js +265 -0
- package/src/services/kinesis-firehose/models/index.js +10 -0
- package/src/services/kinesis-firehose/server.js +215 -0
- package/src/services/kinesis-firehose/simulator.js +388 -0
- package/src/services/kinesis-firehose/store.js +163 -0
- package/src/services/kms/server.js +4 -1
- package/src/services/lambda/handler-loader.js +50 -5
- package/src/services/lambda/index.js +26 -0
- package/src/services/lambda/server.js +18 -12
- package/src/services/lambda/simulator.js +73 -17
- package/src/services/opensearch/index.js +105 -0
- package/src/services/opensearch/models/document.js +115 -0
- package/src/services/opensearch/models/index.js +73 -0
- package/src/services/opensearch/server.js +310 -0
- package/src/services/opensearch/simulator.js +605 -0
- package/src/services/opensearch/store.js +162 -0
- package/src/services/organizations/control-tower-simulator.js +321 -0
- package/src/services/organizations/control-tower-store.js +182 -0
- package/src/services/organizations/iam-integration.js +413 -0
- package/src/services/organizations/index.js +172 -0
- package/src/services/organizations/models/index.js +13 -0
- package/src/services/organizations/models/invitation.js +48 -0
- package/src/services/organizations/models/organization.js +566 -0
- package/src/services/organizations/models/role.js +244 -0
- package/src/services/organizations/models/scp.js +131 -0
- package/src/services/organizations/server.js +736 -0
- package/src/services/organizations/simulator.js +593 -0
- package/src/services/organizations/store.js +235 -0
- package/src/services/organizations/vpc-integration.js +453 -0
- package/src/services/route53/index.js +67 -0
- package/src/services/route53/models/healthCheck.js +101 -0
- package/src/services/route53/models/hostedZone.js +37 -0
- package/src/services/route53/models/resourceRecord.js +106 -0
- package/src/services/route53/server.js +841 -0
- package/src/services/route53/simulator.js +350 -0
- package/src/services/s3/index.js +62 -0
- package/src/services/s3/presigned-url-generator.js +337 -0
- package/src/services/s3/server.js +231 -0
- package/src/services/s3/simulator.js +551 -4
- package/src/services/sns/index.js +31 -0
- package/src/services/sns/server.js +9 -0
- package/src/services/sqs/index.js +38 -0
- package/src/services/sqs/server.js +57 -4
- package/src/services/sqs/simulator.js +423 -33
- package/src/services/sts/simulator.js +209 -17
- package/src/services/vpc/README.md +459 -0
- package/src/services/vpc/ec2ResponseFormatter.js +431 -0
- package/src/services/vpc/index.js +90 -0
- package/src/services/vpc/models/internetGateway.js +71 -0
- package/src/services/vpc/models/routeTable.js +160 -0
- package/src/services/vpc/models/subnet.js +48 -0
- package/src/services/vpc/models/vpc.js +37 -0
- package/src/services/vpc/models/vpcEndpoint.js +100 -0
- package/src/services/vpc/models/vpcGateway.js +134 -0
- package/src/services/vpc/server.js +836 -0
- package/src/services/vpc/simulator.js +613 -0
- package/src/utils/policy-cache.js +215 -0
- 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 };
|