From c1d4050f3b3a7601f315dd6e28aea7922a5f44e0 Mon Sep 17 00:00:00 2001 From: Leon Li Date: Wed, 10 Dec 2025 17:43:12 -0800 Subject: [PATCH 01/10] [DASH] Enable dashboard dataset_catalog/schema in direct deployment mode --- .../databricks.yml.tmpl | 17 ++++++++++ .../out.plan.direct.json | 9 +++++ .../out.post.requests.txt | 14 ++++++++ .../dataset-catalog-schema/out.test.toml | 7 ++++ .../dataset-catalog-schema/output.txt | 25 ++++++++++++++ .../sample-dashboard.lvdash.json | 1 + .../dashboards/dataset-catalog-schema/script | 34 +++++++++++++++++++ .../dataset-catalog-schema/test.toml | 11 ++++++ bundle/config/resources/dashboard.go | 8 +++++ bundle/config/resources/dashboard_test.go | 23 +++++++++++++ bundle/direct/dresources/dashboard.go | 34 ++++++++++--------- 11 files changed, 167 insertions(+), 16 deletions(-) create mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/databricks.yml.tmpl create mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json create mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.txt create mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml create mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt create mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/sample-dashboard.lvdash.json create mode 100755 acceptance/bundle/resources/dashboards/dataset-catalog-schema/script create mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/databricks.yml.tmpl b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/databricks.yml.tmpl new file mode 100644 index 0000000000..41f30b1f81 --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/databricks.yml.tmpl @@ -0,0 +1,17 @@ +# +# Acceptance test for deploying dashboards with dataset_catalog and dataset_schema. +# These fields override the catalog/schema for all datasets in the dashboard. +# +bundle: + name: deploy-dashboard-dataset-test-$UNIQUE_NAME + +resources: + dashboards: + dashboard1: + display_name: $DASHBOARD_DISPLAY_NAME + warehouse_id: $TEST_DEFAULT_WAREHOUSE_ID + embed_credentials: true + dataset_catalog: main + dataset_schema: default + file_path: "sample-dashboard.lvdash.json" + parent_path: /Users/$CURRENT_USER_NAME diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json new file mode 100644 index 0000000000..e5a9addaaa --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json @@ -0,0 +1,9 @@ +{ + "all_resources": [ + { + "resource_type": "databricks_dashboard", + "resource_key": "dashboard1", + "action": "noop" + } + ] +} diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.txt b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.txt new file mode 100644 index 0000000000..ff438733b9 --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.txt @@ -0,0 +1,14 @@ +{ + "method": "POST", + "path": "/api/2.0/lakeview/dashboards", + "body": { + "dashboard": { + "display_name": "test bundle-deploy-dashboard-dataset [UUID]", + "parent_path": "/Users/[USERNAME]", + "serialized_dashboard": "{\"pages\":[{\"name\":\"test_page\",\"displayName\":\"Test Page\"}]}\n", + "warehouse_id": "[TEST_DEFAULT_WAREHOUSE_ID]" + }, + "dataset_catalog": "main", + "dataset_schema": "default" + } +} diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml new file mode 100644 index 0000000000..264ca54272 --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml @@ -0,0 +1,7 @@ +Local = true +Cloud = true +RequiresWarehouse = true +RecordRequests = true + +[EnvMatrix] + DATABRICKS_BUNDLE_ENGINE = ["direct"] diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt new file mode 100644 index 0000000000..8850e89daf --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt @@ -0,0 +1,25 @@ + +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/deploy-dashboard-dataset-test-[UNIQUE_NAME]/default/files... +Deploying resources... +Updating deployment state... +Deployment complete! + +>>> [CLI] lakeview get [DASHBOARD_ID] +{ + "lifecycle_state": "ACTIVE", + "parent_path": "/Users/[USERNAME]", + "path": "/Users/[USERNAME]/test bundle-deploy-dashboard-dataset [UUID].lvdash.json", + "serialized_dashboard": "{\"pages\":[{\"name\":\"test_page\",\"displayName\":\"Test Page\"}]}\n" +} + +>>> [CLI] bundle plan -o json + +>>> [CLI] bundle destroy --auto-approve +The following resources will be deleted: + delete resources.dashboards.dashboard1 + +All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/deploy-dashboard-dataset-test-[UNIQUE_NAME]/default + +Deleting files... +Destroy complete! diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/sample-dashboard.lvdash.json b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/sample-dashboard.lvdash.json new file mode 100644 index 0000000000..43eb82879c --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/sample-dashboard.lvdash.json @@ -0,0 +1 @@ +{"pages":[{"name":"test_page","displayName":"Test Page"}]} diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script new file mode 100755 index 0000000000..656861aad9 --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script @@ -0,0 +1,34 @@ +#!/bin/bash +DASHBOARD_DISPLAY_NAME="test bundle-deploy-dashboard-dataset $(uuid)" +if [ -z "$CLOUD_ENV" ]; then + export TEST_DEFAULT_WAREHOUSE_ID="warehouse-1234" + echo "warehouse-1234:TEST_DEFAULT_WAREHOUSE_ID" >> ACC_REPLS +fi + +export DASHBOARD_DISPLAY_NAME +envsubst < databricks.yml.tmpl > databricks.yml + +cleanup() { + trace $CLI bundle destroy --auto-approve + rm -f out.requests.txt +} +trap cleanup EXIT + +trace $CLI bundle deploy +DASHBOARD_ID=$($CLI bundle summary --output json | jq -r '.resources.dashboards.dashboard1.id') + +# Capture the dashboard ID as a replacement. +echo "$DASHBOARD_ID:DASHBOARD_ID" >> ACC_REPLS + +trace $CLI lakeview get $DASHBOARD_ID | jq '{lifecycle_state, parent_path, path, serialized_dashboard}' + +# Verify that there is no drift right after deploy. +trace $CLI bundle plan -o json > out.plan.$DATABRICKS_BUNDLE_ENGINE.json + +# Print API requests made to create the dashboard. +# This verifies that dataset_catalog and dataset_schema are passed to the API. +cat out.requests.txt | \ + jq 'select(.method == "POST")' | \ + jq 'select(.path | contains("/api/2.0/lakeview/dashboards"))' | \ + jq 'select(.path | contains("/published") | not)' \ + > out.post.requests.txt diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml new file mode 100644 index 0000000000..038e128d10 --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml @@ -0,0 +1,11 @@ +Local = true +Cloud = true +RequiresWarehouse = true +RecordRequests = true + +[EnvMatrix] + DATABRICKS_BUNDLE_ENGINE = ["direct"] + +Ignore = [ + "databricks.yml", +] diff --git a/bundle/config/resources/dashboard.go b/bundle/config/resources/dashboard.go index e58039bdfa..a2c6e04118 100644 --- a/bundle/config/resources/dashboard.go +++ b/bundle/config/resources/dashboard.go @@ -56,6 +56,14 @@ type DashboardConfig struct { // // Defaults to false if not set. EmbedCredentials bool `json:"embed_credentials,omitempty"` + + // DatasetCatalog sets the default catalog for all datasets in this dashboard. + // When set, this overrides the catalog specified in individual dataset definitions. + DatasetCatalog string `json:"dataset_catalog,omitempty"` + + // DatasetSchema sets the default schema for all datasets in this dashboard. + // When set, this overrides the schema specified in individual dataset definitions. + DatasetSchema string `json:"dataset_schema,omitempty"` } func (c *DashboardConfig) UnmarshalJSON(b []byte) error { diff --git a/bundle/config/resources/dashboard_test.go b/bundle/config/resources/dashboard_test.go index 11f8d1b8d8..435392873e 100644 --- a/bundle/config/resources/dashboard_test.go +++ b/bundle/config/resources/dashboard_test.go @@ -1,6 +1,7 @@ package resources import ( + "encoding/json" "reflect" "testing" @@ -59,3 +60,25 @@ func TestDashboardConfigIsSupersetOfSDKDashboard(t *testing.T) { } } } + +func TestDashboardConfigWithDatasetCatalogSchema(t *testing.T) { + jsonConfig := `{ + "display_name": "Test Dashboard", + "warehouse_id": "test_warehouse_id", + "dataset_catalog": "main", + "dataset_schema": "default", + "embed_credentials": true, + "serialized_dashboard": "{\"key\": \"value\"}" + }` + + var config DashboardConfig + err := json.Unmarshal([]byte(jsonConfig), &config) + assert.NoError(t, err) + + assert.Equal(t, "Test Dashboard", config.DisplayName) + assert.Equal(t, "test_warehouse_id", config.WarehouseId) + assert.Equal(t, "main", config.DatasetCatalog) + assert.Equal(t, "default", config.DatasetSchema) + assert.True(t, config.EmbedCredentials) + assert.Equal(t, `{"key": "value"}`, config.SerializedDashboard) +} diff --git a/bundle/direct/dresources/dashboard.go b/bundle/direct/dresources/dashboard.go index fb171876ec..baf0cb9f7a 100644 --- a/bundle/direct/dresources/dashboard.go +++ b/bundle/direct/dresources/dashboard.go @@ -53,6 +53,8 @@ func (r *ResourceDashboard) RemapState(state *resources.DashboardConfig) *resour "Path", "UpdateTime", "SerializedDashboard", + "DatasetCatalog", + "DatasetSchema", }...) // EmbedCredentials must always be included in ForceSendFields to ensure it's serialized @@ -68,6 +70,8 @@ func (r *ResourceDashboard) RemapState(state *resources.DashboardConfig) *resour WarehouseId: state.WarehouseId, SerializedDashboard: state.SerializedDashboard, EmbedCredentials: state.EmbedCredentials, + DatasetCatalog: state.DatasetCatalog, + DatasetSchema: state.DatasetSchema, ForceSendFields: forceSendFields, @@ -119,6 +123,8 @@ func (r *ResourceDashboard) DoRead(ctx context.Context, id string) (*resources.D WarehouseId: dashboard.WarehouseId, SerializedDashboard: dashboard.SerializedDashboard, ParentPath: ensureWorkspacePrefix(dashboard.ParentPath), + DatasetCatalog: "", + DatasetSchema: "", // Output only fields. CreateTime: dashboard.CreateTime, @@ -193,6 +199,8 @@ func responseToState(createOrUpdateResp *dashboards.Dashboard, publishResp *dash WarehouseId: createOrUpdateResp.WarehouseId, SerializedDashboard: serializedDashboard, ParentPath: ensureWorkspacePrefix(createOrUpdateResp.ParentPath), + DatasetCatalog: "", + DatasetSchema: "", // Output only fields CreateTime: createOrUpdateResp.CreateTime, @@ -213,11 +221,9 @@ func (r *ResourceDashboard) DoCreate(ctx context.Context, config *resources.Dash } createResp, err := r.client.Lakeview.Create(ctx, dashboards.CreateDashboardRequest{ - Dashboard: dashboard, - - // Note: these remain unset until there is a TF release with support for these fields. - DatasetCatalog: "", - DatasetSchema: "", + Dashboard: dashboard, + DatasetCatalog: config.DatasetCatalog, + DatasetSchema: config.DatasetSchema, ForceSendFields: nil, }) @@ -230,11 +236,9 @@ func (r *ResourceDashboard) DoCreate(ctx context.Context, config *resources.Dash return "", nil, fmt.Errorf("failed to create parent directory: %w", err) } createResp, err = r.client.Lakeview.Create(ctx, dashboards.CreateDashboardRequest{ - Dashboard: dashboard, - - // Note: these remain unset until there is a TF release with support for these fields. - DatasetCatalog: "", - DatasetSchema: "", + Dashboard: dashboard, + DatasetCatalog: config.DatasetCatalog, + DatasetSchema: config.DatasetSchema, ForceSendFields: nil, }) @@ -268,12 +272,10 @@ func (r *ResourceDashboard) DoUpdate(ctx context.Context, id string, config *res } updateResp, err := r.client.Lakeview.Update(ctx, dashboards.UpdateDashboardRequest{ - DashboardId: id, - Dashboard: dashboard, - - // Note: these remain unset until there is a TF release with support for these fields. - DatasetCatalog: "", - DatasetSchema: "", + DashboardId: id, + Dashboard: dashboard, + DatasetCatalog: config.DatasetCatalog, + DatasetSchema: config.DatasetSchema, ForceSendFields: nil, }) From c465f8942dc08c4b0f5261f79a10760f0c1a25ae Mon Sep 17 00:00:00 2001 From: Leon Li Date: Thu, 11 Dec 2025 11:26:43 -0800 Subject: [PATCH 02/10] respond to feedback + failing tests --- .../resources/dashboards/dataset-catalog-schema/test.toml | 1 + bundle/config/resources/dashboard.go | 2 ++ bundle/direct/dresources/dashboard.go | 1 + bundle/internal/schema/annotations.yml | 7 +++++++ bundle/schema/jsonschema.json | 6 ++++++ 5 files changed, 17 insertions(+) diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml index 038e128d10..154c7950d1 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml @@ -3,6 +3,7 @@ Cloud = true RequiresWarehouse = true RecordRequests = true +# TODO: test terraform once commit had been released (https://github.com/databricks/terraform-provider-databricks/pull/5259) [EnvMatrix] DATABRICKS_BUNDLE_ENGINE = ["direct"] diff --git a/bundle/config/resources/dashboard.go b/bundle/config/resources/dashboard.go index a2c6e04118..64f27702cc 100644 --- a/bundle/config/resources/dashboard.go +++ b/bundle/config/resources/dashboard.go @@ -59,10 +59,12 @@ type DashboardConfig struct { // DatasetCatalog sets the default catalog for all datasets in this dashboard. // When set, this overrides the catalog specified in individual dataset definitions. + // These are request only parameters and not returned by the GET API. DatasetCatalog string `json:"dataset_catalog,omitempty"` // DatasetSchema sets the default schema for all datasets in this dashboard. // When set, this overrides the schema specified in individual dataset definitions. + // These are request only parameters and not returned by the GET API. DatasetSchema string `json:"dataset_schema,omitempty"` } diff --git a/bundle/direct/dresources/dashboard.go b/bundle/direct/dresources/dashboard.go index baf0cb9f7a..3d62b30e16 100644 --- a/bundle/direct/dresources/dashboard.go +++ b/bundle/direct/dresources/dashboard.go @@ -123,6 +123,7 @@ func (r *ResourceDashboard) DoRead(ctx context.Context, id string) (*resources.D WarehouseId: dashboard.WarehouseId, SerializedDashboard: dashboard.SerializedDashboard, ParentPath: ensureWorkspacePrefix(dashboard.ParentPath), + // diffs are detected via etags, which will change if dataset_catalog/dataset_schema is updated. DatasetCatalog: "", DatasetSchema: "", diff --git a/bundle/internal/schema/annotations.yml b/bundle/internal/schema/annotations.yml index 29b2fd03e6..2a9c78b4ac 100644 --- a/bundle/internal/schema/annotations.yml +++ b/bundle/internal/schema/annotations.yml @@ -527,6 +527,13 @@ github.com/databricks/cli/bundle/config/resources.ClusterPermission: "user_name": "description": |- PLACEHOLDER +github.com/databricks/cli/bundle/config/resources.Dashboard: + "dataset_catalog": + "description": |- + Sets the default catalog for all datasets in this dashboard. When set, this overrides the catalog specified in individual dataset definitions. + "dataset_schema": + "description": |- + Sets the default schema for all datasets in this dashboard. When set, this overrides the schema specified in individual dataset definitions. github.com/databricks/cli/bundle/config/resources.DashboardPermission: "group_name": "description": |- diff --git a/bundle/schema/jsonschema.json b/bundle/schema/jsonschema.json index bf8dc42ac0..5ba02e6319 100644 --- a/bundle/schema/jsonschema.json +++ b/bundle/schema/jsonschema.json @@ -461,6 +461,12 @@ "description": "UUID identifying the dashboard.", "$ref": "#/$defs/string" }, + "dataset_catalog": { + "$ref": "#/$defs/string" + }, + "dataset_schema": { + "$ref": "#/$defs/string" + }, "display_name": { "description": "The display name of the dashboard.", "$ref": "#/$defs/string" From 22391a8fe6752038690475d668f61d918fea43c6 Mon Sep 17 00:00:00 2001 From: Leon Li Date: Thu, 11 Dec 2025 11:28:53 -0800 Subject: [PATCH 03/10] grammar --- bundle/config/resources/dashboard.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundle/config/resources/dashboard.go b/bundle/config/resources/dashboard.go index 64f27702cc..6f2ac7b8c8 100644 --- a/bundle/config/resources/dashboard.go +++ b/bundle/config/resources/dashboard.go @@ -59,12 +59,12 @@ type DashboardConfig struct { // DatasetCatalog sets the default catalog for all datasets in this dashboard. // When set, this overrides the catalog specified in individual dataset definitions. - // These are request only parameters and not returned by the GET API. + // This is a request only parameter and not returned by the GET API. DatasetCatalog string `json:"dataset_catalog,omitempty"` // DatasetSchema sets the default schema for all datasets in this dashboard. // When set, this overrides the schema specified in individual dataset definitions. - // These are request only parameters and not returned by the GET API. + // This is a request only parameter and not returned by the GET API. DatasetSchema string `json:"dataset_schema,omitempty"` } From 3f8b827f154768980dbf249c829aaa8c0f0a1d76 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Wed, 17 Dec 2025 13:24:42 +0100 Subject: [PATCH 04/10] Extend dataset_catalog and dataset_schema support to Terraform engine - Add Terraform conversion test for dataset_catalog and dataset_schema - Update acceptance tests to run for both direct and terraform engines - Fix direct engine to skip write-only fields in remote diff computation - Add engine-specific expected output files for requests and plans - Update test script to generate engine-specific request files --- .../out.plan.direct.json | 48 ++++++++++++++++--- .../out.plan.terraform.json | 9 ++++ .../out.post.requests.direct.txt | 14 ++++++ .../out.post.requests.terraform.txt | 14 ++++++ .../out.post.requests.txt | 14 ------ .../dataset-catalog-schema/out.test.toml | 3 +- .../dataset-catalog-schema/output.txt | 2 +- .../dashboards/dataset-catalog-schema/script | 2 +- .../dataset-catalog-schema/test.toml | 4 +- acceptance/internal/materialized_config.go | 1 + .../terraform/tfdyn/convert_dashboard_test.go | 31 ++++++++++++ bundle/direct/dresources/dashboard.go | 10 +++- 12 files changed, 125 insertions(+), 27 deletions(-) create mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.terraform.json create mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.direct.txt create mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.terraform.txt delete mode 100644 acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.txt diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json index e5a9addaaa..a98cc0d974 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json @@ -1,9 +1,45 @@ { - "all_resources": [ - { - "resource_type": "databricks_dashboard", - "resource_key": "dashboard1", - "action": "noop" + "plan_version": 1, + "cli_version": "[DEV_VERSION]", + "plan": { + "resources.dashboards.dashboard1": { + "action": "skip", + "remote_state": { + "create_time": "[TIMESTAMP]", + "dashboard_id": "[DASHBOARD_ID]", + "display_name": "test bundle-deploy-dashboard-dataset [UUID]", + "embed_credentials": true, + "etag": [ETAG], + "lifecycle_state": "ACTIVE", + "parent_path": "/Workspace/Users/[USERNAME]", + "path": "/Users/[USERNAME]/test bundle-deploy-dashboard-dataset [UUID].lvdash.json", + "serialized_dashboard": "{\"pages\":[{\"displayName\":\"Test Page\",\"name\":\"test_page\",\"pageType\":\"PAGE_TYPE_CANVAS\"}]}\n", + "update_time": "[TIMESTAMP]", + "warehouse_id": "[TEST_DEFAULT_WAREHOUSE_ID]" + }, + "changes": { + "local": { + "etag": { + "action": "skip", + "old": [ETAG] + } + }, + "remote": { + "dataset_catalog": { + "action": "skip", + "old": "main" + }, + "dataset_schema": { + "action": "skip", + "old": "default" + }, + "serialized_dashboard": { + "action": "skip", + "old": "{\"pages\":[{\"name\":\"test_page\",\"displayName\":\"Test Page\"}]}\n", + "new": "{\"pages\":[{\"displayName\":\"Test Page\",\"name\":\"test_page\",\"pageType\":\"PAGE_TYPE_CANVAS\"}]}\n" + } + } + } } - ] + } } diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.terraform.json b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.terraform.json new file mode 100644 index 0000000000..683e831f27 --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.terraform.json @@ -0,0 +1,9 @@ +{ + "plan_version": 1, + "cli_version": "[DEV_VERSION]", + "plan": { + "resources.dashboards.dashboard1": { + "action": "skip" + } + } +} diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.direct.txt b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.direct.txt new file mode 100644 index 0000000000..d465f7491e --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.direct.txt @@ -0,0 +1,14 @@ +{ + "method": "POST", + "path": "/api/2.0/lakeview/dashboards", + "q": { + "dataset_catalog": "main", + "dataset_schema": "default" + }, + "body": { + "display_name": "test bundle-deploy-dashboard-dataset [UUID]", + "parent_path": "/Workspace/Users/[USERNAME]", + "serialized_dashboard": "{\"pages\":[{\"name\":\"test_page\",\"displayName\":\"Test Page\"}]}\n", + "warehouse_id": "[TEST_DEFAULT_WAREHOUSE_ID]" + } +} diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.terraform.txt b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.terraform.txt new file mode 100644 index 0000000000..d465f7491e --- /dev/null +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.terraform.txt @@ -0,0 +1,14 @@ +{ + "method": "POST", + "path": "/api/2.0/lakeview/dashboards", + "q": { + "dataset_catalog": "main", + "dataset_schema": "default" + }, + "body": { + "display_name": "test bundle-deploy-dashboard-dataset [UUID]", + "parent_path": "/Workspace/Users/[USERNAME]", + "serialized_dashboard": "{\"pages\":[{\"name\":\"test_page\",\"displayName\":\"Test Page\"}]}\n", + "warehouse_id": "[TEST_DEFAULT_WAREHOUSE_ID]" + } +} diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.txt b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.txt deleted file mode 100644 index ff438733b9..0000000000 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.txt +++ /dev/null @@ -1,14 +0,0 @@ -{ - "method": "POST", - "path": "/api/2.0/lakeview/dashboards", - "body": { - "dashboard": { - "display_name": "test bundle-deploy-dashboard-dataset [UUID]", - "parent_path": "/Users/[USERNAME]", - "serialized_dashboard": "{\"pages\":[{\"name\":\"test_page\",\"displayName\":\"Test Page\"}]}\n", - "warehouse_id": "[TEST_DEFAULT_WAREHOUSE_ID]" - }, - "dataset_catalog": "main", - "dataset_schema": "default" - } -} diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml index 264ca54272..d74f18e4aa 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml @@ -4,4 +4,5 @@ RequiresWarehouse = true RecordRequests = true [EnvMatrix] - DATABRICKS_BUNDLE_ENGINE = ["direct"] + DATABRICKS_BUNDLE_ENGINE = ["direct", "terraform"] + Ignore = ["databricks.yml"] diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt index 8850e89daf..844f6a47da 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt @@ -10,7 +10,7 @@ Deployment complete! "lifecycle_state": "ACTIVE", "parent_path": "/Users/[USERNAME]", "path": "/Users/[USERNAME]/test bundle-deploy-dashboard-dataset [UUID].lvdash.json", - "serialized_dashboard": "{\"pages\":[{\"name\":\"test_page\",\"displayName\":\"Test Page\"}]}\n" + "serialized_dashboard": "{\"pages\":[{\"displayName\":\"Test Page\",\"name\":\"test_page\",\"pageType\":\"PAGE_TYPE_CANVAS\"}]}\n" } >>> [CLI] bundle plan -o json diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script index 656861aad9..d3a28b3b20 100755 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script @@ -31,4 +31,4 @@ cat out.requests.txt | \ jq 'select(.method == "POST")' | \ jq 'select(.path | contains("/api/2.0/lakeview/dashboards"))' | \ jq 'select(.path | contains("/published") | not)' \ - > out.post.requests.txt + > out.post.requests.$DATABRICKS_BUNDLE_ENGINE.txt diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml index 154c7950d1..269db2d0f6 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/test.toml @@ -2,10 +2,10 @@ Local = true Cloud = true RequiresWarehouse = true RecordRequests = true +EnvVaryOutput = "DATABRICKS_BUNDLE_ENGINE" -# TODO: test terraform once commit had been released (https://github.com/databricks/terraform-provider-databricks/pull/5259) [EnvMatrix] - DATABRICKS_BUNDLE_ENGINE = ["direct"] + DATABRICKS_BUNDLE_ENGINE = ["direct", "terraform"] Ignore = [ "databricks.yml", diff --git a/acceptance/internal/materialized_config.go b/acceptance/internal/materialized_config.go index 3233d3907c..d90d32cd07 100644 --- a/acceptance/internal/materialized_config.go +++ b/acceptance/internal/materialized_config.go @@ -32,6 +32,7 @@ func GenerateMaterializedConfig(config TestConfig) (string, error) { RequiresUnityCatalog: config.RequiresUnityCatalog, RequiresCluster: config.RequiresCluster, RequiresWarehouse: config.RequiresWarehouse, + RecordRequests: config.RecordRequests, EnvMatrix: config.EnvMatrix, } diff --git a/bundle/deploy/terraform/tfdyn/convert_dashboard_test.go b/bundle/deploy/terraform/tfdyn/convert_dashboard_test.go index d21e5ce543..f9bbdff447 100644 --- a/bundle/deploy/terraform/tfdyn/convert_dashboard_test.go +++ b/bundle/deploy/terraform/tfdyn/convert_dashboard_test.go @@ -109,3 +109,34 @@ func TestConvertDashboardSerializedDashboardAny(t *testing.T) { // Assert that the "file_path" is dropped. assert.NotContains(t, out.Dashboard["my_dashboard"], "file_path") } + +func TestConvertDashboardDatasetCatalogSchema(t *testing.T) { + src := resources.Dashboard{ + DashboardConfig: resources.DashboardConfig{ + DisplayName: "my dashboard", + WarehouseId: "f00dcafe", + ParentPath: "/some/path", + DatasetCatalog: "main", + DatasetSchema: "default", + EmbedCredentials: true, + }, + } + + vin, err := convert.FromTyped(src, dyn.NilValue) + require.NoError(t, err) + + ctx := context.Background() + out := schema.NewResources() + err = dashboardConverter{}.Convert(ctx, "my_dashboard", vin, out) + require.NoError(t, err) + + // Assert that dataset_catalog and dataset_schema are included. + assert.Subset(t, out.Dashboard["my_dashboard"], map[string]any{ + "display_name": "my dashboard", + "warehouse_id": "f00dcafe", + "parent_path": "/some/path", + "dataset_catalog": "main", + "dataset_schema": "default", + "embed_credentials": true, + }) +} diff --git a/bundle/direct/dresources/dashboard.go b/bundle/direct/dresources/dashboard.go index 3d62b30e16..626c1285f2 100644 --- a/bundle/direct/dresources/dashboard.go +++ b/bundle/direct/dresources/dashboard.go @@ -124,8 +124,8 @@ func (r *ResourceDashboard) DoRead(ctx context.Context, id string) (*resources.D SerializedDashboard: dashboard.SerializedDashboard, ParentPath: ensureWorkspacePrefix(dashboard.ParentPath), // diffs are detected via etags, which will change if dataset_catalog/dataset_schema is updated. - DatasetCatalog: "", - DatasetSchema: "", + DatasetCatalog: "", + DatasetSchema: "", // Output only fields. CreateTime: dashboard.CreateTime, @@ -321,6 +321,12 @@ func (*ResourceDashboard) FieldTriggers(isLocal bool) map[string]deployplan.Acti // "serialized_dashboard" locally and remotely will have different diffs. // We only need to rely on etag here, and can skip this field for diff computation. triggers["serialized_dashboard"] = deployplan.ActionTypeSkip + + // "dataset_catalog" and "dataset_schema" are write-only fields that are not returned by the server. + // They will always differ between local config (which has values) and remote state (which has empty strings), + // so we skip them for remote diff computation to avoid false positives. + triggers["dataset_catalog"] = deployplan.ActionTypeSkip + triggers["dataset_schema"] = deployplan.ActionTypeSkip } return triggers From e546144d5c6a41dc847a4d87ffc082e6da3d845d Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Wed, 17 Dec 2025 13:27:22 +0100 Subject: [PATCH 05/10] Fix --- acceptance/internal/materialized_config.go | 1 - 1 file changed, 1 deletion(-) diff --git a/acceptance/internal/materialized_config.go b/acceptance/internal/materialized_config.go index d90d32cd07..3233d3907c 100644 --- a/acceptance/internal/materialized_config.go +++ b/acceptance/internal/materialized_config.go @@ -32,7 +32,6 @@ func GenerateMaterializedConfig(config TestConfig) (string, error) { RequiresUnityCatalog: config.RequiresUnityCatalog, RequiresCluster: config.RequiresCluster, RequiresWarehouse: config.RequiresWarehouse, - RecordRequests: config.RecordRequests, EnvMatrix: config.EnvMatrix, } From a0d52e410cffa95eb6b5272c3c173a7fb9921cfd Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Wed, 17 Dec 2025 13:29:06 +0100 Subject: [PATCH 06/10] Update schema --- bundle/schema/jsonschema.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bundle/schema/jsonschema.json b/bundle/schema/jsonschema.json index 5415cf9511..41cb0fa591 100644 --- a/bundle/schema/jsonschema.json +++ b/bundle/schema/jsonschema.json @@ -462,9 +462,11 @@ "$ref": "#/$defs/string" }, "dataset_catalog": { + "description": "Sets the default catalog for all datasets in this dashboard. When set, this overrides the catalog specified in individual dataset definitions.", "$ref": "#/$defs/string" }, "dataset_schema": { + "description": "Sets the default schema for all datasets in this dashboard. When set, this overrides the schema specified in individual dataset definitions.", "$ref": "#/$defs/string" }, "display_name": { From 7d5b7dd697a313209267b4747861b4e5f7ca9fdd Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Wed, 17 Dec 2025 14:04:28 +0100 Subject: [PATCH 07/10] Update dashboard dataset acceptance test output --- .../resources/dashboards/dataset-catalog-schema/out.test.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml index d74f18e4aa..dbea8ee3ac 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.test.toml @@ -1,7 +1,6 @@ Local = true Cloud = true RequiresWarehouse = true -RecordRequests = true [EnvMatrix] DATABRICKS_BUNDLE_ENGINE = ["direct", "terraform"] From 2e743dc41bc92f0d13d6efbaf745e901a78dc06b Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Wed, 17 Dec 2025 16:05:50 +0100 Subject: [PATCH 08/10] Test the catalog/schema override e2e --- acceptance/bundle/refschema/out.fields.txt | 2 ++ .../out.plan.direct.json | 6 ++--- .../out.post.requests.direct.txt | 2 +- .../out.post.requests.terraform.txt | 2 +- .../dataset-catalog-schema/output.txt | 9 +++++-- .../sample-dashboard.lvdash.json | 21 ++++++++++++++- .../dashboards/dataset-catalog-schema/script | 17 +++++++++++- libs/testserver/dashboards.go | 27 ++++++++++++++++--- 8 files changed, 74 insertions(+), 12 deletions(-) diff --git a/acceptance/bundle/refschema/out.fields.txt b/acceptance/bundle/refschema/out.fields.txt index 524a99b12a..eb59c1b179 100644 --- a/acceptance/bundle/refschema/out.fields.txt +++ b/acceptance/bundle/refschema/out.fields.txt @@ -424,6 +424,8 @@ resources.clusters.*.permissions.permissions[*].service_principal_name string AL resources.clusters.*.permissions.permissions[*].user_name string ALL resources.dashboards.*.create_time string ALL resources.dashboards.*.dashboard_id string ALL +resources.dashboards.*.dataset_catalog string ALL +resources.dashboards.*.dataset_schema string ALL resources.dashboards.*.display_name string ALL resources.dashboards.*.embed_credentials bool ALL resources.dashboards.*.etag string ALL diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json index a98cc0d974..9ab748c848 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json @@ -13,7 +13,7 @@ "lifecycle_state": "ACTIVE", "parent_path": "/Workspace/Users/[USERNAME]", "path": "/Users/[USERNAME]/test bundle-deploy-dashboard-dataset [UUID].lvdash.json", - "serialized_dashboard": "{\"pages\":[{\"displayName\":\"Test Page\",\"name\":\"test_page\",\"pageType\":\"PAGE_TYPE_CANVAS\"}]}\n", + "serialized_dashboard": "[SERIALIZED_FIXTURE_NEW]", "update_time": "[TIMESTAMP]", "warehouse_id": "[TEST_DEFAULT_WAREHOUSE_ID]" }, @@ -35,8 +35,8 @@ }, "serialized_dashboard": { "action": "skip", - "old": "{\"pages\":[{\"name\":\"test_page\",\"displayName\":\"Test Page\"}]}\n", - "new": "{\"pages\":[{\"displayName\":\"Test Page\",\"name\":\"test_page\",\"pageType\":\"PAGE_TYPE_CANVAS\"}]}\n" + "old": "[SERIALIZED_FIXTURE_OLD]", + "new": "[SERIALIZED_FIXTURE_NEW]" } } } diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.direct.txt b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.direct.txt index d465f7491e..49f54fb76f 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.direct.txt +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.direct.txt @@ -8,7 +8,7 @@ "body": { "display_name": "test bundle-deploy-dashboard-dataset [UUID]", "parent_path": "/Workspace/Users/[USERNAME]", - "serialized_dashboard": "{\"pages\":[{\"name\":\"test_page\",\"displayName\":\"Test Page\"}]}\n", + "serialized_dashboard": "{\n \"pages\": [\n {\n \"name\": \"test_page\",\n \"displayName\": \"Test Page\",\n \"pageType\": \"PAGE_TYPE_CANVAS\"\n }\n ],\n \"datasets\": [\n {\n \"name\": \"bf8f76f4\",\n \"displayName\": \"Test Dataset\",\n \"queryLines\": [\n \"SELECT 1\\n\"\n ],\n \"catalog\": \"foobar\",\n \"schema\": \"foobar\"\n }\n ]\n}\n", "warehouse_id": "[TEST_DEFAULT_WAREHOUSE_ID]" } } diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.terraform.txt b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.terraform.txt index d465f7491e..49f54fb76f 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.terraform.txt +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.post.requests.terraform.txt @@ -8,7 +8,7 @@ "body": { "display_name": "test bundle-deploy-dashboard-dataset [UUID]", "parent_path": "/Workspace/Users/[USERNAME]", - "serialized_dashboard": "{\"pages\":[{\"name\":\"test_page\",\"displayName\":\"Test Page\"}]}\n", + "serialized_dashboard": "{\n \"pages\": [\n {\n \"name\": \"test_page\",\n \"displayName\": \"Test Page\",\n \"pageType\": \"PAGE_TYPE_CANVAS\"\n }\n ],\n \"datasets\": [\n {\n \"name\": \"bf8f76f4\",\n \"displayName\": \"Test Dataset\",\n \"queryLines\": [\n \"SELECT 1\\n\"\n ],\n \"catalog\": \"foobar\",\n \"schema\": \"foobar\"\n }\n ]\n}\n", "warehouse_id": "[TEST_DEFAULT_WAREHOUSE_ID]" } } diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt index 844f6a47da..4c7aa9d490 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/output.txt @@ -9,8 +9,13 @@ Deployment complete! { "lifecycle_state": "ACTIVE", "parent_path": "/Users/[USERNAME]", - "path": "/Users/[USERNAME]/test bundle-deploy-dashboard-dataset [UUID].lvdash.json", - "serialized_dashboard": "{\"pages\":[{\"displayName\":\"Test Page\",\"name\":\"test_page\",\"pageType\":\"PAGE_TYPE_CANVAS\"}]}\n" + "path": "/Users/[USERNAME]/test bundle-deploy-dashboard-dataset [UUID].lvdash.json" +} + +>>> [CLI] lakeview get [DASHBOARD_ID] +{ + "catalog": "main", + "schema": "default" } >>> [CLI] bundle plan -o json diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/sample-dashboard.lvdash.json b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/sample-dashboard.lvdash.json index 43eb82879c..6f76fc192d 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/sample-dashboard.lvdash.json +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/sample-dashboard.lvdash.json @@ -1 +1,20 @@ -{"pages":[{"name":"test_page","displayName":"Test Page"}]} +{ + "pages": [ + { + "name": "test_page", + "displayName": "Test Page", + "pageType": "PAGE_TYPE_CANVAS" + } + ], + "datasets": [ + { + "name": "bf8f76f4", + "displayName": "Test Dataset", + "queryLines": [ + "SELECT 1\n" + ], + "catalog": "foobar", + "schema": "foobar" + } + ] +} diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script index d3a28b3b20..f17a675801 100755 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/script @@ -20,11 +20,26 @@ DASHBOARD_ID=$($CLI bundle summary --output json | jq -r '.resources.dashboards. # Capture the dashboard ID as a replacement. echo "$DASHBOARD_ID:DASHBOARD_ID" >> ACC_REPLS -trace $CLI lakeview get $DASHBOARD_ID | jq '{lifecycle_state, parent_path, path, serialized_dashboard}' +trace $CLI lakeview get $DASHBOARD_ID | jq '{lifecycle_state, parent_path, path}' + +# Verify that the serialized_dashboard datasets have the overridden catalog/schema values. +# The dataset_catalog and dataset_schema parameters should override the values in the datasets. +trace $CLI lakeview get $DASHBOARD_ID | jq '.serialized_dashboard | fromjson | .datasets[] | {catalog, schema}' # Verify that there is no drift right after deploy. trace $CLI bundle plan -o json > out.plan.$DATABRICKS_BUNDLE_ENGINE.json +# Modify the direct plan to replace "serialized_dashboard" with a fixture. +# It is normalized on the backend so we cannot compare reliably across local and cloud. +if [ "$DATABRICKS_BUNDLE_ENGINE" = "direct" ]; then + jq '.plan["resources.dashboards.dashboard1"].remote_state.serialized_dashboard |= + if . then "[SERIALIZED_FIXTURE]" else . end' \ + out.plan.direct.json > out.plan.direct.json.tmp && mv out.plan.direct.json.tmp out.plan.direct.json + jq '.plan["resources.dashboards.dashboard1"].changes.remote.serialized_dashboard |= + if . then {"action": .action, "old": "[SERIALIZED_FIXTURE_OLD]", "new": "[SERIALIZED_FIXTURE_NEW]"} else . end' \ + out.plan.direct.json > out.plan.direct.json.tmp && mv out.plan.direct.json.tmp out.plan.direct.json +fi + # Print API requests made to create the dashboard. # This verifies that dataset_catalog and dataset_schema are passed to the API. cat out.requests.txt | \ diff --git a/libs/testserver/dashboards.go b/libs/testserver/dashboards.go index 155086c9b4..c07a8281c8 100644 --- a/libs/testserver/dashboards.go +++ b/libs/testserver/dashboards.go @@ -25,7 +25,7 @@ func generateDashboardId() (string, error) { } // Transform the serialized dashboard to mimic remote behavior. -func transformSerializedDashboard(serializedDashboard string) string { +func transformSerializedDashboard(serializedDashboard, datasetCatalog, datasetSchema string) string { var dashboardContent map[string]any err := json.Unmarshal([]byte(serializedDashboard), &dashboardContent) if err != nil { @@ -41,6 +41,20 @@ func transformSerializedDashboard(serializedDashboard string) string { } } + // Apply dataset_catalog and dataset_schema overrides to all datasets + if datasets, ok := dashboardContent["datasets"].([]any); ok { + for _, dataset := range datasets { + if datasetMap, ok := dataset.(map[string]any); ok { + if datasetCatalog != "" { + datasetMap["catalog"] = datasetCatalog + } + if datasetSchema != "" { + datasetMap["schema"] = datasetSchema + } + } + } + } + updatedContent, err := json.Marshal(dashboardContent) if err != nil { return serializedDashboard @@ -98,9 +112,13 @@ func (s *FakeWorkspace) DashboardCreate(req Request) Response { inputSerializedDashboard := dashboard.SerializedDashboard + // Extract dataset_catalog and dataset_schema from query parameters + datasetCatalog := req.URL.Query().Get("dataset_catalog") + datasetSchema := req.URL.Query().Get("dataset_schema") + // Parse serializedDashboard into json and put it back as a string if dashboard.SerializedDashboard != "" { - dashboard.SerializedDashboard = transformSerializedDashboard(dashboard.SerializedDashboard) + dashboard.SerializedDashboard = transformSerializedDashboard(dashboard.SerializedDashboard, datasetCatalog, datasetSchema) } dashboard.Etag = "80611980" @@ -170,7 +188,10 @@ func (s *FakeWorkspace) DashboardUpdate(req Request) Response { dashboard.Path = path.Join(dir, base) } if updateReq.SerializedDashboard != "" { - dashboard.SerializedDashboard = transformSerializedDashboard(updateReq.SerializedDashboard) + // Extract dataset_catalog and dataset_schema from query parameters + datasetCatalog := req.URL.Query().Get("dataset_catalog") + datasetSchema := req.URL.Query().Get("dataset_schema") + dashboard.SerializedDashboard = transformSerializedDashboard(updateReq.SerializedDashboard, datasetCatalog, datasetSchema) } if updateReq.WarehouseId != "" { dashboard.WarehouseId = updateReq.WarehouseId From 473c0960e4aa3e780ded92f8dde03801e03821b5 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Wed, 17 Dec 2025 16:07:21 +0100 Subject: [PATCH 09/10] Include CHANGELOG entry --- NEXT_CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 901764652f..8f2f67a763 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -7,6 +7,7 @@ ### CLI ### Bundles +* Add support for configurable catalog/schema for dashboards ([#4130](https://github.com/databricks/cli/pull/4130)) * engine/direct: Fix dependency-ordered deletion by persisting depends_on in state ([#4105](https://github.com/databricks/cli/pull/4105)) * Pass SYSTEM_ACCESSTOKEN from env to the Terraform provider ([#4135](https://github.com/databricks/cli/pull/4135) From ca21bfea1f2743bcfff7789cef04daf51f9a04b4 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Wed, 17 Dec 2025 16:18:01 +0100 Subject: [PATCH 10/10] Fix --- .../dashboards/dataset-catalog-schema/out.plan.direct.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json index 9ab748c848..70f04bf32c 100644 --- a/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json +++ b/acceptance/bundle/resources/dashboards/dataset-catalog-schema/out.plan.direct.json @@ -13,7 +13,7 @@ "lifecycle_state": "ACTIVE", "parent_path": "/Workspace/Users/[USERNAME]", "path": "/Users/[USERNAME]/test bundle-deploy-dashboard-dataset [UUID].lvdash.json", - "serialized_dashboard": "[SERIALIZED_FIXTURE_NEW]", + "serialized_dashboard": "[SERIALIZED_FIXTURE]", "update_time": "[TIMESTAMP]", "warehouse_id": "[TEST_DEFAULT_WAREHOUSE_ID]" },