mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
Add: Ability to manage "proxied" flag of "A", "AAAA" and "CNAME" records via
YAML configuration (see "CloudflareProvider" class docstring for details).
This commit is contained in:
@@ -6,6 +6,7 @@ from __future__ import absolute_import, division, print_function, \
|
||||
unicode_literals
|
||||
|
||||
from collections import defaultdict
|
||||
from copy import deepcopy
|
||||
from logging import getLogger
|
||||
from requests import Session
|
||||
|
||||
@@ -27,6 +28,9 @@ class CloudflareAuthenticationError(CloudflareError):
|
||||
CloudflareError.__init__(self, data)
|
||||
|
||||
|
||||
_PROXIABLE_RECORD_TYPES = {'A', 'AAAA', 'CNAME'}
|
||||
|
||||
|
||||
class CloudflareProvider(BaseProvider):
|
||||
'''
|
||||
Cloudflare DNS provider
|
||||
@@ -221,7 +225,14 @@ class CloudflareProvider(BaseProvider):
|
||||
data_for = getattr(self, '_data_for_{}'.format(_type))
|
||||
data = data_for(_type, records)
|
||||
|
||||
return Record.new(zone, name, data, source=self, lenient=lenient)
|
||||
record = Record.new(zone, name, data, source=self, lenient=lenient)
|
||||
|
||||
if _type in _PROXIABLE_RECORD_TYPES:
|
||||
record._octodns['cloudflare'] = {
|
||||
'proxied': records[0].get('proxied', False)
|
||||
}
|
||||
|
||||
return record
|
||||
|
||||
def populate(self, zone, target=False, lenient=False):
|
||||
self.log.debug('populate: name=%s, target=%s, lenient=%s', zone.name,
|
||||
@@ -260,8 +271,18 @@ class CloudflareProvider(BaseProvider):
|
||||
|
||||
def _include_change(self, change):
|
||||
if isinstance(change, Update):
|
||||
existing = change.existing.data
|
||||
new = change.new.data
|
||||
|
||||
# Cloudflare manages TTL of proxied records, so we should exclude
|
||||
# TTL from the comparison (to prevent false-positives).
|
||||
if self._record_is_proxied(change.existing):
|
||||
existing = deepcopy(change.existing.data)
|
||||
existing.update({
|
||||
'ttl': new['ttl']
|
||||
})
|
||||
else:
|
||||
existing = change.existing.data
|
||||
|
||||
new['ttl'] = max(self.MIN_TTL, new['ttl'])
|
||||
if new == existing:
|
||||
return False
|
||||
@@ -322,6 +343,12 @@ class CloudflareProvider(BaseProvider):
|
||||
}
|
||||
}
|
||||
|
||||
def _record_is_proxied(self, record):
|
||||
return (
|
||||
not self.cdn and
|
||||
record._octodns.get('cloudflare', {}).get('proxied', False)
|
||||
)
|
||||
|
||||
def _gen_data(self, record):
|
||||
name = record.fqdn[:-1]
|
||||
_type = record._type
|
||||
@@ -338,6 +365,12 @@ class CloudflareProvider(BaseProvider):
|
||||
'type': _type,
|
||||
'ttl': ttl,
|
||||
})
|
||||
|
||||
if _type in _PROXIABLE_RECORD_TYPES:
|
||||
content.update({
|
||||
'proxied': self._record_is_proxied(record)
|
||||
})
|
||||
|
||||
yield content
|
||||
|
||||
def _gen_key(self, data):
|
||||
@@ -512,3 +545,23 @@ class CloudflareProvider(BaseProvider):
|
||||
|
||||
# clear the cache
|
||||
self._zone_records.pop(name, None)
|
||||
|
||||
def _extra_changes(self, existing, desired, changes):
|
||||
extra_changes = []
|
||||
|
||||
existing_records = {r: r for r in existing.records}
|
||||
changed_records = {c.record for c in changes}
|
||||
|
||||
for desired_record in desired.records:
|
||||
if desired_record not in existing.records: # Will be created
|
||||
continue
|
||||
elif desired_record in changed_records: # Already being updated
|
||||
continue
|
||||
|
||||
existing_record = existing_records[desired_record]
|
||||
|
||||
if (self._record_is_proxied(existing_record) !=
|
||||
self._record_is_proxied(desired_record)):
|
||||
extra_changes.append(Update(existing_record, desired_record))
|
||||
|
||||
return extra_changes
|
||||
|
||||
Reference in New Issue
Block a user