@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.
- package/README.md +662 -658
- package/package.json +10 -3
- 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/index.js +26 -0
- package/src/services/lambda/server.js +12 -1
- package/src/services/lambda/simulator.js +4 -0
- 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,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route53 Service
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const Route53Simulator = require('./simulator');
|
|
6
|
+
const Route53Server = require('./server');
|
|
7
|
+
const logger = require('../../utils/logger');
|
|
8
|
+
|
|
9
|
+
class Route53Service {
|
|
10
|
+
constructor(config = {}) {
|
|
11
|
+
this.name = 'route53';
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.simulator = null;
|
|
14
|
+
this.server = null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async initialize() {
|
|
18
|
+
this.simulator = new Route53Simulator(this.config);
|
|
19
|
+
await this.simulator.initialize();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
injectDependencies(server) {
|
|
23
|
+
// Para possíveis integrações futuras
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async start() {
|
|
27
|
+
try {
|
|
28
|
+
const port = this.config.port || 4024;
|
|
29
|
+
this.server = new Route53Server(port, this.config);
|
|
30
|
+
await this.server.initialize(this.simulator);
|
|
31
|
+
await this.server.start();
|
|
32
|
+
return true;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
logger.error(`Route53 Service error: ${error.message}`);
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async stop() {
|
|
40
|
+
if (this.server) {
|
|
41
|
+
await this.server.stop();
|
|
42
|
+
}
|
|
43
|
+
if (this.simulator) {
|
|
44
|
+
this.simulator.stopHealthCheckInterval();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getStatus() {
|
|
49
|
+
return {
|
|
50
|
+
name: 'route53',
|
|
51
|
+
port: this.config.port || 4024,
|
|
52
|
+
running: this.server ? true : false,
|
|
53
|
+
endpoint: `http://localhost:${this.config.port || 4024}`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async reset() {
|
|
58
|
+
if (this.simulator) {
|
|
59
|
+
this.simulator.hostedZones.clear();
|
|
60
|
+
this.simulator.resourceRecords.clear();
|
|
61
|
+
this.simulator.healthChecks.clear();
|
|
62
|
+
this.simulator.persistData();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = Route53Service;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route53 Health Check Model
|
|
3
|
+
* Supports HTTP, HTTPS, TCP, and calculated health checks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class HealthCheck {
|
|
7
|
+
constructor(config = {}) {
|
|
8
|
+
this.Id = this.generateHealthCheckId();
|
|
9
|
+
this.Type = config.Type || 'HTTP'; // HTTP, HTTPS, TCP, CALCULATED
|
|
10
|
+
this.Protocol = config.Protocol || 'HTTP';
|
|
11
|
+
this.IPAddress = config.IPAddress || '127.0.0.1';
|
|
12
|
+
this.Port = config.Port || 80;
|
|
13
|
+
this.ResourcePath = config.ResourcePath || '/';
|
|
14
|
+
this.FullyQualifiedDomainName = config.FullyQualifiedDomainName || 'localhost';
|
|
15
|
+
this.RequestInterval = config.RequestInterval || 30;
|
|
16
|
+
this.FailureThreshold = config.FailureThreshold || 3;
|
|
17
|
+
this.Enabled = config.Enabled !== false;
|
|
18
|
+
this.Status = 'Healthy'; // Healthy, Unhealthy
|
|
19
|
+
this.LastStatusChangeTime = new Date().toISOString();
|
|
20
|
+
this.CreatedDate = new Date().toISOString();
|
|
21
|
+
this.MeasureLatency = config.MeasureLatency || false;
|
|
22
|
+
this.HealthThreshold = config.HealthThreshold || 1;
|
|
23
|
+
this.ChildHealthChecks = config.ChildHealthChecks || [];
|
|
24
|
+
this.FailedChecks = 0;
|
|
25
|
+
this.LastCheckResult = {
|
|
26
|
+
status: 'Success',
|
|
27
|
+
timestamp: new Date().toISOString(),
|
|
28
|
+
latency: Math.random() * 100, // 0-100ms
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
generateHealthCheckId() {
|
|
33
|
+
const chars = '0123456789abcdef';
|
|
34
|
+
let id = '';
|
|
35
|
+
for (let i = 0; i < 32; i++) {
|
|
36
|
+
id += chars.charAt(Math.floor(Math.random() * 16));
|
|
37
|
+
}
|
|
38
|
+
return id;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Simulate health check
|
|
43
|
+
*/
|
|
44
|
+
check() {
|
|
45
|
+
if (!this.Enabled) {
|
|
46
|
+
this.Status = 'Disabled';
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Simulate health check with 95% success rate
|
|
51
|
+
const isHealthy = Math.random() > 0.05;
|
|
52
|
+
|
|
53
|
+
if (isHealthy) {
|
|
54
|
+
this.FailedChecks = 0;
|
|
55
|
+
if (this.Status !== 'Healthy') {
|
|
56
|
+
this.Status = 'Healthy';
|
|
57
|
+
this.LastStatusChangeTime = new Date().toISOString();
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
this.FailedChecks++;
|
|
61
|
+
if (this.FailedChecks >= this.FailureThreshold) {
|
|
62
|
+
this.Status = 'Unhealthy';
|
|
63
|
+
this.LastStatusChangeTime = new Date().toISOString();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this.LastCheckResult = {
|
|
68
|
+
status: isHealthy ? 'Success' : 'Failed',
|
|
69
|
+
timestamp: new Date().toISOString(),
|
|
70
|
+
latency: Math.random() * 100,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return isHealthy;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
toJSON() {
|
|
77
|
+
return {
|
|
78
|
+
Id: this.Id,
|
|
79
|
+
Type: this.Type,
|
|
80
|
+
HealthCheckConfig: {
|
|
81
|
+
Type: this.Type,
|
|
82
|
+
Protocol: this.Protocol,
|
|
83
|
+
IPAddress: this.IPAddress,
|
|
84
|
+
Port: this.Port,
|
|
85
|
+
ResourcePath: this.ResourcePath,
|
|
86
|
+
FullyQualifiedDomainName: this.FullyQualifiedDomainName,
|
|
87
|
+
RequestInterval: this.RequestInterval,
|
|
88
|
+
FailureThreshold: this.FailureThreshold,
|
|
89
|
+
MeasureLatency: this.MeasureLatency,
|
|
90
|
+
HealthThreshold: this.HealthThreshold,
|
|
91
|
+
},
|
|
92
|
+
HealthCheckObservations: {
|
|
93
|
+
Status: this.Status,
|
|
94
|
+
LastStatusChangeTime: this.LastStatusChangeTime,
|
|
95
|
+
LastCheckResult: this.LastCheckResult,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = HealthCheck;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route53 Hosted Zone Model
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
class HostedZone {
|
|
6
|
+
constructor(name, config = {}) {
|
|
7
|
+
this.Id = this.generateHostedZoneId();
|
|
8
|
+
this.Name = name;
|
|
9
|
+
this.Config = config || {};
|
|
10
|
+
this.ResourceRecordSetCount = 0;
|
|
11
|
+
this.CallerReference = config.CallerReference || new Date().getTime().toString();
|
|
12
|
+
this.HostedZoneConfig = {
|
|
13
|
+
Comment: config.Comment || '',
|
|
14
|
+
PrivateZone: config.PrivateZone || false,
|
|
15
|
+
};
|
|
16
|
+
this.CreatedDate = new Date().toISOString();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
generateHostedZoneId() {
|
|
20
|
+
const timestamp = Date.now();
|
|
21
|
+
const random = Math.random().toString(36).substring(2, 15);
|
|
22
|
+
return `/hostedzone/${random}${timestamp}`.substring(0, 30);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
toJSON() {
|
|
26
|
+
return {
|
|
27
|
+
Id: this.Id,
|
|
28
|
+
Name: this.Name,
|
|
29
|
+
CallerReference: this.CallerReference,
|
|
30
|
+
Config: this.HostedZoneConfig,
|
|
31
|
+
ResourceRecordSetCount: this.ResourceRecordSetCount,
|
|
32
|
+
CreatedDate: this.CreatedDate,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = HostedZone;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route53 Resource Record Model
|
|
3
|
+
* Supports weighted routing, health checks, and multiple record types
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class ResourceRecord {
|
|
7
|
+
constructor(name, type, values, config = {}) {
|
|
8
|
+
this.Name = name;
|
|
9
|
+
this.Type = type;
|
|
10
|
+
this.TTL = config.TTL || 300;
|
|
11
|
+
this.SetIdentifier = config.SetIdentifier || null;
|
|
12
|
+
this.Weight = config.Weight || null;
|
|
13
|
+
this.Region = config.Region || null;
|
|
14
|
+
this.GeoLocation = config.GeoLocation || null;
|
|
15
|
+
this.MultiValueAnswer = config.MultiValueAnswer || false;
|
|
16
|
+
this.HealthCheckId = config.HealthCheckId || null;
|
|
17
|
+
this.Failover = config.Failover || null; // PRIMARY or SECONDARY
|
|
18
|
+
this.ResourceRecords = Array.isArray(values) ? values.map(v => ({ Value: v })) : [{ Value: values }];
|
|
19
|
+
this.CreatedDate = new Date().toISOString();
|
|
20
|
+
this.LastModified = this.CreatedDate;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
toJSON() {
|
|
24
|
+
const record = {
|
|
25
|
+
Name: this.Name,
|
|
26
|
+
Type: this.Type,
|
|
27
|
+
TTL: this.TTL,
|
|
28
|
+
ResourceRecords: this.ResourceRecords,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
if (this.SetIdentifier) record.SetIdentifier = this.SetIdentifier;
|
|
32
|
+
if (this.Weight) record.Weight = this.Weight;
|
|
33
|
+
if (this.Region) record.Region = this.Region;
|
|
34
|
+
if (this.GeoLocation) record.GeoLocation = this.GeoLocation;
|
|
35
|
+
if (this.MultiValueAnswer) record.MultiValueAnswer = this.MultiValueAnswer;
|
|
36
|
+
if (this.HealthCheckId) record.HealthCheckId = this.HealthCheckId;
|
|
37
|
+
if (this.Failover) record.Failover = this.Failover;
|
|
38
|
+
|
|
39
|
+
return record;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Resolve records based on weights (weighted routing)
|
|
44
|
+
*/
|
|
45
|
+
static selectWeightedRecords(records) {
|
|
46
|
+
// Filter only weighted records
|
|
47
|
+
const weightedRecords = records.filter(r => r.Weight !== null && r.Weight !== undefined);
|
|
48
|
+
|
|
49
|
+
if (weightedRecords.length === 0) {
|
|
50
|
+
return records.filter(r => !r.SetIdentifier); // Return non-weighted records
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const totalWeight = weightedRecords.reduce((sum, r) => sum + r.Weight, 0);
|
|
54
|
+
const random = Math.random() * totalWeight;
|
|
55
|
+
|
|
56
|
+
let accumulated = 0;
|
|
57
|
+
for (const record of weightedRecords) {
|
|
58
|
+
accumulated += record.Weight;
|
|
59
|
+
if (random <= accumulated) {
|
|
60
|
+
return [record];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return [weightedRecords[0]]; // Fallback to first
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Resolve records based on geolocation
|
|
69
|
+
*/
|
|
70
|
+
static selectGeoLocationRecords(records, country = 'US') {
|
|
71
|
+
// Filter geo-located records
|
|
72
|
+
const geoRecords = records.filter(r => r.GeoLocation);
|
|
73
|
+
|
|
74
|
+
if (geoRecords.length === 0) {
|
|
75
|
+
return records.filter(r => !r.SetIdentifier);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const matched = geoRecords.find(r =>
|
|
79
|
+
r.GeoLocation.CountryCode === country ||
|
|
80
|
+
r.GeoLocation.CountryCode === '*'
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
return matched ? [matched] : [geoRecords[0]];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Resolve records based on failover policy
|
|
88
|
+
*/
|
|
89
|
+
static selectFailoverRecords(records, healthyIds = []) {
|
|
90
|
+
const primary = records.find(r => r.Failover === 'PRIMARY');
|
|
91
|
+
const secondary = records.find(r => r.Failover === 'SECONDARY');
|
|
92
|
+
|
|
93
|
+
if (!primary) return [records[0]];
|
|
94
|
+
|
|
95
|
+
// Check if primary is healthy
|
|
96
|
+
const primaryHealthy = !primary.HealthCheckId || healthyIds.includes(primary.HealthCheckId);
|
|
97
|
+
|
|
98
|
+
if (primaryHealthy) {
|
|
99
|
+
return [primary];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return secondary ? [secondary] : [primary];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = ResourceRecord;
|