Implement pool-level fallbacks and validations

This commit is contained in:
Ross McFarland
2018-12-07 14:29:05 -08:00
parent e3b0ce9dcf
commit a767a5cb25
2 changed files with 125 additions and 0 deletions
+19
View File
@@ -509,6 +509,25 @@ class _DynamicMixin(object):
reasons.append('missing value in pool "{}" '
'value {}'.format(_id, value_num))
fallback = pool.get('fallback', None)
if fallback is not None and fallback not in pools:
reasons.append('undefined fallback "{}" for pool "{}"'
.format(fallback, _id))
# Check for loops
fallback = pools[_id].get('fallback', None)
seen = [_id, fallback]
while fallback is not None:
# See if there's a next fallback
fallback = pools.get(fallback, {}).get('fallback', None)
if fallback in seen:
seen = ' -> '.join(seen)
reasons.append('loop in pool fallbacks: {}'
.format(seen))
# exit the loop
break
seen.append(fallback)
try:
rules = data['dynamic']['rules']
except KeyError:
+106
View File
@@ -2177,6 +2177,7 @@ class TestDynamicRecords(TestCase):
}],
},
'two': {
'fallback': 'one',
'values': [{
'value': '4.4.4.4',
}, {
@@ -2184,6 +2185,7 @@ class TestDynamicRecords(TestCase):
}]
},
'three': {
'fallback': 'two',
'values': [{
'weight': 1,
'value': '5.5.5.5',
@@ -2446,6 +2448,110 @@ class TestDynamicRecords(TestCase):
self.assertEquals(['invalid weight "foo" in pool "three" value 2'],
ctx.exception.reasons)
# invalid fallback
a_data = {
'dynamic': {
'pools': {
'one': {
'values': [{
'value': '3.3.3.3',
}],
},
'two': {
'fallback': 'invalid',
'values': [{
'value': '4.4.4.4',
}, {
'value': '5.5.5.5',
}]
},
'three': {
'fallback': 'two',
'values': [{
'weight': 1,
'value': '6.6.6.6',
}, {
'weight': 5,
'value': '7.7.7.7',
}],
},
},
'rules': [{
'geos': ['AF', 'EU'],
'pool': 'three',
}, {
'geos': ['NA-US-CA'],
'pool': 'two',
}, {
'pool': 'one',
}],
},
'ttl': 60,
'type': 'A',
'values': [
'1.1.1.1',
'2.2.2.2',
],
}
with self.assertRaises(ValidationError) as ctx:
Record.new(self.zone, 'bad', a_data)
self.assertEquals(['undefined fallback "invalid" for pool "two"'],
ctx.exception.reasons)
# fallback loop
a_data = {
'dynamic': {
'pools': {
'one': {
'fallback': 'three',
'values': [{
'value': '3.3.3.3',
}],
},
'two': {
'fallback': 'one',
'values': [{
'value': '4.4.4.4',
}, {
'value': '5.5.5.5',
}]
},
'three': {
'fallback': 'two',
'values': [{
'weight': 1,
'value': '6.6.6.6',
}, {
'weight': 5,
'value': '7.7.7.7',
}],
},
},
'rules': [{
'geos': ['AF', 'EU'],
'pool': 'three',
}, {
'geos': ['NA-US-CA'],
'pool': 'two',
}, {
'pool': 'one',
}],
},
'ttl': 60,
'type': 'A',
'values': [
'1.1.1.1',
'2.2.2.2',
],
}
with self.assertRaises(ValidationError) as ctx:
Record.new(self.zone, 'bad', a_data)
self.assertEquals([
'loop in pool fallbacks: one -> three -> two',
'loop in pool fallbacks: three -> two -> one',
'loop in pool fallbacks: two -> one -> three'
], ctx.exception.reasons)
# multiple pool problems
a_data = {
'dynamic': {