generated from Ostorlab/template_agent
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11 from Ostorlab/feature/ip_range_vistor
A draft of ip range visitor to minimize requests to geo range.
- Loading branch information
Showing
8 changed files
with
180 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
""" Module Responsible for sending ip range geolocation""" | ||
import ipaddress | ||
from typing import Callable, Tuple, Any | ||
|
||
from agent import ip2geo | ||
from agent.ip2geo import logger | ||
|
||
|
||
class Error(Exception): | ||
"""Base Error""" | ||
|
||
|
||
class IPGeoError(Error): | ||
"""Error getting the IP geolocation""" | ||
|
||
|
||
class IpRangeVisitor: | ||
"""Ip range visitor implementation.""" | ||
|
||
def dichotomy_ip_network_visit(self, ip_network: ipaddress.IPv4Network | ipaddress.IPv6Network, | ||
accept: Callable[ | ||
[ipaddress.IPv4Network | ipaddress.IPv6Network], Tuple[bool, Any]]) -> Any: | ||
"""get ip ranges based on geolocation""" | ||
|
||
should_continue, result = accept(ip_network) | ||
yield result | ||
if should_continue is False: | ||
return | ||
|
||
subnets = list(ip_network.subnets()) | ||
|
||
if len(subnets) == 1: | ||
# reached the last block. | ||
return | ||
|
||
for subnet in subnets: | ||
yield from self.dichotomy_ip_network_visit(subnet, accept) | ||
|
||
@staticmethod | ||
def is_first_last_ip_same_geolocation(ip_network: ipaddress.IPv4Network | ipaddress.IPv6Network | ||
) -> Tuple[bool, Any]: | ||
"""Compare geolocation of network extremes""" | ||
|
||
first, last = ip_network[0], ip_network[-1] | ||
locator = ip2geo.Ip2GeoLocator() | ||
first_location = locator.get_geolocation_details(str(first)) | ||
last_location = locator.get_geolocation_details(str(last)) | ||
try: | ||
if first_location['latitude'] == last_location['latitude'] and \ | ||
first_location['longitude'] == last_location['longitude']: | ||
return False, (first_location, last_location, ip_network) | ||
else: | ||
return True, (first_location, last_location, ip_network) | ||
except IPGeoError as e: | ||
logger.warning('Error happens in is_first_last_ip_same_geolocation process: %s', str(e)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
"""Unittests for the IP range visitor.""" | ||
|
||
import ipaddress | ||
|
||
from agent.utils.ip_range_visitor import IpRangeVisitor | ||
|
||
ip_range_visitor = IpRangeVisitor() | ||
|
||
|
||
def testVistor_withMatchingIPAndMaskRecieved_returnsLocations(): | ||
results = [] | ||
for result in ip_range_visitor.dichotomy_ip_network_visit(ipaddress.ip_network('8.8.8.0/22'), | ||
ip_range_visitor.is_first_last_ip_same_geolocation): | ||
results.append(result[0:2]) | ||
|
||
assert results == [({'host': '8.8.8.0', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'CA', 'region_name': 'California', | ||
'city': 'Mountain View', 'zip': '94043', 'latitude': 37.4223, 'longitude': -122.085, | ||
'timezone': 'America/Los_Angeles'}, | ||
{'host': '8.8.11.255', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'LA', 'region_name': 'Louisiana', | ||
'city': 'Monroe', 'zip': '71203', 'latitude': 32.5896, 'longitude': -92.0669, | ||
'timezone': 'America/Chicago'}), ( | ||
{'host': '8.8.8.0', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'CA', | ||
'region_name': 'California', | ||
'city': 'Mountain View', 'zip': '94043', 'latitude': 37.4223, 'longitude': -122.085, | ||
'timezone': 'America/Los_Angeles'}, | ||
{'host': '8.8.9.255', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'FL', 'region_name': 'Florida', | ||
'city': 'Fort Lauderdale', 'zip': '33309', 'latitude': 26.2018, 'longitude': -80.1699, | ||
'timezone': 'America/New_York'}), ( | ||
{'host': '8.8.8.0', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'CA', | ||
'region_name': 'California', | ||
'city': 'Mountain View', 'zip': '94043', 'latitude': 37.4223, 'longitude': -122.085, | ||
'timezone': 'America/Los_Angeles'}, | ||
{'host': '8.8.8.255', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'CA', | ||
'region_name': 'California', | ||
'city': 'Mountain View', 'zip': '94043', 'latitude': 37.4223, 'longitude': -122.085, | ||
'timezone': 'America/Los_Angeles'}), ( | ||
{'host': '8.8.9.0', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'FL', 'region_name': 'Florida', | ||
'city': 'Fort Lauderdale', 'zip': '33309', 'latitude': 26.2018, 'longitude': -80.1699, | ||
'timezone': 'America/New_York'}, | ||
{'host': '8.8.9.255', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'FL', 'region_name': 'Florida', | ||
'city': 'Fort Lauderdale', 'zip': '33309', 'latitude': 26.2018, 'longitude': -80.1699, | ||
'timezone': 'America/New_York'}), ( | ||
{'host': '8.8.10.0', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'DC', | ||
'region_name': 'District of Columbia', 'city': 'Washington', 'zip': '20068', | ||
'latitude': 38.9072, 'longitude': -77.0369, 'timezone': 'America/New_York'}, | ||
{'host': '8.8.11.255', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'LA', | ||
'region_name': 'Louisiana', | ||
'city': 'Monroe', 'zip': '71203', 'latitude': 32.5896, 'longitude': -92.0669, | ||
'timezone': 'America/Chicago'}), ( | ||
{'host': '8.8.10.0', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'DC', | ||
'region_name': 'District of Columbia', 'city': 'Washington', 'zip': '20068', | ||
'latitude': 38.9072, 'longitude': -77.0369, 'timezone': 'America/New_York'}, | ||
{'host': '8.8.10.255', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'DC', | ||
'region_name': 'District of Columbia', 'city': 'Washington', 'zip': '20068', | ||
'latitude': 38.9072, 'longitude': -77.0369, 'timezone': 'America/New_York'}), ( | ||
{'host': '8.8.11.0', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'LA', | ||
'region_name': 'Louisiana', | ||
'city': 'Monroe', 'zip': '71203', 'latitude': 32.5896, 'longitude': -92.0669, | ||
'timezone': 'America/Chicago'}, | ||
{'host': '8.8.11.255', 'version': 4, 'continent': 'North America', 'continent_code': 'NA', | ||
'country': 'United States', 'country_code': 'US', 'region': 'LA', | ||
'region_name': 'Louisiana', | ||
'city': 'Monroe', 'zip': '71203', 'latitude': 32.5896, 'longitude': -92.0669, | ||
'timezone': 'America/Chicago'})] | ||
|
||
|
||
def testVistor_withMaskNotRecieved_returnsIfFirstIPGeolocationEqualLastIPGeolocation(): | ||
for result in ip_range_visitor.dichotomy_ip_network_visit(ipaddress.ip_network('8.8.8.0/32'), | ||
ip_range_visitor.is_first_last_ip_same_geolocation): | ||
assert result[0] == result[1] |