Skip to content

Add interactive profile picker to auth logout#4616

Draft
mihaimitrea-db wants to merge 18 commits intomainfrom
mihaimitrea-db/stack/auth_logout_profile_picker
Draft

Add interactive profile picker to auth logout#4616
mihaimitrea-db wants to merge 18 commits intomainfrom
mihaimitrea-db/stack/auth_logout_profile_picker

Conversation

@mihaimitrea-db
Copy link
Collaborator

@mihaimitrea-db mihaimitrea-db commented Feb 27, 2026

🥞 Stacked PR

Use this link to review incremental changes.


When --profile is not specified in an interactive terminal, show a searchable prompt listing all configured profiles. Profiles are sorted alphabetically and displayed with their host or account ID. The picker supports fuzzy search by name, host, or account ID.

Changes

  • When --profile is omitted in an interactive terminal, show a searchable prompt listing all configured profiles sorted alphabetically. Profiles display their host or account ID, and support fuzzy search by name, host, or account ID.
  • Expand the command's long help text to document all four interaction modes (explicit --profile, interactive picker, non-interactive error, --force).

Tests

  • Existing unit tests from #4613 continue to pass (profile picker is only triggered in interactive mode, which tests mock as non-interactive).
  • Manual testing with multiple profiles to verify picker display, search, and selection.

@eng-dev-ecosystem-bot
Copy link
Collaborator

eng-dev-ecosystem-bot commented Feb 27, 2026

Commit: 2d7d3ea

Run: 22665283898

Env 🪲​BUG ❌​FAIL 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
🪲​ aws linux 1 7 1 7 267 783 9:52
🪲​ aws windows 1 7 1 7 269 781 7:56
🪲​ aws-ucws linux 1 2 7 7 363 698 13:59
🪲​ aws-ucws windows 1 2 7 7 365 696 10:38
🪲​ azure linux 1 5 1 3 1 9 262 781 113:37
🪲​ azure windows 1 7 1 1 1 9 264 779 125:39
🪲​ azure-ucws linux 1 6 1 4 9 360 694 111:21
🪲​ azure-ucws windows 1 4 6 1 9 362 692 88:10
🪲​ gcp linux 1 8 1 1 9 258 784 125:14
🪲​ gcp windows 1 7 1 1 1 9 260 782 125:13
26 interesting tests: 9 FAIL, 7 KNOWN, 7 SKIP, 2 flaky, 1 BUG
Test Name aws linux aws windows aws-ucws linux aws-ucws windows azure linux azure windows azure-ucws linux azure-ucws windows gcp linux gcp windows
🟨​ TestAccept 🟨​K 🟨​K 💚​R 🔄​f 🟨​K 🟨​K 🟨​K 🔄​f 🟨​K 🟨​K
❌​ TestAccept/bundle/deployment/bind/alert 🙈​s 🙈​s 🙈​s 🙈​s 🔄​f ❌​F ❌​F 🔄​f ❌​F ❌​F
❌​ TestAccept/bundle/deployment/bind/alert/DATABRICKS_BUNDLE_ENGINE=direct 🔄​f ✅​p ✅​p ✅​p ❌​F ❌​F
❌​ TestAccept/bundle/deployment/bind/alert/DATABRICKS_BUNDLE_ENGINE=terraform 🔄​f ❌​F ❌​F 🔄​f ✅​p ❌​F
❌​ TestAccept/bundle/generate/alert ✅​p ✅​p ✅​p ✅​p ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/generate/alert/DATABRICKS_BUNDLE_ENGINE=direct ✅​p ✅​p ✅​p ✅​p ✅​p ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/generate/alert/DATABRICKS_BUNDLE_ENGINE=terraform ✅​p ✅​p ✅​p ✅​p ❌​F ❌​F 🔄​f 🔄​f ❌​F 🔄​f
❌​ TestAccept/bundle/resources/alerts/with_file ✅​p ✅​p ✅​p ✅​p ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/alerts/with_file/DATABRICKS_BUNDLE_ENGINE=direct ✅​p ✅​p ✅​p ✅​p ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/alerts/with_file/DATABRICKS_BUNDLE_ENGINE=terraform ✅​p ✅​p ✅​p ✅​p ❌​F 🔄​f 🔄​f 🔄​f ❌​F ✅​p
🙈​ TestAccept/bundle/resources/permissions 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🙈​ TestAccept/bundle/resources/postgres_branches/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/update_protected 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/without_branch_id 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_endpoints/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/synced_database_tables/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestAccept/ssh/connect-serverless-gpu 🙈​s 🙈​s 🔄​f 🔄​f 🙈​s 🙈​s 🔄​f 🔄​f 🙈​s 🙈​s
🔄​ TestAccept/ssh/connection 💚​R 💚​R 🔄​f 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R 💚​R
🪲​ TestImportFileFormatSource 🪲​B 🪲​B 🪲​B 🪲​B 🪲​B 🪲​B 🪲​B 🪲​B 🪲​B 🪲​B
Top 35 slowest tests (at least 2 minutes):
duration env testname
9:57 gcp windows TestAccept/bundle/generate/alert/DATABRICKS_BUNDLE_ENGINE=terraform
9:57 azure windows TestAccept/bundle/resources/alerts/with_file/DATABRICKS_BUNDLE_ENGINE=terraform
9:23 azure linux TestAccept/bundle/deployment/bind/alert/DATABRICKS_BUNDLE_ENGINE=direct
9:01 azure-ucws linux TestAccept/bundle/resources/alerts/with_file/DATABRICKS_BUNDLE_ENGINE=terraform
8:34 azure linux TestAccept/bundle/deployment/bind/alert/DATABRICKS_BUNDLE_ENGINE=terraform
8:00 gcp linux TestAccept/bundle/deployment/bind/alert/DATABRICKS_BUNDLE_ENGINE=terraform
7:33 gcp windows TestAccept/bundle/resources/alerts/with_file/DATABRICKS_BUNDLE_ENGINE=terraform
6:47 azure-ucws windows TestAccept/bundle/generate/alert/DATABRICKS_BUNDLE_ENGINE=terraform
5:52 azure-ucws windows TestAccept/bundle/deployment/bind/alert/DATABRICKS_BUNDLE_ENGINE=direct
5:18 azure-ucws linux TestAccept/bundle/deployment/bind/alert/DATABRICKS_BUNDLE_ENGINE=direct
5:13 azure windows TestAccept/bundle/deployment/bind/alert/DATABRICKS_BUNDLE_ENGINE=direct
5:04 azure-ucws linux TestAccept/bundle/generate/alert/DATABRICKS_BUNDLE_ENGINE=terraform
4:32 azure-ucws windows TestAccept/bundle/resources/alerts/with_file/DATABRICKS_BUNDLE_ENGINE=terraform
4:13 azure linux TestAccept/bundle/generate/alert/DATABRICKS_BUNDLE_ENGINE=direct
4:03 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:57 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:55 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:40 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:37 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:37 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:35 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:16 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:12 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:11 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:10 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:04 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:00 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:53 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:37 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:37 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:23 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:19 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:14 aws-ucws windows TestAccept/bundle/deploy/files/no-snapshot-sync/DATABRICKS_BUNDLE_ENGINE=terraform
2:11 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:03 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct

Copy link
Member

@simonfaltum simonfaltum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I left some comments

@mihaimitrea-db mihaimitrea-db self-assigned this Mar 2, 2026
@mihaimitrea-db mihaimitrea-db force-pushed the mihaimitrea-db/stack/auth_logout_profile_picker branch 2 times, most recently from f374e5a to c903ed8 Compare March 2, 2026 11:42
@mihaimitrea-db mihaimitrea-db force-pushed the mihaimitrea-db/stack/auth_logout_profile_picker branch from c903ed8 to 889b7ca Compare March 2, 2026 12:11
@mihaimitrea-db mihaimitrea-db force-pushed the mihaimitrea-db/stack/auth_logout_profile_picker branch from 889b7ca to 7a39778 Compare March 2, 2026 12:45
@mihaimitrea-db mihaimitrea-db force-pushed the mihaimitrea-db/stack/auth_logout_profile_picker branch from 7a39778 to 67eff3f Compare March 2, 2026 13:27
@mihaimitrea-db mihaimitrea-db linked an issue Mar 2, 2026 that may be closed by this pull request
@mihaimitrea-db mihaimitrea-db marked this pull request as ready for review March 2, 2026 14:07
Comment on lines +201 to +203
slices.SortFunc(allProfiles, func(a, b profile.Profile) int {
return strings.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name))
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we always sort profiles alphabetically? I'd think we just want to show them in the order they were added (or alternatively last used or most used but we don't log that anywhere..)

// promptForLogoutProfile shows an interactive profile picker for logout.
// Account profiles are displayed as "name (account: id)", workspace profiles
// as "name (host)".
func promptForLogoutProfile(ctx context.Context, profiler profile.Profiler) (string, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good work but did you look through the codebase for similar patterns?
I think the closest existing pattern is promptForProfileSelection in cmd/auth/token.go (line ~368), which already handles an "all profiles" picker with search by name/host and the StartInSearchMode: len(profiles) > 5 pattern.
I think we are re-implementing much of this logic, which maybe is justified but it might be worth it to make a component we could re-use broadly as selecting profile interactively is something we will have to do multiple times. I think in auth token it lets you create a new profile also, which is probably not something we want to do in logout 😃

@mihaimitrea-db mihaimitrea-db force-pushed the mihaimitrea-db/stack/auth_logout_profile_picker branch from a87d5a2 to bcf6e70 Compare March 3, 2026 12:30
@mihaimitrea-db mihaimitrea-db requested review from a team and lennartkats-db as code owners March 3, 2026 12:30
@mihaimitrea-db mihaimitrea-db force-pushed the mihaimitrea-db/stack/auth_logout_profile_picker branch from bcf6e70 to e536cc8 Compare March 3, 2026 12:37
Replace plain fmt.Sprintf confirmation prompt with a structured template using cmdio.RenderWithTemplate. The warning now uses color and bold formatting to clearly highlight the profile name, config path, and consequences before prompting for confirmation.
Resolve config path from the profiler instead of hardcoding fallbacks. Delete the profile before clearing the token cache so a config write failure does not leave tokens removed. Fix token cleanup for account and unified profiles by computing the correct OIDC cache key (host/oidc/accounts/<account_id>). Drop the nil profiler guard, add a success message on logout, and extract backupConfigFile in ops.go to remove duplication. Consolidate token cleanup tests into a table-driven test covering shared hosts, unique hosts, account, and unified profiles.
Merge shared-host token deletion verification into one main parametrized test by addding the hostBasedKey and isSharedKey parameters to each case. This replaces the TestLogoutTokenCacheCleanup test with an assertion: host-based keys are preserved when another profile shares the same host, and deleted otherwise.
Rewrite the test to use inline config seeds and explicit expected state. Add cases for deleting the last non-default profile, deleting a unified host profile with multiple keys, and deleting the DEFAULT section.
- Use profiler.GetPath() to resolve config path instead of hardcoding platform-specific defaults for the help text.
- Read DATABRICKS_CONFIG_FILE via env.Get(ctx, ...) instead of os.Getenv to respect context-level env overrides.
- Add abort message when user declines the confirmation prompt.
- Guard DeleteProfile against non-existent profiles to avoid creating unnecessary backup files.
- Add TestDeleteProfile_NotFound for the error path.
Cover four scenarios: profile ordering and comments are preserved after deletion, deleting the last non-default profile leaves an empty DEFAULT section, deleting the DEFAULT profile itself clears its keys and restores the default comment, and error paths for non-existent profiles and missing --profile in non-interactive mode.
By default, Authentication related commands. For more information regarding how
authentication for the Databricks CLI and SDKs work please refer to the documentation
linked below.

AWS: https://docs.databricks.com/dev-tools/auth/index.html
Azure: https://learn.microsoft.com/azure/databricks/dev-tools/auth
GCP: https://docs.gcp.databricks.com/dev-tools/auth/index.html

Usage:
  databricks auth [command]

Available Commands:
  describe    Describes the credentials and the source of those credentials, being used by the CLI to authenticate
  env         Get env
  login       Log into a Databricks workspace or account
  profiles    Lists profiles from ~/.databrickscfg
  token       Get authentication token

Flags:
      --account-id string              Databricks Account ID
      --experimental-is-unified-host   Flag to indicate if the host is a unified host
  -h, --help                           help for auth
      --host string                    Databricks Host
      --workspace-id string            Databricks Workspace ID

Global Flags:
      --debug            enable debug logging
  -o, --output type      output type: text or json (default text)
  -p, --profile string   ~/.databrickscfg profile
  -t, --target string    bundle target to use (if applicable)

Use "databricks auth [command] --help" for more information about a command. now only clears cached OAuth
tokens without removing the profile from ~/.databrickscfg. Pass
--delete to also remove the profile entry from the config file.
@mihaimitrea-db mihaimitrea-db force-pushed the mihaimitrea-db/stack/auth_logout_profile_picker branch from e536cc8 to 82cf219 Compare March 3, 2026 13:50
Existing acceptance tests that verify profile deletion now use --delete
since profile removal is opt-in. Two new acceptance tests verify token-only
logout: one for a unique host (both cache entries cleared) and one for a
shared host (host-keyed token preserved).
Replace manual strings.TrimRight(host, /) with the SDK's
config.Config.CanonicalHostName(), which handles scheme
normalization, trailing slashes, and empty hosts consistently
with how the SDK itself computes token cache keys.
@mihaimitrea-db mihaimitrea-db force-pushed the mihaimitrea-db/stack/auth_logout_profile_picker branch from 78ab0ca to 3f790d7 Compare March 4, 2026 09:06
@mihaimitrea-db mihaimitrea-db force-pushed the mihaimitrea-db/stack/auth_logout_profile_picker branch from 3f790d7 to 4d37004 Compare March 4, 2026 09:45
When --profile is not specified in an interactive terminal, show a
searchable prompt listing all configured profiles. Profiles are sorted
alphabetically and displayed with their host or account ID. The picker
supports fuzzy search by name, host, or account ID.
Document the four interaction modes (explicit profile, interactive
picker, non-interactive error, and --force) in the command's long
help text.
@mihaimitrea-db mihaimitrea-db force-pushed the mihaimitrea-db/stack/auth_logout_profile_picker branch from 4d37004 to 2d7d3ea Compare March 4, 2026 10:25
@mihaimitrea-db mihaimitrea-db marked this pull request as draft March 4, 2026 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Add logout command

3 participants