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