diff --git a/.nextchanges/cli/docker-duplicate-profile-hint.md b/.nextchanges/cli/docker-duplicate-profile-hint.md new file mode 100644 index 00000000000..320e3b61460 --- /dev/null +++ b/.nextchanges/cli/docker-duplicate-profile-hint.md @@ -0,0 +1 @@ +* Suggest `databricks auth logout --profile --delete` when multiple profiles match the same workspace in `databricks auth docker` commands. ([#7363](https://github.com/databricks/cli/pull/7363)) diff --git a/acceptance/cmd/auth/docker/configure-errors/output.txt b/acceptance/cmd/auth/docker/configure-errors/output.txt index 7555218534f..c3083199390 100644 --- a/acceptance/cmd/auth/docker/configure-errors/output.txt +++ b/acceptance/cmd/auth/docker/configure-errors/output.txt @@ -48,7 +48,7 @@ Error: profile "blank-auth" uses auth_type "". Docker credential helper requires === Another profile already maps to the workspace >>> musterr [CLI] auth docker configure docker-test -Error: multiple Databricks profiles match workspace ID [WORKSPACE_ID]: duplicate and docker-test. Remove duplicate workspace_id entries before using Docker credential helper +Error: multiple Databricks profiles match workspace ID [WORKSPACE_ID]: duplicate and docker-test. Docker credential helper requires exactly one profile per workspace. Remove the duplicate profile with: databricks auth logout --profile --delete === Nothing changed Docker config not created; profiles unchanged diff --git a/acceptance/cmd/auth/docker/token/output.txt b/acceptance/cmd/auth/docker/token/output.txt index 28262b1f2fe..71126dce314 100644 --- a/acceptance/cmd/auth/docker/token/output.txt +++ b/acceptance/cmd/auth/docker/token/output.txt @@ -54,4 +54,4 @@ Error: no Databricks profile found for workspace ID 444555666 from registry host === Multiple profiles for the workspace >>> musterr [CLI] auth docker token -Error: multiple Databricks profiles match workspace ID [WORKSPACE_ID]: docker-test and duplicate. Remove duplicate workspace_id entries before using Docker credential helper +Error: multiple Databricks profiles match workspace ID [WORKSPACE_ID]: docker-test and duplicate. Docker credential helper requires exactly one profile per workspace. Remove the duplicate profile with: databricks auth logout --profile --delete diff --git a/libs/dockercredentials/profile.go b/libs/dockercredentials/profile.go index e2a1ca0f092..9acdb84edbf 100644 --- a/libs/dockercredentials/profile.go +++ b/libs/dockercredentials/profile.go @@ -72,7 +72,7 @@ func EnsureUniqueProfile(ctx context.Context, profiler profile.Profiler, p profi return nil } - return fmt.Errorf("multiple Databricks profiles match workspace ID %s: %s. Remove duplicate workspace_id entries before using Docker credential helper", workspaceID, strings.Join(names, " and ")) + return duplicateProfilesError(workspaceID, names) } // ProfileForRegistry returns the Docker credential helper profile for registry. @@ -99,10 +99,14 @@ func ProfileForRegistry(ctx context.Context, profiler profile.Profiler, registry case 1: return matchingProfiles[0], nil default: - return profile.Profile{}, fmt.Errorf("multiple Databricks profiles match workspace ID %s: %s. Remove duplicate workspace_id entries before using Docker credential helper", registry.WorkspaceID, strings.Join(matchingProfiles.Names(), " and ")) + return profile.Profile{}, duplicateProfilesError(registry.WorkspaceID, matchingProfiles.Names()) } } +func duplicateProfilesError(workspaceID string, names []string) error { + return fmt.Errorf("multiple Databricks profiles match workspace ID %s: %s. Docker credential helper requires exactly one profile per workspace. Remove the duplicate profile with: databricks auth logout --profile --delete", workspaceID, strings.Join(names, " and ")) +} + // RewriteProfileError adds Docker profile context to authentication errors. func RewriteProfileError(ctx context.Context, p profile.Profile, err error) error { if rewritten, rewrittenErr := auth.RewriteAuthError(ctx, p.Host, p.AccountID, p.Name, err); rewritten { diff --git a/libs/dockercredentials/profile_test.go b/libs/dockercredentials/profile_test.go index 8f426124d8d..0586d7e1e7a 100644 --- a/libs/dockercredentials/profile_test.go +++ b/libs/dockercredentials/profile_test.go @@ -152,7 +152,7 @@ func TestEnsureUniqueProfile(t *testing.T) { name: "duplicate workspace ID", profiles: profile.Profiles{selected, workspaceProfile("dev")}, selected: selected, - wantErr: "multiple Databricks profiles match workspace ID 123456789: prod and dev. Remove duplicate workspace_id entries before using Docker credential helper", + wantErr: "multiple Databricks profiles match workspace ID 123456789: prod and dev. Docker credential helper requires exactly one profile per workspace. Remove the duplicate profile with: databricks auth logout --profile --delete", }, { name: "unsupported duplicate", @@ -172,7 +172,7 @@ func TestEnsureUniqueProfile(t *testing.T) { Host: workspaceHost, AuthType: auth.AuthTypeDatabricksCli, }, - wantErr: "multiple Databricks profiles match workspace ID 123456789: prod and workspace. Remove duplicate workspace_id entries before using Docker credential helper", + wantErr: "multiple Databricks profiles match workspace ID 123456789: prod and workspace. Docker credential helper requires exactly one profile per workspace. Remove the duplicate profile with: databricks auth logout --profile --delete", }, } @@ -204,7 +204,7 @@ func TestProfileForRegistry(t *testing.T) { { name: "duplicate workspace ID", profiles: profile.Profiles{workspaceProfile("prod"), workspaceProfile("dev")}, - wantErr: "multiple Databricks profiles match workspace ID 123456789: prod and dev. Remove duplicate workspace_id entries before using Docker credential helper", + wantErr: "multiple Databricks profiles match workspace ID 123456789: prod and dev. Docker credential helper requires exactly one profile per workspace. Remove the duplicate profile with: databricks auth logout --profile --delete", }, { name: "ignores unsupported duplicate",