mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
Merge branch 'master' into bkane/python_requires
This commit is contained in:
@@ -545,21 +545,16 @@ class Ns1Provider(BaseProvider):
|
||||
pass
|
||||
return pool_name
|
||||
|
||||
def _data_for_dynamic(self, _type, record):
|
||||
# First make sure we have the expected filters config
|
||||
if not self._valid_filter_config(record['filters'], record['domain']):
|
||||
self.log.error('_data_for_dynamic: %s %s has unsupported '
|
||||
'filters', record['domain'], _type)
|
||||
raise Ns1Exception('Unrecognized advanced record')
|
||||
|
||||
def _parse_pools(self, answers):
|
||||
# All regions (pools) will include the list of default values
|
||||
# (eventually) at higher priorities, we'll just add them to this set to
|
||||
# we'll have the complete collection.
|
||||
default = set()
|
||||
|
||||
# Fill out the pools by walking the answers and looking at their
|
||||
# region.
|
||||
# region (< v0.9.11) or notes (> v0.9.11).
|
||||
pools = defaultdict(lambda: {'fallback': None, 'values': []})
|
||||
for answer in record['answers']:
|
||||
for answer in answers:
|
||||
meta = answer['meta']
|
||||
notes = self._parse_notes(meta.get('note', ''))
|
||||
|
||||
@@ -579,7 +574,7 @@ class Ns1Provider(BaseProvider):
|
||||
if meta['priority'] != 1:
|
||||
# Ignore all but priority 1
|
||||
continue
|
||||
# And use region's pool name as the pool name
|
||||
# And use region's name as the pool name
|
||||
pool_name = self._parse_dynamic_pool_name(answer['region'])
|
||||
else:
|
||||
# > v0.9.11, use the notes-based name and consider all values
|
||||
@@ -603,18 +598,83 @@ class Ns1Provider(BaseProvider):
|
||||
if fallback is not None:
|
||||
pool['fallback'] = fallback
|
||||
|
||||
# Order and convert to a list
|
||||
default = sorted(default)
|
||||
|
||||
return default, pools
|
||||
|
||||
def _parse_rule_geos(self, meta):
|
||||
geos = set()
|
||||
|
||||
for georegion in meta.get('georegion', []):
|
||||
geos.add(self._REGION_TO_CONTINENT[georegion])
|
||||
|
||||
# Countries are easy enough to map, we just have to find their
|
||||
# continent
|
||||
#
|
||||
# NOTE: Some continents need special handling since NS1
|
||||
# does not supprt them as regions. These are defined under
|
||||
# _CONTINENT_TO_LIST_OF_COUNTRIES. So the countries for these
|
||||
# regions will be present in meta['country']. If all the countries
|
||||
# in _CONTINENT_TO_LIST_OF_COUNTRIES[<region>] list are found,
|
||||
# set the continent as the region and remove individual countries
|
||||
|
||||
special_continents = dict()
|
||||
for country in meta.get('country', []):
|
||||
# country_alpha2_to_continent_code fails for Pitcairn ('PN'),
|
||||
# United States Minor Outlying Islands ('UM') and
|
||||
# Sint Maarten ('SX')
|
||||
if country == 'PN':
|
||||
con = 'OC'
|
||||
elif country in ['SX', 'UM']:
|
||||
con = 'NA'
|
||||
else:
|
||||
con = country_alpha2_to_continent_code(country)
|
||||
|
||||
if con in self._CONTINENT_TO_LIST_OF_COUNTRIES:
|
||||
special_continents.setdefault(con, set()).add(country)
|
||||
else:
|
||||
geos.add(f'{con}-{country}')
|
||||
|
||||
for continent, countries in special_continents.items():
|
||||
if countries == self._CONTINENT_TO_LIST_OF_COUNTRIES[
|
||||
continent]:
|
||||
# All countries found, so add it to geos
|
||||
geos.add(continent)
|
||||
else:
|
||||
# Partial countries found, so just add them as-is to geos
|
||||
for c in countries:
|
||||
geos.add(f'{continent}-{c}')
|
||||
|
||||
# States and provinces are easy too,
|
||||
# just assume NA-US or NA-CA
|
||||
for state in meta.get('us_state', []):
|
||||
geos.add(f'NA-US-{state}')
|
||||
|
||||
for province in meta.get('ca_province', []):
|
||||
geos.add(f'NA-CA-{province}')
|
||||
|
||||
return geos
|
||||
|
||||
def _parse_rules(self, pools, regions):
|
||||
# The regions objects map to rules, but it's a bit fuzzy since they're
|
||||
# tied to pools on the NS1 side, e.g. we can only have 1 rule per pool,
|
||||
# that may eventually run into problems, but I don't have any use-cases
|
||||
# examples currently where it would
|
||||
rules = {}
|
||||
for pool_name, region in sorted(record['regions'].items()):
|
||||
for pool_name, region in sorted(regions.items()):
|
||||
# Get the actual pool name by removing the type
|
||||
pool_name = self._parse_dynamic_pool_name(pool_name)
|
||||
|
||||
meta = region['meta']
|
||||
notes = self._parse_notes(meta.get('note', ''))
|
||||
|
||||
# The group notes field in the UI is a `note` on the region here,
|
||||
# that's where we can find our pool's fallback in < v0.9.11 anyway
|
||||
if 'fallback' in notes:
|
||||
# set the fallback pool name
|
||||
pools[pool_name]['fallback'] = notes['fallback']
|
||||
|
||||
rule_order = notes['rule-order']
|
||||
try:
|
||||
rule = rules[rule_order]
|
||||
@@ -625,72 +685,26 @@ class Ns1Provider(BaseProvider):
|
||||
}
|
||||
rules[rule_order] = rule
|
||||
|
||||
# The group notes field in the UI is a `note` on the region here,
|
||||
# that's where we can find our pool's fallback in < v0.9.11 anyway
|
||||
if 'fallback' in notes:
|
||||
# set the fallback pool name
|
||||
pools[pool_name]['fallback'] = notes['fallback']
|
||||
|
||||
geos = set()
|
||||
|
||||
for georegion in meta.get('georegion', []):
|
||||
geos.add(self._REGION_TO_CONTINENT[georegion])
|
||||
|
||||
# Countries are easy enough to map, we just have to find their
|
||||
# continent
|
||||
#
|
||||
# NOTE: Some continents need special handling since NS1
|
||||
# does not supprt them as regions. These are defined under
|
||||
# _CONTINENT_TO_LIST_OF_COUNTRIES. So the countries for these
|
||||
# regions will be present in meta['country']. If all the countries
|
||||
# in _CONTINENT_TO_LIST_OF_COUNTRIES[<region>] list are found,
|
||||
# set the continent as the region and remove individual countries
|
||||
|
||||
special_continents = dict()
|
||||
for country in meta.get('country', []):
|
||||
# country_alpha2_to_continent_code fails for Pitcairn ('PN'),
|
||||
# United States Minor Outlying Islands ('UM') and
|
||||
# Sint Maarten ('SX')
|
||||
if country == 'PN':
|
||||
con = 'OC'
|
||||
elif country in ['SX', 'UM']:
|
||||
con = 'NA'
|
||||
else:
|
||||
con = country_alpha2_to_continent_code(country)
|
||||
|
||||
if con in self._CONTINENT_TO_LIST_OF_COUNTRIES:
|
||||
special_continents.setdefault(con, set()).add(country)
|
||||
else:
|
||||
geos.add(f'{con}-{country}')
|
||||
|
||||
for continent, countries in special_continents.items():
|
||||
if countries == self._CONTINENT_TO_LIST_OF_COUNTRIES[
|
||||
continent]:
|
||||
# All countries found, so add it to geos
|
||||
geos.add(continent)
|
||||
else:
|
||||
# Partial countries found, so just add them as-is to geos
|
||||
for c in countries:
|
||||
geos.add(f'{continent}-{c}')
|
||||
|
||||
# States and provinces are easy too,
|
||||
# just assume NA-US or NA-CA
|
||||
for state in meta.get('us_state', []):
|
||||
geos.add(f'NA-US-{state}')
|
||||
|
||||
for province in meta.get('ca_province', []):
|
||||
geos.add(f'NA-CA-{province}')
|
||||
|
||||
geos = self._parse_rule_geos(meta)
|
||||
if geos:
|
||||
# There are geos, combine them with any existing geos for this
|
||||
# pool and recorded the sorted unique set of them
|
||||
rule['geos'] = sorted(set(rule.get('geos', [])) | geos)
|
||||
|
||||
# Order and convert to a list
|
||||
default = sorted(default)
|
||||
# Convert to list and order
|
||||
rules = list(rules.values())
|
||||
rules.sort(key=lambda r: (r['_order'], r['pool']))
|
||||
rules = sorted(rules.values(), key=lambda r: (r['_order'], r['pool']))
|
||||
|
||||
return rules
|
||||
|
||||
def _data_for_dynamic(self, _type, record):
|
||||
# First make sure we have the expected filters config
|
||||
if not self._valid_filter_config(record['filters'], record['domain']):
|
||||
self.log.error('_data_for_dynamic: %s %s has unsupported '
|
||||
'filters', record['domain'], _type)
|
||||
raise Ns1Exception('Unrecognized advanced record')
|
||||
|
||||
default, pools = self._parse_pools(record['answers'])
|
||||
rules = self._parse_rules(pools, record['regions'])
|
||||
|
||||
data = {
|
||||
'dynamic': {
|
||||
@@ -1182,10 +1196,8 @@ class Ns1Provider(BaseProvider):
|
||||
}
|
||||
answers.append(answer)
|
||||
|
||||
def _params_for_dynamic(self, record):
|
||||
def _generate_regions(self, record):
|
||||
pools = record.dynamic.pools
|
||||
|
||||
# Convert rules to regions
|
||||
has_country = False
|
||||
has_region = False
|
||||
regions = {}
|
||||
@@ -1267,6 +1279,10 @@ class Ns1Provider(BaseProvider):
|
||||
'meta': meta,
|
||||
}
|
||||
|
||||
return has_country, has_region, regions
|
||||
|
||||
def _generate_answers(self, record, regions):
|
||||
pools = record.dynamic.pools
|
||||
existing_monitors = self._monitors_for(record)
|
||||
active_monitors = set()
|
||||
|
||||
@@ -1324,6 +1340,15 @@ class Ns1Provider(BaseProvider):
|
||||
pool_label, pool_answers, pools,
|
||||
priority)
|
||||
|
||||
return active_monitors, answers
|
||||
|
||||
def _params_for_dynamic(self, record):
|
||||
# Convert rules to regions
|
||||
has_country, has_region, regions = self._generate_regions(record)
|
||||
|
||||
# Convert pools to answers
|
||||
active_monitors, answers = self._generate_answers(record, regions)
|
||||
|
||||
# Update filters as necessary
|
||||
filters = self._get_updated_filter_chain(has_region, has_country)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user