[Internal] Inject workspace-id routing header per-resource for non-Go-SDK resources#5759
Merged
Conversation
Move X-Databricks-Workspace-Id injection out of common.DatabricksClient's
helpers and into each workspace-level resource. The previous central
approach fired on every raw-HTTP call gated only on Config.WorkspaceID;
this is fragile for account-only and dual resources because the same
client config can carry a WorkspaceID even when the call targets an
account endpoint.
- Get/Post/Patch/Delete/Put now take variadic visitors; workspace-only
callsites pass c.AddWorkspaceIdHeader explicitly (~137 callsites across
repos, pools, sharing, access, catalog, workspace, clusters, storage,
aws, commands, tokens, sql, jobs-legacy, exporter).
- Scim helper injects the header conditionally based on apiLevel so
dual SCIM (users/groups/service_principals) sends it at workspace
level and skips it at account level.
- mws/* (account-only, paths under /accounts/{aid}/...) untouched.
Co-authored-by: Isaac
hectorcast-db
approved these changes
May 29, 2026
databricks_repo.path requires /Repos/<directory>/<repo> (3 components after the leading slash) per validatePath in repos/resource_repo.go. The test fixture used /Repos/tf-acc-<rand> (2 components), causing ValidateResourceConfig to fail before any API call: Error: should have 3 components (/Repos/<directory>/<repo>), got 2 Failure surfaced in eng-dev-ecosystem run 26627275255 on the *-acct-* matrix legs (TestMwsAccUnifiedHostCreateRepo, TestMwsAccAccountHostCreateRepo). Co-authored-by: Isaac
Contributor
|
If integration tests don't run automatically, an authorized user can run them manually by following the instructions below: Trigger: Inputs:
Checks will be approved automatically on success. |
Divyansh-db
approved these changes
May 29, 2026
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.
Changes
Resources that don't use the Go SDK to make API calls go through
common.DatabricksClient's raw HTTP path (Get/Post/Patch/Delete/Put/Scim) rather than a generatedw.<Service>.<Method>(...)call. Eg: repos, pools, sharing, access, catalog, workspace/notebook, clusters, storage/dbfs, aws/instance_profile,commands, tokens, sql/, scim/, jobs legacy 2.0, exporter, etc.
Until now, those calls sent no workspace routing header — on a unified host the gateway has no way to dispatch the request to the right workspace, so these resources either failed outright or routed to the wrong workspace.
This PR adds per-request
X-Databricks-Workspace-Idinjection to those callsites, gated onConfig.WorkspaceIDbeing non-empty.Design choice: injection is per-callsite, not centralized in the helpers. A central "always inject when
Config.WorkspaceID != """ hook is fragile because the same client config can carry aWorkspaceIDeven when the call targets an account endpoint (mws_* on a unified host, or a dual SCIM resource atapi=account). Per-callsite control makes the intent explicit and auditable: workspace-only resources opt in; account-only resources never do; dual SCIM is handled inside theScimhelper based onapiLevel.Summary of main changes
common/client.goAddWorkspaceIdHeaderthat setsX-Databricks-Workspace-Id: <Config.WorkspaceID>whenWorkspaceIDis non-empty (no-op otherwise).Get/Post/Patch/Delete/Put/PatchWithResponse/DeleteWithResponsemade variadic on visitors.addApiPrefixstill runs first.Scimhelper injects the header conditionally based onapiLevel: workspace-level SCIM injects; account-level SCIM does not (path is rewritten to/api/2.0/accounts/{aid}/scim/v2/...and must not be workspace-tagged).Per-resource classification
c.AddWorkspaceIdHeader/accounts/{aid}/...grep AddWorkspaceIdHeader mws/→ emptyScimhelper based onapiLevel. No per-callsite hardcodingClassification was based on the actual API endpoints the resources hit (paths starting with
/accounts/→ account-only; everything else → workspace-only) and a sweep of the docs.Tests
Unit (
common/client_test.go)TestWorkspaceIdHeader_OmittedByDefault— guard against accidental re-centralization: helpers no longer inject the header on their own.TestWorkspaceIdHeader_InjectedWithVisitor— opt-in works onGet/Post/Patch/Delete/PutwhenAddWorkspaceIdHeaderis passed.TestWorkspaceIdHeader_VisitorNoOpWhenWorkspaceIDEmpty— passing the visitor is safe whenConfig.WorkspaceIDis empty.TestScim_WorkspaceLevel_InjectsHeader— dual SCIM atapi=workspacecarries the header and SCIMContent-Type.TestScim_AccountLevel_OmitsHeader— dual SCIM atapi=accountomits the header and the path is rewritten to/accounts/{aid}/scim/v2/....The tests use an
httptest.Serverthat captures each outbound request's headers and URL.Integration (
internal/acceptance/unified_host_acc_test.go)TestMwsAccUnifiedHostCreateJobs/TestAccUnifiedHostWorkspaceCreateJobs— Go SDK path (jobs) on unified host. Unchanged.TestMwsAccUnifiedHostCreateRepo/TestAccUnifiedHostWorkspaceCreateRepo/TestMwsAccAccountHostCreateRepo— workspace-only raw-HTTP path (databricks_repo) on unified host.Mirrors the jobs trio so the contrast is direct: same shape, different code path.
Verification
go build ./...— cleango test ./...— all packages passmake fmt lint ws— cleangrep AddWorkspaceIdHeader mws/ scim/— empty (account-only files untouched; dual SCIM handled in helper, not per-callsite)NO_CHANGELOG=true