@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,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ALB Service - Ponto de entrada
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const ALBServer = require('./server');
|
|
6
|
+
const ALBSimulator = require('./simulator');
|
|
7
|
+
|
|
8
|
+
class ALBService {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.config = config;
|
|
11
|
+
this.name = 'alb';
|
|
12
|
+
this.port = config.ports.alb || 4021;
|
|
13
|
+
this.server = null;
|
|
14
|
+
this.simulator = null;
|
|
15
|
+
this.isRunning = false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async initialize() {
|
|
19
|
+
const logger = require('../../utils/logger');
|
|
20
|
+
logger.debug(`Inicializando ALB Service na porta ${this.port}...`);
|
|
21
|
+
|
|
22
|
+
this.simulator = new ALBSimulator(this.config.alb || {});
|
|
23
|
+
await this.simulator.initialize();
|
|
24
|
+
|
|
25
|
+
this.server = new ALBServer(this.port, this.config);
|
|
26
|
+
this.server.simulator = this.simulator;
|
|
27
|
+
|
|
28
|
+
await this.server.initialize();
|
|
29
|
+
|
|
30
|
+
logger.debug('ALB Service inicializado');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
injectDependencies(server) {
|
|
34
|
+
// Aqui você pode injetar dependências de outros serviços se necessário
|
|
35
|
+
// Por exemplo, integração com EC2 para health checks
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async start() {
|
|
39
|
+
const logger = require('../../utils/logger');
|
|
40
|
+
|
|
41
|
+
if (this.isRunning) {
|
|
42
|
+
logger.warn('ALB Service já está em execução');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
await this.server.start();
|
|
48
|
+
this.isRunning = true;
|
|
49
|
+
logger.info('ALB Service iniciado com sucesso');
|
|
50
|
+
} catch (error) {
|
|
51
|
+
logger.error(`Erro ao iniciar ALB Service: ${error.message}`);
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async stop() {
|
|
57
|
+
const logger = require('../../utils/logger');
|
|
58
|
+
|
|
59
|
+
if (!this.isRunning) {
|
|
60
|
+
logger.warn('ALB Service não está em execução');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
await this.server.stop();
|
|
66
|
+
this.isRunning = false;
|
|
67
|
+
logger.info('ALB Service parado com sucesso');
|
|
68
|
+
} catch (error) {
|
|
69
|
+
logger.error(`Erro ao parar ALB Service: ${error.message}`);
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getSimulator() {
|
|
75
|
+
return this.simulator;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getStatus() {
|
|
79
|
+
const resources = this.simulator.getAllResources();
|
|
80
|
+
const totalTargets = resources.targetGroups.reduce(
|
|
81
|
+
(sum, tg) => sum + tg.Targets.length,
|
|
82
|
+
0
|
|
83
|
+
);
|
|
84
|
+
const healthyTargets = resources.targetGroups.reduce((sum, tg) => {
|
|
85
|
+
return sum + tg.Targets.filter(t => t.HealthState === 'healthy').length;
|
|
86
|
+
}, 0);
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
name: this.name,
|
|
90
|
+
running: this.isRunning,
|
|
91
|
+
port: this.port,
|
|
92
|
+
endpoint: `http://localhost:${this.port}`,
|
|
93
|
+
resources: {
|
|
94
|
+
loadBalancersCount: resources.loadBalancers.length,
|
|
95
|
+
targetGroupsCount: resources.targetGroups.length,
|
|
96
|
+
totalTargets,
|
|
97
|
+
healthyTargets,
|
|
98
|
+
unhealthyTargets: totalTargets - healthyTargets
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
module.exports = ALBService;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application Load Balancer Model
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { v4: uuidv4 } = require('uuid');
|
|
6
|
+
|
|
7
|
+
class LoadBalancer {
|
|
8
|
+
constructor(name, scheme = 'internet-facing', config = {}) {
|
|
9
|
+
this.LoadBalancerArn = `arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/${name}/${uuidv4().substring(0, 8)}`;
|
|
10
|
+
this.LoadBalancerName = name;
|
|
11
|
+
this.DNSName = `${name}-${Math.random().toString(36).substring(7)}.elb.us-east-1.amazonaws.com`;
|
|
12
|
+
this.Scheme = scheme; // internet-facing ou internal
|
|
13
|
+
this.Type = 'application';
|
|
14
|
+
this.State = 'active';
|
|
15
|
+
this.VpcId = config.VpcId || null;
|
|
16
|
+
this.SubnetIds = config.SubnetIds || [];
|
|
17
|
+
this.SecurityGroupIds = config.SecurityGroupIds || [];
|
|
18
|
+
this.IpAddressType = config.IpAddressType || 'ipv4';
|
|
19
|
+
this.Listeners = [];
|
|
20
|
+
this.TargetGroups = [];
|
|
21
|
+
this.Tags = config.Tags || [];
|
|
22
|
+
this.CreatedTime = new Date().toISOString();
|
|
23
|
+
this.Port = config.Port || 80;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
addListener(protocol = 'HTTP', port = 80, targetGroupArn = null) {
|
|
27
|
+
const listener = {
|
|
28
|
+
ListenerArn: `arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/${uuidv4().substring(0, 8)}`,
|
|
29
|
+
LoadBalancerArn: this.LoadBalancerArn,
|
|
30
|
+
Port: port,
|
|
31
|
+
Protocol: protocol,
|
|
32
|
+
Certificates: [],
|
|
33
|
+
DefaultActions: [
|
|
34
|
+
{
|
|
35
|
+
Type: 'forward',
|
|
36
|
+
TargetGroupArn: targetGroupArn
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
AlpnPolicy: []
|
|
40
|
+
};
|
|
41
|
+
this.Listeners.push(listener);
|
|
42
|
+
return listener;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
addTargetGroup(targetGroup) {
|
|
46
|
+
this.TargetGroups.push(targetGroup);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
removeTargetGroup(targetGroupArn) {
|
|
50
|
+
const index = this.TargetGroups.findIndex(tg => tg.TargetGroupArn === targetGroupArn);
|
|
51
|
+
if (index > -1) {
|
|
52
|
+
this.TargetGroups.splice(index, 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getHealthyTargets() {
|
|
57
|
+
const healthyTargets = [];
|
|
58
|
+
this.TargetGroups.forEach(tg => {
|
|
59
|
+
tg.Targets.forEach(target => {
|
|
60
|
+
if (target.HealthState === 'healthy') {
|
|
61
|
+
healthyTargets.push(target);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
return healthyTargets;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
toJSON() {
|
|
69
|
+
return {
|
|
70
|
+
LoadBalancerArn: this.LoadBalancerArn,
|
|
71
|
+
LoadBalancerName: this.LoadBalancerName,
|
|
72
|
+
DNSName: this.DNSName,
|
|
73
|
+
Scheme: this.Scheme,
|
|
74
|
+
Type: this.Type,
|
|
75
|
+
State: this.State,
|
|
76
|
+
VpcId: this.VpcId,
|
|
77
|
+
SubnetIds: this.SubnetIds,
|
|
78
|
+
SecurityGroupIds: this.SecurityGroupIds,
|
|
79
|
+
IpAddressType: this.IpAddressType,
|
|
80
|
+
CreatedTime: this.CreatedTime,
|
|
81
|
+
Port: this.Port,
|
|
82
|
+
ListenersCount: this.Listeners.length,
|
|
83
|
+
TargetGroupsCount: this.TargetGroups.length
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = LoadBalancer;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Target Group Model
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { v4: uuidv4 } = require('uuid');
|
|
6
|
+
|
|
7
|
+
class Target {
|
|
8
|
+
constructor(targetId, port = 80) {
|
|
9
|
+
this.TargetId = targetId; // instance-id ou IP
|
|
10
|
+
this.Port = port;
|
|
11
|
+
this.HealthState = 'healthy';
|
|
12
|
+
this.HealthReason = 'N/A';
|
|
13
|
+
this.Description = 'Target registered';
|
|
14
|
+
this.RegisteredAt = new Date().toISOString();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
setHealthy() {
|
|
18
|
+
this.HealthState = 'healthy';
|
|
19
|
+
this.HealthReason = 'N/A';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
setUnhealthy(reason = 'Health checks failed') {
|
|
23
|
+
this.HealthState = 'unhealthy';
|
|
24
|
+
this.HealthReason = reason;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
toJSON() {
|
|
28
|
+
return {
|
|
29
|
+
TargetId: this.TargetId,
|
|
30
|
+
Port: this.Port,
|
|
31
|
+
HealthState: this.HealthState,
|
|
32
|
+
HealthReason: this.HealthReason,
|
|
33
|
+
Description: this.Description,
|
|
34
|
+
RegisteredAt: this.RegisteredAt
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class TargetGroup {
|
|
40
|
+
constructor(name, protocol = 'HTTP', port = 80, vpcId = null, config = {}) {
|
|
41
|
+
this.TargetGroupArn = `arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/${name}/${uuidv4().substring(0, 8)}`;
|
|
42
|
+
this.TargetGroupName = name;
|
|
43
|
+
this.Protocol = protocol;
|
|
44
|
+
this.Port = port;
|
|
45
|
+
this.VpcId = vpcId;
|
|
46
|
+
this.TargetType = config.TargetType || 'instance'; // instance ou ip
|
|
47
|
+
this.Targets = [];
|
|
48
|
+
this.HealthCheckEnabled = config.HealthCheckEnabled !== false;
|
|
49
|
+
this.HealthCheckProtocol = config.HealthCheckProtocol || 'HTTP';
|
|
50
|
+
this.HealthCheckPath = config.HealthCheckPath || '/';
|
|
51
|
+
this.HealthCheckPort = config.HealthCheckPort || String(port);
|
|
52
|
+
this.HealthCheckIntervalSeconds = config.HealthCheckIntervalSeconds || 30;
|
|
53
|
+
this.HealthCheckTimeoutSeconds = config.HealthCheckTimeoutSeconds || 5;
|
|
54
|
+
this.HealthyThresholdCount = config.HealthyThresholdCount || 2;
|
|
55
|
+
this.UnhealthyThresholdCount = config.UnhealthyThresholdCount || 2;
|
|
56
|
+
this.Matcher = config.Matcher || { HttpCode: '200' };
|
|
57
|
+
this.Tags = config.Tags || [];
|
|
58
|
+
this.CreatedTime = new Date().toISOString();
|
|
59
|
+
this.LoadBalancingAlgorithmType = 'round_robin';
|
|
60
|
+
this.TargetCount = 0;
|
|
61
|
+
this.HealthyCount = 0;
|
|
62
|
+
this.UnhealthyCount = 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
registerTarget(targetId, port = null) {
|
|
66
|
+
const targetPort = port || this.Port;
|
|
67
|
+
|
|
68
|
+
// Verificar se já existe
|
|
69
|
+
if (this.Targets.some(t => t.TargetId === targetId && t.Port === targetPort)) {
|
|
70
|
+
throw new Error(`Target ${targetId}:${targetPort} already registered`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const target = new Target(targetId, targetPort);
|
|
74
|
+
this.Targets.push(target);
|
|
75
|
+
this.updateCounts();
|
|
76
|
+
return target;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
deregisterTarget(targetId, port = null) {
|
|
80
|
+
const targetPort = port || this.Port;
|
|
81
|
+
const index = this.Targets.findIndex(t => t.TargetId === targetId && t.Port === targetPort);
|
|
82
|
+
|
|
83
|
+
if (index === -1) {
|
|
84
|
+
throw new Error(`Target ${targetId}:${targetPort} not found`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const target = this.Targets.splice(index, 1)[0];
|
|
88
|
+
this.updateCounts();
|
|
89
|
+
return target;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getNextTarget() {
|
|
93
|
+
const healthyTargets = this.Targets.filter(t => t.HealthState === 'healthy');
|
|
94
|
+
if (healthyTargets.length === 0) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
// Round robin simples
|
|
98
|
+
return healthyTargets[Math.floor(Math.random() * healthyTargets.length)];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
updateCounts() {
|
|
102
|
+
this.TargetCount = this.Targets.length;
|
|
103
|
+
this.HealthyCount = this.Targets.filter(t => t.HealthState === 'healthy').length;
|
|
104
|
+
this.UnhealthyCount = this.Targets.filter(t => t.HealthState === 'unhealthy').length;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
toJSON() {
|
|
108
|
+
return {
|
|
109
|
+
TargetGroupArn: this.TargetGroupArn,
|
|
110
|
+
TargetGroupName: this.TargetGroupName,
|
|
111
|
+
Protocol: this.Protocol,
|
|
112
|
+
Port: this.Port,
|
|
113
|
+
VpcId: this.VpcId,
|
|
114
|
+
TargetType: this.TargetType,
|
|
115
|
+
TargetCount: this.TargetCount,
|
|
116
|
+
HealthyCount: this.HealthyCount,
|
|
117
|
+
UnhealthyCount: this.UnhealthyCount,
|
|
118
|
+
HealthCheckEnabled: this.HealthCheckEnabled,
|
|
119
|
+
HealthCheckProtocol: this.HealthCheckProtocol,
|
|
120
|
+
HealthCheckPath: this.HealthCheckPath,
|
|
121
|
+
CreatedTime: this.CreatedTime,
|
|
122
|
+
LoadBalancingAlgorithmType: this.LoadBalancingAlgorithmType,
|
|
123
|
+
Targets: this.Targets.map(t => t.toJSON())
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
module.exports = { TargetGroup, Target };
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ALB Server - API REST para Application Load Balancer
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const express = require('express');
|
|
6
|
+
const logger = require('../../utils/logger');
|
|
7
|
+
|
|
8
|
+
class ALBServer {
|
|
9
|
+
constructor(port, config) {
|
|
10
|
+
this.port = port;
|
|
11
|
+
this.config = config;
|
|
12
|
+
this.app = express();
|
|
13
|
+
this.simulator = null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
setupMiddlewares() {
|
|
17
|
+
this.app.use(express.json());
|
|
18
|
+
this.app.use((req, res, next) => {
|
|
19
|
+
logger.debug(`ALB Request: ${req.method} ${req.path}`);
|
|
20
|
+
next();
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async initialize() {
|
|
25
|
+
logger.debug(`Inicializando ALB Server na porta ${this.port}`);
|
|
26
|
+
this.setupMiddlewares();
|
|
27
|
+
this.setupRoutes();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setupRoutes() {
|
|
31
|
+
// Create Load Balancer
|
|
32
|
+
this.app.post('/__admin/alb/load-balancers/create', (req, res) => {
|
|
33
|
+
try {
|
|
34
|
+
const { Name, Scheme = 'internet-facing', ...config } = req.body;
|
|
35
|
+
if (!Name) return res.status(400).json({ error: 'Name is required' });
|
|
36
|
+
|
|
37
|
+
const alb = this.simulator.createLoadBalancer(Name, Scheme, config);
|
|
38
|
+
res.json({ LoadBalancer: alb.toJSON() });
|
|
39
|
+
} catch (error) {
|
|
40
|
+
res.status(400).json({ error: error.message });
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Describe Load Balancers
|
|
45
|
+
this.app.get('/__admin/alb/load-balancers', (req, res) => {
|
|
46
|
+
try {
|
|
47
|
+
const albs = this.simulator.describeLoadBalancers();
|
|
48
|
+
res.json({ LoadBalancers: albs.map(a => a.toJSON()) });
|
|
49
|
+
} catch (error) {
|
|
50
|
+
res.status(400).json({ error: error.message });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Get Load Balancer
|
|
55
|
+
this.app.get('/__admin/alb/load-balancers/:albArn', (req, res) => {
|
|
56
|
+
try {
|
|
57
|
+
const alb = this.simulator.getLoadBalancer(req.params.albArn);
|
|
58
|
+
res.json({ LoadBalancer: alb.toJSON() });
|
|
59
|
+
} catch (error) {
|
|
60
|
+
res.status(404).json({ error: error.message });
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Delete Load Balancer
|
|
65
|
+
this.app.delete('/__admin/alb/load-balancers/:albArn', (req, res) => {
|
|
66
|
+
try {
|
|
67
|
+
this.simulator.deleteLoadBalancer(req.params.albArn);
|
|
68
|
+
res.json({ success: true });
|
|
69
|
+
} catch (error) {
|
|
70
|
+
res.status(400).json({ error: error.message });
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Create Target Group
|
|
75
|
+
this.app.post('/__admin/alb/target-groups/create', (req, res) => {
|
|
76
|
+
try {
|
|
77
|
+
const { Name, Protocol = 'HTTP', Port = 80, VpcId = null, ...config } = req.body;
|
|
78
|
+
if (!Name) return res.status(400).json({ error: 'Name is required' });
|
|
79
|
+
|
|
80
|
+
const tg = this.simulator.createTargetGroup(Name, Protocol, Port, VpcId, config);
|
|
81
|
+
res.json({ TargetGroup: tg.toJSON() });
|
|
82
|
+
} catch (error) {
|
|
83
|
+
res.status(400).json({ error: error.message });
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Describe Target Groups
|
|
88
|
+
this.app.get('/__admin/alb/target-groups', (req, res) => {
|
|
89
|
+
try {
|
|
90
|
+
const tgs = this.simulator.describeTargetGroups();
|
|
91
|
+
res.json({ TargetGroups: tgs.map(t => t.toJSON()) });
|
|
92
|
+
} catch (error) {
|
|
93
|
+
res.status(400).json({ error: error.message });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Register Target
|
|
98
|
+
this.app.post('/__admin/alb/target-groups/:tgArn/register-target', (req, res) => {
|
|
99
|
+
try {
|
|
100
|
+
const { TargetId, Port } = req.body;
|
|
101
|
+
if (!TargetId) return res.status(400).json({ error: 'TargetId is required' });
|
|
102
|
+
|
|
103
|
+
const target = this.simulator.registerTarget(req.params.tgArn, TargetId, Port);
|
|
104
|
+
res.json({ Target: target.toJSON() });
|
|
105
|
+
} catch (error) {
|
|
106
|
+
res.status(400).json({ error: error.message });
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Describe Target Health
|
|
111
|
+
this.app.get('/__admin/alb/target-groups/:tgArn/health', (req, res) => {
|
|
112
|
+
try {
|
|
113
|
+
const health = this.simulator.describeTargetHealth(req.params.tgArn);
|
|
114
|
+
res.json(health);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
res.status(400).json({ error: error.message });
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Health Check
|
|
121
|
+
this.app.get('/__admin/alb/health', (req, res) => {
|
|
122
|
+
res.json({ status: 'ok', service: 'alb' });
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Get All Resources
|
|
126
|
+
this.app.get('/__admin/alb/resources', (req, res) => {
|
|
127
|
+
try {
|
|
128
|
+
const resources = this.simulator.getAllResources();
|
|
129
|
+
res.json({
|
|
130
|
+
loadBalancers: resources.loadBalancers.map(a => a.toJSON()),
|
|
131
|
+
targetGroups: resources.targetGroups.map(t => t.toJSON())
|
|
132
|
+
});
|
|
133
|
+
} catch (error) {
|
|
134
|
+
res.status(400).json({ error: error.message });
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async start() {
|
|
140
|
+
return new Promise((resolve) => {
|
|
141
|
+
this.server = this.app.listen(this.port, () => {
|
|
142
|
+
logger.info(`ALB Server running on http://localhost:${this.port}`);
|
|
143
|
+
resolve();
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async stop() {
|
|
149
|
+
if (this.server) {
|
|
150
|
+
return new Promise((resolve) => {
|
|
151
|
+
this.server.close(() => {
|
|
152
|
+
logger.info('ALB Server stopped');
|
|
153
|
+
resolve();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
module.exports = ALBServer;
|