From c64b123cc11f27975b2abe00665ee36dbd0c5b12 Mon Sep 17 00:00:00 2001 From: Victor Sotero Date: Thu, 25 Jun 2026 17:07:02 +0200 Subject: [PATCH] Persist account login hosts as absolute URLs Scheme-less account-console hosts are valid user input during login, but persisting them without https:// leaves later account commands unable to build a valid account configuration. Normalize only classic accounts.* login hosts after existing slash trimming so arbitrary workspace hosts and test placeholders keep their current spelling. Constraint: User input may omit the URL scheme for accounts.cloud.databricks.com. Rejected: Canonicalize every login host | broader behavior change for workspace aliases and existing placeholder inputs. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep login host normalization conservative unless profile matching and saved config compatibility are tested together. Tested: go test ./cmd/auth -run TestSetHost -count=1 Tested: go test ./cmd/auth -count=1 Related: https://github.com/databricks/cli/issues/1403 --- cmd/auth/login.go | 15 ++++++++++++++- cmd/auth/login_test.go | 8 ++++++++ cmd/auth/token_test.go | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index f9f2531ac74..d76cdd27d7b 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -472,7 +472,7 @@ func setHostAndAccountId(ctx context.Context, existingProfile *profile.Profile, } } - authArguments.Host = strings.TrimSuffix(authArguments.Host, "/") + authArguments.Host = normalizeLoginHost(authArguments.Host) // Extract query parameters from the host URL (?o=workspace_id, ?a=account_id). // URL params from explicit --host override stale profile values. @@ -512,6 +512,19 @@ func setHostAndAccountId(ctx context.Context, existingProfile *profile.Profile, return nil } +func normalizeLoginHost(host string) string { + host = strings.TrimSuffix(host, "/") + if strings.Contains(host, "://") { + return host + } + + canonicalHost := (&config.Config{Host: host}).CanonicalHostName() + if auth.IsClassicAccountHost(canonicalHost) { + return "https://" + host + } + return host +} + // needsAccountIDPrompt reports whether the target host requires an account ID // for OAuth URL construction. True for classic account hosts (accounts.*) and // for unified hosts detected via account-scoped DiscoveryURL. diff --git a/cmd/auth/login_test.go b/cmd/auth/login_test.go index a8eafb4be43..b546ff3dd2d 100644 --- a/cmd/auth/login_test.go +++ b/cmd/auth/login_test.go @@ -150,8 +150,16 @@ func TestSetHost(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "https://www.host1.test", authArguments.Host) + // Test setting account console host from flag without scheme + authArguments.Host = "accounts.test/" + authArguments.AccountID = "account-id" + err = setHostAndAccountId(ctx, profile1, &authArguments, []string{}) + assert.NoError(t, err) + assert.Equal(t, "https://accounts.test", authArguments.Host) + // Test setting host from argument authArguments.Host = "" + authArguments.AccountID = "" err = setHostAndAccountId(ctx, profile1, &authArguments, []string{"val from [HOST]"}) assert.NoError(t, err) assert.Equal(t, "val from [HOST]", authArguments.Host) diff --git a/cmd/auth/token_test.go b/cmd/auth/token_test.go index adda6888a40..c3376de358f 100644 --- a/cmd/auth/token_test.go +++ b/cmd/auth/token_test.go @@ -484,7 +484,7 @@ func TestToken_loadToken(t *testing.T) { u2m.WithOAuthEndpointSupplier(&MockApiClient{}), }, }, - wantErr: "acct-dup1 and acct-dup2 match accounts.cloud.databricks.com in . Use --profile to specify which profile to use", + wantErr: "acct-dup1 and acct-dup2 match https://accounts.cloud.databricks.com in . Use --profile to specify which profile to use", }, { name: "workspace host ambiguity — multiple profiles, non-interactive",