Conversation
MaxRink
requested review from
Buzzglo,
TebogoTS,
ampie,
januarios,
k0da and
kuritka
as code owners
August 6, 2026 18:21
MaxRink
added a commit
to MaxRink/external-dns-infoblox-webhook
that referenced
this pull request
Aug 6, 2026
…ranch GitHub only registers a workflow, and therefore only evaluates its push-tag trigger, once the file has been seen on the repository default branch. tcaas-image.yaml existed solely on tcaas-main, so it was never registered: actions/workflows lists only the four upstream workflows and three -telekom.N tag pushes produced zero runs. Add the file to main so the trigger registers. Also add workflow_dispatch with an explicit ref input for on-demand rebuilds, and a guard that refuses to publish unless the resolved ref is a v*-telekom.* tag, so a dispatch from main cannot publish a misleading image tag. This file is fork-only and is deleted together with the rest of the bridge once upstream ships PRs AbsaOSS#69/AbsaOSS#70.
MaxRink
force-pushed
the
feat/ipv6-ptr-support
branch
from
August 15, 2026 11:15
290da42 to
e285794
Compare
The provider previously fetched and reconciled only A, CNAME, TXT, NS, host and PTR records, so IPv6 services managed through ExternalDNS could never be reconciled against Infoblox: AAAA records already present in a zone were invisible to Records() and any AAAA endpoint in a plan was silently dropped by recordSet() because the switch had no matching case. This adds AAAA end-to-end, following the existing patterns for A records: - ToAAAAResponseMap() maps []ibclient.RecordAAAA onto the shared ResponseMap using the ibclient.AaaaRecord type constant. - Records() fetches record:aaaa per zone through PagingGetObject, the same way A records are fetched. - ToHostAAAAResponseMap() surfaces the Ipv6Addrs of host records as AAAA endpoints, mirroring how Ipv4Addrs are already surfaced as A endpoints. Both host mappers now skip records that carry no address of the respective family, so an IPv4-only or IPv6-only host record no longer yields an endpoint with an empty target. - recordSet() builds a RecordAAAA for create/update/delete and looks the existing object up by name and ipv6addr. - getRefID() resolves the object reference and log fields for RecordAAAA. Infoblox can return the same IPv6 address more than once for a name (the same address in a different but equivalent notation). Such duplicates would produce a permanently dirty plan, so ToAAAAResponseMap de-duplicates targets via the new ResponseDetails.Contains helper. PTR records for AAAA are deliberately not created: the reverse zone lookup path is built around IPv4 (rfc2317.CidrToInAddr) and ip6.arpa delegation would need separate handling. CreatePTR therefore keeps applying to A records only.
ToAAAAResponseMap skips a target that the response map already holds, to avoid a permanent diff in the plan. The comment says that this also covers the same address in a different notation, but the comparison was a plain string comparison, so it did not. Compare the canonical form of an IP target instead. Targets that are not IP addresses keep the plain string comparison.
PR AbsaOSS#69 added AAAA records but deliberately left PTR creation to A records only, on the assumption that the reverse zone lookup was IPv4 specific. It turns out most of that machinery is already family agnostic: - rfc2317.CidrToInAddr already derives ip6.arpa nibble names for IPv6 CIDRs ("2001:db8::/64" -> "0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa"), so Records() needs no change to fetch PTR records from an IPv6 reverse zone. - findReverseZone uses net.ParseCIDR and net.IPNet.Contains, both of which already match IPv6 addresses against IPv6 reverse zones. What actually had to change: - ChangesByZone now derives the companion PTR change for AAAA endpoints as well as A endpoints, and AdjustEndpoints / Records() track the infoblox-ptr-record-exists property for AAAA endpoints too. - recordSet() addresses a PTR record through ipv6addr instead of ipv4addr when the target is an IPv6 address, both when building the object and when looking the existing object up. A record:ptr carries its target in exactly one of the two fields, never in both. - ToPTRResponseMap() falls back to Ipv6Addr when Ipv4Addr is empty, so PTR records read back from an ip6.arpa zone yield a target instead of an empty string. CreatePTR still gates all of this, so nothing changes for users who do not opt in. As before, the reverse zone has to be part of the DOMAIN_FILTER; the README documents the IPv6 CIDR form.
MaxRink
force-pushed
the
feat/ipv6-ptr-support
branch
from
August 28, 2026 00:16
e285794 to
2a2273d
Compare
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.
Follow-up to #69, which added AAAA records but deliberately restricted
CreatePTRto A records. That restriction turned out to be more conservative than necessary — most of the reverse-zone machinery is already family-agnostic:rfc2317.CidrToInAddralready derivesip6.arpanibble names for IPv6 CIDRs (verified:2001:db8::/64→0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa,2001::/16→1.0.0.2.ip6.arpa), soRecords()needed no change to fetch PTRs from an IPv6 reverse zone.findReverseZoneusesnet.ParseCIDR+net.IPNet.Contains, both already IPv6-correct.So no new nibble helper was written — it would have been dead code.
What actually changed
ChangesByZonederives the companion PTR change for AAAA endpoints as well as A;AdjustEndpoints/Records()trackinfoblox-ptr-record-existsfor AAAA too.recordSet()addresses a PTR throughipv6addrrather thanipv4addrwhen the target is IPv6, both when building the object and when looking up the existing one.record:ptrcarries its target in exactly one of the two fields (RecordPTRhas bothIpv4AddrandIpv6Addr;NewEmptyRecordPTR'sreturnFieldslists both).ToPTRResponseMap()falls back toIpv6AddrwhenIpv4Addris empty, so PTRs read back from anip6.arpazone yield a target instead of an empty string.CreatePTRstill gates all of this — no behaviour change for users who haven't opted in. As before, the reverse zone must be inDOMAIN_FILTER; the README now documents the IPv6 CIDR form.Testing
Nibble-name derivation (table test: compressed, expanded, ULA and host forms),
ip6.arpareverse-zone matching,RecordPTRfield-and-query-param assertions, and AAAA+PTR create/update/delete throughApplyChanges— including a case asserting no PTR is created whenCreatePTRis disabled.go build,go vet,go test -count=1 ./...,gofmt -landgolangci-lint run ./...(0 issues) all pass.The tests were mutation-checked. Worth calling out one result: an early version of the
ApplyChangestests passed with the wrong WAPI field being written, because the mock reads whichever field is set. Since a wrong field means broken reverse records against a real Grid,TestInfobloxRecordSetPTRwas added to assert the concreteRecordPTRfields (ipv4addrempty,ipv6addrset) and the lookup query parameter. Forcing all PTRs to writeIpv4Addrnow failsTestInfobloxRecordSetPTR/ipv6and/ipv6_expanded.Found but deliberately left alone
findReverseZonehas a pre-existing longest-prefix-match bug that affects IPv4 too: it keysnetworks[mask]on the second return ofrZoneNet.Mask.Size()(total bits — always 32 or 128) rather than the prefix length. With both10.0.0.0/8and10.0.0.0/24present,10.0.0.5resolves to whichever zone comes last rather than the more specific one. Out of scope here to keep the diff focused; happy to send a separate PR if useful.Depends on #69.