diff --git a/README.md b/README.md index 0c10bab..b6edcf7 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,104 @@ Fetching PeeringDB info for 13414 +----------------------------------------------------+----------------+---------------------+ ``` +## --missing-private + +The cli switch to print the Facilities in which the given list of ASNs are not present in, and report if the present facility. + +eg: +``` +$ peerfinder --asn 2603 13414 --missing-private +Fetching PeeringDB info for 2603,13414 ++-------------------------------------------------+-----------+---------------+ +| Facility | NORDUnet | Twitter, Inc. | ++-------------------------------------------------+-----------+---------------+ +| BT Citywest Data Centre | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| CERN Geneva | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Digital Realty ATL (56 Marietta) | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Digital Realty Amsterdam AMS9 | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Digital Realty Copenhagen CPH1-3 | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Digital Realty Frankfurt FRA1-16 | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Digital Realty NYC (32 AofA) | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Digital Realty Stockholm STO1-6 | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Equinix AM7 - Amsterdam, Kuiperberweg | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix AT1 - Atlanta | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix DA3 - Dallas | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix FR5 - Frankfurt, KleyerStrasse | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix MI1 - Miami, NOTA | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix NY2/NY4/NY5/NY6 - New York, Secaucus | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix OS1 - Osaka | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix SG1 - Singapore | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix SK1 - Stockholm, Bromma | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Equinix SV1/SV5/SV10 - Silicon Valley, San Jose | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix SY1/SY2 - Sydney | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix TY1 - Tokyo | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Forskningsparken Oslo | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Global Switch Singapore | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| GlobalConnect Hamburg (HAM2) | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| MEGA-i (iAdvantage Hong Kong) | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| RIX-K2 | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| RIX-TG | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Telia Copenhagen | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Telia Stockholm STK2 | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| UNI-C | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Verne Iceland | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +``` + +It also prints the specified country code. + +eg: +``` +$ peerfinder --asn 2603 13414 --missing-private US +Fetching PeeringDB info for 2603,13414 ++-------------------------------------------------+-----------+---------------+ +| Facility in US | NORDUnet | Twitter, Inc. | ++-------------------------------------------------+-----------+---------------+ +| Digital Realty ATL (56 Marietta) | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Digital Realty NYC (32 AofA) | ASN: 2603 | | ++-------------------------------------------------+-----------+---------------+ +| Equinix AT1 - Atlanta | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix DA3 - Dallas | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix MI1 - Miami, NOTA | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix NY2/NY4/NY5/NY6 - New York, Secaucus | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +| Equinix SV1/SV5/SV10 - Silicon Valley, San Jose | | ASN: 13414 | ++-------------------------------------------------+-----------+---------------+ +``` + ## Bugs, Features Please open a PR! diff --git a/peerfinder/peerfinder.py b/peerfinder/peerfinder.py index 3dfc196..ef0bf2b 100755 --- a/peerfinder/peerfinder.py +++ b/peerfinder/peerfinder.py @@ -23,6 +23,10 @@ class NoIXFoundException(Error): """IX Not Found Exception.""" +class NoFacilityFoundException(Error): + """Facility Not Found Exception.""" + + @dataclass class IXP: """IXP represents a specific IXP entry. @@ -47,10 +51,12 @@ class Facility: Attributes: name: The facility name. ASN: Local asn. + country: The country code. """ name: str ASN: int + country: str @dataclass @@ -94,6 +100,9 @@ def main(): if args.missing: print_uncommon(peers) + if args.missing_fac: + print_uncommon_fac(peers, args.missing_fac) + exit(0) @@ -130,7 +139,7 @@ def pdb_to_fac(netfac_set: Dict) -> Facility: Returns: A Facility object. """ - return Facility(name=netfac_set["name"], ASN=netfac_set["local_asn"]) + return Facility(name=netfac_set["name"], ASN=netfac_set["local_asn"], country=netfac_set["country"]) def _dedup_ixs(ixlan_set: Dict) -> Dict: @@ -189,7 +198,11 @@ def fetch_fac_from_facilities(fac: str, facs: List[Facility]) -> Facility: A single Facility entry matching the name of Facility. """ - return next(i for i in facs if i.name == fac) + ret = [i for i in facs if i.name == fac] + if not ret: + raise NoFacilityFoundException(f"No Facility Found for {fac}") + else: + return ret.pop() def fetch_common_ixps(peers: List[Peer]) -> List[str]: @@ -238,6 +251,22 @@ def fetch_common_facilities(facilities: List[Facility]) -> List[str]: return common_fac +def fetch_different_facilities(facilities: List[Facility], country: str) -> List[str]: + """Return a list of Facilities which none of the peers have in common. + + Arguments: + facilities: A list of Facility objects for a given ASN. + + Returns: + A list of uncommon Facilities, based in their name. + """ + common_fac = fetch_common_facilities(facilities) + uncommon = list() + for fac in facilities: + uncommon.extend([i.name for i in fac.present_in if (i.name not in common_fac) and (country == "ALL_COUNTRY" or i.country == country)]) + return uncommon + + def print_ixp(peers: List[Peer]) -> None: common_ix_list = fetch_common_ixps(peers) if len(common_ix_list) < 1: @@ -326,6 +355,37 @@ def print_uncommon(peers: List) -> None: print(ix_tab.get_string(sortby=f"{peer.name} speed", reversesort=True)) +def print_uncommon_fac(peers: list, country: str) -> None: + uncommon_fac_list = fetch_different_facilities(peers, country) + if len(uncommon_fac_list) < 1: + print("Didnt find any uncommon Facility, exiting...") + exit(1) + header_msg = "Facility" if country == "ALL_COUNTRY" else f"Facility in {country}" + header = list() + header.append(header_msg) + + for peer in peers: + header.append(peer.name) + + ix_tab = PrettyTable(header) + ix_tab.print_empty = False + + for fac in uncommon_fac_list: + row = [fac] + for peer in peers: + try: + curr_fac = fetch_fac_from_facilities(fac, peer.present_in) + line = f"ASN: {curr_fac.ASN}" + row.append(line) + except NoFacilityFoundException as e: + line = "" + row.append(line) + ix_tab.add_row(row) + + ix_tab.hrules = 1 + print(ix_tab.get_string(sortby=header_msg)) + + def getArgs(): help_text = "Generate a table for common points in an IX. -h for help" parser = argparse.ArgumentParser(help_text) @@ -343,13 +403,21 @@ def getArgs(): default=False, action="store_true", ) + parser.add_argument( + "--missing-private", + nargs="?", + dest="missing_fac", + help="Print missing facilities", + default=False, + const="ALL_COUNTRY", + ) args = parser.parse_args() # Validate args here if not args.asn: print("--asn must be specified!") exit(1) - if not any([args.ix_only, args.fac_only, args.missing]): - print("Must specify --ix, --private or --missing!") + if not any([args.ix_only, args.fac_only, args.missing, args.missing_fac]): + print("Must specify --ix, --private, --missing or --missing-private!") exit(1) return args