Skip to content

Commit 5139f99

Browse files
committed
Address review: discoveryClient interface, consolidate flags, cleanup
Replace package-level var overrides (newDiscoveryOAuthArgument, newDiscoveryPersistentAuth, introspectToken) with a discoveryClient interface injected into discoveryLogin(). Tests use fakeDiscoveryClient instead of save/restore globals, reducing boilerplate. Other review feedback: - Consolidate --configure-cluster and --configure-serverless into discoveryIncompatibleFlags (removes separate if blocks) - Remove httpClientForIntrospection(); default http.Client respects system proxy and CA config already - Remove superfluous empty-string guard in splitScopes - Improve comment on key clearing rationale
1 parent 186a91d commit 5139f99

File tree

2 files changed

+156
-237
lines changed

2 files changed

+156
-237
lines changed

cmd/auth/login.go

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"errors"
66
"fmt"
77
"io"
8-
"net/http"
98
"runtime"
109
"strings"
1110
"time"
@@ -66,13 +65,27 @@ type discoveryPersistentAuth interface {
6665
Close() error
6766
}
6867

69-
var newDiscoveryOAuthArgument = u2m.NewBasicDiscoveryOAuthArgument
68+
// discoveryClient abstracts the external dependencies of discoveryLogin so
69+
// they can be replaced in tests without package-level variable mutation.
70+
type discoveryClient interface {
71+
NewOAuthArgument(profileName string) (*u2m.BasicDiscoveryOAuthArgument, error)
72+
NewPersistentAuth(ctx context.Context, opts ...u2m.PersistentAuthOption) (discoveryPersistentAuth, error)
73+
IntrospectToken(ctx context.Context, host, accessToken string) (*auth.IntrospectionResult, error)
74+
}
75+
76+
type defaultDiscoveryClient struct{}
77+
78+
func (d *defaultDiscoveryClient) NewOAuthArgument(profileName string) (*u2m.BasicDiscoveryOAuthArgument, error) {
79+
return u2m.NewBasicDiscoveryOAuthArgument(profileName)
80+
}
7081

71-
var newDiscoveryPersistentAuth = func(ctx context.Context, opts ...u2m.PersistentAuthOption) (discoveryPersistentAuth, error) {
82+
func (d *defaultDiscoveryClient) NewPersistentAuth(ctx context.Context, opts ...u2m.PersistentAuthOption) (discoveryPersistentAuth, error) {
7283
return u2m.NewPersistentAuth(ctx, opts...)
7384
}
7485

75-
var introspectToken = auth.IntrospectToken
86+
func (d *defaultDiscoveryClient) IntrospectToken(ctx context.Context, host, accessToken string) (*auth.IntrospectionResult, error) {
87+
return auth.IntrospectToken(ctx, host, accessToken, nil)
88+
}
7689

7790
func newLoginCommand(authArguments *auth.AuthArguments) *cobra.Command {
7891
defaultConfigPath := "~/.databrickscfg"
@@ -170,16 +183,10 @@ depends on the existing profiles you have set in your configuration file
170183
// If no host is available from any source, use the discovery flow
171184
// via login.databricks.com.
172185
if shouldUseDiscovery(authArguments.Host, args, existingProfile) {
173-
if configureCluster {
174-
return errors.New("--configure-cluster requires --host to be specified")
175-
}
176-
if configureServerless {
177-
return errors.New("--configure-serverless requires --host to be specified")
178-
}
179186
if err := validateDiscoveryFlagCompatibility(cmd); err != nil {
180187
return err
181188
}
182-
return discoveryLogin(ctx, profileName, loginTimeout, scopes, existingProfile, getBrowserFunc(cmd))
189+
return discoveryLogin(ctx, &defaultDiscoveryClient{}, profileName, loginTimeout, scopes, existingProfile, getBrowserFunc(cmd))
183190
}
184191

185192
// Load unified host flags from the profile if not explicitly set via CLI flag
@@ -461,6 +468,8 @@ var discoveryIncompatibleFlags = []string{
461468
"account-id",
462469
"workspace-id",
463470
"experimental-is-unified-host",
471+
"configure-cluster",
472+
"configure-serverless",
464473
}
465474

466475
// validateDiscoveryFlagCompatibility returns an error if any flags that require
@@ -494,8 +503,8 @@ func openURLSuppressingStderr(url string) error {
494503
// discoveryLogin runs the login.databricks.com discovery flow. The user
495504
// authenticates in the browser, selects a workspace, and the CLI receives
496505
// the workspace host from the OAuth callback's iss parameter.
497-
func discoveryLogin(ctx context.Context, profileName string, timeout time.Duration, scopes string, existingProfile *profile.Profile, browserFunc func(string) error) error {
498-
arg, err := newDiscoveryOAuthArgument(profileName)
506+
func discoveryLogin(ctx context.Context, dc discoveryClient, profileName string, timeout time.Duration, scopes string, existingProfile *profile.Profile, browserFunc func(string) error) error {
507+
arg, err := dc.NewOAuthArgument(profileName)
499508
if err != nil {
500509
return discoveryErr("setting up login.databricks.com", err)
501510
}
@@ -518,7 +527,7 @@ func discoveryLogin(ctx context.Context, profileName string, timeout time.Durati
518527
ctx, cancel := context.WithTimeout(ctx, timeout)
519528
defer cancel()
520529

521-
persistentAuth, err := newDiscoveryPersistentAuth(ctx, opts...)
530+
persistentAuth, err := dc.NewPersistentAuth(ctx, opts...)
522531
if err != nil {
523532
return discoveryErr("setting up login.databricks.com", err)
524533
}
@@ -541,9 +550,8 @@ func discoveryLogin(ctx context.Context, profileName string, timeout time.Durati
541550
}
542551

543552
// Best-effort introspection for metadata.
544-
httpClient := httpClientForIntrospection()
545553
var workspaceID string
546-
introspection, err := introspectToken(ctx, discoveredHost, tok.AccessToken, httpClient)
554+
introspection, err := dc.IntrospectToken(ctx, discoveredHost, tok.AccessToken)
547555
if err != nil {
548556
log.Debugf(ctx, "token introspection failed (non-fatal): %v", err)
549557
} else {
@@ -562,10 +570,11 @@ func discoveryLogin(ctx context.Context, profileName string, timeout time.Durati
562570

563571
configFile := env.Get(ctx, "DATABRICKS_CONFIG_FILE")
564572
clearKeys := oauthLoginClearKeys()
565-
// Clear stale routing fields that may exist from a previous login to a
566-
// different host type. Discovery always produces a workspace-level profile.
567-
// workspace_id is cleared and re-written only if introspection returned a
568-
// fresh value, preventing stale IDs from surviving failed introspection.
573+
// Discovery login always produces a workspace-level profile pointing at the
574+
// discovered host. Any previous routing metadata (account_id, workspace_id,
575+
// is_unified_host, cluster_id, serverless_compute_id) from a prior login to
576+
// a different host type must be cleared so they don't leak into the new
577+
// profile. workspace_id is re-added only when introspection succeeds.
569578
clearKeys = append(clearKeys,
570579
"account_id",
571580
"workspace_id",
@@ -594,9 +603,6 @@ func discoveryLogin(ctx context.Context, profileName string, timeout time.Durati
594603

595604
// splitScopes splits a comma-separated scopes string into a trimmed slice.
596605
func splitScopes(scopes string) []string {
597-
if scopes == "" {
598-
return nil
599-
}
600606
var result []string
601607
for _, s := range strings.Split(scopes, ",") {
602608
scope := strings.TrimSpace(s)
@@ -652,11 +658,3 @@ func getBrowserFunc(cmd *cobra.Command) func(url string) error {
652658
}
653659
}
654660
}
655-
656-
// httpClientForIntrospection returns an *http.Client suitable for the
657-
// best-effort token introspection call. It clones http.DefaultTransport
658-
// to inherit system CA certs, proxy settings, and timeouts.
659-
func httpClientForIntrospection() *http.Client {
660-
transport := http.DefaultTransport.(*http.Transport).Clone()
661-
return &http.Client{Transport: transport}
662-
}

0 commit comments

Comments
 (0)