|
|
@ -142,7 +142,7 @@ class _CachingDynZone(DynZone): |
|
|
return None |
|
|
return None |
|
|
# this value shouldn't really matter, it's not tied to |
|
|
# this value shouldn't really matter, it's not tied to |
|
|
# whois or anything |
|
|
# whois or anything |
|
|
hostname = 'hostmaster@{}'.format(zone_name[:-1]) |
|
|
|
|
|
|
|
|
hostname = f'hostmaster@{zone_name[:-1]}' |
|
|
# Try again with the params necessary to create |
|
|
# Try again with the params necessary to create |
|
|
dyn_zone = _CachingDynZone(zone_name, ttl=3600, |
|
|
dyn_zone = _CachingDynZone(zone_name, ttl=3600, |
|
|
contact=hostname, |
|
|
contact=hostname, |
|
|
@ -247,7 +247,7 @@ class DynProvider(BaseProvider): |
|
|
|
|
|
|
|
|
def __init__(self, id, customer, username, password, |
|
|
def __init__(self, id, customer, username, password, |
|
|
traffic_directors_enabled=False, *args, **kwargs): |
|
|
traffic_directors_enabled=False, *args, **kwargs): |
|
|
self.log = getLogger('DynProvider[{}]'.format(id)) |
|
|
|
|
|
|
|
|
self.log = getLogger(f'DynProvider[{id}]') |
|
|
self.log.debug('__init__: id=%s, customer=%s, username=%s, ' |
|
|
self.log.debug('__init__: id=%s, customer=%s, username=%s, ' |
|
|
'password=***, traffic_directors_enabled=%s', id, |
|
|
'password=***, traffic_directors_enabled=%s', id, |
|
|
customer, username, traffic_directors_enabled) |
|
|
customer, username, traffic_directors_enabled) |
|
|
@ -429,7 +429,7 @@ class DynProvider(BaseProvider): |
|
|
# problems indicate a malformed ruleset, ignore it |
|
|
# problems indicate a malformed ruleset, ignore it |
|
|
continue |
|
|
continue |
|
|
if ruleset.label.startswith('default:'): |
|
|
if ruleset.label.startswith('default:'): |
|
|
data_for = getattr(self, '_data_for_{}'.format(_type)) |
|
|
|
|
|
|
|
|
data_for = getattr(self, f'_data_for_{_type}') |
|
|
data.update(data_for(_type, record_set.records)) |
|
|
data.update(data_for(_type, record_set.records)) |
|
|
else: |
|
|
else: |
|
|
# We've stored the geo in label |
|
|
# We've stored the geo in label |
|
|
@ -465,8 +465,8 @@ class DynProvider(BaseProvider): |
|
|
default = {} |
|
|
default = {} |
|
|
pools = {} |
|
|
pools = {} |
|
|
|
|
|
|
|
|
data_for = getattr(self, '_data_for_{}'.format(_type)) |
|
|
|
|
|
value_for = getattr(self, '_value_for_{}'.format(_type)) |
|
|
|
|
|
|
|
|
data_for = getattr(self, f'_data_for_{_type}') |
|
|
|
|
|
value_for = getattr(self, f'_value_for_{_type}') |
|
|
|
|
|
|
|
|
# Build the list of pools, we can't just read them off of rules b/c we |
|
|
# Build the list of pools, we can't just read them off of rules b/c we |
|
|
# won't see unused pools there. If/when we dis-allow unused pools we |
|
|
# won't see unused pools there. If/when we dis-allow unused pools we |
|
|
@ -626,7 +626,7 @@ class DynProvider(BaseProvider): |
|
|
for fqdn, types in self.traffic_directors.items(): |
|
|
for fqdn, types in self.traffic_directors.items(): |
|
|
for _type, td in types.items(): |
|
|
for _type, td in types.items(): |
|
|
# Does this TD belong to the current zone |
|
|
# Does this TD belong to the current zone |
|
|
td_zone = '{}.'.format(td.nodes[0]['zone']) |
|
|
|
|
|
|
|
|
td_zone = f'{td.nodes[0]["zone"]}.' |
|
|
if td_zone != zone.name: |
|
|
if td_zone != zone.name: |
|
|
# Doesn't belong to the current zone, skip it |
|
|
# Doesn't belong to the current zone, skip it |
|
|
continue |
|
|
continue |
|
|
@ -676,7 +676,7 @@ class DynProvider(BaseProvider): |
|
|
|
|
|
|
|
|
for name, types in values.items(): |
|
|
for name, types in values.items(): |
|
|
for _type, records in types.items(): |
|
|
for _type, records in types.items(): |
|
|
data_for = getattr(self, '_data_for_{}'.format(_type)) |
|
|
|
|
|
|
|
|
data_for = getattr(self, f'_data_for_{_type}') |
|
|
data = data_for(_type, records) |
|
|
data = data_for(_type, records) |
|
|
record = Record.new(zone, name, data, source=self, |
|
|
record = Record.new(zone, name, data, source=self, |
|
|
lenient=lenient) |
|
|
lenient=lenient) |
|
|
@ -697,7 +697,7 @@ class DynProvider(BaseProvider): |
|
|
if record in changed or not getattr(record, 'geo', False): |
|
|
if record in changed or not getattr(record, 'geo', False): |
|
|
# Already changed, or no geo, no need to check it |
|
|
# Already changed, or no geo, no need to check it |
|
|
continue |
|
|
continue |
|
|
label = '{}:{}'.format(record.fqdn, record._type) |
|
|
|
|
|
|
|
|
label = f'{record.fqdn}:{record._type}' |
|
|
try: |
|
|
try: |
|
|
monitor = self.traffic_director_monitors[label] |
|
|
monitor = self.traffic_director_monitors[label] |
|
|
except KeyError: |
|
|
except KeyError: |
|
|
@ -812,7 +812,7 @@ class DynProvider(BaseProvider): |
|
|
|
|
|
|
|
|
def _traffic_director_monitor(self, record): |
|
|
def _traffic_director_monitor(self, record): |
|
|
fqdn = record.fqdn |
|
|
fqdn = record.fqdn |
|
|
label = '{}:{}'.format(fqdn, record._type) |
|
|
|
|
|
|
|
|
label = f'{fqdn}:{record._type}' |
|
|
try: |
|
|
try: |
|
|
try: |
|
|
try: |
|
|
monitor = self.traffic_director_monitors[label] |
|
|
monitor = self.traffic_director_monitors[label] |
|
|
@ -920,14 +920,14 @@ class DynProvider(BaseProvider): |
|
|
continue |
|
|
continue |
|
|
# And the (sorted) values must match once converted for comparison |
|
|
# And the (sorted) values must match once converted for comparison |
|
|
# purposes |
|
|
# purposes |
|
|
value_for = getattr(self, '_value_for_{}'.format(_type)) |
|
|
|
|
|
|
|
|
value_for = getattr(self, f'_value_for_{_type}') |
|
|
record_values = [value_for(_type, r) for r in records] |
|
|
record_values = [value_for(_type, r) for r in records] |
|
|
if record_values == values: |
|
|
if record_values == values: |
|
|
# it's a match |
|
|
# it's a match |
|
|
return pool |
|
|
return pool |
|
|
|
|
|
|
|
|
# We don't have this pool and thus need to create it |
|
|
# We don't have this pool and thus need to create it |
|
|
records_for = getattr(self, '_dynamic_records_for_{}'.format(_type)) |
|
|
|
|
|
|
|
|
records_for = getattr(self, f'_dynamic_records_for_{_type}') |
|
|
records = records_for(values, record_extras) |
|
|
records = records_for(values, record_extras) |
|
|
record_set = DSFRecordSet(_type, label, serve_count=1, records=records, |
|
|
record_set = DSFRecordSet(_type, label, serve_count=1, records=records, |
|
|
dsf_monitor_id=monitor_id) |
|
|
dsf_monitor_id=monitor_id) |
|
|
@ -996,7 +996,7 @@ class DynProvider(BaseProvider): |
|
|
self.log.debug('_mod_geo_rulesets: insert_at=%d', insert_at) |
|
|
self.log.debug('_mod_geo_rulesets: insert_at=%d', insert_at) |
|
|
|
|
|
|
|
|
# add the default |
|
|
# add the default |
|
|
label = 'default:{}'.format(uuid4().hex) |
|
|
|
|
|
|
|
|
label = f'default:{uuid4().hex}' |
|
|
ruleset = DSFRuleset(label, 'always', []) |
|
|
ruleset = DSFRuleset(label, 'always', []) |
|
|
ruleset.create(td, index=insert_at) |
|
|
ruleset.create(td, index=insert_at) |
|
|
pool = self._find_or_create_geo_pool(td, pools, 'default', new._type, |
|
|
pool = self._find_or_create_geo_pool(td, pools, 'default', new._type, |
|
|
@ -1026,7 +1026,7 @@ class DynProvider(BaseProvider): |
|
|
'region': self.REGION_CODES[geo.continent_code] |
|
|
'region': self.REGION_CODES[geo.continent_code] |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
label = '{}:{}'.format(geo.code, uuid4().hex) |
|
|
|
|
|
|
|
|
label = f'{geo.code}:{uuid4().hex}' |
|
|
ruleset = DSFRuleset(label, 'geoip', [], { |
|
|
ruleset = DSFRuleset(label, 'geoip', [], { |
|
|
'geoip': criteria |
|
|
'geoip': criteria |
|
|
}) |
|
|
}) |
|
|
@ -1068,7 +1068,7 @@ class DynProvider(BaseProvider): |
|
|
new = change.new |
|
|
new = change.new |
|
|
fqdn = new.fqdn |
|
|
fqdn = new.fqdn |
|
|
_type = new._type |
|
|
_type = new._type |
|
|
label = '{}:{}'.format(fqdn, _type) |
|
|
|
|
|
|
|
|
label = f'{fqdn}:{_type}' |
|
|
node = DSFNode(new.zone.name, fqdn) |
|
|
node = DSFNode(new.zone.name, fqdn) |
|
|
td = TrafficDirector(label, ttl=new.ttl, nodes=[node], publish='Y') |
|
|
td = TrafficDirector(label, ttl=new.ttl, nodes=[node], publish='Y') |
|
|
self.log.debug('_mod_geo_Create: td=%s', td.service_id) |
|
|
self.log.debug('_mod_geo_Create: td=%s', td.service_id) |
|
|
@ -1158,7 +1158,7 @@ class DynProvider(BaseProvider): |
|
|
self.log.debug('_mod_dynamic_rulesets: insert_at=%d', insert_at) |
|
|
self.log.debug('_mod_dynamic_rulesets: insert_at=%d', insert_at) |
|
|
|
|
|
|
|
|
# Add the base record values as the ultimate/unhealthchecked default |
|
|
# Add the base record values as the ultimate/unhealthchecked default |
|
|
label = 'default:{}'.format(uuid4().hex) |
|
|
|
|
|
|
|
|
label = f'default:{uuid4().hex}' |
|
|
ruleset = DSFRuleset(label, 'always', []) |
|
|
ruleset = DSFRuleset(label, 'always', []) |
|
|
ruleset.create(td, index=insert_at) |
|
|
ruleset.create(td, index=insert_at) |
|
|
# If/when we go beyond A, AAAA, and CNAME this will have to get |
|
|
# If/when we go beyond A, AAAA, and CNAME this will have to get |
|
|
@ -1224,7 +1224,7 @@ class DynProvider(BaseProvider): |
|
|
criteria['geoip']['region'] \ |
|
|
criteria['geoip']['region'] \ |
|
|
.append(self.REGION_CODES[geo['continent_code']]) |
|
|
.append(self.REGION_CODES[geo['continent_code']]) |
|
|
|
|
|
|
|
|
label = '{}:{}'.format(rule_num, uuid4().hex) |
|
|
|
|
|
|
|
|
label = f'{rule_num}:{uuid4().hex}' |
|
|
ruleset = DSFRuleset(label, criteria_type, [], criteria) |
|
|
ruleset = DSFRuleset(label, criteria_type, [], criteria) |
|
|
# Something you have to call create others the constructor does it |
|
|
# Something you have to call create others the constructor does it |
|
|
ruleset.create(td, index=insert_at) |
|
|
ruleset.create(td, index=insert_at) |
|
|
@ -1277,7 +1277,7 @@ class DynProvider(BaseProvider): |
|
|
fqdn = new.fqdn |
|
|
fqdn = new.fqdn |
|
|
_type = new._type |
|
|
_type = new._type |
|
|
# Create a new traffic director |
|
|
# Create a new traffic director |
|
|
label = '{}:{}'.format(fqdn, _type) |
|
|
|
|
|
|
|
|
label = f'{fqdn}:{_type}' |
|
|
node = DSFNode(new.zone.name, fqdn) |
|
|
node = DSFNode(new.zone.name, fqdn) |
|
|
td = TrafficDirector(label, ttl=new.ttl, nodes=[node], publish='Y') |
|
|
td = TrafficDirector(label, ttl=new.ttl, nodes=[node], publish='Y') |
|
|
self.log.debug('_mod_dynamic_Create: td=%s', td.service_id) |
|
|
self.log.debug('_mod_dynamic_Create: td=%s', td.service_id) |
|
|
@ -1335,14 +1335,14 @@ class DynProvider(BaseProvider): |
|
|
|
|
|
|
|
|
def _mod_Create(self, dyn_zone, change): |
|
|
def _mod_Create(self, dyn_zone, change): |
|
|
new = change.new |
|
|
new = change.new |
|
|
kwargs_for = getattr(self, '_kwargs_for_{}'.format(new._type)) |
|
|
|
|
|
|
|
|
kwargs_for = getattr(self, f'_kwargs_for_{new._type}') |
|
|
for kwargs in kwargs_for(new): |
|
|
for kwargs in kwargs_for(new): |
|
|
dyn_zone.add_record(new.name, new._type, **kwargs) |
|
|
dyn_zone.add_record(new.name, new._type, **kwargs) |
|
|
|
|
|
|
|
|
def _mod_Delete(self, dyn_zone, change): |
|
|
def _mod_Delete(self, dyn_zone, change): |
|
|
existing = change.existing |
|
|
existing = change.existing |
|
|
if existing.name: |
|
|
if existing.name: |
|
|
target = '{}.{}'.format(existing.name, existing.zone.name[:-1]) |
|
|
|
|
|
|
|
|
target = f'{existing.name}.{existing.zone.name[:-1]}' |
|
|
else: |
|
|
else: |
|
|
target = existing.zone.name[:-1] |
|
|
target = existing.zone.name[:-1] |
|
|
_type = self.TYPE_TO_RECORDS[existing._type] |
|
|
_type = self.TYPE_TO_RECORDS[existing._type] |
|
|
@ -1361,12 +1361,13 @@ class DynProvider(BaseProvider): |
|
|
# we only mess with changes that have geo info somewhere |
|
|
# we only mess with changes that have geo info somewhere |
|
|
if getattr(c.new, 'dynamic', False) or getattr(c.existing, |
|
|
if getattr(c.new, 'dynamic', False) or getattr(c.existing, |
|
|
'dynamic', False): |
|
|
'dynamic', False): |
|
|
mod = getattr(self, '_mod_dynamic_{}' |
|
|
|
|
|
.format(c.__class__.__name__)) |
|
|
|
|
|
|
|
|
klass = c.__class__.__name__ |
|
|
|
|
|
mod = getattr(self, f'_mod_dynamic_{klass}') |
|
|
mod(dyn_zone, c) |
|
|
mod(dyn_zone, c) |
|
|
elif getattr(c.new, 'geo', False) or getattr(c.existing, 'geo', |
|
|
elif getattr(c.new, 'geo', False) or getattr(c.existing, 'geo', |
|
|
False): |
|
|
False): |
|
|
mod = getattr(self, '_mod_geo_{}'.format(c.__class__.__name__)) |
|
|
|
|
|
|
|
|
klass = c.__class__.__name__ |
|
|
|
|
|
mod = getattr(self, f'_mod_geo_{klass}') |
|
|
mod(dyn_zone, c) |
|
|
mod(dyn_zone, c) |
|
|
else: |
|
|
else: |
|
|
unhandled_changes.append(c) |
|
|
unhandled_changes.append(c) |
|
|
@ -1376,7 +1377,8 @@ class DynProvider(BaseProvider): |
|
|
def _apply_regular(self, desired, changes, dyn_zone): |
|
|
def _apply_regular(self, desired, changes, dyn_zone): |
|
|
self.log.debug('_apply_regular: zone=%s', desired.name) |
|
|
self.log.debug('_apply_regular: zone=%s', desired.name) |
|
|
for c in changes: |
|
|
for c in changes: |
|
|
mod = getattr(self, '_mod_{}'.format(c.__class__.__name__)) |
|
|
|
|
|
|
|
|
klass = c.__class__.__name__ |
|
|
|
|
|
mod = getattr(self, f'_mod_{klass}') |
|
|
mod(dyn_zone, c) |
|
|
mod(dyn_zone, c) |
|
|
|
|
|
|
|
|
# TODO: detect "extra" changes when monitors are out of date or failover |
|
|
# TODO: detect "extra" changes when monitors are out of date or failover |
|
|
|