fix(auth): clearer U2M errors for missing profiles and modern CLI detection#184
Draft
parthban-db wants to merge 1 commit into
Draft
fix(auth): clearer U2M errors for missing profiles and modern CLI detection#184parthban-db wants to merge 1 commit into
parthban-db wants to merge 1 commit into
Conversation
|
Please ensure that the NEXT_CHANGELOG.md file is updated with any relevant changes. |
1 similar comment
|
Please ensure that the NEXT_CHANGELOG.md file is updated with any relevant changes. |
…ection
## Summary
Fixes two misleading failure modes in the Databricks CLI ("U2M") credential provider: a non-existent profile no longer surfaces a confusing host error with a doubled `Error:` prefix, and modern CLI wrappers/shims smaller than 1 MB are no longer misclassified as the legacy Python CLI.
## Why
`newU2mCredentials` shells out to the `databricks` CLI to obtain access tokens, and two of its error paths produced output that pointed developers in the wrong direction.
First, when the requested profile does not exist, `databricks auth token --profile X` treats the unknown profile as "no profile configured" and fails with a host-related message such as `Error: cannot configure default credentials, please check ... or specify --host`. The provider passed that stderr through verbatim and wrapped it as `cannot get access token: <stderr>`. Because the CLI already prefixes its stderr with `Error:`, the rendered result read `cannot get access token: Error: ...`, and once the surrounding `U2mCredentialsError` is logged the prefix doubled again. A developer who simply mistyped a profile name was told to specify a host, with a stutter of `Error:` labels.
Second, the provider distinguished the modern Go-based CLI (>= 0.100.0) from the legacy Python CLI purely by binary size: any file under 1 MB was reported as `LEGACY_CLI_DETECTED`. That heuristic flags legitimate setups where `databricks` is a small wrapper, shim, or symlink-resolving launcher rather than the full statically linked binary, blocking auth even when a perfectly modern CLI is installed.
## What changed
### Interface changes
- **`U2mCredentialsErrorCode`** gains a `'PROFILE_NOT_FOUND'` member. `newU2mCredentials` now rejects with this code (and the message `profile "<name>" was not found in the Databricks config file`) when the requested profile is absent.
### Behavioral changes
- A request for a non-existent profile now fails fast with `PROFILE_NOT_FOUND` naming the missing profile, instead of running the CLI and surfacing its host error. The profile is pre-checked via `resolve` from `@databricks/sdk-core/profiles`, which already reports `PROFILE_NOT_FOUND` for an explicitly requested-but-missing profile; any other resolution error is rethrown unchanged.
- CLI stderr that is already prefixed with `Error:` has that prefix stripped before the SDK wraps it, so the message no longer doubles the label.
- CLI modernity is now determined by running `databricks version` and parsing its `Databricks CLI v<semver>` banner, requiring `>= 0.100.0`. The 1 MB binary-size check is kept only as a fallback for when the version command cannot be run or its output cannot be parsed. Wrappers and shims that report a modern version are accepted.
### Internal changes
- `validateCliPath` delegates the legacy-vs-modern decision to a new `isModernCli(path, size)` helper, backed by `cliVersion` (runs `<path> version`, parses the semver) and `isAtLeastMinVersion` (compares against `MIN_CLI_VERSION`).
- Added `ensureProfileExists` and `stripErrorPrefix` helpers in `u2m.ts`.
- The `u2m` test suite mocks `@databricks/sdk-core/profiles` so the profile pre-check is deterministic and does not read the developer's `~/.databrickscfg`. The CLI exec mock now routes by sub-command (`version` vs `auth token`) so the version probe and the token request can be stubbed independently. New cases cover the profile pre-check, the `Error:`-prefix stripping, a pre-0.100.0 reported version, and the size fallback when the version cannot be read.
### Go-parity note
The Go reference SDK in this checkout implements U2M via a persistent OAuth flow rather than a CLI shell-out, so there is no Go counterpart for this provider's CLI detection. The `databricks version` parsing here follows the Databricks CLI's own version banner (`Databricks CLI v<semver>`); the legacy Python launcher does not emit that banner, so it falls through to the size heuristic. This is a deliberate, TypeScript-only divergence rather than a port of a specific Go function.
## How is this tested?
`npm run build`, `npm test`, `npm run typecheck`, and `npm run lint` for `@databricks/sdk-auth` (built on top of `@databricks/sdk-core`) all pass. The 14-case `u2m` suite covers the new `PROFILE_NOT_FOUND` path, `Error:`-prefix de-duplication, version-based modern-CLI detection, and the binary-size fallback.
Co-authored-by: Isaac
1e04012 to
9bfd9a5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🥞 Stacked PR
Use this link to review incremental changes.
Summary
Makes the U2M (Databricks CLI) credential provider fail with clear, accurate errors: a mistyped profile is reported up front instead of as a misleading host error, CLI stderr no longer renders a doubled
Error:prefix, and modern CLI wrappers/shims are no longer misflagged as the legacy Python CLI.Why
newU2mCredentialsshells out to thedatabricksCLI, and two error paths misled developers. An unknown profile madedatabricks auth tokenfail with a host-configuration error (already prefixed withError:, which the SDK then doubled), so a simple typo told the user to specify a host. Separately, CLI modernity was inferred purely from binary size, rejecting legitimate small wrappers, shims, and launcher symlinks as legacy.What changed
PROFILE_NOT_FOUNDcode toU2mCredentialsErrorCode; the provider now pre-checks the profile viaresolvefrom@databricks/sdk-core/profilesand fails fast naming the missing profile, instead of running the CLI.Error:prefix from CLI stderr before wrapping, so messages no longer readError: Error: ....databricks versionand requiring>= 0.100.0; the 1 MB binary-size check is kept only as a fallback when the version cannot be obtained or parsed.validateCliPathonto newisModernCli/cliVersion/isAtLeastMinVersionhelpers and addsensureProfileExists/stripErrorPrefix.Validated:
npm run build,npm test(14-caseu2msuite),npm run typecheck, andnpm run lintpass for@databricks/sdk-auth.