Browse Source

YamlProvider idna/utf-8 support, prefers utf8

pull/922/head
Ross McFarland 3 years ago
parent
commit
a33235d608
No known key found for this signature in database GPG Key ID: 943B179E15D3B22A
2 changed files with 52 additions and 7 deletions
  1. +16
    -7
      octodns/provider/yaml.py
  2. +36
    -0
      tests/test_octodns_provider_yaml.py

+ 16
- 7
octodns/provider/yaml.py View File

@ -17,6 +17,7 @@ import logging
from ..record import Record from ..record import Record
from ..yaml import safe_load, safe_dump from ..yaml import safe_load, safe_dump
from .base import BaseProvider from .base import BaseProvider
from . import ProviderException
class YamlProvider(BaseProvider): class YamlProvider(BaseProvider):
@ -207,12 +208,20 @@ class YamlProvider(BaseProvider):
return False return False
before = len(zone.records) before = len(zone.records)
filename = join(self.directory, f'{zone.decoded_name}yaml')
if not isfile(filename):
idna_filename = join(self.directory, f'{zone.name}yaml')
utf8_filename = join(self.directory, f'{zone.decoded_name}yaml')
idna_filename = join(self.directory, f'{zone.name}yaml')
# we prefer utf8
if isfile(utf8_filename):
if utf8_filename != idna_filename and isfile(idna_filename):
raise ProviderException(
f'Both UTF-8 "{utf8_filename}" and IDNA "{idna_filename}" exist for {zone.decoded_name}'
)
filename = utf8_filename
else:
self.log.warning( self.log.warning(
'populate: "%s" does not exist, falling back to idna version "%s"',
filename,
'populate: "%s" does not exist, falling back to try idna version "%s"',
utf8_filename,
idna_filename, idna_filename,
) )
filename = idna_filename filename = idna_filename
@ -245,7 +254,7 @@ class YamlProvider(BaseProvider):
del d['ttl'] del d['ttl']
if record._octodns: if record._octodns:
d['octodns'] = record._octodns d['octodns'] = record._octodns
data[record.name].append(d)
data[record.decoded_name].append(d)
# Flatten single element lists # Flatten single element lists
for k in data.keys(): for k in data.keys():
@ -261,7 +270,7 @@ class YamlProvider(BaseProvider):
filename = join(self.directory, f'{desired.decoded_name}yaml') filename = join(self.directory, f'{desired.decoded_name}yaml')
self.log.debug('_apply: writing filename=%s', filename) self.log.debug('_apply: writing filename=%s', filename)
with open(filename, 'w') as fh: with open(filename, 'w') as fh:
safe_dump(dict(data), fh)
safe_dump(dict(data), fh, allow_unicode=True)
def _list_all_yaml_files(directory): def _list_all_yaml_files(directory):


+ 36
- 0
tests/test_octodns_provider_yaml.py View File

@ -15,7 +15,9 @@ from unittest import TestCase
from yaml import safe_load from yaml import safe_load
from yaml.constructor import ConstructorError from yaml.constructor import ConstructorError
from octodns.idna import idna_encode
from octodns.record import Create from octodns.record import Create
from octodns.provider import ProviderException
from octodns.provider.base import Plan from octodns.provider.base import Plan
from octodns.provider.yaml import ( from octodns.provider.yaml import (
_list_all_yaml_files, _list_all_yaml_files,
@ -172,6 +174,40 @@ class TestYamlProvider(TestCase):
# make sure nothing is left # make sure nothing is left
self.assertEqual([], list(data.keys())) self.assertEqual([], list(data.keys()))
def test_idna_filenames(self):
with TemporaryDirectory() as td:
name = 'déjà.vu.'
filename = f'{name}yaml'
provider = YamlProvider('test', td.dirname)
zone = Zone(idna_encode(name), [])
# create a idna named file
with open(join(td.dirname, idna_encode(filename)), 'w') as fh:
pass
fh.write(
'''---
'':
type: A
value: 1.2.3.4
'''
)
# populates fine when there's just the idna version (as a fallback)
provider.populate(zone)
self.assertEqual(1, len(zone.records))
# create a utf8 named file
with open(join(td.dirname, filename), 'w') as fh:
pass
# does not allow both idna and utf8 named files
with self.assertRaises(ProviderException) as ctx:
provider.populate(zone)
msg = str(ctx.exception)
self.assertTrue('Both UTF-8' in msg)
def test_empty(self): def test_empty(self):
source = YamlProvider( source = YamlProvider(
'test', join(dirname(__file__), 'config'), supports_root_ns=False 'test', join(dirname(__file__), 'config'), supports_root_ns=False


Loading…
Cancel
Save