Skip to content

Update Go to version 1.24.1, update base image to AL2023 #4104

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .go-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.23.6
1.24.1
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ IMG ?= public.ecr.aws/eks/aws-load-balancer-controller:v2.12.0
GOLANG_VERSION ?= $(shell cat .go-version)
BUILD_IMAGE ?= public.ecr.aws/docker/library/golang:$(GOLANG_VERSION)
# Image URL to use for base layer in Docker build
BASE_IMAGE ?= public.ecr.aws/eks-distro-build-tooling/eks-distro-minimal-base-nonroot:2024-08-13-1723575672.2
BASE_IMAGE ?= public.ecr.aws/eks-distro-build-tooling/eks-distro-minimal-base-nonroot:2025-01-01-1735689705.2023
IMG_PLATFORM ?= linux/amd64,linux/arm64
# ECR doesn't appear to support SPDX SBOM
IMG_SBOM ?= none
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module sigs.k8s.io/aws-load-balancer-controller

go 1.23.6
go 1.24.1

require (
github.com/aws/aws-sdk-go v1.55.5
Expand Down
28 changes: 14 additions & 14 deletions pkg/networking/utils.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package networking

import (
"fmt"
"net/netip"
"strings"

awssdk "github.com/aws/aws-sdk-go-v2/aws"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/pkg/errors"
"net/netip"
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
"strings"
)

// ParseCIDRs will parse CIDRs in string format into parsed IPPrefix
Expand Down Expand Up @@ -80,30 +80,30 @@ func GetSubnetAssociatedIPv6CIDRs(subnet ec2types.Subnet) ([]netip.Prefix, error
// ValidateEnablePrefixForIpv6SourceNat function returns the validation error if error exists for EnablePrefixForIpv6SourceNat annotation value
func ValidateEnablePrefixForIpv6SourceNat(EnablePrefixForIpv6SourceNat string, ipAddressType elbv2model.IPAddressType, ec2Subnets []ec2types.Subnet) error {
if EnablePrefixForIpv6SourceNat != string(elbv2model.EnablePrefixForIpv6SourceNatOn) && EnablePrefixForIpv6SourceNat != string(elbv2model.EnablePrefixForIpv6SourceNatOff) {
return errors.Errorf(fmt.Sprintf("Invalid enable-prefix-for-ipv6-source-nat value: %v. Valid values are ['on', 'off'].", EnablePrefixForIpv6SourceNat))
return errors.Errorf("Invalid enable-prefix-for-ipv6-source-nat value: %v. Valid values are ['on', 'off'].", EnablePrefixForIpv6SourceNat)
}

if EnablePrefixForIpv6SourceNat != string(elbv2model.EnablePrefixForIpv6SourceNatOn) {
return nil
}

if ipAddressType == elbv2model.IPAddressTypeIPV4 {
return errors.Errorf(fmt.Sprintf("enable-prefix-for-ipv6-source-nat annotation is only applicable to Network Load Balancers using Dualstack IP address type."))
return errors.Errorf("enable-prefix-for-ipv6-source-nat annotation is only applicable to Network Load Balancers using Dualstack IP address type.")
}
var subnetsWithoutIPv6CIDR []string

for _, subnet := range ec2Subnets {
subnetIPv6CIDRs, err := GetSubnetAssociatedIPv6CIDRs(subnet)
if err != nil {
return errors.Errorf(fmt.Sprintf("%v", err))
return errors.Errorf("%v", err)
}
if len(subnetIPv6CIDRs) < 1 {
subnetsWithoutIPv6CIDR = append(subnetsWithoutIPv6CIDR, awssdk.ToString(subnet.SubnetId))

}
}
if len(subnetsWithoutIPv6CIDR) > 0 {
return errors.Errorf(fmt.Sprintf("To enable prefix for source NAT, all associated subnets must have an IPv6 CIDR. Subnets without IPv6 CIDR: %v.", subnetsWithoutIPv6CIDR))
return errors.Errorf("To enable prefix for source NAT, all associated subnets must have an IPv6 CIDR. Subnets without IPv6 CIDR: %v.", subnetsWithoutIPv6CIDR)
}

return nil
Expand All @@ -120,36 +120,36 @@ func ValidateSourceNatPrefixes(sourceNatIpv6Prefixes []string, ipAddressType elb
}

if len(sourceNatIpv6Prefixes) != len(ec2Subnets) {
return errors.Errorf(fmt.Sprintf("Number of values in source-nat-ipv6-prefixes (%d) must match the number of subnets (%d).", len(sourceNatIpv6Prefixes), len(ec2Subnets)))
return errors.Errorf("Number of values in source-nat-ipv6-prefixes (%d) must match the number of subnets (%d).", len(sourceNatIpv6Prefixes), len(ec2Subnets))
}
for idx, sourceNatIpv6Prefix := range sourceNatIpv6Prefixes {
var subnet = ec2Subnets[idx]
var sourceNatIpv6PrefixParsedList []netip.Addr
if sourceNatIpv6Prefix != elbv2model.SourceNatIpv6PrefixAutoAssigned {
subStrings := strings.Split(sourceNatIpv6Prefix, "/")
if len(subStrings) < 2 {
return errors.Errorf(fmt.Sprintf("Invalid value in source-nat-ipv6-prefixes: %v.", sourceNatIpv6Prefix))
return errors.Errorf("Invalid value in source-nat-ipv6-prefixes: %v.", sourceNatIpv6Prefix)
}
var ipAddressPart = subStrings[0]
var prefixLengthPart = subStrings[1]
if prefixLengthPart != requiredPrefixLengthForSourceNatCidr {
return errors.Errorf(fmt.Sprintf("Invalid value in source-nat-ipv6-prefixes: %v. Prefix length must be %v, but %v is specified.", sourceNatIpv6Prefix, requiredPrefixLengthForSourceNatCidr, prefixLengthPart))
return errors.Errorf("Invalid value in source-nat-ipv6-prefixes: %v. Prefix length must be %v, but %v is specified.", sourceNatIpv6Prefix, requiredPrefixLengthForSourceNatCidr, prefixLengthPart)
}
sourceNatIpv6PrefixNetIpParsed, err := netip.ParseAddr(ipAddressPart)
if err != nil {
return errors.Errorf(fmt.Sprintf("Invalid value in source-nat-ipv6-prefixes: %v. Value must be a valid IPv6 CIDR.", sourceNatIpv6Prefix))
return errors.Errorf("Invalid value in source-nat-ipv6-prefixes: %v. Value must be a valid IPv6 CIDR.", sourceNatIpv6Prefix)
}
sourceNatIpv6PrefixParsedList = append(sourceNatIpv6PrefixParsedList, sourceNatIpv6PrefixNetIpParsed)
if !sourceNatIpv6PrefixNetIpParsed.Is6() {
return errors.Errorf(fmt.Sprintf("Invalid value in source-nat-ipv6-prefixes: %v. Value must be a valid IPv6 CIDR.", sourceNatIpv6Prefix))
return errors.Errorf("Invalid value in source-nat-ipv6-prefixes: %v. Value must be a valid IPv6 CIDR.", sourceNatIpv6Prefix)
}
subnetIPv6CIDRs, err := GetSubnetAssociatedIPv6CIDRs(subnet)
if err != nil {
return errors.Errorf(fmt.Sprintf("Subnet has invalid IPv6 CIDRs: %v. Subnet must have valid IPv6 CIDRs.", subnetIPv6CIDRs))
return errors.Errorf("Subnet has invalid IPv6 CIDRs: %v. Subnet must have valid IPv6 CIDRs.", subnetIPv6CIDRs)
}
sourceNatIpv6PrefixWithinSubnet := FilterIPsWithinCIDRs(sourceNatIpv6PrefixParsedList, subnetIPv6CIDRs)
if len(sourceNatIpv6PrefixWithinSubnet) != 1 {
return errors.Errorf(fmt.Sprintf("Invalid value in source-nat-ipv6-prefixes: %v. Value must be within subnet CIDR range: %v.", sourceNatIpv6Prefix, subnetIPv6CIDRs))
return errors.Errorf("Invalid value in source-nat-ipv6-prefixes: %v. Value must be within subnet CIDR range: %v.", sourceNatIpv6Prefix, subnetIPv6CIDRs)
}
}
}
Expand Down
120 changes: 60 additions & 60 deletions pkg/service/model_build_target_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,65 +205,65 @@ func (t *defaultModelBuildTask) buildTargetGroupName(_ context.Context, svcPort
}

func (t *defaultModelBuildTask) buildTargetGroupAttributes(_ context.Context, port corev1.ServicePort) ([]elbv2model.TargetGroupAttribute, error) {
var rawAttributes map[string]string
if _, err := t.annotationParser.ParseStringMapAnnotation(annotations.SvcLBSuffixTargetGroupAttributes, &rawAttributes, t.service.Annotations); err != nil {
return nil, err
}
if rawAttributes == nil {
rawAttributes = make(map[string]string)
}
if _, ok := rawAttributes[tgAttrsProxyProtocolV2Enabled]; !ok {
rawAttributes[tgAttrsProxyProtocolV2Enabled] = strconv.FormatBool(t.defaultProxyProtocolV2Enabled)
}

var proxyProtocolPerTG string
if t.annotationParser.ParseStringAnnotation(annotations.SvcLBSuffixProxyProtocolPerTargetGroup, &proxyProtocolPerTG, t.service.Annotations) {
ports := strings.Split(proxyProtocolPerTG, ",")
enabledPorts := make(map[string]struct{})
for _, p := range ports {
trimmedPort := strings.TrimSpace(p)
if trimmedPort != "" {
if _, err := strconv.Atoi(trimmedPort); err != nil {
return nil, errors.Errorf("invalid port number in proxy-protocol-per-target-group: %v", trimmedPort)
}
enabledPorts[trimmedPort] = struct{}{}
}
}

currentPortStr := strconv.FormatInt(int64(port.Port), 10)
if _, enabled := enabledPorts[currentPortStr]; enabled {
rawAttributes[tgAttrsProxyProtocolV2Enabled] = "true"
} else {
rawAttributes[tgAttrsProxyProtocolV2Enabled] = "false"
}
}

proxyV2Annotation := ""
if exists := t.annotationParser.ParseStringAnnotation(annotations.SvcLBSuffixProxyProtocol, &proxyV2Annotation, t.service.Annotations); exists {
if proxyV2Annotation != "*" {
return []elbv2model.TargetGroupAttribute{}, errors.Errorf("invalid value %v for Load Balancer proxy protocol v2 annotation, only value currently supported is *", proxyV2Annotation)
}
rawAttributes[tgAttrsProxyProtocolV2Enabled] = "true"
}

if rawPreserveIPEnabled, ok := rawAttributes[tgAttrsPreserveClientIPEnabled]; ok {
_, err := strconv.ParseBool(rawPreserveIPEnabled)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse attribute %v=%v", tgAttrsPreserveClientIPEnabled, rawPreserveIPEnabled)
}
}

attributes := make([]elbv2model.TargetGroupAttribute, 0, len(rawAttributes))
for attrKey, attrValue := range rawAttributes {
attributes = append(attributes, elbv2model.TargetGroupAttribute{
Key: attrKey,
Value: attrValue,
})
}
sort.Slice(attributes, func(i, j int) bool {
return attributes[i].Key < attributes[j].Key
})
return attributes, nil
var rawAttributes map[string]string
if _, err := t.annotationParser.ParseStringMapAnnotation(annotations.SvcLBSuffixTargetGroupAttributes, &rawAttributes, t.service.Annotations); err != nil {
return nil, err
}
if rawAttributes == nil {
rawAttributes = make(map[string]string)
}
if _, ok := rawAttributes[tgAttrsProxyProtocolV2Enabled]; !ok {
rawAttributes[tgAttrsProxyProtocolV2Enabled] = strconv.FormatBool(t.defaultProxyProtocolV2Enabled)
}

var proxyProtocolPerTG string
if t.annotationParser.ParseStringAnnotation(annotations.SvcLBSuffixProxyProtocolPerTargetGroup, &proxyProtocolPerTG, t.service.Annotations) {
ports := strings.Split(proxyProtocolPerTG, ",")
enabledPorts := make(map[string]struct{})
for _, p := range ports {
trimmedPort := strings.TrimSpace(p)
if trimmedPort != "" {
if _, err := strconv.Atoi(trimmedPort); err != nil {
return nil, errors.Errorf("invalid port number in proxy-protocol-per-target-group: %v", trimmedPort)
}
enabledPorts[trimmedPort] = struct{}{}
}
}

currentPortStr := strconv.FormatInt(int64(port.Port), 10)
if _, enabled := enabledPorts[currentPortStr]; enabled {
rawAttributes[tgAttrsProxyProtocolV2Enabled] = "true"
} else {
rawAttributes[tgAttrsProxyProtocolV2Enabled] = "false"
}
}

proxyV2Annotation := ""
if exists := t.annotationParser.ParseStringAnnotation(annotations.SvcLBSuffixProxyProtocol, &proxyV2Annotation, t.service.Annotations); exists {
if proxyV2Annotation != "*" {
return []elbv2model.TargetGroupAttribute{}, errors.Errorf("invalid value %v for Load Balancer proxy protocol v2 annotation, only value currently supported is *", proxyV2Annotation)
}
rawAttributes[tgAttrsProxyProtocolV2Enabled] = "true"
}

if rawPreserveIPEnabled, ok := rawAttributes[tgAttrsPreserveClientIPEnabled]; ok {
_, err := strconv.ParseBool(rawPreserveIPEnabled)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse attribute %v=%v", tgAttrsPreserveClientIPEnabled, rawPreserveIPEnabled)
}
}

attributes := make([]elbv2model.TargetGroupAttribute, 0, len(rawAttributes))
for attrKey, attrValue := range rawAttributes {
attributes = append(attributes, elbv2model.TargetGroupAttribute{
Key: attrKey,
Value: attrValue,
})
}
sort.Slice(attributes, func(i, j int) bool {
return attributes[i].Key < attributes[j].Key
})
return attributes, nil
}

func (t *defaultModelBuildTask) buildPreserveClientIPFlag(_ context.Context, targetType elbv2model.TargetType, tgAttrs []elbv2model.TargetGroupAttribute) (bool, error) {
Expand Down Expand Up @@ -736,4 +736,4 @@ func (t *defaultModelBuildTask) buildTargetGroupBindingMultiClusterFlag(svc *cor
return rawEnabled, nil
}
return false, nil
}
}
16 changes: 8 additions & 8 deletions pkg/service/model_build_target_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package service
import (
"context"
"errors"
"sort"
"strconv"
"testing"

ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/golang/mock/gomock"
"sigs.k8s.io/aws-load-balancer-controller/pkg/model/core"
"sigs.k8s.io/aws-load-balancer-controller/pkg/networking"
"sort"
"strconv"
"testing"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -146,15 +147,15 @@ func Test_defaultModelBuilderTask_targetGroupAttrs(t *testing.T) {
svc: &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"service.beta.kubernetes.io/aws-load-balancer-proxy-protocol-per-target-group": "80",
"service.beta.kubernetes.io/aws-load-balancer-proxy-protocol-per-target-group": "80",
},
},
},
port: corev1.ServicePort{Port: 80},
wantError: false,
wantValue: []elbv2.TargetGroupAttribute{
{
Key: tgAttrsProxyProtocolV2Enabled,
Key: tgAttrsProxyProtocolV2Enabled,
Value: "true",
},
},
Expand All @@ -165,16 +166,15 @@ func Test_defaultModelBuilderTask_targetGroupAttrs(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"service.beta.kubernetes.io/aws-load-balancer-proxy-protocol-per-target-group": "443, 22",
"service.beta.kubernetes.io/aws-load-balancer-proxy-protocol": "*",

"service.beta.kubernetes.io/aws-load-balancer-proxy-protocol": "*",
},
},
},
port: corev1.ServicePort{Port: 80},
wantError: false,
wantValue: []elbv2.TargetGroupAttribute{
{
Key: tgAttrsProxyProtocolV2Enabled,
Key: tgAttrsProxyProtocolV2Enabled,
Value: "true",
},
},
Expand Down
Loading