@friggframework/devtools 2.0.0--canary.461.b62a157.0 → 2.0.0--canary.461.b4ab96e.0
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.
|
@@ -83,36 +83,7 @@ class AuroraBuilder extends InfrastructureBuilder {
|
|
|
83
83
|
console.log(`\n[${this.name}] Configuring Aurora PostgreSQL...`);
|
|
84
84
|
|
|
85
85
|
const dbConfig = appDefinition.database.postgres;
|
|
86
|
-
|
|
87
|
-
// Normalize top-level managementMode
|
|
88
|
-
const globalMode = appDefinition.managementMode || 'discover';
|
|
89
|
-
const vpcIsolation = appDefinition.vpcIsolation || 'shared';
|
|
90
|
-
|
|
91
|
-
let management = dbConfig.management;
|
|
92
|
-
|
|
93
|
-
if (globalMode === 'managed') {
|
|
94
|
-
// Warn about ignored granular options
|
|
95
|
-
if (dbConfig.management) {
|
|
96
|
-
console.log(` ⚠️ managementMode='managed' ignoring: database.postgres.management`);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Clear granular option to prevent conflicts
|
|
100
|
-
delete appDefinition.database.postgres.management;
|
|
101
|
-
|
|
102
|
-
// Set management based on isolation strategy
|
|
103
|
-
if (vpcIsolation === 'isolated') {
|
|
104
|
-
management = 'managed'; // New VPC = new Aurora
|
|
105
|
-
console.log(` managementMode='managed' + vpcIsolation='isolated' → creating new Aurora`);
|
|
106
|
-
} else {
|
|
107
|
-
management = 'discover'; // Shared VPC = reuse Aurora
|
|
108
|
-
appDefinition.database.postgres.autoCreateCredentials = true;
|
|
109
|
-
console.log(` managementMode='managed' + vpcIsolation='shared' → discovering Aurora`);
|
|
110
|
-
}
|
|
111
|
-
} else if (globalMode === 'existing') {
|
|
112
|
-
management = 'existing';
|
|
113
|
-
} else {
|
|
114
|
-
management = management || 'discover';
|
|
115
|
-
}
|
|
86
|
+
const management = dbConfig.management || 'discover';
|
|
116
87
|
|
|
117
88
|
console.log(` PostgreSQL Management Mode: ${management}`);
|
|
118
89
|
|
|
@@ -683,12 +683,61 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
683
683
|
},
|
|
684
684
|
};
|
|
685
685
|
|
|
686
|
-
// Create routing
|
|
686
|
+
// Create public routing (public subnets → Internet Gateway)
|
|
687
|
+
this.createPublicRouting(appDefinition, result);
|
|
688
|
+
|
|
689
|
+
// Create routing for the new NAT Gateway (private subnets → NAT → IGW)
|
|
687
690
|
this.createNatGatewayRouting(appDefinition, discoveredResources, result, { Ref: 'FriggNATGateway' });
|
|
688
691
|
|
|
689
692
|
console.log(' ✅ NAT Gateway infrastructure created');
|
|
690
693
|
}
|
|
691
694
|
|
|
695
|
+
/**
|
|
696
|
+
* Create public route table with Internet Gateway route
|
|
697
|
+
* Required for NAT Gateway to have internet access
|
|
698
|
+
*/
|
|
699
|
+
createPublicRouting(appDefinition, result) {
|
|
700
|
+
// Public route table with Internet Gateway route
|
|
701
|
+
result.resources.FriggPublicRouteTable = {
|
|
702
|
+
Type: 'AWS::EC2::RouteTable',
|
|
703
|
+
Properties: {
|
|
704
|
+
VpcId: result.vpcId,
|
|
705
|
+
Tags: [
|
|
706
|
+
{ Key: 'Name', Value: '${self:service}-${self:provider.stage}-public-rt' },
|
|
707
|
+
{ Key: 'ManagedBy', Value: 'Frigg' },
|
|
708
|
+
],
|
|
709
|
+
},
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
// Route to Internet Gateway
|
|
713
|
+
result.resources.FriggPublicRoute = {
|
|
714
|
+
Type: 'AWS::EC2::Route',
|
|
715
|
+
DependsOn: 'FriggVPCGatewayAttachment',
|
|
716
|
+
Properties: {
|
|
717
|
+
RouteTableId: { Ref: 'FriggPublicRouteTable' },
|
|
718
|
+
DestinationCidrBlock: '0.0.0.0/0',
|
|
719
|
+
GatewayId: { Ref: 'FriggInternetGateway' },
|
|
720
|
+
},
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
// Associate public subnets with public route table
|
|
724
|
+
result.resources.FriggPublicSubnet1RouteTableAssociation = {
|
|
725
|
+
Type: 'AWS::EC2::SubnetRouteTableAssociation',
|
|
726
|
+
Properties: {
|
|
727
|
+
SubnetId: { Ref: 'FriggPublicSubnet' },
|
|
728
|
+
RouteTableId: { Ref: 'FriggPublicRouteTable' },
|
|
729
|
+
},
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
result.resources.FriggPublicSubnet2RouteTableAssociation = {
|
|
733
|
+
Type: 'AWS::EC2::SubnetRouteTableAssociation',
|
|
734
|
+
Properties: {
|
|
735
|
+
SubnetId: { Ref: 'FriggPublicSubnet2' },
|
|
736
|
+
RouteTableId: { Ref: 'FriggPublicRouteTable' },
|
|
737
|
+
},
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
|
|
692
741
|
/**
|
|
693
742
|
* Create route table and associations for NAT Gateway
|
|
694
743
|
*/
|
|
@@ -432,21 +432,18 @@ describe('Resource Discovery', () => {
|
|
|
432
432
|
|
|
433
433
|
// Should return empty (no discovery)
|
|
434
434
|
expect(result).toEqual({});
|
|
435
|
-
|
|
435
|
+
|
|
436
436
|
// Should NOT call AWS API discovery
|
|
437
437
|
expect(mockVpcDiscovery.discover).not.toHaveBeenCalled();
|
|
438
438
|
expect(mockAuroraDiscovery.discover).not.toHaveBeenCalled();
|
|
439
439
|
});
|
|
440
440
|
|
|
441
|
-
it('should
|
|
441
|
+
it('should return empty in isolated mode even if stack exists (fresh creation)', async () => {
|
|
442
442
|
const { CloudFormationDiscovery } = require('./cloudformation-discovery');
|
|
443
|
-
const mockCfDiscover = jest.fn().mockResolvedValue({
|
|
444
|
-
defaultVpcId: 'vpc-stage-specific',
|
|
445
|
-
auroraClusterId: 'cluster-stage-specific',
|
|
446
|
-
});
|
|
447
443
|
|
|
444
|
+
// Mock that CF stack exists but we still want fresh resources
|
|
448
445
|
CloudFormationDiscovery.mockImplementation(() => ({
|
|
449
|
-
discoverFromStack:
|
|
446
|
+
discoverFromStack: jest.fn().mockResolvedValue({}), // Stack exists but empty
|
|
450
447
|
}));
|
|
451
448
|
|
|
452
449
|
const appDefinition = {
|
|
@@ -460,11 +457,12 @@ describe('Resource Discovery', () => {
|
|
|
460
457
|
|
|
461
458
|
const result = await gatherDiscoveredResources(appDefinition);
|
|
462
459
|
|
|
463
|
-
//
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
460
|
+
// In isolated mode, always return empty to force fresh creation
|
|
461
|
+
// This prevents any cross-stage resource reuse
|
|
462
|
+
expect(result).toEqual({});
|
|
463
|
+
|
|
464
|
+
// Should NOT call AWS API discovery
|
|
465
|
+
expect(mockVpcDiscovery.discover).not.toHaveBeenCalled();
|
|
468
466
|
});
|
|
469
467
|
|
|
470
468
|
it('should use AWS API discovery in shared mode', async () => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/devtools",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0--canary.461.
|
|
4
|
+
"version": "2.0.0--canary.461.b4ab96e.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@aws-sdk/client-ec2": "^3.835.0",
|
|
7
7
|
"@aws-sdk/client-kms": "^3.835.0",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"@babel/eslint-parser": "^7.18.9",
|
|
12
12
|
"@babel/parser": "^7.25.3",
|
|
13
13
|
"@babel/traverse": "^7.25.3",
|
|
14
|
-
"@friggframework/schemas": "2.0.0--canary.461.
|
|
15
|
-
"@friggframework/test": "2.0.0--canary.461.
|
|
14
|
+
"@friggframework/schemas": "2.0.0--canary.461.b4ab96e.0",
|
|
15
|
+
"@friggframework/test": "2.0.0--canary.461.b4ab96e.0",
|
|
16
16
|
"@hapi/boom": "^10.0.1",
|
|
17
17
|
"@inquirer/prompts": "^5.3.8",
|
|
18
18
|
"axios": "^1.7.2",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"serverless-http": "^2.7.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@friggframework/eslint-config": "2.0.0--canary.461.
|
|
38
|
-
"@friggframework/prettier-config": "2.0.0--canary.461.
|
|
37
|
+
"@friggframework/eslint-config": "2.0.0--canary.461.b4ab96e.0",
|
|
38
|
+
"@friggframework/prettier-config": "2.0.0--canary.461.b4ab96e.0",
|
|
39
39
|
"aws-sdk-client-mock": "^4.1.0",
|
|
40
40
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
41
41
|
"jest": "^30.1.3",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "b4ab96e66e22c1d48bbd77bc48374b4df6c7fb0a"
|
|
74
74
|
}
|