diff --git a/octodns/record.py b/octodns/record.py index 570988b..163efc1 100644 --- a/octodns/record.py +++ b/octodns/record.py @@ -112,6 +112,9 @@ class Record(object): raise Exception('Invalid record {}, missing ttl'.format(self.fqdn)) self.source = source + octodns = data.get('octodns', {}) + self.ignored = octodns.get('ignored', False) + def _data(self): return {'ttl': self.ttl} diff --git a/octodns/zone.py b/octodns/zone.py index e9c64b4..1822fec 100644 --- a/octodns/zone.py +++ b/octodns/zone.py @@ -76,8 +76,12 @@ class Zone(object): # Find diffs & removes for record in filter(_is_eligible, self.records): + if record.ignored: + continue try: desired_record = desired_records[record] + if desired_record.ignored: + continue except KeyError: if not target.supports(record): self.log.debug('changes: skipping record=%s %s - %s does ' @@ -103,6 +107,8 @@ class Zone(object): # This uses set math and our special __hash__ and __cmp__ functions as # well for record in filter(_is_eligible, desired.records - self.records): + if record.ignored: + 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 c71638b..d18bf59 100644 --- a/tests/config/unit.tests.yaml +++ b/tests/config/unit.tests.yaml @@ -51,6 +51,11 @@ cname: ttl: 300 type: CNAME value: unit.tests. +ignored: + octodns: + ignored: true + type: A + value: 9.9.9.9 mx: ttl: 300 type: MX diff --git a/tests/test_octodns_provider_dnsimple.py b/tests/test_octodns_provider_dnsimple.py index ace7376..1f62bfd 100644 --- a/tests/test_octodns_provider_dnsimple.py +++ b/tests/test_octodns_provider_dnsimple.py @@ -129,8 +129,8 @@ class TestDnsimpleProvider(TestCase): ] plan = provider.plan(self.expected) - # No root NS - n = len(self.expected.records) - 1 + # No root NS, no ignored + n = len(self.expected.records) - 2 self.assertEquals(n, len(plan.changes)) self.assertEquals(n, provider.apply(plan)) diff --git a/tests/test_octodns_provider_powerdns.py b/tests/test_octodns_provider_powerdns.py index fd2752c..01e7d83 100644 --- a/tests/test_octodns_provider_powerdns.py +++ b/tests/test_octodns_provider_powerdns.py @@ -78,7 +78,8 @@ class TestPowerDnsProvider(TestCase): expected = Zone('unit.tests.', []) source = YamlProvider('test', join(dirname(__file__), 'config')) source.populate(expected) - self.assertEquals(14, len(expected.records)) + expected_n = len(expected.records) - 1 + self.assertEquals(14, expected_n) # No diffs == no changes with requests_mock() as mock: @@ -93,7 +94,7 @@ class TestPowerDnsProvider(TestCase): # Used in a minute def assert_rrsets_callback(request, context): data = loads(request.body) - self.assertEquals(len(expected.records), len(data['rrsets'])) + self.assertEquals(expected_n, len(data['rrsets'])) return '' # No existing records -> creates for every record in expected @@ -103,8 +104,8 @@ class TestPowerDnsProvider(TestCase): mock.patch(ANY, status_code=201, text=assert_rrsets_callback) plan = provider.plan(expected) - self.assertEquals(len(expected.records), len(plan.changes)) - self.assertEquals(len(expected.records), provider.apply(plan)) + self.assertEquals(expected_n, len(plan.changes)) + self.assertEquals(expected_n, provider.apply(plan)) # Non-existent zone -> creates for every record in expected # OMG this is fucking ugly, probably better to ditch requests_mocks and @@ -121,8 +122,8 @@ class TestPowerDnsProvider(TestCase): mock.post(ANY, status_code=201, text=assert_rrsets_callback) plan = provider.plan(expected) - self.assertEquals(len(expected.records), len(plan.changes)) - self.assertEquals(len(expected.records), provider.apply(plan)) + self.assertEquals(expected_n, len(plan.changes)) + self.assertEquals(expected_n, provider.apply(plan)) with requests_mock() as mock: # get 422's, unknown zone @@ -166,7 +167,7 @@ class TestPowerDnsProvider(TestCase): expected = Zone('unit.tests.', []) source = YamlProvider('test', join(dirname(__file__), 'config')) source.populate(expected) - self.assertEquals(14, len(expected.records)) + self.assertEquals(15, 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 a557bb3..05c5248 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(14, len(zone.records)) + self.assertEquals(15, 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 diff --git a/tests/test_octodns_zone.py b/tests/test_octodns_zone.py index da83dfc..88bbb68 100644 --- a/tests/test_octodns_zone.py +++ b/tests/test_octodns_zone.py @@ -172,3 +172,36 @@ class TestZone(TestCase): with self.assertRaises(SubzoneRecordException) as ctx: zone.add_record(record) self.assertTrue('under a managed sub-zone', ctx.exception.message) + + def test_ignored_records(self): + zone_normal = Zone('unit.tests.', []) + zone_ignored = Zone('unit.tests.', []) + zone_missing = Zone('unit.tests.', []) + + normal = Record.new(zone_normal, 'www', { + 'ttl': 60, + 'type': 'A', + 'value': '9.9.9.9', + }) + zone_normal.add_record(normal) + + ignored = Record.new(zone_ignored, 'www', { + 'octodns': { + 'ignored': True + }, + 'ttl': 60, + 'type': 'A', + 'value': '9.9.9.9', + }) + zone_ignored.add_record(ignored) + + provider = SimpleProvider() + + self.assertFalse(zone_normal.changes(zone_ignored, provider)) + self.assertTrue(zone_normal.changes(zone_missing, provider)) + + self.assertFalse(zone_ignored.changes(zone_normal, provider)) + self.assertFalse(zone_ignored.changes(zone_missing, provider)) + + self.assertTrue(zone_missing.changes(zone_normal, provider)) + self.assertFalse(zone_missing.changes(zone_ignored, provider))