1
0
mirror of https://github.com/github/octodns.git synced 2024-05-11 05:55:00 +00:00

Merge branch 'master' into configurable-geo-healthcheck

This commit is contained in:
Dirkjan Bussink
2018-03-22 08:51:51 +01:00
71 changed files with 5717 additions and 551 deletions

View File

@@ -7,78 +7,7 @@ from __future__ import absolute_import, division, print_function, \
from ..source.base import BaseSource
from ..zone import Zone
from logging import getLogger
class UnsafePlan(Exception):
pass
class Plan(object):
log = getLogger('Plan')
MAX_SAFE_UPDATE_PCENT = .3
MAX_SAFE_DELETE_PCENT = .3
MIN_EXISTING_RECORDS = 10
def __init__(self, existing, desired, changes,
update_pcent_threshold=MAX_SAFE_UPDATE_PCENT,
delete_pcent_threshold=MAX_SAFE_DELETE_PCENT):
self.existing = existing
self.desired = desired
self.changes = changes
self.update_pcent_threshold = update_pcent_threshold
self.delete_pcent_threshold = delete_pcent_threshold
change_counts = {
'Create': 0,
'Delete': 0,
'Update': 0
}
for change in changes:
change_counts[change.__class__.__name__] += 1
self.change_counts = change_counts
try:
existing_n = len(self.existing.records)
except AttributeError:
existing_n = 0
self.log.debug('__init__: Creates=%d, Updates=%d, Deletes=%d'
'Existing=%d',
self.change_counts['Create'],
self.change_counts['Update'],
self.change_counts['Delete'], existing_n)
def raise_if_unsafe(self):
# TODO: what is safe really?
if self.existing and \
len(self.existing.records) >= self.MIN_EXISTING_RECORDS:
existing_record_count = len(self.existing.records)
update_pcent = self.change_counts['Update'] / existing_record_count
delete_pcent = self.change_counts['Delete'] / existing_record_count
if update_pcent > self.update_pcent_threshold:
raise UnsafePlan('Too many updates, {} is over {} percent'
'({}/{})'.format(
update_pcent,
self.MAX_SAFE_UPDATE_PCENT * 100,
self.change_counts['Update'],
existing_record_count))
if delete_pcent > self.delete_pcent_threshold:
raise UnsafePlan('Too many deletes, {} is over {} percent'
'({}/{})'.format(
delete_pcent,
self.MAX_SAFE_DELETE_PCENT * 100,
self.change_counts['Delete'],
existing_record_count))
def __repr__(self):
return 'Creates={}, Updates={}, Deletes={}, Existing Records={}' \
.format(self.change_counts['Create'], self.change_counts['Update'],
self.change_counts['Delete'],
len(self.existing.records))
from .plan import Plan
class BaseProvider(BaseSource):
@@ -88,7 +17,8 @@ class BaseProvider(BaseSource):
delete_pcent_threshold=Plan.MAX_SAFE_DELETE_PCENT):
super(BaseProvider, self).__init__(id)
self.log.debug('__init__: id=%s, apply_disabled=%s, '
'update_pcent_threshold=%d, delete_pcent_threshold=%d',
'update_pcent_threshold=%.2f'
'delete_pcent_threshold=%.2f',
id,
apply_disabled,
update_pcent_threshold,
@@ -100,14 +30,14 @@ class BaseProvider(BaseSource):
def _include_change(self, change):
'''
An opportunity for providers to filter out false positives due to
pecularities in their implementation. E.g. minimum TTLs.
peculiarities in their implementation. E.g. minimum TTLs.
'''
return True
def _extra_changes(self, existing, desired, changes):
'''
An opportunity for providers to add extra changes to the plan that are
necessary to update ancilary record data or configure the zone. E.g.
necessary to update ancillary record data or configure the zone. E.g.
base NS records.
'''
return []
@@ -116,7 +46,12 @@ class BaseProvider(BaseSource):
self.log.info('plan: desired=%s', desired.name)
existing = Zone(desired.name, desired.sub_zones)
self.populate(existing, target=True, lenient=True)
exists = self.populate(existing, target=True, lenient=True)
if exists is None:
# If your code gets this warning see Source.populate for more
# information
self.log.warn('Provider %s used in target mode did not return '
'exists', self.id)
# compute the changes at the zone/record level
changes = existing.changes(desired, self)
@@ -132,11 +67,11 @@ class BaseProvider(BaseSource):
extra = self._extra_changes(existing, desired, changes)
if extra:
self.log.info('plan: extra changes\n %s', '\n '
.join([str(c) for c in extra]))
.join([unicode(c) for c in extra]))
changes += extra
if changes:
plan = Plan(existing, desired, changes,
plan = Plan(existing, desired, changes, exists,
self.update_pcent_threshold,
self.delete_pcent_threshold)
self.log.info('plan: %s', plan)