Skip to content

Add opt-in strict profile matching for bundle targets - #7109

Merged
pavloKozlov merged 9 commits into
mainfrom
strict-profile-match
Oct 21, 2026
Merged

pavloKozlov merged 9 commits into
mainfrom
strict-profile-match

Conversation

@pavloKozlov

@pavloKozlov pavloKozlov commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Changes

Add DATABRICKS_BUNDLE_STRICT_PROFILE_MATCH, read as a boolean. When it is true and the target has a host or workspace ID, a strict loader runs before the config file, so the profile name always comes from the config file, even if DATABRICKS_TOKEN is set. The host and workspace ID must match exactly one workspace profile, and a profile without workspace_id only matches targets without one. A target with a workspace ID but no host must name a profile with that ID. A target with neither resolves as without strict mode.

The loader does the same lookup as ResolveProfileFromHost, but fails when there is no single match, a different profile is selected, or the file is missing.

Why

With env auth the CLI skips host-based profile matching, so the token goes to whatever host the target sets. A caller that passes its own token and a file of trusted profiles needs the target checked against them first, including on a custom host shared by several workspaces.

Tests

Unit tests in loader_test.go list the loader cases side by side. Acceptance tests under acceptance/bundle/strict_profile_match/ cover the same rules end to end, including --profile, workspace.profile, default_profile and the behavior without the variable. Accepted cases print the auth a bundle script receives, which shows the selected profile and host.

This pull request and its description were written by Isaac.

pavloKozlov and others added 2 commits October 19, 2026 14:39
When DATABRICKS_BUNDLE_STRICT_PROFILE_MATCH is set, the target's host and
workspace ID must match exactly one profile in the config file, and that
profile is used even if credentials are set in the environment. A profile
without workspace_id only matches targets without one. A missing host, no
match, several matches, or a different workspace.profile or --profile fails
before authentication.

Co-authored-by: Isaac <no-reply@databricks.com>
Account profiles on a shared host have no workspace_id and could match a
target without one, so strict matching now only considers workspace profiles.
The acceptance test also pins that [DEFAULT] counts like any other profile and
that a missing config file fails.

Co-authored-by: Isaac <no-reply@databricks.com>
@github-actions github-actions Bot added the DABs DABs related issues label Oct 19, 2026
Co-authored-by: Isaac <no-reply@databricks.com>
@pavloKozlov
pavloKozlov marked this pull request as ready for review October 19, 2026 15:22
@pavloKozlov
pavloKozlov requested review from a team as code owners October 19, 2026 15:22
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 505a230

Run: 39607690616

Env ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 281 22 4:14
✅​ aws-windows-latest-4core-16gb 283 20 3:23
✅​ azure linux-2core-8gb 280 22 4:07
✅​ azure-windows-latest-4core-16gb 282 20 3:23
✅​ gcp linux-2core-8gb 281 22 4:17
✅​ gcp-windows-latest-4core-16gb 283 20 3:29
Top 3 slowest tests (at least 2 minutes):
duration env testname
3:22 gcp-windows-latest-4core-16gb TestAccept
3:18 azure-windows-latest-4core-16gb TestAccept
3:16 aws-windows-latest-4core-16gb TestAccept

Substitute only the test variables in the templates, so the bundle script
expands $CLI at run time instead of getting a Windows path with backslashes.
Use $TEST_TMP_DIR in traced commands, because $PWD is a POSIX path on Windows
and is not masked in the output.

Co-authored-by: Isaac <no-reply@databricks.com>
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Commit: 505a2307f | Workflow run

Regression test report

Selected 7 changed tests (limit=20, 0 not selected)

14 tests: regression=12 unreleased=0 coverage=2 failing=0

test branch main (be6a8e1) latest (v1.21.0)
TestAccept/bundle/strict_profile_match/config_file/DMS= ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/config_file/DMS=true ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/default_profile/host/DMS= ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/default_profile/host/DMS=true ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/default_profile/no_host/DMS= ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/default_profile/no_host/DMS=true ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/disabled/DMS= ✅ ✅ ✅
TestAccept/bundle/strict_profile_match/disabled/DMS=true ✅ ✅ ✅
TestAccept/bundle/strict_profile_match/host/DMS= ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/host/DMS=true ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/no_host/DMS= ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/no_host/DMS=true ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/profile/DMS= ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/profile/DMS=true ✅ ❌ ❌
TestAccept/bundle/strict_profile_match/config_file/DMS=: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: Diff:
        --- bundle/strict_profile_match/config_file/output.txt
        +++ /tmp/TestAcceptbundlestrict_profile_matchconfig_fileDMS=691326908/002/output.txt
        @@ -1,52 +1,45 @@
         
         === A target that matches several profiles, including [DEFAULT], is rejected
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/ambiguous.databrickscfg [CLI] bundle validate -t classic
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: multiple profiles match host [DATABRICKS_URL]: DEFAULT, workspace_classic. Config: host=[DATABRICKS_URL], config_file=[TEST_TMP_DIR]/ambiguous.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: classic
         Workspace:
           Host: [DATABRICKS_URL]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/classic
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === Account profiles are skipped
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/account.databrickscfg [CLI] bundle run -t custom_host show_auth
        -profile=workspace_custom_host host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
        +profile= host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
         
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/account.databrickscfg [CLI] bundle validate -t custom_host_without_workspace_id
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: host [CUSTOM_HOST] requires a workspace ID; set workspace.workspace_id or add ?o=<workspace-id> to workspace.host. Config: host=[CUSTOM_HOST], config_file=[TEST_TMP_DIR]/account.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: custom_host_without_workspace_id
         Workspace:
           Host: [CUSTOM_HOST]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/custom_host_without_workspace_id
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/account.databrickscfg [CLI] bundle validate -t no_host_with_workspace_id -p account_custom_host
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: account_custom_host is not a workspace profile with a host in the config file. Config: workspace_id=[WORKSPACE_ID], profile=account_custom_host, config_file=[TEST_TMP_DIR]/account.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: no_host_with_workspace_id
        +Workspace:
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/no_host_with_workspace_id
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === A missing config file is rejected
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/missing.databrickscfg [CLI] bundle validate -t classic
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: config file [TEST_TMP_DIR]/missing.databrickscfg not found. Config: host=[DATABRICKS_URL], config_file=[TEST_TMP_DIR]/missing.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: classic
         Workspace:
           Host: [DATABRICKS_URL]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/classic
         
        -Found 1 error
        -
        -Exit code: 1
        +Validation OK!

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/config_file/DMS=true: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: Diff:
        --- bundle/strict_profile_match/config_file/output.txt
        +++ /tmp/TestAcceptbundlestrict_profile_matchconfig_fileDMS=true1328554711/002/output.txt
        @@ -1,52 +1,45 @@
         
         === A target that matches several profiles, including [DEFAULT], is rejected
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/ambiguous.databrickscfg [CLI] bundle validate -t classic
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: multiple profiles match host [DATABRICKS_URL]: DEFAULT, workspace_classic. Config: host=[DATABRICKS_URL], config_file=[TEST_TMP_DIR]/ambiguous.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: classic
         Workspace:
           Host: [DATABRICKS_URL]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/classic
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === Account profiles are skipped
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/account.databrickscfg [CLI] bundle run -t custom_host show_auth
        -profile=workspace_custom_host host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
        +profile= host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
         
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/account.databrickscfg [CLI] bundle validate -t custom_host_without_workspace_id
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: host [CUSTOM_HOST] requires a workspace ID; set workspace.workspace_id or add ?o=<workspace-id> to workspace.host. Config: host=[CUSTOM_HOST], config_file=[TEST_TMP_DIR]/account.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: custom_host_without_workspace_id
         Workspace:
           Host: [CUSTOM_HOST]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/custom_host_without_workspace_id
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/account.databrickscfg [CLI] bundle validate -t no_host_with_workspace_id -p account_custom_host
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: account_custom_host is not a workspace profile with a host in the config file. Config: workspace_id=[WORKSPACE_ID], profile=account_custom_host, config_file=[TEST_TMP_DIR]/account.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: no_host_with_workspace_id
        +Workspace:
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/no_host_with_workspace_id
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === A missing config file is rejected
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/missing.databrickscfg [CLI] bundle validate -t classic
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: config file [TEST_TMP_DIR]/missing.databrickscfg not found. Config: host=[DATABRICKS_URL], config_file=[TEST_TMP_DIR]/missing.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: classic
         Workspace:
           Host: [DATABRICKS_URL]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/classic
         
        -Found 1 error
        -
        -Exit code: 1
        +Validation OK!

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/default_profile/host/DMS=: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: Diff:
        --- bundle/strict_profile_match/default_profile/host/output.txt
        +++ /tmp/TestAcceptbundlestrict_profile_matchdefault_profilehostDMS=1327920845/002/output.txt
        @@ -1,38 +1,34 @@
         
         === Target classic matches by host, not the default profile
         >>> errcode [CLI] bundle run -t classic show_auth
        -profile=workspace_classic host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
        +profile= host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
         
         === Target classic_with_workspace_id matches by host, not the default profile
         >>> errcode [CLI] bundle run -t classic_with_workspace_id show_auth
        -profile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
        +profile= host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
         
         === Target custom_host matches by host, not the default profile
         >>> errcode [CLI] bundle run -t custom_host show_auth
        -profile=workspace_custom_host host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
        +profile= host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
         
         === Target classic_other_workspace is rejected
         >>> errcode [CLI] bundle validate -t classic_other_workspace
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: no profile for host [DATABRICKS_URL] has workspace_id 2222222222. Config: host=[DATABRICKS_URL], workspace_id=2222222222, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: classic_other_workspace
         Workspace:
        -  Host: [DATABRICKS_URL]
        +  Host: [DATABRICKS_URL]/?o=2222222222
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/classic_other_workspace
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === Target custom_host_without_workspace_id is rejected
         >>> errcode [CLI] bundle validate -t custom_host_without_workspace_id
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: host [CUSTOM_HOST] requires a workspace ID; set workspace.workspace_id or add ?o=<workspace-id> to workspace.host. Config: host=[CUSTOM_HOST], config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: custom_host_without_workspace_id
         Workspace:
           Host: [CUSTOM_HOST]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/custom_host_without_workspace_id
         
        -Found 1 error
        -
        -Exit code: 1
        +Validation OK!

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/default_profile/host/DMS=true: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: Diff:
        --- bundle/strict_profile_match/default_profile/host/output.txt
        +++ /tmp/TestAcceptbundlestrict_profile_matchdefault_profilehostDMS=1283403169/002/output.txt
        @@ -1,38 +1,34 @@
         
         === Target classic matches by host, not the default profile
         >>> errcode [CLI] bundle run -t classic show_auth
        -profile=workspace_classic host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
        +profile= host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
         
         === Target classic_with_workspace_id matches by host, not the default profile
         >>> errcode [CLI] bundle run -t classic_with_workspace_id show_auth
        -profile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
        +profile= host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
         
         === Target custom_host matches by host, not the default profile
         >>> errcode [CLI] bundle run -t custom_host show_auth
        -profile=workspace_custom_host host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
        +profile= host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
         
         === Target classic_other_workspace is rejected
         >>> errcode [CLI] bundle validate -t classic_other_workspace
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: no profile for host [DATABRICKS_URL] has workspace_id 2222222222. Config: host=[DATABRICKS_URL], workspace_id=2222222222, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: classic_other_workspace
         Workspace:
        -  Host: [DATABRICKS_URL]
        +  Host: [DATABRICKS_URL]/?o=2222222222
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/classic_other_workspace
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === Target custom_host_without_workspace_id is rejected
         >>> errcode [CLI] bundle validate -t custom_host_without_workspace_id
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: host [CUSTOM_HOST] requires a workspace ID; set workspace.workspace_id or add ?o=<workspace-id> to workspace.host. Config: host=[CUSTOM_HOST], config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: custom_host_without_workspace_id
         Workspace:
           Host: [CUSTOM_HOST]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/custom_host_without_workspace_id
         
        -Found 1 error
        -
        -Exit code: 1
        +Validation OK!
        
FAIL

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/default_profile/no_host/DMS=: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1307
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1077
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:655
        	Error:      	Not equal: 
        	            	expected: "\n=== Target no_host uses the default profile\n>>> errcode [CLI] bundle run -t no_host show_auth\nprofile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]\n\n=== Target no_host_with_workspace_id uses the default profile\n>>> errcode [CLI] bundle run -t no_host_with_workspace_id show_auth\nprofile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]\n\n=== Target no_host_other_workspace is rejected\n>>> errcode [CLI] bundle validate -t no_host_other_workspace\nError: cannot resolve bundle auth configuration: resolve: strict profile matching: profile workspace_classic_id does not have workspace_id 2222222222. Config: workspace_id=2222222222, profile=workspace_classic_id, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH\n\nName: strict-profile-match\nTarget: no_host_other_workspace\n\nFound 1 error\n\nExit code: 1\n"
        	            	actual  : "\n=== Target no_host uses the default profile\n>>> errcode [CLI] bundle run -t no_host show_auth\nprofile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]\n\n=== Target no_host_with_workspace_id uses the default profile\n>>> errcode [CLI] bundle run -t no_host_with_workspace_id show_auth\nprofile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]\n\n=== Target no_host_other_workspace is rejected\n>>> errcode [CLI] bundle validate -t no_host_other_workspace\nName: strict-profile-match\nTarget: no_host_other_workspace\nWorkspace:\n  User: [USERNAME]\n  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/no_host_other_workspace\n\nValidation OK!\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -11,10 +11,9 @@
        	            	 >>> errcode [CLI] bundle validate -t no_host_other_workspace
        	            	-Error: cannot resolve bundle auth configuration: resolve: strict profile matching: profile workspace_classic_id does not have workspace_id 2222222222. Config: workspace_id=2222222222, profile=workspace_classic_id, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        	            	-
        	            	 Name: strict-profile-match
        	            	 Target: no_host_other_workspace
        	            	+Workspace:
        	            	+  User: [USERNAME]
        	            	+  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/no_host_other_workspace
        	            	 
        	            	-Found 1 error
        	            	+Validation OK!
        	            	 
        	            	-Exit code: 1
        	            	-
        	Test:       	TestAccept/bundle/strict_profile_match/default_profile/no_host/DMS=
        	Messages:   	bundle/strict_profile_match/default_profile/no_host/output.txt vs /tmp/TestAcceptbundlestrict_profile_matchdefault_profileno_hostD2665272197/002/output.txt

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/default_profile/no_host/DMS=true: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1307
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1077
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:655
        	Error:      	Not equal: 
        	            	expected: "\n=== Target no_host uses the default profile\n>>> errcode [CLI] bundle run -t no_host show_auth\nprofile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]\n\n=== Target no_host_with_workspace_id uses the default profile\n>>> errcode [CLI] bundle run -t no_host_with_workspace_id show_auth\nprofile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]\n\n=== Target no_host_other_workspace is rejected\n>>> errcode [CLI] bundle validate -t no_host_other_workspace\nError: cannot resolve bundle auth configuration: resolve: strict profile matching: profile workspace_classic_id does not have workspace_id 2222222222. Config: workspace_id=2222222222, profile=workspace_classic_id, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH\n\nName: strict-profile-match\nTarget: no_host_other_workspace\n\nFound 1 error\n\nExit code: 1\n"
        	            	actual  : "\n=== Target no_host uses the default profile\n>>> errcode [CLI] bundle run -t no_host show_auth\nprofile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]\n\n=== Target no_host_with_workspace_id uses the default profile\n>>> errcode [CLI] bundle run -t no_host_with_workspace_id show_auth\nprofile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]\n\n=== Target no_host_other_workspace is rejected\n>>> errcode [CLI] bundle validate -t no_host_other_workspace\nName: strict-profile-match\nTarget: no_host_other_workspace\nWorkspace:\n  User: [USERNAME]\n  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/no_host_other_workspace\n\nValidation OK!\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -11,10 +11,9 @@
        	            	 >>> errcode [CLI] bundle validate -t no_host_other_workspace
        	            	-Error: cannot resolve bundle auth configuration: resolve: strict profile matching: profile workspace_classic_id does not have workspace_id 2222222222. Config: workspace_id=2222222222, profile=workspace_classic_id, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        	            	-
        	            	 Name: strict-profile-match
        	            	 Target: no_host_other_workspace
        	            	+Workspace:
        	            	+  User: [USERNAME]
        	            	+  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/no_host_other_workspace
        	            	 
        	            	-Found 1 error
        	            	+Validation OK!
        	            	 
        	            	-Exit code: 1
        	            	-
        	Test:       	TestAccept/bundle/strict_profile_match/default_profile/no_host/DMS=true
        	Messages:   	bundle/strict_profile_match/default_profile/no_host/output.txt vs /tmp/TestAcceptbundlestrict_profile_matchdefault_profileno_hostD1158012680/002/output.txt

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/host/DMS=: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: Diff:
        --- bundle/strict_profile_match/host/output.txt
        +++ /tmp/TestAcceptbundlestrict_profile_matchhostDMS=2560382203/002/output.txt
        @@ -1,62 +1,57 @@
         
         === Target classic matches one profile
         >>> errcode [CLI] bundle run -t classic show_auth
        -profile=workspace_classic host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
        +profile= host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
         
         === Target classic_with_workspace_id matches one profile
         >>> errcode [CLI] bundle run -t classic_with_workspace_id show_auth
        -profile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
        +profile= host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
         
         === Target custom_host matches one profile
         >>> errcode [CLI] bundle run -t custom_host show_auth
        -profile=workspace_custom_host host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
        +profile= host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
         
         === Target custom_host_workspace_id_field matches one profile
         >>> errcode [CLI] bundle run -t custom_host_workspace_id_field show_auth
        -profile=workspace_custom_host host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
        +profile= host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
         
         === Target classic_other_workspace is rejected
         >>> errcode [CLI] bundle validate -t classic_other_workspace
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: no profile for host [DATABRICKS_URL] has workspace_id 2222222222. Config: host=[DATABRICKS_URL], workspace_id=2222222222, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: classic_other_workspace
         Workspace:
        -  Host: [DATABRICKS_URL]
        +  Host: [DATABRICKS_URL]/?o=2222222222
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/classic_other_workspace
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === Target custom_host_without_workspace_id is rejected
         >>> errcode [CLI] bundle validate -t custom_host_without_workspace_id
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: host [CUSTOM_HOST] requires a workspace ID; set workspace.workspace_id or add ?o=<workspace-id> to workspace.host. Config: host=[CUSTOM_HOST], config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: custom_host_without_workspace_id
         Workspace:
           Host: [CUSTOM_HOST]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/custom_host_without_workspace_id
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === Target custom_host_other_workspace is rejected
         >>> errcode [CLI] bundle validate -t custom_host_other_workspace
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: no profile for host [CUSTOM_HOST] has workspace_id 2222222222. Config: host=[CUSTOM_HOST], workspace_id=2222222222, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: custom_host_other_workspace
         Workspace:
        -  Host: [CUSTOM_HOST]
        +  Host: [CUSTOM_HOST]/?o=2222222222
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/custom_host_other_workspace
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === Target unknown_host is rejected
         >>> errcode [CLI] bundle validate -t unknown_host
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: no workspace profile matches host https://unknown.test. Config: host=https://unknown.test, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        +Warn: [hostmetadata] failed to fetch host metadata for https://unknown.test, will skip for 1m0s
        +Error: Get "https://unknown.test/api/2.0/preview/scim/v2/Me?": Bad Request
         
         Name: strict-profile-match
         Target: unknown_host

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/host/DMS=true: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: Diff:
        --- bundle/strict_profile_match/host/output.txt
        +++ /tmp/TestAcceptbundlestrict_profile_matchhostDMS=true893261925/002/output.txt
        @@ -1,62 +1,57 @@
         
         === Target classic matches one profile
         >>> errcode [CLI] bundle run -t classic show_auth
        -profile=workspace_classic host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
        +profile= host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
         
         === Target classic_with_workspace_id matches one profile
         >>> errcode [CLI] bundle run -t classic_with_workspace_id show_auth
        -profile=workspace_classic_id host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
        +profile= host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
         
         === Target custom_host matches one profile
         >>> errcode [CLI] bundle run -t custom_host show_auth
        -profile=workspace_custom_host host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
        +profile= host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
         
         === Target custom_host_workspace_id_field matches one profile
         >>> errcode [CLI] bundle run -t custom_host_workspace_id_field show_auth
        -profile=workspace_custom_host host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
        +profile= host=[CUSTOM_HOST] workspace_id=[WORKSPACE_ID]
         
         === Target classic_other_workspace is rejected
         >>> errcode [CLI] bundle validate -t classic_other_workspace
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: no profile for host [DATABRICKS_URL] has workspace_id 2222222222. Config: host=[DATABRICKS_URL], workspace_id=2222222222, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: classic_other_workspace
         Workspace:
        -  Host: [DATABRICKS_URL]
        +  Host: [DATABRICKS_URL]/?o=2222222222
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/classic_other_workspace
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === Target custom_host_without_workspace_id is rejected
         >>> errcode [CLI] bundle validate -t custom_host_without_workspace_id
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: host [CUSTOM_HOST] requires a workspace ID; set workspace.workspace_id or add ?o=<workspace-id> to workspace.host. Config: host=[CUSTOM_HOST], config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: custom_host_without_workspace_id
         Workspace:
           Host: [CUSTOM_HOST]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/custom_host_without_workspace_id
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === Target custom_host_other_workspace is rejected
         >>> errcode [CLI] bundle validate -t custom_host_other_workspace
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: no profile for host [CUSTOM_HOST] has workspace_id 2222222222. Config: host=[CUSTOM_HOST], workspace_id=2222222222, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: custom_host_other_workspace
         Workspace:
        -  Host: [CUSTOM_HOST]
        +  Host: [CUSTOM_HOST]/?o=2222222222
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/custom_host_other_workspace
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === Target unknown_host is rejected
         >>> errcode [CLI] bundle validate -t unknown_host
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: no workspace profile matches host https://unknown.test. Config: host=https://unknown.test, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        +Warn: [hostmetadata] failed to fetch host metadata for https://unknown.test, will skip for 1m0s
        +Error: Get "https://unknown.test/api/2.0/preview/scim/v2/Me?": Bad Request
         
         Name: strict-profile-match
         Target: unknown_host

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/no_host/DMS=: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: Diff:
        --- bundle/strict_profile_match/no_host/output.txt
        +++ /tmp/TestAcceptbundlestrict_profile_matchno_hostDMS=1558316631/002/output.txt
        @@ -21,15 +21,14 @@
         
         === A target without a host rejects a profile without the target's workspace ID
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/default.databrickscfg [CLI] bundle validate -t no_host_with_workspace_id
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: profile workspace_classic does not have workspace_id [WORKSPACE_ID]. Config: workspace_id=[WORKSPACE_ID], profile=workspace_classic, config_file=[TEST_TMP_DIR]/default.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: no_host_with_workspace_id
        +Workspace:
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/no_host_with_workspace_id
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === A target without a host rejects an unknown profile
         >>> errcode [CLI] bundle validate -t no_host -p my-local-profile
         Error: cannot resolve bundle auth configuration: resolve: [TEST_TMP_DIR]/.databrickscfg has no my-local-profile profile configured. Config: profile=my-local-profile, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/no_host/DMS=true: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: Diff:
        --- bundle/strict_profile_match/no_host/output.txt
        +++ /tmp/TestAcceptbundlestrict_profile_matchno_hostDMS=true3880105329/002/output.txt
        @@ -21,15 +21,14 @@
         
         === A target without a host rejects a profile without the target's workspace ID
         >>> errcode env DATABRICKS_CONFIG_FILE=[TEST_TMP_DIR]/default.databrickscfg [CLI] bundle validate -t no_host_with_workspace_id
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: profile workspace_classic does not have workspace_id [WORKSPACE_ID]. Config: workspace_id=[WORKSPACE_ID], profile=workspace_classic, config_file=[TEST_TMP_DIR]/default.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: no_host_with_workspace_id
        +Workspace:
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/no_host_with_workspace_id
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === A target without a host rejects an unknown profile
         >>> errcode [CLI] bundle validate -t no_host -p my-local-profile
         Error: cannot resolve bundle auth configuration: resolve: [TEST_TMP_DIR]/.databrickscfg has no my-local-profile profile configured. Config: profile=my-local-profile, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/profile/DMS=: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: Diff:
        --- bundle/strict_profile_match/profile/output.txt
        +++ /tmp/TestAcceptbundlestrict_profile_matchprofileDMS=3965326502/002/output.txt
        @@ -5,7 +5,7 @@
         
         === A workspace.profile that doesn't match the target is rejected
         >>> errcode [CLI] bundle validate -t classic_with_profile
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: profile my-local-profile does not match profile workspace_classic selected for host [DATABRICKS_URL]. Config: host=[DATABRICKS_URL], profile=my-local-profile, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        +Error: cannot resolve bundle auth configuration: resolve: [TEST_TMP_DIR]/.databrickscfg has no my-local-profile profile configured. Config: host=[DATABRICKS_URL], profile=my-local-profile, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
         
         Name: strict-profile-match
         Target: classic_with_profile
        @@ -22,21 +22,19 @@
         
         === An explicit profile that doesn't match the target is rejected
         >>> errcode [CLI] bundle validate -t classic -p workspace_classic_id
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: profile workspace_classic_id does not match profile workspace_classic selected for host [DATABRICKS_URL]. Config: host=[DATABRICKS_URL], profile=workspace_classic_id, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: classic
         Workspace:
           Host: [DATABRICKS_URL]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/classic
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === An explicit profile wins over workspace.profile, as without strict mode
         >>> errcode [CLI] bundle run -t classic_with_profile -p workspace_classic show_auth
         profile=workspace_classic host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
         
         === A CLI started from a bundle script uses the selected profile
         >>> errcode [CLI] bundle run -t custom_host nested_validate
        -workspace_custom_host
        +null

latest (v1.21.0): same output as main (be6a8e1)

TestAccept/bundle/strict_profile_match/profile/DMS=true: branch ✅ | main (be6a8e1) ❌ | latest (v1.21.0) ❌

main (be6a8e1):

acceptance_test.go:1307: Diff:
        --- bundle/strict_profile_match/profile/output.txt
        +++ /tmp/TestAcceptbundlestrict_profile_matchprofileDMS=true2248443275/002/output.txt
        @@ -5,7 +5,7 @@
         
         === A workspace.profile that doesn't match the target is rejected
         >>> errcode [CLI] bundle validate -t classic_with_profile
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: profile my-local-profile does not match profile workspace_classic selected for host [DATABRICKS_URL]. Config: host=[DATABRICKS_URL], profile=my-local-profile, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        +Error: cannot resolve bundle auth configuration: resolve: [TEST_TMP_DIR]/.databrickscfg has no my-local-profile profile configured. Config: host=[DATABRICKS_URL], profile=my-local-profile, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
         
         Name: strict-profile-match
         Target: classic_with_profile
        @@ -22,21 +22,19 @@
         
         === An explicit profile that doesn't match the target is rejected
         >>> errcode [CLI] bundle validate -t classic -p workspace_classic_id
        -Error: cannot resolve bundle auth configuration: resolve: strict profile matching: profile workspace_classic_id does not match profile workspace_classic selected for host [DATABRICKS_URL]. Config: host=[DATABRICKS_URL], profile=workspace_classic_id, config_file=[TEST_TMP_DIR]/.databrickscfg, databricks_cli_path=[CLI]. Env: DATABRICKS_CONFIG_FILE, DATABRICKS_CLI_PATH
        -
         Name: strict-profile-match
         Target: classic
         Workspace:
           Host: [DATABRICKS_URL]
        +  User: [USERNAME]
        +  Path: /Workspace/Users/[USERNAME]/.bundle/strict-profile-match/classic
         
        -Found 1 error
        +Validation OK!
         
        -Exit code: 1
        -
         === An explicit profile wins over workspace.profile, as without strict mode
         >>> errcode [CLI] bundle run -t classic_with_profile -p workspace_classic show_auth
         profile=workspace_classic host=[DATABRICKS_URL] workspace_id=[WORKSPACE_ID]
         
         === A CLI started from a bundle script uses the selected profile
         >>> errcode [CLI] bundle run -t custom_host nested_validate
        -workspace_custom_host
        +null

latest (v1.21.0): same output as main (be6a8e1)

The acceptance envsubst.py substitutes every variable and ignores the
variable list, so on Windows the bundle script still got the CLI path with
backslashes. Move the script to an included scripts.yml that is not
substituted, so bash expands $CLI at run time.

Co-authored-by: Isaac <no-reply@databricks.com>
Comment thread bundle/config/workspace.go
Comment thread cmd/root/bundle.go Outdated
configureStrictProfile(cmd.Context(), b, profile)
return
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If this is integrated in the series of loaders it can be the first one to run and fail hard if there is no match.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated.

trace errcode env DATABRICKS_CONFIG_FILE=$TEST_TMP_DIR/account.databrickscfg $CLI bundle validate -t custom_host_without_workspace_id

title "Strict mode, a missing config file is rejected"
trace errcode env DATABRICKS_CONFIG_FILE=$TEST_TMP_DIR/missing.databrickscfg $CLI bundle validate -t classic

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This acc test is pretty hard to review.

Is there a logical separation to make for different categories of failure modes, and turn them into separate acc tests, or is this not worth the squeeze?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Split it into 5 tests: disabled, host, profile, no_host, config_file.

pavloKozlov and others added 2 commits October 20, 2026 11:44
A target without a host takes its profile from --profile or
DATABRICKS_CONFIG_PROFILE, then workspace.profile, then
[__settings__].default_profile, the same order as without strict mode. The
profile must be a workspace profile in the config file, and if the target sets
a workspace ID, the profile must have it. This lets a caller that writes the
config file run bundles without a host without passing a profile.

Co-authored-by: Isaac <no-reply@databricks.com>
Strict profile matching is now a loader next to ResolveProfileFromHost, so
there is one mechanism that selects a profile. When strict mode is on,
Workspace.Client uses ProfileAuthLoaders with the strict loader before the
config file. The loader does the same host and workspace_id lookup as
ResolveProfileFromHost, but always runs and fails when there is no single
match. Targets without a host use the profile that configureProfile already
selects from --profile, workspace.profile or default_profile.

Split the acceptance test into separate tests for the disabled mode, targets
with a host, explicit profiles, targets without a host and config file cases.

Co-authored-by: Isaac <no-reply@databricks.com>
With [__settings__].default_profile set, targets without a host use the
default profile and must agree with its workspace ID, while targets with a
host still match by host and workspace ID and ignore the default.

Co-authored-by: Isaac <no-reply@databricks.com>
github-merge-queue Bot pushed a commit that referenced this pull request Oct 20, 2026
Follow-up to #7105. The comments
on #6989 and
#7109 were 34-44 KB, close to the
60 KB cap, mostly because a new test fails the same way on main and on
the latest release and the same diff was printed twice.

- A failing run whose output equals an earlier column's (ignoring the
random temp dir) now says "same output as <column>".
- When the comment is over the cap, whole failure details are dropped
(with a count) instead of cutting one in the middle and leaving its
markup open.

This pull request and its description were written by Isaac.

---------

Co-authored-by: Isaac <no-reply@databricks.com>

@pietern pietern left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add unit tests to loader_test.go like the existing ones.

It helps to see the specific cases side by side and I think it would have helped surface the error returned for empty configs (this should not error).

Comment thread libs/databrickscfg/loader.go Outdated

// StrictProfileLoaders is ProfileAuthLoaders with strictProfileLoader before
// the config file, so the profile always comes from the config file, even when
// auth env vars are set.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This comment should be more specific. The intent is that the profile name always comes from the databrickscfg config file, based on the workspace host and workspace ID in the bundle configuration.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

Comment thread libs/databrickscfg/loader.go Outdated
// one that the profile must have.
func checkNamedProfile(cfg *config.Config, configFile *config.File) error {
if cfg.Profile == "" {
return errors.New("strict profile matching: set workspace.host, or select a profile with --profile, workspace.profile or [__settings__].default_profile")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This means a hard failure if the neither the host nor the profile are set in the bundle configuration.

I thought it would have to fall through to the default profile in this case.

The strict matching only kicks in when you have a host and/or a workspace ID in the incoming config.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think there was a misunderstanding. Fixed. If there is no host or workspace id it falls through like in non-strict mode.

Comment thread libs/databrickscfg/loader.go Outdated
if err != nil || sectionValue(s, hostAttr) == "" || !isWorkspaceSection(s) {
return fmt.Errorf("strict profile matching: %s is not a workspace profile with a host in the config file", cfg.Profile)
}
if cfg.WorkspaceID != "" && sectionValue(s, "workspace_id") != cfg.WorkspaceID {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We don't check the workspace host here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There's no host in the bundle config in this branch, so there is nothing to compare.

if cfg.Host == "" {
    return checkNamedProfile(cfg, configFile)
}

Added a comment there.

Comment thread bundle/config/workspace.go Outdated

cfg := w.Config(ctx)

_, strict := env.StrictProfileMatch(ctx)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The value is ignored, meaning false or 0 still enabled it.

IIRC there is precedence for interpreting the value as boolish.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Updated it to use env.GetBool.

…e ID

A target without a host or workspace ID has nothing to match, so it now
resolves as without strict mode instead of failing. The loader also returns
nil in that case.

Read DATABRICKS_BUNDLE_STRICT_PROFILE_MATCH as a boolean, so "0" or "false"
leave strict mode off.

Add unit tests for the strict loader next to the existing loader tests.

Co-authored-by: Isaac <no-reply@databricks.com>
@pavloKozlov
pavloKozlov requested a review from pietern October 21, 2026 13:35
@pavloKozlov
pavloKozlov added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit f5a6790 Oct 21, 2026
28 checks passed
@pavloKozlov
pavloKozlov deleted the strict-profile-match branch October 21, 2026 13:58
deco-sdk-tagging Bot added a commit that referenced this pull request Oct 22, 2026
## Release v1.22.0

### CLI

 * Fix `databricks aitools install` overwriting newer raw skills with an older pinned release. CLI 1.22.0 and newer now install the latest published skills and prevent automatic downgrades. ([#7069](#7069))
 * Fix `auth login --timeout` not applying to the browser login, which waited for the OAuth redirect indefinitely. ([#7103](#7103))
 * Remove the 50-workspace limit in `auth login` and support searching workspaces by name or ID. ([#7071](#7071))
 * `databricks ssh connect` now fails right away with the workspace's reason when port forwarding to serverless compute is disabled, instead of waiting out the server start timeout. ([#7057](#7057))

### AI Runtime

 * `air run` now spends less time before submitting: it fetches only the user name from SCIM. ([#7153](#7153))
 * Align multi-image container name validation with backend services: allow hyphens and up to 32 characters, and reject uppercase letters and underscores. ([#7154](#7154))

### Bundles

 * The `compute_id` deprecation warning for a target now shows the full path (`targets.<name>.compute_id`). ([#7048](#7048))
 * Add `DATABRICKS_BUNDLE_STRICT_PROFILE_MATCH`, which requires a target's host and workspace ID to match exactly one profile in the config file before authenticating. Targets without a host or workspace ID are not affected. ([#7109](#7109))
 * Zero-value overrides of `presets`, `lifecycle.prevent_destroy` and `deployment` settings in includes now replace non-zero base values, and `bundle validate -o json` shows explicit zero presets. ([#7117](#7117))
 * `bundle deployment bind` and `unbind` now accept a resource as `type.key`, e.g. `jobs.foo`. ([#7128](#7128))
 * Retry more transient server errors during `bundle deploy` and `bundle destroy`, including when releasing the deploy lock and reading state. ([#7129](#7129))
 * Fix migration from Terraform failing when a deployed resource references a resource that was never deployed. ([#7157](#7157))
 * Add `app-appkit` to bundle templates to simplify starting a Databricks Apps project. ([#7004](#7004), [#7007](#7007))
 * Add support for the `features` resource type. ([#6952](#6952))
 * Fix `bundle validate` warning that `sync.include` and `sync.exclude` patterns do not match any files when `sync.paths` includes a directory outside the bundle root. ([#7122](#7122))

### Dependency Updates

 * Bump dependencies with known vulnerabilities. ([#7083](#7083))
 * Bump Go to 1.27.2. Release binaries now require macOS 13 Ventura or later. ([#7052](#7052))
 * Update the Go SDK to [v0.189.0](https://github.com/databricks/databricks-sdk-go/releases/tag/v0.189.0). ([#7138](#7138))
 * Bump Go toolchain to 1.27.3. ([#7116](#7116))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DABs DABs related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants