From 889d83fbdcceadfa2ec6dd64997ed8d0289d5a64 Mon Sep 17 00:00:00 2001 From: Maximilian Rink Date: Mon, 13 Jul 2026 09:53:14 +0200 Subject: [PATCH] Fix CSI controller URL for IPv6 service hosts Build the CSI controller REST endpoint with net.JoinHostPort so IPv6 service hosts from Kubernetes environment variables are bracketed correctly while preserving IPv4 and DNS host behavior. Add unit coverage for IPv6, IPv4, and DNS controller hosts. Fixes #1164 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Maximilian Rink --- frontend/csi/plugin.go | 9 +++++++-- frontend/csi/plugin_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/frontend/csi/plugin.go b/frontend/csi/plugin.go index 2d4bb7a23..6fb866577 100644 --- a/frontend/csi/plugin.go +++ b/frontend/csi/plugin.go @@ -5,6 +5,7 @@ package csi import ( "context" "fmt" + "net" "os" "runtime" "strings" @@ -42,6 +43,10 @@ const ( CSIAllInOne = "allInOne" ) +func controllerRestURL(host, port string) string { + return "https://" + net.JoinHostPort(host, port) +} + type Plugin struct { orchestrator core.Orchestrator activatedChan chan struct{} @@ -262,7 +267,7 @@ func NewNodePlugin( hostname = tridentconfig.ServerCertName } - restURL := "https://" + hostname + ":" + port + restURL := controllerRestURL(hostname, port) p.restClient, err = controllerAPI.CreateTLSRestClient(restURL, caCert, clientCert, clientKey) if err != nil { return nil, err @@ -354,7 +359,7 @@ func NewAllInOnePlugin( break } } - restURL := "https://" + tridentconfig.ServerCertName + ":" + port + restURL := controllerRestURL(tridentconfig.ServerCertName, port) p.restClient, err = controllerAPI.CreateTLSRestClient(restURL, caCert, clientCert, clientKey) if err != nil { return nil, err diff --git a/frontend/csi/plugin_test.go b/frontend/csi/plugin_test.go index ffde05caa..8ba43481c 100644 --- a/frontend/csi/plugin_test.go +++ b/frontend/csi/plugin_test.go @@ -37,6 +37,40 @@ import ( "github.com/netapp/trident/utils/osutils" ) +func TestControllerRestURL(t *testing.T) { + testCases := []struct { + name string + host string + port string + expected string + }{ + { + name: "IPv6 address", + host: "2001:db8::1", + port: "34571", + expected: "https://[2001:db8::1]:34571", + }, + { + name: "IPv4 address", + host: "192.0.2.10", + port: "34571", + expected: "https://192.0.2.10:34571", + }, + { + name: "DNS name", + host: "trident-csi", + port: "34571", + expected: "https://trident-csi:34571", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expected, controllerRestURL(tc.host, tc.port)) + }) + } +} + func TestNewControllerPlugin(t *testing.T) { testCases := []struct { name string