From be62e6dc68650c986c76c69df2d75ad204034e14 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 11 Mar 2026 20:17:05 +0000 Subject: [PATCH] tsnet: make tsnet fallback to control url from environment This commit adds a "fallback" mechanism to tsnet to allow the consumer to set "TS_CONTROL_URL" to override the control server. This allows tsnet applications to gain support for an alternative control server by just updating without explicitly exposing the ControlURL option. Updates #16934 Signed-off-by: Kristoffer Dalby --- tsnet/tsnet.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tsnet/tsnet.go b/tsnet/tsnet.go index 4a116cf34..38ea86599 100644 --- a/tsnet/tsnet.go +++ b/tsnet/tsnet.go @@ -151,6 +151,8 @@ type Server struct { // ControlURL optionally specifies the coordination server URL. // If empty, the Tailscale default is used. + // If empty, it defaults to the TS_CONTROL_URL environment variable. + // If that is also empty, the Tailscale default is used. ControlURL string // RunWebClient, if true, runs a client for managing this node over @@ -568,6 +570,13 @@ func (s *Server) getAuthKey() string { return os.Getenv("TS_AUTH_KEY") } +func (s *Server) getControlURL() string { + if v := s.ControlURL; v != "" { + return v + } + return os.Getenv("TS_CONTROL_URL") +} + func (s *Server) getClientSecret() string { if v := s.ClientSecret; v != "" { return v @@ -769,7 +778,7 @@ func (s *Server) start() (reterr error) { prefs := ipn.NewPrefs() prefs.Hostname = s.hostname prefs.WantRunning = true - prefs.ControlURL = s.ControlURL + prefs.ControlURL = s.getControlURL() prefs.RunWebClient = s.RunWebClient prefs.AdvertiseTags = s.AdvertiseTags authKey, err := s.resolveAuthKey() @@ -858,7 +867,7 @@ func (s *Server) resolveAuthKey() (string, error) { return "", fmt.Errorf("audience for workload identity federation found, but client ID is empty") } } - authKey, err = resolveViaWIF(s.shutdownCtx, s.ControlURL, clientID, idToken, audience, s.AdvertiseTags) + authKey, err = resolveViaWIF(s.shutdownCtx, s.getControlURL(), clientID, idToken, audience, s.AdvertiseTags) if err != nil { return "", err }