From 7939dc9c8e1b1f7e8e566d797cc39c10d427afa3 Mon Sep 17 00:00:00 2001 From: simonhammes Date: Wed, 4 Sep 2024 12:00:03 +0200 Subject: [PATCH] feat(load-balancer): Set IPMode to "Proxy" if load balancer is configured to use proxy protocol (#727) Fixes #727 --- hcloud/load_balancers.go | 37 ++++++++++++++++++++++++++++++++--- hcloud/load_balancers_test.go | 24 ++++++++++++----------- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/hcloud/load_balancers.go b/hcloud/load_balancers.go index 7f95a16d..14ea5fbd 100644 --- a/hcloud/load_balancers.go +++ b/hcloud/load_balancers.go @@ -33,6 +33,7 @@ type loadBalancers struct { lbOps LoadBalancerOps disablePrivateIngressDefault bool disableIPv6Default bool + useProxyProtocolDefault bool } func newLoadBalancers(lbOps LoadBalancerOps, disablePrivateIngressDefault bool, disableIPv6Default bool) *loadBalancers { @@ -220,6 +221,16 @@ func (l *loadBalancers) buildLoadBalancerStatusIngress(lb *hcloud.LoadBalancer, metrics.OperationCalled.WithLabelValues(op).Inc() var ingress []corev1.LoadBalancerIngress + ipMode := corev1.LoadBalancerIPModeVIP + + useProxyProtocol, err := l.getUseProxyProtocol(svc) + if err != nil { + return nil, fmt.Errorf("%s: %w", op, err) + } + + if useProxyProtocol { + ipMode = corev1.LoadBalancerIPModeProxy + } disablePubNet, err := annotation.LBDisablePublicNetwork.BoolFromService(svc) if err != nil && !errors.Is(err, annotation.ErrNotSet) { @@ -227,14 +238,20 @@ func (l *loadBalancers) buildLoadBalancerStatusIngress(lb *hcloud.LoadBalancer, } if !disablePubNet { - ingress = append(ingress, corev1.LoadBalancerIngress{IP: lb.PublicNet.IPv4.IP.String()}) + ingress = append(ingress, corev1.LoadBalancerIngress{ + IP: lb.PublicNet.IPv4.IP.String(), + IPMode: &ipMode, + }) disableIPV6, err := l.getDisableIPv6(svc) if err != nil { return nil, fmt.Errorf("%s: %w", op, err) } if !disableIPV6 { - ingress = append(ingress, corev1.LoadBalancerIngress{IP: lb.PublicNet.IPv6.IP.String()}) + ingress = append(ingress, corev1.LoadBalancerIngress{ + IP: lb.PublicNet.IPv6.IP.String(), + IPMode: &ipMode, + }) } } @@ -245,7 +262,10 @@ func (l *loadBalancers) buildLoadBalancerStatusIngress(lb *hcloud.LoadBalancer, if !disablePrivIngress { for _, privateNet := range lb.PrivateNet { - ingress = append(ingress, corev1.LoadBalancerIngress{IP: privateNet.IP.String()}) + ingress = append(ingress, corev1.LoadBalancerIngress{ + IP: privateNet.IP.String(), + IPMode: &ipMode, + }) } } @@ -263,6 +283,17 @@ func (l *loadBalancers) getDisablePrivateIngress(svc *corev1.Service) (bool, err return false, err } +func (l *loadBalancers) getUseProxyProtocol(svc *corev1.Service) (bool, error) { + disable, err := annotation.LBSvcProxyProtocol.BoolFromService(svc) + if err == nil { + return disable, nil + } + if errors.Is(err, annotation.ErrNotSet) { + return l.useProxyProtocolDefault, nil + } + return false, err +} + func (l *loadBalancers) getDisableIPv6(svc *corev1.Service) (bool, error) { disable, err := annotation.LBIPv6Disabled.BoolFromService(svc) if err == nil { diff --git a/hcloud/load_balancers_test.go b/hcloud/load_balancers_test.go index 04bdf9bd..fa3ee84b 100644 --- a/hcloud/load_balancers_test.go +++ b/hcloud/load_balancers_test.go @@ -241,6 +241,8 @@ func TestLoadBalancers_EnsureLoadBalancer_CreateLoadBalancer(t *testing.T) { Return(false, nil) } + ipModeVIP := corev1.LoadBalancerIPModeVIP + tests := []LoadBalancerTestCase{ { Name: "check for existing Load Balancer fails", @@ -278,7 +280,7 @@ func TestLoadBalancers_EnsureLoadBalancer_CreateLoadBalancer(t *testing.T) { Perform: func(t *testing.T, tt *LoadBalancerTestCase) { expected := &corev1.LoadBalancerStatus{ Ingress: []corev1.LoadBalancerIngress{ - {IP: tt.LB.PublicNet.IPv4.IP.String()}, + {IP: tt.LB.PublicNet.IPv4.IP.String(), IPMode: &ipModeVIP}, }, } lbStat, err := tt.LoadBalancers.EnsureLoadBalancer(tt.Ctx, tt.ClusterName, tt.Service, tt.Nodes) @@ -309,8 +311,8 @@ func TestLoadBalancers_EnsureLoadBalancer_CreateLoadBalancer(t *testing.T) { Perform: func(t *testing.T, tt *LoadBalancerTestCase) { expected := &corev1.LoadBalancerStatus{ Ingress: []corev1.LoadBalancerIngress{ - {IP: tt.LB.PublicNet.IPv4.IP.String()}, - {IP: tt.LB.PublicNet.IPv6.IP.String()}, + {IP: tt.LB.PublicNet.IPv4.IP.String(), IPMode: &ipModeVIP}, + {IP: tt.LB.PublicNet.IPv6.IP.String(), IPMode: &ipModeVIP}, }, } lbStat, err := tt.LoadBalancers.EnsureLoadBalancer(tt.Ctx, tt.ClusterName, tt.Service, tt.Nodes) @@ -351,9 +353,9 @@ func TestLoadBalancers_EnsureLoadBalancer_CreateLoadBalancer(t *testing.T) { Perform: func(t *testing.T, tt *LoadBalancerTestCase) { expected := &corev1.LoadBalancerStatus{ Ingress: []corev1.LoadBalancerIngress{ - {IP: tt.LB.PublicNet.IPv4.IP.String()}, - {IP: tt.LB.PublicNet.IPv6.IP.String()}, - {IP: tt.LB.PrivateNet[0].IP.String()}, + {IP: tt.LB.PublicNet.IPv4.IP.String(), IPMode: &ipModeVIP}, + {IP: tt.LB.PublicNet.IPv6.IP.String(), IPMode: &ipModeVIP}, + {IP: tt.LB.PrivateNet[0].IP.String(), IPMode: &ipModeVIP}, }, } lbStat, err := tt.LoadBalancers.EnsureLoadBalancer(tt.Ctx, tt.ClusterName, tt.Service, tt.Nodes) @@ -395,8 +397,8 @@ func TestLoadBalancers_EnsureLoadBalancer_CreateLoadBalancer(t *testing.T) { Perform: func(t *testing.T, tt *LoadBalancerTestCase) { expected := &corev1.LoadBalancerStatus{ Ingress: []corev1.LoadBalancerIngress{ - {IP: tt.LB.PublicNet.IPv4.IP.String()}, - {IP: tt.LB.PublicNet.IPv6.IP.String()}, + {IP: tt.LB.PublicNet.IPv4.IP.String(), IPMode: &ipModeVIP}, + {IP: tt.LB.PublicNet.IPv6.IP.String(), IPMode: &ipModeVIP}, }, } lbStat, err := tt.LoadBalancers.EnsureLoadBalancer(tt.Ctx, tt.ClusterName, tt.Service, tt.Nodes) @@ -438,8 +440,8 @@ func TestLoadBalancers_EnsureLoadBalancer_CreateLoadBalancer(t *testing.T) { Perform: func(t *testing.T, tt *LoadBalancerTestCase) { expected := &corev1.LoadBalancerStatus{ Ingress: []corev1.LoadBalancerIngress{ - {IP: tt.LB.PublicNet.IPv4.IP.String()}, - {IP: tt.LB.PublicNet.IPv6.IP.String()}, + {IP: tt.LB.PublicNet.IPv4.IP.String(), IPMode: &ipModeVIP}, + {IP: tt.LB.PublicNet.IPv6.IP.String(), IPMode: &ipModeVIP}, }, } lbStat, err := tt.LoadBalancers.EnsureLoadBalancer(tt.Ctx, tt.ClusterName, tt.Service, tt.Nodes) @@ -493,7 +495,7 @@ func TestLoadBalancers_EnsureLoadBalancer_CreateLoadBalancer(t *testing.T) { Perform: func(t *testing.T, tt *LoadBalancerTestCase) { expected := &corev1.LoadBalancerStatus{ Ingress: []corev1.LoadBalancerIngress{ - {IP: tt.LB.PrivateNet[0].IP.String()}, + {IP: tt.LB.PrivateNet[0].IP.String(), IPMode: &ipModeVIP}, }, } lbStat, err := tt.LoadBalancers.EnsureLoadBalancer(tt.Ctx, tt.ClusterName, tt.Service, tt.Nodes)