8000 Terraform conformance test, UC grants, workspace-admin belt, legacy SQL by dmux · Pull Request #19 · dmux/minilake · GitHub
[go: up one dir, main page]

Skip to content

Terraform conformance test, UC grants, workspace-admin belt, legacy SQL - #19

Merged
dmux merged 1 commit into
mainfrom
feat/terraform-conformance-and-api-gaps
Sep 15, 2026
Merged

dmux merged 1 commit into
mainfrom
feat/terraform-conformance-and-api-gaps

Conversation

@dmux
@dmux dmux commented Sep 15, 2026
Copy link
Copy Markdown
Owner

Follow-up to #17 and #18, and a change of measure.

Coverage: 17.8% → 22.9% of the endpoints the databricks-sdk calls (208 → 267).
CLI command groups working end to end: 21 → 30.

First: the headline number was misleading, including in my own roadmap

604 of the "missing" endpoints are in blocks this project has deliberately decided not
to emulate — MLflow, the Account API, identity v2, marketplace, Genie, Lakebase, vector
search, serving, clean rooms, apps. Counting those as gaps makes progress look
permanently hopeless.

Against the reachable surface, coverage is 267 of 564 — about 47%. The roadmap
now leads with that and says why.

The main event: Terraform is now tested, not asserted

docs/terraform.md promised the provider worked against minilake. Nothing verified
it
— there was no Terraform test anywhere in the repo, and the services I added in #17
(SCIM, tokens, policies, pools) were specifically Terraform-facing resources I had no
way to check.

tests/terraform/ now runs the real provider through apply → plan → destroy over
a 15-resource config, asserting the second plan is empty. terraform and a pinned
provider mirror are baked into Dockerfile.test, so the suite still needs no network.

Its first run found three defects that every SDK-driven test in the suite had missed,
because they live in behaviour only the provider exercises:

Defect Why no SDK test caught it
The provider posts "entitlements": [{}] for a group with none; minilake echoed the empty entry back and broke the provider on its own input (Invalid address to set: []string{""}) The SDK never sends [{}]. Real Databricks drops valueless entries from multi-valued SCIM attributes; now so does minilake
SQL warehouses never reported auto_stop_mins, enable_photon, max_num_clusters or odbc_params, so every terraform plan showed a permanent in-place update The SDK reads back only what it asked about; Terraform diffs the whole object
SCIM ignored the attributes projection the provider requests The SDK does not send it

Permanent drift is worse than a 501 — it looks like it works until someone runs plan
twice. That is exactly what the empty-plan assertion is for, and why it is the sharp
assertion in that file rather than the resource-by-resource ones.

New endpoints

  • UC grants (w.grants.*, databricks_grants) with real inheritance: a grant
    on a catalog is effective on its schemas and tables, tagged with the ancestor it came
    from. Without that, get_effective would just be get under another name — worse
    than not implementing it, because it would look right while hiding the one behaviour
    it exists for.
  • The workspace-admin belt — git credentials, IP access lists, global init scripts,
    notification destinations, instance profiles, workspace-conf. Individually dull;
    collectively what a realistic terraform apply touches before it reaches anything
    interesting, where one 501 fails the whole plan.
  • Legacy /api/2.0/preview/sql/* as adapters over the modern stores, not a
    second copy: an object created through either surface is visible and editable from
    the other. A separate implementation would have passed every single-surface test and
    still been wrong.

Three things 8000 that look like details and are not

The legacy list endpoints must paginate. The SDK walks them by incrementing page
until a response comes back empty. A handler that ignores the parameter and returns
everything never terminates — the symptom is a hung test suite, not a failing one.

DELETE trashes and POST .../trash/{id} restores, not the other way round. I had
it backwards first; implemented that way, a client asking to restore would destroy.

The SDK sends securable_type as an Enum that is not a str subclass, so the
wire carries SecurableType.CATALOG, not CATALOG. My local smoke test passed a plain
string and hid this; the Docker run caught it as three silent failures — grants stored
under an unrecognised key, inheritance finding nothing, validation skipped. Both forms
are now accepted.

What this does not give you

Nothing added here is enforced. Grants, secret ACLs, IP access lists and cluster
policies are stored and read back faithfully and checked nowhere; no IP is blocked, no
init script runs, no notification is sent. A terraform plan that applies cleanly
against minilake says the shape of your config is right, not that its access control
is. docs/terraform.md now says this explicitly, because a table of working resources
invites the opposite inference.

Also: a bug in my own coverage harness

It scored all 8 Files API endpoints as missing — they are implemented and tested. The
SDK writes /api/2.0/fs/files{path} with the parameter carrying its own leading slash,
and my normalizer produced fs/files__probe__, matching no route. Those two paths are
the only ones in the SDK shaped that way. Fixed, and docs/CLI_COVERAGE.md regenerated.

Testing

378 passing, up from 338. Docker suite green, ruff clean.

docker compose -f docker-compose.test.yml build
docker compose -f docker-compose.test.yml up --abort-on-container-exit --exit-code-from test-runner
docker compose -f docker-compose.test.yml down -v

Running pytest on the host without terraform installed skips the conformance tests
rather than failing.

…acy SQL

Coverage 17.8% -> 22.9% of the endpoints the databricks-sdk calls (208 -> 267).
CLI command groups working end to end: 21 -> 30.

The headline number understates things, and the roadmap now says so: 604 of
the missing endpoints are in blocks this project deliberately skips (MLflow,
Account API, identity v2, marketplace, Genie, Lakebase, vector search,
serving, clean rooms, apps). Against the reachable surface it is 267/564,
about 47%.

Terraform conformance
---------------------
docs/terraform.md promised the provider worked against minilake. Nothing
verified it. tests/terraform/ now runs the real provider through
apply -> plan -> destroy over a 15-resource config, asserting the second plan
is empty, with terraform and a pinned provider mirror baked into
Dockerfile.test so the suite still needs no network.

Its first run found three defects every SDK-driven test had missed, because
they are in behaviour only the provider exercises:

- The provider posts `"entitlements": [{}]` for a group with none. minilake
  echoed the empty entry back and broke the provider on its own input
  (`Invalid address to set: []string{""}`). Real Databricks drops valueless
  entries from multi-valued SCIM attributes; now so does minilake.
- SQL warehouses never reported auto_stop_mins, enable_photon,
  max_num_clusters or odbc_params, so every `terraform plan` showed a
  permanent in-place update. They are now stored and returned with the real
  API's defaults. None of them changes how a statement executes.
- SCIM ignored the `attributes` projection the provider asks for.

Permanent drift is worse than a 501: it looks like it works until someone
runs plan twice. That is what the empty-plan assertion is for.

New endpoints
-------------
- UC grants (w.grants.*, databricks_grants) with real inheritance: a grant on
  a catalog is effective on its schemas and tables, tagged with its source.
  Without that, get_effective would just be get under another name.
- The workspace-admin belt: git credentials, IP access lists, global init
  scripts, notification destinations, instance profiles, workspace-conf.
  Individually dull, collectively what a terraform apply hits before it
  reaches anything interesting.
- Legacy /api/2.0/preview/sql/*, as adapters over the modern stores rather
  than a second copy — an object created through either surface is visible
  from the other. Includes the operator translation (a legacy ">" that
  reached the evaluator untranslated would leave an alert that never fires)
  and the correct trash semantics: DELETE trashes, POST .../trash/{id}
  restores.

Legacy list endpoints are page-numbered because they have to be: the SDK
walks them by incrementing `page` until a response comes back empty, so a
handler that ignores the parameter never terminates.

Nothing added here is enforced. Grants, secret ACLs, IP access lists and
cluster policies are stored and read back faithfully and checked nowhere. A
terraform plan that applies cleanly says the shape of a config is right, not
that its access control is.

Coverage harness fix
--------------------
It scored all 8 Files API endpoints as missing. The SDK writes
/api/2.0/fs/files{path} with the parameter carrying its own leading slash,
and the normalizer produced a path matching no route. Those two paths are the
only ones in the SDK shaped that way.

Tests: 378 passing, up from 338.
@dmux dmux self-assigned this Sep 15, 2026
@dmux dmux added the enhancement New feature or request label Sep 15, 2026
@dmux
dmux commented Sep 15, 2026
Copy link
Copy Markdown
Owner Author

LGTM! 🚀

A002
@dmux
dmux merged commit 9684a37 into main Sep 15, 2026
3 checks passed
@dmux
dmux deleted the feat/terraform-conformance-and-api-gaps branch September 30, 2026 01:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0