From 9ed33d692154b47b211757362c067cbf1b9a5d5b Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Sat, 17 May 2025 20:49:21 -0400 Subject: [PATCH] feat: improve certSANs with hostname and domain support --- pkg/blueprint/templates/default.jsonnet | 18 ++++++++++-------- pkg/services/talos_service.go | 12 ++++++++++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/pkg/blueprint/templates/default.jsonnet b/pkg/blueprint/templates/default.jsonnet index b4b91bd1c..416f195df 100644 --- a/pkg/blueprint/templates/default.jsonnet +++ b/pkg/blueprint/templates/default.jsonnet @@ -31,6 +31,14 @@ local extractBaseUrl(endpoint) = local endpoint = if std.objectHas(context.cluster, "endpoint") then context.cluster.endpoint else if firstNode != null then firstNode.endpoint else ""; local baseUrl = extractBaseUrl(endpoint); +// Build certSANs list +local certSANs = ["localhost", baseUrl] + (if std.objectHas(context.cluster, "controlplanes") && std.objectHas(context.cluster.controlplanes, "nodes") && std.length(std.objectValues(context.cluster.controlplanes.nodes)) > 0 then + local firstNode = std.objectValues(context.cluster.controlplanes.nodes)[0]; + local hostname = firstNode.hostname; + local domain = if std.objectHas(context, "dns") && std.objectHas(context.dns, "domain") then context.dns.domain else ""; + [hostname] + (if domain != "" then [hostname + "." + domain] else []) +else []); + // Build the mirrors dynamically, only if registries are defined local registryMirrors = if std.objectHas(context, "docker") && std.objectHas(context.docker, "registries") then std.foldl( @@ -125,10 +133,7 @@ local terraformConfig = if platform == "local" || platform == "metal" then [ { cluster: { apiServer: { - certSANs: [ - "localhost", - baseUrl, - ], + certSANs: certSANs, }, extraManifests: [ // renovate: datasource=github-releases depName=kubelet-serving-cert-approver package=alex1989hu/kubelet-serving-cert-approver @@ -140,10 +145,7 @@ local terraformConfig = if platform == "local" || platform == "metal" then [ // Merge in the base `machine` config { machine: { - certSANs: [ - "localhost", - baseUrl, - ], + certSANs: certSANs, network: if vmDriver == "docker-desktop" then { interfaces: [ { diff --git a/pkg/services/talos_service.go b/pkg/services/talos_service.go index e6bb359ff..c71a13f91 100644 --- a/pkg/services/talos_service.go +++ b/pkg/services/talos_service.go @@ -82,10 +82,10 @@ func (s *TalosService) SetAddress(address string) error { nodeType = "controlplanes" } - if err := s.configHandler.SetContextValue(fmt.Sprintf("cluster.%s.nodes.%s.hostname", nodeType, s.name), s.name); err != nil { + if err := s.configHandler.SetContextValue(fmt.Sprintf("cluster.%s.nodes.%s.hostname", nodeType, s.name), s.GetHostname()); err != nil { return err } - if err := s.configHandler.SetContextValue(fmt.Sprintf("cluster.%s.nodes.%s.node", nodeType, s.name), s.name); err != nil { + if err := s.configHandler.SetContextValue(fmt.Sprintf("cluster.%s.nodes.%s.node", nodeType, s.name), s.GetHostname()); err != nil { return err } @@ -310,6 +310,14 @@ func (s *TalosService) GetComposeConfig() (*types.Config, error) { // Private Methods // ============================================================================= +// GetHostname returns the hostname without any TLD +func (s *TalosService) GetHostname() string { + if parts := strings.Split(s.name, "."); len(parts) > 1 { + return parts[0] + } + return s.name +} + // validateHostPort parses and validates a host port string in the format "hostPort:nodePort/protocol" // Returns the parsed hostPort, nodePort, and protocol, or an error if validation fails func validateHostPort(hostPortStr string) (uint32, uint32, string, error) {