Repository: hetznercloud/hcloud-cloud-controller-manager
Pull request #51 (2020-06-24 05:53:01)

Add support for Load Balancer sticky sessions


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a45685eb..5560e7f9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,11 @@
 Changelog
 =========
 
+master
+------
+
+* Add missing support Load Balancer sticky sessions
+
 v1.6.0
 ------
 
diff --git a/internal/annotation/load_balancer.go b/internal/annotation/load_balancer.go
index 80a13fc5..0dbb8a76 100644
--- a/internal/annotation/load_balancer.go
+++ b/internal/annotation/load_balancer.go
@@ -86,6 +86,12 @@ const (
 	// LBSvcRedirectHTTP create a redirect from HTTP to HTTPS. HTTPS only.
 	LBSvcRedirectHTTP Name = "load-balancer.hetzner.cloud/http-redirect-http"
 
+	// LBSvcHTTPStickySessions enables the sticky sessions feature of Hetzner
+	// Cloud HTTP Load Balancers.
+	//
+	// Default: false
+	LBSvcHTTPStickySessions Name = "load-balancer.hetzner.cloud/http-sticky-sessions"
+
 	// LBSvcHealthCheckProtocol sets the protocol the health check should be
 	// performed over.
 	//
diff --git a/internal/hcops/load_balancer.go b/internal/hcops/load_balancer.go
index ec3fa774..64596866 100644
--- a/internal/hcops/load_balancer.go
+++ b/internal/hcops/load_balancer.go
@@ -561,6 +561,19 @@ func (b *hclbServiceOptsBuilder) extract() {
 		return nil
 	})
 
+	b.do(func() error {
+		stickySessions, err := annotation.LBSvcHTTPStickySessions.BoolFromService(b.Service)
+		if errors.Is(err, annotation.ErrNotSet) {
+			return nil
+		}
+		if err != nil {
+			return fmt.Errorf("%s: %w", op, err)
+		}
+		b.httpOpts.StickySessions = &stickySessions
+		b.addHTTP = true
+		return nil
+	})
+
 	b.extractHealthCheck()
 }
 
@@ -700,6 +713,7 @@ func (b *hclbServiceOptsBuilder) buildAddServiceOpts() (hcloud.LoadBalancerAddSe
 			CookieLifetime: b.httpOpts.CookieLifetime,
 			Certificates:   b.httpOpts.Certificates,
 			RedirectHTTP:   b.httpOpts.RedirectHTTP,
+			StickySessions: b.httpOpts.StickySessions,
 		}
 	}
 	if b.addHealthCheck {
@@ -743,6 +757,7 @@ func (b *hclbServiceOptsBuilder) buildUpdateServiceOpts() (hcloud.LoadBalancerUp
 			CookieLifetime: b.httpOpts.CookieLifetime,
 			RedirectHTTP:   b.httpOpts.RedirectHTTP,
 			Certificates:   b.httpOpts.Certificates,
+			StickySessions: b.httpOpts.StickySessions,
 		}
 	}
 	if b.addHealthCheck {


Test patch:
diff --git a/internal/hcops/load_balancer_internal_test.go b/internal/hcops/load_balancer_internal_test.go
index 5824b087..b1b424fc 100644
--- a/internal/hcops/load_balancer_internal_test.go
+++ b/internal/hcops/load_balancer_internal_test.go
@@ -60,6 +60,7 @@ func TestHCLBServiceOptsBuilder(t *testing.T) {
 				annotation.LBSvcHTTPCookieLifetime: time.Hour,
 				annotation.LBSvcHTTPCertificates:   []*hcloud.Certificate{{ID: 1}, {ID: 3}},
 				annotation.LBSvcRedirectHTTP:       true,
+				annotation.LBSvcHTTPStickySessions: true,
 			},
 			expectedAddOpts: hcloud.LoadBalancerAddServiceOpts{
 				ListenPort:      hcloud.Int(82),
@@ -71,6 +72,7 @@ func TestHCLBServiceOptsBuilder(t *testing.T) {
 					CookieLifetime: hcloud.Duration(time.Hour),
 					Certificates:   []*hcloud.Certificate{{ID: 1}, {ID: 3}},
 					RedirectHTTP:   hcloud.Bool(true),
+					StickySessions: hcloud.Bool(true),
 				},
 			},
 			expectedUpdateOpts: hcloud.LoadBalancerUpdateServiceOpts{
@@ -82,10 +84,10 @@ func TestHCLBServiceOptsBuilder(t *testing.T) {
 					CookieLifetime: hcloud.Duration(time.Hour),
 					Certificates:   []*hcloud.Certificate{{ID: 1}, {ID: 3}},
 					RedirectHTTP:   hcloud.Bool(true),
+					StickySessions: hcloud.Bool(true),
 				},
 			},
 		},
-		// TODO invalid values for annotations above
 		{
 			name:        "add TCP health check",
 			servicePort: v1.ServicePort{Port: 83, NodePort: 8083},
@@ -122,7 +124,6 @@ func TestHCLBServiceOptsBuilder(t *testing.T) {
 				},
 			},
 		},
-		// TODO invalid values for annotations above
 		{
 			name:        "add HTTP health check",
 			servicePort: v1.ServicePort{Port: 84, NodePort: 8084},