Add ability for specific geographic regions to be blocked from pulling images within a namespace
This commit is contained in:
parent
c71a43a06c
commit
c3710a6a5e
20 changed files with 257 additions and 37 deletions
|
@ -16,7 +16,8 @@ import requests
|
|||
|
||||
from util.abchelpers import nooper
|
||||
|
||||
ResolvedLocation = namedtuple('ResolvedLocation', ['provider', 'region', 'service', 'sync_token'])
|
||||
ResolvedLocation = namedtuple('ResolvedLocation', ['provider', 'region', 'service', 'sync_token',
|
||||
'country_iso_code'])
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -124,7 +125,11 @@ class IPResolver(IPResolverInterface):
|
|||
fails, returns None.
|
||||
"""
|
||||
location_function = self._get_location_function()
|
||||
if not ip_address or not location_function:
|
||||
if not ip_address:
|
||||
return None
|
||||
|
||||
if not location_function:
|
||||
logger.debug('No location function could be defined for IP address resolution')
|
||||
return None
|
||||
|
||||
return location_function(ip_address)
|
||||
|
@ -142,8 +147,9 @@ class IPResolver(IPResolverInterface):
|
|||
cache = CACHE
|
||||
sync_token = cache.get('sync_token', None)
|
||||
if sync_token is None:
|
||||
logger.debug('The aws ip range has not been cached from %s', _DATA_FILES['aws-ip-ranges.json'])
|
||||
return None
|
||||
logger.debug('The aws ip range has not been cached from %s',
|
||||
_DATA_FILES['aws-ip-ranges.json'])
|
||||
return IPResolver._build_location_function(sync_token, set(), {}, self.geoip_db)
|
||||
|
||||
all_amazon = cache['all_amazon']
|
||||
regions = cache['regions']
|
||||
|
@ -163,20 +169,25 @@ class IPResolver(IPResolverInterface):
|
|||
try:
|
||||
parsed_ip = IPAddress(ip_address)
|
||||
except AddrFormatError:
|
||||
return ResolvedLocation('invalid_ip', None, None, sync_token)
|
||||
return ResolvedLocation('invalid_ip', None, None, sync_token, None)
|
||||
|
||||
# Try geoip classification
|
||||
try:
|
||||
geoinfo = country_db.country(parsed_ip)
|
||||
except geoip2.errors.AddressNotFoundError:
|
||||
geoinfo = None
|
||||
|
||||
if parsed_ip not in all_amazon:
|
||||
# Try geoip classification
|
||||
try:
|
||||
found = country_db.country(parsed_ip)
|
||||
if geoinfo:
|
||||
return ResolvedLocation(
|
||||
'internet',
|
||||
found.continent.code,
|
||||
found.country.iso_code,
|
||||
geoinfo.continent.code,
|
||||
geoinfo.country.iso_code,
|
||||
sync_token,
|
||||
geoinfo.country.iso_code,
|
||||
)
|
||||
except geoip2.errors.AddressNotFoundError:
|
||||
return ResolvedLocation('internet', None, None, sync_token)
|
||||
|
||||
return ResolvedLocation('internet', None, None, sync_token, None)
|
||||
|
||||
region = None
|
||||
|
||||
|
@ -185,7 +196,8 @@ class IPResolver(IPResolverInterface):
|
|||
region = region_name
|
||||
break
|
||||
|
||||
return ResolvedLocation('aws', region, None, sync_token)
|
||||
return ResolvedLocation('aws', region, None, sync_token,
|
||||
geoinfo.country.country_iso_code if geoinfo else None)
|
||||
return _get_location
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -44,17 +44,17 @@ def test_unstarted(app, test_aws_ip, unstarted_cache):
|
|||
ipresolver = IPResolver(app)
|
||||
|
||||
with patch.dict('util.ipresolver.CACHE', unstarted_cache):
|
||||
assert ipresolver.resolve_ip(test_aws_ip) is None
|
||||
assert ipresolver.resolve_ip(test_aws_ip) is not None
|
||||
|
||||
def test_resolved(aws_ip_range_data, test_ip_range_cache, test_aws_ip, app):
|
||||
with patch('util.ipresolver._UpdateIPRange'):
|
||||
ipresolver = IPResolver(app)
|
||||
|
||||
with patch.dict('util.ipresolver.CACHE', test_ip_range_cache):
|
||||
assert ipresolver.resolve_ip(test_aws_ip) == ResolvedLocation(provider='aws', region=u'GLOBAL', service=None, sync_token=123456789)
|
||||
assert ipresolver.resolve_ip('10.0.0.2') == ResolvedLocation(provider='aws', region=u'GLOBAL', service=None, sync_token=123456789)
|
||||
assert ipresolver.resolve_ip('1.2.3.4') == ResolvedLocation(provider='internet', region=u'NA', service=u'US', sync_token=123456789)
|
||||
assert ipresolver.resolve_ip('127.0.0.1') == ResolvedLocation(provider='internet', region=None, service=None, sync_token=123456789)
|
||||
assert ipresolver.resolve_ip(test_aws_ip) == ResolvedLocation(provider='aws', region=u'GLOBAL', service=None, sync_token=123456789, country_iso_code=None)
|
||||
assert ipresolver.resolve_ip('10.0.0.2') == ResolvedLocation(provider='aws', region=u'GLOBAL', service=None, sync_token=123456789, country_iso_code=None)
|
||||
assert ipresolver.resolve_ip('1.2.3.4') == ResolvedLocation(provider='internet', region=u'NA', service=u'US', sync_token=123456789, country_iso_code=u'US')
|
||||
assert ipresolver.resolve_ip('127.0.0.1') == ResolvedLocation(provider='internet', region=None, service=None, sync_token=123456789, country_iso_code=None)
|
||||
|
||||
def test_thread_missing_file():
|
||||
class LoopInterruptionForTest(Exception):
|
||||
|
|
Reference in a new issue