From 2160ef5cd74a49cf9970856581c3daad06a8e2b4 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Mon, 31 Aug 2026 12:53:09 +0200 Subject: [PATCH 1/4] Mask a Lakebase oneof member under its group name expire_time / ttl / no_expiry are one oneof, suspend_timeout_duration / no_suspension another, and the API accepts them in update_mask only under the group name -- masking the field itself is answered with "Unknown field path in update_mask". So four changes a bundle can express could not be deployed at all: branch expire_time and ttl, endpoint suspend_timeout_duration, and the project's default_endpoint_settings equivalent. All four now apply, and their tests drop Badness. The group names are not in the OpenAPI spec or in the SDK doc comments, so each map is hand-written from what the backend accepts, probed on 2026-08-31. Removing suspend_timeout_duration still fails, and the mask is no longer why: the API requires a masked field to be populated in the body, so a removal has nothing to send. That test keeps a Badness saying so. Co-authored-by: Isaac --- .../bundles/postgres-oneof-update-mask.md | 5 ++++ .../update_expire_time/out.branch.direct.txt | 2 +- .../update_expire_time/out.deploy.direct.txt | 11 ++------ .../out.requests.direct.json | 2 +- .../update_expire_time/test.toml | 10 +++---- .../update_ttl/out.deploy.direct.txt | 11 ++------ .../update_ttl/out.requests.direct.json | 2 +- .../postgres_branches/update_ttl/script | 4 +++ .../postgres_branches/update_ttl/test.toml | 6 ----- .../out.deploy.direct.txt | 6 ++--- .../out.requests.direct.json | 2 +- .../remove_suspend_timeout/test.toml | 17 ++++++------ .../out.deploy.direct.txt | 11 ++------ .../out.endpoint.direct.txt | 2 +- .../out.requests.direct.json | 2 +- .../update_suspend_timeout/script | 5 ++++ .../update_suspend_timeout/test.toml | 22 ---------------- .../out.deploy.direct.txt | 11 ++------ .../out.project.direct.txt | 2 +- .../out.requests.direct.json | 2 +- .../update_default_endpoint_suspend/script | 5 ++++ .../update_default_endpoint_suspend/test.toml | 7 ----- bundle/direct/dresources/postgres_branch.go | 11 +++++++- bundle/direct/dresources/postgres_database.go | 2 +- bundle/direct/dresources/postgres_endpoint.go | 9 ++++++- bundle/direct/dresources/postgres_project.go | 9 ++++++- bundle/direct/dresources/postgres_role.go | 2 +- bundle/direct/dresources/util.go | 14 +++++++--- bundle/direct/dresources/util_test.go | 26 ++++++++++++++++--- libs/testserver/postgres.go | 9 +++++-- 30 files changed, 118 insertions(+), 111 deletions(-) create mode 100644 .nextchanges/bundles/postgres-oneof-update-mask.md delete mode 100644 acceptance/bundle/resources/postgres_branches/update_ttl/test.toml delete mode 100644 acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/test.toml delete mode 100644 acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/test.toml diff --git a/.nextchanges/bundles/postgres-oneof-update-mask.md b/.nextchanges/bundles/postgres-oneof-update-mask.md new file mode 100644 index 00000000000..390a8ee8fd5 --- /dev/null +++ b/.nextchanges/bundles/postgres-oneof-update-mask.md @@ -0,0 +1,5 @@ +Fixed deploying a change to a Lakebase field that belongs to a oneof — +`postgres_branches.expire_time` and `.ttl`, `postgres_endpoints.suspend_timeout_duration`, +and `postgres_projects.default_endpoint_settings.suspend_timeout_duration`. The update +masked each field under its own name, which the API rejects; it accepts only the oneof +group name. diff --git a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.direct.txt b/acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.direct.txt index 7d5df9bf89a..c6bec73d4e2 100644 --- a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.direct.txt +++ b/acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.direct.txt @@ -6,7 +6,7 @@ "branch_id": "dev-branch", "current_state": "READY", "default": false, - "expire_time": "[EXPIRE_TIME_BEFORE]", + "expire_time": "[EXPIRE_TIME_AFTER]", "is_protected": false, "source_branch": "projects/test-pg-proj-[UNIQUE_NAME]/branches/production", "source_branch_lsn": "[LSN]", diff --git a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.direct.txt b/acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.direct.txt index 9d5c0364154..5d7079e4ca3 100644 --- a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.direct.txt +++ b/acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.direct.txt @@ -1,11 +1,4 @@ Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-branch-expire-[UNIQUE_NAME]/default/files... -Error: cannot update resources.postgres_branches.dev_branch: updating id=projects/test-pg-proj-[UNIQUE_NAME]/branches/dev-branch: Unknown field path in update_mask: 'spec.expire_time' (400 INVALID_PARAMETER_VALUE) - -Endpoint: PATCH [DATABRICKS_URL]/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]/branches/dev-branch?update_mask=spec.expire_time -HTTP Status: 400 Bad Request -API error_code: INVALID_PARAMETER_VALUE -API message: Unknown field path in update_mask: 'spec.expire_time' - +Updated postgres_branches.dev_branch Files: 0 uploaded, 0 deleted - -Exit code: 1 +Resources: 0 created, 1 changed, 0 deleted, 1 unchanged diff --git a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.requests.direct.json b/acceptance/bundle/resources/postgres_branches/update_expire_time/out.requests.direct.json index 501fdc8f7ca..4d9bc1cbd89 100644 --- a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.requests.direct.json +++ b/acceptance/bundle/resources/postgres_branches/update_expire_time/out.requests.direct.json @@ -2,7 +2,7 @@ "method": "PATCH", "path": "/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]/branches/dev-branch", "q": { - "update_mask": "spec.expire_time" + "update_mask": "spec.expiration" }, "body": { "spec": { diff --git a/acceptance/bundle/resources/postgres_branches/update_expire_time/test.toml b/acceptance/bundle/resources/postgres_branches/update_expire_time/test.toml index 3aa478b751f..b9330252d52 100644 --- a/acceptance/bundle/resources/postgres_branches/update_expire_time/test.toml +++ b/acceptance/bundle/resources/postgres_branches/update_expire_time/test.toml @@ -1,9 +1,7 @@ -# expire_time, ttl and no_expiry are three sides of one oneof. The API masks them -# together under spec.expiration and rejects each field name on its own, so the -# direct engine's update_mask=spec.expire_time is answered with -# 400 INVALID_PARAMETER_VALUE. Same bug as postgres_endpoints/update_suspend_timeout, -# and a separate fix from the diffing this test covers. -Badness = "Direct engine cannot apply an expire_time change: it masks the field under its own name, but the API only accepts the oneof group name spec.expiration" +# expire_time, ttl and no_expiry are three sides of one oneof, and the API accepts them +# in update_mask only under the group name spec.expiration. Both engines apply the change; +# out.requests.direct.json records the group mask the direct engine now sends. + # Local only: a real workspace caps how far ahead a branch may expire and answers # these literal timestamps with 400 "expiration time exceeds the maximum diff --git a/acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.direct.txt b/acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.direct.txt index cbc5b5056dc..86be60be051 100644 --- a/acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.direct.txt +++ b/acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.direct.txt @@ -1,11 +1,4 @@ Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-branch-ttl-[UNIQUE_NAME]/default/files... -Error: cannot update resources.postgres_branches.dev_branch: updating id=projects/test-pg-proj-[UNIQUE_NAME]/branches/dev-branch: Unknown field path in update_mask: 'spec.ttl' (400 INVALID_PARAMETER_VALUE) - -Endpoint: PATCH [DATABRICKS_URL]/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]/branches/dev-branch?update_mask=spec.ttl -HTTP Status: 400 Bad Request -API error_code: INVALID_PARAMETER_VALUE -API message: Unknown field path in update_mask: 'spec.ttl' - +Updated postgres_branches.dev_branch Files: 0 uploaded, 0 deleted - -Exit code: 1 +Resources: 0 created, 1 changed, 0 deleted, 1 unchanged diff --git a/acceptance/bundle/resources/postgres_branches/update_ttl/out.requests.direct.json b/acceptance/bundle/resources/postgres_branches/update_ttl/out.requests.direct.json index 8da21837568..433fadb089e 100644 --- a/acceptance/bundle/resources/postgres_branches/update_ttl/out.requests.direct.json +++ b/acceptance/bundle/resources/postgres_branches/update_ttl/out.requests.direct.json @@ -2,7 +2,7 @@ "method": "PATCH", "path": "/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]/branches/dev-branch", "q": { - "update_mask": "spec.ttl" + "update_mask": "spec.expiration" }, "body": { "spec": { diff --git a/acceptance/bundle/resources/postgres_branches/update_ttl/script b/acceptance/bundle/resources/postgres_branches/update_ttl/script index dbf6594a97d..dbefd086ff3 100644 --- a/acceptance/bundle/resources/postgres_branches/update_ttl/script +++ b/acceptance/bundle/resources/postgres_branches/update_ttl/script @@ -1,3 +1,7 @@ +# ttl, expire_time and no_expiry are three sides of one oneof, and the API accepts them in +# update_mask only under the group name spec.expiration. This is the cloud-covered case of +# that oneof; update_expire_time is local only. + envsubst < databricks.yml.tmpl > databricks.yml cleanup() { diff --git a/acceptance/bundle/resources/postgres_branches/update_ttl/test.toml b/acceptance/bundle/resources/postgres_branches/update_ttl/test.toml deleted file mode 100644 index 9f9335b55db..00000000000 --- a/acceptance/bundle/resources/postgres_branches/update_ttl/test.toml +++ /dev/null @@ -1,6 +0,0 @@ -# ttl, expire_time and no_expiry are three sides of one oneof. The API masks them -# together under spec.expiration and rejects each field name on its own, so the -# direct engine's update_mask=spec.ttl is answered with 400 INVALID_PARAMETER_VALUE. -# Same bug as postgres_endpoints/update_suspend_timeout, and a separate fix from -# the diffing this test covers. -Badness = "Direct engine cannot apply a ttl change: it masks the field under its own name, but the API only accepts the oneof group name spec.expiration" diff --git a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.deploy.direct.txt b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.deploy.direct.txt index bd3e850e268..062615af571 100644 --- a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.deploy.direct.txt +++ b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.deploy.direct.txt @@ -1,10 +1,10 @@ Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/remove-postgres-endpoint-suspend-[UNIQUE_NAME]/default/files... -Error: cannot update resources.postgres_endpoints.my_endpoint: updating id=projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint: Unknown field path in update_mask: 'spec.suspend_timeout_duration' (400 INVALID_PARAMETER_VALUE) +Error: cannot update resources.postgres_endpoints.my_endpoint: updating id=projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint: Field 'spec.suspension' is in update_mask but not provided in request (400 INVALID_PARAMETER_VALUE) -Endpoint: PATCH [DATABRICKS_URL]/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint?update_mask=spec.suspend_timeout_duration +Endpoint: PATCH [DATABRICKS_URL]/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint?update_mask=spec.suspension HTTP Status: 400 Bad Request API error_code: INVALID_PARAMETER_VALUE -API message: Unknown field path in update_mask: 'spec.suspend_timeout_duration' +API message: Field 'spec.suspension' is in update_mask but not provided in request Files: 0 uploaded, 0 deleted diff --git a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.requests.direct.json b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.requests.direct.json index 38f7d78dda8..56aefeeca6c 100644 --- a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.requests.direct.json +++ b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.requests.direct.json @@ -2,7 +2,7 @@ "method": "PATCH", "path": "/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint", "q": { - "update_mask": "spec.suspend_timeout_duration" + "update_mask": "spec.suspension" }, "body": { "spec": { diff --git a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/test.toml b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/test.toml index 5ad72faf762..e9fdc923eed 100644 --- a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/test.toml +++ b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/test.toml @@ -1,9 +1,8 @@ -# suspend_timeout_duration and no_suspension are two sides of one oneof. The API -# masks them together under spec.suspension and rejects either field name, so -# removing the field is answered with 400 INVALID_PARAMETER_VALUE just like changing -# it (postgres_endpoints/update_suspend_timeout). Separate fix from the diffing this -# test covers. -# -# out.plan.drift.direct.* records what the failed removal leaves behind: the old -# value stays in state, so every later deploy plans the removal again and fails again. -Badness = "Direct engine cannot remove suspend_timeout_duration: it masks the field under its own name, but the API only accepts the oneof group name spec.suspension, so the removal fails on every deploy" +# The mask is now correct: suspend_timeout_duration is masked under its oneof group name +# spec.suspension. The removal still cannot be applied, and that is a property of the API +# rather than of the mask: a masked field has to be populated in the request body, so +# dropping it from the bundle leaves nothing to send. Probed against a real workspace on +# 2026-08-31 -- an absent value and an explicit null are both answered with "is in +# update_mask but not provided in request". The only way to stop an endpoint suspending is +# to set the other member of the oneof, no_suspension: true. +Badness = "Removing suspend_timeout_duration cannot be applied: the API requires a masked field to be populated, so the removal fails on every deploy. Setting no_suspension: true instead is the supported way to express it" diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.direct.txt b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.direct.txt index e1ce824d334..8f5d94669f4 100644 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.direct.txt +++ b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.direct.txt @@ -1,11 +1,4 @@ Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-endpoint-suspend-[UNIQUE_NAME]/default/files... -Error: cannot update resources.postgres_endpoints.my_endpoint: updating id=projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint: Unknown field path in update_mask: 'spec.suspend_timeout_duration' (400 INVALID_PARAMETER_VALUE) - -Endpoint: PATCH [DATABRICKS_URL]/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint?update_mask=spec.suspend_timeout_duration -HTTP Status: 400 Bad Request -API error_code: INVALID_PARAMETER_VALUE -API message: Unknown field path in update_mask: 'spec.suspend_timeout_duration' - +Updated postgres_endpoints.my_endpoint Files: 0 uploaded, 0 deleted - -Exit code: 1 +Resources: 0 created, 1 changed, 0 deleted, 2 unchanged diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.direct.txt b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.direct.txt index 3108e3da669..1703715e87e 100644 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.direct.txt +++ b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.direct.txt @@ -8,6 +8,6 @@ "endpoint_type": "ENDPOINT_TYPE_READ_ONLY", "autoscaling_limit_min_cu": 0.5, "autoscaling_limit_max_cu": 8, - "suspend_timeout_duration": "300s" + "suspend_timeout_duration": "600s" } } diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.requests.direct.json b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.requests.direct.json index 7aa62582e90..3acf526f897 100644 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.requests.direct.json +++ b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.requests.direct.json @@ -2,7 +2,7 @@ "method": "PATCH", "path": "/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint", "q": { - "update_mask": "spec.suspend_timeout_duration" + "update_mask": "spec.suspension" }, "body": { "spec": { diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/script b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/script index ef0a28c0dad..4617f21697e 100644 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/script +++ b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/script @@ -1,3 +1,8 @@ +# suspend_timeout_duration and no_suspension are two sides of one oneof, and the API +# accepts them in update_mask only under the group name spec.suspension. out.requests.*.json +# shows both engines applying the change: direct masks the group, the Terraform provider +# masks the whole spec. + envsubst < databricks.yml.tmpl > databricks.yml cleanup() { diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/test.toml b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/test.toml deleted file mode 100644 index 652b1fb7455..00000000000 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/test.toml +++ /dev/null @@ -1,22 +0,0 @@ -# Both engines plan the duration change correctly. Applying it is where they part: -# the direct engine builds update_mask from the plan's change paths, so it sends -# -# PATCH .../endpoints/my-endpoint?update_mask=spec.suspend_timeout_duration -# -# and the API answers 400 INVALID_PARAMETER_VALUE, "Unknown field path in -# update_mask: 'spec.suspend_timeout_duration'". suspend_timeout_duration and -# no_suspension are two sides of one oneof, and the API masks oneof members under -# the group name: the field's doc comment in the SDK says to use spec.suspension. -# -# That is a separate bug from the diffing this test covers, fixed separately in -# https://github.com/databricks/cli/pull/6374. It only became reachable now: -# before, the direct engine planned no change for a duration edit, so it never -# sent the PATCH at all. -# -# out.requests.*.json shows the difference directly: both engines send -# suspend_timeout_duration: 600s in the body, but direct masks it as -# spec.suspend_timeout_duration while the Terraform provider masks the whole spec. -# out.deploy.direct.txt records the resulting failure. libs/testserver/postgres.go -# validates update_mask against the paths the real API accepts, so the local run -# reproduces this rather than passing against a fake that ignores the mask. -Badness = "Direct engine cannot apply a suspend_timeout_duration change: it masks the field under its own name, but the API only accepts the oneof group name spec.suspension" diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.direct.txt b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.direct.txt index efb6fc55733..39f7b28edfd 100644 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.direct.txt +++ b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.direct.txt @@ -1,11 +1,4 @@ Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-project-default-suspend-[UNIQUE_NAME]/default/files... -Error: cannot update resources.postgres_projects.my_project: updating id=projects/test-pg-proj-[UNIQUE_NAME]: Unknown field path in update_mask: 'spec.default_endpoint_settings.suspend_timeout_duration' (400 INVALID_PARAMETER_VALUE) - -Endpoint: PATCH [DATABRICKS_URL]/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]?update_mask=spec.default_endpoint_settings.suspend_timeout_duration -HTTP Status: 400 Bad Request -API error_code: INVALID_PARAMETER_VALUE -API message: Unknown field path in update_mask: 'spec.default_endpoint_settings.suspend_timeout_duration' - +Updated postgres_projects.my_project Files: 0 uploaded, 0 deleted - -Exit code: 1 +Resources: 0 created, 1 changed, 0 deleted, 0 unchanged diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.direct.txt b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.direct.txt index 80a7ffcea6e..4337bc5b199 100644 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.direct.txt +++ b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.direct.txt @@ -7,7 +7,7 @@ "default_endpoint_settings": { "autoscaling_limit_max_cu": 4, "autoscaling_limit_min_cu": 0.5, - "suspend_timeout_duration": "300s" + "suspend_timeout_duration": "600s" }, "display_name": "Test Project for Default Endpoint Suspend Update", "enable_pg_native_login": false, diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.requests.direct.json b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.requests.direct.json index 6099f1ef52f..3747f87142d 100644 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.requests.direct.json +++ b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.requests.direct.json @@ -2,7 +2,7 @@ "method": "PATCH", "path": "/api/2.0/postgres/projects/test-pg-proj-[UNIQUE_NAME]", "q": { - "update_mask": "spec.default_endpoint_settings.suspend_timeout_duration" + "update_mask": "spec.default_endpoint_settings.suspension" }, "body": { "spec": { diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/script b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/script index cac7a5fd809..4f09ca25905 100644 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/script +++ b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/script @@ -1,3 +1,8 @@ +# default_endpoint_settings.no_suspension and .suspend_timeout_duration are two sides of one +# oneof, and the API accepts them in update_mask only under the group name +# spec.default_endpoint_settings.suspension. Same oneof as +# postgres_endpoints/update_suspend_timeout, one level of nesting down. + envsubst < databricks.yml.tmpl > databricks.yml cleanup() { diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/test.toml b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/test.toml deleted file mode 100644 index 07d6a932d9c..00000000000 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/test.toml +++ /dev/null @@ -1,7 +0,0 @@ -# default_endpoint_settings.no_suspension and .suspend_timeout_duration are two -# sides of one oneof. The API masks them together under -# spec.default_endpoint_settings.suspension and rejects either field name, so the -# direct engine's mask is answered with 400 INVALID_PARAMETER_VALUE. Same bug as -# postgres_endpoints/update_suspend_timeout, one level of nesting down, and a -# separate fix from the diffing this test covers. -Badness = "Direct engine cannot apply a default_endpoint_settings.suspend_timeout_duration change: it masks the field under its own name, but the API only accepts the oneof group name default_endpoint_settings.suspension" diff --git a/bundle/direct/dresources/postgres_branch.go b/bundle/direct/dresources/postgres_branch.go index b033b42a8f0..96629c222ab 100644 --- a/bundle/direct/dresources/postgres_branch.go +++ b/bundle/direct/dresources/postgres_branch.go @@ -140,6 +140,15 @@ func (r *ResourcePostgresBranch) DoCreate(ctx context.Context, config *PostgresB return remote.Name, remote, nil } +// expire_time, no_expiry and ttl are three sides of one oneof, and the API accepts them +// in update_mask only under the group name: masking the field itself is answered with +// "Unknown field path in update_mask". Probed against a real workspace on 2026-08-31. +var branchOneofGroups = map[string]string{ + "expire_time": "expiration", + "no_expiry": "expiration", + "ttl": "expiration", +} + func (r *ResourcePostgresBranch) DoUpdate(ctx context.Context, id string, config *PostgresBranchState, entry *PlanEntry) (*PostgresBranchRemote, error) { // Build the mask from the plan's change list and prefix with "spec." (the // API expects paths relative to Branch). The API rejects mask entries @@ -147,7 +156,7 @@ func (r *ResourcePostgresBranch) DoUpdate(ctx context.Context, id string, config // expands to nested attributes the body would have to set too — so we // can't use a static all-fields mask. The change list naturally tracks // what the user actually set, so the body and mask stay consistent. - fieldPaths := collectUpdatePathsWithPrefix(entry.Changes, "spec.") + fieldPaths := collectUpdatePathsWithPrefix(entry.Changes, "spec.", branchOneofGroups) // purge_on_delete is an input-only flag consulted at delete time; it is // not a spec field. Strip it from the mask so toggling it between deploys diff --git a/bundle/direct/dresources/postgres_database.go b/bundle/direct/dresources/postgres_database.go index 02a31116ae5..fb5927b728d 100644 --- a/bundle/direct/dresources/postgres_database.go +++ b/bundle/direct/dresources/postgres_database.go @@ -135,7 +135,7 @@ func (r *ResourcePostgresDatabase) DoUpdate(ctx context.Context, id string, conf // This excludes immutable fields and fields that haven't changed. // Prefix with "spec." because the API expects paths relative to the Database object, // not relative to our flattened state type. - fieldPaths := collectUpdatePathsWithPrefix(entry.Changes, "spec.") + fieldPaths := collectUpdatePathsWithPrefix(entry.Changes, "spec.", nil) waiter, err := r.client.Postgres.UpdateDatabase(ctx, postgres.UpdateDatabaseRequest{ Database: postgres.Database{ diff --git a/bundle/direct/dresources/postgres_endpoint.go b/bundle/direct/dresources/postgres_endpoint.go index c370ff120be..fbc0849401e 100644 --- a/bundle/direct/dresources/postgres_endpoint.go +++ b/bundle/direct/dresources/postgres_endpoint.go @@ -176,12 +176,19 @@ func (r *ResourcePostgresEndpoint) DoCreate(ctx context.Context, config *Postgre return remote.Name, remote, nil } +// no_suspension and suspend_timeout_duration are two sides of one oneof, which the API +// accepts in update_mask only under the group name; see branchOneofGroups. +var endpointOneofGroups = map[string]string{ + "no_suspension": "suspension", + "suspend_timeout_duration": "suspension", +} + func (r *ResourcePostgresEndpoint) DoUpdate(ctx context.Context, id string, config *PostgresEndpointState, entry *PlanEntry) (*PostgresEndpointRemote, error) { // Build update mask from fields that have action="update" in the changes map. // This excludes immutable fields and fields that haven't changed. // Prefix with "spec." because the API expects paths relative to the Endpoint object, // not relative to our flattened state type. - fieldPaths := collectUpdatePathsWithPrefix(entry.Changes, "spec.") + fieldPaths := collectUpdatePathsWithPrefix(entry.Changes, "spec.", endpointOneofGroups) waiter, err := r.client.Postgres.UpdateEndpoint(ctx, postgres.UpdateEndpointRequest{ Endpoint: postgres.Endpoint{ diff --git a/bundle/direct/dresources/postgres_project.go b/bundle/direct/dresources/postgres_project.go index ae9fa51ccb1..909e90cf972 100644 --- a/bundle/direct/dresources/postgres_project.go +++ b/bundle/direct/dresources/postgres_project.go @@ -136,6 +136,13 @@ func (r *ResourcePostgresProject) DoCreate(ctx context.Context, config *Postgres return remote.Name, remote, nil } +// The default endpoint settings carry the same suspension oneof as an endpoint does; +// see branchOneofGroups. +var projectOneofGroups = map[string]string{ + "default_endpoint_settings.no_suspension": "default_endpoint_settings.suspension", + "default_endpoint_settings.suspend_timeout_duration": "default_endpoint_settings.suspension", +} + func (r *ResourcePostgresProject) DoUpdate(ctx context.Context, id string, config *PostgresProjectState, entry *PlanEntry) (*PostgresProjectRemote, error) { // Build the mask from the plan's change list and prefix with "spec." (the // API expects paths relative to Project). The API rejects mask entries @@ -143,7 +150,7 @@ func (r *ResourcePostgresProject) DoUpdate(ctx context.Context, id string, confi // expands to nested attributes the body would have to set too — so we // can't use a static all-fields mask. The change list naturally tracks // what the user actually set, so the body and mask stay consistent. - fieldPaths := collectUpdatePathsWithPrefix(entry.Changes, "spec.") + fieldPaths := collectUpdatePathsWithPrefix(entry.Changes, "spec.", projectOneofGroups) // purge_on_delete is an input-only flag consulted at delete time; it is // not a spec field. Strip it from the mask so toggling it between deploys diff --git a/bundle/direct/dresources/postgres_role.go b/bundle/direct/dresources/postgres_role.go index f00921eb8c5..a0f72f29aa2 100644 --- a/bundle/direct/dresources/postgres_role.go +++ b/bundle/direct/dresources/postgres_role.go @@ -158,7 +158,7 @@ func (r *ResourcePostgresRole) DoUpdate(ctx context.Context, id string, config * // Build update mask from fields that have action="update" in the changes map. // Prefix with "spec." because the API expects paths relative to the Role // object, not relative to our flattened state type. - fieldPaths := collectUpdatePathsWithPrefix(entry.Changes, "spec.") + fieldPaths := collectUpdatePathsWithPrefix(entry.Changes, "spec.", nil) waiter, err := r.client.Postgres.UpdateRole(ctx, postgres.UpdateRoleRequest{ Name: id, diff --git a/bundle/direct/dresources/util.go b/bundle/direct/dresources/util.go index e6d4911ccc4..3b918693ebf 100644 --- a/bundle/direct/dresources/util.go +++ b/bundle/direct/dresources/util.go @@ -34,8 +34,11 @@ func shouldRetry(err error) bool { // 'spec.default_endpoint_settings.suspension' is in update_mask but not provided in // request". A bundle sends only the fields it declares, so only the leaf may be masked. // +// oneofGroups renames a change path to the group it belongs to, for fields the API only +// accepts under their oneof group name; see the per-resource maps below. +// // Sorted, so the generated update_mask does not depend on map iteration order. -func collectUpdatePathsWithPrefix(changes Changes, prefix string) []string { +func collectUpdatePathsWithPrefix(changes Changes, prefix string, oneofGroups map[string]string) []string { var paths []string for path, change := range changes { if change.Action != deployplan.Update { @@ -52,11 +55,16 @@ func collectUpdatePathsWithPrefix(changes Changes, prefix string) []string { } } if !hasChild { - paths = append(paths, prefix+maskPath(path)) + masked := maskPath(path) + if group, ok := oneofGroups[masked]; ok { + masked = group + } + paths = append(paths, prefix+masked) } } slices.Sort(paths) - // Truncating subscripts can map two changed entries of the same map onto one path. + // Truncating subscripts can map two changed entries of the same map onto one path, and + // two members of one oneof collapse onto their group. return slices.Compact(paths) } diff --git a/bundle/direct/dresources/util_test.go b/bundle/direct/dresources/util_test.go index de37675ba5e..518fa2e3cc8 100644 --- a/bundle/direct/dresources/util_test.go +++ b/bundle/direct/dresources/util_test.go @@ -33,9 +33,10 @@ func TestCollectUpdatePathsWithPrefix(t *testing.T) { skip := func() *deployplan.ChangeDesc { return &deployplan.ChangeDesc{Action: deployplan.Skip} } tests := []struct { - name string - changes Changes - want []string + name string + changes Changes + oneofGroups map[string]string + want []string }{ { name: "drops parent when a child is also updated", @@ -62,11 +63,28 @@ func TestCollectUpdatePathsWithPrefix(t *testing.T) { changes: Changes{"parent": skip()}, want: nil, }, + { + name: "renames a oneof member to its group", + changes: Changes{"ttl": upd()}, + oneofGroups: map[string]string{"ttl": "expiration"}, + want: []string{"spec.expiration"}, + }, + { + name: "collapses two members of one oneof", + changes: Changes{"ttl": upd(), "no_expiry": upd()}, + oneofGroups: map[string]string{"ttl": "expiration", "no_expiry": "expiration"}, + want: []string{"spec.expiration"}, + }, + { + name: "masks a map as a whole", + changes: Changes{"settings.pg_settings['work_mem']": upd(), "settings.pg_settings['jit']": upd()}, + want: []string{"spec.settings.pg_settings"}, + }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - assert.Equal(t, tc.want, collectUpdatePathsWithPrefix(tc.changes, "spec.")) + assert.Equal(t, tc.want, collectUpdatePathsWithPrefix(tc.changes, "spec.", tc.oneofGroups)) }) } } diff --git a/libs/testserver/postgres.go b/libs/testserver/postgres.go index 54f0610a1d4..b6067a37355 100644 --- a/libs/testserver/postgres.go +++ b/libs/testserver/postgres.go @@ -815,7 +815,7 @@ func parentPath(path string) string { // how a removal from bundle config reaches the API. Verified against a real // workspace: "Field 'spec.history_retention_duration' is in update_mask but not // provided in request". -func missingMaskedField(req Request) string { +func missingMaskedField(req Request, oneofGroups map[string][]string) string { mask := req.URL.Query().Get("update_mask") if mask == "" || len(req.Body) == 0 { return "" @@ -826,6 +826,11 @@ func missingMaskedField(req Request) string { } for path := range strings.SplitSeq(mask, ",") { path = strings.TrimSpace(path) + if _, ok := oneofGroups[path]; ok { + // A group is not a body field of its own; a member populates it instead, which + // unpopulatedOneofGroup checks. + continue + } parts := strings.Split(path, ".") if path == "" || path == "*" || len(parts) < 2 { // A whole message the request omits is tolerated: the Terraform provider @@ -875,7 +880,7 @@ func validateUpdateMask(req Request, allowed []string, oneofGroups map[string][] return &resp } // An unknown path is reported ahead of a missing one, matching the API. - if path := missingMaskedField(req); path != "" { + if path := missingMaskedField(req, oneofGroups); path != "" { resp := missingMaskedFieldResponse(path) return &resp } From c0a7054c4e7171f47f1d2b6378b2309b99ed6416 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Mon, 31 Aug 2026 16:59:03 +0200 Subject: [PATCH 2/4] Shorten the changelog entry and link the PR Co-authored-by: Isaac --- .nextchanges/bundles/postgres-oneof-update-mask.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.nextchanges/bundles/postgres-oneof-update-mask.md b/.nextchanges/bundles/postgres-oneof-update-mask.md index 390a8ee8fd5..2467a5962c5 100644 --- a/.nextchanges/bundles/postgres-oneof-update-mask.md +++ b/.nextchanges/bundles/postgres-oneof-update-mask.md @@ -1,5 +1,3 @@ -Fixed deploying a change to a Lakebase field that belongs to a oneof — +Fixed deploying a change to a Lakebase field that belongs to a oneof: `postgres_branches.expire_time` and `.ttl`, `postgres_endpoints.suspend_timeout_duration`, -and `postgres_projects.default_endpoint_settings.suspend_timeout_duration`. The update -masked each field under its own name, which the API rejects; it accepts only the oneof -group name. +and `postgres_projects.default_endpoint_settings.suspend_timeout_duration` ([#6443](https://github.com/databricks/cli/pull/6443)). From d254cd64db4f2c7a0602b88f7dbee4b8f8b828c1 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Tue, 1 Sep 2026 11:39:44 +0200 Subject: [PATCH 3/4] Simplify the changelog entry Co-authored-by: Isaac --- .nextchanges/bundles/postgres-oneof-update-mask.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.nextchanges/bundles/postgres-oneof-update-mask.md b/.nextchanges/bundles/postgres-oneof-update-mask.md index 2467a5962c5..05aa13b3695 100644 --- a/.nextchanges/bundles/postgres-oneof-update-mask.md +++ b/.nextchanges/bundles/postgres-oneof-update-mask.md @@ -1,3 +1 @@ -Fixed deploying a change to a Lakebase field that belongs to a oneof: -`postgres_branches.expire_time` and `.ttl`, `postgres_endpoints.suspend_timeout_duration`, -and `postgres_projects.default_endpoint_settings.suspend_timeout_duration` ([#6443](https://github.com/databricks/cli/pull/6443)). +direct: Fix deploying an update to `expire_time`, `ttl` or `suspend_timeout_duration` on Lakebase resources ([#6443](https://github.com/databricks/cli/pull/6443)). From e10bb5abd7815d56b75f27598a685feb8f0f2647 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Tue, 1 Sep 2026 14:18:58 +0200 Subject: [PATCH 4/4] Merge the per-engine files the fix made identical The deploy output and the post-deploy read were split per engine only because direct used to fail where terraform succeeded. Now that both apply the change they are byte identical, so they go back inline in output.txt: 16 files gone. out.requests stays split -- the mask each engine sends is what these tests are about -- and so does out.plan, which the two engines render differently. remove_suspend_timeout keeps its deploy and drift files too: direct is rejected, terraform is accepted and then ignored. Also drops four titles claiming "only terraform applies it", and rewrites remove_suspend_timeout's comment, which still blamed the oneof masking this PR fixes rather than the real reason -- the API requires a masked field to be populated. Co-authored-by: Isaac --- .../update_expire_time/out.branch.direct.txt | 17 ----------- .../out.branch.terraform.txt | 17 ----------- .../update_expire_time/out.deploy.direct.txt | 4 --- .../out.deploy.terraform.txt | 4 --- .../update_expire_time/output.txt | 25 +++++++++++++++- .../update_expire_time/script | 6 ++-- .../update_ttl/out.deploy.direct.txt | 4 --- .../update_ttl/out.deploy.terraform.txt | 4 --- .../postgres_branches/update_ttl/output.txt | 8 ++++- .../postgres_branches/update_ttl/script | 4 +-- .../out.endpoint.direct.txt | 13 --------- .../out.endpoint.terraform.txt | 13 --------- .../remove_suspend_timeout/output.txt | 15 +++++++++- .../remove_suspend_timeout/script | 12 ++++---- .../out.deploy.direct.txt | 4 --- .../out.deploy.terraform.txt | 4 --- .../out.endpoint.direct.txt | 13 --------- .../out.endpoint.terraform.txt | 13 --------- .../update_suspend_timeout/output.txt | 21 +++++++++++++- .../update_suspend_timeout/script | 18 +++++------- .../out.deploy.direct.txt | 4 --- .../out.deploy.terraform.txt | 4 --- .../out.project.direct.txt | 21 -------------- .../out.project.terraform.txt | 21 -------------- .../output.txt | 29 ++++++++++++++++++- .../update_default_endpoint_suspend/script | 6 ++-- 26 files changed, 115 insertions(+), 189 deletions(-) delete mode 100644 acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.direct.txt delete mode 100644 acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.terraform.txt delete mode 100644 acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.direct.txt delete mode 100644 acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.terraform.txt delete mode 100644 acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.direct.txt delete mode 100644 acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.terraform.txt delete mode 100644 acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.endpoint.direct.txt delete mode 100644 acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.endpoint.terraform.txt delete mode 100644 acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.direct.txt delete mode 100644 acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.terraform.txt delete mode 100644 acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.direct.txt delete mode 100644 acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.terraform.txt delete mode 100644 acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.direct.txt delete mode 100644 acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.terraform.txt delete mode 100644 acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.direct.txt delete mode 100644 acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.terraform.txt diff --git a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.direct.txt b/acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.direct.txt deleted file mode 100644 index c6bec73d4e2..00000000000 --- a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.direct.txt +++ /dev/null @@ -1,17 +0,0 @@ -{ - "branch_id": "dev-branch", - "name": "projects/test-pg-proj-[UNIQUE_NAME]/branches/dev-branch", - "parent": "projects/test-pg-proj-[UNIQUE_NAME]", - "status": { - "branch_id": "dev-branch", - "current_state": "READY", - "default": false, - "expire_time": "[EXPIRE_TIME_AFTER]", - "is_protected": false, - "source_branch": "projects/test-pg-proj-[UNIQUE_NAME]/branches/production", - "source_branch_lsn": "[LSN]", - "source_branch_time": "[TIMESTAMP]", - "state_change_time": "[TIMESTAMP]" - }, - "uid": "[BRANCH_UID]" -} diff --git a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.terraform.txt b/acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.terraform.txt deleted file mode 100644 index c6bec73d4e2..00000000000 --- a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.branch.terraform.txt +++ /dev/null @@ -1,17 +0,0 @@ -{ - "branch_id": "dev-branch", - "name": "projects/test-pg-proj-[UNIQUE_NAME]/branches/dev-branch", - "parent": "projects/test-pg-proj-[UNIQUE_NAME]", - "status": { - "branch_id": "dev-branch", - "current_state": "READY", - "default": false, - "expire_time": "[EXPIRE_TIME_AFTER]", - "is_protected": false, - "source_branch": "projects/test-pg-proj-[UNIQUE_NAME]/branches/production", - "source_branch_lsn": "[LSN]", - "source_branch_time": "[TIMESTAMP]", - "state_change_time": "[TIMESTAMP]" - }, - "uid": "[BRANCH_UID]" -} diff --git a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.direct.txt b/acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.direct.txt deleted file mode 100644 index 5d7079e4ca3..00000000000 --- a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.direct.txt +++ /dev/null @@ -1,4 +0,0 @@ -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-branch-expire-[UNIQUE_NAME]/default/files... -Updated postgres_branches.dev_branch -Files: 0 uploaded, 0 deleted -Resources: 0 created, 1 changed, 0 deleted, 1 unchanged diff --git a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.terraform.txt b/acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.terraform.txt deleted file mode 100644 index 5d7079e4ca3..00000000000 --- a/acceptance/bundle/resources/postgres_branches/update_expire_time/out.deploy.terraform.txt +++ /dev/null @@ -1,4 +0,0 @@ -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-branch-expire-[UNIQUE_NAME]/default/files... -Updated postgres_branches.dev_branch -Files: 0 uploaded, 0 deleted -Resources: 0 created, 1 changed, 0 deleted, 1 unchanged diff --git a/acceptance/bundle/resources/postgres_branches/update_expire_time/output.txt b/acceptance/bundle/resources/postgres_branches/update_expire_time/output.txt index 955fe9f4468..a87b943addc 100644 --- a/acceptance/bundle/resources/postgres_branches/update_expire_time/output.txt +++ b/acceptance/bundle/resources/postgres_branches/update_expire_time/output.txt @@ -26,7 +26,7 @@ Resources: 2 created, 0 changed, 0 deleted, 0 unchanged "uid": "[BRANCH_UID]" } -=== Change expire_time: both engines plan it, only terraform applies it +=== Change expire_time and re-deploy >>> update_file.py databricks.yml [EXPIRE_TIME_BEFORE] [EXPIRE_TIME_AFTER] >>> [CLI] bundle plan @@ -36,9 +36,32 @@ Plan: 0 to add, 1 to change, 0 to delete, 1 unchanged >>> [CLI] bundle plan -o json +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-branch-expire-[UNIQUE_NAME]/default/files... +Updated postgres_branches.dev_branch +Files: 0 uploaded, 0 deleted +Resources: 0 created, 1 changed, 0 deleted, 1 unchanged + >>> print_requests.py --del-body project_id,branch_id --sort //postgres ^//workspace-files/ ^//workspace/ ^//telemetry-ext ^//operations/ >>> [CLI] postgres get-branch projects/test-pg-proj-[UNIQUE_NAME]/branches/dev-branch +{ + "branch_id": "dev-branch", + "name": "projects/test-pg-proj-[UNIQUE_NAME]/branches/dev-branch", + "parent": "projects/test-pg-proj-[UNIQUE_NAME]", + "status": { + "branch_id": "dev-branch", + "current_state": "READY", + "default": false, + "expire_time": "[EXPIRE_TIME_AFTER]", + "is_protected": false, + "source_branch": "projects/test-pg-proj-[UNIQUE_NAME]/branches/production", + "source_branch_lsn": "[LSN]", + "source_branch_time": "[TIMESTAMP]", + "state_change_time": "[TIMESTAMP]" + }, + "uid": "[BRANCH_UID]" +} >>> [CLI] bundle destroy --auto-approve The following resources will be deleted: diff --git a/acceptance/bundle/resources/postgres_branches/update_expire_time/script b/acceptance/bundle/resources/postgres_branches/update_expire_time/script index d27c5c5c1b9..6c393dc60f0 100644 --- a/acceptance/bundle/resources/postgres_branches/update_expire_time/script +++ b/acceptance/bundle/resources/postgres_branches/update_expire_time/script @@ -13,7 +13,7 @@ trace $CLI bundle deploy rm -f out.requests.txt trace $CLI postgres get-branch "${branch_name}" | branch_fields -title "Change expire_time: both engines plan it, only terraform applies it" +title "Change expire_time and re-deploy" trace update_file.py databricks.yml "2030-01-01T00:00:00Z" "2031-06-15T12:00:00Z" # Only terraform applies it: expire_time is a member of the @@ -21,6 +21,6 @@ trace update_file.py databricks.yml "2030-01-01T00:00:00Z" "2031-06-15T12:00:00Z trace $CLI bundle plan trace $CLI bundle plan -o json | jq '.plan."resources.postgres_branches.dev_branch" | {action, changes}' > out.plan.$DATABRICKS_BUNDLE_ENGINE.json rm -f out.requests.txt -errcode $CLI bundle deploy &> out.deploy.$DATABRICKS_BUNDLE_ENGINE.txt +trace $CLI bundle deploy trace print_requests.py --del-body project_id,branch_id --sort '//postgres' '^//workspace-files/' '^//workspace/' '^//telemetry-ext' '^//operations/' > out.requests.$DATABRICKS_BUNDLE_ENGINE.json -trace $CLI postgres get-branch "${branch_name}" | branch_fields > out.branch.$DATABRICKS_BUNDLE_ENGINE.txt +trace $CLI postgres get-branch "${branch_name}" | branch_fields diff --git a/acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.direct.txt b/acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.direct.txt deleted file mode 100644 index 86be60be051..00000000000 --- a/acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.direct.txt +++ /dev/null @@ -1,4 +0,0 @@ -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-branch-ttl-[UNIQUE_NAME]/default/files... -Updated postgres_branches.dev_branch -Files: 0 uploaded, 0 deleted -Resources: 0 created, 1 changed, 0 deleted, 1 unchanged diff --git a/acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.terraform.txt b/acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.terraform.txt deleted file mode 100644 index 86be60be051..00000000000 --- a/acceptance/bundle/resources/postgres_branches/update_ttl/out.deploy.terraform.txt +++ /dev/null @@ -1,4 +0,0 @@ -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-branch-ttl-[UNIQUE_NAME]/default/files... -Updated postgres_branches.dev_branch -Files: 0 uploaded, 0 deleted -Resources: 0 created, 1 changed, 0 deleted, 1 unchanged diff --git a/acceptance/bundle/resources/postgres_branches/update_ttl/output.txt b/acceptance/bundle/resources/postgres_branches/update_ttl/output.txt index eba67020246..a0f75d30074 100644 --- a/acceptance/bundle/resources/postgres_branches/update_ttl/output.txt +++ b/acceptance/bundle/resources/postgres_branches/update_ttl/output.txt @@ -7,7 +7,7 @@ Created postgres_projects.my_project Files: 0 uploaded, 0 deleted Resources: 2 created, 0 changed, 0 deleted, 0 unchanged -=== Change ttl: both engines plan it, only terraform applies it +=== Change ttl and re-deploy >>> update_file.py databricks.yml ttl: 604800s ttl: 259200s >>> [CLI] bundle plan @@ -17,6 +17,12 @@ Plan: 0 to add, 1 to change, 0 to delete, 1 unchanged >>> [CLI] bundle plan -o json +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-branch-ttl-[UNIQUE_NAME]/default/files... +Updated postgres_branches.dev_branch +Files: 0 uploaded, 0 deleted +Resources: 0 created, 1 changed, 0 deleted, 1 unchanged + >>> print_requests.py --del-body project_id,branch_id --sort //postgres ^//workspace-files/ ^//workspace/ ^//telemetry-ext ^//operations/ >>> [CLI] bundle destroy --auto-approve diff --git a/acceptance/bundle/resources/postgres_branches/update_ttl/script b/acceptance/bundle/resources/postgres_branches/update_ttl/script index dbefd086ff3..a450a54d745 100644 --- a/acceptance/bundle/resources/postgres_branches/update_ttl/script +++ b/acceptance/bundle/resources/postgres_branches/update_ttl/script @@ -14,7 +14,7 @@ title "Initial deployment" trace $CLI bundle deploy rm -f out.requests.txt -title "Change ttl: both engines plan it, only terraform applies it" +title "Change ttl and re-deploy" trace update_file.py databricks.yml "ttl: 604800s" "ttl: 259200s" # Only terraform applies it: ttl is a member of the @@ -26,5 +26,5 @@ trace update_file.py databricks.yml "ttl: 604800s" "ttl: 259200s" trace $CLI bundle plan trace $CLI bundle plan -o json | jq '.plan."resources.postgres_branches.dev_branch" | {action, changes}' > out.plan.$DATABRICKS_BUNDLE_ENGINE.json rm -f out.requests.txt -errcode $CLI bundle deploy &> out.deploy.$DATABRICKS_BUNDLE_ENGINE.txt +trace $CLI bundle deploy trace print_requests.py --del-body project_id,branch_id --sort '//postgres' '^//workspace-files/' '^//workspace/' '^//telemetry-ext' '^//operations/' > out.requests.$DATABRICKS_BUNDLE_ENGINE.json diff --git a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.endpoint.direct.txt b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.endpoint.direct.txt deleted file mode 100644 index 3108e3da669..00000000000 --- a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.endpoint.direct.txt +++ /dev/null @@ -1,13 +0,0 @@ -{ - "endpoint_id": "my-endpoint", - "name": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint", - "parent": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main", - "uid": "[ENDPOINT_UID]", - "status": { - "endpoint_id": "my-endpoint", - "endpoint_type": "ENDPOINT_TYPE_READ_ONLY", - "autoscaling_limit_min_cu": 0.5, - "autoscaling_limit_max_cu": 8, - "suspend_timeout_duration": "300s" - } -} diff --git a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.endpoint.terraform.txt b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.endpoint.terraform.txt deleted file mode 100644 index 3108e3da669..00000000000 --- a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/out.endpoint.terraform.txt +++ /dev/null @@ -1,13 +0,0 @@ -{ - "endpoint_id": "my-endpoint", - "name": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint", - "parent": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main", - "uid": "[ENDPOINT_UID]", - "status": { - "endpoint_id": "my-endpoint", - "endpoint_type": "ENDPOINT_TYPE_READ_ONLY", - "autoscaling_limit_min_cu": 0.5, - "autoscaling_limit_max_cu": 8, - "suspend_timeout_duration": "300s" - } -} diff --git a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/output.txt b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/output.txt index d79e4a9db04..09186727f10 100644 --- a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/output.txt +++ b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/output.txt @@ -23,7 +23,7 @@ Resources: 3 created, 0 changed, 0 deleted, 0 unchanged } } -=== Remove suspend_timeout_duration: both engines plan it, only terraform applies it +=== Remove suspend_timeout_duration: neither engine can apply it >>> update_file.py databricks.yml suspend_timeout_duration: 300s >>> [CLI] bundle plan @@ -36,6 +36,19 @@ Plan: 0 to add, 1 to change, 0 to delete, 2 unchanged >>> print_requests.py --del-body project_id,branch_id,endpoint_id --sort //postgres ^//workspace-files/ ^//workspace/ ^//telemetry-ext ^//operations/ >>> [CLI] postgres get-endpoint projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint +{ + "endpoint_id": "my-endpoint", + "name": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint", + "parent": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main", + "uid": "[ENDPOINT_UID]", + "status": { + "endpoint_id": "my-endpoint", + "endpoint_type": "ENDPOINT_TYPE_READ_ONLY", + "autoscaling_limit_min_cu": 0.5, + "autoscaling_limit_max_cu": 8, + "suspend_timeout_duration": "300s" + } +} >>> [CLI] bundle plan -o json diff --git a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/script b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/script index c9e0dde0134..65696066385 100644 --- a/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/script +++ b/acceptance/bundle/resources/postgres_endpoints/remove_suspend_timeout/script @@ -13,12 +13,14 @@ trace $CLI bundle deploy rm -f out.requests.txt trace $CLI postgres get-endpoint "${endpoint_name}" | endpoint_fields -title "Remove suspend_timeout_duration: both engines plan it, only terraform applies it" +title "Remove suspend_timeout_duration: neither engine can apply it" trace update_file.py databricks.yml " suspend_timeout_duration: 300s" "" -# Both engines plan the removal, so the plan stays in output.txt. They diverge from -# the deploy on: the direct engine masks the field under its own name, which the API -# rejects because it is a member of the suspension oneof. See test.toml. +# Both engines plan the removal and neither applies it, but they fail differently, so the +# deploy and the drift it leaves stay in per-engine files. The direct engine masks +# spec.suspension with no member of that oneof in the body and the API rejects it; the +# Terraform provider masks the whole spec, which the API accepts and then ignores. See +# test.toml. trace $CLI bundle plan trace $CLI bundle plan -o json | jq '.plan."resources.postgres_endpoints.my_endpoint" | {action, changes}' > out.plan.$DATABRICKS_BUNDLE_ENGINE.json rm -f out.requests.txt @@ -28,6 +30,6 @@ trace print_requests.py --del-body project_id,branch_id,endpoint_id --sort '//po # Read the endpoint back to see whether the removal reached it, then plan again to # record the drift it leaves behind: direct still has the removal pending and will # fail again on every deploy, terraform applied it and is clean. -trace $CLI postgres get-endpoint "${endpoint_name}" | endpoint_fields > out.endpoint.$DATABRICKS_BUNDLE_ENGINE.txt +trace $CLI postgres get-endpoint "${endpoint_name}" | endpoint_fields trace $CLI bundle plan &> out.plan.drift.$DATABRICKS_BUNDLE_ENGINE.txt trace $CLI bundle plan -o json | jq '.plan."resources.postgres_endpoints.my_endpoint" | {action, changes}' > out.plan.drift.$DATABRICKS_BUNDLE_ENGINE.json diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.direct.txt b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.direct.txt deleted file mode 100644 index 8f5d94669f4..00000000000 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.direct.txt +++ /dev/null @@ -1,4 +0,0 @@ -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-endpoint-suspend-[UNIQUE_NAME]/default/files... -Updated postgres_endpoints.my_endpoint -Files: 0 uploaded, 0 deleted -Resources: 0 created, 1 changed, 0 deleted, 2 unchanged diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.terraform.txt b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.terraform.txt deleted file mode 100644 index 8f5d94669f4..00000000000 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.deploy.terraform.txt +++ /dev/null @@ -1,4 +0,0 @@ -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-endpoint-suspend-[UNIQUE_NAME]/default/files... -Updated postgres_endpoints.my_endpoint -Files: 0 uploaded, 0 deleted -Resources: 0 created, 1 changed, 0 deleted, 2 unchanged diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.direct.txt b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.direct.txt deleted file mode 100644 index 1703715e87e..00000000000 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.direct.txt +++ /dev/null @@ -1,13 +0,0 @@ -{ - "endpoint_id": "my-endpoint", - "name": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint", - "parent": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main", - "uid": "[ENDPOINT_UID]", - "status": { - "endpoint_id": "my-endpoint", - "endpoint_type": "ENDPOINT_TYPE_READ_ONLY", - "autoscaling_limit_min_cu": 0.5, - "autoscaling_limit_max_cu": 8, - "suspend_timeout_duration": "600s" - } -} diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.terraform.txt b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.terraform.txt deleted file mode 100644 index 1703715e87e..00000000000 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/out.endpoint.terraform.txt +++ /dev/null @@ -1,13 +0,0 @@ -{ - "endpoint_id": "my-endpoint", - "name": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint", - "parent": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main", - "uid": "[ENDPOINT_UID]", - "status": { - "endpoint_id": "my-endpoint", - "endpoint_type": "ENDPOINT_TYPE_READ_ONLY", - "autoscaling_limit_min_cu": 0.5, - "autoscaling_limit_max_cu": 8, - "suspend_timeout_duration": "600s" - } -} diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/output.txt b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/output.txt index b9a69e36f24..68c0c87cbbb 100644 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/output.txt +++ b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/output.txt @@ -26,7 +26,7 @@ Resources: 3 created, 0 changed, 0 deleted, 0 unchanged === Change suspend_timeout_duration to 600s >>> update_file.py databricks.yml suspend_timeout_duration: 300s suspend_timeout_duration: 600s -=== Plan and deploy: both engines plan it, only terraform applies it +=== Plan and deploy >>> [CLI] bundle plan update postgres_endpoints.my_endpoint @@ -34,9 +34,28 @@ Plan: 0 to add, 1 to change, 0 to delete, 2 unchanged >>> [CLI] bundle plan -o json +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-endpoint-suspend-[UNIQUE_NAME]/default/files... +Updated postgres_endpoints.my_endpoint +Files: 0 uploaded, 0 deleted +Resources: 0 created, 1 changed, 0 deleted, 2 unchanged + >>> print_requests.py --del-body project_id,branch_id,endpoint_id --sort //postgres ^//workspace-files/ ^//workspace/ ^//telemetry-ext ^//operations/ >>> [CLI] postgres get-endpoint projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint +{ + "endpoint_id": "my-endpoint", + "name": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main/endpoints/my-endpoint", + "parent": "projects/test-pg-proj-[UNIQUE_NAME]/branches/main", + "uid": "[ENDPOINT_UID]", + "status": { + "endpoint_id": "my-endpoint", + "endpoint_type": "ENDPOINT_TYPE_READ_ONLY", + "autoscaling_limit_min_cu": 0.5, + "autoscaling_limit_max_cu": 8, + "suspend_timeout_duration": "600s" + } +} >>> [CLI] bundle destroy --auto-approve The following resources will be deleted: diff --git a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/script b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/script index 4617f21697e..2f383859007 100644 --- a/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/script +++ b/acceptance/bundle/resources/postgres_endpoints/update_suspend_timeout/script @@ -21,20 +21,16 @@ trace $CLI postgres get-endpoint "${endpoint_name}" | endpoint_fields title "Change suspend_timeout_duration to 600s" trace update_file.py databricks.yml "suspend_timeout_duration: 300s" "suspend_timeout_duration: 600s" -title "Plan and deploy: both engines plan it, only terraform applies it" - -# Both engines plan the same change, so the plan stays in output.txt. They -# diverge from the deploy on, so those steps go to per-engine files. -# Both plan the update. Only terraform applies it: the direct engine builds -# update_mask from the plan's change paths and sends spec.suspend_timeout_duration, -# which the API rejects because that field is a member of the suspension oneof and -# only the group name spec.suspension is accepted. See test.toml. +title "Plan and deploy" + +# Both engines apply the change; only the mask they send differs, so out.requests +# is the one per-engine file left. trace $CLI bundle plan trace $CLI bundle plan -o json | jq '.plan."resources.postgres_endpoints.my_endpoint" | {action, changes}' > out.plan.$DATABRICKS_BUNDLE_ENGINE.json rm -f out.requests.txt -errcode $CLI bundle deploy &> out.deploy.$DATABRICKS_BUNDLE_ENGINE.txt +trace $CLI bundle deploy -# The update_mask each engine sends is the whole point of the divergence. +# The update_mask each engine sends is the whole point of this test. trace print_requests.py --del-body project_id,branch_id,endpoint_id --sort '//postgres' '^//workspace-files/' '^//workspace/' '^//telemetry-ext' '^//operations/' > out.requests.$DATABRICKS_BUNDLE_ENGINE.json -trace $CLI postgres get-endpoint "${endpoint_name}" | endpoint_fields > out.endpoint.$DATABRICKS_BUNDLE_ENGINE.txt +trace $CLI postgres get-endpoint "${endpoint_name}" | endpoint_fields diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.direct.txt b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.direct.txt deleted file mode 100644 index 39f7b28edfd..00000000000 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.direct.txt +++ /dev/null @@ -1,4 +0,0 @@ -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-project-default-suspend-[UNIQUE_NAME]/default/files... -Updated postgres_projects.my_project -Files: 0 uploaded, 0 deleted -Resources: 0 created, 1 changed, 0 deleted, 0 unchanged diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.terraform.txt b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.terraform.txt deleted file mode 100644 index 39f7b28edfd..00000000000 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.deploy.terraform.txt +++ /dev/null @@ -1,4 +0,0 @@ -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-project-default-suspend-[UNIQUE_NAME]/default/files... -Updated postgres_projects.my_project -Files: 0 uploaded, 0 deleted -Resources: 0 created, 1 changed, 0 deleted, 0 unchanged diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.direct.txt b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.direct.txt deleted file mode 100644 index 4337bc5b199..00000000000 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.direct.txt +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "projects/test-pg-proj-[UNIQUE_NAME]", - "project_id": "test-pg-proj-[UNIQUE_NAME]", - "status": { - "branch_logical_size_limit_bytes": [NUMID], - "default_branch": "projects/test-pg-proj-[UNIQUE_NAME]/branches/production", - "default_endpoint_settings": { - "autoscaling_limit_max_cu": 4, - "autoscaling_limit_min_cu": 0.5, - "suspend_timeout_duration": "600s" - }, - "display_name": "Test Project for Default Endpoint Suspend Update", - "enable_pg_native_login": false, - "history_retention_duration": "604800s", - "owner": "[USERNAME]", - "pg_version": 16, - "project_id": "test-pg-proj-[UNIQUE_NAME]", - "synthetic_storage_size_bytes": 0 - }, - "uid": "[UUID]" -} diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.terraform.txt b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.terraform.txt deleted file mode 100644 index 4337bc5b199..00000000000 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/out.project.terraform.txt +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "projects/test-pg-proj-[UNIQUE_NAME]", - "project_id": "test-pg-proj-[UNIQUE_NAME]", - "status": { - "branch_logical_size_limit_bytes": [NUMID], - "default_branch": "projects/test-pg-proj-[UNIQUE_NAME]/branches/production", - "default_endpoint_settings": { - "autoscaling_limit_max_cu": 4, - "autoscaling_limit_min_cu": 0.5, - "suspend_timeout_duration": "600s" - }, - "display_name": "Test Project for Default Endpoint Suspend Update", - "enable_pg_native_login": false, - "history_retention_duration": "604800s", - "owner": "[USERNAME]", - "pg_version": 16, - "project_id": "test-pg-proj-[UNIQUE_NAME]", - "synthetic_storage_size_bytes": 0 - }, - "uid": "[UUID]" -} diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/output.txt b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/output.txt index 5bc3d0207d7..fe37d6db91d 100644 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/output.txt +++ b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/output.txt @@ -29,7 +29,7 @@ Resources: 1 created, 0 changed, 0 deleted, 0 unchanged "uid": "[UUID]" } -=== Change default_endpoint_settings.suspend_timeout_duration: both engines plan it, only terraform applies it +=== Change default_endpoint_settings.suspend_timeout_duration and re-deploy >>> update_file.py databricks.yml suspend_timeout_duration: 300s suspend_timeout_duration: 600s >>> [CLI] bundle plan @@ -39,9 +39,36 @@ Plan: 0 to add, 1 to change, 0 to delete, 0 unchanged >>> [CLI] bundle plan -o json +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/update-postgres-project-default-suspend-[UNIQUE_NAME]/default/files... +Updated postgres_projects.my_project +Files: 0 uploaded, 0 deleted +Resources: 0 created, 1 changed, 0 deleted, 0 unchanged + >>> print_requests.py --del-body project_id --sort //postgres ^//workspace-files/ ^//workspace/ ^//telemetry-ext ^//operations/ >>> [CLI] postgres get-project projects/test-pg-proj-[UNIQUE_NAME] +{ + "name": "projects/test-pg-proj-[UNIQUE_NAME]", + "project_id": "test-pg-proj-[UNIQUE_NAME]", + "status": { + "branch_logical_size_limit_bytes": [NUMID], + "default_branch": "projects/test-pg-proj-[UNIQUE_NAME]/branches/production", + "default_endpoint_settings": { + "autoscaling_limit_max_cu": 4, + "autoscaling_limit_min_cu": 0.5, + "suspend_timeout_duration": "600s" + }, + "display_name": "Test Project for Default Endpoint Suspend Update", + "enable_pg_native_login": false, + "history_retention_duration": "604800s", + "owner": "[USERNAME]", + "pg_version": 16, + "project_id": "test-pg-proj-[UNIQUE_NAME]", + "synthetic_storage_size_bytes": 0 + }, + "uid": "[UUID]" +} >>> [CLI] bundle destroy --auto-approve The following resources will be deleted: diff --git a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/script b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/script index 4f09ca25905..574a6cf5301 100644 --- a/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/script +++ b/acceptance/bundle/resources/postgres_projects/update_default_endpoint_suspend/script @@ -18,7 +18,7 @@ trace $CLI bundle deploy rm -f out.requests.txt trace $CLI postgres get-project "${project_name}" | project_fields -title "Change default_endpoint_settings.suspend_timeout_duration: both engines plan it, only terraform applies it" +title "Change default_endpoint_settings.suspend_timeout_duration and re-deploy" trace update_file.py databricks.yml "suspend_timeout_duration: 300s" "suspend_timeout_duration: 600s" # Only terraform applies it: suspend_timeout_duration is a @@ -27,6 +27,6 @@ trace update_file.py databricks.yml "suspend_timeout_duration: 300s" "suspend_ti trace $CLI bundle plan trace $CLI bundle plan -o json | jq '.plan."resources.postgres_projects.my_project" | {action, changes}' > out.plan.$DATABRICKS_BUNDLE_ENGINE.json rm -f out.requests.txt -errcode $CLI bundle deploy &> out.deploy.$DATABRICKS_BUNDLE_ENGINE.txt +trace $CLI bundle deploy trace print_requests.py --del-body project_id --sort '//postgres' '^//workspace-files/' '^//workspace/' '^//telemetry-ext' '^//operations/' > out.requests.$DATABRICKS_BUNDLE_ENGINE.json -trace $CLI postgres get-project "${project_name}" | project_fields > out.project.$DATABRICKS_BUNDLE_ENGINE.txt +trace $CLI postgres get-project "${project_name}" | project_fields