1
0
mirror of https://github.com/github/octodns.git synced 2024-05-11 05:55:00 +00:00

NS1 doesn't support region OC. Handle it explicitly in the provider

This commit is contained in:
Pavan Chandrashekar
2020-03-03 11:07:29 -08:00
parent 4f304943cf
commit 71a277f6ad
2 changed files with 98 additions and 3 deletions

View File

@@ -227,6 +227,13 @@ class Ns1Provider(BaseProvider):
'NA': ('US-CENTRAL', 'US-EAST', 'US-WEST'),
}
# Necessary for handling unsupported continents in _CONTINENT_TO_REGIONS
_CONTINENT_TO_LIST_OF_COUNTRIES = {
'OC': ['FJ', 'NC', 'PG', 'SB', 'VU', 'AU', 'NF', 'NZ', 'FM', 'GU',
'KI', 'MH', 'MP', 'NR', 'PW', 'AS', 'CK', 'NU', 'PF', 'PN',
'TK', 'TO', 'TV', 'WF', 'WS'],
}
def __init__(self, id, api_key, retry_count=4, monitor_regions=None, *args,
**kwargs):
self.log = getLogger('Ns1Provider[{}]'.format(id))
@@ -351,12 +358,35 @@ class Ns1Provider(BaseProvider):
for georegion in meta.get('georegion', []):
geos.add(self._REGION_TO_CONTINENT[georegion])
# Countries are easy enough to map, we just have ot find their
# Countries are easy enough to map, we just have to find their
# continent
#
# NOTE: Special handling for Oceania
# NS1 doesn't support Oceania as a region. So the Oceania countries
# will be present in meta['country']. If all the countries in the
# Oceania countries list are found, set the region to OC and remove
# individual oceania country entries
oc_countries = []
for country in meta.get('country', []):
con = country_alpha2_to_continent_code(country)
# country_alpha2_to_continent_code fails for Pitcairn ('PN')
if country == 'PN':
con = 'OC'
else:
con = country_alpha2_to_continent_code(country)
if con == 'OC':
oc_countries.append(country)
geos.add('{}-{}'.format(con, country))
if len(oc_countries):
all_oc_countries = self._CONTINENT_TO_LIST_OF_COUNTRIES['OC']
if sorted(oc_countries) == sorted(all_oc_countries):
# Remove oceania countries from the map, add 'OC' region
for c in oc_countries:
geos.remove('{}-{}'.format('OC', c))
geos.add('OC')
# States are easy too, just assume NA-US (CA providences aren't
# supported by octoDNS currently)
for state in meta.get('us_state', []):
@@ -782,7 +812,15 @@ class Ns1Provider(BaseProvider):
country.add(geo[-2:])
else:
# Continent, e.g. AS
georegion.update(self._CONTINENT_TO_REGIONS[geo])
if geo in self._CONTINENT_TO_REGIONS:
georegion.update(self._CONTINENT_TO_REGIONS[geo])
else:
# No maps for geo in _CONTINENT_TO_REGIONS.
# Use the country list
self.log.debug('Converting geo {} to country list'.
format(geo))
for c in self._CONTINENT_TO_LIST_OF_COUNTRIES[geo]:
country.add(c)
meta = {
'note': self._encode_notes(notes),

View File

@@ -521,6 +521,12 @@ class TestNs1Provider(TestCase):
class TestNs1ProviderDynamic(TestCase):
zone = Zone('unit.tests.', [])
_CONTINENT_TO_LIST_OF_COUNTRIES = {
'OC': ['FJ', 'NC', 'PG', 'SB', 'VU', 'AU', 'NF', 'NZ', 'FM', 'GU',
'KI', 'MH', 'MP', 'NR', 'PW', 'AS', 'CK', 'NU', 'PF', 'PN',
'TK', 'TO', 'TV', 'WF', 'WS'],
}
record = Record.new(zone, '', {
'dynamic': {
'pools': {
@@ -926,6 +932,43 @@ class TestNs1ProviderDynamic(TestCase):
monitors_delete_mock.assert_has_calls([call('mon-id2')])
notifylists_delete_mock.assert_has_calls([call('nl-id2')])
@patch('octodns.provider.ns1.Ns1Provider._monitor_sync')
@patch('octodns.provider.ns1.Ns1Provider._monitors_for')
def test_params_for_dynamic_oceania(self, monitors_for_mock,
monitor_sync_mock):
provider = Ns1Provider('test', 'api-key')
# pre-fill caches to avoid extranious calls (things we're testing
# elsewhere)
provider._client._datasource_id = 'foo'
provider._client._feeds_for_monitors = {
'mon-id': 'feed-id',
}
# provider._params_for_A() calls provider._monitors_for() and
# provider._monitor_sync(). Mock their return values so that we don't
# make NS1 API calls during tests
monitors_for_mock.reset_mock()
monitor_sync_mock.reset_mock()
monitors_for_mock.side_effect = [{
'3.4.5.6': 'mid-3',
}]
monitor_sync_mock.side_effect = [
('mid-1', 'fid-1'),
('mid-2', 'fid-2'),
('mid-3', 'fid-3'),
]
# Set geos to 'OC' in rules[0] (pool - 'lhr')
# Check returned dict has list of countries under 'OC'
rule0 = self.record.data['dynamic']['rules'][0]
saved_geos = rule0['geos']
rule0['geos'] = ['OC']
ret, _ = provider._params_for_A(self.record)
self.assertEquals(sorted(ret['regions']['lhr']['meta']['country']),
sorted(self._CONTINENT_TO_LIST_OF_COUNTRIES['OC']))
rule0['geos'] = saved_geos
@patch('octodns.provider.ns1.Ns1Provider._monitor_sync')
@patch('octodns.provider.ns1.Ns1Provider._monitors_for')
def test_params_for_dynamic(self, monitors_for_mock, monitors_sync_mock):
@@ -1092,6 +1135,20 @@ class TestNs1ProviderDynamic(TestCase):
data2 = provider._data_for_A('A', ns1_record)
self.assertEquals(data, data2)
# Oceania test cases
# 1. Full list of countries should return 'OC' in geos
oc_country_list = self._CONTINENT_TO_LIST_OF_COUNTRIES['OC']
ns1_record['regions']['lhr']['meta']['country'] = oc_country_list
data3 = provider._data_for_A('A', ns1_record)
assert('OC' in data3['dynamic']['rules'][0]['geos'])
# 2. Partial list of countries should return just those
partial_oc_cntry_list = oc_country_list[:5]
ns1_record['regions']['lhr']['meta']['country'] = partial_oc_cntry_list
data4 = provider._data_for_A('A', ns1_record)
for c in partial_oc_cntry_list:
assert('OC-{}'.format(c) in data4['dynamic']['rules'][0]['geos'])
@patch('octodns.provider.ns1.Ns1Provider._monitors_for')
def test_extra_changes(self, monitors_for_mock):
provider = Ns1Provider('test', 'api-key')