Skip to content

Resolve workspace IDs as strings at all CLI consumers#5379

Open
Divyansh-db wants to merge 2 commits into
emit-workspace-id-url-paramfrom
resolve-workspace-id-as-string
Open

Resolve workspace IDs as strings at all CLI consumers#5379
Divyansh-db wants to merge 2 commits into
emit-workspace-id-url-paramfrom
resolve-workspace-id-as-string

Conversation

@Divyansh-db
Copy link
Copy Markdown

Summary

The CLI calls `CurrentWorkspaceID` on the workspace client in five places to obtain the workspace ID. The SDK helper returns `(int64, error)` and reads the value from the `X-Databricks-Org-Id` response header on `/api/2.0/preview/scim/v2/Me`, parsing with `strconv.ParseInt`. Every consumer then formats the int64 back to a string at its own boundary — or, in two cases under `experimental/ssh`, embeds it directly with `%d`.

This PR introduces a small helper that returns the workspace ID as a string and short-circuits the API call when the workspace ID is already configured on the client, and migrates the five consumers to use it. As a side effect, the in-CLI workspace ID flow becomes string-typed end-to-end, so non-numeric workspace identifiers (e.g. connection-style IDs) flow through cleanly when configured.

The helper

`libs/auth.ResolveWorkspaceID(ctx, w)`:

  1. If `w.Config.WorkspaceID` is set (and not the CLI-only `"none"` sentinel), return it verbatim. No API call.
  2. Otherwise call `w.CurrentWorkspaceID(ctx)` and return `strconv.FormatInt(id, 10)`.

The fast path is also a small performance win — the workspace ID is already configured in the common SPOG case (set via `--workspace-id`, `DATABRICKS_WORKSPACE_ID`, `workspace_id` in `.databrickscfg`, or `?w=`/`?o=` on a host URL), and the existing code unconditionally hit `/Me` to resolve the same value.

Consumer migrations

Five call sites switch from `CurrentWorkspaceID` to `ResolveWorkspaceID`:

  • `cmd/experimental/workspace_open.go` (`databricks experimental open`)
  • `bundle/config/mutator/initialize_urls.go` (`databricks bundle summary` and any other bundle command that renders resource URLs)
  • `cmd/apps/run_local.go` (`databricks apps run-local`)
  • `experimental/ssh/internal/client/websockets.go` (`databricks experimental ssh` driver-proxy URL)
  • `experimental/ssh/internal/client/client.go` (`databricks experimental ssh` cluster-metadata fetch)

Downstream signatures widen from int64 to string

  • `libs/workspaceurls.BuildResourceURL`, `workspaceBaseURL`
  • `libs/apps/runlocal.Config.WorkspaceID`, `NewConfig`
  • The two `fmt.Sprintf` calls in `experimental/ssh` swap `%d` → `%s`. The `/driver-proxy-api/o//...` URL keeps its legacy `o` path segment — that's a separate platform-side URL scheme decision from the `?o=`/`?w=` query parameter migration.

Behavior change summary

  • Configured workspace ID flow: no behavior change. The value the CLI sends as a routing header / appends to a URL / sets as `DATABRICKS_WORKSPACE_ID` for child processes is the same string it was before.
  • Resolved-from-`/Me` flow: also no behavior change. The SDK still enforces numeric in that path; the helper just stringifies the result.
  • Non-numeric configured IDs (UUID-shaped connection-style identifiers set via `?w=` etc.): newly supported end-to-end through the five consumers. Previously the int64 typing dropped them.

Out of scope

  • `libs/auth/introspect.go` declares `WorkspaceID int64` on the `/api/2.0/tokens/introspect` response. Different endpoint, separate follow-up.
  • `cmd/auth/login.go`'s workspace picker reads `WorkspaceId int64` from the SDK's `Workspaces.List` schema. Upstream SDK change.
  • The `/driver-proxy-api/o//` URL path segment in `experimental ssh` keeps the legacy `o` form. That's a separate platform-side URL scheme decision; only the format specifier changes here.

Test plan

  • `go test ./libs/auth/... ./libs/workspaceurls/... ./libs/apps/... ./bundle/config/mutator/... ./cmd/experimental/... ./cmd/apps/... ./experimental/ssh/...` — green
  • `./task test-update` over the previously-affected acceptance suites produces no diff (behavior preserved)
  • `./task lint-q` — 0 issues; `./task fmt` — clean

The CLI calls CurrentWorkspaceID on the workspace client in five places.
The SDK helper returns (int64, error) and reads the value from the
X-Databricks-Org-Id response header on /api/2.0/preview/scim/v2/Me. Every
caller then formats the int64 back to a string at its own boundary, or
embeds it with %d in the case of experimental/ssh's driver-proxy URL.

This commit introduces auth.ResolveWorkspaceID, a small helper that:

  1. Returns w.Config.WorkspaceID if set (and not the CLI-only "none"
     sentinel) — no API call.
  2. Otherwise calls w.CurrentWorkspaceID and stringifies the result.

The fast path is also a small performance win — the workspace ID is
already configured in the common SPOG case (set via --workspace-id,
DATABRICKS_WORKSPACE_ID, workspace_id in .databrickscfg, or ?w=/?o= on
a host URL), so resolving it no longer requires hitting /Me when the
value is already known.

Migrating the five consumers makes the in-CLI workspace ID flow string-
typed end-to-end. As a side effect, non-numeric workspace identifiers
(e.g. connection-style IDs that the new X-Databricks-Workspace-Id
header accepts) now flow cleanly through these consumers when
configured by the user.

Consumers migrated:
  - databricks experimental open (cmd/experimental/workspace_open.go)
  - databricks bundle summary URL builder
    (bundle/config/mutator/initialize_urls.go)
  - databricks apps run-local (cmd/apps/run_local.go)
  - databricks experimental ssh driver-proxy URL
    (experimental/ssh/internal/client/websockets.go)
  - databricks experimental ssh cluster-metadata fetch
    (experimental/ssh/internal/client/client.go)

Downstream signatures widened from int64 to string:
  - workspaceurls.BuildResourceURL, workspaceurls.workspaceBaseURL
  - runlocal.Config.WorkspaceID, runlocal.NewConfig
  - The two fmt.Sprintf calls in experimental/ssh swap %d -> %s for the
    workspace ID slot. The /driver-proxy-api/o/<id>/... URL keeps its
    legacy "o" path segment — that's a separate platform-side URL
    scheme decision from the ?o=/?w= query parameter migration.

Out of scope:
  - libs/auth/introspect.go declares WorkspaceID int64 on the
    /api/2.0/tokens/introspect response. Different endpoint, separate
    follow-up.
  - cmd/auth/login.go's workspace picker reads WorkspaceId int64 from
    the SDK's Workspaces.List response — upstream SDK schema, not
    fixable in the CLI alone.

Behavior preserved:
  - Configured workspace ID: identical value flows downstream.
  - Resolved-from-/Me path: SDK still parses the response header as
    int64; the helper just stringifies it.
  - Acceptance tests pass unchanged.
The ResolveWorkspaceID helper's fast path returns the already-configured
cfg.WorkspaceID without hitting /api/2.0/preview/scim/v2/Me. This is the
intended behavior — saves an API call when the workspace ID is already
known — but the bundle/user_agent/simple golden was recorded with the
old behavior where bundle summary always made the /Me call.

Regenerated via ./task test-update. Diff is a clean removal of the
/Me request from out.requests.summary.{direct,terraform}.json, plus the
matching count in output.txt. No other behavior change.
@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

Commit: ae92528

Run: 26650117494

Copy link
Copy Markdown
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.

Reviewed the current head. My earlier concern about ?w= / string workspace ID parsing is covered by #5373, so this PR looks good from my side.

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.

3 participants