Browse Source

Merge pull request #1343 from octodns/ignore-missing-zones

Add ignore_missing_zones parameter to YamlProvider
pull/1344/head
Ross McFarland 3 weeks ago
committed by GitHub
parent
commit
bce3b24e8c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
3 changed files with 74 additions and 2 deletions
  1. +4
    -0
      .changelog/a036eb2d018549f0952f01e0790e8f32.md
  2. +9
    -2
      octodns/provider/yaml.py
  3. +61
    -0
      tests/test_octodns_provider_yaml.py

+ 4
- 0
.changelog/a036eb2d018549f0952f01e0790e8f32.md View File

@ -0,0 +1,4 @@
---
type: minor
---
Add ignore_missing_zones parameter to YamlProvider

+ 9
- 2
octodns/provider/yaml.py View File

@ -64,6 +64,10 @@ Core provider for records configured in yaml files on disk::
# (optional, default True)
escaped_semicolons: True
# Whether to ignore missing zone files when used as a source
# (optional, default False)
ignore_missing_zones: False
.. Note::
When using this provider as a target any existing comments or formatting in
@ -203,13 +207,14 @@ class YamlProvider(BaseProvider):
shared_filename=False,
disable_zonefile=False,
escaped_semicolons=True,
ignore_missing_zones=False,
*args,
**kwargs,
):
klass = self.__class__.__name__
self.log = logging.getLogger(f'{klass}[{id}]')
self.log.debug(
'__init__: id=%s, directory=%s, default_ttl=%d, enforce_order=%d, order_mode=%s, populate_should_replace=%s, supports_root_ns=%s, split_extension=%s, split_catchall=%s, shared_filename=%s, disable_zonefile=%s, escaped_semicolons=%s',
'__init__: id=%s, directory=%s, default_ttl=%d, enforce_order=%d, order_mode=%s, populate_should_replace=%s, supports_root_ns=%s, split_extension=%s, split_catchall=%s, shared_filename=%s, disable_zonefile=%s, escaped_semicolons=%s, ignore_missing_zones=%s',
id,
directory,
default_ttl,
@ -222,6 +227,7 @@ class YamlProvider(BaseProvider):
shared_filename,
disable_zonefile,
escaped_semicolons,
ignore_missing_zones,
)
super().__init__(id, *args, **kwargs)
self.directory = directory
@ -235,6 +241,7 @@ class YamlProvider(BaseProvider):
self.shared_filename = shared_filename
self.disable_zonefile = disable_zonefile
self.escaped_semicolons = escaped_semicolons
self.ignore_missing_zones = ignore_missing_zones
def copy(self):
kwargs = dict(self.__dict__)
@ -388,7 +395,7 @@ class YamlProvider(BaseProvider):
if self.shared_filename:
sources.append(join(self.directory, self.shared_filename))
if not sources and not target:
if not sources and not target and not self.ignore_missing_zones:
raise ProviderException(f'no YAMLs found for {zone.decoded_name}')
# deterministically order our sources


+ 61
- 0
tests/test_octodns_provider_yaml.py View File

@ -242,6 +242,67 @@ xn--dj-kia8a:
source.populate(zone)
self.assertEqual(0, len(zone.records))
def test_ignore_missing_zones(self):
# Test that ignore_missing_zones prevents errors when zone files are missing
with TemporaryDirectory() as td:
directory = td.dirname
# Create a provider with ignore_missing_zones disabled (default)
provider = YamlProvider(
'test', directory, ignore_missing_zones=False
)
zone = Zone('missing.zone.', [])
# Should raise an exception when zone file is missing
with self.assertRaises(ProviderException) as ctx:
provider.populate(zone)
self.assertEqual(
'no YAMLs found for missing.zone.', str(ctx.exception)
)
# Create a provider with ignore_missing_zones enabled
provider = YamlProvider(
'test', directory, ignore_missing_zones=True
)
zone = Zone('missing.zone.', [])
# Should not raise an exception and should return False (zone doesn't exist)
exists = provider.populate(zone)
self.assertFalse(exists)
self.assertEqual(0, len(zone.records))
# Test with multiple sources where some have the zone and some don't
# Create one zone file
zone_file = join(directory, 'exists.zone.yaml')
with open(zone_file, 'w') as fh:
fh.write(
'''---
www:
type: A
value: 1.2.3.4
'''
)
# Create a second directory without the zone file
directory2 = join(td.dirname, 'other')
makedirs(directory2)
# Provider 1 has the zone
provider1 = YamlProvider('test1', directory)
# Provider 2 doesn't have the zone but ignores missing
provider2 = YamlProvider(
'test2', directory2, ignore_missing_zones=True
)
zone = Zone('exists.zone.', [])
provider1.populate(zone)
self.assertEqual(1, len(zone.records))
# Provider 2 should not error when the zone is missing
provider2.populate(zone)
# Still just 1 record from provider1
self.assertEqual(1, len(zone.records))
def test_unsorted(self):
source = YamlProvider(
'test', join(dirname(__file__), 'config'), supports_root_ns=False


Loading…
Cancel
Save