diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index e098fc190d3..665031fa09e 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -11,6 +11,7 @@ ### Bundles * Fix processing short pip flags in environment dependencies ([#3708](https://github.com/databricks/cli/pull/3708)) * Add support for referencing local files in -e pip flag for environment dependencies ([#3708](https://github.com/databricks/cli/pull/3708)) +* Add error for when an etag is specified in dashboard configuration. Setting etags was never supported / valid in bundles but now users will see this error during validation rather than deployment. ([#3723](https://github.com/databricks/cli/pull/3723)) * Fix PIP flag processing in pipeline environment dependencies ([#3734](https://github.com/databricks/cli/pull/3734)) ### API Changes diff --git a/acceptance/bundle/validate/no_dashboard_etag/databricks.yml b/acceptance/bundle/validate/no_dashboard_etag/databricks.yml new file mode 100644 index 00000000000..9a518ab88c7 --- /dev/null +++ b/acceptance/bundle/validate/no_dashboard_etag/databricks.yml @@ -0,0 +1,6 @@ +resources: + dashboards: + foobar: + display_name: foobar + etag: "1234567890" + serialized_dashboard: "{}" diff --git a/acceptance/bundle/validate/no_dashboard_etag/out.test.toml b/acceptance/bundle/validate/no_dashboard_etag/out.test.toml new file mode 100644 index 00000000000..e092fd5ed6a --- /dev/null +++ b/acceptance/bundle/validate/no_dashboard_etag/out.test.toml @@ -0,0 +1,5 @@ +Local = true +Cloud = false + +[EnvMatrix] + DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct-exp"] diff --git a/acceptance/bundle/validate/no_dashboard_etag/output.txt b/acceptance/bundle/validate/no_dashboard_etag/output.txt new file mode 100644 index 00000000000..d7d3ca110bb --- /dev/null +++ b/acceptance/bundle/validate/no_dashboard_etag/output.txt @@ -0,0 +1,15 @@ + +>>> [CLI] bundle validate +Error: dashboard "foobar" has an etag set. Etags must not be set in bundle configuration + at resources.dashboards.foobar + in databricks.yml:6:7 + +Name: test-bundle +Target: default +Workspace: + User: [USERNAME] + Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default + +Found 1 error + +Exit code: 1 diff --git a/acceptance/bundle/validate/no_dashboard_etag/script b/acceptance/bundle/validate/no_dashboard_etag/script new file mode 100644 index 00000000000..5350876150f --- /dev/null +++ b/acceptance/bundle/validate/no_dashboard_etag/script @@ -0,0 +1 @@ +trace $CLI bundle validate diff --git a/bundle/config/validate/validate_dashboard_etags.go b/bundle/config/validate/validate_dashboard_etags.go new file mode 100644 index 00000000000..53c428af1dd --- /dev/null +++ b/bundle/config/validate/validate_dashboard_etags.go @@ -0,0 +1,37 @@ +package validate + +import ( + "context" + "fmt" + + "github.com/databricks/cli/bundle" + "github.com/databricks/cli/libs/diag" + "github.com/databricks/cli/libs/dyn" +) + +func ValidateDashboardEtags() bundle.ReadOnlyMutator { + return &validateDashboardEtags{} +} + +type validateDashboardEtags struct{ bundle.RO } + +func (v *validateDashboardEtags) Name() string { + return "validate:validate_dashboard_etags" +} + +func (v *validateDashboardEtags) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics { + // No dashboards should have etags set. They are purely internal state. + for k, dashboard := range b.Config.Resources.Dashboards { + if dashboard.Etag != "" { + return diag.Diagnostics{ + { + Severity: diag.Error, + Summary: fmt.Sprintf("dashboard %q has an etag set. Etags must not be set in bundle configuration", dashboard.DisplayName), + Paths: []dyn.Path{dyn.MustPathFromString("resources.dashboards." + k)}, + Locations: b.Config.GetLocations("resources.dashboards." + k), + }, + } + } + } + return nil +} diff --git a/bundle/phases/initialize.go b/bundle/phases/initialize.go index 9db68efb5a6..93a291bca33 100644 --- a/bundle/phases/initialize.go +++ b/bundle/phases/initialize.go @@ -142,6 +142,9 @@ func Initialize(ctx context.Context, b *bundle.Bundle) { // Validate that all fields with enum values specified are set to a valid value. validate.Enum(), + // Validate that no dashboard etags are set. They are purely internal state and should not be set by the user. + validate.ValidateDashboardEtags(), + // Reads (typed): b.Config.Permissions (checks if current user or their groups have CAN_MANAGE permissions) // Reads (typed): b.Config.Workspace.CurrentUser (gets current user information) // Provides diagnostic recommendations if the current deployment identity isn't explicitly granted CAN_MANAGE permissions