feat(servicedirectory): add Namespace, Service and Endpoint - #165
Merged
Conversation
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
force-pushed
the
naxty/gcpBatchResources2
branch
from
August 27, 2026 22:43
cd65cb7 to
c9133bd
Compare
This was referenced Aug 28, 2026
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.
# Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds GCP Service Directory — all three types its v1 API has.
GCP::ServiceDirectory::NamespaceGCP::ServiceDirectory::ServiceGCP::ServiceDirectory::EndpointA 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 additionallyrequires 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 wayCI 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
-replacefixture, the sameas 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
nextPageTokenateach level.
The walk is registered from the package
initinresources.go, not from aninitinlist.go: Go runsinitfunctions in filename order andlist.gosorts 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.ParentResourceConfiggainsGrandParentType/GrandParentPropertyName. Read, update and delete rebuild the whole path fromthe 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].portcomes back as a JSON number, not a string, so notoString. A unittest pins that — stringifying it would make a correct endpoint plan an update.
clean-environment.shsweeps leftover namespaces. The service and endpointfixtures build one as a prerequisite and conformance Destroy only removes the
resource under test.
--filteris server-side forgcloud service-directory namespaces listand 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
-replace.pklfixtures, matching the rest of the repo.ci.yml/nightly.ymltimeout entries: the slowest case is 54s end toend, well inside the default.
trigger. That was superseded by c14ab91 on
mainand has been dropped —nothing here touches the workflows.
Correction (2026-08-28): this body reported CRUD as
8/8. That was wrong. TheReplace step reports
[~]— skipped, not passed: the harness only runs it when atestdata/<case>-replace.pklfixture exists, and no case in this repo has one (0 of118). Read every
8/8above as 7 passed, Replace not exercised. The same appliesto every GCP resource already on
main— the Replace path has never been coveredhere. Nothing in this PR regressed.