Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions pybird/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,89 @@ def _parse_peer_data(self, data, data_contains_detail):

return peers

def get_rpki_status(self, peer_name=None):
"""Get the status of all peers or a specific peer.

Optional argument: peer_name: case-sensitive full name of a peer,
as configured in BIRD.

If no argument is given, returns a list of peers - each peer represented
by a dict with fields. See README for a full list.

If a peer_name argument is given, returns a single peer, represented
as a dict. If the peer is not found, returns a zero length array.
"""
if peer_name:
query = 'show protocols all "%s"' % self._clean_input(peer_name)
else:
query = "show protocols all"

data = self._send_query(query)
if not self.socket_file:
return data

peers = self._parse_rpki_data(data=data, data_contains_detail=True)

if not peer_name:
return peers

if len(peers) == 0:
return []
elif len(peers) > 1:
raise ValueError(
"Searched for a specific peer, but got multiple returned from BIRD?"
)
else:
return peers[0]

def _parse_rpki_data(self, data, data_contains_detail):
"""Parse the data from BIRD to find peer information."""
lineiterator = iter(data.splitlines())
peers = []

peer_summary = None

for line in lineiterator:
line = line.strip()
(field_number, line) = self._extract_field_number(line)

if field_number in self.ignored_field_numbers:
continue

if field_number == 1002:
peer_summary = self._parse_peer_summary(line)
if peer_summary["protocol"] != "RPKI":
peer_summary = None
continue

# If there is no detail section to be expected,
# we are done.
if not data_contains_detail:
peers.append_peer_summary()
continue

peer_detail = None
if field_number == 1006:
if not peer_summary:
# This is not detail of a BGP peer
continue

# A peer summary spans multiple lines, read them all
peer_detail_raw = []
while line.strip() != "":
peer_detail_raw.append(line)
line = next(lineiterator)

peer_detail = self._parse_peer_detail(peer_detail_raw)

# Save the summary+detail info in our result
peer_detail.update(peer_summary)
peers.append(peer_detail)
# Do not use this summary again on the next run
peer_summary = None

return peers

def _parse_peer_summary(self, line):
"""Parse the summary of a peer line, like:
PS1 BGP T_PS1 start Jun13 Passive
Expand Down