Skip to content

Fix spurious grants create for empty grants list on direct engine - #6039

Open
radakam wants to merge 6 commits into
mainfrom
fix-empty-grants-migrate
Open

Fix spurious grants create for empty grants list on direct engine#6039
radakam wants to merge 6 commits into
mainfrom
fix-empty-grants-migrate

Conversation

@radakam

@radakam radakam commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Changes

Add an optional SkipCreate method to the direct engine's IResource: a resource can report that a given desired state needs no create at all, and makePlan then omits the node instead of planning one. ResourceGrants implements it for an empty grants list.

The planner only consults it for nodes with no state entry. A node that already has state keeps its plan entry, so emptying a previously deployed grants: list still plans the revoke — dropping it there would move the node to the delete branch, where grants' deliberately no-op DoDelete would silently skip the revoke.

Why

Terraform writes no databricks_grants resource for an empty grants list, so bundle deployment migrate records no state for the grants node. But makePlan emitted a node for every grants config unconditionally, so bundle plan showed a spurious grants -> create, contradicting migrate's "no actions planned".

Permissions avoid this because an empty permissions: [] either drops the node or defaults to a real IS_OWNER resource. Grants have no default owner, so the Terraform-faithful behavior for an empty list is a no-op.

Found by fuzz testing.

Tests

  • Re-enables the schema_empty_grants migrate invariant (added in acc: add empty-grants invariant config, disable failing migrate variant #6055, previously excluded pending this fix). Verified it fails without the fix (Unexpected action='create' for resources.schemas.foo.grants) and passes with it.
  • Unit tests in grants_test.go for the empty, unset, and populated cases, plus a resource that doesn't implement SkipCreate. They call through the adapter so the optional-method discovery and type validation are covered too.

@radakam
radakam marked this pull request as ready for review July 23, 2026 13:14
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approval status: pending

/acceptance/bundle/ - needs approval

Files: acceptance/bundle/invariant/migrate/out.test.toml, acceptance/bundle/invariant/migrate/test.toml
Suggested: @denik
Also eligible: @janniklasrose, @pietern, @andrewnester, @shreyas-goenka, @lennartkats-db, @anton-107

/bundle/ - needs approval

5 files changed
Suggested: @denik
Also eligible: @janniklasrose, @pietern, @andrewnester, @shreyas-goenka, @lennartkats-db, @anton-107

General files (require maintainer)

Files: .nextchanges/bundles/empty-grants-migrate.md
Based on git history:

  • @denik -- recent work in bundle/direct/, bundle/direct/dresources/, .nextchanges/bundles/

Any maintainer (@andrewnester, @anton-107, @denik, @pietern, @shreyas-goenka, @simonfaltum, @renaudhartert-db, @janniklasrose, @lennartkats-db) can approve all areas.
See OWNERS for ownership rules.

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 98822e4

Run: 30336264517

Env 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
💚​ aws linux 4 4 349 1061 6:20
💚​ aws windows 4 4 351 1059 9:22
💚​ azure linux 4 4 349 1060 6:11
💚​ azure windows 4 4 351 1058 7:06
💚​ gcp linux 1 5 348 1062 6:00
💚​ gcp windows 1 5 350 1060 10:00
8 interesting tests: 4 RECOVERED, 4 SKIP
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo 💚​R 💚​R 💚​R 💚​R 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo/root 💚​R 💚​R 💚​R 💚​R
💚​ TestFetchRepositoryInfoAPI_FromRepo/subdir 💚​R 💚​R 💚​R 💚​R
Top 6 slowest tests (at least 2 minutes):
duration env testname
6:12 gcp windows TestAccept
5:11 aws windows TestAccept
3:08 azure windows TestAccept
2:54 aws linux TestAccept
2:48 azure linux TestAccept
2:48 gcp linux TestAccept

@radakam
radakam force-pushed the fix-empty-grants-migrate branch 2 times, most recently from 0c35ccb to 61002e0 Compare July 24, 2026 08:08
radakam added 3 commits July 24, 2026 08:16
An empty grants: [] list produced no databricks_grants resource in
terraform state, so bundle deployment migrate wrote no grants entry.
The direct engine's makePlan then always emitted a plan node for the
grants config node, so bundle plan showed a spurious 'create' for the
empty grants node -- contradicting migrate's 'no actions planned'.

Skip an empty grants node in makePlan when there is no existing state
entry. When a state entry exists (grants were deployed and are now being
emptied), the node is still emitted so the revoke is planned.
With the direct-engine fix in place, the migrate invariant no longer shows a
spurious grants -> create for an empty grants: [] list, so remove the
no_empty_grants exclude added by the invariant-config PR and regenerate the
migrate matrix. This is the variant the fuzz-found config was disabled for.
@radakam
radakam force-pushed the fix-empty-grants-migrate branch from 61002e0 to 5a47a08 Compare July 24, 2026 08:18
denik added a commit that referenced this pull request Jul 24, 2026
grants: [] triggers a spurious grants update when the plan is computed from
saved state rather than a live remote read (config has a non-nil empty slice,
state persists none). --planmode=offline hits the same known direct-engine bug
that migrate already excludes this config for (fixed by #6039). Exclude the
offline variant until that lands, mirroring migrate/test.toml.

Co-authored-by: Isaac
denik added a commit that referenced this pull request Jul 24, 2026
grants: [] triggers a spurious grants update when the plan is computed from
saved state rather than a live remote read (config has a non-nil empty slice,
state persists none). --planmode=offline hits the same known direct-engine bug
that migrate already excludes this config for (fixed by #6039). Exclude the
offline variant until that lands, mirroring migrate/test.toml.

Co-authored-by: Isaac
Comment thread bundle/direct/bundle_plan.go Outdated
denik added a commit that referenced this pull request Jul 24, 2026
grants: [] triggers a spurious grants update when the plan is computed from
saved state rather than a live remote read (config has a non-nil empty slice,
state persists none). --planmode=offline hits the same known direct-engine bug
that migrate already excludes this config for (fixed by #6039). Exclude the
offline variant until that lands, mirroring migrate/test.toml.

Co-authored-by: Isaac
radakam added 3 commits July 27, 2026 07:05
The planner asserted on *dresources.GrantsState directly to detect an empty
grants list. Add an optional SkipCreate method to IResource so the predicate
lives with the resource, and have makePlan consult it through the adapter.

The state lookup stays in the planner: a node that already has state must keep
its plan entry even when creating it would be a no-op, otherwise it falls into
the delete branch and grants' no-op DoDelete would silently stop revoking.
…grants-migrate

# Conflicts:
#	bundle/direct/dresources/grants_test.go
@radakam
radakam requested a review from denik July 28, 2026 07:02
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