@friggframework/devtools 2.0.0-next.44 → 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 -2074
- /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,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for AWS Provider Adapter
|
|
3
|
+
*
|
|
4
|
+
* Tests AWS-specific cloud resource discovery
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { AWSProviderAdapter } = require('./aws-provider-adapter');
|
|
8
|
+
|
|
9
|
+
// Mock AWS SDK v3 clients
|
|
10
|
+
jest.mock('@aws-sdk/client-ec2');
|
|
11
|
+
jest.mock('@aws-sdk/client-kms');
|
|
12
|
+
jest.mock('@aws-sdk/client-rds');
|
|
13
|
+
jest.mock('@aws-sdk/client-ssm');
|
|
14
|
+
jest.mock('@aws-sdk/client-secrets-manager');
|
|
15
|
+
|
|
16
|
+
describe('AWSProviderAdapter', () => {
|
|
17
|
+
let provider;
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
jest.clearAllMocks();
|
|
21
|
+
delete process.env.AWS_REGION;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('constructor()', () => {
|
|
25
|
+
it('should initialize with provided region', () => {
|
|
26
|
+
provider = new AWSProviderAdapter('eu-west-1');
|
|
27
|
+
|
|
28
|
+
expect(provider.region).toBe('eu-west-1');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should default to us-east-1 if no region provided', () => {
|
|
32
|
+
provider = new AWSProviderAdapter();
|
|
33
|
+
|
|
34
|
+
expect(provider.region).toBe('us-east-1');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should use AWS_REGION environment variable', () => {
|
|
38
|
+
process.env.AWS_REGION = 'ap-southeast-1';
|
|
39
|
+
provider = new AWSProviderAdapter();
|
|
40
|
+
|
|
41
|
+
expect(provider.region).toBe('ap-southeast-1');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should prefer provided region over environment variable', () => {
|
|
45
|
+
process.env.AWS_REGION = 'us-west-2';
|
|
46
|
+
provider = new AWSProviderAdapter('eu-central-1');
|
|
47
|
+
|
|
48
|
+
expect(provider.region).toBe('eu-central-1');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should store credentials if provided', () => {
|
|
52
|
+
const credentials = {
|
|
53
|
+
accessKeyId: 'test-key',
|
|
54
|
+
secretAccessKey: 'test-secret',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
provider = new AWSProviderAdapter('us-east-1', credentials);
|
|
58
|
+
|
|
59
|
+
expect(provider.credentials).toEqual(credentials);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should lazy-load clients (not instantiated on construction)', () => {
|
|
63
|
+
provider = new AWSProviderAdapter('us-east-1');
|
|
64
|
+
|
|
65
|
+
expect(provider.ec2).toBeNull();
|
|
66
|
+
expect(provider.kms).toBeNull();
|
|
67
|
+
expect(provider.rds).toBeNull();
|
|
68
|
+
expect(provider.ssm).toBeNull();
|
|
69
|
+
expect(provider.secretsManager).toBeNull();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('getName()', () => {
|
|
74
|
+
it('should return "aws"', () => {
|
|
75
|
+
provider = new AWSProviderAdapter();
|
|
76
|
+
|
|
77
|
+
expect(provider.getName()).toBe('aws');
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('getSupportedRegions()', () => {
|
|
82
|
+
it('should return array of AWS regions', () => {
|
|
83
|
+
provider = new AWSProviderAdapter();
|
|
84
|
+
|
|
85
|
+
const regions = provider.getSupportedRegions();
|
|
86
|
+
|
|
87
|
+
expect(Array.isArray(regions)).toBe(true);
|
|
88
|
+
expect(regions.length).toBeGreaterThan(0);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should include common US regions', () => {
|
|
92
|
+
provider = new AWSProviderAdapter();
|
|
93
|
+
|
|
94
|
+
const regions = provider.getSupportedRegions();
|
|
95
|
+
|
|
96
|
+
expect(regions).toContain('us-east-1');
|
|
97
|
+
expect(regions).toContain('us-east-2');
|
|
98
|
+
expect(regions).toContain('us-west-1');
|
|
99
|
+
expect(regions).toContain('us-west-2');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should include common EU regions', () => {
|
|
103
|
+
provider = new AWSProviderAdapter();
|
|
104
|
+
|
|
105
|
+
const regions = provider.getSupportedRegions();
|
|
106
|
+
|
|
107
|
+
expect(regions).toContain('eu-west-1');
|
|
108
|
+
expect(regions).toContain('eu-central-1');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should include common APAC regions', () => {
|
|
112
|
+
provider = new AWSProviderAdapter();
|
|
113
|
+
|
|
114
|
+
const regions = provider.getSupportedRegions();
|
|
115
|
+
|
|
116
|
+
expect(regions).toContain('ap-southeast-1');
|
|
117
|
+
expect(regions).toContain('ap-northeast-1');
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('Lazy loading clients', () => {
|
|
122
|
+
beforeEach(() => {
|
|
123
|
+
provider = new AWSProviderAdapter('us-east-1');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should lazy-load EC2 client', () => {
|
|
127
|
+
expect(provider.ec2).toBeNull();
|
|
128
|
+
|
|
129
|
+
const client = provider.getEC2Client();
|
|
130
|
+
|
|
131
|
+
expect(provider.ec2).not.toBeNull();
|
|
132
|
+
expect(client).toBe(provider.ec2);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should lazy-load KMS client', () => {
|
|
136
|
+
expect(provider.kms).toBeNull();
|
|
137
|
+
|
|
138
|
+
const client = provider.getKMSClient();
|
|
139
|
+
|
|
140
|
+
expect(provider.kms).not.toBeNull();
|
|
141
|
+
expect(client).toBe(provider.kms);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('should lazy-load RDS client', () => {
|
|
145
|
+
expect(provider.rds).toBeNull();
|
|
146
|
+
|
|
147
|
+
const client = provider.getRDSClient();
|
|
148
|
+
|
|
149
|
+
expect(provider.rds).not.toBeNull();
|
|
150
|
+
expect(client).toBe(provider.rds);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should lazy-load SSM client', () => {
|
|
154
|
+
expect(provider.ssm).toBeNull();
|
|
155
|
+
|
|
156
|
+
const client = provider.getSSMClient();
|
|
157
|
+
|
|
158
|
+
expect(provider.ssm).not.toBeNull();
|
|
159
|
+
expect(client).toBe(provider.ssm);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should lazy-load Secrets Manager client', () => {
|
|
163
|
+
expect(provider.secretsManager).toBeNull();
|
|
164
|
+
|
|
165
|
+
const client = provider.getSecretsManagerClient();
|
|
166
|
+
|
|
167
|
+
expect(provider.secretsManager).not.toBeNull();
|
|
168
|
+
expect(client).toBe(provider.secretsManager);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should lazy-load CloudFormation client', () => {
|
|
172
|
+
expect(provider.cloudformation).toBeNull();
|
|
173
|
+
|
|
174
|
+
const client = provider.getCloudFormationClient();
|
|
175
|
+
|
|
176
|
+
expect(provider.cloudformation).not.toBeNull();
|
|
177
|
+
expect(client).toBe(provider.cloudformation);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should reuse client on subsequent calls', () => {
|
|
181
|
+
const client1 = provider.getEC2Client();
|
|
182
|
+
const client2 = provider.getEC2Client();
|
|
183
|
+
|
|
184
|
+
expect(client1).toBe(client2);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
describe('discoverVpc()', () => {
|
|
189
|
+
beforeEach(() => {
|
|
190
|
+
provider = new AWSProviderAdapter('us-east-1');
|
|
191
|
+
const { EC2Client } = require('@aws-sdk/client-ec2');
|
|
192
|
+
EC2Client.mockImplementation(() => ({
|
|
193
|
+
send: jest.fn(),
|
|
194
|
+
}));
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('should return VPC discovery results', async () => {
|
|
198
|
+
const mockSend = jest.fn()
|
|
199
|
+
.mockResolvedValueOnce({ // VPCs
|
|
200
|
+
Vpcs: [
|
|
201
|
+
{ VpcId: 'vpc-123', CidrBlock: '172.31.0.0/16' },
|
|
202
|
+
],
|
|
203
|
+
})
|
|
204
|
+
.mockResolvedValueOnce({ Subnets: [] }) // Subnets
|
|
205
|
+
.mockResolvedValueOnce({ SecurityGroups: [] }) // Security Groups
|
|
206
|
+
.mockResolvedValueOnce({ RouteTables: [] }) // Route Tables
|
|
207
|
+
.mockResolvedValueOnce({ NatGateways: [] }) // NAT Gateways
|
|
208
|
+
.mockResolvedValueOnce({ InternetGateways: [] }) // Internet Gateways
|
|
209
|
+
.mockResolvedValueOnce({ VpcEndpoints: [] }); // VPC Endpoints
|
|
210
|
+
|
|
211
|
+
provider.getEC2Client = jest.fn().mockReturnValue({ send: mockSend });
|
|
212
|
+
|
|
213
|
+
const result = await provider.discoverVpc({});
|
|
214
|
+
|
|
215
|
+
expect(result.vpcId).toBe('vpc-123');
|
|
216
|
+
expect(result.vpcCidr).toBe('172.31.0.0/16');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('should handle discovery errors', async () => {
|
|
220
|
+
provider.getEC2Client = jest.fn().mockReturnValue({
|
|
221
|
+
send: jest.fn().mockRejectedValue(new Error('EC2 API Error')),
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
await expect(provider.discoverVpc({})).rejects.toThrow('Failed to discover AWS VPC');
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('should discover default VPC when no vpcId specified', async () => {
|
|
228
|
+
const mockSend = jest.fn();
|
|
229
|
+
provider.getEC2Client = jest.fn().mockReturnValue({ send: mockSend });
|
|
230
|
+
|
|
231
|
+
await provider.discoverVpc({}).catch(() => { });
|
|
232
|
+
|
|
233
|
+
// First call should filter for default VPC
|
|
234
|
+
expect(mockSend).toHaveBeenCalled();
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
describe('discoverKmsKeys()', () => {
|
|
239
|
+
beforeEach(() => {
|
|
240
|
+
provider = new AWSProviderAdapter('us-east-1');
|
|
241
|
+
const { KMSClient } = require('@aws-sdk/client-kms');
|
|
242
|
+
KMSClient.mockImplementation(() => ({
|
|
243
|
+
send: jest.fn(),
|
|
244
|
+
}));
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('should return KMS discovery results', async () => {
|
|
248
|
+
const mockSend = jest.fn()
|
|
249
|
+
.mockResolvedValueOnce({ // ListKeys
|
|
250
|
+
Keys: [{ KeyId: 'key-123' }],
|
|
251
|
+
})
|
|
252
|
+
.mockResolvedValueOnce({ // DescribeKey
|
|
253
|
+
KeyMetadata: {
|
|
254
|
+
KeyId: 'key-123',
|
|
255
|
+
Arn: 'arn:aws:kms:us-east-1:123:key/abc',
|
|
256
|
+
Enabled: true,
|
|
257
|
+
},
|
|
258
|
+
})
|
|
259
|
+
.mockResolvedValueOnce({ // ListAliases
|
|
260
|
+
Aliases: [
|
|
261
|
+
{ AliasName: 'alias/my-key', TargetKeyId: 'key-123' },
|
|
262
|
+
],
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
provider.getKMSClient = jest.fn().mockReturnValue({ send: mockSend });
|
|
266
|
+
|
|
267
|
+
const result = await provider.discoverKmsKeys({});
|
|
268
|
+
|
|
269
|
+
expect(result.keys.length).toBeGreaterThan(0);
|
|
270
|
+
expect(result.defaultKey).toBeDefined();
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('should handle discovery errors', async () => {
|
|
274
|
+
provider.getKMSClient = jest.fn().mockReturnValue({
|
|
275
|
+
send: jest.fn().mockRejectedValue(new Error('KMS API Error')),
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
await expect(provider.discoverKmsKeys({})).rejects.toThrow('Failed to discover AWS KMS keys');
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
describe('discoverDatabase()', () => {
|
|
283
|
+
beforeEach(() => {
|
|
284
|
+
provider = new AWSProviderAdapter('us-east-1');
|
|
285
|
+
const { RDSClient } = require('@aws-sdk/client-rds');
|
|
286
|
+
RDSClient.mockImplementation(() => ({
|
|
287
|
+
send: jest.fn(),
|
|
288
|
+
}));
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('should return database discovery results', async () => {
|
|
292
|
+
const mockSend = jest.fn()
|
|
293
|
+
.mockResolvedValueOnce({ // Clusters
|
|
294
|
+
DBClusters: [
|
|
295
|
+
{
|
|
296
|
+
DBClusterIdentifier: 'cluster-1',
|
|
297
|
+
Endpoint: 'cluster-1.example.com',
|
|
298
|
+
Port: 5432,
|
|
299
|
+
Engine: 'aurora-postgresql',
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
})
|
|
303
|
+
.mockResolvedValueOnce({ DBInstances: [] }); // Instances
|
|
304
|
+
|
|
305
|
+
provider.getRDSClient = jest.fn().mockReturnValue({ send: mockSend });
|
|
306
|
+
|
|
307
|
+
const result = await provider.discoverDatabase({});
|
|
308
|
+
|
|
309
|
+
expect(result.endpoint).toBe('cluster-1.example.com');
|
|
310
|
+
expect(result.port).toBe(5432);
|
|
311
|
+
expect(result.engine).toBe('aurora-postgresql');
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
it('should handle discovery errors', async () => {
|
|
315
|
+
provider.getRDSClient = jest.fn().mockReturnValue({
|
|
316
|
+
send: jest.fn().mockRejectedValue(new Error('RDS API Error')),
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
await expect(provider.discoverDatabase({})).rejects.toThrow('Failed to discover AWS databases');
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
describe('discoverParameters()', () => {
|
|
324
|
+
beforeEach(() => {
|
|
325
|
+
provider = new AWSProviderAdapter('us-east-1');
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('should return parameter discovery results', async () => {
|
|
329
|
+
const mockSSMSend = jest.fn().mockResolvedValue({
|
|
330
|
+
Parameters: [
|
|
331
|
+
{ Name: '/my-app/api-key', Value: 'encrypted' },
|
|
332
|
+
],
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const mockSMSend = jest.fn().mockResolvedValue({
|
|
336
|
+
SecretList: [
|
|
337
|
+
{ Name: 'my-app/secret', ARN: 'arn:aws:secretsmanager:us-east-1:123:secret:my-app/secret' },
|
|
338
|
+
],
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
provider.getSSMClient = jest.fn().mockReturnValue({ send: mockSSMSend });
|
|
342
|
+
provider.getSecretsManagerClient = jest.fn().mockReturnValue({ send: mockSMSend });
|
|
343
|
+
|
|
344
|
+
const result = await provider.discoverParameters({
|
|
345
|
+
parameterPath: '/my-app',
|
|
346
|
+
includeSecrets: true,
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
expect(result.parameters).toHaveLength(1);
|
|
350
|
+
expect(result.secrets).toHaveLength(1);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it('should handle discovery errors', async () => {
|
|
354
|
+
provider.getSSMClient = jest.fn().mockReturnValue({
|
|
355
|
+
send: jest.fn().mockRejectedValue(new Error('SSM API Error')),
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
await expect(provider.discoverParameters({ parameterPath: '/test' })).rejects.toThrow('Failed to discover AWS parameters');
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('should skip secrets when includeSecrets is false', async () => {
|
|
362
|
+
const mockSSMSend = jest.fn().mockResolvedValue({ Parameters: [] });
|
|
363
|
+
|
|
364
|
+
provider.getSSMClient = jest.fn().mockReturnValue({ send: mockSSMSend });
|
|
365
|
+
|
|
366
|
+
const result = await provider.discoverParameters({
|
|
367
|
+
includeSecrets: false,
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
expect(result.parameters).toEqual([]);
|
|
371
|
+
expect(result.secrets).toEqual([]);
|
|
372
|
+
// Behavior-based test: secrets should be empty when includeSecrets is false
|
|
373
|
+
// (Implementation detail: getSecretsManagerClient shouldn't be called)
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FUTURE: Microsoft Azure Provider Adapter
|
|
3
|
+
*
|
|
4
|
+
* This file serves as a placeholder for future Azure support.
|
|
5
|
+
*
|
|
6
|
+
* Implementation will use:
|
|
7
|
+
* - @azure/arm-network for Virtual Network discovery
|
|
8
|
+
* - @azure/keyvault-keys for Key Vault key management
|
|
9
|
+
* - @azure/arm-sql for Azure SQL database discovery
|
|
10
|
+
* - @azure/keyvault-secrets for secrets management
|
|
11
|
+
* - @azure/arm-resources for resource group management
|
|
12
|
+
*
|
|
13
|
+
* Resources:
|
|
14
|
+
* - Azure SDK for JavaScript: https://docs.microsoft.com/en-us/javascript/azure/
|
|
15
|
+
* - ARM Network API: https://docs.microsoft.com/en-us/javascript/api/@azure/arm-network
|
|
16
|
+
* - Key Vault API: https://docs.microsoft.com/en-us/javascript/api/@azure/keyvault-keys
|
|
17
|
+
* - Azure SQL API: https://docs.microsoft.com/en-us/javascript/api/@azure/arm-sql
|
|
18
|
+
*
|
|
19
|
+
* Architecture mapping:
|
|
20
|
+
* - AWS VPC → Azure Virtual Network (VNet)
|
|
21
|
+
* - AWS KMS → Azure Key Vault
|
|
22
|
+
* - AWS RDS Aurora → Azure SQL Database / Azure Database for PostgreSQL
|
|
23
|
+
* - AWS SSM Parameter Store → Azure Key Vault Secrets
|
|
24
|
+
* - AWS Lambda → Azure Functions
|
|
25
|
+
*
|
|
26
|
+
* Example structure:
|
|
27
|
+
*
|
|
28
|
+
* const { NetworkManagementClient } = require('@azure/arm-network');
|
|
29
|
+
* const { KeyClient } = require('@azure/keyvault-keys');
|
|
30
|
+
* const { DefaultAzureCredential } = require('@azure/identity');
|
|
31
|
+
* const { CloudProviderAdapter } = require('./cloud-provider-adapter');
|
|
32
|
+
*
|
|
33
|
+
* class AzureProviderAdapter extends CloudProviderAdapter {
|
|
34
|
+
* constructor(region, credentials = {}) {
|
|
35
|
+
* super();
|
|
36
|
+
* this.region = region || 'eastus';
|
|
37
|
+
* this.subscriptionId = credentials.subscriptionId || process.env.AZURE_SUBSCRIPTION_ID;
|
|
38
|
+
* this.credential = new DefaultAzureCredential();
|
|
39
|
+
*
|
|
40
|
+
* this.networkClient = new NetworkManagementClient(
|
|
41
|
+
* this.credential,
|
|
42
|
+
* this.subscriptionId
|
|
43
|
+
* );
|
|
44
|
+
* }
|
|
45
|
+
*
|
|
46
|
+
* getName() {
|
|
47
|
+
* return 'azure';
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* getSupportedRegions() {
|
|
51
|
+
* return [
|
|
52
|
+
* 'eastus', 'eastus2', 'westus', 'westus2',
|
|
53
|
+
* 'northeurope', 'westeurope', 'southeastasia'
|
|
54
|
+
* ];
|
|
55
|
+
* }
|
|
56
|
+
*
|
|
57
|
+
* async discoverVpc(config) {
|
|
58
|
+
* // Discover Azure Virtual Networks
|
|
59
|
+
* const vnets = [];
|
|
60
|
+
* for await (const vnet of this.networkClient.virtualNetworks.listAll()) {
|
|
61
|
+
* vnets.push(vnet);
|
|
62
|
+
* }
|
|
63
|
+
* // ... implementation
|
|
64
|
+
* }
|
|
65
|
+
*
|
|
66
|
+
* async discoverKmsKeys(config) {
|
|
67
|
+
* // Discover Azure Key Vault keys
|
|
68
|
+
* const keyVaultUrl = `https://${config.keyVaultName}.vault.azure.net`;
|
|
69
|
+
* const keyClient = new KeyClient(keyVaultUrl, this.credential);
|
|
70
|
+
* const keys = [];
|
|
71
|
+
* for await (const key of keyClient.listPropertiesOfKeys()) {
|
|
72
|
+
* keys.push(key);
|
|
73
|
+
* }
|
|
74
|
+
* // ... implementation
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* async discoverDatabase(config) {
|
|
78
|
+
* // Discover Azure SQL databases
|
|
79
|
+
* // ... implementation
|
|
80
|
+
* }
|
|
81
|
+
*
|
|
82
|
+
* async discoverParameters(config) {
|
|
83
|
+
* // Discover Azure Key Vault secrets
|
|
84
|
+
* // ... implementation
|
|
85
|
+
* }
|
|
86
|
+
* }
|
|
87
|
+
*
|
|
88
|
+
* module.exports = { AzureProviderAdapter };
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
// Placeholder export to prevent import errors
|
|
92
|
+
module.exports = {};
|
|
93
|
+
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud Provider Adapter (Abstract Base Class)
|
|
3
|
+
*
|
|
4
|
+
* Port - Hexagonal Architecture
|
|
5
|
+
*
|
|
6
|
+
* Defines the contract for cloud provider implementations.
|
|
7
|
+
* This abstraction enables multi-cloud support by providing a consistent
|
|
8
|
+
* interface for AWS, GCP, Azure, and other cloud providers.
|
|
9
|
+
*
|
|
10
|
+
* Benefits:
|
|
11
|
+
* - Cloud-agnostic infrastructure code
|
|
12
|
+
* - Easy to add new providers (just implement this interface)
|
|
13
|
+
* - Testable with mock providers
|
|
14
|
+
* - Clear separation between cloud-specific and business logic
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
class CloudProviderAdapter {
|
|
18
|
+
/**
|
|
19
|
+
* Get provider name
|
|
20
|
+
* @returns {string} Provider name ('aws', 'gcp', 'azure', etc.)
|
|
21
|
+
*/
|
|
22
|
+
getName() {
|
|
23
|
+
throw new Error('CloudProviderAdapter.getName() must be implemented by subclass');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get supported regions for this provider
|
|
28
|
+
* @returns {Array<string>} List of supported region identifiers
|
|
29
|
+
*/
|
|
30
|
+
getSupportedRegions() {
|
|
31
|
+
throw new Error('CloudProviderAdapter.getSupportedRegions() must be implemented by subclass');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ==================== Discovery Methods ====================
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Discover VPC/network resources
|
|
38
|
+
*
|
|
39
|
+
* @param {Object} config - Discovery configuration
|
|
40
|
+
* @param {string} [config.vpcId] - Specific VPC ID to discover
|
|
41
|
+
* @param {string} [config.vpcName] - VPC name pattern to search for
|
|
42
|
+
* @param {boolean} [config.includeSubnets] - Whether to include subnet details
|
|
43
|
+
* @returns {Promise<Object>} Discovered VPC resources
|
|
44
|
+
* @returns {Promise<Object>} result.vpcId - VPC identifier
|
|
45
|
+
* @returns {Promise<Object>} result.vpcCidr - VPC CIDR block
|
|
46
|
+
* @returns {Promise<Object>} result.subnets - Array of subnet objects
|
|
47
|
+
* @returns {Promise<Object>} result.securityGroups - Array of security group objects
|
|
48
|
+
* @returns {Promise<Object>} result.routeTables - Array of route table objects
|
|
49
|
+
*/
|
|
50
|
+
async discoverVpc(config) {
|
|
51
|
+
throw new Error('CloudProviderAdapter.discoverVpc() must be implemented by subclass');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Discover encryption keys (KMS, Cloud KMS, Azure Key Vault, etc.)
|
|
56
|
+
*
|
|
57
|
+
* @param {Object} config - Discovery configuration
|
|
58
|
+
* @param {string} [config.keyId] - Specific key ID to discover
|
|
59
|
+
* @param {string} [config.keyAlias] - Key alias to search for
|
|
60
|
+
* @returns {Promise<Object>} Discovered encryption key resources
|
|
61
|
+
* @returns {Promise<Object>} result.keyId - Key identifier
|
|
62
|
+
* @returns {Promise<Object>} result.keyArn - Key ARN/resource name
|
|
63
|
+
* @returns {Promise<Object>} result.aliases - Array of key aliases
|
|
64
|
+
*/
|
|
65
|
+
async discoverKmsKeys(config) {
|
|
66
|
+
throw new Error('CloudProviderAdapter.discoverKmsKeys() must be implemented by subclass');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Discover database resources (RDS, Cloud SQL, Azure SQL, etc.)
|
|
71
|
+
*
|
|
72
|
+
* @param {Object} config - Discovery configuration
|
|
73
|
+
* @param {string} [config.databaseId] - Specific database instance/cluster ID
|
|
74
|
+
* @param {string} [config.engine] - Database engine filter ('postgresql', 'mysql', etc.)
|
|
75
|
+
* @returns {Promise<Object>} Discovered database resources
|
|
76
|
+
* @returns {Promise<Object>} result.endpoint - Database connection endpoint
|
|
77
|
+
* @returns {Promise<Object>} result.port - Database port
|
|
78
|
+
* @returns {Promise<Object>} result.engine - Database engine type
|
|
79
|
+
* @returns {Promise<Object>} result.version - Database version
|
|
80
|
+
*/
|
|
81
|
+
async discoverDatabase(config) {
|
|
82
|
+
throw new Error('CloudProviderAdapter.discoverDatabase() must be implemented by subclass');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Discover parameter store/secret manager resources
|
|
87
|
+
*
|
|
88
|
+
* @param {Object} config - Discovery configuration
|
|
89
|
+
* @param {string} [config.parameterPath] - Parameter path prefix to search
|
|
90
|
+
* @param {string} [config.secretName] - Specific secret name to discover
|
|
91
|
+
* @returns {Promise<Object>} Discovered parameter/secret resources
|
|
92
|
+
* @returns {Promise<Object>} result.parameters - Array of parameter objects
|
|
93
|
+
* @returns {Promise<Object>} result.secrets - Array of secret objects
|
|
94
|
+
*/
|
|
95
|
+
async discoverParameters(config) {
|
|
96
|
+
throw new Error('CloudProviderAdapter.discoverParameters() must be implemented by subclass');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ==================== Provisioning Methods (Future) ====================
|
|
100
|
+
// These will be used for Terraform/Pulumi/CloudFormation generation
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Generate VPC provisioning configuration
|
|
104
|
+
*
|
|
105
|
+
* @param {Object} config - VPC configuration
|
|
106
|
+
* @returns {Promise<Object>} Infrastructure-as-code configuration
|
|
107
|
+
*/
|
|
108
|
+
async provisionVpc(config) {
|
|
109
|
+
throw new Error('CloudProviderAdapter.provisionVpc() not yet implemented. Future feature for IaC generation.');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Generate encryption key provisioning configuration
|
|
114
|
+
*
|
|
115
|
+
* @param {Object} config - Key configuration
|
|
116
|
+
* @returns {Promise<Object>} Infrastructure-as-code configuration
|
|
117
|
+
*/
|
|
118
|
+
async provisionKmsKey(config) {
|
|
119
|
+
throw new Error('CloudProviderAdapter.provisionKmsKey() not yet implemented. Future feature for IaC generation.');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Generate database provisioning configuration
|
|
124
|
+
*
|
|
125
|
+
* @param {Object} config - Database configuration
|
|
126
|
+
* @returns {Promise<Object>} Infrastructure-as-code configuration
|
|
127
|
+
*/
|
|
128
|
+
async provisionDatabase(config) {
|
|
129
|
+
throw new Error('CloudProviderAdapter.provisionDatabase() not yet implemented. Future feature for IaC generation.');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
module.exports = {
|
|
134
|
+
CloudProviderAdapter,
|
|
135
|
+
};
|
|
136
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FUTURE: Google Cloud Platform Provider Adapter
|
|
3
|
+
*
|
|
4
|
+
* This file serves as a placeholder for future GCP support.
|
|
5
|
+
*
|
|
6
|
+
* Implementation will use:
|
|
7
|
+
* - @google-cloud/compute for VPC/network discovery
|
|
8
|
+
* - @google-cloud/kms for encryption key management
|
|
9
|
+
* - @google-cloud/sql for Cloud SQL database discovery
|
|
10
|
+
* - @google-cloud/secret-manager for secrets management
|
|
11
|
+
*
|
|
12
|
+
* Resources:
|
|
13
|
+
* - GCP Node.js SDK: https://cloud.google.com/nodejs/docs/reference
|
|
14
|
+
* - Compute Engine API: https://cloud.google.com/compute/docs/reference/rest/v1
|
|
15
|
+
* - Cloud KMS API: https://cloud.google.com/kms/docs/reference/rest
|
|
16
|
+
* - Cloud SQL API: https://cloud.google.com/sql/docs/mysql/admin-api
|
|
17
|
+
*
|
|
18
|
+
* Architecture mapping:
|
|
19
|
+
* - AWS VPC → GCP VPC Network
|
|
20
|
+
* - AWS KMS → GCP Cloud KMS
|
|
21
|
+
* - AWS RDS Aurora → GCP Cloud SQL
|
|
22
|
+
* - AWS SSM Parameter Store → GCP Secret Manager
|
|
23
|
+
* - AWS Lambda → GCP Cloud Functions / Cloud Run
|
|
24
|
+
*
|
|
25
|
+
* Example structure:
|
|
26
|
+
*
|
|
27
|
+
* const { Compute } = require('@google-cloud/compute');
|
|
28
|
+
* const { KeyManagementServiceClient } = require('@google-cloud/kms');
|
|
29
|
+
* const { CloudProviderAdapter } = require('./cloud-provider-adapter');
|
|
30
|
+
*
|
|
31
|
+
* class GCPProviderAdapter extends CloudProviderAdapter {
|
|
32
|
+
* constructor(region, credentials = {}) {
|
|
33
|
+
* super();
|
|
34
|
+
* this.region = region || 'us-central1';
|
|
35
|
+
* this.projectId = credentials.projectId || process.env.GCP_PROJECT_ID;
|
|
36
|
+
*
|
|
37
|
+
* this.compute = new Compute({ projectId: this.projectId });
|
|
38
|
+
* this.kms = new KeyManagementServiceClient();
|
|
39
|
+
* }
|
|
40
|
+
*
|
|
41
|
+
* getName() {
|
|
42
|
+
* return 'gcp';
|
|
43
|
+
* }
|
|
44
|
+
*
|
|
45
|
+
* getSupportedRegions() {
|
|
46
|
+
* return [
|
|
47
|
+
* 'us-central1', 'us-east1', 'us-west1',
|
|
48
|
+
* 'europe-west1', 'asia-east1', 'asia-northeast1'
|
|
49
|
+
* ];
|
|
50
|
+
* }
|
|
51
|
+
*
|
|
52
|
+
* async discoverVpc(config) {
|
|
53
|
+
* // Discover GCP VPC networks
|
|
54
|
+
* const [networks] = await this.compute.getNetworks();
|
|
55
|
+
* // ... implementation
|
|
56
|
+
* }
|
|
57
|
+
*
|
|
58
|
+
* async discoverKmsKeys(config) {
|
|
59
|
+
* // Discover GCP Cloud KMS keys
|
|
60
|
+
* const [keyRings] = await this.kms.listKeyRings({
|
|
61
|
+
* parent: `projects/${this.projectId}/locations/${this.region}`
|
|
62
|
+
* });
|
|
63
|
+
* // ... implementation
|
|
64
|
+
* }
|
|
65
|
+
*
|
|
66
|
+
* async discoverDatabase(config) {
|
|
67
|
+
* // Discover GCP Cloud SQL instances
|
|
68
|
+
* // ... implementation
|
|
69
|
+
* }
|
|
70
|
+
*
|
|
71
|
+
* async discoverParameters(config) {
|
|
72
|
+
* // Discover GCP Secret Manager secrets
|
|
73
|
+
* // ... implementation
|
|
74
|
+
* }
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* module.exports = { GCPProviderAdapter };
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
// Placeholder export to prevent import errors
|
|
81
|
+
module.exports = {};
|
|
82
|
+
|