Repository: hetznercloud/hcloud-cloud-controller-manager
Pull request #239 (2021-09-03 06:15:07)

Health Check: Set healthcheck port to destination port if no port was not defined via annotation
Signed-off-by: Lukas Kämmerling <lukas.kaemmerling@hetzner-cloud.de>


Patch:
diff --git a/internal/hcops/load_balancer.go b/internal/hcops/load_balancer.go
index c2a4e381..9eed2f31 100644
--- a/internal/hcops/load_balancer.go
+++ b/internal/hcops/load_balancer.go
@@ -1027,10 +1027,14 @@ func (b *hclbServiceOptsBuilder) buildAddServiceOpts() (hcloud.LoadBalancerAddSe
 		}
 	}
 	if b.addHealthCheck {
+		port := b.healthCheckOpts.Port
+		if port == nil {
+			port = hcloud.Int(b.destinationPort)
+		}
 		opts.HealthCheck = &hcloud.LoadBalancerAddServiceOptsHealthCheck{
 			Protocol: b.healthCheckOpts.Protocol,
 			Interval: b.healthCheckOpts.Interval,
-			Port:     b.healthCheckOpts.Port,
+			Port:     port,
 			Retries:  b.healthCheckOpts.Retries,
 			Timeout:  b.healthCheckOpts.Timeout,
 		}
@@ -1076,10 +1080,14 @@ func (b *hclbServiceOptsBuilder) buildUpdateServiceOpts() (hcloud.LoadBalancerUp
 		}
 	}
 	if b.addHealthCheck {
+		port := b.healthCheckOpts.Port
+		if port == nil {
+			port = hcloud.Int(b.destinationPort)
+		}
 		opts.HealthCheck = &hcloud.LoadBalancerUpdateServiceOptsHealthCheck{
 			Protocol: b.healthCheckOpts.Protocol,
 			Interval: b.healthCheckOpts.Interval,
-			Port:     b.healthCheckOpts.Port,
+			Port:     port,
 			Retries:  b.healthCheckOpts.Retries,
 			Timeout:  b.healthCheckOpts.Timeout,
 		}


Test patch:
diff --git a/internal/hcops/load_balancer_internal_test.go b/internal/hcops/load_balancer_internal_test.go
index 72a2fa99..0af7c6b9 100644
--- a/internal/hcops/load_balancer_internal_test.go
+++ b/internal/hcops/load_balancer_internal_test.go
@@ -310,6 +310,55 @@ func TestHCLBServiceOptsBuilder(t *testing.T) {
 				},
 			},
 		},
+		{
+			name:        "health check port defaults to node port/destination Port if not specified",
+			servicePort: v1.ServicePort{Port: 84, NodePort: 8084},
+			serviceAnnotations: map[annotation.Name]interface{}{
+				annotation.LBSvcHealthCheckProtocol:                hcloud.LoadBalancerServiceProtocolHTTP,
+				annotation.LBSvcHealthCheckInterval:                time.Hour,
+				annotation.LBSvcHealthCheckTimeout:                 30 * time.Second,
+				annotation.LBSvcHealthCheckRetries:                 5,
+				annotation.LBSvcHealthCheckHTTPDomain:              "example.com",
+				annotation.LBSvcHealthCheckHTTPPath:                "/internal/health",
+				annotation.LBSvcHealthCheckHTTPValidateCertificate: "true",
+				annotation.LBSvcHealthCheckHTTPStatusCodes:         "200,202",
+			},
+			expectedAddOpts: hcloud.LoadBalancerAddServiceOpts{
+				ListenPort:      hcloud.Int(84),
+				DestinationPort: hcloud.Int(8084),
+				Protocol:        hcloud.LoadBalancerServiceProtocolTCP,
+				HealthCheck: &hcloud.LoadBalancerAddServiceOptsHealthCheck{
+					Protocol: hcloud.LoadBalancerServiceProtocolHTTP,
+					Port:     hcloud.Int(8084),
+					Interval: hcloud.Duration(time.Hour),
+					Timeout:  hcloud.Duration(30 * time.Second),
+					Retries:  hcloud.Int(5),
+					HTTP: &hcloud.LoadBalancerAddServiceOptsHealthCheckHTTP{
+						Domain:      hcloud.String("example.com"),
+						Path:        hcloud.String("/internal/health"),
+						TLS:         hcloud.Bool(true),
+						StatusCodes: []string{"200", "202"},
+					},
+				},
+			},
+			expectedUpdateOpts: hcloud.LoadBalancerUpdateServiceOpts{
+				DestinationPort: hcloud.Int(8084),
+				Protocol:        hcloud.LoadBalancerServiceProtocolTCP,
+				HealthCheck: &hcloud.LoadBalancerUpdateServiceOptsHealthCheck{
+					Protocol: hcloud.LoadBalancerServiceProtocolHTTP,
+					Port:     hcloud.Int(8084),
+					Interval: hcloud.Duration(time.Hour),
+					Timeout:  hcloud.Duration(30 * time.Second),
+					Retries:  hcloud.Int(5),
+					HTTP: &hcloud.LoadBalancerUpdateServiceOptsHealthCheckHTTP{
+						Domain:      hcloud.String("example.com"),
+						Path:        hcloud.String("/internal/health"),
+						TLS:         hcloud.Bool(true),
+						StatusCodes: []string{"200", "202"},
+					},
+				},
+			},
+		},
 	}
 
 	for _, tt := range tests {