mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
fix: pass security groups to load balancer
This commit is contained in:
@@ -611,7 +611,7 @@ func (s *ELBv2ServiceImpl) CreateLoadBalancer(input *elbv2.CreateLoadBalancerInp
|
||||
vpcID := ""
|
||||
if s.VPCService != nil && len(subnets) > 0 {
|
||||
for _, subnetID := range subnets {
|
||||
eniOut, eniErr := s.VPCService.CreateNetworkInterface(&ec2.CreateNetworkInterfaceInput{
|
||||
eniIn := &ec2.CreateNetworkInterfaceInput{
|
||||
SubnetId: aws.String(subnetID),
|
||||
Description: aws.String(fmt.Sprintf("ELB %s/%s/%s", arnPathSegment, name, lbID)),
|
||||
TagSpecifications: []*ec2.TagSpecification{
|
||||
@@ -623,7 +623,15 @@ func (s *ELBv2ServiceImpl) CreateLoadBalancer(input *elbv2.CreateLoadBalancerInp
|
||||
},
|
||||
},
|
||||
},
|
||||
}, accountID)
|
||||
}
|
||||
// SG enforcement gates inbound traffic by the ENI's port-group
|
||||
// membership, which is set at ENI creation. Empty Groups
|
||||
// intentionally falls back to the VPC default SG inside
|
||||
// eni.CreateNetworkInterface.
|
||||
if len(securityGroups) > 0 {
|
||||
eniIn.Groups = aws.StringSlice(securityGroups)
|
||||
}
|
||||
eniOut, eniErr := s.VPCService.CreateNetworkInterface(eniIn, accountID)
|
||||
if eniErr != nil {
|
||||
// Rollback: delete any ENIs already created
|
||||
for _, rollbackENI := range eniIDs {
|
||||
|
||||
@@ -679,3 +679,84 @@ func TestCreateLoadBalancer_AMIResolverError_ReturnsServerInternal(t *testing.T)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, lbs, "no LB record should be persisted when AMI resolver errors")
|
||||
}
|
||||
|
||||
// TestCreateLoadBalancer_AttachesSpecifiedSecurityGroupsToENI verifies that
|
||||
// when the caller supplies SecurityGroups on the LB input, the underlying ALB
|
||||
// ENI is created with those SGs (not the VPC default SG). Without this the
|
||||
// ENI's OVN port-group never gains the user's allow rules and inbound traffic
|
||||
// is dropped by the SG enforcement default-deny ACL.
|
||||
func TestCreateLoadBalancer_AttachesSpecifiedSecurityGroupsToENI(t *testing.T) {
|
||||
svc, vpcSvc := setupTestServiceWithVPC(t)
|
||||
|
||||
subnets, err := vpcSvc.DescribeSubnets(&ec2.DescribeSubnetsInput{}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, subnets.Subnets)
|
||||
subnetID := *subnets.Subnets[0].SubnetId
|
||||
vpcID := *subnets.Subnets[0].VpcId
|
||||
|
||||
sgOut, err := vpcSvc.CreateSecurityGroup(&ec2.CreateSecurityGroupInput{
|
||||
GroupName: aws.String("alb-sg"),
|
||||
Description: aws.String("ALB ingress"),
|
||||
VpcId: aws.String(vpcID),
|
||||
}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
sgID := *sgOut.GroupId
|
||||
|
||||
_, err = svc.CreateLoadBalancer(&elbv2.CreateLoadBalancerInput{
|
||||
Name: aws.String("sg-attach-alb"),
|
||||
Subnets: []*string{aws.String(subnetID)},
|
||||
SecurityGroups: []*string{aws.String(sgID)},
|
||||
}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
|
||||
eniDesc, err := vpcSvc.DescribeNetworkInterfaces(&ec2.DescribeNetworkInterfacesInput{}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
|
||||
var albENI *ec2.NetworkInterface
|
||||
for _, eni := range eniDesc.NetworkInterfaces {
|
||||
if eni.RequesterManaged != nil && *eni.RequesterManaged {
|
||||
albENI = eni
|
||||
break
|
||||
}
|
||||
}
|
||||
require.NotNil(t, albENI, "ELB-managed ENI must be created")
|
||||
|
||||
require.Len(t, albENI.Groups, 1, "ALB ENI must join exactly the specified SG, not the default SG")
|
||||
assert.Equal(t, sgID, *albENI.Groups[0].GroupId)
|
||||
}
|
||||
|
||||
// TestCreateLoadBalancer_NoSecurityGroupsFallsBackToDefault preserves the
|
||||
// AWS-semantics fallback: an ALB created without SecurityGroups joins the
|
||||
// VPC's default SG (so the default-deny ACL has at least one allow source).
|
||||
func TestCreateLoadBalancer_NoSecurityGroupsFallsBackToDefault(t *testing.T) {
|
||||
svc, vpcSvc := setupTestServiceWithVPC(t)
|
||||
|
||||
subnets, err := vpcSvc.DescribeSubnets(&ec2.DescribeSubnetsInput{}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
subnetID := *subnets.Subnets[0].SubnetId
|
||||
vpcID := *subnets.Subnets[0].VpcId
|
||||
|
||||
defaultSGID, err := vpcSvc.FindDefaultSGForVPC(testAccountID, vpcID)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, defaultSGID, "VPC must have a default SG provisioned")
|
||||
|
||||
_, err = svc.CreateLoadBalancer(&elbv2.CreateLoadBalancerInput{
|
||||
Name: aws.String("no-sg-alb"),
|
||||
Subnets: []*string{aws.String(subnetID)},
|
||||
}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
|
||||
eniDesc, err := vpcSvc.DescribeNetworkInterfaces(&ec2.DescribeNetworkInterfacesInput{}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
|
||||
var albENI *ec2.NetworkInterface
|
||||
for _, eni := range eniDesc.NetworkInterfaces {
|
||||
if eni.RequesterManaged != nil && *eni.RequesterManaged {
|
||||
albENI = eni
|
||||
break
|
||||
}
|
||||
}
|
||||
require.NotNil(t, albENI)
|
||||
require.Len(t, albENI.Groups, 1)
|
||||
assert.Equal(t, defaultSGID, *albENI.Groups[0].GroupId)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user