feat(gcp): add Network Services meshes, gateways and LB policies - #191
Open
naxty wants to merge 1 commit into
Open
feat(gcp): add Network Services meshes, gateways and LB policies#191naxty wants to merge 1 commit into
naxty wants to merge 1 commit into
Conversation
Three types from networkservices.googleapis.com v1, a service the plugin
had no package for: Mesh and ServiceLbPolicy (global) and Gateway
(regional). All three are config objects that provision no capacity, so
the conformance cases they come with are free to run.
Each was exercised live before this landed - create, poll the operation
to completion, GET to confirm the resource actually materialised, PATCH,
delete - because this API accepts a create, hands back an operation and
can still fail it, leaving nothing behind but the operation's error.
Three findings are encoded here that are not visible from the discovery
document, and each would otherwise be a defect:
Gateway.scope is immutable, silently. The API accepts a changed scope in
the update mask, reports the operation as done and successful, and keeps
the old value. Left as a normal field it would look applied and never be,
and the forma would disagree with state forever with nothing to show for
it. It is dropped from the update body and marked createOnly, so a change
plans a replacement - the only thing that actually moves it. Gateway.type
fails the honest way, refused outright, and gets the same treatment.
A Gateway PATCH validates the whole resource rather than only the fields
it masks, so ports must be present on every update: omit it and the API
answers "Gateway must have at least one port" however narrow the mask
was. The update fixture repeats ports for that reason, not by accident.
ServiceLbPolicy.autoCapacityDrain is a message whose only field is a
bool, and the API omits that bool when it is false: {"enable": false}
reads back as {}. A policy that turned the drain off would then drift on
every reconcile and never settle, so the response transformer puts the
omitted false back. The field is nested, so the fix belongs in the
transformer rather than a hasProviderDefault hint; enable is required in
the schema, which is what makes restoring it unambiguous - the block
reaches a forma only when someone wrote the field.
serviceBindings was in the batch and is dropped. Its `service` field is
the only thing that gives the type meaning, and the API now refuses it on
both create and update: "Cloud Service Mesh's integration with Service
Directory will be deprecated. Creating service binding resources with
service field is disabled." What is left is creatable but inert - a name,
a description and labels - so shipping it would mean shipping a resource
that cannot express its own purpose.
The schema file is gateway_networkservices.pkl rather than gateway.pkl
because apigateway already claims that basename and verify-schema rejects
duplicate filenames across directories; the module keeps its natural name,
as spanner/database_spanner.pkl does.
Conformance has NOT been run for these types - see the PR description.
naxty
force-pushed
the
naxty/gcpNetworkServicesMesh
branch
from
September 3, 2026 09:35
0e7f384 to
6481a5b
Compare
naxty
marked this pull request as ready for review
September 3, 2026 09:36
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 three types from
networkservices.googleapis.comv1, a service this plugin had no package for.GCP::NetworkServices::MeshnameGCP::NetworkServices::GatewayOPEN_MESHtypeandscopeGCP::NetworkServices::ServiceLbPolicynameConformance has NOT been run — these types are unverified
No
make conformance-*target was run against this branch, andmake installwas deliberately not run either (it doesrm -rf $HOME/.pel/formae/plugins/gcp, which is shared with other agents' runs). The three types are therefore unverified end-to-end through formae. The conformance fixtures in this PR have never been executed.What was verified, and how, is set out below — but it was verified by driving the REST API directly with curl, not by running the plugin. Nothing here should be read as "these types work in formae".
What the live probe did establish
Every type was created, its operation polled to completion, then GET'd to confirm the resource actually materialised — this API accepts a create, returns an operation, and can still fail it with nothing left behind but the operation's error. All probe resources were deleted and their absence re-listed; zero leaks.
Three behaviours are encoded in this PR that the discovery document does not show, each of which would otherwise be a defect:
Gateway.scopeis immutable, silently. A patch changing it is accepted, the operation reports done and successful, and the value does not change. Left as an ordinary field, a changed scope would look applied and never be, and the forma would disagree with state permanently. It is dropped from the update body and markedcreateOnlyso a change plans a replacement.Gateway.typefails honestly (Gateway type can not be updated once created) and gets the same treatment.A
GatewayPATCH validates the whole resource, not just the masked fields. Omitportsand the API answersGateway must have at least one porthowever narrow the update mask was. The update fixture repeatsportsfor that reason.ServiceLbPolicy.autoCapacityDraindrops a falseenableon the way back. Sending{"enable": false}reads back as{}, so a policy with the drain turned off would drift on every reconcile and never settle. The response transformer restores the omitted false. Because the field is nested it cannot carry ahasProviderDefaulthint, so the fix lives in the transformer;enableis required in the schema, which is what makes restoring it unambiguous — the block reaches a forma only when someone actually wrote the field. The update fixture flips ittrue → falsespecifically to exercise this against the live API when conformance is eventually run.Read-back forms were checked for the mismatch class that has bitten this repo before:
namecomes back as a full path (handled byShortNameResponseTransformer), and the project appears as the project id, not the number. No other field changed form between request and response.serviceBindingsdropped from the batchIt was in the original batch of four. Its
servicefield is the only thing that gives the type meaning, and the API now refuses it on both create and update:A binding without it is creatable but inert — a name, a description and labels. Shipping that would mean shipping a resource that cannot express its own purpose, so it is left out rather than added as an empty shell.
Shared-project state change
networkservices.googleapis.comwas disabled ondevelopment-477117and I enabled it. It is additive, free, and a hard prerequisite for these types (and for conformance), but it is a change to shared project state and is flagged here rather than left silent. The API also neededroles/networkservices.admin, which was granted out of band to bothformae-tester@andgithub-deploy@— CI would 403 on all three types without the latter.Gates
go build·golangci-lint run·make test-unit·make verify-schema·pkl eval formae-plugin.pkl·bash -non all tracked shell files — all pass. All six fixtures were evaluated withpkl evaland their renderedPropertiesdiffed against the request bodies the live API actually accepted.Unit tests cover the path builder (global vs regional, and that a target's region cannot leak into a global URL), native-id extraction from an operation, operation failure mapping, and the
autoCapacityDrainround trip.No
hasProviderDefaultis used anywhere in these schemas, soschema/provider-default-dispositions.jsonneeds no new rows.