@friggframework/devtools 2.0.0-next.45 → 2.0.0-next.46
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/infrastructure/ARCHITECTURE.md +487 -0
- package/infrastructure/HEALTH.md +468 -0
- package/infrastructure/README.md +51 -0
- package/infrastructure/__tests__/postgres-config.test.js +914 -0
- package/infrastructure/__tests__/template-generation.test.js +687 -0
- package/infrastructure/create-frigg-infrastructure.js +1 -1
- package/infrastructure/docs/POSTGRES-CONFIGURATION.md +630 -0
- package/infrastructure/{DEPLOYMENT-INSTRUCTIONS.md → docs/deployment-instructions.md} +3 -3
- package/infrastructure/{IAM-POLICY-TEMPLATES.md → docs/iam-policy-templates.md} +9 -10
- package/infrastructure/domains/database/aurora-builder.js +809 -0
- package/infrastructure/domains/database/aurora-builder.test.js +950 -0
- package/infrastructure/domains/database/aurora-discovery.js +87 -0
- package/infrastructure/domains/database/aurora-discovery.test.js +188 -0
- package/infrastructure/domains/database/aurora-resolver.js +210 -0
- package/infrastructure/domains/database/aurora-resolver.test.js +347 -0
- package/infrastructure/domains/database/migration-builder.js +633 -0
- package/infrastructure/domains/database/migration-builder.test.js +294 -0
- package/infrastructure/domains/database/migration-resolver.js +163 -0
- package/infrastructure/domains/database/migration-resolver.test.js +337 -0
- package/infrastructure/domains/health/application/ports/IPropertyReconciler.js +164 -0
- package/infrastructure/domains/health/application/ports/IResourceDetector.js +129 -0
- package/infrastructure/domains/health/application/ports/IResourceImporter.js +142 -0
- package/infrastructure/domains/health/application/ports/IStackRepository.js +131 -0
- package/infrastructure/domains/health/application/ports/index.js +26 -0
- package/infrastructure/domains/health/application/use-cases/__tests__/execute-resource-import-use-case.test.js +679 -0
- package/infrastructure/domains/health/application/use-cases/__tests__/mismatch-analyzer-method-name.test.js +167 -0
- package/infrastructure/domains/health/application/use-cases/__tests__/repair-via-import-use-case.test.js +1130 -0
- package/infrastructure/domains/health/application/use-cases/execute-resource-import-use-case.js +221 -0
- package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.js +152 -0
- package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.test.js +343 -0
- package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.js +535 -0
- package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.test.js +376 -0
- package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.js +213 -0
- package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.test.js +441 -0
- package/infrastructure/domains/health/docs/ACME-DEV-DRIFT-ANALYSIS.md +267 -0
- package/infrastructure/domains/health/docs/BUILD-VS-DEPLOYED-TEMPLATE-ANALYSIS.md +324 -0
- package/infrastructure/domains/health/docs/ORPHAN-DETECTION-ANALYSIS.md +386 -0
- package/infrastructure/domains/health/docs/SPEC-CLEANUP-COMMAND.md +1419 -0
- package/infrastructure/domains/health/docs/TDD-IMPLEMENTATION-SUMMARY.md +391 -0
- package/infrastructure/domains/health/docs/TEMPLATE-COMPARISON-IMPLEMENTATION.md +551 -0
- package/infrastructure/domains/health/domain/entities/issue.js +299 -0
- package/infrastructure/domains/health/domain/entities/issue.test.js +528 -0
- package/infrastructure/domains/health/domain/entities/property-mismatch.js +108 -0
- package/infrastructure/domains/health/domain/entities/property-mismatch.test.js +275 -0
- package/infrastructure/domains/health/domain/entities/resource.js +159 -0
- package/infrastructure/domains/health/domain/entities/resource.test.js +432 -0
- package/infrastructure/domains/health/domain/entities/stack-health-report.js +306 -0
- package/infrastructure/domains/health/domain/entities/stack-health-report.test.js +601 -0
- package/infrastructure/domains/health/domain/services/__tests__/health-score-percentage-based.test.js +380 -0
- package/infrastructure/domains/health/domain/services/__tests__/import-progress-monitor.test.js +971 -0
- package/infrastructure/domains/health/domain/services/__tests__/import-template-generator.test.js +1150 -0
- package/infrastructure/domains/health/domain/services/__tests__/logical-id-mapper.test.js +672 -0
- package/infrastructure/domains/health/domain/services/__tests__/template-parser.test.js +496 -0
- package/infrastructure/domains/health/domain/services/__tests__/update-progress-monitor.test.js +419 -0
- package/infrastructure/domains/health/domain/services/health-score-calculator.js +248 -0
- package/infrastructure/domains/health/domain/services/health-score-calculator.test.js +504 -0
- package/infrastructure/domains/health/domain/services/import-progress-monitor.js +195 -0
- package/infrastructure/domains/health/domain/services/import-template-generator.js +435 -0
- package/infrastructure/domains/health/domain/services/logical-id-mapper.js +345 -0
- package/infrastructure/domains/health/domain/services/mismatch-analyzer.js +234 -0
- package/infrastructure/domains/health/domain/services/mismatch-analyzer.test.js +431 -0
- package/infrastructure/domains/health/domain/services/property-mutability-config.js +382 -0
- package/infrastructure/domains/health/domain/services/template-parser.js +245 -0
- package/infrastructure/domains/health/domain/services/update-progress-monitor.js +192 -0
- package/infrastructure/domains/health/domain/value-objects/health-score.js +138 -0
- package/infrastructure/domains/health/domain/value-objects/health-score.test.js +267 -0
- package/infrastructure/domains/health/domain/value-objects/property-mutability.js +161 -0
- package/infrastructure/domains/health/domain/value-objects/property-mutability.test.js +198 -0
- package/infrastructure/domains/health/domain/value-objects/resource-state.js +167 -0
- package/infrastructure/domains/health/domain/value-objects/resource-state.test.js +196 -0
- package/infrastructure/domains/health/domain/value-objects/stack-identifier.js +192 -0
- package/infrastructure/domains/health/domain/value-objects/stack-identifier.test.js +262 -0
- package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-cfn-tagged.test.js +312 -0
- package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-multi-stack.test.js +367 -0
- package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-relationship-analysis.test.js +432 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.js +784 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.test.js +1133 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.js +565 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.test.js +554 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.js +318 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.test.js +398 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.js +777 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.test.js +580 -0
- package/infrastructure/domains/integration/integration-builder.js +397 -0
- package/infrastructure/domains/integration/integration-builder.test.js +593 -0
- package/infrastructure/domains/integration/integration-resolver.js +170 -0
- package/infrastructure/domains/integration/integration-resolver.test.js +369 -0
- package/infrastructure/domains/integration/websocket-builder.js +69 -0
- package/infrastructure/domains/integration/websocket-builder.test.js +195 -0
- package/infrastructure/domains/networking/vpc-builder.js +1829 -0
- package/infrastructure/domains/networking/vpc-builder.test.js +1262 -0
- package/infrastructure/domains/networking/vpc-discovery.js +177 -0
- package/infrastructure/domains/networking/vpc-discovery.test.js +350 -0
- package/infrastructure/domains/networking/vpc-resolver.js +324 -0
- package/infrastructure/domains/networking/vpc-resolver.test.js +501 -0
- package/infrastructure/domains/parameters/ssm-builder.js +79 -0
- package/infrastructure/domains/parameters/ssm-builder.test.js +189 -0
- package/infrastructure/domains/parameters/ssm-discovery.js +84 -0
- package/infrastructure/domains/parameters/ssm-discovery.test.js +210 -0
- package/infrastructure/{iam-generator.js → domains/security/iam-generator.js} +2 -2
- package/infrastructure/domains/security/kms-builder.js +366 -0
- package/infrastructure/domains/security/kms-builder.test.js +374 -0
- package/infrastructure/domains/security/kms-discovery.js +80 -0
- package/infrastructure/domains/security/kms-discovery.test.js +177 -0
- package/infrastructure/domains/security/kms-resolver.js +96 -0
- package/infrastructure/domains/security/kms-resolver.test.js +216 -0
- package/infrastructure/domains/shared/base-builder.js +112 -0
- package/infrastructure/domains/shared/base-resolver.js +186 -0
- package/infrastructure/domains/shared/base-resolver.test.js +305 -0
- package/infrastructure/domains/shared/builder-orchestrator.js +212 -0
- package/infrastructure/domains/shared/builder-orchestrator.test.js +213 -0
- package/infrastructure/domains/shared/cloudformation-discovery-v2.js +334 -0
- package/infrastructure/domains/shared/cloudformation-discovery.js +375 -0
- package/infrastructure/domains/shared/cloudformation-discovery.test.js +590 -0
- package/infrastructure/domains/shared/environment-builder.js +119 -0
- package/infrastructure/domains/shared/environment-builder.test.js +247 -0
- package/infrastructure/domains/shared/providers/aws-provider-adapter.js +544 -0
- package/infrastructure/domains/shared/providers/aws-provider-adapter.test.js +377 -0
- package/infrastructure/domains/shared/providers/azure-provider-adapter.stub.js +93 -0
- package/infrastructure/domains/shared/providers/cloud-provider-adapter.js +136 -0
- package/infrastructure/domains/shared/providers/gcp-provider-adapter.stub.js +82 -0
- package/infrastructure/domains/shared/providers/provider-factory.js +108 -0
- package/infrastructure/domains/shared/providers/provider-factory.test.js +170 -0
- package/infrastructure/domains/shared/resource-discovery.js +192 -0
- package/infrastructure/domains/shared/resource-discovery.test.js +552 -0
- package/infrastructure/domains/shared/types/app-definition.js +205 -0
- package/infrastructure/domains/shared/types/discovery-result.js +106 -0
- package/infrastructure/domains/shared/types/discovery-result.test.js +258 -0
- package/infrastructure/domains/shared/types/index.js +46 -0
- package/infrastructure/domains/shared/types/resource-ownership.js +108 -0
- package/infrastructure/domains/shared/types/resource-ownership.test.js +101 -0
- package/infrastructure/domains/shared/utilities/base-definition-factory.js +380 -0
- package/infrastructure/domains/shared/utilities/base-definition-factory.js.bak +338 -0
- package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +248 -0
- package/infrastructure/domains/shared/utilities/handler-path-resolver.js +134 -0
- package/infrastructure/domains/shared/utilities/handler-path-resolver.test.js +268 -0
- package/infrastructure/domains/shared/utilities/prisma-layer-manager.js +55 -0
- package/infrastructure/domains/shared/utilities/prisma-layer-manager.test.js +138 -0
- package/infrastructure/{env-validator.js → domains/shared/validation/env-validator.js} +2 -1
- package/infrastructure/domains/shared/validation/env-validator.test.js +173 -0
- package/infrastructure/esbuild.config.js +53 -0
- package/infrastructure/infrastructure-composer.js +87 -0
- package/infrastructure/{serverless-template.test.js → infrastructure-composer.test.js} +115 -24
- package/infrastructure/scripts/build-prisma-layer.js +553 -0
- package/infrastructure/scripts/build-prisma-layer.test.js +102 -0
- package/infrastructure/{build-time-discovery.js → scripts/build-time-discovery.js} +80 -48
- package/infrastructure/{build-time-discovery.test.js → scripts/build-time-discovery.test.js} +5 -4
- package/layers/prisma/nodejs/package.json +8 -0
- package/management-ui/server/utils/cliIntegration.js +1 -1
- package/management-ui/server/utils/environment/awsParameterStore.js +29 -18
- package/package.json +11 -11
- package/frigg-cli/.eslintrc.js +0 -141
- package/frigg-cli/__tests__/unit/commands/build.test.js +0 -251
- package/frigg-cli/__tests__/unit/commands/db-setup.test.js +0 -548
- package/frigg-cli/__tests__/unit/commands/install.test.js +0 -400
- package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -346
- package/frigg-cli/__tests__/unit/utils/database-validator.test.js +0 -366
- package/frigg-cli/__tests__/unit/utils/error-messages.test.js +0 -304
- package/frigg-cli/__tests__/unit/utils/prisma-runner.test.js +0 -486
- package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
- package/frigg-cli/__tests__/utils/prisma-mock.js +0 -194
- package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
- package/frigg-cli/__tests__/utils/test-setup.js +0 -287
- package/frigg-cli/build-command/index.js +0 -65
- package/frigg-cli/db-setup-command/index.js +0 -193
- package/frigg-cli/deploy-command/index.js +0 -175
- package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -301
- package/frigg-cli/generate-command/azure-generator.js +0 -43
- package/frigg-cli/generate-command/gcp-generator.js +0 -47
- package/frigg-cli/generate-command/index.js +0 -332
- package/frigg-cli/generate-command/terraform-generator.js +0 -555
- package/frigg-cli/generate-iam-command.js +0 -118
- package/frigg-cli/index.js +0 -75
- package/frigg-cli/index.test.js +0 -158
- package/frigg-cli/init-command/backend-first-handler.js +0 -756
- package/frigg-cli/init-command/index.js +0 -93
- package/frigg-cli/init-command/template-handler.js +0 -143
- package/frigg-cli/install-command/backend-js.js +0 -33
- package/frigg-cli/install-command/commit-changes.js +0 -16
- package/frigg-cli/install-command/environment-variables.js +0 -127
- package/frigg-cli/install-command/environment-variables.test.js +0 -136
- package/frigg-cli/install-command/index.js +0 -54
- package/frigg-cli/install-command/install-package.js +0 -13
- package/frigg-cli/install-command/integration-file.js +0 -30
- package/frigg-cli/install-command/logger.js +0 -12
- package/frigg-cli/install-command/template.js +0 -90
- package/frigg-cli/install-command/validate-package.js +0 -75
- package/frigg-cli/jest.config.js +0 -124
- package/frigg-cli/package.json +0 -54
- package/frigg-cli/start-command/index.js +0 -149
- package/frigg-cli/start-command/start-command.test.js +0 -297
- package/frigg-cli/test/init-command.test.js +0 -180
- package/frigg-cli/test/npm-registry.test.js +0 -319
- package/frigg-cli/ui-command/index.js +0 -154
- package/frigg-cli/utils/app-resolver.js +0 -319
- package/frigg-cli/utils/backend-path.js +0 -25
- package/frigg-cli/utils/database-validator.js +0 -161
- package/frigg-cli/utils/error-messages.js +0 -257
- package/frigg-cli/utils/npm-registry.js +0 -167
- package/frigg-cli/utils/prisma-runner.js +0 -280
- package/frigg-cli/utils/process-manager.js +0 -199
- package/frigg-cli/utils/repo-detection.js +0 -405
- package/infrastructure/aws-discovery.js +0 -1176
- package/infrastructure/aws-discovery.test.js +0 -1220
- package/infrastructure/serverless-template.js +0 -2094
- /package/infrastructure/{WEBSOCKET-CONFIGURATION.md → docs/WEBSOCKET-CONFIGURATION.md} +0 -0
- /package/infrastructure/{GENERATE-IAM-DOCS.md → docs/generate-iam-command.md} +0 -0
- /package/infrastructure/{iam-generator.test.js → domains/security/iam-generator.test.js} +0 -0
- /package/infrastructure/{frigg-deployment-iam-stack.yaml → domains/security/templates/frigg-deployment-iam-stack.yaml} +0 -0
- /package/infrastructure/{iam-policy-basic.json → domains/security/templates/iam-policy-basic.json} +0 -0
- /package/infrastructure/{iam-policy-full.json → domains/security/templates/iam-policy-full.json} +0 -0
- /package/infrastructure/{run-discovery.js → scripts/run-discovery.js} +0 -0
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS Provider Adapter
|
|
3
|
+
*
|
|
4
|
+
* Adapter - Hexagonal Architecture
|
|
5
|
+
*
|
|
6
|
+
* Implements CloudProviderAdapter interface for Amazon Web Services.
|
|
7
|
+
* Handles AWS-specific resource discovery using AWS SDK v3.
|
|
8
|
+
*
|
|
9
|
+
* This adapter lazy-loads AWS SDK clients to minimize cold start time
|
|
10
|
+
* and memory usage when not all discovery features are needed.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const { CloudProviderAdapter } = require('./cloud-provider-adapter');
|
|
14
|
+
|
|
15
|
+
// Lazy-loaded AWS SDK clients
|
|
16
|
+
let EC2Client, DescribeVpcsCommand, DescribeSubnetsCommand, DescribeSecurityGroupsCommand,
|
|
17
|
+
DescribeRouteTablesCommand, DescribeNatGatewaysCommand, DescribeInternetGatewaysCommand,
|
|
18
|
+
DescribeVpcEndpointsCommand;
|
|
19
|
+
let KMSClient, ListKeysCommand, DescribeKeyCommand, ListAliasesCommand;
|
|
20
|
+
let RDSClient, DescribeDBClustersCommand, DescribeDBInstancesCommand;
|
|
21
|
+
let SSMClient, GetParameterCommand, GetParametersByPathCommand;
|
|
22
|
+
let SecretsManagerClient, ListSecretsCommand, GetSecretValueCommand;
|
|
23
|
+
let CloudFormationClient, DescribeStacksCommand, ListStackResourcesCommand;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Lazy load EC2 SDK
|
|
27
|
+
*/
|
|
28
|
+
function loadEC2() {
|
|
29
|
+
if (!EC2Client) {
|
|
30
|
+
const ec2Module = require('@aws-sdk/client-ec2');
|
|
31
|
+
EC2Client = ec2Module.EC2Client;
|
|
32
|
+
DescribeVpcsCommand = ec2Module.DescribeVpcsCommand;
|
|
33
|
+
DescribeSubnetsCommand = ec2Module.DescribeSubnetsCommand;
|
|
34
|
+
DescribeSecurityGroupsCommand = ec2Module.DescribeSecurityGroupsCommand;
|
|
35
|
+
DescribeRouteTablesCommand = ec2Module.DescribeRouteTablesCommand;
|
|
36
|
+
DescribeNatGatewaysCommand = ec2Module.DescribeNatGatewaysCommand;
|
|
37
|
+
DescribeInternetGatewaysCommand = ec2Module.DescribeInternetGatewaysCommand;
|
|
38
|
+
DescribeVpcEndpointsCommand = ec2Module.DescribeVpcEndpointsCommand;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Lazy load KMS SDK
|
|
44
|
+
*/
|
|
45
|
+
function loadKMS() {
|
|
46
|
+
if (!KMSClient) {
|
|
47
|
+
const kmsModule = require('@aws-sdk/client-kms');
|
|
48
|
+
KMSClient = kmsModule.KMSClient;
|
|
49
|
+
ListKeysCommand = kmsModule.ListKeysCommand;
|
|
50
|
+
DescribeKeyCommand = kmsModule.DescribeKeyCommand;
|
|
51
|
+
ListAliasesCommand = kmsModule.ListAliasesCommand;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Lazy load RDS SDK
|
|
57
|
+
*/
|
|
58
|
+
function loadRDS() {
|
|
59
|
+
if (!RDSClient) {
|
|
60
|
+
const rdsModule = require('@aws-sdk/client-rds');
|
|
61
|
+
RDSClient = rdsModule.RDSClient;
|
|
62
|
+
DescribeDBClustersCommand = rdsModule.DescribeDBClustersCommand;
|
|
63
|
+
DescribeDBInstancesCommand = rdsModule.DescribeDBInstancesCommand;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Lazy load SSM SDK
|
|
69
|
+
*/
|
|
70
|
+
function loadSSM() {
|
|
71
|
+
if (!SSMClient) {
|
|
72
|
+
const ssmModule = require('@aws-sdk/client-ssm');
|
|
73
|
+
SSMClient = ssmModule.SSMClient;
|
|
74
|
+
GetParameterCommand = ssmModule.GetParameterCommand;
|
|
75
|
+
GetParametersByPathCommand = ssmModule.GetParametersByPathCommand;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Lazy load Secrets Manager SDK
|
|
81
|
+
*/
|
|
82
|
+
function loadSecretsManager() {
|
|
83
|
+
if (!SecretsManagerClient) {
|
|
84
|
+
const smModule = require('@aws-sdk/client-secrets-manager');
|
|
85
|
+
SecretsManagerClient = smModule.SecretsManagerClient;
|
|
86
|
+
ListSecretsCommand = smModule.ListSecretsCommand;
|
|
87
|
+
GetSecretValueCommand = smModule.GetSecretValueCommand;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Lazy load CloudFormation SDK
|
|
93
|
+
*/
|
|
94
|
+
function loadCloudFormation() {
|
|
95
|
+
if (!CloudFormationClient) {
|
|
96
|
+
const cfModule = require('@aws-sdk/client-cloudformation');
|
|
97
|
+
CloudFormationClient = cfModule.CloudFormationClient;
|
|
98
|
+
DescribeStacksCommand = cfModule.DescribeStacksCommand;
|
|
99
|
+
ListStackResourcesCommand = cfModule.ListStackResourcesCommand;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
class AWSProviderAdapter extends CloudProviderAdapter {
|
|
104
|
+
constructor(region, credentials = {}) {
|
|
105
|
+
super();
|
|
106
|
+
this.region = region || process.env.AWS_REGION || 'us-east-1';
|
|
107
|
+
this.credentials = credentials;
|
|
108
|
+
|
|
109
|
+
// Initialize clients as null - will be lazy loaded
|
|
110
|
+
this.ec2 = null;
|
|
111
|
+
this.kms = null;
|
|
112
|
+
this.rds = null;
|
|
113
|
+
this.ssm = null;
|
|
114
|
+
this.secretsManager = null;
|
|
115
|
+
this.cloudformation = null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Get EC2 client (lazy loaded)
|
|
120
|
+
*/
|
|
121
|
+
getEC2Client() {
|
|
122
|
+
if (!this.ec2) {
|
|
123
|
+
loadEC2();
|
|
124
|
+
this.ec2 = new EC2Client({
|
|
125
|
+
region: this.region,
|
|
126
|
+
...this.credentials,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return this.ec2;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get KMS client (lazy loaded)
|
|
134
|
+
*/
|
|
135
|
+
getKMSClient() {
|
|
136
|
+
if (!this.kms) {
|
|
137
|
+
loadKMS();
|
|
138
|
+
this.kms = new KMSClient({
|
|
139
|
+
region: this.region,
|
|
140
|
+
...this.credentials,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return this.kms;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Get RDS client (lazy loaded)
|
|
148
|
+
*/
|
|
149
|
+
getRDSClient() {
|
|
150
|
+
if (!this.rds) {
|
|
151
|
+
loadRDS();
|
|
152
|
+
this.rds = new RDSClient({
|
|
153
|
+
region: this.region,
|
|
154
|
+
...this.credentials,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return this.rds;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Get SSM client (lazy loaded)
|
|
162
|
+
*/
|
|
163
|
+
getSSMClient() {
|
|
164
|
+
if (!this.ssm) {
|
|
165
|
+
loadSSM();
|
|
166
|
+
this.ssm = new SSMClient({
|
|
167
|
+
region: this.region,
|
|
168
|
+
...this.credentials,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return this.ssm;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get Secrets Manager client (lazy loaded)
|
|
176
|
+
*/
|
|
177
|
+
getSecretsManagerClient() {
|
|
178
|
+
if (!this.secretsManager) {
|
|
179
|
+
loadSecretsManager();
|
|
180
|
+
this.secretsManager = new SecretsManagerClient({
|
|
181
|
+
region: this.region,
|
|
182
|
+
...this.credentials,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return this.secretsManager;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Get CloudFormation client (lazy loaded)
|
|
190
|
+
*/
|
|
191
|
+
getCloudFormationClient() {
|
|
192
|
+
if (!this.cloudformation) {
|
|
193
|
+
loadCloudFormation();
|
|
194
|
+
this.cloudformation = new CloudFormationClient({
|
|
195
|
+
region: this.region,
|
|
196
|
+
...this.credentials,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
return this.cloudformation;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
getName() {
|
|
203
|
+
return 'aws';
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
getSupportedRegions() {
|
|
207
|
+
return [
|
|
208
|
+
'us-east-1', 'us-east-2', 'us-west-1', 'us-west-2',
|
|
209
|
+
'eu-west-1', 'eu-west-2', 'eu-west-3', 'eu-central-1',
|
|
210
|
+
'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1', 'ap-northeast-2',
|
|
211
|
+
'sa-east-1', 'ca-central-1',
|
|
212
|
+
];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Discover VPC resources
|
|
217
|
+
*
|
|
218
|
+
* @param {Object} config - Discovery configuration
|
|
219
|
+
* @returns {Promise<Object>} Discovered VPC resources
|
|
220
|
+
*/
|
|
221
|
+
async discoverVpc(config) {
|
|
222
|
+
const ec2 = this.getEC2Client();
|
|
223
|
+
const result = {
|
|
224
|
+
vpcId: null,
|
|
225
|
+
vpcCidr: null,
|
|
226
|
+
subnets: [],
|
|
227
|
+
securityGroups: [],
|
|
228
|
+
routeTables: [],
|
|
229
|
+
natGateways: [],
|
|
230
|
+
internetGateways: [],
|
|
231
|
+
vpcEndpoints: [],
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
// Discover VPC
|
|
236
|
+
const vpcFilter = config.vpcId
|
|
237
|
+
? [{ Name: 'vpc-id', Values: [config.vpcId] }]
|
|
238
|
+
: [{ Name: 'isDefault', Values: ['true'] }];
|
|
239
|
+
|
|
240
|
+
const vpcsResponse = await ec2.send(new DescribeVpcsCommand({
|
|
241
|
+
Filters: vpcFilter,
|
|
242
|
+
}));
|
|
243
|
+
|
|
244
|
+
if (vpcsResponse.Vpcs && vpcsResponse.Vpcs.length > 0) {
|
|
245
|
+
const vpc = vpcsResponse.Vpcs[0];
|
|
246
|
+
result.vpcId = vpc.VpcId;
|
|
247
|
+
result.vpcCidr = vpc.CidrBlock;
|
|
248
|
+
|
|
249
|
+
// Discover subnets in VPC
|
|
250
|
+
const subnetsResponse = await ec2.send(new DescribeSubnetsCommand({
|
|
251
|
+
Filters: [{ Name: 'vpc-id', Values: [result.vpcId] }],
|
|
252
|
+
}));
|
|
253
|
+
result.subnets = subnetsResponse.Subnets || [];
|
|
254
|
+
|
|
255
|
+
// Discover security groups
|
|
256
|
+
const sgResponse = await ec2.send(new DescribeSecurityGroupsCommand({
|
|
257
|
+
Filters: [{ Name: 'vpc-id', Values: [result.vpcId] }],
|
|
258
|
+
}));
|
|
259
|
+
result.securityGroups = sgResponse.SecurityGroups || [];
|
|
260
|
+
|
|
261
|
+
// Discover route tables
|
|
262
|
+
const rtResponse = await ec2.send(new DescribeRouteTablesCommand({
|
|
263
|
+
Filters: [{ Name: 'vpc-id', Values: [result.vpcId] }],
|
|
264
|
+
}));
|
|
265
|
+
result.routeTables = rtResponse.RouteTables || [];
|
|
266
|
+
|
|
267
|
+
// Discover NAT gateways
|
|
268
|
+
const natResponse = await ec2.send(new DescribeNatGatewaysCommand({
|
|
269
|
+
Filter: [{ Name: 'vpc-id', Values: [result.vpcId] }],
|
|
270
|
+
}));
|
|
271
|
+
result.natGateways = natResponse.NatGateways || [];
|
|
272
|
+
|
|
273
|
+
// Discover Internet gateways
|
|
274
|
+
const igwResponse = await ec2.send(new DescribeInternetGatewaysCommand({
|
|
275
|
+
Filters: [
|
|
276
|
+
{ Name: 'attachment.vpc-id', Values: [result.vpcId] },
|
|
277
|
+
],
|
|
278
|
+
}));
|
|
279
|
+
result.internetGateways = igwResponse.InternetGateways || [];
|
|
280
|
+
|
|
281
|
+
// Discover VPC Endpoints
|
|
282
|
+
const vpcEndpointsResponse = await ec2.send(new DescribeVpcEndpointsCommand({
|
|
283
|
+
Filters: [
|
|
284
|
+
{ Name: 'vpc-id', Values: [result.vpcId] },
|
|
285
|
+
],
|
|
286
|
+
}));
|
|
287
|
+
result.vpcEndpoints = vpcEndpointsResponse.VpcEndpoints || [];
|
|
288
|
+
}
|
|
289
|
+
} catch (error) {
|
|
290
|
+
console.error('AWS VPC discovery failed:', error);
|
|
291
|
+
throw new Error(`Failed to discover AWS VPC: ${error.message}`);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Discover KMS keys
|
|
299
|
+
*
|
|
300
|
+
* @param {Object} config - Discovery configuration
|
|
301
|
+
* @returns {Promise<Object>} Discovered KMS keys
|
|
302
|
+
*/
|
|
303
|
+
async discoverKmsKeys(config) {
|
|
304
|
+
const kms = this.getKMSClient();
|
|
305
|
+
const result = {
|
|
306
|
+
keys: [],
|
|
307
|
+
aliases: [],
|
|
308
|
+
defaultKey: null,
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
// List KMS keys
|
|
313
|
+
const keysResponse = await kms.send(new ListKeysCommand({}));
|
|
314
|
+
|
|
315
|
+
if (keysResponse.Keys && keysResponse.Keys.length > 0) {
|
|
316
|
+
// Get details for each key
|
|
317
|
+
for (const key of keysResponse.Keys) {
|
|
318
|
+
try {
|
|
319
|
+
const keyDetails = await kms.send(new DescribeKeyCommand({
|
|
320
|
+
KeyId: key.KeyId,
|
|
321
|
+
}));
|
|
322
|
+
|
|
323
|
+
if (keyDetails.KeyMetadata && keyDetails.KeyMetadata.Enabled) {
|
|
324
|
+
result.keys.push(keyDetails.KeyMetadata);
|
|
325
|
+
|
|
326
|
+
// Set first enabled key as default
|
|
327
|
+
if (!result.defaultKey) {
|
|
328
|
+
result.defaultKey = keyDetails.KeyMetadata;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
} catch (error) {
|
|
332
|
+
// Skip keys we can't access
|
|
333
|
+
console.warn(`Could not describe key ${key.KeyId}:`, error.message);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// List KMS aliases
|
|
339
|
+
const aliasesResponse = await kms.send(new ListAliasesCommand({}));
|
|
340
|
+
result.aliases = aliasesResponse.Aliases || [];
|
|
341
|
+
|
|
342
|
+
// If a specific alias is requested, find it
|
|
343
|
+
if (config.keyAlias) {
|
|
344
|
+
const alias = result.aliases.find(a => a.AliasName === config.keyAlias);
|
|
345
|
+
if (alias && alias.TargetKeyId) {
|
|
346
|
+
const key = result.keys.find(k => k.KeyId === alias.TargetKeyId);
|
|
347
|
+
if (key) {
|
|
348
|
+
result.defaultKey = key;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
} catch (error) {
|
|
353
|
+
console.error('AWS KMS discovery failed:', error);
|
|
354
|
+
throw new Error(`Failed to discover AWS KMS keys: ${error.message}`);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Discover database resources (RDS/Aurora)
|
|
362
|
+
*
|
|
363
|
+
* @param {Object} config - Discovery configuration
|
|
364
|
+
* @returns {Promise<Object>} Discovered database resources
|
|
365
|
+
*/
|
|
366
|
+
async discoverDatabase(config) {
|
|
367
|
+
const rds = this.getRDSClient();
|
|
368
|
+
const result = {
|
|
369
|
+
clusters: [],
|
|
370
|
+
instances: [],
|
|
371
|
+
endpoint: null,
|
|
372
|
+
port: null,
|
|
373
|
+
engine: null,
|
|
374
|
+
securityGroupIds: [],
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
try {
|
|
378
|
+
// Discover Aurora clusters
|
|
379
|
+
const clustersResponse = await rds.send(new DescribeDBClustersCommand({}));
|
|
380
|
+
|
|
381
|
+
if (clustersResponse.DBClusters) {
|
|
382
|
+
result.clusters = clustersResponse.DBClusters;
|
|
383
|
+
|
|
384
|
+
// Find cluster matching config
|
|
385
|
+
if (config.databaseId) {
|
|
386
|
+
const cluster = result.clusters.find(c =>
|
|
387
|
+
c.DBClusterIdentifier === config.databaseId
|
|
388
|
+
);
|
|
389
|
+
if (cluster) {
|
|
390
|
+
result.endpoint = cluster.Endpoint;
|
|
391
|
+
result.port = cluster.Port;
|
|
392
|
+
result.engine = cluster.Engine;
|
|
393
|
+
result.securityGroupIds = (cluster.VpcSecurityGroups || []).map(sg => sg.VpcSecurityGroupId);
|
|
394
|
+
}
|
|
395
|
+
} else if (result.clusters.length > 0) {
|
|
396
|
+
// Use first available cluster
|
|
397
|
+
const cluster = result.clusters[0];
|
|
398
|
+
result.endpoint = cluster.Endpoint;
|
|
399
|
+
result.port = cluster.Port;
|
|
400
|
+
result.engine = cluster.Engine;
|
|
401
|
+
result.securityGroupIds = (cluster.VpcSecurityGroups || []).map(sg => sg.VpcSecurityGroupId);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Discover RDS instances (if no cluster found)
|
|
406
|
+
if (!result.endpoint) {
|
|
407
|
+
const instancesResponse = await rds.send(new DescribeDBInstancesCommand({}));
|
|
408
|
+
if (instancesResponse.DBInstances) {
|
|
409
|
+
result.instances = instancesResponse.DBInstances;
|
|
410
|
+
|
|
411
|
+
if (config.databaseId) {
|
|
412
|
+
const instance = result.instances.find(i =>
|
|
413
|
+
i.DBInstanceIdentifier === config.databaseId
|
|
414
|
+
);
|
|
415
|
+
if (instance) {
|
|
416
|
+
result.endpoint = instance.Endpoint?.Address;
|
|
417
|
+
result.port = instance.Endpoint?.Port;
|
|
418
|
+
result.engine = instance.Engine;
|
|
419
|
+
}
|
|
420
|
+
} else if (result.instances.length > 0) {
|
|
421
|
+
const instance = result.instances[0];
|
|
422
|
+
result.endpoint = instance.Endpoint?.Address;
|
|
423
|
+
result.port = instance.Endpoint?.Port;
|
|
424
|
+
result.engine = instance.Engine;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
} catch (error) {
|
|
429
|
+
console.error('AWS RDS discovery failed:', error);
|
|
430
|
+
throw new Error(`Failed to discover AWS databases: ${error.message}`);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return result;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Discover SSM parameters
|
|
438
|
+
*
|
|
439
|
+
* @param {Object} config - Discovery configuration
|
|
440
|
+
* @returns {Promise<Object>} Discovered parameters
|
|
441
|
+
*/
|
|
442
|
+
async discoverParameters(config) {
|
|
443
|
+
const ssm = this.getSSMClient();
|
|
444
|
+
const result = {
|
|
445
|
+
parameters: [],
|
|
446
|
+
secrets: [],
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
try {
|
|
450
|
+
if (config.parameterPath) {
|
|
451
|
+
const response = await ssm.send(new GetParametersByPathCommand({
|
|
452
|
+
Path: config.parameterPath,
|
|
453
|
+
Recursive: true,
|
|
454
|
+
}));
|
|
455
|
+
result.parameters = response.Parameters || [];
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Discover secrets if enabled
|
|
459
|
+
if (config.includeSecrets) {
|
|
460
|
+
const sm = this.getSecretsManagerClient();
|
|
461
|
+
const secretsResponse = await sm.send(new ListSecretsCommand({}));
|
|
462
|
+
result.secrets = secretsResponse.SecretList || [];
|
|
463
|
+
}
|
|
464
|
+
} catch (error) {
|
|
465
|
+
console.error('AWS SSM discovery failed:', error);
|
|
466
|
+
throw new Error(`Failed to discover AWS parameters: ${error.message}`);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
return result;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Describe KMS key by key ID or alias
|
|
474
|
+
*
|
|
475
|
+
* @param {string} keyIdOrAlias - Key ID or alias name
|
|
476
|
+
* @returns {Promise<Object>} Key metadata
|
|
477
|
+
*/
|
|
478
|
+
async describeKmsKey(keyIdOrAlias) {
|
|
479
|
+
const kms = this.getKMSClient();
|
|
480
|
+
|
|
481
|
+
try {
|
|
482
|
+
const response = await kms.send(new DescribeKeyCommand({
|
|
483
|
+
KeyId: keyIdOrAlias,
|
|
484
|
+
}));
|
|
485
|
+
|
|
486
|
+
return response.KeyMetadata;
|
|
487
|
+
} catch (error) {
|
|
488
|
+
throw new Error(`Failed to describe KMS key ${keyIdOrAlias}: ${error.message}`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Describe CloudFormation stack
|
|
494
|
+
*
|
|
495
|
+
* @param {string} stackName - Name of the CloudFormation stack
|
|
496
|
+
* @returns {Promise<Object>} Stack details including outputs
|
|
497
|
+
*/
|
|
498
|
+
async describeStack(stackName) {
|
|
499
|
+
const cf = this.getCloudFormationClient();
|
|
500
|
+
|
|
501
|
+
try {
|
|
502
|
+
const response = await cf.send(new DescribeStacksCommand({
|
|
503
|
+
StackName: stackName,
|
|
504
|
+
}));
|
|
505
|
+
|
|
506
|
+
if (!response.Stacks || response.Stacks.length === 0) {
|
|
507
|
+
throw new Error(`Stack ${stackName} not found`);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return response.Stacks[0];
|
|
511
|
+
} catch (error) {
|
|
512
|
+
if (error.message && error.message.includes('does not exist')) {
|
|
513
|
+
throw new Error(`Stack with id ${stackName} does not exist`);
|
|
514
|
+
}
|
|
515
|
+
throw error;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* List CloudFormation stack resources
|
|
521
|
+
*
|
|
522
|
+
* @param {string} stackName - Name of the CloudFormation stack
|
|
523
|
+
* @returns {Promise<Array>} List of stack resources
|
|
524
|
+
*/
|
|
525
|
+
async listStackResources(stackName) {
|
|
526
|
+
const cf = this.getCloudFormationClient();
|
|
527
|
+
|
|
528
|
+
try {
|
|
529
|
+
const response = await cf.send(new ListStackResourcesCommand({
|
|
530
|
+
StackName: stackName,
|
|
531
|
+
}));
|
|
532
|
+
|
|
533
|
+
return response.StackResourceSummaries || [];
|
|
534
|
+
} catch (error) {
|
|
535
|
+
console.warn(`Failed to list stack resources for ${stackName}:`, error.message);
|
|
536
|
+
return [];
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
module.exports = {
|
|
542
|
+
AWSProviderAdapter,
|
|
543
|
+
};
|
|
544
|
+
|