mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
Merge pull request #753 from octodns/acme-ignoring-processor-with-ownership
Allow octoDNS managed _acme-challenge records to exist by marking them
This commit is contained in:
@@ -16,18 +16,33 @@ class AcmeIgnoringProcessor(BaseProcessor):
|
||||
def __init__(self, name):
|
||||
super(AcmeIgnoringProcessor, self).__init__(name)
|
||||
|
||||
def _process(self, zone, *args, **kwargs):
|
||||
self._owned = set()
|
||||
|
||||
def process_source_zone(self, zone, *args, **kwargs):
|
||||
ret = self._clone_zone(zone)
|
||||
for record in zone.records:
|
||||
if record._type == 'TXT' and \
|
||||
record.name.startswith('_acme-challenge'):
|
||||
# We have a managed acme challenge record (owned by octoDNS) so
|
||||
# we should mark it as such
|
||||
record = record.copy()
|
||||
record.values.append('*octoDNS*')
|
||||
record.values.sort()
|
||||
self._owned.add(record)
|
||||
ret.add_record(record)
|
||||
return ret
|
||||
|
||||
def process_target_zone(self, zone, *args, **kwargs):
|
||||
ret = self._clone_zone(zone)
|
||||
for record in zone.records:
|
||||
# Uses a startswith rather than == to ignore subdomain challenges,
|
||||
# e.g. _acme-challenge.foo.domain.com when managing domain.com
|
||||
if record._type == 'TXT' and \
|
||||
record.name.startswith('_acme-challenge'):
|
||||
record.name.startswith('_acme-challenge') and \
|
||||
'*octoDNS*' not in record.values and \
|
||||
record not in self._owned:
|
||||
self.log.info('_process: ignoring %s', record.fqdn)
|
||||
continue
|
||||
ret.add_record(record)
|
||||
|
||||
return ret
|
||||
|
||||
process_source_zone = _process
|
||||
process_target_zone = _process
|
||||
|
||||
@@ -12,40 +12,92 @@ from octodns.record import Record
|
||||
from octodns.zone import Zone
|
||||
|
||||
zone = Zone('unit.tests.', [])
|
||||
for record in [
|
||||
# Will be ignored
|
||||
Record.new(zone, '_acme-challenge', {
|
||||
records = {
|
||||
'root-unowned': Record.new(zone, '_acme-challenge', {
|
||||
'ttl': 30,
|
||||
'type': 'TXT',
|
||||
'value': 'magic bit',
|
||||
}),
|
||||
# Not TXT so will live
|
||||
Record.new(zone, '_acme-challenge.aaaa', {
|
||||
'sub-unowned': Record.new(zone, '_acme-challenge.sub-unowned', {
|
||||
'ttl': 30,
|
||||
'type': 'TXT',
|
||||
'value': 'magic bit',
|
||||
}),
|
||||
'not-txt': Record.new(zone, '_acme-challenge.not-txt', {
|
||||
'ttl': 30,
|
||||
'type': 'AAAA',
|
||||
'value': '::1',
|
||||
}),
|
||||
# Will be ignored
|
||||
Record.new(zone, '_acme-challenge.foo', {
|
||||
'ttl': 30,
|
||||
'type': 'TXT',
|
||||
'value': 'magic bit',
|
||||
}),
|
||||
# Not acme-challenge so will live
|
||||
Record.new(zone, 'txt', {
|
||||
'not-acme': Record.new(zone, 'not-acme', {
|
||||
'ttl': 30,
|
||||
'type': 'TXT',
|
||||
'value': 'Hello World!',
|
||||
}),
|
||||
]:
|
||||
zone.add_record(record)
|
||||
'managed': Record.new(zone, '_acme-challenge.managed', {
|
||||
'ttl': 30,
|
||||
'type': 'TXT',
|
||||
'value': 'magic bit',
|
||||
}),
|
||||
'owned': Record.new(zone, '_acme-challenge.owned', {
|
||||
'ttl': 30,
|
||||
'type': 'TXT',
|
||||
'values': ['*octoDNS*', 'magic bit'],
|
||||
}),
|
||||
'going-away': Record.new(zone, '_acme-challenge.going-away', {
|
||||
'ttl': 30,
|
||||
'type': 'TXT',
|
||||
'values': ['*octoDNS*', 'magic bit'],
|
||||
}),
|
||||
}
|
||||
|
||||
|
||||
class TestAcmeIgnoringProcessor(TestCase):
|
||||
|
||||
def test_basics(self):
|
||||
def test_process_zones(self):
|
||||
acme = AcmeIgnoringProcessor('acme')
|
||||
|
||||
got = acme.process_source_zone(zone)
|
||||
self.assertEquals(['_acme-challenge.aaaa', 'txt'],
|
||||
sorted([r.name for r in got.records]))
|
||||
source = Zone(zone.name, [])
|
||||
# Unrelated stuff that should be untouched
|
||||
source.add_record(records['not-txt'])
|
||||
source.add_record(records['not-acme'])
|
||||
# A managed acme that will have ownership value added
|
||||
source.add_record(records['managed'])
|
||||
|
||||
got = acme.process_source_zone(source)
|
||||
self.assertEquals([
|
||||
'_acme-challenge.managed',
|
||||
'_acme-challenge.not-txt',
|
||||
'not-acme',
|
||||
], sorted([r.name for r in got.records]))
|
||||
managed = None
|
||||
for record in got.records:
|
||||
print(record.name)
|
||||
if record.name.endswith('managed'):
|
||||
managed = record
|
||||
break
|
||||
self.assertTrue(managed)
|
||||
# Ownership was marked with an extra value
|
||||
self.assertEquals(['*octoDNS*', 'magic bit'], record.values)
|
||||
|
||||
existing = Zone(zone.name, [])
|
||||
# Unrelated stuff that should be untouched
|
||||
existing.add_record(records['not-txt'])
|
||||
existing.add_record(records['not-acme'])
|
||||
# Stuff that will be ignored
|
||||
existing.add_record(records['root-unowned'])
|
||||
existing.add_record(records['sub-unowned'])
|
||||
# A managed acme that needs ownership value added
|
||||
existing.add_record(records['managed'])
|
||||
# A managed acme that has ownershp managed
|
||||
existing.add_record(records['owned'])
|
||||
# A managed acme that needs to go away
|
||||
existing.add_record(records['going-away'])
|
||||
|
||||
got = acme.process_target_zone(existing)
|
||||
self.assertEquals([
|
||||
'_acme-challenge.going-away',
|
||||
'_acme-challenge.managed',
|
||||
'_acme-challenge.not-txt',
|
||||
'_acme-challenge.owned',
|
||||
'not-acme'
|
||||
], sorted([r.name for r in got.records]))
|
||||
|
||||
Reference in New Issue
Block a user