From 05fd310fe71f8a61dcfe6d03369695e5056015ac Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Tue, 13 Oct 2026 14:02:12 +0000 Subject: [PATCH 01/10] Validate supported DMS resource types in test server --- libs/testserver/bundledeployments.go | 43 +++++++++++- libs/testserver/bundledeployments_test.go | 83 +++++++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 libs/testserver/bundledeployments_test.go diff --git a/libs/testserver/bundledeployments.go b/libs/testserver/bundledeployments.go index b4019b75d0a..caaeaada39f 100644 --- a/libs/testserver/bundledeployments.go +++ b/libs/testserver/bundledeployments.go @@ -34,6 +34,46 @@ const dmsDeploymentNodeName = "resources.deployment.json" // created. var dmsUpdatableOperationFields = []string{"state", "error_message", "resource_id", "status"} +// dmsResourceTypes mirrors the resource_key prefixes in Universe's bundle/metadata-service. +// NOTE: When adding a type here, also add the corresponding enum in bundle/metadata-service/service.proto +// and prefix mapping in parser/ResourceTypes.java in Universe. +var dmsResourceTypes = []string{ + "alerts", + "apps", + "catalogs", + "cluster_policies", + "clusters", + "dashboards", + "database_catalogs", + "database_instances", + "experiments", + "external_locations", + "genie_spaces", + "instance_pools", + "job_runs", + "jobs", + "model_serving_endpoints", + "models", + "pipelines", + "postgres_branches", + "postgres_catalogs", + "postgres_databases", + "postgres_endpoints", + "postgres_projects", + "postgres_roles", + "postgres_synced_tables", + "quality_monitors", + "registered_models", + "schemas", + "secret_scopes", + "secrets", + "sql_warehouses", + "synced_database_tables", + "vector_search_endpoints", + "vector_search_indexes", + "volumes", +} + // DmsDeployment holds a deployment record together with the versions and // resources recorded under it, so the read APIs (ListVersions/ListResources) // can serve back what deploys wrote. @@ -327,10 +367,11 @@ func (s *FakeWorkspace) CreateVersion(req Request, deploymentID string) Response } seen := make(map[string]bool, len(staged.Operations)) for _, staged := range staged.Operations { + resourceType, _, hasPrefix := strings.Cut(staged.ResourceKey, ".") switch { case staged.ResourceKey == "": return dmsInvalidArgument("operations.resource_key is required") - case !strings.Contains(staged.ResourceKey, "."): + case !hasPrefix || !slices.Contains(dmsResourceTypes, resourceType): return dmsInvalidArgument("operations.resource_key must have a known resource type prefix (e.g. 'jobs.', 'pipelines.'): " + staged.ResourceKey) case staged.ActionType == "": return dmsInvalidArgument("operations.action_type is required and must not be UNSPECIFIED for resource " + staged.ResourceKey) diff --git a/libs/testserver/bundledeployments_test.go b/libs/testserver/bundledeployments_test.go new file mode 100644 index 00000000000..ca862ef52d7 --- /dev/null +++ b/libs/testserver/bundledeployments_test.go @@ -0,0 +1,83 @@ +package testserver_test + +import ( + "encoding/json" + "net/url" + "testing" + + "github.com/databricks/cli/libs/testserver" + "github.com/databricks/databricks-sdk-go/service/bundledeployments" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestCreateVersionResourceTypes checks the resource_key validation shared with DMS. +func TestCreateVersionResourceTypes(t *testing.T) { + tests := []struct { + resourceKey string + supported bool + }{ + {resourceKey: "jobs.my_job", supported: true}, + {resourceKey: "pipelines.my_pipeline", supported: true}, + {resourceKey: "postgres_roles.my_role", supported: true}, + {resourceKey: "secrets.my_secret", supported: true}, + {resourceKey: "cluster_policies.my_policy", supported: true}, + {resourceKey: "jobs.name.with.dots", supported: true}, + {resourceKey: ""}, + {resourceKey: "jobs"}, + {resourceKey: ".my_resource"}, + {resourceKey: "unknown.my_resource"}, + {resourceKey: "mcp_services.my_service"}, + {resourceKey: "model_provider_services.my_service"}, + {resourceKey: "model_services.my_service"}, + {resourceKey: "postgres_snapshot_schedules.my_schedule"}, + {resourceKey: "resources.jobs.my_job"}, + {resourceKey: "JOBS.my_job"}, + } + for _, tt := range tests { + t.Run(tt.resourceKey, func(t *testing.T) { + deployment := &testserver.DmsDeployment{ + Versions: map[string]*bundledeployments.Version{}, + Resources: map[string]bundledeployments.Resource{}, + Operations: map[string]*bundledeployments.Operation{}, + } + ws := &testserver.FakeWorkspace{ + DmsDeployments: map[string]*testserver.DmsDeployment{"123": deployment}, + } + body, err := json.Marshal(map[string]any{ + "operations": []map[string]string{ + {"resource_key": "jobs.other", "action_type": "OPERATION_ACTION_TYPE_CREATE"}, + {"resource_key": tt.resourceKey, "action_type": "OPERATION_ACTION_TYPE_CREATE"}, + }, + }) + require.NoError(t, err) + resp := ws.CreateVersion(testserver.Request{ + URL: &url.URL{RawQuery: "version_id=1"}, + Body: body, + }, "123") + + if !tt.supported { + require.Equal(t, 400, resp.StatusCode) + message := "operations.resource_key must have a known resource type prefix (e.g. 'jobs.', 'pipelines.'): " + tt.resourceKey + if tt.resourceKey == "" { + message = "operations.resource_key is required" + } + assert.Equal(t, map[string]string{ + "error_code": "INVALID_PARAMETER_VALUE", + "message": message, + }, resp.Body) + assert.Empty(t, deployment.Deployment.LastVersionId) + assert.Empty(t, deployment.Versions) + assert.Empty(t, deployment.Operations) + assert.Empty(t, deployment.Resources) + return + } + + require.Zero(t, resp.StatusCode) + assert.Equal(t, "1", deployment.Deployment.LastVersionId) + assert.Contains(t, deployment.Versions, "1") + assert.Len(t, deployment.Operations, 2) + assert.Contains(t, deployment.Operations, "deployments/123/versions/1/operations/"+tt.resourceKey) + }) + } +} From fba87eaad3bdc3708f18e6e79b4a5948f0d433aa Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Tue, 13 Oct 2026 14:17:45 +0000 Subject: [PATCH 02/10] Remove DMS resource validation test file --- libs/testserver/bundledeployments_test.go | 83 ----------------------- 1 file changed, 83 deletions(-) delete mode 100644 libs/testserver/bundledeployments_test.go diff --git a/libs/testserver/bundledeployments_test.go b/libs/testserver/bundledeployments_test.go deleted file mode 100644 index ca862ef52d7..00000000000 --- a/libs/testserver/bundledeployments_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package testserver_test - -import ( - "encoding/json" - "net/url" - "testing" - - "github.com/databricks/cli/libs/testserver" - "github.com/databricks/databricks-sdk-go/service/bundledeployments" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -// TestCreateVersionResourceTypes checks the resource_key validation shared with DMS. -func TestCreateVersionResourceTypes(t *testing.T) { - tests := []struct { - resourceKey string - supported bool - }{ - {resourceKey: "jobs.my_job", supported: true}, - {resourceKey: "pipelines.my_pipeline", supported: true}, - {resourceKey: "postgres_roles.my_role", supported: true}, - {resourceKey: "secrets.my_secret", supported: true}, - {resourceKey: "cluster_policies.my_policy", supported: true}, - {resourceKey: "jobs.name.with.dots", supported: true}, - {resourceKey: ""}, - {resourceKey: "jobs"}, - {resourceKey: ".my_resource"}, - {resourceKey: "unknown.my_resource"}, - {resourceKey: "mcp_services.my_service"}, - {resourceKey: "model_provider_services.my_service"}, - {resourceKey: "model_services.my_service"}, - {resourceKey: "postgres_snapshot_schedules.my_schedule"}, - {resourceKey: "resources.jobs.my_job"}, - {resourceKey: "JOBS.my_job"}, - } - for _, tt := range tests { - t.Run(tt.resourceKey, func(t *testing.T) { - deployment := &testserver.DmsDeployment{ - Versions: map[string]*bundledeployments.Version{}, - Resources: map[string]bundledeployments.Resource{}, - Operations: map[string]*bundledeployments.Operation{}, - } - ws := &testserver.FakeWorkspace{ - DmsDeployments: map[string]*testserver.DmsDeployment{"123": deployment}, - } - body, err := json.Marshal(map[string]any{ - "operations": []map[string]string{ - {"resource_key": "jobs.other", "action_type": "OPERATION_ACTION_TYPE_CREATE"}, - {"resource_key": tt.resourceKey, "action_type": "OPERATION_ACTION_TYPE_CREATE"}, - }, - }) - require.NoError(t, err) - resp := ws.CreateVersion(testserver.Request{ - URL: &url.URL{RawQuery: "version_id=1"}, - Body: body, - }, "123") - - if !tt.supported { - require.Equal(t, 400, resp.StatusCode) - message := "operations.resource_key must have a known resource type prefix (e.g. 'jobs.', 'pipelines.'): " + tt.resourceKey - if tt.resourceKey == "" { - message = "operations.resource_key is required" - } - assert.Equal(t, map[string]string{ - "error_code": "INVALID_PARAMETER_VALUE", - "message": message, - }, resp.Body) - assert.Empty(t, deployment.Deployment.LastVersionId) - assert.Empty(t, deployment.Versions) - assert.Empty(t, deployment.Operations) - assert.Empty(t, deployment.Resources) - return - } - - require.Zero(t, resp.StatusCode) - assert.Equal(t, "1", deployment.Deployment.LastVersionId) - assert.Contains(t, deployment.Versions, "1") - assert.Len(t, deployment.Operations, 2) - assert.Contains(t, deployment.Operations, "deployments/123/versions/1/operations/"+tt.resourceKey) - }) - } -} From 4c6089e3e4fed9642e438c808cbf873d26d247a9 Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Wed, 14 Oct 2026 11:41:33 +0000 Subject: [PATCH 03/10] Assert DMS rejection for unsupported resource types in acceptance tests --- .../deploy/immutable-no-artifacts/script | 2 ++ .../immutable-permissions-change/script | 2 ++ acceptance/bundle/deploy/immutable/script | 2 ++ .../bundle/dms/immutable-folder/output.txt | 27 +++++++------------ acceptance/bundle/dms/immutable-folder/script | 8 +++--- acceptance/bundle/invariant/no_drift/script | 4 +++ .../bundle/resources/apps/immutable/script | 2 ++ .../resources/grants/mcp_services/script | 2 ++ .../grants/model_provider_services/script | 2 ++ .../resources/grants/model_services/script | 2 ++ .../resources/mcp_services/basic/script | 2 ++ .../resources/mcp_services/lifecycle/script | 2 ++ .../mcp_services/remote-delete/script | 2 ++ .../model_provider_services/basic/script | 2 ++ .../model_provider_services/lifecycle/script | 2 ++ .../remote-delete/script | 2 ++ .../resources/model_services/basic/script | 2 ++ .../resources/model_services/lifecycle/script | 2 ++ .../model_services/remote-delete/script | 2 ++ .../postgres_snapshot_schedules/basic/script | 2 ++ .../out-of-band/script | 2 ++ acceptance/script.prepare | 18 +++++++++++++ 22 files changed, 73 insertions(+), 20 deletions(-) diff --git a/acceptance/bundle/deploy/immutable-no-artifacts/script b/acceptance/bundle/deploy/immutable-no-artifacts/script index 4bf3fddd7a6..8a41c1493eb 100644 --- a/acceptance/bundle/deploy/immutable-no-artifacts/script +++ b/acceptance/bundle/deploy/immutable-no-artifacts/script @@ -1,5 +1,7 @@ envsubst < databricks.yml.tmpl > databricks.yml +assert_dms_unsupported internal_immutable_snapshots + trace $CLI bundle validate trace $CLI bundle plan -o json > plan.json trace jq '.plan["resources.jobs.my_job"].new_state.value.tasks' plan.json diff --git a/acceptance/bundle/deploy/immutable-permissions-change/script b/acceptance/bundle/deploy/immutable-permissions-change/script index 458bfdd2c85..4c9acc92719 100644 --- a/acceptance/bundle/deploy/immutable-permissions-change/script +++ b/acceptance/bundle/deploy/immutable-permissions-change/script @@ -1,5 +1,7 @@ envsubst < databricks.yml.tmpl > databricks.yml +assert_dms_unsupported internal_immutable_snapshots + cleanup() { trace $CLI bundle destroy --auto-approve } diff --git a/acceptance/bundle/deploy/immutable/script b/acceptance/bundle/deploy/immutable/script index 5babe793a9a..8bc130b1ad4 100644 --- a/acceptance/bundle/deploy/immutable/script +++ b/acceptance/bundle/deploy/immutable/script @@ -1,4 +1,6 @@ envsubst < databricks.yml.tmpl > databricks.yml + +assert_dms_unsupported internal_immutable_snapshots cleanup() { trace $CLI bundle destroy --auto-approve } diff --git a/acceptance/bundle/dms/immutable-folder/output.txt b/acceptance/bundle/dms/immutable-folder/output.txt index a45aa8ba189..925e01b3fe6 100644 --- a/acceptance/bundle/dms/immutable-folder/output.txt +++ b/acceptance/bundle/dms/immutable-folder/output.txt @@ -1,43 +1,36 @@ -=== Deploying with an immutable folder records the resolved snapshot path as the deployment's file_path ->>> [CLI] bundle deploy -Created internal_immutable_snapshots.immutable -Created jobs.foo -Files: 0 uploaded, 0 deleted -Resources: 2 created, 0 changed, 0 deleted, 0 unchanged +=== DMS records the requested snapshot path but rejects unsupported immutable snapshots +DMS rejected unsupported immutable snapshots >>> MSYS_NO_PATHCONV=1 [CLI] api get /api/2.0/bundle/deployments/[DEPLOYMENT_ID] { "workspace_info": { "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-immutable-folder-[UNIQUE_NAME]/default", "file_path": "/Workspace/Users/[UUID]/.snapshots/[SNAPSHOT_HASH]/[SNAPSHOT_HASH]/files" - } + }, + "last_version_id": "" } === A new snapshot moves file_path, which is then updated on the deployment ->>> [CLI] bundle deploy -Recreated internal_immutable_snapshots.immutable -Updated jobs.foo -Files: 0 uploaded, 0 deleted -Resources: 1 created, 1 changed, 1 deleted, 0 unchanged +DMS rejected unsupported immutable snapshots >>> MSYS_NO_PATHCONV=1 [CLI] api get /api/2.0/bundle/deployments/[DEPLOYMENT_ID] { "workspace_info": { "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-immutable-folder-[UNIQUE_NAME]/default", "file_path": "/Workspace/Users/[UUID]/.snapshots/[SNAPSHOT_HASH]/[SNAPSHOT_HASH]/files" - } + }, + "last_version_id": "" } === An unchanged snapshot keeps the recorded file_path ->>> [CLI] bundle deploy -Files: 0 uploaded, 0 deleted -Resources: 0 created, 0 changed, 0 deleted, 2 unchanged +DMS rejected unsupported immutable snapshots >>> MSYS_NO_PATHCONV=1 [CLI] api get /api/2.0/bundle/deployments/[DEPLOYMENT_ID] { "workspace_info": { "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-immutable-folder-[UNIQUE_NAME]/default", "file_path": "/Workspace/Users/[UUID]/.snapshots/[SNAPSHOT_HASH]/[SNAPSHOT_HASH]/files" - } + }, + "last_version_id": "" } diff --git a/acceptance/bundle/dms/immutable-folder/script b/acceptance/bundle/dms/immutable-folder/script index ff70d11a08f..35b5ed553cd 100644 --- a/acceptance/bundle/dms/immutable-folder/script +++ b/acceptance/bundle/dms/immutable-folder/script @@ -4,17 +4,19 @@ deployment_workspace_info() { deployment_id=$(MSYS_NO_PATHCONV=1 $CLI workspace get-status "/Workspace/Users/${CURRENT_USER_NAME}/.bundle/dms-immutable-folder-${UNIQUE_NAME}/default/state/resources.deployment.json" -o json | python3 -c 'import sys,json; print(json.load(sys.stdin)["object_id"])') add_repl "$deployment_id" DEPLOYMENT_ID # MSYS_NO_PATHCONV: Git Bash on Windows would rewrite the leading-'/' API path. - trace MSYS_NO_PATHCONV=1 $CLI api get "/api/2.0/bundle/deployments/${deployment_id}" | jq '{workspace_info}' + trace MSYS_NO_PATHCONV=1 $CLI api get "/api/2.0/bundle/deployments/${deployment_id}" | jq '{workspace_info, last_version_id: (.last_version_id // "")}' } deploy() { mkdir -p .databricks $CLI bundle plan -o json > .databricks/plan.json - trace $CLI bundle deploy $(readplanarg .databricks/plan.json) + trace musterr $CLI bundle deploy $(readplanarg .databricks/plan.json) &> "$(dirname "$OUT_REQUESTS")/LOG.deploy" + contains.py "operations.resource_key must have a known resource type prefix" "internal_immutable_snapshots.immutable" < "$(dirname "$OUT_REQUESTS")/LOG.deploy" > /dev/null + printf '\nDMS rejected unsupported immutable snapshots\n' rm .databricks/plan.json } -title "Deploying with an immutable folder records the resolved snapshot path as the deployment's file_path" +title "DMS records the requested snapshot path but rejects unsupported immutable snapshots" deploy deployment_workspace_info diff --git a/acceptance/bundle/invariant/no_drift/script b/acceptance/bundle/invariant/no_drift/script index 0961e8edac8..89a5edc9ef0 100644 --- a/acceptance/bundle/invariant/no_drift/script +++ b/acceptance/bundle/invariant/no_drift/script @@ -3,6 +3,10 @@ invariant_setup +if [[ "$INPUT_CONFIG" == "model_service.yml.tmpl" ]]; then + assert_dms_unsupported model_services +fi + # Only compute a plan up front when the READPLAN variant actually consumes it via --plan. # Without READPLAN, deploy computes its own plan internally, so a separate `bundle plan` # invocation is pure waste. diff --git a/acceptance/bundle/resources/apps/immutable/script b/acceptance/bundle/resources/apps/immutable/script index a64a9bdaf16..b16d68c98a7 100644 --- a/acceptance/bundle/resources/apps/immutable/script +++ b/acceptance/bundle/resources/apps/immutable/script @@ -1,5 +1,7 @@ envsubst < databricks.yml.tmpl > databricks.yml +assert_dms_unsupported internal_immutable_snapshots + cleanup() { rm -f "$OUT_REQUESTS" } diff --git a/acceptance/bundle/resources/grants/mcp_services/script b/acceptance/bundle/resources/grants/mcp_services/script index eafb6a07c58..e666dcec582 100644 --- a/acceptance/bundle/resources/grants/mcp_services/script +++ b/acceptance/bundle/resources/grants/mcp_services/script @@ -1,5 +1,7 @@ envsubst < databricks.yml.tmpl > databricks.yml +assert_dms_unsupported mcp_services + trace $CLI bundle plan -o json | jq 'del(.features)' > out.plan1.json trace print_requests.py --get //permissions trace $CLI bundle deploy diff --git a/acceptance/bundle/resources/grants/model_provider_services/script b/acceptance/bundle/resources/grants/model_provider_services/script index 7c9f39f37db..32093ca1768 100644 --- a/acceptance/bundle/resources/grants/model_provider_services/script +++ b/acceptance/bundle/resources/grants/model_provider_services/script @@ -1,5 +1,7 @@ envsubst < databricks.yml.tmpl > databricks.yml +assert_dms_unsupported model_provider_services + trace $CLI bundle plan -o json | jq 'del(.features)' > out.plan1.json trace print_requests.py --get //permissions trace $CLI bundle deploy diff --git a/acceptance/bundle/resources/grants/model_services/script b/acceptance/bundle/resources/grants/model_services/script index 60f6d70750c..c95f429dd66 100644 --- a/acceptance/bundle/resources/grants/model_services/script +++ b/acceptance/bundle/resources/grants/model_services/script @@ -1,5 +1,7 @@ envsubst < databricks.yml.tmpl > databricks.yml +assert_dms_unsupported model_services + trace $CLI bundle plan -o json | jq 'del(.features)' > out.plan1.json trace print_requests.py --get //permissions trace $CLI bundle deploy diff --git a/acceptance/bundle/resources/mcp_services/basic/script b/acceptance/bundle/resources/mcp_services/basic/script index eedd128b1e6..f56bcaab263 100644 --- a/acceptance/bundle/resources/mcp_services/basic/script +++ b/acceptance/bundle/resources/mcp_services/basic/script @@ -1,3 +1,5 @@ +assert_dms_unsupported mcp_services + title "Initial summary before deploy" trace $CLI bundle summary -o json | jq .resources.mcp_services.mcp1 diff --git a/acceptance/bundle/resources/mcp_services/lifecycle/script b/acceptance/bundle/resources/mcp_services/lifecycle/script index 6e9514f3a38..18964e3c728 100644 --- a/acceptance/bundle/resources/mcp_services/lifecycle/script +++ b/acceptance/bundle/resources/mcp_services/lifecycle/script @@ -1,5 +1,7 @@ envsubst < databricks.yml.tmpl > databricks.yml +assert_dms_unsupported mcp_services + CONN="mcp_conn_$UNIQUE_NAME" cleanup() { diff --git a/acceptance/bundle/resources/mcp_services/remote-delete/script b/acceptance/bundle/resources/mcp_services/remote-delete/script index 413e6174fd4..c5ac658b246 100644 --- a/acceptance/bundle/resources/mcp_services/remote-delete/script +++ b/acceptance/bundle/resources/mcp_services/remote-delete/script @@ -1,3 +1,5 @@ +assert_dms_unsupported mcp_services + trace $CLI bundle deploy title "Delete the resource out of band" diff --git a/acceptance/bundle/resources/model_provider_services/basic/script b/acceptance/bundle/resources/model_provider_services/basic/script index f12527b141d..f486db2103c 100644 --- a/acceptance/bundle/resources/model_provider_services/basic/script +++ b/acceptance/bundle/resources/model_provider_services/basic/script @@ -1,3 +1,5 @@ +assert_dms_unsupported model_provider_services + title "Initial summary before deploy" trace $CLI bundle summary -o json | jq .resources.model_provider_services.mps1 diff --git a/acceptance/bundle/resources/model_provider_services/lifecycle/script b/acceptance/bundle/resources/model_provider_services/lifecycle/script index 634183f4759..4e45d3ab13b 100644 --- a/acceptance/bundle/resources/model_provider_services/lifecycle/script +++ b/acceptance/bundle/resources/model_provider_services/lifecycle/script @@ -1,5 +1,7 @@ envsubst < databricks.yml.tmpl > databricks.yml +assert_dms_unsupported model_provider_services + cleanup() { trace $CLI bundle destroy --auto-approve } diff --git a/acceptance/bundle/resources/model_provider_services/remote-delete/script b/acceptance/bundle/resources/model_provider_services/remote-delete/script index e7377733cc6..2640b843e7f 100644 --- a/acceptance/bundle/resources/model_provider_services/remote-delete/script +++ b/acceptance/bundle/resources/model_provider_services/remote-delete/script @@ -1,3 +1,5 @@ +assert_dms_unsupported model_provider_services + trace $CLI bundle deploy title "Delete the resource out of band" diff --git a/acceptance/bundle/resources/model_services/basic/script b/acceptance/bundle/resources/model_services/basic/script index f52a481086a..77a9cd4d97a 100644 --- a/acceptance/bundle/resources/model_services/basic/script +++ b/acceptance/bundle/resources/model_services/basic/script @@ -1,3 +1,5 @@ +assert_dms_unsupported model_services + title "Initial summary before deploy" trace $CLI bundle summary -o json | jq .resources.model_services.ms1 diff --git a/acceptance/bundle/resources/model_services/lifecycle/script b/acceptance/bundle/resources/model_services/lifecycle/script index ed9c256d01c..da56d001af8 100644 --- a/acceptance/bundle/resources/model_services/lifecycle/script +++ b/acceptance/bundle/resources/model_services/lifecycle/script @@ -1,5 +1,7 @@ envsubst < databricks.yml.tmpl > databricks.yml +assert_dms_unsupported model_services + cleanup() { trace $CLI bundle destroy --auto-approve } diff --git a/acceptance/bundle/resources/model_services/remote-delete/script b/acceptance/bundle/resources/model_services/remote-delete/script index ad9170ef687..e6a4e7e3af8 100644 --- a/acceptance/bundle/resources/model_services/remote-delete/script +++ b/acceptance/bundle/resources/model_services/remote-delete/script @@ -1,3 +1,5 @@ +assert_dms_unsupported model_services + trace $CLI bundle deploy title "Delete the resource out of band" diff --git a/acceptance/bundle/resources/postgres_snapshot_schedules/basic/script b/acceptance/bundle/resources/postgres_snapshot_schedules/basic/script index 7f0fb2587c5..5fa36a6a12d 100644 --- a/acceptance/bundle/resources/postgres_snapshot_schedules/basic/script +++ b/acceptance/bundle/resources/postgres_snapshot_schedules/basic/script @@ -8,6 +8,8 @@ schedule_name="projects/test-pg-proj-${UNIQUE_NAME}/branches/production/snapshot title "Create with a snapshot schedule" envsubst < databricks.yml.tmpl > databricks.yml + +assert_dms_unsupported postgres_snapshot_schedules rm -f "$OUT_REQUESTS" trace $CLI bundle deploy trace $CLI postgres get-snapshot-schedule "${schedule_name}" | snapshot_schedule_fields diff --git a/acceptance/bundle/resources/postgres_snapshot_schedules/out-of-band/script b/acceptance/bundle/resources/postgres_snapshot_schedules/out-of-band/script index 563f339418a..00eb1115c3d 100644 --- a/acceptance/bundle/resources/postgres_snapshot_schedules/out-of-band/script +++ b/acceptance/bundle/resources/postgres_snapshot_schedules/out-of-band/script @@ -7,6 +7,8 @@ schedule_name="projects/test-pg-proj-${UNIQUE_NAME}/branches/production/snapshot title "Deploy with a snapshot schedule" envsubst < databricks.yml.tmpl > databricks.yml + +assert_dms_unsupported postgres_snapshot_schedules trace $CLI bundle deploy trace $CLI postgres get-snapshot-schedule "${schedule_name}" | snapshot_schedule_fields diff --git a/acceptance/script.prepare b/acceptance/script.prepare index 66080eb1fcb..d0d889fd06f 100644 --- a/acceptance/script.prepare +++ b/acceptance/script.prepare @@ -115,6 +115,24 @@ add_repl() { env -u MSYS_NO_PATHCONV add_repl.py "$@" } +# DMS has no resource enum for these types. Assert the rejection, then exercise +# their lifecycle with file-backed state after removing the failed deployment. +assert_dms_unsupported() { + local resource_type="$1" + if [[ "$DMS" != "true" ]]; then + return + fi + + # Keep these logs outside the bundle so they do not enter sync or snapshots. + local log_dir="$(dirname "$OUT_REQUESTS")" + musterr $CLI bundle deploy &> "$log_dir/LOG.dms_unsupported" + contains.py "operations.resource_key must have a known resource type prefix" "$resource_type." '!panic:' '!internal error' < "$log_dir/LOG.dms_unsupported" > /dev/null + $CLI bundle destroy --auto-approve &> "$log_dir/LOG.dms_unsupported_cleanup" + rm -rf .databricks + rm -f "$OUT_REQUESTS" + export DATABRICKS_BUNDLE_DEPLOYMENT_HISTORY=false +} + nostamp() { # Same MSYS_NO_PATHCONV workaround as envsubst above: otherwise Python cannot # find nostamp.py on Windows. From 17acacb86b8c374486d865515d3cc898f1a7d1e1 Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Wed, 14 Oct 2026 11:57:59 +0000 Subject: [PATCH 04/10] Cover DMS rejection for immutable development deployments --- acceptance/bundle/deploy/immutable-dev-mode/script | 3 +++ acceptance/script.prepare | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/acceptance/bundle/deploy/immutable-dev-mode/script b/acceptance/bundle/deploy/immutable-dev-mode/script index 31c0bdbb415..f7a04d0ec75 100644 --- a/acceptance/bundle/deploy/immutable-dev-mode/script +++ b/acceptance/bundle/deploy/immutable-dev-mode/script @@ -1,4 +1,7 @@ envsubst < databricks.yml.tmpl > databricks.yml + +assert_dms_unsupported internal_immutable_snapshots -t dev + cleanup() { trace $CLI bundle destroy -t dev --auto-approve } diff --git a/acceptance/script.prepare b/acceptance/script.prepare index d0d889fd06f..51f174d02ff 100644 --- a/acceptance/script.prepare +++ b/acceptance/script.prepare @@ -119,15 +119,16 @@ add_repl() { # their lifecycle with file-backed state after removing the failed deployment. assert_dms_unsupported() { local resource_type="$1" + shift if [[ "$DMS" != "true" ]]; then return fi # Keep these logs outside the bundle so they do not enter sync or snapshots. local log_dir="$(dirname "$OUT_REQUESTS")" - musterr $CLI bundle deploy &> "$log_dir/LOG.dms_unsupported" + musterr $CLI bundle deploy "$@" &> "$log_dir/LOG.dms_unsupported" contains.py "operations.resource_key must have a known resource type prefix" "$resource_type." '!panic:' '!internal error' < "$log_dir/LOG.dms_unsupported" > /dev/null - $CLI bundle destroy --auto-approve &> "$log_dir/LOG.dms_unsupported_cleanup" + $CLI bundle destroy "$@" --auto-approve &> "$log_dir/LOG.dms_unsupported_cleanup" rm -rf .databricks rm -f "$OUT_REQUESTS" export DATABRICKS_BUNDLE_DEPLOYMENT_HISTORY=false From 83f96145ba33289a185a297678d250182b008caf Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Wed, 14 Oct 2026 12:49:41 +0000 Subject: [PATCH 05/10] Keep DMS test-server rejection assertions local --- acceptance/script.prepare | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/acceptance/script.prepare b/acceptance/script.prepare index 51f174d02ff..b3ab41349ca 100644 --- a/acceptance/script.prepare +++ b/acceptance/script.prepare @@ -115,8 +115,8 @@ add_repl() { env -u MSYS_NO_PATHCONV add_repl.py "$@" } -# DMS has no resource enum for these types. Assert the rejection, then exercise -# their lifecycle with file-backed state after removing the failed deployment. +# Assert the test server's unsupported-type rejection locally. Cloud runs +# exercise these resource lifecycles with file-backed state. assert_dms_unsupported() { local resource_type="$1" shift @@ -124,13 +124,15 @@ assert_dms_unsupported() { return fi - # Keep these logs outside the bundle so they do not enter sync or snapshots. - local log_dir="$(dirname "$OUT_REQUESTS")" - musterr $CLI bundle deploy "$@" &> "$log_dir/LOG.dms_unsupported" - contains.py "operations.resource_key must have a known resource type prefix" "$resource_type." '!panic:' '!internal error' < "$log_dir/LOG.dms_unsupported" > /dev/null - $CLI bundle destroy "$@" --auto-approve &> "$log_dir/LOG.dms_unsupported_cleanup" - rm -rf .databricks - rm -f "$OUT_REQUESTS" + if [[ -z "$CLOUD_ENV" ]]; then + # Keep these logs outside the bundle so they do not enter sync or snapshots. + local log_dir="$(dirname "$OUT_REQUESTS")" + musterr $CLI bundle deploy "$@" &> "$log_dir/LOG.dms_unsupported" + contains.py "operations.resource_key must have a known resource type prefix" "$resource_type." '!panic:' '!internal error' < "$log_dir/LOG.dms_unsupported" > /dev/null + $CLI bundle destroy "$@" --auto-approve &> "$log_dir/LOG.dms_unsupported_cleanup" + rm -rf .databricks + rm -f "$OUT_REQUESTS" + fi export DATABRICKS_BUNDLE_DEPLOYMENT_HISTORY=false } From 67fff130a22c61d58b0cc5ab6f4beaf9e2722b7c Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Thu, 15 Oct 2026 10:03:40 +0000 Subject: [PATCH 06/10] Allow immutable snapshots in the DMS test server --- .../bundle/deploy/immutable-dev-mode/script | 3 --- .../deploy/immutable-no-artifacts/script | 2 -- .../immutable-permissions-change/script | 2 -- acceptance/bundle/deploy/immutable/script | 2 -- .../bundle/dms/immutable-folder/output.txt | 27 ++++++++++++------- acceptance/bundle/dms/immutable-folder/script | 8 +++--- .../bundle/resources/apps/immutable/script | 2 -- libs/testserver/bundledeployments.go | 1 + 8 files changed, 21 insertions(+), 26 deletions(-) diff --git a/acceptance/bundle/deploy/immutable-dev-mode/script b/acceptance/bundle/deploy/immutable-dev-mode/script index f7a04d0ec75..31c0bdbb415 100644 --- a/acceptance/bundle/deploy/immutable-dev-mode/script +++ b/acceptance/bundle/deploy/immutable-dev-mode/script @@ -1,7 +1,4 @@ envsubst < databricks.yml.tmpl > databricks.yml - -assert_dms_unsupported internal_immutable_snapshots -t dev - cleanup() { trace $CLI bundle destroy -t dev --auto-approve } diff --git a/acceptance/bundle/deploy/immutable-no-artifacts/script b/acceptance/bundle/deploy/immutable-no-artifacts/script index 8a41c1493eb..4bf3fddd7a6 100644 --- a/acceptance/bundle/deploy/immutable-no-artifacts/script +++ b/acceptance/bundle/deploy/immutable-no-artifacts/script @@ -1,7 +1,5 @@ envsubst < databricks.yml.tmpl > databricks.yml -assert_dms_unsupported internal_immutable_snapshots - trace $CLI bundle validate trace $CLI bundle plan -o json > plan.json trace jq '.plan["resources.jobs.my_job"].new_state.value.tasks' plan.json diff --git a/acceptance/bundle/deploy/immutable-permissions-change/script b/acceptance/bundle/deploy/immutable-permissions-change/script index 4c9acc92719..458bfdd2c85 100644 --- a/acceptance/bundle/deploy/immutable-permissions-change/script +++ b/acceptance/bundle/deploy/immutable-permissions-change/script @@ -1,7 +1,5 @@ envsubst < databricks.yml.tmpl > databricks.yml -assert_dms_unsupported internal_immutable_snapshots - cleanup() { trace $CLI bundle destroy --auto-approve } diff --git a/acceptance/bundle/deploy/immutable/script b/acceptance/bundle/deploy/immutable/script index 8bc130b1ad4..5babe793a9a 100644 --- a/acceptance/bundle/deploy/immutable/script +++ b/acceptance/bundle/deploy/immutable/script @@ -1,6 +1,4 @@ envsubst < databricks.yml.tmpl > databricks.yml - -assert_dms_unsupported internal_immutable_snapshots cleanup() { trace $CLI bundle destroy --auto-approve } diff --git a/acceptance/bundle/dms/immutable-folder/output.txt b/acceptance/bundle/dms/immutable-folder/output.txt index 925e01b3fe6..a45aa8ba189 100644 --- a/acceptance/bundle/dms/immutable-folder/output.txt +++ b/acceptance/bundle/dms/immutable-folder/output.txt @@ -1,36 +1,43 @@ -=== DMS records the requested snapshot path but rejects unsupported immutable snapshots -DMS rejected unsupported immutable snapshots +=== Deploying with an immutable folder records the resolved snapshot path as the deployment's file_path +>>> [CLI] bundle deploy +Created internal_immutable_snapshots.immutable +Created jobs.foo +Files: 0 uploaded, 0 deleted +Resources: 2 created, 0 changed, 0 deleted, 0 unchanged >>> MSYS_NO_PATHCONV=1 [CLI] api get /api/2.0/bundle/deployments/[DEPLOYMENT_ID] { "workspace_info": { "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-immutable-folder-[UNIQUE_NAME]/default", "file_path": "/Workspace/Users/[UUID]/.snapshots/[SNAPSHOT_HASH]/[SNAPSHOT_HASH]/files" - }, - "last_version_id": "" + } } === A new snapshot moves file_path, which is then updated on the deployment -DMS rejected unsupported immutable snapshots +>>> [CLI] bundle deploy +Recreated internal_immutable_snapshots.immutable +Updated jobs.foo +Files: 0 uploaded, 0 deleted +Resources: 1 created, 1 changed, 1 deleted, 0 unchanged >>> MSYS_NO_PATHCONV=1 [CLI] api get /api/2.0/bundle/deployments/[DEPLOYMENT_ID] { "workspace_info": { "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-immutable-folder-[UNIQUE_NAME]/default", "file_path": "/Workspace/Users/[UUID]/.snapshots/[SNAPSHOT_HASH]/[SNAPSHOT_HASH]/files" - }, - "last_version_id": "" + } } === An unchanged snapshot keeps the recorded file_path -DMS rejected unsupported immutable snapshots +>>> [CLI] bundle deploy +Files: 0 uploaded, 0 deleted +Resources: 0 created, 0 changed, 0 deleted, 2 unchanged >>> MSYS_NO_PATHCONV=1 [CLI] api get /api/2.0/bundle/deployments/[DEPLOYMENT_ID] { "workspace_info": { "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-immutable-folder-[UNIQUE_NAME]/default", "file_path": "/Workspace/Users/[UUID]/.snapshots/[SNAPSHOT_HASH]/[SNAPSHOT_HASH]/files" - }, - "last_version_id": "" + } } diff --git a/acceptance/bundle/dms/immutable-folder/script b/acceptance/bundle/dms/immutable-folder/script index 35b5ed553cd..ff70d11a08f 100644 --- a/acceptance/bundle/dms/immutable-folder/script +++ b/acceptance/bundle/dms/immutable-folder/script @@ -4,19 +4,17 @@ deployment_workspace_info() { deployment_id=$(MSYS_NO_PATHCONV=1 $CLI workspace get-status "/Workspace/Users/${CURRENT_USER_NAME}/.bundle/dms-immutable-folder-${UNIQUE_NAME}/default/state/resources.deployment.json" -o json | python3 -c 'import sys,json; print(json.load(sys.stdin)["object_id"])') add_repl "$deployment_id" DEPLOYMENT_ID # MSYS_NO_PATHCONV: Git Bash on Windows would rewrite the leading-'/' API path. - trace MSYS_NO_PATHCONV=1 $CLI api get "/api/2.0/bundle/deployments/${deployment_id}" | jq '{workspace_info, last_version_id: (.last_version_id // "")}' + trace MSYS_NO_PATHCONV=1 $CLI api get "/api/2.0/bundle/deployments/${deployment_id}" | jq '{workspace_info}' } deploy() { mkdir -p .databricks $CLI bundle plan -o json > .databricks/plan.json - trace musterr $CLI bundle deploy $(readplanarg .databricks/plan.json) &> "$(dirname "$OUT_REQUESTS")/LOG.deploy" - contains.py "operations.resource_key must have a known resource type prefix" "internal_immutable_snapshots.immutable" < "$(dirname "$OUT_REQUESTS")/LOG.deploy" > /dev/null - printf '\nDMS rejected unsupported immutable snapshots\n' + trace $CLI bundle deploy $(readplanarg .databricks/plan.json) rm .databricks/plan.json } -title "DMS records the requested snapshot path but rejects unsupported immutable snapshots" +title "Deploying with an immutable folder records the resolved snapshot path as the deployment's file_path" deploy deployment_workspace_info diff --git a/acceptance/bundle/resources/apps/immutable/script b/acceptance/bundle/resources/apps/immutable/script index b16d68c98a7..a64a9bdaf16 100644 --- a/acceptance/bundle/resources/apps/immutable/script +++ b/acceptance/bundle/resources/apps/immutable/script @@ -1,7 +1,5 @@ envsubst < databricks.yml.tmpl > databricks.yml -assert_dms_unsupported internal_immutable_snapshots - cleanup() { rm -f "$OUT_REQUESTS" } diff --git a/libs/testserver/bundledeployments.go b/libs/testserver/bundledeployments.go index caaeaada39f..c03e84ebef0 100644 --- a/libs/testserver/bundledeployments.go +++ b/libs/testserver/bundledeployments.go @@ -50,6 +50,7 @@ var dmsResourceTypes = []string{ "external_locations", "genie_spaces", "instance_pools", + "internal_immutable_snapshots", "job_runs", "jobs", "model_serving_endpoints", From 97545a47135fb30d61c0f35ee295c9ce9ca32814 Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Thu, 15 Oct 2026 11:11:25 +0000 Subject: [PATCH 07/10] Keep DMS resource validation changes scoped to the test server --- acceptance/bundle/invariant/no_drift/script | 4 ---- .../resources/grants/mcp_services/script | 2 -- .../grants/model_provider_services/script | 2 -- .../resources/grants/model_services/script | 2 -- .../resources/mcp_services/basic/script | 2 -- .../resources/mcp_services/lifecycle/script | 2 -- .../mcp_services/remote-delete/script | 2 -- .../model_provider_services/basic/script | 2 -- .../model_provider_services/lifecycle/script | 2 -- .../remote-delete/script | 2 -- .../resources/model_services/basic/script | 2 -- .../resources/model_services/lifecycle/script | 2 -- .../model_services/remote-delete/script | 2 -- .../postgres_snapshot_schedules/basic/script | 2 -- .../out-of-band/script | 2 -- acceptance/script.prepare | 21 ------------------- libs/testserver/bundledeployments.go | 8 ++++++- 17 files changed, 7 insertions(+), 54 deletions(-) diff --git a/acceptance/bundle/invariant/no_drift/script b/acceptance/bundle/invariant/no_drift/script index 89a5edc9ef0..0961e8edac8 100644 --- a/acceptance/bundle/invariant/no_drift/script +++ b/acceptance/bundle/invariant/no_drift/script @@ -3,10 +3,6 @@ invariant_setup -if [[ "$INPUT_CONFIG" == "model_service.yml.tmpl" ]]; then - assert_dms_unsupported model_services -fi - # Only compute a plan up front when the READPLAN variant actually consumes it via --plan. # Without READPLAN, deploy computes its own plan internally, so a separate `bundle plan` # invocation is pure waste. diff --git a/acceptance/bundle/resources/grants/mcp_services/script b/acceptance/bundle/resources/grants/mcp_services/script index e666dcec582..eafb6a07c58 100644 --- a/acceptance/bundle/resources/grants/mcp_services/script +++ b/acceptance/bundle/resources/grants/mcp_services/script @@ -1,7 +1,5 @@ envsubst < databricks.yml.tmpl > databricks.yml -assert_dms_unsupported mcp_services - trace $CLI bundle plan -o json | jq 'del(.features)' > out.plan1.json trace print_requests.py --get //permissions trace $CLI bundle deploy diff --git a/acceptance/bundle/resources/grants/model_provider_services/script b/acceptance/bundle/resources/grants/model_provider_services/script index 32093ca1768..7c9f39f37db 100644 --- a/acceptance/bundle/resources/grants/model_provider_services/script +++ b/acceptance/bundle/resources/grants/model_provider_services/script @@ -1,7 +1,5 @@ envsubst < databricks.yml.tmpl > databricks.yml -assert_dms_unsupported model_provider_services - trace $CLI bundle plan -o json | jq 'del(.features)' > out.plan1.json trace print_requests.py --get //permissions trace $CLI bundle deploy diff --git a/acceptance/bundle/resources/grants/model_services/script b/acceptance/bundle/resources/grants/model_services/script index c95f429dd66..60f6d70750c 100644 --- a/acceptance/bundle/resources/grants/model_services/script +++ b/acceptance/bundle/resources/grants/model_services/script @@ -1,7 +1,5 @@ envsubst < databricks.yml.tmpl > databricks.yml -assert_dms_unsupported model_services - trace $CLI bundle plan -o json | jq 'del(.features)' > out.plan1.json trace print_requests.py --get //permissions trace $CLI bundle deploy diff --git a/acceptance/bundle/resources/mcp_services/basic/script b/acceptance/bundle/resources/mcp_services/basic/script index f56bcaab263..eedd128b1e6 100644 --- a/acceptance/bundle/resources/mcp_services/basic/script +++ b/acceptance/bundle/resources/mcp_services/basic/script @@ -1,5 +1,3 @@ -assert_dms_unsupported mcp_services - title "Initial summary before deploy" trace $CLI bundle summary -o json | jq .resources.mcp_services.mcp1 diff --git a/acceptance/bundle/resources/mcp_services/lifecycle/script b/acceptance/bundle/resources/mcp_services/lifecycle/script index 18964e3c728..6e9514f3a38 100644 --- a/acceptance/bundle/resources/mcp_services/lifecycle/script +++ b/acceptance/bundle/resources/mcp_services/lifecycle/script @@ -1,7 +1,5 @@ envsubst < databricks.yml.tmpl > databricks.yml -assert_dms_unsupported mcp_services - CONN="mcp_conn_$UNIQUE_NAME" cleanup() { diff --git a/acceptance/bundle/resources/mcp_services/remote-delete/script b/acceptance/bundle/resources/mcp_services/remote-delete/script index c5ac658b246..413e6174fd4 100644 --- a/acceptance/bundle/resources/mcp_services/remote-delete/script +++ b/acceptance/bundle/resources/mcp_services/remote-delete/script @@ -1,5 +1,3 @@ -assert_dms_unsupported mcp_services - trace $CLI bundle deploy title "Delete the resource out of band" diff --git a/acceptance/bundle/resources/model_provider_services/basic/script b/acceptance/bundle/resources/model_provider_services/basic/script index f486db2103c..f12527b141d 100644 --- a/acceptance/bundle/resources/model_provider_services/basic/script +++ b/acceptance/bundle/resources/model_provider_services/basic/script @@ -1,5 +1,3 @@ -assert_dms_unsupported model_provider_services - title "Initial summary before deploy" trace $CLI bundle summary -o json | jq .resources.model_provider_services.mps1 diff --git a/acceptance/bundle/resources/model_provider_services/lifecycle/script b/acceptance/bundle/resources/model_provider_services/lifecycle/script index 4e45d3ab13b..634183f4759 100644 --- a/acceptance/bundle/resources/model_provider_services/lifecycle/script +++ b/acceptance/bundle/resources/model_provider_services/lifecycle/script @@ -1,7 +1,5 @@ envsubst < databricks.yml.tmpl > databricks.yml -assert_dms_unsupported model_provider_services - cleanup() { trace $CLI bundle destroy --auto-approve } diff --git a/acceptance/bundle/resources/model_provider_services/remote-delete/script b/acceptance/bundle/resources/model_provider_services/remote-delete/script index 2640b843e7f..e7377733cc6 100644 --- a/acceptance/bundle/resources/model_provider_services/remote-delete/script +++ b/acceptance/bundle/resources/model_provider_services/remote-delete/script @@ -1,5 +1,3 @@ -assert_dms_unsupported model_provider_services - trace $CLI bundle deploy title "Delete the resource out of band" diff --git a/acceptance/bundle/resources/model_services/basic/script b/acceptance/bundle/resources/model_services/basic/script index 77a9cd4d97a..f52a481086a 100644 --- a/acceptance/bundle/resources/model_services/basic/script +++ b/acceptance/bundle/resources/model_services/basic/script @@ -1,5 +1,3 @@ -assert_dms_unsupported model_services - title "Initial summary before deploy" trace $CLI bundle summary -o json | jq .resources.model_services.ms1 diff --git a/acceptance/bundle/resources/model_services/lifecycle/script b/acceptance/bundle/resources/model_services/lifecycle/script index da56d001af8..ed9c256d01c 100644 --- a/acceptance/bundle/resources/model_services/lifecycle/script +++ b/acceptance/bundle/resources/model_services/lifecycle/script @@ -1,7 +1,5 @@ envsubst < databricks.yml.tmpl > databricks.yml -assert_dms_unsupported model_services - cleanup() { trace $CLI bundle destroy --auto-approve } diff --git a/acceptance/bundle/resources/model_services/remote-delete/script b/acceptance/bundle/resources/model_services/remote-delete/script index e6a4e7e3af8..ad9170ef687 100644 --- a/acceptance/bundle/resources/model_services/remote-delete/script +++ b/acceptance/bundle/resources/model_services/remote-delete/script @@ -1,5 +1,3 @@ -assert_dms_unsupported model_services - trace $CLI bundle deploy title "Delete the resource out of band" diff --git a/acceptance/bundle/resources/postgres_snapshot_schedules/basic/script b/acceptance/bundle/resources/postgres_snapshot_schedules/basic/script index 5fa36a6a12d..7f0fb2587c5 100644 --- a/acceptance/bundle/resources/postgres_snapshot_schedules/basic/script +++ b/acceptance/bundle/resources/postgres_snapshot_schedules/basic/script @@ -8,8 +8,6 @@ schedule_name="projects/test-pg-proj-${UNIQUE_NAME}/branches/production/snapshot title "Create with a snapshot schedule" envsubst < databricks.yml.tmpl > databricks.yml - -assert_dms_unsupported postgres_snapshot_schedules rm -f "$OUT_REQUESTS" trace $CLI bundle deploy trace $CLI postgres get-snapshot-schedule "${schedule_name}" | snapshot_schedule_fields diff --git a/acceptance/bundle/resources/postgres_snapshot_schedules/out-of-band/script b/acceptance/bundle/resources/postgres_snapshot_schedules/out-of-band/script index 00eb1115c3d..563f339418a 100644 --- a/acceptance/bundle/resources/postgres_snapshot_schedules/out-of-band/script +++ b/acceptance/bundle/resources/postgres_snapshot_schedules/out-of-band/script @@ -7,8 +7,6 @@ schedule_name="projects/test-pg-proj-${UNIQUE_NAME}/branches/production/snapshot title "Deploy with a snapshot schedule" envsubst < databricks.yml.tmpl > databricks.yml - -assert_dms_unsupported postgres_snapshot_schedules trace $CLI bundle deploy trace $CLI postgres get-snapshot-schedule "${schedule_name}" | snapshot_schedule_fields diff --git a/acceptance/script.prepare b/acceptance/script.prepare index b3ab41349ca..66080eb1fcb 100644 --- a/acceptance/script.prepare +++ b/acceptance/script.prepare @@ -115,27 +115,6 @@ add_repl() { env -u MSYS_NO_PATHCONV add_repl.py "$@" } -# Assert the test server's unsupported-type rejection locally. Cloud runs -# exercise these resource lifecycles with file-backed state. -assert_dms_unsupported() { - local resource_type="$1" - shift - if [[ "$DMS" != "true" ]]; then - return - fi - - if [[ -z "$CLOUD_ENV" ]]; then - # Keep these logs outside the bundle so they do not enter sync or snapshots. - local log_dir="$(dirname "$OUT_REQUESTS")" - musterr $CLI bundle deploy "$@" &> "$log_dir/LOG.dms_unsupported" - contains.py "operations.resource_key must have a known resource type prefix" "$resource_type." '!panic:' '!internal error' < "$log_dir/LOG.dms_unsupported" > /dev/null - $CLI bundle destroy "$@" --auto-approve &> "$log_dir/LOG.dms_unsupported_cleanup" - rm -rf .databricks - rm -f "$OUT_REQUESTS" - fi - export DATABRICKS_BUNDLE_DEPLOYMENT_HISTORY=false -} - nostamp() { # Same MSYS_NO_PATHCONV workaround as envsubst above: otherwise Python cannot # find nostamp.py on Windows. diff --git a/libs/testserver/bundledeployments.go b/libs/testserver/bundledeployments.go index c03e84ebef0..d2435f838cc 100644 --- a/libs/testserver/bundledeployments.go +++ b/libs/testserver/bundledeployments.go @@ -34,9 +34,11 @@ const dmsDeploymentNodeName = "resources.deployment.json" // created. var dmsUpdatableOperationFields = []string{"state", "error_message", "resource_id", "status"} -// dmsResourceTypes mirrors the resource_key prefixes in Universe's bundle/metadata-service. +// dmsResourceTypes lists the resource_key prefixes accepted by DMS. // NOTE: When adding a type here, also add the corresponding enum in bundle/metadata-service/service.proto // and prefix mapping in parser/ResourceTypes.java in Universe. +// TODO: Add internal_immutable_snapshots, mcp_services, model_services, +// model_provider_services, and postgres_snapshot_schedules to the Universe enum and prefix mapping. var dmsResourceTypes = []string{ "alerts", "apps", @@ -53,6 +55,9 @@ var dmsResourceTypes = []string{ "internal_immutable_snapshots", "job_runs", "jobs", + "mcp_services", + "model_provider_services", + "model_services", "model_serving_endpoints", "models", "pipelines", @@ -62,6 +67,7 @@ var dmsResourceTypes = []string{ "postgres_endpoints", "postgres_projects", "postgres_roles", + "postgres_snapshot_schedules", "postgres_synced_tables", "quality_monitors", "registered_models", From 1c1048ea22cda447cb2544499e617e1100c518eb Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Mon, 19 Oct 2026 14:40:04 +0000 Subject: [PATCH 08/10] Track the remaining Universe resource enum addition --- libs/testserver/bundledeployments.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/testserver/bundledeployments.go b/libs/testserver/bundledeployments.go index d2435f838cc..cf32869813f 100644 --- a/libs/testserver/bundledeployments.go +++ b/libs/testserver/bundledeployments.go @@ -37,8 +37,7 @@ var dmsUpdatableOperationFields = []string{"state", "error_message", "resource_i // dmsResourceTypes lists the resource_key prefixes accepted by DMS. // NOTE: When adding a type here, also add the corresponding enum in bundle/metadata-service/service.proto // and prefix mapping in parser/ResourceTypes.java in Universe. -// TODO: Add internal_immutable_snapshots, mcp_services, model_services, -// model_provider_services, and postgres_snapshot_schedules to the Universe enum and prefix mapping. +// TODO: Add internal_immutable_snapshots to Universe (databricks-eng/universe#2810194). var dmsResourceTypes = []string{ "alerts", "apps", From 7c21b104980feb0a6c65a21a6dd8fa6dc82e296f Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Mon, 19 Oct 2026 14:52:04 +0000 Subject: [PATCH 09/10] Align the test-server allow list with current Universe resource types --- libs/testserver/bundledeployments.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/testserver/bundledeployments.go b/libs/testserver/bundledeployments.go index cf32869813f..06604a48a46 100644 --- a/libs/testserver/bundledeployments.go +++ b/libs/testserver/bundledeployments.go @@ -39,6 +39,7 @@ var dmsUpdatableOperationFields = []string{"state", "error_message", "resource_i // and prefix mapping in parser/ResourceTypes.java in Universe. // TODO: Add internal_immutable_snapshots to Universe (databricks-eng/universe#2810194). var dmsResourceTypes = []string{ + "agent_services", "alerts", "apps", "catalogs", @@ -51,6 +52,7 @@ var dmsResourceTypes = []string{ "external_locations", "genie_spaces", "instance_pools", + "internal_immutable_folders", "internal_immutable_snapshots", "job_runs", "jobs", From 27af3725bedbfbb677352b97006de81e763d3795 Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Mon, 19 Oct 2026 14:58:55 +0000 Subject: [PATCH 10/10] Remove the resolved Universe resource-type TODO --- libs/testserver/bundledeployments.go | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/testserver/bundledeployments.go b/libs/testserver/bundledeployments.go index 06604a48a46..353da95325f 100644 --- a/libs/testserver/bundledeployments.go +++ b/libs/testserver/bundledeployments.go @@ -37,7 +37,6 @@ var dmsUpdatableOperationFields = []string{"state", "error_message", "resource_i // dmsResourceTypes lists the resource_key prefixes accepted by DMS. // NOTE: When adding a type here, also add the corresponding enum in bundle/metadata-service/service.proto // and prefix mapping in parser/ResourceTypes.java in Universe. -// TODO: Add internal_immutable_snapshots to Universe (databricks-eng/universe#2810194). var dmsResourceTypes = []string{ "agent_services", "alerts",