mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-07 01:56:57 +02:00
fix(zonefinder): handle underscores in dns records
Signed-off-by: Arthur Le Roux <arthurleroux@protonmail.com>
This commit is contained in:
parent
2de3b50b14
commit
64f7989628
@ -29,12 +29,34 @@ func (z ZoneIDName) Add(zoneID, zoneName string) {
|
|||||||
z[zoneID] = zoneName
|
z[zoneID] = zoneName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindZone identifies the most suitable DNS zone for a given hostname.
|
||||||
|
// It returns the zone ID and name that best match the hostname.
|
||||||
|
//
|
||||||
|
// The function processes the hostname by splitting it into labels and
|
||||||
|
// converting each label to its Unicode form using IDNA (Internationalized
|
||||||
|
// Domain Names for Applications) standards.
|
||||||
|
//
|
||||||
|
// Labels containing underscores ('_') are skipped during Unicode conversion.
|
||||||
|
// This is because underscores are often used in special DNS records (e.g.,
|
||||||
|
// SRV records as per RFC 2782, or TXT record for services) that are not
|
||||||
|
// IDNA-aware and cannot represent non-ASCII labels. Skipping these labels
|
||||||
|
// ensures compatibility with such use cases.
|
||||||
func (z ZoneIDName) FindZone(hostname string) (suitableZoneID, suitableZoneName string) {
|
func (z ZoneIDName) FindZone(hostname string) (suitableZoneID, suitableZoneName string) {
|
||||||
name, err := idna.Lookup.ToUnicode(hostname)
|
var name string
|
||||||
if err != nil {
|
domain_labels := strings.Split(hostname, ".")
|
||||||
log.Warnf("Failed to convert hostname '%s' to its Unicode form: %v", hostname, err)
|
for i, label := range domain_labels {
|
||||||
name = hostname
|
if strings.Contains(label, "_") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
convertedLabel, err := idna.Lookup.ToUnicode(label)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Failed to convert label '%s' of hostname '%s' to its Unicode form: %v", label, hostname, err)
|
||||||
|
convertedLabel = label
|
||||||
|
}
|
||||||
|
domain_labels[i] = convertedLabel
|
||||||
}
|
}
|
||||||
|
name = strings.Join(domain_labels, ".")
|
||||||
|
|
||||||
for zoneID, zoneName := range z {
|
for zoneID, zoneName := range z {
|
||||||
if name == zoneName || strings.HasSuffix(name, "."+zoneName) {
|
if name == zoneName || strings.HasSuffix(name, "."+zoneName) {
|
||||||
if suitableZoneName == "" || len(zoneName) > len(suitableZoneName) {
|
if suitableZoneName == "" || len(zoneName) > len(suitableZoneName) {
|
||||||
|
@ -30,11 +30,15 @@ func TestZoneIDName(t *testing.T) {
|
|||||||
z.Add("123456", "qux.baz")
|
z.Add("123456", "qux.baz")
|
||||||
z.Add("654321", "foo.qux.baz")
|
z.Add("654321", "foo.qux.baz")
|
||||||
z.Add("987654", "エイミー.みんな")
|
z.Add("987654", "エイミー.みんな")
|
||||||
|
z.Add("123123", "_metadata.example.com")
|
||||||
|
z.Add("456456", "_metadata.エイミー.みんな")
|
||||||
|
|
||||||
assert.Equal(t, ZoneIDName{
|
assert.Equal(t, ZoneIDName{
|
||||||
"123456": "qux.baz",
|
"123456": "qux.baz",
|
||||||
"654321": "foo.qux.baz",
|
"654321": "foo.qux.baz",
|
||||||
"987654": "エイミー.みんな",
|
"987654": "エイミー.みんな",
|
||||||
|
"123123": "_metadata.example.com",
|
||||||
|
"456456": "_metadata.エイミー.みんな",
|
||||||
}, z)
|
}, z)
|
||||||
|
|
||||||
// simple entry in a domain
|
// simple entry in a domain
|
||||||
@ -73,6 +77,6 @@ func TestZoneIDName(t *testing.T) {
|
|||||||
assert.Equal(t, "987654", zoneID)
|
assert.Equal(t, "987654", zoneID)
|
||||||
|
|
||||||
b := testutils.LogsToBuffer(log.WarnLevel, t)
|
b := testutils.LogsToBuffer(log.WarnLevel, t)
|
||||||
zoneID, zoneName = z.FindZone("???")
|
_, _ = z.FindZone("???")
|
||||||
assert.Contains(t, b.String(), "level=warning msg=\"Failed to convert hostname '???' to its Unicode form: idna: disallowed rune U+003F\"")
|
assert.Contains(t, b.String(), "level=warning msg=\"Failed to convert label '???' of hostname '???' to its Unicode form: idna: disallowed rune U+003F\"")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user