Browse Source

Add value status support to Route53 dynamic

pull/819/head
Ross McFarland 4 years ago
parent
commit
7a32e4c912
No known key found for this signature in database GPG Key ID: 943B179E15D3B22A
1 changed files with 48 additions and 9 deletions
  1. +48
    -9
      octodns/provider/route53.py

+ 48
- 9
octodns/provider/route53.py View File

@ -80,9 +80,11 @@ class _Route53Record(EqualityTupleMixin):
# be served out according to their weights
for i, value in enumerate(pool.data['values']):
weight = value['weight']
status = value['status']
value = value['value']
ret.add(_Route53DynamicValue(provider, record, pool_name,
value, weight, i, creating))
value, weight, status, i,
creating))
# Rules
for i, rule in enumerate(record.dynamic.rules):
@ -345,19 +347,21 @@ class _Route53DynamicRule(_Route53Record):
class _Route53DynamicValue(_Route53Record):
def __init__(self, provider, record, pool_name, value, weight, index,
creating):
def __init__(self, provider, record, pool_name, value, weight, status,
index, creating):
fqdn_override = f'_octodns-{pool_name}-value.{record.fqdn}'
super(_Route53DynamicValue, self).__init__(provider, record, creating,
fqdn_override=fqdn_override)
self.pool_name = pool_name
self.status = status
self.index = index
value_convert = getattr(self, f'_value_convert_{record._type}')
self.value = value_convert(value, record)
self.weight = weight
self.health_check_id = provider.get_health_check_id(record, self.value,
self.status,
creating)
@property
@ -433,7 +437,7 @@ class _Route53GeoRecord(_Route53Record):
value = geo.values[0]
self.health_check_id = provider.get_health_check_id(record, value,
creating)
'obey', creating)
def mod(self, action, existing_rrsets):
geo = self.geo
@ -599,6 +603,7 @@ class Route53Provider(BaseProvider):
'''
SUPPORTS_GEO = True
SUPPORTS_DYNAMIC = True
SUPPORTS_POOL_VALUE_STATUS = True
SUPPORTS = set(('A', 'AAAA', 'CAA', 'CNAME', 'MX', 'NAPTR', 'NS', 'PTR',
'SPF', 'SRV', 'TXT'))
@ -914,7 +919,25 @@ class Route53Provider(BaseProvider):
# it's ignored only used to make sure the value is unique
pool_name = rrset['SetIdentifier'][:-4]
value = rrset['ResourceRecords'][0]['Value']
try:
health_check_id = rrset.get('HealthCheckId', None)
health_check = self.health_checks[health_check_id]
health_check_config = health_check['HealthCheckConfig']
if health_check_config['Disabled']:
if health_check_config['Inverted']:
# disabled and inverted means down
status = 'down'
else:
# disabled means always up
status = 'up'
else:
# otherwise obey
status = 'obey'
except KeyError:
# No healthcheck implies status is always up
status = 'up'
pools[pool_name]['values'].append({
'status': status,
'value': value,
'weight': rrset['Weight'],
})
@ -1092,7 +1115,8 @@ class Route53Provider(BaseProvider):
def _health_check_equivalent(self, host, path, protocol, port,
measure_latency, request_interval,
health_check, value=None):
health_check, value=None, disabled=None,
inverted=None):
config = health_check['HealthCheckConfig']
# So interestingly Route53 normalizes IPv6 addresses to a funky, but
@ -1115,16 +1139,18 @@ class Route53Provider(BaseProvider):
port == config['Port'] and \
measure_latency == config['MeasureLatency'] and \
request_interval == config['RequestInterval'] and \
(disabled is None or disabled == config['Disabled']) and \
(inverted is None or inverted == config['Inverted']) and \
value == config_ip_address
def get_health_check_id(self, record, value, create):
def get_health_check_id(self, record, value, status, create):
# fqdn & the first value are special, we use them to match up health
# checks to their records. Route53 health checks check a single ip and
# we're going to assume that ips are interchangeable to avoid
# health-checking each one independently
fqdn = record.fqdn
self.log.debug('get_health_check_id: fqdn=%s, type=%s, value=%s',
fqdn, record._type, value)
self.log.debug('get_health_check_id: fqdn=%s, type=%s, value=%s, '
'status=%s', fqdn, record._type, value, status)
try:
ip_address(str(value))
@ -1140,6 +1166,15 @@ class Route53Provider(BaseProvider):
healthcheck_port = record.healthcheck_port
healthcheck_latency = self._healthcheck_measure_latency(record)
healthcheck_interval = self._healthcheck_request_interval(record)
if status == 'up':
healthcheck_disabled = True
healthcheck_inverted = False
elif status == 'down':
healthcheck_disabled = True
healthcheck_inverted = True
else:
healthcheck_disabled = False
healthcheck_inverted = False
# we're looking for a healthcheck with the current version & our record
# type, we'll ignore anything else
@ -1156,7 +1191,9 @@ class Route53Provider(BaseProvider):
healthcheck_latency,
healthcheck_interval,
health_check,
value=value):
value=value,
disabled=healthcheck_disabled,
inverted=healthcheck_inverted):
# this is the health check we're looking for
self.log.debug('get_health_check_id: found match id=%s', id)
return id
@ -1168,6 +1205,8 @@ class Route53Provider(BaseProvider):
# no existing matches, we need to create a new health check
config = {
'Disabled': healthcheck_disabled,
'Inverted': healthcheck_inverted,
'EnableSNI': healthcheck_protocol == 'HTTPS',
'FailureThreshold': 6,
'MeasureLatency': healthcheck_latency,


Loading…
Cancel
Save