Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/devstack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,23 @@ jobs:
run: |
if [ $(openstack recordset list all -f value | grep -c " TXT ") -ne 10 ]; then exit 1; fi
if [ $(openstack recordset list all -f value | grep -c " A ") -ne 10 ]; then exit 2; fi

# external-dns's `fake` source only ever produces A records, so the checks above never
# exercise AAAA handling. Regression test for a bug where the webhook's Records() call
# silently dropped AAAA recordsets, so external-dns would never see an AAAA record as
# already existing and would loop forever trying (and failing) to recreate it. Designate
# itself already had the record correctly, so `openstack recordset list` alone can't catch
# this - the bug is specifically in what the webhook reports back over its own API.
Comment on lines +111 to +116

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for not just not testing things, but for thinking outside the box to work around external-dns in this case. But actually the Fake source does support other record types, see kubernetes-sigs/external-dns#6308.

I know this has not made it into a release, but 0.22 is indeed planned: kubernetes-sigs/external-dns#6607

- name: Seed an AAAA recordset directly in Designate
run: |
openstack recordset create example.com. aaaa-webhook-test.example.com. --type AAAA --record 2001:db8::1

- name: Wait for AAAA recordset to become ACTIVE
run: |
while [ "$(openstack recordset list example.com. --status PENDING -f value)" != "" ]; do date; openstack recordset list example.com. -f value; sleep 1; done

- name: Verify the webhook reports the AAAA recordset via GET /records
run: |
curl -sf -H "Accept: application/external.dns.webhook+json;version=1" http://127.0.0.1:8888/records -o /tmp/records.json
cat /tmp/records.json
jq -e '[.[] | select(.recordType == "AAAA" and .dnsName == "aaaa-webhook-test.example.com" and (.targets[0] == "2001:db8::1"))] | length == 1' /tmp/records.json
12 changes: 11 additions & 1 deletion internal/designate/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@ func getHostZoneID(hostname string, managedZones map[string]string) string {
return resultID
}

// isTypeSupported returns whether recordType is a type this provider reads back from Designate.
func isTypeSupported(recordType string) bool {
switch recordType {
case endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeTXT, endpoint.RecordTypeCNAME:
return true
default:
return false
}
}

// Records returns the list of records.
func (p designateProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, error) {
var result []*endpoint.Endpoint
Expand All @@ -139,7 +149,7 @@ func (p designateProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, e
for zoneID := range managedZones {
err = p.client.ForEachRecordSet(ctx, zoneID,
func(recordSet *recordsets.RecordSet) error {
if recordSet.Type != endpoint.RecordTypeA && recordSet.Type != endpoint.RecordTypeTXT && recordSet.Type != endpoint.RecordTypeCNAME {
if !isTypeSupported(recordSet.Type) {
return nil
}

Expand Down
15 changes: 15 additions & 0 deletions internal/designate/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,11 @@ func TestDesignateRecords(t *testing.T) {
TTL: 120,
Records: []string{"10.1.1.2"},
})
rs15ID, _ := client.CreateRecordSet(ctx, zone1ID, recordsets.CreateOpts{
Name: "www6.example.com.",

@frittentheke frittentheke Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we are not yet following this yet, but I'd like to use the test. TLD as per RFC 6761.
See my PR about changing the other occurrences: #74

Edit: I know the Fake source of external-dns does only create "example.com" records though.

Type: endpoint.RecordTypeAAAA,
Records: []string{"2001:db8::1"},
})

zone2ID := client.AddZone(ctx, zones.Zone{
Name: "test.net.",
Expand Down Expand Up @@ -345,6 +350,16 @@ func TestDesignateRecords(t *testing.T) {
designateOriginalRecords: "10.1.1.2",
},
},
{
DNSName: "www6.example.com",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:db8::1"},
Labels: map[string]string{
designateRecordSetID: rs15ID,
designateZoneID: zone1ID,
designateOriginalRecords: "2001:db8::1",
},
},
{
DNSName: "srv.test.net",
RecordType: endpoint.RecordTypeA,
Expand Down
Loading