def update_local(self, request): api = PeeringDB() synchronization = api.update_local_database(api.get_last_sync_time()) return Response( {"synchronization": SynchronizationSerializer(synchronization).data} )
def get_available_peers(self): # Not linked to PeeringDB, cannot determine peers if not self.peeringdb_id: return None # Get the IX LAN we are belonging to api = PeeringDB() network_ixlan = api.get_ix_network(self.peeringdb_id) # Get all peering sessions currently existing existing_sessions = self.get_peering_sessions() ipv4_sessions = [] ipv6_sessions = [] for session in existing_sessions: ip = ipaddress.ip_address(session.ip_address) if ip.version == 6: ipv6_sessions.append(str(ip)) elif ip.version == 4: ipv4_sessions.append(str(ip)) else: self.logger.debug("peering session with strange ip: %s", ip) # Find all peers belonging to the same IX and order them by ASN # Exclude our own ASN and already existing sessions return PeerRecord.objects.filter( Q(network_ixlan__ixlan_id=network_ixlan.ixlan_id) & ~Q(network__asn=settings.MY_ASN) & ( ~Q(network_ixlan__ipaddr6__in=ipv6_sessions) | ~Q(network_ixlan__ipaddr4__in=ipv4_sessions) ) ).order_by("network__asn")
def synchronize_with_peeringdb(self): """ Synchronize AS properties with those found in PeeringDB. """ peeringdb_info = PeeringDB().get_autonomous_system(self.asn) # No record found, nothing to sync if not peeringdb_info: return False # Always synchronize the name self.name = peeringdb_info.name # Sync other properties if we are told to do so if self.irr_as_set_peeringdb_sync: self.irr_as_set = peeringdb_info.irr_as_set if self.ipv6_max_prefixes_peeringdb_sync: self.ipv6_max_prefixes = peeringdb_info.info_prefixes6 if self.ipv4_max_prefixes_peeringdb_sync: self.ipv4_max_prefixes = peeringdb_info.info_prefixes4 # Save the new AS self.save() return True
def test_get_ix_network(self): api = PeeringDB() ix_network_id = 29146 # Must not exist self.assertIsNone(api.get_ix_network(0)) # Using an API call (no cached data) ix_network = api.get_ix_network(ix_network_id) self.assertEqual(ix_network.id, ix_network_id) # Save the data inside the cache details = { "id": ix_network.id, "asn": ix_network.asn, "name": ix_network.name, "ix_id": ix_network.ix_id, "ixlan_id": ix_network.ixlan_id, } network_ixlan = NetworkIXLAN(**details) network_ixlan.save() # Using no API calls (cached data) ix_network = api.get_ix_network(ix_network_id) self.assertEqual(ix_network.id, ix_network_id)
def test_get_ix_network(self, *_): api = PeeringDB() ix_network_id = 1 with patch("peeringdb.http.requests.get", return_value=MockedResponse(status_code=404)): # Must not exist self.assertIsNone(api.get_ix_network(0)) # Using an API call (no cached data) ix_network = api.get_ix_network(ix_network_id) self.assertEqual(ix_network.id, ix_network_id) # Save the data inside the cache details = { "id": ix_network.id, "asn": ix_network.asn, "name": ix_network.name, "ix_id": ix_network.ix_id, "ixlan_id": ix_network.ixlan_id, } network_ixlan = NetworkIXLAN(**details) network_ixlan.save() # Using no API calls (cached data) ix_network = api.get_ix_network(ix_network_id) self.assertEqual(ix_network.id, ix_network_id)
def test_get_autonomous_system(self, *_): api = PeeringDB() asn = 65536 # Must not exist with patch("peeringdb.http.requests.get", return_value=MockedResponse(status_code=404)): self.assertIsNone(api.get_autonomous_system(64500)) # Using an API call (no cached data) autonomous_system = api.get_autonomous_system(asn) self.assertEqual(autonomous_system.asn, asn) # Save the data inside the cache details = { "id": autonomous_system.id, "asn": autonomous_system.asn, "name": autonomous_system.name, } network = Network(**details) network.save() # Using no API calls (cached data) autonomous_system = api.get_autonomous_system(asn) self.assertEqual(autonomous_system.asn, asn)
def test_get_last_synchronization(self): api = PeeringDB() # Test when no sync has been done self.assertIsNone(api.get_last_synchronization()) # Test of sync record with no objects time_of_sync = timezone.now() api.record_last_sync(time_of_sync, { "added": 0, "updated": 0, "deleted": 0 }) self.assertEqual(api.get_last_sync_time(), 0) # Test of sync record with one object time_of_sync = timezone.now() api.record_last_sync(time_of_sync, { "added": 1, "updated": 0, "deleted": 0 }) self.assertEqual( int(api.get_last_synchronization().time.timestamp()), int(time_of_sync.timestamp()), )
def test_get_ix_networks_for_asn(self): api = PeeringDB() asn = 29467 # Must not exist self.assertIsNone(api.get_ix_networks_for_asn(64500)) known_ix_networks = [ 29146, 15321, 24292, 15210, 16774, 14657, 23162, 14659, 17707, 27863, 48704, 51129, ] found_ix_networks = [] ix_networks = api.get_ix_networks_for_asn(asn) for ix_network in ix_networks: found_ix_networks.append(ix_network.id) self.assertEqual(sorted(found_ix_networks), sorted(known_ix_networks))
def get_objects(self): objects = [] known_objects = [] api = PeeringDB() for ix in InternetExchange.objects.all(): if ix.peeringdb_id: known_objects.append(ix.peeringdb_id) ix_networks = api.get_ix_networks_for_asn(settings.MY_ASN) or [] slugs_occurences = {} for ix_network in ix_networks: if ix_network.id not in known_objects: slug = slugify(ix_network.name) if slug in slugs_occurences: slugs_occurences[slug] += 1 slug = "{}-{}".format(slug, slugs_occurences[slug]) else: slugs_occurences[slug] = 0 objects.append({ "peeringdb_id": ix_network.id, "name": ix_network.name, "slug": slug, "ipv6_address": ix_network.ipaddr6, "ipv4_address": ix_network.ipaddr4, }) return objects
def build_queryset(self, request, kwargs): queryset = None # The queryset needs to be composed of Contact objects related to the AS we # are looking at. if "asn" in kwargs: autonomous_system = get_object_or_404(AutonomousSystem, asn=kwargs["asn"]) queryset = PeeringDB().get_autonomous_system_contacts(autonomous_system.asn) return queryset
def test_get_peers_for_ix(self): api = PeeringDB() ix_id = 1019 # Must not be found self.assertIsNone(api.get_peers_for_ix(0)) # Must have some peers self.assertEqual(len(api.get_peers_for_ix(ix_id)), 10)
def get_common_internet_exchanges(self): """ Return all IX we have in common with the AS. """ # Get common IX networks between us and this AS common = PeeringDB().get_common_ix_networks_for_asns(settings.MY_ASN, self.asn) return InternetExchange.objects.filter( peeringdb_id__in=[us.id for us, _ in common] )
def get_peeringdb_id(self): """ Retrieves the PeeringDB ID for this IX based on the IP addresses that have been recorded. The ID of the PeeringDB record will be returned on success. In any other cases 0 will be returned. """ network_ixlan = PeeringDB().get_ix_network_by_ip_address( ipv6_address=self.ipv6_address, ipv4_address=self.ipv4_address) return network_ixlan.id if network_ixlan else 0
def find_potential_ix_peering_sessions(self): """ Saves an IP address list. Each IP address of the list is the address of a potential peering session with the current AS on an Internet Exchange. """ # Potential IX peering sessions potential_ix_peering_sessions = [] # Get common IX networks between us and this AS common = PeeringDB().get_common_ix_networks_for_asns(settings.MY_ASN, self.asn) # For each common networks take a look at it for us, peer in common: peering_sessions = [] if peer.ipaddr6: try: peering_sessions.append(str(ipaddress.IPv6Address(peer.ipaddr6))) except ipaddress.AddressValueError: continue if peer.ipaddr4: try: peering_sessions.append(str(ipaddress.IPv4Address(peer.ipaddr4))) except ipaddress.AddressValueError: continue # Get all known sessions for this AS on the given IX known_sessions = InternetExchangePeeringSession.objects.filter( autonomous_system=self, ip_address__in=peering_sessions ) # Check if peer IP addresses are known sessions for peering_session in peering_sessions: # Consider the session as not existing at first exists = False for known_session in known_sessions: if peering_session == known_session.ip_address: # If the IP is found, stop looking for the info and mark it # as the peering session as existing exists = True break if not exists: # If the IP address is not used in any peering sessions append it, # keep an eye on it potential_ix_peering_sessions.append(peering_session) # Only save the new potential IX peering session list if it has changed if ( potential_ix_peering_sessions != self.potential_internet_exchange_peering_sessions ): self.potential_internet_exchange_peering_sessions = ( potential_ix_peering_sessions ) self.save()
def handle(self, *args, **options): self.logger.info("Syncing networks with PeeringDB...") api = PeeringDB() api.update_local_database(api.get_last_sync_time()) self.logger.info("Syncing AS details with PeeringDB...") autonomous_systems = AutonomousSystem.objects.all() for autonomous_system in autonomous_systems: autonomous_system.synchronize_with_peeringdb()
def is_peeringdb_valid(self): """ Tells if the PeeringDB ID for this IX is still valid. This function will return true if the PeeringDB record for this IX is valid or if this IX does not have a Peering DB ID set. In any other cases, the return value will be false. """ if self.peeringdb_id: peeringdb_record = PeeringDB().get_ix_network(self.peeringdb_id) if not peeringdb_record: return False return True
def test_get_peers_for_ix(self): api = PeeringDB() with patch("peeringdb.http.requests.get", return_value=MockedResponse(status_code=404)): # Must not be found self.assertIsNone(api.get_peers_for_ix(0)) with patch( "peeringdb.http.requests.get", return_value=MockedResponse( fixture="peeringdb/tests/fixtures/netixlan_by_ix_id.json"), ): # Must have some peers self.assertEqual(len(api.get_peers_for_ix(1)), 2)
def test_get_prefixes_for_ix_network(self): api = PeeringDB() ix_network_id = 29146 # Must be empty self.assertFalse(api.get_prefixes_for_ix_network(0)) known_prefixes = [ ipaddress.ip_network("2001:7f8:1::/64"), ipaddress.ip_network("80.249.208.0/21"), ] found_prefixes = [] for ix_prefix in api.get_prefixes_for_ix_network(ix_network_id): self.assertIn(ix_prefix, known_prefixes)
def test_get_prefixes_for_ix_network(self): api = PeeringDB() ix_network_id = 29146 # Must be empty self.assertFalse(api.get_prefixes_for_ix_network(0)) known_prefixes = ["2001:7f8:1::/64", "80.249.208.0/21"] found_prefixes = [] ix_prefixes = api.get_prefixes_for_ix_network(ix_network_id) for ix_prefix in ix_prefixes: found_prefixes.append(ix_prefix) self.assertEqual(sorted(found_prefixes), sorted(known_prefixes))
def test_get_common_ix_networks_for_asns(self): api = PeeringDB() asn1 = 29467 asn2 = 50903 # Empty list should be returned self.assertFalse(api.get_common_ix_networks_for_asns(asn1, 64500)) # Known common IX networks known_ix_networks = [359, 255] found_ix_networks = [] # Found common IX networks for n1, n2 in api.get_common_ix_networks_for_asns(asn1, asn2): self.assertEqual(n1.ixlan_id, n2.ixlan_id) found_ix_networks.append(n1.ixlan_id) self.assertEqual(sorted(known_ix_networks), sorted(found_ix_networks))
def test_get_prefixes_for_ix_network(self, *_): api = PeeringDB() ix_network_id = 29146 with patch("peeringdb.http.requests.get", return_value=MockedResponse(status_code=404)): # Must be empty self.assertFalse(api.get_prefixes_for_ix_network(0)) known_prefixes = [ ipaddress.ip_network("2001:db8:1337::/64"), ipaddress.ip_network("203.0.113.0/24"), ] found_prefixes = [] for ix_prefix in api.get_prefixes_for_ix_network(ix_network_id): self.assertIn(ix_prefix, known_prefixes)
def test_get_common_ix_networks_for_asns(self, *_): api = PeeringDB() asn1 = 65536 asn2 = 65537 with patch("peeringdb.http.requests.get", return_value=MockedResponse(status_code=404)): # Empty list should be returned self.assertFalse(api.get_common_ix_networks_for_asns(asn1, 64500)) # Found common IX networks found_ix_networks = [] for n1, n2 in api.get_common_ix_networks_for_asns(asn1, asn2): self.assertEqual(n1.ixlan_id, n2.ixlan_id) found_ix_networks.append(n1.ixlan_id) self.assertEqual([1], found_ix_networks)
def test_get_ix_networks_for_asn(self, *_): api = PeeringDB() asn = 65536 with patch("peeringdb.http.requests.get", return_value=MockedResponse(status_code=404)): # Must not exist self.assertIsNone(api.get_ix_networks_for_asn(64500)) known_ix_networks = [1, 2] found_ix_networks = [] ix_networks = api.get_ix_networks_for_asn(asn) for ix_network in ix_networks: found_ix_networks.append(ix_network.id) self.assertEqual(sorted(found_ix_networks), sorted(known_ix_networks))
def test_get_ix_network_by_ip_address(self, *_): api = PeeringDB() ipv6_address = "2001:db8:1337::1" ipv4_address = "203.0.113.1" ix_network_id = 1 # No IP given we cannot guess what the user wants self.assertIsNone(api.get_ix_network_by_ip_address()) # Using an API call (no cached data) ix_network = api.get_ix_network_by_ip_address( ipv6_address=ipv6_address) self.assertEqual(ix_network.id, ix_network_id) ix_network = api.get_ix_network_by_ip_address( ipv4_address=ipv4_address) self.assertEqual(ix_network.id, ix_network_id) ix_network = api.get_ix_network_by_ip_address( ipv6_address=ipv6_address, ipv4_address=ipv4_address) self.assertEqual(ix_network.id, ix_network_id) # Save the data inside the cache details = { "id": ix_network.id, "asn": ix_network.asn, "name": ix_network.name, "ipaddr6": ipv6_address, "ipaddr4": ipv4_address, "ix_id": ix_network.ix_id, "ixlan_id": ix_network.ixlan_id, } network_ixlan = NetworkIXLAN(**details) network_ixlan.save() # Using no API calls (cached data) ix_network = api.get_ix_network_by_ip_address( ipv6_address=ipv6_address) self.assertEqual(ix_network.id, ix_network_id) ix_network = api.get_ix_network_by_ip_address( ipv4_address=ipv4_address) self.assertEqual(ix_network.id, ix_network_id) ix_network = api.get_ix_network_by_ip_address( ipv6_address=ipv6_address, ipv4_address=ipv4_address) self.assertEqual(ix_network.id, ix_network_id)
def get(self, request, asn): autonomous_system = get_object_or_404(AutonomousSystem, asn=asn) peeringdb_contacts = PeeringDB().get_autonomous_system_contacts( autonomous_system.asn) common_ix_and_sessions = [] for ix in autonomous_system.get_common_internet_exchanges(): common_ix_and_sessions.append({ "internet_exchange": ix, "has_potential_ix_peering_sessions": autonomous_system.has_potential_ix_peering_sessions(ix), }) context = { "autonomous_system": autonomous_system, "peeringdb_contacts": peeringdb_contacts, "common_ix_and_sessions": common_ix_and_sessions, } return render(request, "peering/as/details.html", context)
def create_from_peeringdb(asn): peeringdb_network = PeeringDB().get_autonomous_system(asn) if not peeringdb_network: return None try: return AutonomousSystem.objects.get(asn=peeringdb_network.asn) except AutonomousSystem.DoesNotExist: values = { "asn": peeringdb_network.asn, "name": peeringdb_network.name, "irr_as_set": peeringdb_network.irr_as_set, "ipv6_max_prefixes": peeringdb_network.info_prefixes6, "ipv4_max_prefixes": peeringdb_network.info_prefixes4, } autonomous_system = AutonomousSystem(**values) autonomous_system.save() return autonomous_system
def get_objects(self): objects = [] known_objects = [] api = PeeringDB() for ix in InternetExchange.objects.all(): if ix.peeringdb_id: known_objects.append(ix.peeringdb_id) ix_networks = api.get_ix_networks_for_asn(settings.MY_ASN) or [] for ix_network in ix_networks: if ix_network.id not in known_objects: objects.append({ "peeringdb_id": ix_network.id, "name": ix_network.name, "slug": slugify(ix_network.name), "ipv6_address": ix_network.ipaddr6, "ipv4_address": ix_network.ipaddr4, }) return objects
def test_get_autonomous_system(self): api = PeeringDB() asn = 15169 # Must not exist self.assertIsNone(api.get_autonomous_system(64500)) # Using an API call (no cached data) autonomous_system = api.get_autonomous_system(asn) self.assertEqual(autonomous_system.asn, asn) # Save the data inside the cache details = { "id": autonomous_system.id, "asn": autonomous_system.asn, "name": autonomous_system.name, } network = Network(**details) network.save() # Using no API calls (cached data) autonomous_system = api.get_autonomous_system(asn) self.assertEqual(autonomous_system.asn, asn)
def test_clear_local_database(self): try: PeeringDB().clear_local_database() except Exception: self.fail("Unexpected exception raised.")
def test_update_local_database(self, *_): sync_result = PeeringDB().update_local_database(0) self.assertEqual(8, sync_result.added) self.assertEqual(0, sync_result.updated) self.assertEqual(0, sync_result.deleted)