@friggframework/devtools 2.0.0--canary.490.36b3031.0 → 2.0.0--canary.490.6e556a4.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.
|
@@ -1348,18 +1348,19 @@ describe('VpcBuilder', () => {
|
|
|
1348
1348
|
});
|
|
1349
1349
|
});
|
|
1350
1350
|
|
|
1351
|
-
describe('
|
|
1352
|
-
it('should correctly handle
|
|
1353
|
-
// This
|
|
1351
|
+
describe('External VPC with stack-managed routing infrastructure pattern', () => {
|
|
1352
|
+
it('should correctly handle external VPC with stack-managed routing infrastructure', async () => {
|
|
1353
|
+
// This pattern occurs when VPC/subnets/NAT are external but routing (route tables,
|
|
1354
|
+
// VPC endpoints, security groups) are managed by CloudFormation stack
|
|
1354
1355
|
const appDefinition = {
|
|
1355
1356
|
vpc: { enable: true },
|
|
1356
1357
|
encryption: { fieldLevelEncryptionMethod: 'kms' },
|
|
1357
1358
|
};
|
|
1358
1359
|
|
|
1359
|
-
//
|
|
1360
|
+
// Discovery results from real-world production scenario
|
|
1360
1361
|
const discoveredResources = {
|
|
1361
1362
|
fromCloudFormationStack: true,
|
|
1362
|
-
stackName: '
|
|
1363
|
+
stackName: 'test-production-stack',
|
|
1363
1364
|
existingLogicalIds: [
|
|
1364
1365
|
'FriggLambdaSecurityGroup',
|
|
1365
1366
|
'FriggLambdaRouteTable',
|
|
@@ -1447,6 +1448,122 @@ describe('VpcBuilder', () => {
|
|
|
1447
1448
|
});
|
|
1448
1449
|
});
|
|
1449
1450
|
|
|
1451
|
+
describe('convertFlatDiscoveryToStructured - VPC Endpoints from CloudFormation', () => {
|
|
1452
|
+
it('should add VPC endpoints to stackManaged when in existingLogicalIds', () => {
|
|
1453
|
+
const flatDiscovery = {
|
|
1454
|
+
fromCloudFormationStack: true,
|
|
1455
|
+
stackName: 'test-stack',
|
|
1456
|
+
existingLogicalIds: [
|
|
1457
|
+
'FriggS3VPCEndpoint',
|
|
1458
|
+
'FriggDynamoDBVPCEndpoint',
|
|
1459
|
+
'FriggKMSVPCEndpoint'
|
|
1460
|
+
],
|
|
1461
|
+
s3VpcEndpointId: 'vpce-s3-stack',
|
|
1462
|
+
dynamodbVpcEndpointId: 'vpce-ddb-stack',
|
|
1463
|
+
kmsVpcEndpointId: 'vpce-kms-stack'
|
|
1464
|
+
};
|
|
1465
|
+
|
|
1466
|
+
const result = vpcBuilder.convertFlatDiscoveryToStructured(flatDiscovery);
|
|
1467
|
+
|
|
1468
|
+
// VPC endpoints should be in stackManaged (not external)
|
|
1469
|
+
expect(result.stackManaged).toContainEqual(
|
|
1470
|
+
expect.objectContaining({
|
|
1471
|
+
logicalId: 'FriggS3VPCEndpoint',
|
|
1472
|
+
physicalId: 'vpce-s3-stack',
|
|
1473
|
+
resourceType: 'AWS::EC2::VPCEndpoint'
|
|
1474
|
+
})
|
|
1475
|
+
);
|
|
1476
|
+
expect(result.stackManaged).toContainEqual(
|
|
1477
|
+
expect.objectContaining({
|
|
1478
|
+
logicalId: 'FriggDynamoDBVPCEndpoint',
|
|
1479
|
+
physicalId: 'vpce-ddb-stack',
|
|
1480
|
+
resourceType: 'AWS::EC2::VPCEndpoint'
|
|
1481
|
+
})
|
|
1482
|
+
);
|
|
1483
|
+
expect(result.stackManaged).toContainEqual(
|
|
1484
|
+
expect.objectContaining({
|
|
1485
|
+
logicalId: 'FriggKMSVPCEndpoint',
|
|
1486
|
+
physicalId: 'vpce-kms-stack',
|
|
1487
|
+
resourceType: 'AWS::EC2::VPCEndpoint'
|
|
1488
|
+
})
|
|
1489
|
+
);
|
|
1490
|
+
|
|
1491
|
+
// Should NOT be in external array
|
|
1492
|
+
expect(result.external.some(r => r.physicalId === 'vpce-s3-stack')).toBe(false);
|
|
1493
|
+
expect(result.external.some(r => r.physicalId === 'vpce-ddb-stack')).toBe(false);
|
|
1494
|
+
expect(result.external.some(r => r.physicalId === 'vpce-kms-stack')).toBe(false);
|
|
1495
|
+
});
|
|
1496
|
+
|
|
1497
|
+
it('should add VPC endpoints to external when NOT in existingLogicalIds', () => {
|
|
1498
|
+
const flatDiscovery = {
|
|
1499
|
+
fromCloudFormationStack: false, // AWS API discovery
|
|
1500
|
+
s3VpcEndpointId: 'vpce-s3-external',
|
|
1501
|
+
dynamodbVpcEndpointId: 'vpce-ddb-external'
|
|
1502
|
+
};
|
|
1503
|
+
|
|
1504
|
+
const result = vpcBuilder.convertFlatDiscoveryToStructured(flatDiscovery);
|
|
1505
|
+
|
|
1506
|
+
// Should be in external (AWS discovery)
|
|
1507
|
+
expect(result.external).toContainEqual(
|
|
1508
|
+
expect.objectContaining({
|
|
1509
|
+
physicalId: 'vpce-s3-external',
|
|
1510
|
+
resourceType: 'AWS::EC2::VPCEndpoint',
|
|
1511
|
+
source: 'aws-discovery'
|
|
1512
|
+
})
|
|
1513
|
+
);
|
|
1514
|
+
|
|
1515
|
+
// Should NOT be in stackManaged
|
|
1516
|
+
expect(result.stackManaged.some(r => r.physicalId === 'vpce-s3-external')).toBe(false);
|
|
1517
|
+
});
|
|
1518
|
+
|
|
1519
|
+
it('should preserve existing VPC endpoints and only create missing ones', async () => {
|
|
1520
|
+
const appDefinition = {
|
|
1521
|
+
vpc: { enable: true },
|
|
1522
|
+
encryption: { fieldLevelEncryptionMethod: 'kms' },
|
|
1523
|
+
};
|
|
1524
|
+
|
|
1525
|
+
const discoveredResources = {
|
|
1526
|
+
fromCloudFormationStack: true,
|
|
1527
|
+
stackName: 'test-stack',
|
|
1528
|
+
existingLogicalIds: [
|
|
1529
|
+
'FriggS3VPCEndpoint', // In stack
|
|
1530
|
+
'FriggDynamoDBVPCEndpoint', // In stack
|
|
1531
|
+
'FriggKMSVPCEndpoint' // In stack
|
|
1532
|
+
// SecretsManager and SQS NOT in stack (were deleted)
|
|
1533
|
+
],
|
|
1534
|
+
defaultVpcId: 'vpc-123',
|
|
1535
|
+
privateSubnetId1: 'subnet-1',
|
|
1536
|
+
privateSubnetId2: 'subnet-2',
|
|
1537
|
+
lambdaSecurityGroupId: 'sg-123',
|
|
1538
|
+
routeTableId: 'rtb-123',
|
|
1539
|
+
// Endpoints in stack
|
|
1540
|
+
s3VpcEndpointId: 'vpce-s3-existing',
|
|
1541
|
+
dynamodbVpcEndpointId: 'vpce-ddb-existing',
|
|
1542
|
+
kmsVpcEndpointId: 'vpce-kms-existing'
|
|
1543
|
+
// secretsManagerVpcEndpointId and sqsVpcEndpointId NOT present
|
|
1544
|
+
};
|
|
1545
|
+
|
|
1546
|
+
const result = await vpcBuilder.build(appDefinition, discoveredResources);
|
|
1547
|
+
|
|
1548
|
+
// Existing endpoints MUST be in template (re-added)
|
|
1549
|
+
expect(result.resources.FriggS3VPCEndpoint).toBeDefined();
|
|
1550
|
+
expect(result.resources.FriggS3VPCEndpoint.Properties.VpcId).toBe('vpc-123');
|
|
1551
|
+
|
|
1552
|
+
expect(result.resources.FriggDynamoDBVPCEndpoint).toBeDefined();
|
|
1553
|
+
expect(result.resources.FriggDynamoDBVPCEndpoint.Properties.VpcId).toBe('vpc-123');
|
|
1554
|
+
|
|
1555
|
+
expect(result.resources.FriggKMSVPCEndpoint).toBeDefined();
|
|
1556
|
+
expect(result.resources.FriggKMSVPCEndpoint.Properties.VpcId).toBe('vpc-123');
|
|
1557
|
+
|
|
1558
|
+
// Missing endpoints should also be created
|
|
1559
|
+
expect(result.resources.FriggSecretsManagerVPCEndpoint).toBeDefined();
|
|
1560
|
+
expect(result.resources.FriggSQSVPCEndpoint).toBeDefined();
|
|
1561
|
+
|
|
1562
|
+
// VPC Endpoint Security Group should be created
|
|
1563
|
+
expect(result.resources.FriggVPCEndpointSecurityGroup).toBeDefined();
|
|
1564
|
+
});
|
|
1565
|
+
});
|
|
1566
|
+
|
|
1450
1567
|
describe('convertFlatDiscoveryToStructured - CloudFormation query results', () => {
|
|
1451
1568
|
it('should add VPC from CloudFormation query to external array', () => {
|
|
1452
1569
|
const flatDiscovery = {
|
|
@@ -1539,10 +1656,10 @@ describe('VpcBuilder', () => {
|
|
|
1539
1656
|
expect(result.external.some(r => r.physicalId === 'subnet-in-stack')).toBe(false);
|
|
1540
1657
|
});
|
|
1541
1658
|
|
|
1542
|
-
it('should handle
|
|
1659
|
+
it('should handle external VPC pattern: stack resources + queried external references', () => {
|
|
1543
1660
|
const flatDiscovery = {
|
|
1544
1661
|
fromCloudFormationStack: true,
|
|
1545
|
-
stackName: '
|
|
1662
|
+
stackName: 'test-production-stack',
|
|
1546
1663
|
existingLogicalIds: [
|
|
1547
1664
|
'FriggLambdaSecurityGroup',
|
|
1548
1665
|
'FriggLambdaRouteTable',
|
|
@@ -1554,14 +1671,14 @@ describe('VpcBuilder', () => {
|
|
|
1554
1671
|
'FriggKMSVPCEndpoint'
|
|
1555
1672
|
],
|
|
1556
1673
|
// Stack resources
|
|
1557
|
-
lambdaSecurityGroupId: 'sg-
|
|
1558
|
-
routeTableId: 'rtb-
|
|
1559
|
-
s3VpcEndpointId: 'vpce-s3',
|
|
1674
|
+
lambdaSecurityGroupId: 'sg-stack-123',
|
|
1675
|
+
routeTableId: 'rtb-stack-456',
|
|
1676
|
+
s3VpcEndpointId: 'vpce-s3-stack',
|
|
1560
1677
|
// External resources (discovered via queries)
|
|
1561
|
-
defaultVpcId: 'vpc-
|
|
1562
|
-
privateSubnetId1: 'subnet-
|
|
1563
|
-
privateSubnetId2: 'subnet-
|
|
1564
|
-
existingNatGatewayId: 'nat-
|
|
1678
|
+
defaultVpcId: 'vpc-external-123',
|
|
1679
|
+
privateSubnetId1: 'subnet-external-1',
|
|
1680
|
+
privateSubnetId2: 'subnet-external-2',
|
|
1681
|
+
existingNatGatewayId: 'nat-external-789'
|
|
1565
1682
|
};
|
|
1566
1683
|
|
|
1567
1684
|
const result = vpcBuilder.convertFlatDiscoveryToStructured(flatDiscovery);
|
|
@@ -1569,19 +1686,19 @@ describe('VpcBuilder', () => {
|
|
|
1569
1686
|
// Stack resources should be in stackManaged
|
|
1570
1687
|
expect(result.stackManaged).toEqual(
|
|
1571
1688
|
expect.arrayContaining([
|
|
1572
|
-
expect.objectContaining({ logicalId: 'FriggLambdaSecurityGroup', physicalId: 'sg-
|
|
1573
|
-
expect.objectContaining({ logicalId: 'FriggLambdaRouteTable', physicalId: 'rtb-
|
|
1574
|
-
expect.objectContaining({ logicalId: 'FriggS3VPCEndpoint' })
|
|
1689
|
+
expect.objectContaining({ logicalId: 'FriggLambdaSecurityGroup', physicalId: 'sg-stack-123' }),
|
|
1690
|
+
expect.objectContaining({ logicalId: 'FriggLambdaRouteTable', physicalId: 'rtb-stack-456' }),
|
|
1691
|
+
expect.objectContaining({ logicalId: 'FriggS3VPCEndpoint', physicalId: 'vpce-s3-stack' })
|
|
1575
1692
|
])
|
|
1576
1693
|
);
|
|
1577
1694
|
|
|
1578
1695
|
// External resources should be in external array
|
|
1579
1696
|
expect(result.external).toEqual(
|
|
1580
1697
|
expect.arrayContaining([
|
|
1581
|
-
expect.objectContaining({ physicalId: 'vpc-
|
|
1582
|
-
expect.objectContaining({ physicalId: 'subnet-
|
|
1583
|
-
expect.objectContaining({ physicalId: 'subnet-
|
|
1584
|
-
expect.objectContaining({ physicalId: 'nat-
|
|
1698
|
+
expect.objectContaining({ physicalId: 'vpc-external-123', resourceType: 'AWS::EC2::VPC', source: 'cloudformation-query' }),
|
|
1699
|
+
expect.objectContaining({ physicalId: 'subnet-external-1', resourceType: 'AWS::EC2::Subnet', source: 'cloudformation-query' }),
|
|
1700
|
+
expect.objectContaining({ physicalId: 'subnet-external-2', resourceType: 'AWS::EC2::Subnet', source: 'cloudformation-query' }),
|
|
1701
|
+
expect.objectContaining({ physicalId: 'nat-external-789', resourceType: 'AWS::EC2::NatGateway', source: 'cloudformation-query' })
|
|
1585
1702
|
])
|
|
1586
1703
|
);
|
|
1587
1704
|
});
|
|
@@ -589,7 +589,7 @@ describe('CloudFormationDiscovery', () => {
|
|
|
589
589
|
|
|
590
590
|
describe('External VPC with routing infrastructure pattern', () => {
|
|
591
591
|
it('should discover routing resources when VPC is external', async () => {
|
|
592
|
-
// This tests the
|
|
592
|
+
// This tests the external VPC pattern: external VPC/subnets/KMS,
|
|
593
593
|
// but stack creates routing infrastructure (route table, NAT route, VPC endpoints)
|
|
594
594
|
const mockStack = {
|
|
595
595
|
StackName: 'create-frigg-app-production',
|
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.490.
|
|
4
|
+
"version": "2.0.0--canary.490.6e556a4.0",
|
|
5
5
|
"bin": {
|
|
6
6
|
"frigg": "./frigg-cli/index.js"
|
|
7
7
|
},
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"@babel/eslint-parser": "^7.18.9",
|
|
17
17
|
"@babel/parser": "^7.25.3",
|
|
18
18
|
"@babel/traverse": "^7.25.3",
|
|
19
|
-
"@friggframework/core": "2.0.0--canary.490.
|
|
20
|
-
"@friggframework/schemas": "2.0.0--canary.490.
|
|
21
|
-
"@friggframework/test": "2.0.0--canary.490.
|
|
19
|
+
"@friggframework/core": "2.0.0--canary.490.6e556a4.0",
|
|
20
|
+
"@friggframework/schemas": "2.0.0--canary.490.6e556a4.0",
|
|
21
|
+
"@friggframework/test": "2.0.0--canary.490.6e556a4.0",
|
|
22
22
|
"@hapi/boom": "^10.0.1",
|
|
23
23
|
"@inquirer/prompts": "^5.3.8",
|
|
24
24
|
"axios": "^1.7.2",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"validate-npm-package-name": "^5.0.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@friggframework/eslint-config": "2.0.0--canary.490.
|
|
50
|
-
"@friggframework/prettier-config": "2.0.0--canary.490.
|
|
49
|
+
"@friggframework/eslint-config": "2.0.0--canary.490.6e556a4.0",
|
|
50
|
+
"@friggframework/prettier-config": "2.0.0--canary.490.6e556a4.0",
|
|
51
51
|
"aws-sdk-client-mock": "^4.1.0",
|
|
52
52
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
53
53
|
"jest": "^30.1.3",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"publishConfig": {
|
|
80
80
|
"access": "public"
|
|
81
81
|
},
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "6e556a4ddd243fe9163916341b1d70c31dd86ca0"
|
|
83
83
|
}
|