Skip to content

[WIP] postgres roles#5467

Draft
janniklasrose wants to merge 9 commits into
mainfrom
postgres-roles
Draft

[WIP] postgres roles#5467
janniklasrose wants to merge 9 commits into
mainfrom
postgres-roles

Conversation

@janniklasrose
Copy link
Copy Markdown
Contributor

Changes

Why

Tests

pietern and others added 9 commits May 19, 2026 11:23
Adds DAB support for Lakebase Postgres roles, mirroring the existing
postgres_databases resource. The state holds role_id and parent
separately (so bundle variable references resolve), and RemapState
recovers role_id from remote.Name via a local strings.TrimPrefix —
no shared parser helper. recreate_on_changes fires on either field
since both are part of the immutable hierarchical name.

Also fixes collectUpdatePathsWithPrefix to drop a parent path when a
more specific child path is present; the real Postgres API rejects an
update_mask that contains both (e.g. spec.attributes plus
spec.attributes.createdb), expecting all sibling fields when the
parent is named.

Tested end-to-end against AWS prod (basic, recreate, update, bind) as
well as the invariant suite.

Co-authored-by: Isaac
Two follow-ups to the postgres_roles resource:

- Regenerate required-field validation so role_id is required alongside
  parent, matching the JSON schema (jsonschema.json already lists both
  under required). Without this, bundle validate accepted a role config
  missing role_id and the failure only surfaced during deploy.
- In PostgresRole.Exists, recognize 404 via apierr.IsMissing and return
  (false, nil) so bundle deployment bind reports the user-friendly
  "postgres_role ... is not found" path instead of a generic fetch
  error.

Co-authored-by: Isaac
Missed alongside required_fields in the previous commit. Same
generator run, just the second output file.

Co-authored-by: Isaac
Previously logged "does not exist" for any GetRole error, including
transient failures, before checking apierr.IsMissing. Flip the order
so the debug message only fires when the role is genuinely absent.

Co-authored-by: Isaac
The SDK's RoleRoleStatus already carries role_id; use it directly
instead of stripping the "<parent>/roles/" prefix from remote.Name.
Matches the catalog convention (Status.CatalogId) and avoids a
local string parse.

Co-authored-by: Isaac
# Conflicts:
#	NEXT_CHANGELOG.md
#	acceptance/bundle/invariant/continue_293/out.test.toml
#	acceptance/bundle/invariant/migrate/out.test.toml
#	acceptance/bundle/invariant/no_drift/out.test.toml
#	acceptance/bundle/invariant/test.toml
#	acceptance/bundle/refschema/out.fields.txt
#	bundle/config/mutator/resourcemutator/apply_bundle_permissions_test.go
#	bundle/config/mutator/resourcemutator/apply_target_mode_test.go
#	bundle/config/mutator/resourcemutator/run_as_test.go
#	bundle/config/resources.go
#	bundle/config/resources_test.go
#	bundle/deploy/terraform/interpolate.go
#	bundle/deploy/terraform/pkg.go
#	bundle/deploy/terraform/util.go
#	bundle/direct/dresources/all.go
#	bundle/direct/dresources/apitypes.generated.yml
#	bundle/direct/dresources/apitypes.yml
#	bundle/direct/dresources/resources.generated.yml
#	bundle/direct/dresources/util.go
#	bundle/internal/schema/annotations.yml
#	bundle/internal/validation/generated/enum_fields.go
#	bundle/internal/validation/generated/required_fields.go
#	bundle/schema/jsonschema.json
#	bundle/schema/jsonschema_for_docs.json
#	bundle/statemgmt/state_load_test.go
#	libs/testserver/fake_workspace.go
#	libs/testserver/handlers.go
#	libs/testserver/postgres.go
…ate-only

Live testing showed the PATCH update_mask only accepts spec.attributes
and spec.membership_roles; the backend rejects spec.postgres_role,
spec.auth_method, and spec.identity_type with 400 INVALID_PARAMETER_VALUE
"Unknown field path in update_mask". Without declaring these as
recreate_on_changes:

- direct engine: deploy fails on PATCH and re-plan loops on the same
  "1 to change" forever
- terraform engine: silently no-ops the change (state records new value,
  remote keeps old, GET returns no spec → invisible divergence)

These spec fields aren't marked immutable in the OpenAPI definition,
so the generator can't pick them up — declare them in the manual
resources.yml until upstream is fixed.

Adds an acceptance test that toggles postgres_role and confirms the
plan recreates instead of patching. Restricted to the direct engine
because the terraform provider still treats the field as updateable
and would silently diverge from the bundle.

Co-authored-by: Isaac
@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

Commit: ee1eb81

Run: 27133419925

Env 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
💚​ aws linux 7 15 261 928 6:04
🔄​ aws windows 2 7 15 261 926 9:35
💚​ aws-ucws linux 7 15 357 842 7:35
💚​ aws-ucws windows 7 15 359 840 9:45
💚​ azure linux 1 17 264 926 5:55
🔄​ azure windows 3 17 264 924 7:52
🔄​ azure-ucws linux 1 1 17 361 838 9:31
💚​ azure-ucws windows 1 17 364 836 10:05
💚​ gcp linux 1 17 260 929 6:43
💚​ gcp windows 1 17 262 927 10:10
27 interesting tests: 15 SKIP, 6 flaky, 6 RECOVERED
Test Name aws linux aws windows aws-ucws linux aws-ucws windows azure linux azure windows azure-ucws linux azure-ucws windows gcp linux gcp windows
🔄​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R 💚​R 💚​R
🔄​ TestAccept/bundle/destroy/jobs-and-pipeline ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/destroy/jobs-and-pipeline/DATABRICKS_BUNDLE_ENGINE=direct ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🙈​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/permissions 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions 💚​R 💚​R 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=direct 💚​R 💚​R 💚​R 💚​R
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R 💚​R 💚​R
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions 💚​R 💚​R 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct 💚​R 💚​R 💚​R 💚​R
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/resources/postgres_branches/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/replace_existing 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/update_protected 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/without_branch_id 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_endpoints/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_endpoints/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_projects/update_display_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/synced_database_tables/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/grants/select 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestAccept/selftest/record_cloud/pipeline-crud/DATABRICKS_BUNDLE_ENGINE=direct ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p
🔄​ TestAccept/selftest/record_cloud/pipeline-crud/DATABRICKS_BUNDLE_ENGINE=terraform ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestFetchRepositoryInfoAPI_FromRepo ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
Top 23 slowest tests (at least 2 minutes):
duration env testname
4:38 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
4:31 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
4:24 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
4:19 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
4:12 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:36 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:33 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:16 gcp windows TestAccept
3:14 aws-ucws windows TestAccept
3:10 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:07 azure-ucws windows TestAccept
2:50 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:50 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:50 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:48 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:47 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:47 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:43 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:40 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:39 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:34 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:34 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:28 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants