diff --git a/docs/tutorials/crd.md b/docs/tutorials/crd.md index 81834a8b9..53c8fa579 100644 --- a/docs/tutorials/crd.md +++ b/docs/tutorials/crd.md @@ -69,3 +69,45 @@ spec: - **With `--force-default-targets` (Legacy Behavior):** A CNAME record for `smoke-nt.example.com` will be created pointing to `1.2.3.4`. `--force-default-targets` allows migration path to clean CRD resources. + +### DNSEndpoint with an SRV record + +Here's an example of a `DNSEndpoint` with an SRV record: + +```yaml +--- +apiVersion: externaldns.k8s.io/v1alpha1 +kind: DNSEndpoint +metadata: + name: test-srv + namespace: default +spec: + endpoints: + - dnsName: _sip._udp.test.example.com + recordTTL: 180 + recordType: SRV + targets: + - 1 50 5060 sip1-n1.test.example.com + - 1 50 5060 sip1-n2.test.example.com +``` + +### DNSEndpoint with an NAPTR record + +Here's an example of a `DNSEndpoint` with an NAPTR record: + +```yaml +--- +apiVersion: externaldns.k8s.io/v1alpha1 +kind: DNSEndpoint +metadata: + name: test-naptr + namespace: default +spec: + endpoints: + - dnsName: test.example.com + recordTTL: 180 + recordType: NAPTR + targets: + - 50 50 "S" "SIPS+D2T" "" _sips._tcp.test.example.com. + - 100 50 "S" "SIP+D2U" "" _sip._udp.test.example.com. +``` diff --git a/registry/txt.go b/registry/txt.go index 7802367ce..417434c85 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -158,7 +158,7 @@ func NewTXTRegistry(provider provider.Provider, txtPrefix, txtSuffix, ownerID st } func getSupportedTypes() []string { - return []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME, endpoint.RecordTypeNS, endpoint.RecordTypeMX} + return []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME, endpoint.RecordTypeNS, endpoint.RecordTypeMX, endpoint.RecordTypeSRV, endpoint.RecordTypeNAPTR} } func (im *TXTRegistry) GetDomainFilter() endpoint.DomainFilterInterface { diff --git a/registry/txt_test.go b/registry/txt_test.go index b7bb36732..6a09cc4a2 100644 --- a/registry/txt_test.go +++ b/registry/txt_test.go @@ -122,6 +122,15 @@ func testTXTRegistryRecordsPrefixed(t *testing.T) { newEndpointWithOwner("txt.aaaa-dualstack.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner-2\"", endpoint.RecordTypeTXT, ""), newEndpointWithOwner("mail.test-zone.example.org", "10 onemail.example.com", endpoint.RecordTypeMX, ""), newEndpointWithOwner("txt.mx-mail.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), + newMultiTargetEndpointWithOwner( + "_sip._udp.sip1.test-zone.example.org", + []string{"1 50 5060 sip1-n1.test-zone.example.org", "1 50 5060 sip1-n2.test-zone.example.org"}, + endpoint.RecordTypeSRV, + "", + ), + newEndpointWithOwner("txt._sip._udp.sip1.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), + newEndpointWithOwner("sip1.test-zone.example.org", `10 "U" "SIP+DTU" "" _sip._udp.sip1.test-zone.example.org.`, endpoint.RecordTypeNAPTR, ""), + newEndpointWithOwner("txt.sip1.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), }, }) expectedRecords := []*endpoint.Endpoint{ @@ -226,6 +235,25 @@ func testTXTRegistryRecordsPrefixed(t *testing.T) { endpoint.OwnerLabelKey: "owner", }, }, + { + DNSName: "_sip._udp.sip1.test-zone.example.org", + Targets: endpoint.Targets{ + "1 50 5060 sip1-n1.test-zone.example.org", + "1 50 5060 sip1-n2.test-zone.example.org", + }, + RecordType: endpoint.RecordTypeSRV, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "owner", + }, + }, + { + DNSName: "sip1.test-zone.example.org", + Targets: endpoint.Targets{`10 "U" "SIP+DTU" "" _sip._udp.sip1.test-zone.example.org.`}, + RecordType: endpoint.RecordTypeNAPTR, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "owner", + }, + }, } r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{}, []string{}, false, nil, "") @@ -265,6 +293,15 @@ func testTXTRegistryRecordsSuffixed(t *testing.T) { newEndpointWithOwner("aaaa-dualstack-txt.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner-2\"", endpoint.RecordTypeTXT, ""), newEndpointWithOwner("mail.test-zone.example.org", "10 onemail.example.com", endpoint.RecordTypeMX, ""), newEndpointWithOwner("mx-mail-txt.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), + newMultiTargetEndpointWithOwner( + "_sip._udp.sip1.test-zone.example.org", + []string{"1 50 5060 sip1-n1.test-zone.example.org", "1 50 5060 sip1-n2.test-zone.example.org"}, + endpoint.RecordTypeSRV, + "", + ), + newEndpointWithOwner("_sip-txt._udp.sip1.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), + newEndpointWithOwner("sip1.test-zone.example.org", `10 "U" "SIP+DTU" "" _sip._udp.sip1.test-zone.example.org.`, endpoint.RecordTypeNAPTR, ""), + newEndpointWithOwner("sip1-txt.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), }, }) expectedRecords := []*endpoint.Endpoint{ @@ -361,6 +398,25 @@ func testTXTRegistryRecordsSuffixed(t *testing.T) { endpoint.OwnerLabelKey: "owner", }, }, + { + DNSName: "_sip._udp.sip1.test-zone.example.org", + Targets: endpoint.Targets{ + "1 50 5060 sip1-n1.test-zone.example.org", + "1 50 5060 sip1-n2.test-zone.example.org", + }, + RecordType: endpoint.RecordTypeSRV, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "owner", + }, + }, + { + DNSName: "sip1.test-zone.example.org", + Targets: endpoint.Targets{`10 "U" "SIP+DTU" "" _sip._udp.sip1.test-zone.example.org.`}, + RecordType: endpoint.RecordTypeNAPTR, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "owner", + }, + }, } r, _ := NewTXTRegistry(p, "", "-txt", "owner", time.Hour, "", []string{}, []string{}, false, nil, "") @@ -398,6 +454,15 @@ func testTXTRegistryRecordsNoPrefix(t *testing.T) { newEndpointWithOwner("aaaa-dualstack.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner-2\"", endpoint.RecordTypeTXT, ""), newEndpointWithOwner("mail.test-zone.example.org", "10 onemail.example.com", endpoint.RecordTypeMX, ""), newEndpointWithOwner("mx-mail.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), + newMultiTargetEndpointWithOwner( + "_sip._udp.sip1.test-zone.example.org", + []string{"1 50 5060 sip1-n1.test-zone.example.org", "1 50 5060 sip1-n2.test-zone.example.org"}, + endpoint.RecordTypeSRV, + "", + ), + newEndpointWithOwner("_sip._udp.sip1.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), + newEndpointWithOwner("sip1.test-zone.example.org", `10 "U" "SIP+DTU" "" _sip._udp.sip1.test-zone.example.org.`, endpoint.RecordTypeNAPTR, ""), + newEndpointWithOwner("sip1.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), }, }) expectedRecords := []*endpoint.Endpoint{ @@ -488,6 +553,25 @@ func testTXTRegistryRecordsNoPrefix(t *testing.T) { endpoint.OwnerLabelKey: "owner", }, }, + { + DNSName: "_sip._udp.sip1.test-zone.example.org", + Targets: endpoint.Targets{ + "1 50 5060 sip1-n1.test-zone.example.org", + "1 50 5060 sip1-n2.test-zone.example.org", + }, + RecordType: endpoint.RecordTypeSRV, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "owner", + }, + }, + { + DNSName: "sip1.test-zone.example.org", + Targets: endpoint.Targets{`10 "U" "SIP+DTU" "" _sip._udp.sip1.test-zone.example.org.`}, + RecordType: endpoint.RecordTypeNAPTR, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "owner", + }, + }, } r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, false, nil, "") diff --git a/registry/txt_utils_test.go b/registry/txt_utils_test.go index e37c5495b..a81b619f2 100644 --- a/registry/txt_utils_test.go +++ b/registry/txt_utils_test.go @@ -24,10 +24,23 @@ func newEndpointWithOwner(dnsName, target, recordType, ownerID string) *endpoint return newEndpointWithOwnerAndLabels(dnsName, target, recordType, ownerID, nil) } +func newMultiTargetEndpointWithOwner(dnsName string, targets endpoint.Targets, recordType, ownerID string) *endpoint.Endpoint { + return newMultiTargetEndpointWithOwnerAndLabels(dnsName, targets, recordType, ownerID, nil) +} + func newEndpointWithOwnerAndOwnedRecord(dnsName, target, recordType, ownerID, ownedRecord string) *endpoint.Endpoint { return newEndpointWithOwnerAndLabels(dnsName, target, recordType, ownerID, endpoint.Labels{endpoint.OwnedRecordLabelKey: ownedRecord}) } +func newMultiTargetEndpointWithOwnerAndLabels(dnsName string, targets endpoint.Targets, recordType, ownerID string, labels endpoint.Labels) *endpoint.Endpoint { + e := endpoint.NewEndpoint(dnsName, recordType, targets...) + e.Labels[endpoint.OwnerLabelKey] = ownerID + for k, v := range labels { + e.Labels[k] = v + } + return e +} + func newEndpointWithOwnerAndLabels(dnsName, target, recordType, ownerID string, labels endpoint.Labels) *endpoint.Endpoint { e := endpoint.NewEndpoint(dnsName, recordType, target) e.Labels[endpoint.OwnerLabelKey] = ownerID