Skip to content

feat(servicedirectory): add Namespace, Service and Endpoint - #165

Merged
naxty merged 4 commits into
mainfrom
naxty/gcpBatchResources2
Aug 31, 2026
Merged

feat(servicedirectory): add Namespace, Service and Endpoint#165
naxty merged 4 commits into
mainfrom
naxty/gcpBatchResources2

Conversation

@naxty

@naxty naxty commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Adds GCP Service Directory — all three types its v1 API has.

Type Result
GCP::ServiceDirectory::Namespace crud 8/8, discovery 4/4
GCP::ServiceDirectory::Service crud 8/8, discovery 4/4
GCP::ServiceDirectory::Endpoint crud 8/8, discovery 4/4

A namespace contains services; a service contains the endpoints a resolve call
actually returns. All three are free, instant and location-scoped, and deleting
a namespace deletes everything under it.

Every case was run twice against europe-central2: once on released formae
(0.89.0) and once on a binary built from formae main, which additionally
requires an extracted forma to re-apply as a zero-operation simulate. Both
phases were also run back-to-back under one fixed FORMAE_TEST_RUN_ID, the way
CI runs them, to confirm the prerequisite namespace surviving Destroy does not
collide with the discovery phase.

"8/8" is 7 passed and Replace skipped — there is no -replace fixture, the same
as every other case in the repo.

Notes for review

No wildcard at any level. Discovery lists with no properties, so a nested
resource can name no parent to look in. Service Directory rejects a wildcard for
every segment — locations/- answers "Unsupported location", namespaces/-
answers "Could not parse namespace name" — so services and endpoints are
discovered by walking the collections above them, following nextPageToken at
each level.

The walk is registered from the package init in resources.go, not from an
init in list.go: Go runs init functions in filename order and list.go
sorts first, so an override registered there would be silently replaced by the
generic registration.

Endpoints sit two collections deep, which the config-driven engine could not
express. base.ParentResourceConfig gains GrandParentType /
GrandParentPropertyName. Read, update and delete rebuild the whole path from
the native ID, so create was the one operation with nothing but the declared
properties to route with; it now carries the grandparent in
PathContext.CustomSegments[0].

port comes back as a JSON number, not a string, so no toString. A unit
test pins that — stringifying it would make a correct endpoint plan an update.

clean-environment.sh sweeps leftover namespaces. The service and endpoint
fixtures build one as a prerequisite and conformance Destroy only removes the
resource under test. --filter is server-side for
gcloud service-directory namespaces list and Service Directory rejects the ~
operator, so the prefix is matched with grep. List and delete were both run
against the live project.

What I could not verify

  • No -replace.pkl fixtures, matching the rest of the repo.
  • No ci.yml / nightly.yml timeout entries: the slowest case is 54s end to
    end, well inside the default.
  • An earlier revision of this PR also changed which conformance cases run per
    trigger. That was superseded by c14ab91 on main and has been dropped —
    nothing here touches the workflows.

Correction (2026-08-28): this body reported CRUD as 8/8. That was wrong. The
Replace step reports [~]skipped, not passed: the harness only runs it when a
testdata/<case>-replace.pkl fixture exists, and no case in this repo has one (0 of
118). Read every 8/8 above as 7 passed, Replace not exercised. The same applies
to every GCP resource already on main — the Replace path has never been covered
here. Nothing in this PR regressed.

@naxty naxty added the full-conformance Run every conformance case on this PR, not just the ones whose testdata changed label Aug 27, 2026
Service Directory was absent from the plugin. These three types are the whole
of its v1 API: a namespace contains services, a service contains the endpoints
a resolve call actually returns.

The API rejects a wildcard at every level - "locations/-" answers "Unsupported
location", "namespaces/-" answers "Could not parse namespace name" - so
services and endpoints are discovered by walking the collections above them,
following nextPageToken at each level. A dropped namespace would otherwise hide
every service and endpoint under it. The walk is registered from the package
init rather than an init of its own: Go runs init functions in filename order
and "list.go" sorts before "resources.go", so an override registered there
would be silently replaced by the generic registration.

base.ParentResourceConfig gains GrandParentType/GrandParentPropertyName for
APIs three collections deep. Read, update and delete rebuild the whole path
from the native ID, so create was the one operation with nothing but the
declared properties to route with.

clean-environment.sh sweeps leftover namespaces: the service and endpoint
fixtures build one as a prerequisite, and conformance Destroy only removes the
resource under test. --filter is server-side for this command and Service
Directory rejects "~", so the prefix is matched with grep.

Verified against europe-central2: every case crud 8/8 (Replace skipped, no
-replace fixture) and discovery 4/4, on released formae and on formae main.
naxty added 3 commits August 31, 2026 10:56
A pull request based on another pull request's branch matched no trigger, so
the six stacked pull requests in this chain got no CI at all - no build, no
lint, no conformance. Only the four based on main ever ran, and those were
separately gated out of conformance by discover-tests.

The scope is resolved from the diff, so a stacked pull request runs exactly the
fixtures it touches. The push filter is untouched: the full matrix stays a main
thing, and a push to a feature branch still runs nothing.
@naxty
naxty merged commit b751343 into main Aug 31, 2026
123 of 127 checks passed
@naxty naxty removed the full-conformance Run every conformance case on this PR, not just the ones whose testdata changed label Aug 31, 2026
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.

1 participant