You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2021/11/17 09:36:57 UTC

[camel-k] 02/05: chore(heath): Extract port number from readiness probe before proxying via API server

This is an automated email from the ASF dual-hosted git repository.

astefanutti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 3a6651f878676791d407ad56beed41bb57ac481b
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Fri Nov 12 11:44:20 2021 +0100

    chore(heath): Extract port number from readiness probe before proxying via API server
---
 pkg/controller/integration/health.go  | 45 +++++++++++++++++++++++++++++++++--
 pkg/controller/integration/monitor.go |  2 +-
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/pkg/controller/integration/health.go b/pkg/controller/integration/health.go
index e14d241..e56b10a 100644
--- a/pkg/controller/integration/health.go
+++ b/pkg/controller/integration/health.go
@@ -20,10 +20,12 @@ package integration
 import (
 	"context"
 	"fmt"
+	"strconv"
 	"strings"
 	"time"
 
 	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/util/intstr"
 	"k8s.io/client-go/kubernetes"
 )
 
@@ -45,15 +47,54 @@ type HealthCheckResponse struct {
 	Data   map[string]interface{} `json:"data,omitempty"`
 }
 
-func proxyGetHTTPProbe(ctx context.Context, c kubernetes.Interface, p *corev1.Probe, pod *corev1.Pod) ([]byte, error) {
+func proxyGetHTTPProbe(ctx context.Context, c kubernetes.Interface, p *corev1.Probe, pod *corev1.Pod, container *corev1.Container) ([]byte, error) {
 	if p.HTTPGet == nil {
 		return nil, fmt.Errorf("missing probe handler for %s/%s", pod.Namespace, pod.Name)
 	}
 
+	// We have to extract the port number from the HTTP probe in case it's a named port,
+	// as Pod proxying via the API Server does not work with named ports.
+	port, err := extractPortNumber(p.HTTPGet.Port, container)
+	if err != nil {
+		return nil, err
+	}
+
 	probeCtx, cancel := context.WithTimeout(ctx, time.Duration(p.TimeoutSeconds)*time.Second)
 	defer cancel()
 	params := make(map[string]string)
 	return c.CoreV1().Pods(pod.Namespace).
-		ProxyGet(strings.ToLower(string(p.HTTPGet.Scheme)), pod.Name, p.HTTPGet.Port.String(), p.HTTPGet.Path, params).
+		ProxyGet(strings.ToLower(string(p.HTTPGet.Scheme)), pod.Name, strconv.Itoa(port), p.HTTPGet.Path, params).
 		DoRaw(probeCtx)
 }
+
+func extractPortNumber(port intstr.IntOrString, container *corev1.Container) (int, error) {
+	number := -1
+	var err error
+	switch port.Type {
+	case intstr.Int:
+		number = port.IntValue()
+	case intstr.String:
+		if number, err = findPortByName(container, port.StrVal); err != nil {
+			// Last ditch effort - maybe it was an int stored as string?
+			if number, err = strconv.Atoi(port.StrVal); err != nil {
+				return number, err
+			}
+		}
+	default:
+		return number, fmt.Errorf("intOrString had no kind: %+v", port)
+	}
+	if number > 0 && number < 65536 {
+		return number, nil
+	}
+	return number, fmt.Errorf("invalid port number: %v", number)
+}
+
+// findPortByName is a helper function to look up a port in a container by name.
+func findPortByName(container *corev1.Container, portName string) (int, error) {
+	for _, port := range container.Ports {
+		if port.Name == portName {
+			return int(port.ContainerPort), nil
+		}
+	}
+	return 0, fmt.Errorf("port %s not found", portName)
+}
diff --git a/pkg/controller/integration/monitor.go b/pkg/controller/integration/monitor.go
index d4bd5ab..08ee93d 100644
--- a/pkg/controller/integration/monitor.go
+++ b/pkg/controller/integration/monitor.go
@@ -368,7 +368,7 @@ func (action *monitorAction) updateIntegrationPhaseAndReadyCondition(ctx context
 			return fmt.Errorf("integration container not found in Pod %s/%s", pod.Namespace, pod.Name)
 		}
 		if probe := container.ReadinessProbe; probe != nil && probe.HTTPGet != nil {
-			body, err := proxyGetHTTPProbe(ctx, action.client, probe, &pod)
+			body, err := proxyGetHTTPProbe(ctx, action.client, probe, &pod, container)
 			if err == nil {
 				continue
 			}