This commit is contained in:
marcosvbuzo
2021-08-12 11:11:50 -07:00
committed by GitHub

View File

@@ -472,12 +472,14 @@ class VyOSDriver(NetworkDriver):
""" """
output = self.device.send_command("show ip bgp summary") output = self.device.send_command("show ip bgp summary")
output = output.split("\n") match = re.search(
r"bgp router identifier (\d+\.\d+\.\d+\.\d+), local as number (\d+) vrf-id (\d+)",
match = re.search(r".* router identifier (\d+\.\d+\.\d+\.\d+), local AS number (\d+)", output,
output[0]) re.MULTILINE | re.IGNORECASE
)
if not match: if not match:
return {} return {}
router_id = match.group(1) router_id = match.group(1)
local_as = int(match.group(2)) local_as = int(match.group(2))
@@ -486,72 +488,83 @@ class VyOSDriver(NetworkDriver):
bgp_neighbor_data["global"]["router_id"] = router_id bgp_neighbor_data["global"]["router_id"] = router_id
bgp_neighbor_data["global"]["peers"] = {} bgp_neighbor_data["global"]["peers"] = {}
# delete the header and empty element re_neighbor = re.compile(
bgp_info = [i.strip() for i in output[6:-2] if i] '^([\w\d:\.]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\w+)'
)
for bgp_line in output.split("\n"):
match = re_neighbor.search(bgp_line)
if not match:
continue
for i in bgp_info: peer_id = match.group(1)
if len(i) > 0: bgp_version = match.group(2)
peer_id, bgp_version, remote_as, msg_rcvd, msg_sent, table_version, \ remote_as = match.group(3)
in_queue, out_queue, up_time, state_prefix = i.split() msg_rcvd = match.group(4)
msg_sent = match.group(5)
table_version = match.group(6)
in_queue = match.group(7)
out_queue = match.group(8)
up_time = match.group(9)
state_prefix = match.group(10)
is_enabled = "(Admin)" not in state_prefix is_enabled = "(Admin)" not in state_prefix
received_prefixes = None received_prefixes = None
try: try:
state_prefix = int(state_prefix) state_prefix = int(state_prefix)
received_prefixes = int(state_prefix) received_prefixes = int(state_prefix)
is_up = True is_up = True
except ValueError: except ValueError:
state_prefix = -1 state_prefix = -1
received_prefixes = -1 received_prefixes = -1
is_up = False is_up = False
if bgp_version == "4": if bgp_version == "4":
address_family = "ipv4" address_family = "ipv4"
elif bgp_version == "6": elif bgp_version == "6":
address_family = "ipv6" address_family = "ipv6"
else: else:
raise ValueError("BGP neighbor parsing failed") raise ValueError("BGP neighbor parsing failed")
""" """
'show ip bgp neighbors 192.168.1.1' output example: 'show ip bgp neighbors 192.168.1.1' output example:
BGP neighbor is 192.168.1.1, remote AS 64519, local AS 64520, external link BGP neighbor is 192.168.1.1, remote AS 64519, local AS 64520, external link
BGP version 4, remote router ID 192.168.1.1 BGP version 4, remote router ID 192.168.1.1
For address family: IPv4 Unicast For address family: IPv4 Unicast
~~~ ~~~
Community attribute sent to this neighbor(both) Community attribute sent to this neighbor(both)
1 accepted prefixes 1 accepted prefixes
~~~ ~~~
""" """
bgp_detail = self.device.send_command("show ip bgp neighbors %s" % peer_id) bgp_detail = self.device.send_command("show ip bgp neighbors %s" % peer_id)
match_rid = re.search(r"remote router ID (\d+\.\d+\.\d+\.\d+).*", bgp_detail) match_rid = re.search(r"remote router ID (\d+\.\d+\.\d+\.\d+).*", bgp_detail)
remote_rid = match_rid.group(1) remote_rid = match_rid.group(1)
match_prefix_accepted = re.search(r"(\d+) accepted prefixes", bgp_detail) match_prefix_accepted = re.search(r"(\d+) accepted prefixes", bgp_detail)
accepted_prefixes = match_prefix_accepted.group(1) accepted_prefixes = match_prefix_accepted.group(1)
bgp_neighbor_data["global"]["peers"].setdefault(peer_id, {}) bgp_neighbor_data["global"]["peers"].setdefault(peer_id, {})
peer_dict = { peer_dict = {
"description": "", "description": "",
"is_enabled": bool(is_enabled), "is_enabled": bool(is_enabled),
"local_as": int(local_as), "local_as": int(local_as),
"is_up": bool(is_up), "is_up": bool(is_up),
"remote_id": remote_rid, "remote_id": remote_rid,
"uptime": int(self._bgp_time_conversion(up_time)), "uptime": int(self._bgp_time_conversion(up_time)),
"remote_as": int(remote_as) "remote_as": int(remote_as)
} }
af_dict = dict() af_dict = dict()
af_dict[address_family] = { af_dict[address_family] = {
"sent_prefixes": int(-1), "sent_prefixes": int(-1),
"accepted_prefixes": int(accepted_prefixes), "accepted_prefixes": int(accepted_prefixes),
"received_prefixes": int(received_prefixes) "received_prefixes": int(received_prefixes)
} }
peer_dict["address_family"] = af_dict peer_dict["address_family"] = af_dict
bgp_neighbor_data["global"]["peers"][peer_id] = peer_dict bgp_neighbor_data["global"]["peers"][peer_id] = peer_dict
return bgp_neighbor_data return bgp_neighbor_data
@@ -586,27 +599,28 @@ class VyOSDriver(NetworkDriver):
return uptime return uptime
def get_lldp_neighbors(self): def get_lldp_neighbors(self):
# Multiple neighbors per port are not implemented ret = []
# The show lldp neighbors commands lists port descriptions, not IDs
output = self.device.send_command("show lldp neighbors detail") output = self.device.send_command("show lldp neighbors detail")
pattern = r'''(?s)Interface: +(?P<interface>\S+), [^\n]+ regex = '{},.+?{}.+?{}'.format(
.+? "Interface:\s+(\S+)",
+SysName: +(?P<hostname>\S+) "SysName:\s+(\S+)",
.+? "PortID:\s+ifname (\S+)"
+PortID: +ifname (?P<port>\S+)''' )
re_lldp = re.compile(
regex,
re.MULTILINE|re.DOTALL
)
match = re_lldp.findall(output)
if not match:
return []
def _get_interface(match): for ocurrence in match:
return [ ret.append({
{ 'hostname' : ocurrence[0],
'hostname': match.group('hostname'), 'port' : ocurrence[1],
'port': match.group('port'), 'interface' : ocurrence[2]
} })
] return ret
return {
match.group('interface'): _get_interface(match)
for match in re.finditer(pattern, output)
}
def get_interfaces_counters(self): def get_interfaces_counters(self):
# 'rx_unicast_packet', 'rx_broadcast_packets', 'tx_unicast_packets', # 'rx_unicast_packet', 'rx_broadcast_packets', 'tx_unicast_packets',
@@ -958,3 +972,17 @@ class VyOSDriver(NetworkDriver):
config = config[:config.rfind('\n')] config = config[:config.rfind('\n')]
self.device.exit_config_mode() self.device.exit_config_mode()
return config return config
def cli(self, commands):
cli_output = {}
if not isinstance(commands, list):
raise TypeError("Please enter a valid list of commands!")
for command in commands:
try:
cli_output[command] = self.device.send_command(command)
except Exception:
cli_output[command] = 'error running command'
return cli_output