@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,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview App definition types
|
|
3
|
+
*
|
|
4
|
+
* Defines the structure of the application definition with new ownership-based schema.
|
|
5
|
+
* This replaces the old 'management' mode system.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* VPC configuration
|
|
10
|
+
* @typedef {Object} VpcDefinition
|
|
11
|
+
* @property {boolean} enable - Whether VPC is enabled
|
|
12
|
+
*
|
|
13
|
+
* @property {Object} [ownership] - Resource ownership configuration
|
|
14
|
+
* @property {'stack'|'external'|'auto'} [ownership.vpc] - VPC ownership
|
|
15
|
+
* @property {'stack'|'external'|'auto'} [ownership.securityGroup] - Security group ownership
|
|
16
|
+
* @property {'stack'|'external'|'auto'} [ownership.subnets] - Subnets ownership
|
|
17
|
+
* @property {'stack'|'external'|'auto'} [ownership.natGateway] - NAT gateway ownership
|
|
18
|
+
* @property {'stack'|'external'|'auto'} [ownership.vpcEndpoints] - VPC endpoints ownership
|
|
19
|
+
*
|
|
20
|
+
* @property {Object} [external] - External resource references (required if ownership='external')
|
|
21
|
+
* @property {string} [external.vpcId] - External VPC ID
|
|
22
|
+
* @property {string[]} [external.securityGroupIds] - External security group IDs
|
|
23
|
+
* @property {string[]} [external.subnetIds] - External subnet IDs
|
|
24
|
+
* @property {string} [external.natGatewayId] - External NAT gateway ID
|
|
25
|
+
* @property {Object} [external.vpcEndpointIds] - External VPC endpoint IDs
|
|
26
|
+
* @property {string} [external.vpcEndpointIds.s3] - S3 endpoint ID
|
|
27
|
+
* @property {string} [external.vpcEndpointIds.dynamodb] - DynamoDB endpoint ID
|
|
28
|
+
* @property {string} [external.vpcEndpointIds.kms] - KMS endpoint ID
|
|
29
|
+
* @property {string} [external.vpcEndpointIds.secretsManager] - Secrets Manager endpoint ID
|
|
30
|
+
* @property {string} [external.vpcEndpointIds.sqs] - SQS endpoint ID
|
|
31
|
+
*
|
|
32
|
+
* @property {Object} [config] - Configuration preferences
|
|
33
|
+
* @property {boolean} [config.selfHeal] - Auto-configure NAT/routes/etc (default: false)
|
|
34
|
+
* @property {string} [config.cidrBlock] - CIDR block for stack-owned VPC (default: '10.0.0.0/16')
|
|
35
|
+
* @property {boolean} [config.enableVpcEndpoints] - Enable VPC endpoints (default: true)
|
|
36
|
+
* @property {Object} [config.natGateway] - NAT Gateway configuration
|
|
37
|
+
* @property {boolean} [config.natGateway.enable] - Enable NAT Gateway (default: true)
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Aurora PostgreSQL configuration
|
|
42
|
+
* @typedef {Object} AuroraDefinition
|
|
43
|
+
* @property {boolean} enable - Whether Aurora is enabled
|
|
44
|
+
*
|
|
45
|
+
* @property {Object} [ownership] - Resource ownership configuration
|
|
46
|
+
* @property {'stack'|'external'|'auto'} [ownership.cluster] - Aurora cluster ownership
|
|
47
|
+
* @property {'stack'|'external'|'auto'} [ownership.subnetGroup] - DB subnet group ownership
|
|
48
|
+
* @property {'stack'|'external'|'auto'} [ownership.secret] - Secrets Manager secret ownership
|
|
49
|
+
*
|
|
50
|
+
* @property {Object} [external] - External resource references
|
|
51
|
+
* @property {string} [external.clusterId] - External cluster identifier
|
|
52
|
+
* @property {string} [external.clusterEndpoint] - External cluster endpoint
|
|
53
|
+
* @property {number} [external.port] - External cluster port
|
|
54
|
+
* @property {string} [external.secretArn] - External Secrets Manager ARN
|
|
55
|
+
*
|
|
56
|
+
* @property {Object} [config] - Configuration preferences
|
|
57
|
+
* @property {'aurora-postgresql'|'aurora-mysql'} [config.engine] - Database engine
|
|
58
|
+
* @property {number} [config.minCapacity] - Min serverless capacity (default: 0.5)
|
|
59
|
+
* @property {number} [config.maxCapacity] - Max serverless capacity (default: 1)
|
|
60
|
+
* @property {string} [config.database] - Database name (default: 'frigg')
|
|
61
|
+
* @property {boolean} [config.publiclyAccessible] - Public access (default: false)
|
|
62
|
+
* @property {boolean} [config.autoCreateCredentials] - Auto-create credentials in Secrets Manager
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* KMS encryption configuration
|
|
67
|
+
* @typedef {Object} KmsDefinition
|
|
68
|
+
* @property {boolean} enable - Whether KMS is enabled
|
|
69
|
+
*
|
|
70
|
+
* @property {Object} [ownership] - Resource ownership configuration
|
|
71
|
+
* @property {'stack'|'external'|'auto'} [ownership.key] - KMS key ownership
|
|
72
|
+
*
|
|
73
|
+
* @property {Object} [external] - External resource references
|
|
74
|
+
* @property {string} [external.keyId] - External KMS key ID or ARN
|
|
75
|
+
* @property {string} [external.keyAlias] - External KMS key alias
|
|
76
|
+
*
|
|
77
|
+
* @property {Object} [config] - Configuration preferences
|
|
78
|
+
* @property {boolean} [config.enableKeyRotation] - Enable automatic key rotation
|
|
79
|
+
* @property {string} [config.description] - Key description
|
|
80
|
+
*/
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* SSM Parameter Store configuration
|
|
84
|
+
* @typedef {Object} SsmDefinition
|
|
85
|
+
* @property {boolean} enable - Whether SSM is enabled
|
|
86
|
+
* @property {string[]} [parameterPaths] - Parameter paths to grant access to
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Database migration configuration
|
|
91
|
+
* @typedef {Object} MigrationDefinition
|
|
92
|
+
* @property {boolean} enable - Whether migrations are enabled
|
|
93
|
+
* @property {string} [migrationPath] - Path to migration files
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* WebSocket configuration
|
|
98
|
+
* @typedef {Object} WebsocketDefinition
|
|
99
|
+
* @property {boolean} enable - Whether WebSocket API is enabled
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Integration configuration
|
|
104
|
+
* @typedef {Object} IntegrationDefinition
|
|
105
|
+
* @property {Object} Definition - Integration definition object
|
|
106
|
+
* @property {string} Definition.name - Integration name
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Complete application definition
|
|
111
|
+
* @typedef {Object} AppDefinition
|
|
112
|
+
* @property {string} name - Application name
|
|
113
|
+
* @property {string} stage - Deployment stage (e.g., 'dev', 'production')
|
|
114
|
+
* @property {string} provider - Cloud provider (e.g., 'aws')
|
|
115
|
+
* @property {string} region - AWS region
|
|
116
|
+
*
|
|
117
|
+
* @property {VpcDefinition} [vpc] - VPC configuration
|
|
118
|
+
* @property {Object} [database] - Database configuration
|
|
119
|
+
* @property {AuroraDefinition} [database.postgres] - PostgreSQL configuration
|
|
120
|
+
* @property {KmsDefinition} [encryption] - KMS encryption configuration
|
|
121
|
+
* @property {SsmDefinition} [ssm] - SSM Parameter Store configuration
|
|
122
|
+
* @property {MigrationDefinition} [migrations] - Database migration configuration
|
|
123
|
+
* @property {WebsocketDefinition} [websockets] - WebSocket API configuration
|
|
124
|
+
* @property {IntegrationDefinition[]} [integrations] - Integration definitions
|
|
125
|
+
*
|
|
126
|
+
* @property {Object} [environment] - Environment variables
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Validate app definition has required fields
|
|
131
|
+
* @param {AppDefinition} appDefinition - App definition to validate
|
|
132
|
+
* @throws {Error} If required fields are missing
|
|
133
|
+
*/
|
|
134
|
+
function validateAppDefinition(appDefinition) {
|
|
135
|
+
if (!appDefinition) {
|
|
136
|
+
throw new Error('App definition is required');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!appDefinition.name) {
|
|
140
|
+
throw new Error('App definition must have a name');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!appDefinition.provider) {
|
|
144
|
+
throw new Error('App definition must have a provider');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (!appDefinition.region) {
|
|
148
|
+
throw new Error('App definition must have a region');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Get stack name from app definition
|
|
154
|
+
* @param {AppDefinition} appDefinition - App definition
|
|
155
|
+
* @returns {string} Stack name
|
|
156
|
+
*/
|
|
157
|
+
function getStackName(appDefinition) {
|
|
158
|
+
const stage = appDefinition.stage || 'dev';
|
|
159
|
+
return `${appDefinition.name}-${stage}`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Check if VPC is enabled
|
|
164
|
+
* @param {AppDefinition} appDefinition - App definition
|
|
165
|
+
* @returns {boolean}
|
|
166
|
+
*/
|
|
167
|
+
function isVpcEnabled(appDefinition) {
|
|
168
|
+
return appDefinition.vpc?.enable === true;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Check if Aurora is enabled
|
|
173
|
+
* @param {AppDefinition} appDefinition - App definition
|
|
174
|
+
* @returns {boolean}
|
|
175
|
+
*/
|
|
176
|
+
function isAuroraEnabled(appDefinition) {
|
|
177
|
+
return appDefinition.database?.postgres?.enable === true;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Check if KMS is enabled
|
|
182
|
+
* @param {AppDefinition} appDefinition - App definition
|
|
183
|
+
* @returns {boolean}
|
|
184
|
+
*/
|
|
185
|
+
function isKmsEnabled(appDefinition) {
|
|
186
|
+
return appDefinition.encryption?.enable === true;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Check if SSM is enabled
|
|
191
|
+
* @param {AppDefinition} appDefinition - App definition
|
|
192
|
+
* @returns {boolean}
|
|
193
|
+
*/
|
|
194
|
+
function isSsmEnabled(appDefinition) {
|
|
195
|
+
return appDefinition.ssm?.enable === true;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
module.exports = {
|
|
199
|
+
validateAppDefinition,
|
|
200
|
+
getStackName,
|
|
201
|
+
isVpcEnabled,
|
|
202
|
+
isAuroraEnabled,
|
|
203
|
+
isKmsEnabled,
|
|
204
|
+
isSsmEnabled
|
|
205
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Discovery result types
|
|
3
|
+
*
|
|
4
|
+
* Defines the structure of resource discovery results.
|
|
5
|
+
* Discovery reports FACTS - it doesn't make ownership decisions.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resource that exists in our CloudFormation stack
|
|
10
|
+
* @typedef {Object} StackManagedResource
|
|
11
|
+
* @property {string} logicalId - CloudFormation logical resource ID (e.g., 'FriggLambdaSecurityGroup')
|
|
12
|
+
* @property {string} physicalId - AWS physical resource ID (e.g., 'sg-069629001ade41c9a')
|
|
13
|
+
* @property {string} resourceType - CloudFormation resource type (e.g., 'AWS::EC2::SecurityGroup')
|
|
14
|
+
* @property {Object} [properties] - Resource properties (optional, for detailed info)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Resource that exists outside our CloudFormation stack
|
|
19
|
+
* @typedef {Object} ExternalResource
|
|
20
|
+
* @property {string} physicalId - AWS physical resource ID
|
|
21
|
+
* @property {string} resourceType - CloudFormation resource type
|
|
22
|
+
* @property {'tag-search' | 'name-search' | 'aws-api' | 'user-provided'} source - How it was discovered
|
|
23
|
+
* @property {Object} [properties] - Resource properties (optional)
|
|
24
|
+
* @property {Object} [tags] - Resource tags (if available)
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Complete discovery result
|
|
29
|
+
* @typedef {Object} DiscoveryResult
|
|
30
|
+
* @property {StackManagedResource[]} stackManaged - Resources in OUR CloudFormation stack
|
|
31
|
+
* @property {ExternalResource[]} external - Resources outside our stack
|
|
32
|
+
* @property {string} [stackName] - Name of our CloudFormation stack (if exists)
|
|
33
|
+
* @property {boolean} fromCloudFormation - Whether stack was found in CloudFormation
|
|
34
|
+
* @property {string} [region] - AWS region
|
|
35
|
+
* @property {Object} [metadata] - Additional discovery metadata
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Create empty discovery result
|
|
40
|
+
* @returns {DiscoveryResult}
|
|
41
|
+
*/
|
|
42
|
+
function createEmptyDiscoveryResult() {
|
|
43
|
+
return {
|
|
44
|
+
stackManaged: [],
|
|
45
|
+
external: [],
|
|
46
|
+
fromCloudFormation: false
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Find stack-managed resource by logical ID
|
|
52
|
+
* @param {DiscoveryResult} discovery - Discovery result
|
|
53
|
+
* @param {string} logicalId - Logical resource ID to find
|
|
54
|
+
* @returns {StackManagedResource|null}
|
|
55
|
+
*/
|
|
56
|
+
function findStackResource(discovery, logicalId) {
|
|
57
|
+
return discovery.stackManaged.find(r => r.logicalId === logicalId) || null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Find external resource by type
|
|
62
|
+
* @param {DiscoveryResult} discovery - Discovery result
|
|
63
|
+
* @param {string} resourceType - CloudFormation resource type
|
|
64
|
+
* @returns {ExternalResource|null}
|
|
65
|
+
*/
|
|
66
|
+
function findExternalResource(discovery, resourceType) {
|
|
67
|
+
return discovery.external.find(r => r.resourceType === resourceType) || null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Find all external resources by type
|
|
72
|
+
* @param {DiscoveryResult} discovery - Discovery result
|
|
73
|
+
* @param {string} resourceType - CloudFormation resource type
|
|
74
|
+
* @returns {ExternalResource[]}
|
|
75
|
+
*/
|
|
76
|
+
function findAllExternalResources(discovery, resourceType) {
|
|
77
|
+
return discovery.external.filter(r => r.resourceType === resourceType);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Check if specific resource exists in stack
|
|
82
|
+
* @param {DiscoveryResult} discovery - Discovery result
|
|
83
|
+
* @param {string} logicalId - Logical resource ID
|
|
84
|
+
* @returns {boolean}
|
|
85
|
+
*/
|
|
86
|
+
function isResourceInStack(discovery, logicalId) {
|
|
87
|
+
return discovery.stackManaged.some(r => r.logicalId === logicalId);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get all stack logical IDs
|
|
92
|
+
* @param {DiscoveryResult} discovery - Discovery result
|
|
93
|
+
* @returns {string[]}
|
|
94
|
+
*/
|
|
95
|
+
function getStackLogicalIds(discovery) {
|
|
96
|
+
return discovery.stackManaged.map(r => r.logicalId);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = {
|
|
100
|
+
createEmptyDiscoveryResult,
|
|
101
|
+
findStackResource,
|
|
102
|
+
findExternalResource,
|
|
103
|
+
findAllExternalResources,
|
|
104
|
+
isResourceInStack,
|
|
105
|
+
getStackLogicalIds
|
|
106
|
+
};
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
const {
|
|
2
|
+
createEmptyDiscoveryResult,
|
|
3
|
+
findStackResource,
|
|
4
|
+
findExternalResource,
|
|
5
|
+
findAllExternalResources,
|
|
6
|
+
isResourceInStack,
|
|
7
|
+
getStackLogicalIds
|
|
8
|
+
} = require('./discovery-result');
|
|
9
|
+
|
|
10
|
+
describe('Discovery Result Utilities', () => {
|
|
11
|
+
describe('createEmptyDiscoveryResult', () => {
|
|
12
|
+
it('should create empty discovery result with correct structure', () => {
|
|
13
|
+
const result = createEmptyDiscoveryResult();
|
|
14
|
+
|
|
15
|
+
expect(result).toEqual({
|
|
16
|
+
stackManaged: [],
|
|
17
|
+
external: [],
|
|
18
|
+
fromCloudFormation: false
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('findStackResource', () => {
|
|
24
|
+
it('should find resource by logical ID', () => {
|
|
25
|
+
const discovery = {
|
|
26
|
+
stackManaged: [
|
|
27
|
+
{ logicalId: 'FriggVPC', physicalId: 'vpc-123', resourceType: 'AWS::EC2::VPC' },
|
|
28
|
+
{ logicalId: 'FriggLambdaSecurityGroup', physicalId: 'sg-456', resourceType: 'AWS::EC2::SecurityGroup' }
|
|
29
|
+
],
|
|
30
|
+
external: [],
|
|
31
|
+
fromCloudFormation: true
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const found = findStackResource(discovery, 'FriggLambdaSecurityGroup');
|
|
35
|
+
|
|
36
|
+
expect(found).toEqual({
|
|
37
|
+
logicalId: 'FriggLambdaSecurityGroup',
|
|
38
|
+
physicalId: 'sg-456',
|
|
39
|
+
resourceType: 'AWS::EC2::SecurityGroup'
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should return null if resource not found', () => {
|
|
44
|
+
const discovery = {
|
|
45
|
+
stackManaged: [
|
|
46
|
+
{ logicalId: 'FriggVPC', physicalId: 'vpc-123', resourceType: 'AWS::EC2::VPC' }
|
|
47
|
+
],
|
|
48
|
+
external: [],
|
|
49
|
+
fromCloudFormation: true
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const found = findStackResource(discovery, 'NonExistent');
|
|
53
|
+
|
|
54
|
+
expect(found).toBeNull();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should return null for empty stack managed resources', () => {
|
|
58
|
+
const discovery = createEmptyDiscoveryResult();
|
|
59
|
+
const found = findStackResource(discovery, 'FriggVPC');
|
|
60
|
+
|
|
61
|
+
expect(found).toBeNull();
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('findExternalResource', () => {
|
|
66
|
+
it('should find external resource by type', () => {
|
|
67
|
+
const discovery = {
|
|
68
|
+
stackManaged: [],
|
|
69
|
+
external: [
|
|
70
|
+
{ physicalId: 'vpc-external', resourceType: 'AWS::EC2::VPC', source: 'tag-search' },
|
|
71
|
+
{ physicalId: 'sg-external', resourceType: 'AWS::EC2::SecurityGroup', source: 'tag-search' }
|
|
72
|
+
],
|
|
73
|
+
fromCloudFormation: false
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const found = findExternalResource(discovery, 'AWS::EC2::SecurityGroup');
|
|
77
|
+
|
|
78
|
+
expect(found).toEqual({
|
|
79
|
+
physicalId: 'sg-external',
|
|
80
|
+
resourceType: 'AWS::EC2::SecurityGroup',
|
|
81
|
+
source: 'tag-search'
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should return null if external resource not found', () => {
|
|
86
|
+
const discovery = createEmptyDiscoveryResult();
|
|
87
|
+
const found = findExternalResource(discovery, 'AWS::EC2::VPC');
|
|
88
|
+
|
|
89
|
+
expect(found).toBeNull();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should return first match if multiple resources of same type', () => {
|
|
93
|
+
const discovery = {
|
|
94
|
+
stackManaged: [],
|
|
95
|
+
external: [
|
|
96
|
+
{ physicalId: 'subnet-1', resourceType: 'AWS::EC2::Subnet', source: 'tag-search' },
|
|
97
|
+
{ physicalId: 'subnet-2', resourceType: 'AWS::EC2::Subnet', source: 'tag-search' }
|
|
98
|
+
],
|
|
99
|
+
fromCloudFormation: false
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const found = findExternalResource(discovery, 'AWS::EC2::Subnet');
|
|
103
|
+
|
|
104
|
+
expect(found.physicalId).toBe('subnet-1');
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('findAllExternalResources', () => {
|
|
109
|
+
it('should find all external resources of given type', () => {
|
|
110
|
+
const discovery = {
|
|
111
|
+
stackManaged: [],
|
|
112
|
+
external: [
|
|
113
|
+
{ physicalId: 'subnet-1', resourceType: 'AWS::EC2::Subnet', source: 'tag-search' },
|
|
114
|
+
{ physicalId: 'subnet-2', resourceType: 'AWS::EC2::Subnet', source: 'tag-search' },
|
|
115
|
+
{ physicalId: 'sg-1', resourceType: 'AWS::EC2::SecurityGroup', source: 'tag-search' }
|
|
116
|
+
],
|
|
117
|
+
fromCloudFormation: false
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const found = findAllExternalResources(discovery, 'AWS::EC2::Subnet');
|
|
121
|
+
|
|
122
|
+
expect(found).toHaveLength(2);
|
|
123
|
+
expect(found[0].physicalId).toBe('subnet-1');
|
|
124
|
+
expect(found[1].physicalId).toBe('subnet-2');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should return empty array if no resources found', () => {
|
|
128
|
+
const discovery = createEmptyDiscoveryResult();
|
|
129
|
+
const found = findAllExternalResources(discovery, 'AWS::EC2::VPC');
|
|
130
|
+
|
|
131
|
+
expect(found).toEqual([]);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('isResourceInStack', () => {
|
|
136
|
+
it('should return true if resource is in stack', () => {
|
|
137
|
+
const discovery = {
|
|
138
|
+
stackManaged: [
|
|
139
|
+
{ logicalId: 'FriggVPC', physicalId: 'vpc-123', resourceType: 'AWS::EC2::VPC' },
|
|
140
|
+
{ logicalId: 'FriggLambdaSecurityGroup', physicalId: 'sg-456', resourceType: 'AWS::EC2::SecurityGroup' }
|
|
141
|
+
],
|
|
142
|
+
external: [],
|
|
143
|
+
fromCloudFormation: true
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
expect(isResourceInStack(discovery, 'FriggVPC')).toBe(true);
|
|
147
|
+
expect(isResourceInStack(discovery, 'FriggLambdaSecurityGroup')).toBe(true);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('should return false if resource is not in stack', () => {
|
|
151
|
+
const discovery = {
|
|
152
|
+
stackManaged: [
|
|
153
|
+
{ logicalId: 'FriggVPC', physicalId: 'vpc-123', resourceType: 'AWS::EC2::VPC' }
|
|
154
|
+
],
|
|
155
|
+
external: [],
|
|
156
|
+
fromCloudFormation: true
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
expect(isResourceInStack(discovery, 'NonExistent')).toBe(false);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should return false for empty stack', () => {
|
|
163
|
+
const discovery = createEmptyDiscoveryResult();
|
|
164
|
+
|
|
165
|
+
expect(isResourceInStack(discovery, 'FriggVPC')).toBe(false);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('getStackLogicalIds', () => {
|
|
170
|
+
it('should return all logical IDs from stack', () => {
|
|
171
|
+
const discovery = {
|
|
172
|
+
stackManaged: [
|
|
173
|
+
{ logicalId: 'FriggVPC', physicalId: 'vpc-123', resourceType: 'AWS::EC2::VPC' },
|
|
174
|
+
{ logicalId: 'FriggLambdaSecurityGroup', physicalId: 'sg-456', resourceType: 'AWS::EC2::SecurityGroup' },
|
|
175
|
+
{ logicalId: 'FriggAuroraCluster', physicalId: 'cluster-789', resourceType: 'AWS::RDS::DBCluster' }
|
|
176
|
+
],
|
|
177
|
+
external: [],
|
|
178
|
+
fromCloudFormation: true
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const ids = getStackLogicalIds(discovery);
|
|
182
|
+
|
|
183
|
+
expect(ids).toEqual([
|
|
184
|
+
'FriggVPC',
|
|
185
|
+
'FriggLambdaSecurityGroup',
|
|
186
|
+
'FriggAuroraCluster'
|
|
187
|
+
]);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should return empty array for empty stack', () => {
|
|
191
|
+
const discovery = createEmptyDiscoveryResult();
|
|
192
|
+
const ids = getStackLogicalIds(discovery);
|
|
193
|
+
|
|
194
|
+
expect(ids).toEqual([]);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
describe('real-world scenarios', () => {
|
|
199
|
+
it('scenario: fresh deploy, no stack exists', () => {
|
|
200
|
+
const discovery = createEmptyDiscoveryResult();
|
|
201
|
+
|
|
202
|
+
expect(discovery.fromCloudFormation).toBe(false);
|
|
203
|
+
expect(discovery.stackManaged).toHaveLength(0);
|
|
204
|
+
expect(discovery.external).toHaveLength(0);
|
|
205
|
+
|
|
206
|
+
expect(isResourceInStack(discovery, 'FriggVPC')).toBe(false);
|
|
207
|
+
expect(findStackResource(discovery, 'FriggVPC')).toBeNull();
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('scenario: redeploy existing stack', () => {
|
|
211
|
+
const discovery = {
|
|
212
|
+
stackManaged: [
|
|
213
|
+
{ logicalId: 'FriggVPC', physicalId: 'vpc-123', resourceType: 'AWS::EC2::VPC' },
|
|
214
|
+
{ logicalId: 'FriggLambdaSecurityGroup', physicalId: 'sg-069629001ade41c9a', resourceType: 'AWS::EC2::SecurityGroup' },
|
|
215
|
+
{ logicalId: 'FriggPrivateSubnet1', physicalId: 'subnet-1', resourceType: 'AWS::EC2::Subnet' },
|
|
216
|
+
{ logicalId: 'FriggPrivateSubnet2', physicalId: 'subnet-2', resourceType: 'AWS::EC2::Subnet' },
|
|
217
|
+
{ logicalId: 'FriggAuroraCluster', physicalId: 'cluster-abc', resourceType: 'AWS::RDS::DBCluster' },
|
|
218
|
+
{ logicalId: 'FriggKMSKey', physicalId: 'key-xyz', resourceType: 'AWS::KMS::Key' }
|
|
219
|
+
],
|
|
220
|
+
external: [],
|
|
221
|
+
fromCloudFormation: true,
|
|
222
|
+
stackName: 'create-frigg-app-production'
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
expect(discovery.fromCloudFormation).toBe(true);
|
|
226
|
+
expect(discovery.stackManaged).toHaveLength(6);
|
|
227
|
+
|
|
228
|
+
// All these resources are in stack - MUST be kept in template
|
|
229
|
+
expect(isResourceInStack(discovery, 'FriggLambdaSecurityGroup')).toBe(true);
|
|
230
|
+
expect(isResourceInStack(discovery, 'FriggAuroraCluster')).toBe(true);
|
|
231
|
+
|
|
232
|
+
const sg = findStackResource(discovery, 'FriggLambdaSecurityGroup');
|
|
233
|
+
expect(sg.physicalId).toBe('sg-069629001ade41c9a');
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it('scenario: use external VPC with stack-managed resources', () => {
|
|
237
|
+
const discovery = {
|
|
238
|
+
stackManaged: [
|
|
239
|
+
{ logicalId: 'FriggLambdaSecurityGroup', physicalId: 'sg-456', resourceType: 'AWS::EC2::SecurityGroup' },
|
|
240
|
+
{ logicalId: 'FriggPrivateSubnet1', physicalId: 'subnet-1', resourceType: 'AWS::EC2::Subnet' }
|
|
241
|
+
],
|
|
242
|
+
external: [
|
|
243
|
+
{ physicalId: 'vpc-external', resourceType: 'AWS::EC2::VPC', source: 'user-provided' }
|
|
244
|
+
],
|
|
245
|
+
fromCloudFormation: true,
|
|
246
|
+
stackName: 'my-app-dev'
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// VPC is external - should NOT be in template
|
|
250
|
+
expect(isResourceInStack(discovery, 'FriggVPC')).toBe(false);
|
|
251
|
+
const externalVpc = findExternalResource(discovery, 'AWS::EC2::VPC');
|
|
252
|
+
expect(externalVpc.physicalId).toBe('vpc-external');
|
|
253
|
+
|
|
254
|
+
// But security group IS in stack - MUST be in template
|
|
255
|
+
expect(isResourceInStack(discovery, 'FriggLambdaSecurityGroup')).toBe(true);
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Central export for all infrastructure types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { ResourceOwnership, validateOwnership, resolveOwnership } = require('./resource-ownership');
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
createEmptyDiscoveryResult,
|
|
9
|
+
findStackResource,
|
|
10
|
+
findExternalResource,
|
|
11
|
+
findAllExternalResources,
|
|
12
|
+
isResourceInStack,
|
|
13
|
+
getStackLogicalIds
|
|
14
|
+
} = require('./discovery-result');
|
|
15
|
+
|
|
16
|
+
const {
|
|
17
|
+
validateAppDefinition,
|
|
18
|
+
getStackName,
|
|
19
|
+
isVpcEnabled,
|
|
20
|
+
isAuroraEnabled,
|
|
21
|
+
isKmsEnabled,
|
|
22
|
+
isSsmEnabled
|
|
23
|
+
} = require('./app-definition');
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
// Resource Ownership
|
|
27
|
+
ResourceOwnership,
|
|
28
|
+
validateOwnership,
|
|
29
|
+
resolveOwnership,
|
|
30
|
+
|
|
31
|
+
// Discovery Result
|
|
32
|
+
createEmptyDiscoveryResult,
|
|
33
|
+
findStackResource,
|
|
34
|
+
findExternalResource,
|
|
35
|
+
findAllExternalResources,
|
|
36
|
+
isResourceInStack,
|
|
37
|
+
getStackLogicalIds,
|
|
38
|
+
|
|
39
|
+
// App Definition
|
|
40
|
+
validateAppDefinition,
|
|
41
|
+
getStackName,
|
|
42
|
+
isVpcEnabled,
|
|
43
|
+
isAuroraEnabled,
|
|
44
|
+
isKmsEnabled,
|
|
45
|
+
isSsmEnabled
|
|
46
|
+
};
|