Skip to content

Commit

Permalink
fix: Cannot set the IPv6 addresses in dualstack mode during modification
Browse files Browse the repository at this point in the history
  • Loading branch information
wweiwei-li committed Nov 27, 2024
1 parent 8ba34e2 commit 3faf573
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 2 deletions.
25 changes: 24 additions & 1 deletion pkg/deploy/elbv2/load_balancer_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package elbv2
import (
"context"
"fmt"

awssdk "github.com/aws/aws-sdk-go-v2/aws"
elbv2sdk "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"
Expand Down Expand Up @@ -154,20 +155,28 @@ func (m *defaultLoadBalancerManager) updateSDKLoadBalancerWithIPAddressType(ctx

func (m *defaultLoadBalancerManager) updateSDKLoadBalancerWithSubnetMappings(ctx context.Context, resLB *elbv2model.LoadBalancer, sdkLB LoadBalancerWithTags) error {
desiredSubnets := sets.NewString()
desiredIPv6Addresses := sets.NewString()
desiredSubnetsSourceNATPrefixes := sets.NewString()
currentSubnetsSourceNATPrefixes := sets.NewString()
for _, mapping := range resLB.Spec.SubnetMappings {
desiredSubnets.Insert(mapping.SubnetID)
if mapping.SourceNatIpv6Prefix != nil {
desiredSubnetsSourceNATPrefixes.Insert(awssdk.ToString(mapping.SourceNatIpv6Prefix))
}
if mapping.IPv6Address != nil {
desiredIPv6Addresses.Insert(awssdk.ToString(mapping.IPv6Address))
}
}
currentSubnets := sets.NewString()
currentIPv6Addresses := sets.NewString()
for _, az := range sdkLB.LoadBalancer.AvailabilityZones {
currentSubnets.Insert(awssdk.ToString(az.SubnetId))
if len(az.SourceNatIpv6Prefixes) != 0 {
currentSubnetsSourceNATPrefixes.Insert(az.SourceNatIpv6Prefixes[0])
}
if len(az.LoadBalancerAddresses) > 0 && az.LoadBalancerAddresses[0].IPv6Address != nil {
currentIPv6Addresses.Insert(awssdk.ToString(az.LoadBalancerAddresses[0].IPv6Address))
}
}
sdkLBEnablePrefixForIpv6SourceNatValue := string(elbv2model.EnablePrefixForIpv6SourceNatOff)
resLBEnablePrefixForIpv6SourceNatValue := string(elbv2model.EnablePrefixForIpv6SourceNatOff)
Expand All @@ -176,7 +185,9 @@ func (m *defaultLoadBalancerManager) updateSDKLoadBalancerWithSubnetMappings(ctx

resLBEnablePrefixForIpv6SourceNatValue = string(resLB.Spec.EnablePrefixForIpv6SourceNat)

if desiredSubnets.Equal(currentSubnets) && desiredSubnetsSourceNATPrefixes.Equal(currentSubnetsSourceNATPrefixes) && sdkLBEnablePrefixForIpv6SourceNatValue == resLBEnablePrefixForIpv6SourceNatValue {
isFirstTimeIPv6Setup := currentIPv6Addresses.Len() == 0 && desiredIPv6Addresses.Len() > 0
needsDualstackIPv6Update := isIPv4ToDualstackUpdate(resLB, sdkLB) && isFirstTimeIPv6Setup
if !needsDualstackIPv6Update && desiredSubnets.Equal(currentSubnets) && desiredSubnetsSourceNATPrefixes.Equal(currentSubnetsSourceNATPrefixes) && sdkLBEnablePrefixForIpv6SourceNatValue == resLBEnablePrefixForIpv6SourceNatValue {
return nil
}

Expand Down Expand Up @@ -350,3 +361,15 @@ func isEnforceSGInboundRulesOnPrivateLinkUpdated(resLB *elbv2model.LoadBalancer,
return true, currentEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic, desiredEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic

}

func isIPv4ToDualstackUpdate(resLB *elbv2model.LoadBalancer, sdkLB LoadBalancerWithTags) bool {
if &resLB.Spec.IPAddressType == nil {
return false
}
desiredIPAddressType := string(resLB.Spec.IPAddressType)
currentIPAddressType := sdkLB.LoadBalancer.IpAddressType
isIPAddressTypeUpdated := desiredIPAddressType != string(currentIPAddressType)
return isIPAddressTypeUpdated &&
resLB.Spec.Type == elbv2model.LoadBalancerTypeNetwork &&
desiredIPAddressType == string(elbv2model.IPAddressTypeDualStack)
}
54 changes: 53 additions & 1 deletion pkg/deploy/elbv2/load_balancer_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package elbv2

import (
"context"
"testing"

elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"
"github.com/aws/aws-sdk-go/aws"
"github.com/go-logr/logr"
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/services"
"testing"

awssdk "github.com/aws/aws-sdk-go-v2/aws"
elbv2sdk "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
Expand Down Expand Up @@ -609,6 +611,55 @@ func Test_defaultLoadBalancerManager_updateSDKLoadBalancerWithSubnetMappings(t *
},
wantErr: nil,
},
{
name: "Set NLB IPv6 address in dualstack mode during ip address type modification ",
fields: fields{
setSubnetsWithContextCall: setSubnetsWithContextCall{
req: &elbv2sdk.SetSubnetsInput{
LoadBalancerArn: awssdk.String("LoadBalancerArn"),
SubnetMappings: []elbv2types.SubnetMapping{
{
SubnetId: awssdk.String("subnet-A"),
IPv6Address: aws.String("2600:1f18::1"),
},
{
SubnetId: awssdk.String("subnet-B"),
IPv6Address: aws.String("2600:1f18::2"),
},
},
},
resp: &elbv2sdk.SetSubnetsOutput{},
},
},
args: args{
resLB: &elbv2model.LoadBalancer{
ResourceMeta: coremodel.NewResourceMeta(stack, "AWS::ElasticLoadBalancingV2::LoadBalancer", "id-1"),
Spec: elbv2model.LoadBalancerSpec{
SubnetMappings: []elbv2model.SubnetMapping{
{
SubnetID: "subnet-A",
IPv6Address: aws.String("2600:1f18::1"),
},
{
SubnetID: "subnet-B",
IPv6Address: aws.String("2600:1f18::2"),
},
},
Type: elbv2model.LoadBalancerTypeNetwork,
IPAddressType: elbv2model.IPAddressTypeDualStack,
},
},
sdkLB: LoadBalancerWithTags{
LoadBalancer: &elbv2types.LoadBalancer{
LoadBalancerArn: awssdk.String("LoadBalancerArn"),
Type: elbv2types.LoadBalancerTypeEnumNetwork,
AvailabilityZones: []elbv2types.AvailabilityZone{{SubnetId: awssdk.String("subnet-A")}, {SubnetId: awssdk.String("subnet-B")}},
IpAddressType: elbv2types.IpAddressTypeIpv4,
},
},
},
wantErr: nil,
},
}

for _, tt := range tests {
Expand All @@ -629,6 +680,7 @@ func Test_defaultLoadBalancerManager_updateSDKLoadBalancerWithSubnetMappings(t *
} else {
assert.NoError(t, err)
}

})
}
}

0 comments on commit 3faf573

Please sign in to comment.