def get_bgp_neighbors(self): bgp_neighbors = defaultdict(lambda: dict(peers={})) sent_prefixes = defaultdict(lambda: defaultdict(int)) # Count prefixes advertised to each configured peer for route in self.api("/routing/bgp/advertisements/print"): sent_prefixes[route["peer"]]["ipv{}".format( IPNetwork(route["prefix"]).version)] += 1 # Calculate stats for each routing bgp instance for inst in self.api("/routing/bgp/instance/print"): instance_name = "global" if inst["name"] == "default" else inst[ "name"] bgp_neighbors[instance_name]["router_id"] = inst["router-id"] inst_peers = find_rows(self.api("/routing/bgp/peer/print"), key="instance", value=inst["name"]) for peer in inst_peers: prefix_stats = {} # Mikrotik prefix counts are not per-AFI so attempt to query # the routing table if more than one address family is present on a peer if len(peer["address-families"].split(",")) > 1: for af in peer["address-families"].split(","): prefix_count = len( self.api.path(f"/{af}/route").select( Keys.dst_addr).where( Keys.bgp == True, # pylint: disable=singleton-comparison Keys.rcv_from == peer["name"], )) family = "ipv4" if af == "ip" else af prefix_stats[family] = { "sent_prefixes": sent_prefixes.get(peer["name"], {}).get(family, 0), "accepted_prefixes": prefix_count, "received_prefixes": prefix_count, } else: family = "ipv4" if peer["address-families"] == "ip" else af prefix_stats[family] = { "sent_prefixes": sent_prefixes.get(peer["name"], {}).get(family, 0), "accepted_prefixes": peer.get("prefix-count", 0), "received_prefixes": peer.get("prefix-count", 0), } bgp_neighbors[instance_name]["peers"][ peer["remote-address"]] = { "local_as": inst["as"], "remote_as": peer["remote-as"], "remote_id": peer.get("remote-id", ""), "is_up": peer.get("established", False), "is_enabled": not peer["disabled"], "description": peer["name"], "uptime": to_seconds(peer.get("uptime", "0s")), "address_family": prefix_stats, } return dict(bgp_neighbors)
def bgp_peer_detail(peer, inst, sent_prefixes): return { "up": peer.get("established", False), "local_as": inst["as"], "remote_as": peer["remote-as"], "router_id": inst["router-id"], "local_address": peer.get("local-address", False), "local_address_configured": bool(peer.get("local-address", False)), "local_port": 179, "routing_table": inst["routing-table"], "remote_address": peer["remote-address"], "remote_port": 179, "multihop": peer["multihop"], "multipath": False, "remove_private_as": peer["remove-private-as"], "import_policy": peer["in-filter"], "export_policy": peer["out-filter"], "input_messages": peer.get("updates-received", 0) + peer.get("withdrawn-received", 0), "output_messages": peer.get("updates-sent", 0) + peer.get("withdrawn-sent", 0), "input_updates": peer.get("updates-received", 0), "output_updates": peer.get("updates-sent", 0), "messages_queued_out": 0, "connection_state": peer.get("state", ""), "previous_connection_state": "", "last_event": "", "suppress_4byte_as": not peer.get("as4-capability", True), "local_as_prepend": False, "holdtime": to_seconds(peer.get("used-hold-time", peer.get("hold-time", "30s"))), "configured_holdtime": to_seconds(peer.get("hold-time", "30s")), "keepalive": to_seconds(peer.get("used-keepalive-time", "10s")), "configured_keepalive": to_seconds(peer.get("keepalive-time", "10s")), "active_prefix_count": peer.get("prefix-count", 0), "received_prefix_count": peer.get("prefix-count", 0), "accepted_prefix_count": peer.get("prefix-count", 0), "suppressed_prefix_count": 0, "advertised_prefix_count": sent_prefixes.get(peer["name"], 0), "flap_count": 0, }
def get_facts(self): resource = self.api('/system/resource/print')[0] identity = self.api('/system/identity/print')[0] routerboard = self.api('/system/routerboard/print')[0] interfaces = self.api('/interface/print') return { 'uptime': to_seconds(resource['uptime']), 'vendor': resource['platform'], 'model': resource['board-name'], 'hostname': identity['name'], 'fqdn': u'', 'os_version': resource['version'], 'serial_number': routerboard.get('serial-number', ''), 'interface_list': napalm.base.utils.string_parsers.sorted_nicely( tuple(iface['name'] for iface in interfaces) ), }
def get_facts(self): resource = self.api('/system/resource/print')[0] identity = self.api('/system/identity/print')[0] routerboard = self.api('/system/routerboard/print')[0] interfaces = self.api('/interface/print') return { 'uptime': to_seconds(resource['uptime']), 'vendor': resource['platform'], 'model': resource['board-name'], 'hostname': identity['name'], 'fqdn': u'', 'os_version': resource['version'], 'serial_number': routerboard.get('serial-number', ''), 'interface_list': napalm.base.utils.string_parsers.sorted_nicely( tuple(iface['name'] for iface in interfaces) ), }
def test_to_seconds(passed, expected): assert utils.to_seconds(passed) == expected
def get_bgp_neighbors_detail(self, neighbor_address=""): sent_prefixes = defaultdict(int) bgp_neighbors = defaultdict(lambda: defaultdict(list)) # Get all configured peers peers = self.api("/routing/bgp/peer/print") # Get all configured advertisements advertisements = self.api("/routing/bgp/advertisements/print") # Count prefixes advertised to each configured peer for route in advertisements: sent_prefixes[route["peer"]] += 1 for inst in self.api("/routing/bgp/instance/print"): instance_name = "global" if inst["name"] == "default" else inst[ "name"] inst_peers = find(peers, key="instance", value=inst["name"]) for peer in inst_peers: if neighbor_address and peer[ "remote-address"] != neighbor_address: continue peer_details = { "up": peer.get("established", False), "local_as": inst["as"], "remote_as": peer["remote-as"], "router_id": inst["router-id"], "local_address": peer.get("local-address", False), "local_address_configured": bool(peer.get("local-address", False)), "local_port": 179, "routing_table": inst["routing-table"], "remote_address": peer["remote-address"], "remote_port": 179, "multihop": peer["multihop"], "multipath": False, "remove_private_as": peer["remove-private-as"], "import_policy": peer["in-filter"], "export_policy": peer["out-filter"], "input_messages": peer.get("updates-received", 0) + peer.get("withdrawn-received", 0), "output_messages": peer.get("updates-sent", 0) + peer.get("withdrawn-sent", 0), "input_updates": peer.get("updates-received", 0), "output_updates": peer.get("updates-sent", 0), "messages_queued_out": 0, "connection_state": peer.get("state", ""), "previous_connection_state": "", "last_event": "", "suppress_4byte_as": not peer.get("as4-capability", True), "local_as_prepend": False, "holdtime": to_seconds( peer.get("used-hold-time", peer.get("hold-time", "30s"))), "configured_holdtime": to_seconds(peer.get("hold-time", "30s")), "keepalive": to_seconds(peer.get("used-keepalive-time", "10s")), "configured_keepalive": to_seconds(peer.get("keepalive-time", "10s")), "active_prefix_count": peer.get("prefix-count", 0), "received_prefix_count": peer.get("prefix-count", 0), "accepted_prefix_count": peer.get("prefix-count", 0), "suppressed_prefix_count": 0, "advertised_prefix_count": sent_prefixes.get(peer["name"], 0), "flap_count": 0, } bgp_neighbors[instance_name][peer["remote-as"]].append( peer_details) return {k: dict(v) for k, v in bgp_neighbors.items()}
def test_to_seconds(passed, expected): assert utils.to_seconds(passed) == expected