Skip to content

feat(dns): add Policy, ResponsePolicy and ResponsePolicyRule - #169

Merged
naxty merged 6 commits into
naxty/gcpCloudSqlBatchfrom
naxty/gcpDnsBatch
Aug 31, 2026
Merged

feat(dns): add Policy, ResponsePolicy and ResponsePolicyRule#169
naxty merged 6 commits into
naxty/gcpCloudSqlBatchfrom
naxty/gcpDnsBatch

Conversation

@naxty

@naxty naxty commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Completes Cloud DNS, which had only ManagedZone. Stacked on #168.

Case Result
dns-policy crud 8/8, discovery 4/4
dns-response-policy crud 8/8, discovery 4/4
dns-response-policy-rule crud 8/8, discovery 4/4

All three green in one clean sweep (24–29 seconds per case — DNS is by far the
cheapest service to test in this plugin).

Verified through debug-conformance.yml, not locally. The local
service-account key is 403 on every DNS call, while CI's identity creates DNS
zones routinely for the existing managed-zone case. That is why the workflow
c14ab91 added is the verification path for this batch.

Notes for review

Cloud DNS does not agree with itself about what an identifier is called. A
managed zone and a policy use name, a response policy uses
responsePolicyName, a rule uses ruleName. A forma declares name for all of
them and paired transformers translate at the API boundary, so three spellings
stay inside the plugin rather than leaking into every forma. The native-ID
extractor accepts all three, because a list item is the only place an id appears
during discovery.

The rule collection is rules in the URL but responsePolicyRules in a list
response
— handled with ListItemsKey.

Three bugs the first CI runs found, all in discovery:

  1. base.extractNativeIDFromItem reads itemMap["name"] and gives up when
    it is empty
    , before ever calling the API's own native-ID extractor. So any
    GCP collection whose items do not use name is invisible to the generic
    List, no matter what the plugin supports. Worked around with a small custom
    List here rather than changing base under a stack of branches — but it is
    worth fixing properly.
  2. Cloud DNS stamps every local-data record with a kind, which failed Verify,
    Sync and Update as a property no forma wrote.
  3. A rule's read carries nothing naming its response policy — that lives
    only in the URL — so discovered rules arrived without responsePolicy, a
    required createOnly property, and were dropped. Found on every pass,
    persisted on none. TransformContext carries no parent, so this had to be a
    Read override rather than a response transformer.

What I could not verify

  • ResourceRecordSet is deliberately absent. Its delete path takes a
    two-segment {name}/{type} identifier unlike anything else in this plugin;
    bolting that onto a batch whose other three are conventional would risk the
    whole PR on one awkward type. It is the last gap in the service.

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 added 3 commits August 28, 2026 03:42
Cloud DNS had only ManagedZone. These three cover the rest of what the v1 API
can create and delete, bar ResourceRecordSet, whose delete path takes a
two-segment {name}/{type} identifier unlike anything else in the plugin.

Cloud DNS does not agree with itself about what an identifier is called: a
managed zone and a policy use "name", a response policy "responsePolicyName",
a rule "ruleName". A forma declares "name" for all of them and paired
request/response transformers translate at the API boundary, so three
spellings stay inside the plugin instead of leaking into every forma. The
native-ID extractor accepts all three, because a list item is the only place an
id appears during discovery.

Two more things the generic engine had to be told: the rule collection is
"rules" in the URL but "responsePolicyRules" in a list response, and a rule
is discovered by walking the response policies - discovery lists with no
properties and there is no wildcard for that segment.

Verification runs through debug-conformance.yml rather than locally: the local
service-account key is 403 on every DNS call, while CI's identity creates DNS
zones for the existing managed-zone case.
… kind

Two failures from the first debug-conformance run against real GCP.

A response policy was never discovered. base.extractNativeIDFromItem reads
itemMap["name"] and gives up when it is empty, before it ever calls the API's
own native-ID extractor - and a response policy names itself
"responsePolicyName". Every item was skipped and Discover timed out with
"resource did not appear in inventory". Worth knowing generally: any GCP
collection whose items do not use "name" is invisible to the generic List, no
matter what the plugin's extractor supports. A small custom List fixes it here
rather than changing base under four in-flight branches.

Separately, Cloud DNS stamps every local-data record with a "kind", which
failed Verify, Sync and Update as a property no forma wrote. It is now declared
a provider default, like Spanner's cronSpec fields.
The listing found the rule every time - "Received 1 resources for
GCP::DNS::ResponsePolicyRule" on each pass - and discovery still finished with
nothing discovered, while the conformance Discover step timed out.

Cloud DNS answers a rule read with ruleName, dnsName, localData and behavior,
and nothing naming the owning response policy: that lives only in the URL. So a
discovered rule arrived without "responsePolicy", a required createOnly
property, and was dropped rather than entering inventory.

TransformContext carries no parent, so this cannot be a response transformer -
the policy has to come from the native ID, which means a Read override.
@naxty
naxty merged commit ea8c8b6 into naxty/gcpCloudSqlBatch Aug 31, 2026
naxty added a commit that referenced this pull request Aug 31, 2026
…ustConfig

Restores #171. That pull request was stacked, and it merged into its parent
branch rather than into main - GitHub marks a stacked pull request merged once
its commits reach its base, and its base was a branch. #167, #168, #169 and #170
went the same way but were recovered when #173 landed, because #173 descended
from them. Nothing descended from #171, so certificate manager was the one batch
left behind: main has carried a Merged badge and no code since.

This is that content on top of current main, nothing else - the three types,
their schemas, six fixtures, and the package registration.

Verified locally against the service account CI uses, all three CRUD 7/7 with
Replace skipped and discovery 4/4. Two things it needed, both recorded in the
CHANGELOG: roles/certificatemanager.owner rather than editor, which carries no
delete permission at all; and a trust config that is not empty, since the API
rejects one carrying neither a trust store nor an allowlisted certificate.
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