diff --git a/octodns/record.py b/octodns/record.py index 8ef80be..8a05b9e 100644 --- a/octodns/record.py +++ b/octodns/record.py @@ -124,6 +124,8 @@ class Record(object): octodns = data.get('octodns', {}) self.ignored = octodns.get('ignored', False) + self.excluded = octodns.get('excluded', []) + self.included = octodns.get('included', []) def _data(self): return {'ttl': self.ttl} diff --git a/octodns/zone.py b/octodns/zone.py index 74e5d9e..f715e3f 100644 --- a/octodns/zone.py +++ b/octodns/zone.py @@ -110,10 +110,29 @@ class Zone(object): for record in filter(_is_eligible, self.records): if record.ignored: continue + elif len(record.included) > 0 and \ + target.__class__.__name__ not in record.included: + self.log.debug('changes: skipping record=%s %s - %s not' + ' included ', record.fqdn, record._type, + target.id) + continue + elif target.__class__.__name__ in record.excluded: + self.log.debug('changes: skipping record=%s %s - %s ' + 'excluded ', record.fqdn, record._type, + target.id) + continue try: desired_record = desired_records[record] if desired_record.ignored: continue + elif len(record.included) > 0 and \ + target.__class__.__name__ not in record.included: + self.log.debug('changes: skipping record=%s %s - %s' + 'not included ', record.fqdn, record._type, + target.id) + continue + elif target.__class__.__name__ in record.excluded: + continue except KeyError: if not target.supports(record): self.log.debug('changes: skipping record=%s %s - %s does ' @@ -141,6 +160,18 @@ class Zone(object): for record in filter(_is_eligible, desired.records - self.records): if record.ignored: continue + elif len(record.included) > 0 and \ + target.__class__.__name__ not in record.included: + self.log.debug('changes: skipping record=%s %s - %s not' + ' included ', record.fqdn, record._type, + target.id) + continue + elif target.__class__.__name__ in record.excluded: + self.log.debug('changes: skipping record=%s %s - %s ' + 'excluded ', record.fqdn, record._type, + target.id) + continue + if not target.supports(record): self.log.debug('changes: skipping record=%s %s - %s does not ' 'support it', record.fqdn, record._type, diff --git a/tests/config/unit.tests.yaml b/tests/config/unit.tests.yaml index 5241406..548dc8f 100644 --- a/tests/config/unit.tests.yaml +++ b/tests/config/unit.tests.yaml @@ -56,11 +56,23 @@ cname: ttl: 300 type: CNAME value: unit.tests. +excluded: + octodns: + excluded: + - CloudflareProvider + type: CNAME + value: excluded.unit.tests. ignored: octodns: ignored: true type: A value: 9.9.9.9 +included: + octodns: + included: + - DnsimpleProvider + type: CNAME + value: included.unit.tests. mx: ttl: 300 type: MX diff --git a/tests/fixtures/dnsimple-page-2.json b/tests/fixtures/dnsimple-page-2.json index 40aaa48..d66c8da 100644 --- a/tests/fixtures/dnsimple-page-2.json +++ b/tests/fixtures/dnsimple-page-2.json @@ -175,6 +175,38 @@ "system_record": false, "created_at": "2017-03-09T15:55:09Z", "updated_at": "2017-03-09T15:55:09Z" + }, + { + "id": 12188804, + "zone_id": "unit.tests", + "parent_id": null, + "name": "excluded", + "content": "excluded.unit.tests", + "ttl": 3600, + "priority": null, + "type": "CNAME", + "regions": [ + "global" + ], + "system_record": false, + "created_at": "2017-03-09T15:55:09Z", + "updated_at": "2017-03-09T15:55:09Z" + }, + { + "id": 12188805, + "zone_id": "unit.tests", + "parent_id": null, + "name": "included", + "content": "included.unit.tests", + "ttl": 3600, + "priority": null, + "type": "CNAME", + "regions": [ + "global" + ], + "system_record": false, + "created_at": "2017-03-09T15:55:09Z", + "updated_at": "2017-03-09T15:55:09Z" } ], "pagination": { diff --git a/tests/fixtures/powerdns-full-data.json b/tests/fixtures/powerdns-full-data.json index b8f8bf3..2d7117a 100644 --- a/tests/fixtures/powerdns-full-data.json +++ b/tests/fixtures/powerdns-full-data.json @@ -242,6 +242,18 @@ ], "ttl": 3600, "type": "CAA" + }, + { + "comments": [], + "name": "excluded.unit.tests.", + "records": [ + { + "content": "excluded.unit.tests.", + "disabled": false + } + ], + "ttl": 3600, + "type": "CNAME" } ], "serial": 2017012803, diff --git a/tests/test_octodns_manager.py b/tests/test_octodns_manager.py index 45a3b55..2b947b5 100644 --- a/tests/test_octodns_manager.py +++ b/tests/test_octodns_manager.py @@ -101,12 +101,12 @@ class TestManager(TestCase): environ['YAML_TMP_DIR'] = tmpdir.dirname tc = Manager(get_config_filename('simple.yaml')) \ .sync(dry_run=False) - self.assertEquals(19, tc) + self.assertEquals(20, tc) # try with just one of the zones tc = Manager(get_config_filename('simple.yaml')) \ .sync(dry_run=False, eligible_zones=['unit.tests.']) - self.assertEquals(13, tc) + self.assertEquals(14, tc) # the subzone, with 2 targets tc = Manager(get_config_filename('simple.yaml')) \ @@ -121,18 +121,18 @@ class TestManager(TestCase): # Again with force tc = Manager(get_config_filename('simple.yaml')) \ .sync(dry_run=False, force=True) - self.assertEquals(19, tc) + self.assertEquals(20, tc) # Again with max_workers = 1 tc = Manager(get_config_filename('simple.yaml'), max_workers=1) \ .sync(dry_run=False, force=True) - self.assertEquals(19, tc) + self.assertEquals(20, tc) # Include meta tc = Manager(get_config_filename('simple.yaml'), max_workers=1, include_meta=True) \ .sync(dry_run=False, force=True) - self.assertEquals(23, tc) + self.assertEquals(24, tc) def test_eligible_targets(self): with TemporaryDirectory() as tmpdir: @@ -158,13 +158,13 @@ class TestManager(TestCase): fh.write('---\n{}') changes = manager.compare(['in'], ['dump'], 'unit.tests.') - self.assertEquals(13, len(changes)) + self.assertEquals(14, len(changes)) # Compound sources with varying support changes = manager.compare(['in', 'nosshfp'], ['dump'], 'unit.tests.') - self.assertEquals(12, len(changes)) + self.assertEquals(13, len(changes)) with self.assertRaises(Exception) as ctx: manager.compare(['nope'], ['dump'], 'unit.tests.') diff --git a/tests/test_octodns_provider_dnsimple.py b/tests/test_octodns_provider_dnsimple.py index 950d460..befb39e 100644 --- a/tests/test_octodns_provider_dnsimple.py +++ b/tests/test_octodns_provider_dnsimple.py @@ -78,14 +78,14 @@ class TestDnsimpleProvider(TestCase): zone = Zone('unit.tests.', []) provider.populate(zone) - self.assertEquals(15, len(zone.records)) + self.assertEquals(17, len(zone.records)) changes = self.expected.changes(zone, provider) self.assertEquals(0, len(changes)) # 2nd populate makes no network calls/all from cache again = Zone('unit.tests.', []) provider.populate(again) - self.assertEquals(15, len(again.records)) + self.assertEquals(17, len(again.records)) # bust the cache del provider._zone_records[zone.name] @@ -147,7 +147,7 @@ class TestDnsimpleProvider(TestCase): }), ]) # expected number of total calls - self.assertEquals(27, provider._client._request.call_count) + self.assertEquals(29, provider._client._request.call_count) provider._client._request.reset_mock() diff --git a/tests/test_octodns_provider_powerdns.py b/tests/test_octodns_provider_powerdns.py index b6e02ff..22ccdd6 100644 --- a/tests/test_octodns_provider_powerdns.py +++ b/tests/test_octodns_provider_powerdns.py @@ -78,8 +78,8 @@ class TestPowerDnsProvider(TestCase): expected = Zone('unit.tests.', []) source = YamlProvider('test', join(dirname(__file__), 'config')) source.populate(expected) - expected_n = len(expected.records) - 1 - self.assertEquals(15, expected_n) + expected_n = len(expected.records) - 2 + self.assertEquals(16, expected_n) # No diffs == no changes with requests_mock() as mock: @@ -87,7 +87,7 @@ class TestPowerDnsProvider(TestCase): zone = Zone('unit.tests.', []) provider.populate(zone) - self.assertEquals(15, len(zone.records)) + self.assertEquals(16, len(zone.records)) changes = expected.changes(zone, provider) self.assertEquals(0, len(changes)) @@ -167,7 +167,7 @@ class TestPowerDnsProvider(TestCase): expected = Zone('unit.tests.', []) source = YamlProvider('test', join(dirname(__file__), 'config')) source.populate(expected) - self.assertEquals(16, len(expected.records)) + self.assertEquals(18, len(expected.records)) # A small change to a single record with requests_mock() as mock: diff --git a/tests/test_octodns_provider_yaml.py b/tests/test_octodns_provider_yaml.py index 36cd8d6..a199355 100644 --- a/tests/test_octodns_provider_yaml.py +++ b/tests/test_octodns_provider_yaml.py @@ -30,7 +30,7 @@ class TestYamlProvider(TestCase): # without it we see everything source.populate(zone) - self.assertEquals(16, len(zone.records)) + self.assertEquals(18, len(zone.records)) # Assumption here is that a clean round-trip means that everything # worked as expected, data that went in came back out and could be @@ -49,12 +49,12 @@ class TestYamlProvider(TestCase): # We add everything plan = target.plan(zone) - self.assertEquals(13, len(filter(lambda c: isinstance(c, Create), + self.assertEquals(14, len(filter(lambda c: isinstance(c, Create), plan.changes))) self.assertFalse(isfile(yaml_file)) # Now actually do it - self.assertEquals(13, target.apply(plan)) + self.assertEquals(14, target.apply(plan)) self.assertTrue(isfile(yaml_file)) # There should be no changes after the round trip @@ -64,7 +64,7 @@ class TestYamlProvider(TestCase): # A 2nd sync should still create everything plan = target.plan(zone) - self.assertEquals(13, len(filter(lambda c: isinstance(c, Create), + self.assertEquals(14, len(filter(lambda c: isinstance(c, Create), plan.changes))) with open(yaml_file) as fh: