Browse Source

quick pass of hacks at getting cname going

pull/101/head
Ross McFarland 9 years ago
parent
commit
4ab357fb09
No known key found for this signature in database GPG Key ID: 61C10C4FC8FE4A89
2 changed files with 73 additions and 27 deletions
  1. +45
    -18
      octodns/provider/dyn.py
  2. +28
    -9
      octodns/provider/route53.py

+ 45
- 18
octodns/provider/dyn.py View File

@ -7,9 +7,9 @@ from __future__ import absolute_import, division, print_function, \
from collections import defaultdict
from dyn.tm.errors import DynectGetError
from dyn.tm.services.dsf import DSFARecord, DSFAAAARecord, DSFFailoverChain, \
DSFMonitor, DSFNode, DSFRecordSet, DSFResponsePool, DSFRuleset, \
TrafficDirector, get_all_dsf_monitors, get_all_dsf_services, \
from dyn.tm.services.dsf import DSFARecord, DSFAAAARecord, DSFCNAMERecord, \
DSFFailoverChain, DSFMonitor, DSFNode, DSFRecordSet, DSFResponsePool, \
DSFRuleset, TrafficDirector, get_all_dsf_monitors, get_all_dsf_services, \
get_response_pool
from dyn.tm.session import DynectSession
from dyn.tm.zones import Zone as DynZone
@ -288,7 +288,15 @@ class DynProvider(BaseProvider):
return self._traffic_directors
def _populate_traffic_directors(self, zone):
def _convert_value_A(self, records):
return sorted([r.address for r in records])
_convert_value_AAAA = _convert_value_A
def _convert_value_CNAME(self, records):
return records[0].cname
def _populate_traffic_directors(self, zone, lenient):
self.log.debug('_populate_traffic_directors: zone=%s', zone.name)
td_records = set()
for fqdn, types in self.traffic_directors.items():
@ -297,20 +305,27 @@ class DynProvider(BaseProvider):
continue
for _type, td in types.items():
# critical to call rulesets once, each call loads them :-(
rulesets = td.rulesets
# We start out with something that will always change show
# change in case this is a busted TD. This will prevent us from
# creating a duplicate td. We'll overwrite this with real data
# provide we have it
# We start out with something that will always show change in
# case this is a busted TD. This will prevent us from creating
# a duplicate td. We'll overwrite this with real data provide
# we have it
geo = {}
data = {
'geo': geo,
'type': _type,
'ttl': td.ttl,
'values': ['0.0.0.0']
}
if _type == 'CNAME':
data['value'] = '0.0.0.0'
else:
data['values'] = ['0.0.0.0']
convert_value = \
getattr(self, '_convert_value_{}'.format(_type))
for ruleset in rulesets:
try:
record_set = ruleset.response_pools[0].rs_chains[0] \
@ -328,16 +343,18 @@ class DynProvider(BaseProvider):
code, _ = ruleset.label.split(':', 1)
except ValueError:
continue
values = [r.address for r in record_set.records]
geo[code] = values
geo[code] = convert_value(record_set.records)
name = zone.hostname_from_fqdn(fqdn)
record = Record.new(zone, name, data, source=self)
record = Record.new(zone, name, data, source=self,
lenient=lenient)
zone.add_record(record)
td_records.add(record)
return td_records
def populate(self, zone, target=False, lenient=False):
self.log.debug('populate: name=%s, target=%s, lenient=%s', zone.name,
target, lenient)
@ -348,7 +365,7 @@ class DynProvider(BaseProvider):
td_records = set()
if self.traffic_directors_enabled:
td_records = self._populate_traffic_directors(zone)
td_records = self._populate_traffic_directors(zone, lenient=lenient)
dyn_zone = _CachingDynZone.get(zone.name[:-1])
@ -474,14 +491,16 @@ class DynProvider(BaseProvider):
if pool.label != label:
continue
records = pool.rs_chains[0].record_sets[0].records
record_values = sorted([r.address for r in records])
convert_value = getattr(self, '_convert_value_{}'.format(_type))
record_values = convert_value(records)
if record_values == values:
# it's a match
return pool
# we need to create the pool
_class = {
'A': DSFARecord,
'AAAA': DSFAAAARecord
'AAAA': DSFAAAARecord,
'CNAME': DSFCNAMERecord
}[_type]
records = [_class(v) for v in values]
record_set = DSFRecordSet(_type, label, serve_count=len(records),
@ -529,8 +548,12 @@ class DynProvider(BaseProvider):
label = 'default:{}'.format(uuid4().hex)
ruleset = DSFRuleset(label, 'always', [])
ruleset.create(td, index=0)
try:
values = new.values
except AttributeError:
values = [new.value]
pool = self._find_or_create_pool(td, pools, 'default', new._type,
new.values)
values)
# There's no way in the client lib to create a ruleset with an existing
# pool (ref'd by id) so we have to do this round-a-bout.
active_pools = {
@ -563,9 +586,13 @@ class DynProvider(BaseProvider):
# Something you have to call create others the constructor does it
ruleset.create(td, index=0)
first = geo.values[0]
try:
values = geo.values
except AttributeError:
values = [geo.value]
first = values[0]
pool = self._find_or_create_pool(td, pools, first, new._type,
geo.values, monitor_id)
values, monitor_id)
active_pools[geo.code] = pool.response_pool_id
ruleset.add_response_pool(pool.response_pool_id)


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

@ -158,12 +158,16 @@ class _Route53GeoRecord(_Route53Record):
def mod(self, action):
geo = self.geo
try:
values = geo.values
except AttributeError:
values = [geo.value]
rrset = {
'Name': self.fqdn,
'GeoLocation': {
'CountryCode': '*'
},
'ResourceRecords': [{'Value': v} for v in geo.values],
'ResourceRecords': [{'Value': v} for v in values],
'SetIdentifier': geo.code,
'TTL': self.ttl,
'Type': self._type,
@ -319,15 +323,23 @@ class Route53Provider(BaseProvider):
_data_for_A = _data_for_geo
_data_for_AAAA = _data_for_geo
def _data_for_single(self, rrset):
return {
def _data_for_CNAME(self, rrset):
ret = {
'type': rrset['Type'],
'value': rrset['ResourceRecords'][0]['Value'],
'ttl': int(rrset['TTL'])
}
geo = self._parse_geo(rrset)
if geo:
ret['geo'] = geo
return ret
_data_for_PTR = _data_for_single
_data_for_CNAME = _data_for_single
def _data_for_PTR(self, rrset):
return {
'type': rrset['Type'],
'value': rrset['ResourceRecords'][0]['Value'],
'ttl': int(rrset['TTL'])
}
_fix_semicolons = re.compile(r'(?<!\\);')
@ -453,9 +465,10 @@ class Route53Provider(BaseProvider):
# them data into the format we need
geo = {}
for d in data:
try:
geo[d['geo']] = d['values']
except KeyError:
if 'geo' in d:
geo[d['geo']] = \
d.get('values', None) or d['value']
else:
primary = d
data = primary
data['geo'] = geo
@ -500,6 +513,9 @@ class Route53Provider(BaseProvider):
return self._health_checks
def get_health_check_id(self, record, ident, geo, create):
if record._type == 'CNAME':
# CNAME records don't support health checks
return
# 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
@ -643,9 +659,12 @@ class Route53Provider(BaseProvider):
if record in changed:
# already have a change for it, skipping
continue
if not getattr(record, 'geo', False):
elif not getattr(record, 'geo', False):
# record doesn't support geo, we don't need to inspect it
continue
elif record._type == 'CNAME':
# CNAME geo's don't support health checks
continue
# OK this is a record we don't have change for that does have geo
# information. We need to look and see if it needs to be updated
# b/c of a health check version bump


Loading…
Cancel
Save