From a8d5a548d83ae03404ea499a3c689b4e5e15f52a Mon Sep 17 00:00:00 2001
From: Dario Tranchitella <dario@tranchitella.eu>
Date: Mon, 10 Mar 2025 17:13:52 +0100
Subject: [PATCH 1/2] fix: validating certificate subject alternative names

Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---
 controllers/kamajicontrolplane_controller_tcp.go | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/controllers/kamajicontrolplane_controller_tcp.go b/controllers/kamajicontrolplane_controller_tcp.go
index c34e696..ef27130 100644
--- a/controllers/kamajicontrolplane_controller_tcp.go
+++ b/controllers/kamajicontrolplane_controller_tcp.go
@@ -6,6 +6,7 @@ package controllers
 import (
 	"context"
 	"fmt"
+	"net"
 	"strings"
 
 	kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1"
@@ -20,6 +21,8 @@ import (
 	"github.com/clastix/cluster-api-control-plane-provider-kamaji/pkg/externalclusterreference"
 )
 
+var ErrUnsupportedCertificateSAN = errors.New("a certificate SAN must be made of host only with no port")
+
 //+kubebuilder:rbac:groups=kamaji.clastix.io,resources=tenantcontrolplanes,verbs=get;list;watch;create;update
 
 //nolint:funlen,gocognit,cyclop
@@ -141,6 +144,15 @@ func (r *KamajiControlPlaneReconciler) createOrUpdateTenantControlPlane(ctx cont
 			tcp.Spec.ControlPlane.Service.ServiceType = kcp.Spec.Network.ServiceType
 			tcp.Spec.ControlPlane.Service.AdditionalMetadata.Labels = kcp.Spec.Network.ServiceLabels
 			tcp.Spec.ControlPlane.Service.AdditionalMetadata.Annotations = kcp.Spec.Network.ServiceAnnotations
+
+			for _, i := range kcp.Spec.Network.CertSANs {
+				// validating CertSANs as soon as possible to avoid github.com/clastix/kamaji/issues/679:
+				// nil err means the entry is in the form of <HOST>:<PORT> which is not accepted
+				if _, _, err := net.SplitHostPort(i); err == nil {
+					return errors.Wrap(ErrUnsupportedCertificateSAN, fmt.Sprintf("entry %s is invalid", i))
+				}
+			}
+
 			tcp.Spec.NetworkProfile.CertSANs = kcp.Spec.Network.CertSANs
 			// Ingress
 			if kcp.Spec.Network.Ingress != nil {

From 9e046d5bb1d2b1c1309cf90975611f988df76684 Mon Sep 17 00:00:00 2001
From: Dario Tranchitella <dario@tranchitella.eu>
Date: Wed, 19 Mar 2025 12:04:10 +0100
Subject: [PATCH 2/2] fix: split host port when adding ingress to certsan

Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---
 controllers/kamajicontrolplane_controller_tcp.go | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/controllers/kamajicontrolplane_controller_tcp.go b/controllers/kamajicontrolplane_controller_tcp.go
index ef27130..1c05c6f 100644
--- a/controllers/kamajicontrolplane_controller_tcp.go
+++ b/controllers/kamajicontrolplane_controller_tcp.go
@@ -169,7 +169,13 @@ func (r *KamajiControlPlaneReconciler) createOrUpdateTenantControlPlane(ctx cont
 					tcp.Spec.NetworkProfile.CertSANs = []string{}
 				}
 
-				tcp.Spec.NetworkProfile.CertSANs = append(tcp.Spec.NetworkProfile.CertSANs, kcp.Spec.Network.Ingress.Hostname)
+				if host, _, err := net.SplitHostPort(kcp.Spec.Network.Ingress.Hostname); err == nil {
+					// no error means <FQDN>:<PORT>, we need the host variable
+					tcp.Spec.NetworkProfile.CertSANs = append(tcp.Spec.NetworkProfile.CertSANs, host)
+				} else {
+					// No port specification, adding bare entry
+					tcp.Spec.NetworkProfile.CertSANs = append(tcp.Spec.NetworkProfile.CertSANs, kcp.Spec.Network.Ingress.Hostname)
+				}
 			} else {
 				tcp.Spec.ControlPlane.Ingress = nil
 			}