diff --git a/provider/zonefinder.go b/provider/zonefinder.go index 18396000b..6a07646c1 100644 --- a/provider/zonefinder.go +++ b/provider/zonefinder.go @@ -16,7 +16,12 @@ limitations under the License. package provider -import "strings" +import ( + "strings" + + log "github.com/sirupsen/logrus" + "golang.org/x/net/idna" +) type ZoneIDName map[string]string @@ -25,8 +30,13 @@ func (z ZoneIDName) Add(zoneID, zoneName string) { } func (z ZoneIDName) FindZone(hostname string) (suitableZoneID, suitableZoneName string) { + name, err := idna.Lookup.ToUnicode(hostname) + if err != nil { + log.Warnf("Failed to convert hostname '%s' to its Unicode form: %v", hostname, err) + name = hostname + } for zoneID, zoneName := range z { - if hostname == zoneName || strings.HasSuffix(hostname, "."+zoneName) { + if name == zoneName || strings.HasSuffix(name, "."+zoneName) { if suitableZoneName == "" || len(zoneName) > len(suitableZoneName) { suitableZoneID = zoneID suitableZoneName = zoneName diff --git a/provider/zonefinder_test.go b/provider/zonefinder_test.go index 592ef65fb..0037edadd 100644 --- a/provider/zonefinder_test.go +++ b/provider/zonefinder_test.go @@ -19,7 +19,9 @@ package provider import ( "testing" + log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + "sigs.k8s.io/external-dns/internal/testutils" ) func TestZoneIDName(t *testing.T) { @@ -27,10 +29,12 @@ func TestZoneIDName(t *testing.T) { z.Add("123456", "foo.bar") z.Add("123456", "qux.baz") z.Add("654321", "foo.qux.baz") + z.Add("987654", "エイミー.みんな") assert.Equal(t, ZoneIDName{ "123456": "qux.baz", "654321": "foo.qux.baz", + "987654": "エイミー.みんな", }, z) // simple entry in a domain @@ -62,4 +66,13 @@ func TestZoneIDName(t *testing.T) { zoneID, zoneName = z.FindZone("foo.qux.baz") assert.Equal(t, "foo.qux.baz", zoneName) assert.Equal(t, "654321", zoneID) + + // entry gets normalized before finding + zoneID, zoneName = z.FindZone("xn--eckh0ome.xn--q9jyb4c") + assert.Equal(t, "エイミー.みんな", zoneName) + assert.Equal(t, "987654", zoneID) + + b := testutils.LogsToBuffer(log.WarnLevel, t) + zoneID, zoneName = z.FindZone("???") + assert.Contains(t, b.String(), "level=warning msg=\"Failed to convert hostname '???' to its Unicode form: idna: disallowed rune U+003F\"") }