From 497dc02c1245cc225b276483e9488f53fac8447d Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Wed, 4 Jun 2025 13:09:49 -0700 Subject: [PATCH 01/12] Preserve custom profile fields during 'databricks auth login' (#1897) --- cmd/auth/login.go | 47 ++++++++++++++++++++++---------- cmd/auth/login_test.go | 21 ++++++++++++++ cmd/auth/testdata/.databrickscfg | 5 ++++ 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index 9fd1ee519e..231e6fbe34 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -136,20 +136,7 @@ depends on the existing profiles you have set in your configuration file return err } - if configureCluster { - w, err := databricks.NewWorkspaceClient((*databricks.Config)(&cfg)) - if err != nil { - return err - } - ctx := cmd.Context() - clusterID, err := cfgpickers.AskForCluster(ctx, w, - cfgpickers.WithDatabricksConnect(minimalDbConnectVersion)) - if err != nil { - return err - } - cfg.ClusterID = clusterID - } - + cfg.ClusterID, err = getClusterID(ctx, profileName, &cfg, configureCluster, defaultConfigPath) if profileName != "" { err = databrickscfg.SaveToProfile(ctx, &config.Config{ Profile: profileName, @@ -245,3 +232,35 @@ func getProfileName(authArguments *auth.AuthArguments) string { split := strings.Split(host, ".") return split[0] } + +func getClusterID(ctx context.Context, profileName string, cfg *config.Config, configureCluster bool, configPath string) (string, error) { + if !configureCluster { + return readClusterIDFromConfig(configPath, profileName) + } + + w, err := databricks.NewWorkspaceClient((*databricks.Config)(cfg)) + if err != nil { + return "", err + } + configuredClusterID, err := cfgpickers.AskForCluster(ctx, w, + cfgpickers.WithDatabricksConnect(minimalDbConnectVersion)) + if err != nil { + return "", err + } + return configuredClusterID, nil +} + +func readClusterIDFromConfig(configPath string, profileName string) (string, error) { + // Load cluster ID from the config file on disk. + configFile, err := config.LoadFile(configPath) + if err != nil { + return "", err + } + + section, err := configFile.GetSection(profileName) + if err != nil { + return "", err + } + + return section.Key("cluster_id").String(), nil +} diff --git a/cmd/auth/login_test.go b/cmd/auth/login_test.go index 8412dab2ce..21b5fe5d20 100644 --- a/cmd/auth/login_test.go +++ b/cmd/auth/login_test.go @@ -8,6 +8,7 @@ import ( "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/databrickscfg/profile" "github.com/databricks/cli/libs/env" + "github.com/databricks/databricks-sdk-go/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -84,3 +85,23 @@ func TestSetAccountId(t *testing.T) { err = setHostAndAccountId(ctx, profile.DefaultProfiler, "", &authArguments, []string{}) assert.EqualError(t, err, "the command is being run in a non-interactive environment, please specify an account ID using --account-id") } + +func TestLoginPreservesClusterID(t *testing.T) { + var authArguments auth.AuthArguments + t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") + ctx, _ := cmdio.SetupTest(context.Background()) + + err := setHostAndAccountId(ctx, profile.DefaultProfiler, "cluster-profile", &authArguments, []string{}) + require.NoError(t, err) + assert.Equal(t, "https://www.host2.com", authArguments.Host) + + cfg := config.Config{ + Host: authArguments.Host, + AccountID: authArguments.AccountID, + AuthType: "databricks-cli", + } + + clusterID, err := getClusterID(ctx, "cluster-profile", &cfg, false, "./testdata/.databrickscfg") + require.NoError(t, err) + assert.Equal(t, "cluster-from-config", clusterID) +} diff --git a/cmd/auth/testdata/.databrickscfg b/cmd/auth/testdata/.databrickscfg index 06e55224a1..3c433db193 100644 --- a/cmd/auth/testdata/.databrickscfg +++ b/cmd/auth/testdata/.databrickscfg @@ -7,3 +7,8 @@ host = https://www.host2.com [account-profile] host = https://accounts.cloud.databricks.com account_id = id-from-profile + + +[cluster-profile] +host = https://www.host2.com +cluster_id = cluster-from-config From 1cca51a183063d28e976c2d6eb56e15eda48f139 Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Wed, 4 Jun 2025 18:18:28 -0700 Subject: [PATCH 02/12] refactoring cluster id function --- cmd/auth/login.go | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index 231e6fbe34..5e50b88a53 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -235,7 +235,17 @@ func getProfileName(authArguments *auth.AuthArguments) string { func getClusterID(ctx context.Context, profileName string, cfg *config.Config, configureCluster bool, configPath string) (string, error) { if !configureCluster { - return readClusterIDFromConfig(configPath, profileName) + configFile, err := config.LoadFile(configPath) + if err != nil { + return "", err + } + + section, err := configFile.GetSection(profileName) + if err != nil { + return "", err + } + + return section.Key("cluster_id").String(), nil } w, err := databricks.NewWorkspaceClient((*databricks.Config)(cfg)) @@ -249,18 +259,3 @@ func getClusterID(ctx context.Context, profileName string, cfg *config.Config, c } return configuredClusterID, nil } - -func readClusterIDFromConfig(configPath string, profileName string) (string, error) { - // Load cluster ID from the config file on disk. - configFile, err := config.LoadFile(configPath) - if err != nil { - return "", err - } - - section, err := configFile.GetSection(profileName) - if err != nil { - return "", err - } - - return section.Key("cluster_id").String(), nil -} From ec4819a44ca20131d8422fbc295983cf218d4829 Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Thu, 5 Jun 2025 11:54:17 -0700 Subject: [PATCH 03/12] Address code review comments of missing profile section and error check, added test cases --- cmd/auth/login.go | 8 ++++++++ cmd/auth/login_test.go | 25 +++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index 5e50b88a53..8d654b5d5a 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -137,6 +137,10 @@ depends on the existing profiles you have set in your configuration file } cfg.ClusterID, err = getClusterID(ctx, profileName, &cfg, configureCluster, defaultConfigPath) + if err != nil { + return err + } + if profileName != "" { err = databrickscfg.SaveToProfile(ctx, &config.Config{ Profile: profileName, @@ -240,6 +244,10 @@ func getClusterID(ctx context.Context, profileName string, cfg *config.Config, c return "", err } + if !configFile.HasSection(profileName) { + return "", nil + } + section, err := configFile.GetSection(profileName) if err != nil { return "", err diff --git a/cmd/auth/login_test.go b/cmd/auth/login_test.go index 21b5fe5d20..9672318f49 100644 --- a/cmd/auth/login_test.go +++ b/cmd/auth/login_test.go @@ -87,21 +87,22 @@ func TestSetAccountId(t *testing.T) { } func TestLoginPreservesClusterID(t *testing.T) { - var authArguments auth.AuthArguments t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") - ctx, _ := cmdio.SetupTest(context.Background()) - - err := setHostAndAccountId(ctx, profile.DefaultProfiler, "cluster-profile", &authArguments, []string{}) + clusterID, err := getClusterID(context.Background(), "cluster-profile", &config.Config{}, false, "./testdata/.databrickscfg") require.NoError(t, err) - assert.Equal(t, "https://www.host2.com", authArguments.Host) + assert.Equal(t, "cluster-from-config", clusterID) +} - cfg := config.Config{ - Host: authArguments.Host, - AccountID: authArguments.AccountID, - AuthType: "databricks-cli", - } +func TestLoginPreservesClusterIDWithEmptyHostAndAccountID(t *testing.T) { + t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") + clusterID, err := getClusterID(context.Background(), "no-profile", &config.Config{}, false, "./testdata/.databrickscfg") + require.NoError(t, err) + assert.Equal(t, "", clusterID) +} - clusterID, err := getClusterID(ctx, "cluster-profile", &cfg, false, "./testdata/.databrickscfg") +func TestLoginNoClusterIDWithAccountProfile(t *testing.T) { + t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") + clusterID, err := getClusterID(context.Background(), "account-profile", &config.Config{}, false, "./testdata/.databrickscfg") require.NoError(t, err) - assert.Equal(t, "cluster-from-config", clusterID) + assert.Equal(t, "", clusterID) } From 9977de1a3b373aeda08505094a58055794417691 Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Fri, 6 Jun 2025 11:51:14 -0700 Subject: [PATCH 04/12] Add changelog entry for cluster_id preservation fix --- NEXT_CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 655f3c11dc..3bdbc11698 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -7,6 +7,7 @@ ### Dependency updates ### CLI +- Fixed an issue where running `databricks auth login` would remove the `cluster_id` field from profiles in `.databrickscfg`. The login process now preserves the `cluster_id` field. Also added a test to ensure `cluster_id` is retained after login. ([#2988](https://github.com/databricks/cli/pull/2988)) ### Bundles From f183cf505998dbf89aaa974392cfa385fae849d1 Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Thu, 12 Jun 2025 18:44:38 -0700 Subject: [PATCH 05/12] refactored clusterID to only read config file --- NEXT_CHANGELOG.md | 2 +- cmd/auth/login.go | 54 ++++++++++++++++++++++-------------------- cmd/auth/login_test.go | 7 +++--- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index b07eb08a74..10ecfe34c0 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -9,7 +9,7 @@ ### Dependency updates ### CLI -* Fixed an issue where running `databricks auth login` would remove the `cluster_id` field from profiles in `.databrickscfg`. The login process now preserves the `cluster_id` field. Also added a test to ensure `cluster_id` is retained after login. ([#2988](https://github.com/databricks/cli/pull/2988)) +* Fixed an issue where running `databricks auth login` would remove the `cluster_id` field from profiles in `.databrickscfg`. The login process now preserves the `cluster_id` field. ([#2988](https://github.com/databricks/cli/pull/2988)) * Use OS aware runner instead of bash for run-local command ([#2996](https://github.com/databricks/cli/pull/2996)) ### Bundles diff --git a/cmd/auth/login.go b/cmd/auth/login.go index 8d654b5d5a..0ba1aee352 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -136,9 +136,24 @@ depends on the existing profiles you have set in your configuration file return err } - cfg.ClusterID, err = getClusterID(ctx, profileName, &cfg, configureCluster, defaultConfigPath) - if err != nil { - return err + if configureCluster { + w, err := databricks.NewWorkspaceClient((*databricks.Config)(&cfg)) + if err != nil { + return err + } + ctx := cmd.Context() + clusterID, err := cfgpickers.AskForCluster(ctx, w, + cfgpickers.WithDatabricksConnect(minimalDbConnectVersion)) + if err != nil { + return err + } + cfg.ClusterID = clusterID + } else { + cfg.ClusterID, err = getClusterID(ctx, profileName, defaultConfigPath) + if err != nil { + return err + } + } if profileName != "" { @@ -237,33 +252,20 @@ func getProfileName(authArguments *auth.AuthArguments) string { return split[0] } -func getClusterID(ctx context.Context, profileName string, cfg *config.Config, configureCluster bool, configPath string) (string, error) { - if !configureCluster { - configFile, err := config.LoadFile(configPath) - if err != nil { - return "", err - } - - if !configFile.HasSection(profileName) { - return "", nil - } - - section, err := configFile.GetSection(profileName) - if err != nil { - return "", err - } - - return section.Key("cluster_id").String(), nil - } - - w, err := databricks.NewWorkspaceClient((*databricks.Config)(cfg)) +func getClusterID(ctx context.Context, profileName, configPath string) (string, error) { + configFile, err := config.LoadFile(configPath) if err != nil { return "", err } - configuredClusterID, err := cfgpickers.AskForCluster(ctx, w, - cfgpickers.WithDatabricksConnect(minimalDbConnectVersion)) + + if !configFile.HasSection(profileName) { + return "", nil + } + + section, err := configFile.GetSection(profileName) if err != nil { return "", err } - return configuredClusterID, nil + + return section.Key("cluster_id").String(), nil } diff --git a/cmd/auth/login_test.go b/cmd/auth/login_test.go index 9672318f49..cd80dc0465 100644 --- a/cmd/auth/login_test.go +++ b/cmd/auth/login_test.go @@ -8,7 +8,6 @@ import ( "github.com/databricks/cli/libs/cmdio" "github.com/databricks/cli/libs/databrickscfg/profile" "github.com/databricks/cli/libs/env" - "github.com/databricks/databricks-sdk-go/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -88,21 +87,21 @@ func TestSetAccountId(t *testing.T) { func TestLoginPreservesClusterID(t *testing.T) { t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") - clusterID, err := getClusterID(context.Background(), "cluster-profile", &config.Config{}, false, "./testdata/.databrickscfg") + clusterID, err := getClusterID(context.Background(), "cluster-profile", "./testdata/.databrickscfg") require.NoError(t, err) assert.Equal(t, "cluster-from-config", clusterID) } func TestLoginPreservesClusterIDWithEmptyHostAndAccountID(t *testing.T) { t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") - clusterID, err := getClusterID(context.Background(), "no-profile", &config.Config{}, false, "./testdata/.databrickscfg") + clusterID, err := getClusterID(context.Background(), "no-profile", "./testdata/.databrickscfg") require.NoError(t, err) assert.Equal(t, "", clusterID) } func TestLoginNoClusterIDWithAccountProfile(t *testing.T) { t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") - clusterID, err := getClusterID(context.Background(), "account-profile", &config.Config{}, false, "./testdata/.databrickscfg") + clusterID, err := getClusterID(context.Background(), "account-profile", "./testdata/.databrickscfg") require.NoError(t, err) assert.Equal(t, "", clusterID) } From 102b1c2021db30d568494a163c0d16e4cb23691a Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Fri, 13 Jun 2025 15:26:47 -0700 Subject: [PATCH 06/12] updated changelog --- NEXT_CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 9d3e18dcf2..7ec44ee464 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -8,7 +8,6 @@ ### CLI * Fixed an issue where running `databricks auth login` would remove the `cluster_id` field from profiles in `.databrickscfg`. The login process now preserves the `cluster_id` field. ([#2988](https://github.com/databricks/cli/pull/2988)) -* Use OS aware runner instead of bash for run-local command ([#2996](https://github.com/databricks/cli/pull/2996)) ### Bundles * Fix reading dashboard contents when the sync root is different than the bundle root ([#3006](https://github.com/databricks/cli/pull/3006)) From 8ddc65e4d090742ac1ef633ff291ee6ee311f504 Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Tue, 17 Jun 2025 16:30:04 -0700 Subject: [PATCH 07/12] Refactoring of tests with comments --- cmd/auth/login.go | 14 +++++----- cmd/auth/login_test.go | 45 ++++++++++++++++++++------------ cmd/auth/testdata/.databrickscfg | 1 - 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index 0ba1aee352..d1e6ccf040 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -136,6 +136,14 @@ depends on the existing profiles you have set in your configuration file return err } + // Bug fix: Preserve cluster_id from existing profile during login + // Prior to v0.233.0, the login command would overwrite the entire profile configuration, + // causing loss of cluster_id and other settings. Now we first retrieve the existing + // cluster_id before saving the new configuration to ensure it's preserved. + cfg.ClusterID, err = getClusterID(ctx, profileName, defaultConfigPath) + if err != nil { + return err + } if configureCluster { w, err := databricks.NewWorkspaceClient((*databricks.Config)(&cfg)) if err != nil { @@ -148,12 +156,6 @@ depends on the existing profiles you have set in your configuration file return err } cfg.ClusterID = clusterID - } else { - cfg.ClusterID, err = getClusterID(ctx, profileName, defaultConfigPath) - if err != nil { - return err - } - } if profileName != "" { diff --git a/cmd/auth/login_test.go b/cmd/auth/login_test.go index cd80dc0465..9aaa813e10 100644 --- a/cmd/auth/login_test.go +++ b/cmd/auth/login_test.go @@ -85,23 +85,36 @@ func TestSetAccountId(t *testing.T) { assert.EqualError(t, err, "the command is being run in a non-interactive environment, please specify an account ID using --account-id") } -func TestLoginPreservesClusterID(t *testing.T) { - t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") - clusterID, err := getClusterID(context.Background(), "cluster-profile", "./testdata/.databrickscfg") - require.NoError(t, err) - assert.Equal(t, "cluster-from-config", clusterID) -} +func TestLoginGetClusterID(t *testing.T) { + testCases := []struct { + name string + profile string + expected string + }{ + { + name: "existing cluster profile", + profile: "cluster-profile", + expected: "cluster-from-config", + }, + { + name: "empty profile", + profile: "no-profile", + expected: "", + }, + { + name: "account profile", + profile: "account-profile", + expected: "", + }, + } -func TestLoginPreservesClusterIDWithEmptyHostAndAccountID(t *testing.T) { t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") - clusterID, err := getClusterID(context.Background(), "no-profile", "./testdata/.databrickscfg") - require.NoError(t, err) - assert.Equal(t, "", clusterID) -} -func TestLoginNoClusterIDWithAccountProfile(t *testing.T) { - t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") - clusterID, err := getClusterID(context.Background(), "account-profile", "./testdata/.databrickscfg") - require.NoError(t, err) - assert.Equal(t, "", clusterID) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + clusterID, err := getClusterID(context.Background(), tc.profile, "./testdata/.databrickscfg") + require.NoError(t, err) + assert.Equal(t, tc.expected, clusterID) + }) + } } diff --git a/cmd/auth/testdata/.databrickscfg b/cmd/auth/testdata/.databrickscfg index 3c433db193..39b08f8ef7 100644 --- a/cmd/auth/testdata/.databrickscfg +++ b/cmd/auth/testdata/.databrickscfg @@ -8,7 +8,6 @@ host = https://www.host2.com host = https://accounts.cloud.databricks.com account_id = id-from-profile - [cluster-profile] host = https://www.host2.com cluster_id = cluster-from-config From b77aa736e83afd686b4c4ec1abcd6bffd9d3a13d Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Wed, 18 Jun 2025 16:52:06 -0700 Subject: [PATCH 08/12] section from config logic --- cmd/auth/login.go | 32 ++++++++++++-------- cmd/auth/login_test.go | 50 ++++++++++++++++++++++---------- cmd/auth/testdata/.databrickscfg | 4 +++ 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index d1e6ccf040..d7559c3975 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -140,7 +140,7 @@ depends on the existing profiles you have set in your configuration file // Prior to v0.233.0, the login command would overwrite the entire profile configuration, // causing loss of cluster_id and other settings. Now we first retrieve the existing // cluster_id before saving the new configuration to ensure it's preserved. - cfg.ClusterID, err = getClusterID(ctx, profileName, defaultConfigPath) + cfg.ClusterID, err = getClusterID(ctx, profileName) if err != nil { return err } @@ -254,20 +254,28 @@ func getProfileName(authArguments *auth.AuthArguments) string { return split[0] } -func getClusterID(ctx context.Context, profileName, configPath string) (string, error) { - configFile, err := config.LoadFile(configPath) +func getClusterID(ctx context.Context, profileName string) (string, error) { + file, err := profile.DefaultProfiler.Get(ctx) if err != nil { - return "", err - } - - if !configFile.HasSection(profileName) { - return "", nil + // If no configuration file exists, return empty string (no error) + if errors.Is(err, profile.ErrNoConfiguration) { + return "", nil + } + return "", fmt.Errorf("cannot load Databricks config file: %w", err) } - section, err := configFile.GetSection(profileName) - if err != nil { - return "", err + for _, v := range file.Sections() { + if v.Name() != profileName { + continue + } + all := v.KeysHash() + _, ok := all["host"] + if !ok { + // invalid profile, skip + continue + } + return all["cluster_id"], nil } - return section.Key("cluster_id").String(), nil + return "", nil } diff --git a/cmd/auth/login_test.go b/cmd/auth/login_test.go index 9aaa813e10..a51b01682d 100644 --- a/cmd/auth/login_test.go +++ b/cmd/auth/login_test.go @@ -87,34 +87,52 @@ func TestSetAccountId(t *testing.T) { func TestLoginGetClusterID(t *testing.T) { testCases := []struct { - name string - profile string - expected string + name string + profile string + configFileEnv string + expected string }{ { - name: "existing cluster profile", - profile: "cluster-profile", - expected: "cluster-from-config", + name: "cluster profile", + profile: "cluster-profile", + configFileEnv: "./testdata/.databrickscfg", + expected: "cluster-from-config", }, { - name: "empty profile", - profile: "no-profile", - expected: "", + name: "empty profile", + profile: "no-profile", + configFileEnv: "./testdata/.databrickscfg", + expected: "", }, { - name: "account profile", - profile: "account-profile", - expected: "", + name: "account profile", + profile: "account-profile", + configFileEnv: "./testdata/.databrickscfg", + expected: "", + }, + { + name: "config doesn't exist", + profile: "any-profile", + configFileEnv: "./nonexistent/.databrickscfg", + expected: "", + }, + { + name: "invalid profile (missing host)", + profile: "invalid-profile", + configFileEnv: "./testdata/.databrickscfg", + expected: "", }, } - t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") - for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - clusterID, err := getClusterID(context.Background(), tc.profile, "./testdata/.databrickscfg") + t.Setenv("DATABRICKS_CONFIG_FILE", tc.configFileEnv) + + clusterID, err := getClusterID(context.Background(), tc.profile) require.NoError(t, err) - assert.Equal(t, tc.expected, clusterID) + assert.Equal(t, tc.expected, clusterID, + "Test case '%s' failed: expected cluster ID '%s', but got '%s' (profile: %s, config file: %s)", + tc.name, tc.expected, clusterID, tc.profile, tc.configFileEnv) }) } } diff --git a/cmd/auth/testdata/.databrickscfg b/cmd/auth/testdata/.databrickscfg index 39b08f8ef7..192839b9be 100644 --- a/cmd/auth/testdata/.databrickscfg +++ b/cmd/auth/testdata/.databrickscfg @@ -11,3 +11,7 @@ account_id = id-from-profile [cluster-profile] host = https://www.host2.com cluster_id = cluster-from-config + +[invalid-profile] +# This profile is missing the required 'host' field +cluster_id = some-cluster-id From b73caddf840fdb95dc32801728f7f0d82e6ed0a0 Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Fri, 20 Jun 2025 15:09:11 -0700 Subject: [PATCH 09/12] added clusterid to profile --- cmd/auth/login.go | 78 +++++++--------- cmd/auth/login_test.go | 116 ++++++++++++++++-------- cmd/auth/token.go | 7 +- libs/databrickscfg/profile/file.go | 1 + libs/databrickscfg/profile/file_test.go | 7 +- libs/databrickscfg/profile/profile.go | 4 +- 6 files changed, 126 insertions(+), 87 deletions(-) diff --git a/cmd/auth/login.go b/cmd/auth/login.go index cb44d92701..46f279489a 100644 --- a/cmd/auth/login.go +++ b/cmd/auth/login.go @@ -106,11 +106,22 @@ depends on the existing profiles you have set in your configuration file } } + existingProfile, err := loadProfileByName(ctx, profileName, profile.DefaultProfiler) + if err != nil { + return err + } + // Set the host and account-id based on the provided arguments and flags. - err := setHostAndAccountId(ctx, profile.DefaultProfiler, profileName, authArguments, args) + err = setHostAndAccountId(ctx, existingProfile, authArguments, args) if err != nil { return err } + + clusterID := "" + if existingProfile != nil { + clusterID = existingProfile.ClusterID + } + oauthArgument, err := authArguments.ToOAuthArgument() if err != nil { return err @@ -127,6 +138,7 @@ depends on the existing profiles you have set in your configuration file Host: authArguments.Host, AccountID: authArguments.AccountID, AuthType: "databricks-cli", + ClusterID: clusterID, } ctx, cancel := context.WithTimeout(ctx, loginTimeout) @@ -136,14 +148,6 @@ depends on the existing profiles you have set in your configuration file return err } - // Bug fix: Preserve cluster_id from existing profile during login - // Prior to v0.233.0, the login command would overwrite the entire profile configuration, - // causing loss of cluster_id and other settings. Now we first retrieve the existing - // cluster_id before saving the new configuration to ensure it's preserved. - cfg.ClusterID, err = getClusterID(ctx, profileName) - if err != nil { - return err - } if configureCluster { w, err := databricks.NewWorkspaceClient((*databricks.Config)(&cfg)) if err != nil { @@ -190,7 +194,7 @@ depends on the existing profiles you have set in your configuration file // 1. --account-id flag. // 2. account-id from the specified profile, if available. // 3. Prompt the user for the account-id. -func setHostAndAccountId(ctx context.Context, profiler profile.Profiler, profileName string, authArguments *auth.AuthArguments, args []string) error { +func setHostAndAccountId(ctx context.Context, existingProfile *profile.Profile, authArguments *auth.AuthArguments, args []string) error { // If both [HOST] and --host are provided, return an error. host := authArguments.Host if len(args) > 0 && host != "" { @@ -198,19 +202,13 @@ func setHostAndAccountId(ctx context.Context, profiler profile.Profiler, profile } // If the chosen profile has a hostname and the user hasn't specified a host, infer the host from the profile. - profiles, err := profiler.LoadProfiles(ctx, profile.WithName(profileName)) - // Tolerate ErrNoConfiguration here, as we will write out a configuration as part of the login flow. - if err != nil && !errors.Is(err, profile.ErrNoConfiguration) { - return err - } - if host == "" { if len(args) > 0 { // If [HOST] is provided, set the host to the provided positional argument. authArguments.Host = args[0] - } else if len(profiles) > 0 && profiles[0].Host != "" { + } else if existingProfile != nil && existingProfile.Host != "" { // If neither [HOST] nor --host are provided, and the profile has a host, use it. - authArguments.Host = profiles[0].Host + authArguments.Host = existingProfile.Host } else { // If neither [HOST] nor --host are provided, and the profile does not have a host, // then prompt the user for a host. @@ -227,8 +225,8 @@ func setHostAndAccountId(ctx context.Context, profiler profile.Profiler, profile isAccountClient := (&config.Config{Host: authArguments.Host}).IsAccountClient() accountID := authArguments.AccountID if isAccountClient && accountID == "" { - if len(profiles) > 0 && profiles[0].AccountID != "" { - authArguments.AccountID = profiles[0].AccountID + if existingProfile != nil && existingProfile.AccountID != "" { + authArguments.AccountID = existingProfile.AccountID } else { // Prompt user for the account-id if it we could not get it from a // profile. @@ -254,32 +252,24 @@ func getProfileName(authArguments *auth.AuthArguments) string { return split[0] } -func getClusterID(ctx context.Context, profileName string) (string, error) { - file, err := profile.DefaultProfiler.Get(ctx) - if err != nil { - // If no configuration file exists, return empty string (no error) - if errors.Is(err, profile.ErrNoConfiguration) { - return "", nil - } - return "", fmt.Errorf("cannot load Databricks config file: %w", err) +func loadProfileByName(ctx context.Context, profileName string, profiler profile.Profiler) (*profile.Profile, error) { + if profileName == "" { + return nil, nil } - // file.Sections() is used in LoadProfiles() to iterate over profiles in login. - // Even with multiple profiles of the same name in the config file, - // it associates each profile name to at most one section. - // It takes the cluster_id if any profiles of the same name have it. - for _, v := range file.Sections() { - if v.Name() != profileName { - continue - } - all := v.KeysHash() - _, ok := all["host"] - if !ok { - // invalid profile, skip - continue - } - return all["cluster_id"], nil + if profiler == nil { + return nil, errors.New("profiler cannot be nil") } - return "", nil + profiles, err := profiler.LoadProfiles(ctx, profile.WithName(profileName)) + // Tolerate ErrNoConfiguration here, as we will write out a configuration as part of the login flow. + if err != nil && !errors.Is(err, profile.ErrNoConfiguration) { + return nil, err + } + + if len(profiles) > 0 { + // LoadProfiles returns only one profile per name, even with multiple profiles in the config file with the same name. + return &profiles[0], nil + } + return nil, nil } diff --git a/cmd/auth/login_test.go b/cmd/auth/login_test.go index a51b01682d..9bf1c4740e 100644 --- a/cmd/auth/login_test.go +++ b/cmd/auth/login_test.go @@ -12,50 +12,64 @@ import ( "github.com/stretchr/testify/require" ) +func loadTestProfile(t *testing.T, ctx context.Context, profileName string) *profile.Profile { + profile, err := loadProfileByName(ctx, profileName, profile.DefaultProfiler) + require.NoError(t, err) + require.NotNil(t, profile) + return profile +} + func TestSetHostDoesNotFailWithNoDatabrickscfg(t *testing.T) { ctx := context.Background() ctx = env.Set(ctx, "DATABRICKS_CONFIG_FILE", "./imaginary-file/databrickscfg") - err := setHostAndAccountId(ctx, profile.DefaultProfiler, "foo", &auth.AuthArguments{Host: "test"}, []string{}) + + existingProfile, err := loadProfileByName(ctx, "foo", profile.DefaultProfiler) + assert.NoError(t, err) + + err = setHostAndAccountId(ctx, existingProfile, &auth.AuthArguments{Host: "test"}, []string{}) assert.NoError(t, err) } func TestSetHost(t *testing.T) { - authArguments := auth.AuthArguments{} + var authArguments auth.AuthArguments t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") ctx, _ := cmdio.SetupTest(context.Background()) + profile1 := loadTestProfile(t, ctx, "profile-1") + profile2 := loadTestProfile(t, ctx, "profile-2") + // Test error when both flag and argument are provided authArguments.Host = "val from --host" - err := setHostAndAccountId(ctx, profile.DefaultProfiler, "profile-1", &authArguments, []string{"val from [HOST]"}) + err := setHostAndAccountId(ctx, profile1, &authArguments, []string{"val from [HOST]"}) assert.EqualError(t, err, "please only provide a host as an argument or a flag, not both") // Test setting host from flag authArguments.Host = "val from --host" - err = setHostAndAccountId(ctx, profile.DefaultProfiler, "profile-1", &authArguments, []string{}) + err = setHostAndAccountId(ctx, profile1, &authArguments, []string{}) assert.NoError(t, err) assert.Equal(t, "val from --host", authArguments.Host) // Test setting host from argument authArguments.Host = "" - err = setHostAndAccountId(ctx, profile.DefaultProfiler, "profile-1", &authArguments, []string{"val from [HOST]"}) + err = setHostAndAccountId(ctx, profile1, &authArguments, []string{"val from [HOST]"}) assert.NoError(t, err) assert.Equal(t, "val from [HOST]", authArguments.Host) // Test setting host from profile authArguments.Host = "" - err = setHostAndAccountId(ctx, profile.DefaultProfiler, "profile-1", &authArguments, []string{}) + err = setHostAndAccountId(ctx, profile1, &authArguments, []string{}) assert.NoError(t, err) assert.Equal(t, "https://www.host1.com", authArguments.Host) // Test setting host from profile authArguments.Host = "" - err = setHostAndAccountId(ctx, profile.DefaultProfiler, "profile-2", &authArguments, []string{}) + err = setHostAndAccountId(ctx, profile2, &authArguments, []string{}) assert.NoError(t, err) assert.Equal(t, "https://www.host2.com", authArguments.Host) // Test host is not set. Should prompt. authArguments.Host = "" - err = setHostAndAccountId(ctx, profile.DefaultProfiler, "", &authArguments, []string{}) + err = setHostAndAccountId(ctx, nil, &authArguments, []string{}) assert.EqualError(t, err, "the command is being run in a non-interactive environment, please specify a host using --host") } @@ -64,16 +78,18 @@ func TestSetAccountId(t *testing.T) { t.Setenv("DATABRICKS_CONFIG_FILE", "./testdata/.databrickscfg") ctx, _ := cmdio.SetupTest(context.Background()) + accountProfile := loadTestProfile(t, ctx, "account-profile") + // Test setting account-id from flag authArguments.AccountID = "val from --account-id" - err := setHostAndAccountId(ctx, profile.DefaultProfiler, "account-profile", &authArguments, []string{}) + err := setHostAndAccountId(ctx, accountProfile, &authArguments, []string{}) assert.NoError(t, err) assert.Equal(t, "https://accounts.cloud.databricks.com", authArguments.Host) assert.Equal(t, "val from --account-id", authArguments.AccountID) // Test setting account_id from profile authArguments.AccountID = "" - err = setHostAndAccountId(ctx, profile.DefaultProfiler, "account-profile", &authArguments, []string{}) + err = setHostAndAccountId(ctx, accountProfile, &authArguments, []string{}) require.NoError(t, err) assert.Equal(t, "https://accounts.cloud.databricks.com", authArguments.Host) assert.Equal(t, "id-from-profile", authArguments.AccountID) @@ -81,46 +97,59 @@ func TestSetAccountId(t *testing.T) { // Neither flag nor profile account-id is set, should prompt authArguments.AccountID = "" authArguments.Host = "https://accounts.cloud.databricks.com" - err = setHostAndAccountId(ctx, profile.DefaultProfiler, "", &authArguments, []string{}) + err = setHostAndAccountId(ctx, nil, &authArguments, []string{}) assert.EqualError(t, err, "the command is being run in a non-interactive environment, please specify an account ID using --account-id") } -func TestLoginGetClusterID(t *testing.T) { +func TestLoadProfileByNameAndClusterID(t *testing.T) { testCases := []struct { - name string - profile string - configFileEnv string - expected string + name string + profile string + configFileEnv string + expectedHost string + expectedClusterID string }{ { - name: "cluster profile", - profile: "cluster-profile", - configFileEnv: "./testdata/.databrickscfg", - expected: "cluster-from-config", + name: "cluster profile", + profile: "cluster-profile", + configFileEnv: "./testdata/.databrickscfg", + expectedHost: "https://www.host2.com", + expectedClusterID: "cluster-from-config", }, { - name: "empty profile", - profile: "no-profile", - configFileEnv: "./testdata/.databrickscfg", - expected: "", + name: "empty profile", + profile: "no-profile", + configFileEnv: "./testdata/.databrickscfg", + expectedHost: "", + expectedClusterID: "", }, { - name: "account profile", - profile: "account-profile", - configFileEnv: "./testdata/.databrickscfg", - expected: "", + name: "account profile", + profile: "account-profile", + configFileEnv: "./testdata/.databrickscfg", + expectedHost: "https://accounts.cloud.databricks.com", + expectedClusterID: "", }, { - name: "config doesn't exist", - profile: "any-profile", - configFileEnv: "./nonexistent/.databrickscfg", - expected: "", + name: "config doesn't exist", + profile: "any-profile", + configFileEnv: "./nonexistent/.databrickscfg", + expectedHost: "", + expectedClusterID: "", }, { - name: "invalid profile (missing host)", - profile: "invalid-profile", - configFileEnv: "./testdata/.databrickscfg", - expected: "", + name: "invalid profile (missing host)", + profile: "invalid-profile", + configFileEnv: "./testdata/.databrickscfg", + expectedHost: "", + expectedClusterID: "", + }, + { + name: "no config file specified", + profile: "any-profile", + configFileEnv: "", + expectedHost: "", + expectedClusterID: "", }, } @@ -128,11 +157,18 @@ func TestLoginGetClusterID(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Setenv("DATABRICKS_CONFIG_FILE", tc.configFileEnv) - clusterID, err := getClusterID(context.Background(), tc.profile) + profile, err := loadProfileByName(context.Background(), tc.profile, profile.DefaultProfiler) require.NoError(t, err) - assert.Equal(t, tc.expected, clusterID, - "Test case '%s' failed: expected cluster ID '%s', but got '%s' (profile: %s, config file: %s)", - tc.name, tc.expected, clusterID, tc.profile, tc.configFileEnv) + + if tc.expectedHost == "" { + assert.Nil(t, profile, "Test case '%s' failed: expected nil profile but got non-nil profile", tc.name) + } else { + assert.NotNil(t, profile, "Test case '%s' failed: expected profile but got nil", tc.name) + assert.Equal(t, tc.expectedHost, profile.Host, + "Test case '%s' failed: expected host '%s', but got '%s'", tc.name, tc.expectedHost, profile.Host) + assert.Equal(t, tc.expectedClusterID, profile.ClusterID, + "Test case '%s' failed: expected cluster ID '%s', but got '%s'", tc.name, tc.expectedClusterID, profile.ClusterID) + } }) } } diff --git a/cmd/auth/token.go b/cmd/auth/token.go index dd0f95732e..5c9e549f77 100644 --- a/cmd/auth/token.go +++ b/cmd/auth/token.go @@ -92,7 +92,12 @@ func loadToken(ctx context.Context, args loadTokenArgs) (*oauth2.Token, error) { return nil, errors.New("providing both a profile and host is not supported") } - err := setHostAndAccountId(ctx, args.profiler, args.profileName, args.authArguments, args.args) + existingProfile, err := loadProfileByName(ctx, args.profileName, args.profiler) + if err != nil { + return nil, err + } + + err = setHostAndAccountId(ctx, existingProfile, args.authArguments, args.args) if err != nil { return nil, err } diff --git a/libs/databrickscfg/profile/file.go b/libs/databrickscfg/profile/file.go index 1b743014e3..9817f53abc 100644 --- a/libs/databrickscfg/profile/file.go +++ b/libs/databrickscfg/profile/file.go @@ -82,6 +82,7 @@ func (f FileProfilerImpl) LoadProfiles(ctx context.Context, fn ProfileMatchFunct Name: v.Name(), Host: host, AccountID: all["account_id"], + ClusterID: all["cluster_id"], } if fn(profile) { profiles = append(profiles, profile) diff --git a/libs/databrickscfg/profile/file_test.go b/libs/databrickscfg/profile/file_test.go index 6bcaec4b77..313a9adbe6 100644 --- a/libs/databrickscfg/profile/file_test.go +++ b/libs/databrickscfg/profile/file_test.go @@ -19,13 +19,18 @@ func TestProfileCloud(t *testing.T) { func TestProfilesSearchCaseInsensitive(t *testing.T) { profiles := Profiles{ - Profile{Name: "foo", Host: "bar"}, + Profile{Name: "foo", Host: "bar", ClusterID: "cluster123"}, } + assert.True(t, profiles.SearchCaseInsensitive("f", 0)) assert.True(t, profiles.SearchCaseInsensitive("OO", 0)) assert.True(t, profiles.SearchCaseInsensitive("b", 0)) assert.True(t, profiles.SearchCaseInsensitive("AR", 0)) assert.False(t, profiles.SearchCaseInsensitive("qu", 0)) + assert.True(t, profiles.SearchCaseInsensitive("cluster", 0)) + assert.True(t, profiles.SearchCaseInsensitive("123", 0)) + assert.True(t, profiles.SearchCaseInsensitive("CLUSTER", 0)) + assert.False(t, profiles.SearchCaseInsensitive("xyz", 0)) } func TestLoadProfilesReturnsHomedirAsTilde(t *testing.T) { diff --git a/libs/databrickscfg/profile/profile.go b/libs/databrickscfg/profile/profile.go index 510e5c9e55..889b536c44 100644 --- a/libs/databrickscfg/profile/profile.go +++ b/libs/databrickscfg/profile/profile.go @@ -13,6 +13,7 @@ type Profile struct { Name string Host string AccountID string + ClusterID string } func (p Profile) Cloud() string { @@ -37,7 +38,8 @@ func (p Profiles) SearchCaseInsensitive(input string, index int) bool { input = strings.ToLower(input) name := strings.ToLower(p[index].Name) host := strings.ToLower(p[index].Host) - return strings.Contains(name, input) || strings.Contains(host, input) + clusterID := strings.ToLower(p[index].ClusterID) + return strings.Contains(name, input) || strings.Contains(host, input) || strings.Contains(clusterID, input) } func (p Profiles) Names() []string { From fe8af1cab679874b2e3c2e10394e602c659411e1 Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Mon, 23 Jun 2025 14:43:22 -0700 Subject: [PATCH 10/12] .databrickscfg file --- cmd/auth/login_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/cmd/auth/login_test.go b/cmd/auth/login_test.go index 9bf1c4740e..ff68f80598 100644 --- a/cmd/auth/login_test.go +++ b/cmd/auth/login_test.go @@ -172,3 +172,23 @@ func TestLoadProfileByNameAndClusterID(t *testing.T) { }) } } + +func TestLoadProfileByNameWithHomeDirectory(t *testing.T) { + // Test when ~/.databrickscfg exists + ctx := context.Background() + ctx = env.WithUserHomeDir(ctx, "testdata") + + // The testdata directory already contains a .databrickscfg file + existingProfile, err := loadProfileByName(ctx, "profile-1", profile.DefaultProfiler) + require.NoError(t, err) + assert.NotNil(t, existingProfile) + assert.Equal(t, "https://www.host1.com", existingProfile.Host) + + // Test when ~/.databrickscfg does not exist + ctx2 := context.Background() + ctx2 = env.WithUserHomeDir(ctx2, "nonexistent") + + noProfile, err := loadProfileByName(ctx2, "any-profile", profile.DefaultProfiler) + require.NoError(t, err) + assert.Nil(t, noProfile, "Expected nil profile when ~/.databrickscfg doesn't exist") +} From a8e50180eab8629d993466119585db77986c0b1c Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Tue, 24 Jun 2025 08:23:36 -0700 Subject: [PATCH 11/12] reverted changes and consolidated tests --- cmd/auth/login_test.go | 51 +++++++++++-------------- libs/databrickscfg/profile/file_test.go | 7 +--- libs/databrickscfg/profile/profile.go | 3 +- 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/cmd/auth/login_test.go b/cmd/auth/login_test.go index ff68f80598..0eafd839db 100644 --- a/cmd/auth/login_test.go +++ b/cmd/auth/login_test.go @@ -106,6 +106,7 @@ func TestLoadProfileByNameAndClusterID(t *testing.T) { name string profile string configFileEnv string + homeDirOverride string expectedHost string expectedClusterID string }{ @@ -116,6 +117,13 @@ func TestLoadProfileByNameAndClusterID(t *testing.T) { expectedHost: "https://www.host2.com", expectedClusterID: "cluster-from-config", }, + { + name: "profile from home directory (existing)", + profile: "cluster-profile", + homeDirOverride: "testdata", + expectedHost: "https://www.host2.com", + expectedClusterID: "cluster-from-config", + }, { name: "empty profile", profile: "no-profile", @@ -138,16 +146,16 @@ func TestLoadProfileByNameAndClusterID(t *testing.T) { expectedClusterID: "", }, { - name: "invalid profile (missing host)", - profile: "invalid-profile", - configFileEnv: "./testdata/.databrickscfg", + name: "profile from home directory (non-existent)", + profile: "any-profile", + homeDirOverride: "nonexistent", expectedHost: "", expectedClusterID: "", }, { - name: "no config file specified", - profile: "any-profile", - configFileEnv: "", + name: "invalid profile (missing host)", + profile: "invalid-profile", + configFileEnv: "./testdata/.databrickscfg", expectedHost: "", expectedClusterID: "", }, @@ -155,9 +163,16 @@ func TestLoadProfileByNameAndClusterID(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - t.Setenv("DATABRICKS_CONFIG_FILE", tc.configFileEnv) + ctx := context.Background() + + if tc.configFileEnv != "" { + t.Setenv("DATABRICKS_CONFIG_FILE", tc.configFileEnv) + } else if tc.homeDirOverride != "" { + // Use default ~/.databrickscfg + ctx = env.WithUserHomeDir(ctx, tc.homeDirOverride) + } - profile, err := loadProfileByName(context.Background(), tc.profile, profile.DefaultProfiler) + profile, err := loadProfileByName(ctx, tc.profile, profile.DefaultProfiler) require.NoError(t, err) if tc.expectedHost == "" { @@ -172,23 +187,3 @@ func TestLoadProfileByNameAndClusterID(t *testing.T) { }) } } - -func TestLoadProfileByNameWithHomeDirectory(t *testing.T) { - // Test when ~/.databrickscfg exists - ctx := context.Background() - ctx = env.WithUserHomeDir(ctx, "testdata") - - // The testdata directory already contains a .databrickscfg file - existingProfile, err := loadProfileByName(ctx, "profile-1", profile.DefaultProfiler) - require.NoError(t, err) - assert.NotNil(t, existingProfile) - assert.Equal(t, "https://www.host1.com", existingProfile.Host) - - // Test when ~/.databrickscfg does not exist - ctx2 := context.Background() - ctx2 = env.WithUserHomeDir(ctx2, "nonexistent") - - noProfile, err := loadProfileByName(ctx2, "any-profile", profile.DefaultProfiler) - require.NoError(t, err) - assert.Nil(t, noProfile, "Expected nil profile when ~/.databrickscfg doesn't exist") -} diff --git a/libs/databrickscfg/profile/file_test.go b/libs/databrickscfg/profile/file_test.go index 313a9adbe6..6bcaec4b77 100644 --- a/libs/databrickscfg/profile/file_test.go +++ b/libs/databrickscfg/profile/file_test.go @@ -19,18 +19,13 @@ func TestProfileCloud(t *testing.T) { func TestProfilesSearchCaseInsensitive(t *testing.T) { profiles := Profiles{ - Profile{Name: "foo", Host: "bar", ClusterID: "cluster123"}, + Profile{Name: "foo", Host: "bar"}, } - assert.True(t, profiles.SearchCaseInsensitive("f", 0)) assert.True(t, profiles.SearchCaseInsensitive("OO", 0)) assert.True(t, profiles.SearchCaseInsensitive("b", 0)) assert.True(t, profiles.SearchCaseInsensitive("AR", 0)) assert.False(t, profiles.SearchCaseInsensitive("qu", 0)) - assert.True(t, profiles.SearchCaseInsensitive("cluster", 0)) - assert.True(t, profiles.SearchCaseInsensitive("123", 0)) - assert.True(t, profiles.SearchCaseInsensitive("CLUSTER", 0)) - assert.False(t, profiles.SearchCaseInsensitive("xyz", 0)) } func TestLoadProfilesReturnsHomedirAsTilde(t *testing.T) { diff --git a/libs/databrickscfg/profile/profile.go b/libs/databrickscfg/profile/profile.go index 889b536c44..923f7482a0 100644 --- a/libs/databrickscfg/profile/profile.go +++ b/libs/databrickscfg/profile/profile.go @@ -38,8 +38,7 @@ func (p Profiles) SearchCaseInsensitive(input string, index int) bool { input = strings.ToLower(input) name := strings.ToLower(p[index].Name) host := strings.ToLower(p[index].Host) - clusterID := strings.ToLower(p[index].ClusterID) - return strings.Contains(name, input) || strings.Contains(host, input) || strings.Contains(clusterID, input) + return strings.Contains(name, input) || strings.Contains(host, input) } func (p Profiles) Names() []string { From 77e7d18243cac73be7eaa113661ad0c6b0775d09 Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Wed, 25 Jun 2025 10:43:01 -0700 Subject: [PATCH 12/12] Update cmd/auth/login_test.go Co-authored-by: shreyas-goenka <88374338+shreyas-goenka@users.noreply.github.com> --- cmd/auth/login_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/auth/login_test.go b/cmd/auth/login_test.go index 0eafd839db..9b9b8cc526 100644 --- a/cmd/auth/login_test.go +++ b/cmd/auth/login_test.go @@ -125,7 +125,7 @@ func TestLoadProfileByNameAndClusterID(t *testing.T) { expectedClusterID: "cluster-from-config", }, { - name: "empty profile", + name: "profile does not exist", profile: "no-profile", configFileEnv: "./testdata/.databrickscfg", expectedHost: "",