From 315e1d74de794badfd906bbf3a7a666e5d14dd93 Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" Date: Wed, 17 Jun 2020 09:54:58 -0400 Subject: [PATCH 1/7] Update netmiko device profile to dellos6 --- napalm_dellos6/dellos6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/napalm_dellos6/dellos6.py b/napalm_dellos6/dellos6.py index b3be272..2d3bbdc 100644 --- a/napalm_dellos6/dellos6.py +++ b/napalm_dellos6/dellos6.py @@ -95,7 +95,7 @@ def __init__(self, hostname, username, password, timeout=60, optional_args=None) self.device = None self.config_replace = False - self.profile = ["dellos10"] + self.profile = ["dellos6"] def open(self): """Open a connection to the device.""" From 10181dedb4c73703237025465dff78782a4ed9e0 Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" Date: Wed, 17 Jun 2020 14:35:24 -0400 Subject: [PATCH 2/7] Implement ping() method --- napalm_dellos6/dellos6.py | 161 +++++++++++++++++- .../test_ping/normal/expected_result.json | 27 +++ ...ng_8_8_8_8_timeout_2_size_100_repeat_5.txt | 11 ++ 3 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 test/unit/mocked_data/test_ping/normal/expected_result.json create mode 100644 test/unit/mocked_data/test_ping/normal/ping_8_8_8_8_timeout_2_size_100_repeat_5.txt diff --git a/napalm_dellos6/dellos6.py b/napalm_dellos6/dellos6.py index 93fae14..149bec8 100644 --- a/napalm_dellos6/dellos6.py +++ b/napalm_dellos6/dellos6.py @@ -21,8 +21,9 @@ import re import socket from ipaddress import IPv4Interface, IPv6Interface +from statistics import stdev -import napalm_dellos6.dellos6_constants as D6C +import napalm.base.constants as C from napalm.base import NetworkDriver from napalm.base.exceptions import CommandErrorException, ConnectionClosedException from napalm.base.helpers import ( @@ -32,6 +33,7 @@ textfsm_extractor, ) +import napalm_dellos6.dellos6_constants as D6C from napalm_dellos6.dellos6_canonical_map import dellos6_interfaces from netmiko import ConnectHandler @@ -1454,6 +1456,163 @@ def get_snmp_information(self): return snmp_info + def ping( + self, + destination, + source=C.PING_SOURCE, + ttl=C.PING_TTL, + timeout=C.PING_TIMEOUT, + size=C.PING_SIZE, + count=C.PING_COUNT, + vrf=C.PING_VRF, + ): + """ + Executes ping on the device and returns a dictionary with the result + :param destination: Host or IP Address of the destination + :param source (optional): Source address of echo request + :param ttl (optional): Maximum number of hops + :param timeout (optional): Maximum seconds to wait after sending final packet + :param size (optional): Size of request (bytes) + :param count (optional): Number of ping request to send + Output dictionary has one of following keys: + * success + * error + In case of success, inner dictionary will have the followin keys: + * probes_sent (int) + * packet_loss (int) + * rtt_min (float) + * rtt_max (float) + * rtt_avg (float) + * rtt_stddev (float) + * results (list) + 'results' is a list of dictionaries with the following keys: + * ip_address (str) + * rtt (float) + Example:: + { + 'success': { + 'probes_sent': 5, + 'packet_loss': 0, + 'rtt_min': 72.158, + 'rtt_max': 72.433, + 'rtt_avg': 72.268, + 'rtt_stddev': 0.094, + 'results': [ + { + 'ip_address': u'1.1.1.1', + 'rtt': 72.248 + }, + { + 'ip_address': '2.2.2.2', + 'rtt': 72.299 + } + ] + } + } + OR + { + 'error': 'unknown host 8.8.8.8.8' + } + """ + + vrf_name = "" + if vrf: + vrf_name = " vrf " + str(vrf) + + params = "" + if source: + params = params + " source " + if timeout: + params = params + " timeout " + str(timeout) + if size: + params = params + " size " + str(size) + if count: + params = params + " repeat " + str(count) + + cmd = "ping{} {}{}".format(vrf_name, destination, params) + ping_dict = {} + + send_received_regexp = ( + r"(\d+)\s+packets transmitted\S+\s+(\d+)\s+" + r"packets received\S+\s+\S+\s+packet loss" + ) + icmp_result_regexp = ( + r"Reply From\s+(\S+)\:\s+icmp_seq\s+=\s+(\d+)\.\s+" + r"time=\s+(\d+)\s+usec\." + ) + min_avg_max_reg_exp = ( + r"round-trip \(msec\)\s+min\/avg\/max\s+=\s+(\S+)\/" r"(\S+)\/(\S+)" + ) + + output = self._send_command(cmd) + print(output) + + if "% Error" in output: + status = "error" + ping_dict = {"results": ("command :: " + cmd + " :: " + output)} + elif "packets transmitted" in output: + ping_dict = { + "probes_sent": 0, + "packet_loss": 0, + "rtt_min": 0.0, + "rtt_max": 0.0, + "rtt_avg": 0.0, + "rtt_stddev": 0.0, + "results": [], + } + + results_array = [] + std_dev_list = [] + for line in output.splitlines(): + status = "success" + if "packets transmitted" in line: + sent_and_received = re.search(send_received_regexp, line) + probes_sent = int(sent_and_received.groups()[0]) + probes_received = int(sent_and_received.groups()[1]) + if probes_received == 0: + status = "error" + ping_dict["probes_sent"] = probes_sent + ping_dict["packet_loss"] = probes_sent - probes_received + elif "icmp_seq" in line: + print(line) + icmp_result = re.search(icmp_result_regexp, line) + results_array.append( + { + "ip_address": icmp_result.groups()[0], + "rtt": float(icmp_result.groups()[2]) / 1000, + } + ) + ping_dict.update({"results": results_array}) + std_dev_list.append(float(icmp_result.groups()[2]) / 1000) + elif "round-trip (msec)" in line: + min_avg = re.search(min_avg_max_reg_exp, line) + if std_dev_list: + rtt_stddev = stdev(std_dev_list) + else: + rtt_stddev = 0.0 + if min_avg.groups()[0] == "<10": + rtt_min = 0.0 + else: + rtt_min = float(min_avg.groups()[0]) + if min_avg.groups()[1] == "<10": + rtt_avg = 0.0 + else: + rtt_avg = float(min_avg.groups()[1]) + if min_avg.groups()[2] == "<10": + rtt_max = 0.0 + else: + rtt_max = float(min_avg.groups()[2]) + ping_dict.update( + { + "rtt_min": rtt_min, + "rtt_avg": rtt_avg, + "rtt_max": rtt_max, + "rtt_stddev": rtt_stddev, + } + ) + + return {status: ping_dict} + def get_users(self): """ Returns a dictionary with the configured users. diff --git a/test/unit/mocked_data/test_ping/normal/expected_result.json b/test/unit/mocked_data/test_ping/normal/expected_result.json new file mode 100644 index 0000000..1ac022b --- /dev/null +++ b/test/unit/mocked_data/test_ping/normal/expected_result.json @@ -0,0 +1,27 @@ +{ + "success": { + "packet_loss": 0, + "probes_sent": 5, + "results": [{ + "ip_address": "8.8.8.8", + "rtt": 53.458 + }, { + "ip_address": "8.8.8.8", + "rtt": 53.536 + }, { + "ip_address": "8.8.8.8", + "rtt": 53.547 + }, { + "ip_address": "8.8.8.8", + "rtt": 53.628 + }, { + "ip_address": "8.8.8.8", + "rtt": 53.438 + } + ], + "rtt_avg": 53.0, + "rtt_max": 53.0, + "rtt_min": 53.0, + "rtt_stddev": 0.07616954772085711 + } +} diff --git a/test/unit/mocked_data/test_ping/normal/ping_8_8_8_8_timeout_2_size_100_repeat_5.txt b/test/unit/mocked_data/test_ping/normal/ping_8_8_8_8_timeout_2_size_100_repeat_5.txt new file mode 100644 index 0000000..f2200be --- /dev/null +++ b/test/unit/mocked_data/test_ping/normal/ping_8_8_8_8_timeout_2_size_100_repeat_5.txt @@ -0,0 +1,11 @@ + Pinging 8.8.8.8 with 100 bytes of data: + +Reply From 8.8.8.8: icmp_seq = 0. time= 53458 usec. +Reply From 8.8.8.8: icmp_seq = 1. time= 53536 usec. +Reply From 8.8.8.8: icmp_seq = 2. time= 53547 usec. +Reply From 8.8.8.8: icmp_seq = 3. time= 53628 usec. +Reply From 8.8.8.8: icmp_seq = 4. time= 53438 usec. + +----8.8.8.8 PING statistics---- +5 packets transmitted, 5 packets received, 0% packet loss +round-trip (msec) min/avg/max = 53/53/53 From e8269dd08f055970101c56fdc1f525ab1a188dfc Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" Date: Wed, 17 Jun 2020 14:36:19 -0400 Subject: [PATCH 3/7] Update README.md with newly-implemented ping() method --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eeb10c1..641bc08 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ NAPALM driver for Dell EMC Networking OS6 Operating System. * get_interfaces_ip * get_mac_address_table * get_snmp_information +* ping * get_users * get_config * get_network_instances @@ -41,7 +42,6 @@ NAPALM driver for Dell EMC Networking OS6 Operating System. * get_route_to * get_probes_config * get_probes_results -* ping * traceroute * get_optics * get_firewall_policies From 908e8d1064c73e3f88f370af488371f2ad34b7a9 Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" Date: Wed, 17 Jun 2020 19:02:01 -0400 Subject: [PATCH 4/7] Implement get_optics() getter, remove debugging output for ping() --- napalm_dellos6/dellos6.py | 112 +++++++++++++++++- .../show_fiber-ports_optical-transceiver.tpl | 18 +++ .../normal/expected_result.json | 30 +++++ .../show_fiber_ports_optical_transceiver.txt | 5 + 4 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 napalm_dellos6/utils/textfsm_templates/show_fiber-ports_optical-transceiver.tpl create mode 100644 test/unit/mocked_data/test_get_optics/normal/expected_result.json create mode 100644 test/unit/mocked_data/test_get_optics/normal/show_fiber_ports_optical_transceiver.txt diff --git a/napalm_dellos6/dellos6.py b/napalm_dellos6/dellos6.py index 149bec8..0d60ec8 100644 --- a/napalm_dellos6/dellos6.py +++ b/napalm_dellos6/dellos6.py @@ -1545,7 +1545,6 @@ def ping( ) output = self._send_command(cmd) - print(output) if "% Error" in output: status = "error" @@ -1574,7 +1573,6 @@ def ping( ping_dict["probes_sent"] = probes_sent ping_dict["packet_loss"] = probes_sent - probes_received elif "icmp_seq" in line: - print(line) icmp_result = re.search(icmp_result_regexp, line) results_array.append( { @@ -1666,6 +1664,116 @@ def get_users(self): return users + def get_optics(self): + """Fetches the power usage on the various transceivers installed + on the switch (in dbm), and returns a view that conforms with the + openconfig model openconfig-platform-transceiver.yang + Returns a dictionary where the keys are as listed below: + * intf_name (unicode) + * physical_channels + * channels (list of dicts) + * index (int) + * state + * input_power + * instant (float) + * avg (float) + * min (float) + * max (float) + * output_power + * instant (float) + * avg (float) + * min (float) + * max (float) + * laser_bias_current + * instant (float) + * avg (float) + * min (float) + * max (float) + Example:: + { + 'et1': { + 'physical_channels': { + 'channel': [ + { + 'index': 0, + 'state': { + 'input_power': { + 'instant': 0.0, + 'avg': 0.0, + 'min': 0.0, + 'max': 0.0, + }, + 'output_power': { + 'instant': 0.0, + 'avg': 0.0, + 'min': 0.0, + 'max': 0.0, + }, + 'laser_bias_current': { + 'instant': 0.0, + 'avg': 0.0, + 'min': 0.0, + 'max': 0.0, + }, + } + } + ] + } + } + } + """ + + raw_show_fiber_ports_optical_transceiver = self._send_command( + "show fiber-ports optical transceiver" + ) + show_fiber_ports_optical_transceiver = textfsm_extractor( + self, + "show_fiber-ports_optical-transceiver", + raw_show_fiber_ports_optical_transceiver, + ) + + optics = {} + for interface in show_fiber_ports_optical_transceiver: + interface_name = canonical_interface_name( + interface["int_name"], addl_name_map=dellos6_interfaces + ) + pwr_rx = float(interface["pwr_rx"]) + pwr_tx = float(interface["pwr_tx"]) + current = float(interface["current"]) + + optics[interface_name] = { + "physical_channels": { + "channel": [ + { + # We do not yet support multiple channels + "index": 0, + "state": { + "input_power": { + "instant": pwr_rx, + "avg": -0.0, + "min": -0.0, + "max": -0.0, + }, + "output_power": { + "instant": pwr_tx, + "avg": -0.0, + "min": -0.0, + "max": -0.0, + }, + "laser_bias_current": { + "instant": current, + "avg": -0.0, + "min": -0.0, + "max": -0.0, + }, + }, + } + ] + } + } + + return optics + def get_config(self, retrieve="all", full=False, sanitized=False): """ Return the configuration of a device. diff --git a/napalm_dellos6/utils/textfsm_templates/show_fiber-ports_optical-transceiver.tpl b/napalm_dellos6/utils/textfsm_templates/show_fiber-ports_optical-transceiver.tpl new file mode 100644 index 0000000..8235d67 --- /dev/null +++ b/napalm_dellos6/utils/textfsm_templates/show_fiber-ports_optical-transceiver.tpl @@ -0,0 +1,18 @@ +Value Required INT_NAME (\S+) +Value TEMP (\S+) +Value VOLTAGE (\S+) +Value CURRENT (\S+) +Value PWR_TX (\S+) +Value PWR_RX (\S+) +Value FAULT_TX (\S+) +Value LOS (\S+) + +Start + ^\s+Output\s+Input + ^Port\s+Temp\s+Voltage\s+Current\s+Power\s+Power\s+TX\s+LOS + ^\s+\[C\]\s+\[Volt\]\s+\[mA\]\s+\[dBm\]\s+\[dBm\]\s+Fault + ^---------\s+----\s+-------\s+-------\s+-------\s+-------\s+-----\s+--- + ^${INT_NAME}\s+${TEMP}\s+${VOLTAGE}\s+${CURRENT}\s+${PWR_TX}\s+${PWR_RX}\s+${FAULT_TX}\s+${LOS} -> Record + ^. -> Error + +EOF \ No newline at end of file diff --git a/test/unit/mocked_data/test_get_optics/normal/expected_result.json b/test/unit/mocked_data/test_get_optics/normal/expected_result.json new file mode 100644 index 0000000..00e50db --- /dev/null +++ b/test/unit/mocked_data/test_get_optics/normal/expected_result.json @@ -0,0 +1,30 @@ +{ + "Tengigabitethernet2/0/23": { + "physical_channels": { + "channel": [{ + "index": 0, + "state": { + "input_power": { + "instant": -36.990, + "avg": -0.0, + "min": -0.0, + "max": -0.0 + }, + "output_power": { + "instant": -2.184, + "avg": -0.0, + "min": -0.0, + "max": -0.0 + }, + "laser_bias_current": { + "instant": 7.5, + "avg": -0.0, + "min": -0.0, + "max": -0.0 + } + } + } + ] + } + } +} \ No newline at end of file diff --git a/test/unit/mocked_data/test_get_optics/normal/show_fiber_ports_optical_transceiver.txt b/test/unit/mocked_data/test_get_optics/normal/show_fiber_ports_optical_transceiver.txt new file mode 100644 index 0000000..f7ebe51 --- /dev/null +++ b/test/unit/mocked_data/test_get_optics/normal/show_fiber_ports_optical_transceiver.txt @@ -0,0 +1,5 @@ + Output Input +Port Temp Voltage Current Power Power TX LOS + [C] [Volt] [mA] [dBm] [dBm] Fault +--------- ---- ------- ------- ------- ------- ----- --- +Te2/0/23 22.5 3.296 7.5 -2.184 -36.990 No Yes From dc47e07e172c1e7ca46cfb188a2a395ae323ed2f Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" Date: Wed, 17 Jun 2020 19:03:18 -0400 Subject: [PATCH 5/7] Updated README.md with support for get_optics() --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 641bc08..48d8ab1 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ NAPALM driver for Dell EMC Networking OS6 Operating System. * get_snmp_information * ping * get_users +* get_optics * get_config * get_network_instances * get_vlans @@ -43,7 +44,6 @@ NAPALM driver for Dell EMC Networking OS6 Operating System. * get_probes_config * get_probes_results * traceroute -* get_optics * get_firewall_policies * get_ipv6_neighbors_table * compliance_report From 945e59bcd029748931fc22464f165be74d3eb0c6 Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" Date: Wed, 17 Jun 2020 19:54:56 -0400 Subject: [PATCH 6/7] Implement get_ipv6_neighbors_table() getter --- README.md | 2 +- napalm_dellos6/dellos6.py | 55 +++++++++++++++++++ .../textfsm_templates/show_ipv6_neighbors.tpl | 15 +++++ .../normal/expected_result.json | 14 +++++ .../normal/show_ipv6_neighbors.txt | 6 ++ 5 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 napalm_dellos6/utils/textfsm_templates/show_ipv6_neighbors.tpl create mode 100644 test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json create mode 100644 test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt diff --git a/README.md b/README.md index 48d8ab1..836235d 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ NAPALM driver for Dell EMC Networking OS6 Operating System. * get_optics * get_config * get_network_instances +* get_ipv6_neighbors_table * get_vlans ### Missing APIs @@ -45,7 +46,6 @@ NAPALM driver for Dell EMC Networking OS6 Operating System. * get_probes_results * traceroute * get_firewall_policies -* get_ipv6_neighbors_table * compliance_report This driver is in the early stages, and is a work in progress. Feel free to submit a PR to add additional getters or better implementations of existing getters. diff --git a/napalm_dellos6/dellos6.py b/napalm_dellos6/dellos6.py index 0d60ec8..e898a36 100644 --- a/napalm_dellos6/dellos6.py +++ b/napalm_dellos6/dellos6.py @@ -1259,6 +1259,61 @@ def get_interfaces_ip(self): return interfaces_ip + def get_ipv6_neighbors_table(self): + """ + Get IPv6 neighbors table information. + Return a list of dictionaries having the following set of keys: + * interface (string) + * mac (string) + * ip (string) + * age (float) in seconds + * state (string) + For example:: + [ + { + 'interface' : 'MgmtEth0/RSP0/CPU0/0', + 'mac' : '5c:5e:ab:da:3c:f0', + 'ip' : '2001:db8:1:1::1', + 'age' : 1454496274.84, + 'state' : 'REACH' + }, + { + 'interface': 'MgmtEth0/RSP0/CPU0/0', + 'mac' : '66:0e:94:96:e0:ff', + 'ip' : '2001:db8:1:1::2', + 'age' : 1435641582.49, + 'state' : 'STALE' + } + ] + """ + + raw_show_ipv6_neighbors = self._send_command("show ipv6 neighbors") + show_ipv6_neighbors = textfsm_extractor( + self, "show_ipv6_neighbors", raw_show_ipv6_neighbors + ) + + ipv6_neighbors = [] + for neighbor in show_ipv6_neighbors: + interface_name = canonical_interface_name( + neighbor["int_name"], addl_name_map=dellos6_interfaces + ) + mac_addr = mac(neighbor["mac_addr"]) + ipv6_addr = neighbor["ipv6_addr"] + # Dell OS6 doesn't support age + age = -0.0 + state = neighbor["state"].upper() + ipv6_neighbors.append( + { + "interface": interface_name, + "mac": mac_addr, + "ip": ipv6_addr, + "age": age, + "state": state, + } + ) + + return ipv6_neighbors + def _expand_ranges(self, iflist): """ In: ["Gi1/0/42-43"] diff --git a/napalm_dellos6/utils/textfsm_templates/show_ipv6_neighbors.tpl b/napalm_dellos6/utils/textfsm_templates/show_ipv6_neighbors.tpl new file mode 100644 index 0000000..b0e6c5f --- /dev/null +++ b/napalm_dellos6/utils/textfsm_templates/show_ipv6_neighbors.tpl @@ -0,0 +1,15 @@ +Value Required IPV6_ADDR (\S+) +Value Required MAC_ADDR (\S+) +Value Required IS_RTR (\S+) +Value Required STATE (\S+) +Value Required INT_NAME (\S+) + +Start + ^Neighbor Last + ^IPv6 Address\s+MAC Address\s+isRtr\s+State\s+Updated + ^\s+Interface + ^----------------------\s+-----------------\s+-----\s+-------\s+--------- + ^${IPV6_ADDR}\s+${MAC_ADDR}\s+${IS_RTR}\s+${STATE}\s+${INT_NAME} -> Record + ^. -> Error + +EOF \ No newline at end of file diff --git a/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json new file mode 100644 index 0000000..dcf9bd9 --- /dev/null +++ b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json @@ -0,0 +1,14 @@ +[{ + "interface": "vlan 3840", + "mac": "02:01:D0:59:6F:CB", + "ip": "fe80::1:d0ff:fe59:6fcb", + "age": -0.0, + "state": "REACH" +}, { + "interface": "vlan 3840", + "mac": "02:01:D0:61:6F:97", + "ip": "fe80::7:d0ff:fed7:6f1b", + "age": -0.0, + "state": "STALE" +} +] diff --git a/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt new file mode 100644 index 0000000..11e04d6 --- /dev/null +++ b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt @@ -0,0 +1,6 @@ +Neighbor Last +IPv6 Address MAC Address isRtr State Updated + Interface +---------------------- ----------------- ----- ------- --------- +fe80::1:d0ff:fe59:6fcb 0201.D059.6FCB No Reach Vl3840 +fe80::7:d0ff:fed7:6f1b 0201.D061.6F97 No Stale Vl3840 From 92bb7150cf453288fe99c5eb5e698e240e3dc628 Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" Date: Wed, 24 Jun 2020 14:30:23 -0400 Subject: [PATCH 7/7] Implement get_bgp_neighbors() --- README.md | 6 +- napalm_dellos6/dellos6.py | 128 +++++++++++++++++ .../show_bgp_ipv6_neighbors.tpl | 130 +++++++++++++++++ .../show_ip_bgp_neighbors.tpl | 134 ++++++++++++++++++ .../textfsm_templates/show_ip_bgp_summary.tpl | 34 +++++ .../normal/expected_result.json | 81 +++++++++++ .../normal/show_bgp_ipv6_neighbors.txt | 108 ++++++++++++++ .../normal/show_ip_bgp_neighbors.txt | 107 ++++++++++++++ .../normal/show_ip_bgp_summary.txt | 28 ++++ 9 files changed, 753 insertions(+), 3 deletions(-) create mode 100644 napalm_dellos6/utils/textfsm_templates/show_bgp_ipv6_neighbors.tpl create mode 100644 napalm_dellos6/utils/textfsm_templates/show_ip_bgp_neighbors.tpl create mode 100644 napalm_dellos6/utils/textfsm_templates/show_ip_bgp_summary.tpl create mode 100644 test/unit/mocked_data/test_get_bgp_neighbors/normal/expected_result.json create mode 100644 test/unit/mocked_data/test_get_bgp_neighbors/normal/show_bgp_ipv6_neighbors.txt create mode 100644 test/unit/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors.txt create mode 100644 test/unit/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_summary.txt diff --git a/README.md b/README.md index 836235d..2ea2b13 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ NAPALM driver for Dell EMC Networking OS6 Operating System. * get_facts * get_interfaces * get_lldp_neighbors +* get_bgp_neighbors \*needs additional testing, built based on descriptions in manual * get_environment * get_interfaces_counters * get_lldp_neighbors_detail @@ -26,7 +27,7 @@ NAPALM driver for Dell EMC Networking OS6 Operating System. * get_optics * get_config * get_network_instances -* get_ipv6_neighbors_table +* get_ipv6_neighbors_table \*needs additional testing, built based on descriptions in manual * get_vlans ### Missing APIs @@ -38,7 +39,6 @@ NAPALM driver for Dell EMC Networking OS6 Operating System. * commit_config * discard_config * rollback -* get_bgp_neighbors * get_bgp_config * get_bgp_neighbors_detail * get_route_to @@ -48,5 +48,5 @@ NAPALM driver for Dell EMC Networking OS6 Operating System. * get_firewall_policies * compliance_report -This driver is in the early stages, and is a work in progress. Feel free to submit a PR to add additional getters or better implementations of existing getters. +This driver is in the early stages, and is a work in progress. Feel free to submit a PR to add additional getters or better implementations of existing getters. Please create an issue (or comment on an existing issue) if you have problems with any of the implemented getters. diff --git a/napalm_dellos6/dellos6.py b/napalm_dellos6/dellos6.py index e898a36..3061ba2 100644 --- a/napalm_dellos6/dellos6.py +++ b/napalm_dellos6/dellos6.py @@ -531,6 +531,134 @@ def get_lldp_neighbors(self): return lldp + def get_bgp_neighbors(self): + """ + Returns a dictionary of dictionaries. The keys for the first dictionary will be the vrf + (global if no vrf). The inner dictionary will contain the following data for each vrf: + * router_id + * peers - another dictionary of dictionaries. Outer keys are the IPs of the neighbors. \ + The inner keys are: + * local_as (int) + * remote_as (int) + * remote_id - peer router id + * is_up (True/False) + * is_enabled (True/False) + * description (string) + * uptime (int in seconds) + * address_family (dictionary) - A dictionary of address families available for the \ + neighbor. So far it can be 'ipv4' or 'ipv6' + * received_prefixes (int) + * accepted_prefixes (int) + * sent_prefixes (int) + Note, if is_up is False and uptime has a positive value then this indicates the + uptime of the last active BGP session. + Example:: + { + "global": { + "router_id": "10.0.1.1", + "peers": { + "10.0.0.2": { + "local_as": 65000, + "remote_as": 65000, + "remote_id": "10.0.1.2", + "is_up": True, + "is_enabled": True, + "description": "internal-2", + "uptime": 4838400, + "address_family": { + "ipv4": { + "sent_prefixes": 637213, + "accepted_prefixes": 3142, + "received_prefixes": 3142 + }, + "ipv6": { + "sent_prefixes": 36714, + "accepted_prefixes": 148, + "received_prefixes": 148 + } + } + } + } + } + } + """ + + raw_show_ip_bgp_summary = self._send_command("show ip bgp summary") + raw_show_ip_bgp_neighbors = self._send_command("show ip bgp neighbors") + raw_show_bgp_ipv6_neighbors = self._send_command("show bgp ipv6 neighbors") + + show_ip_bgp_summary = textfsm_extractor( + self, "show_ip_bgp_summary", raw_show_ip_bgp_summary + ) + show_ip_bgp_neighbors = textfsm_extractor( + self, "show_ip_bgp_neighbors", raw_show_ip_bgp_neighbors + ) + show_bgp_ipv6_neighbors = textfsm_extractor( + self, "show_bgp_ipv6_neighbors", raw_show_bgp_ipv6_neighbors + ) + + router_id = show_ip_bgp_summary[0]["bgp_router_id"] + local_as = int(show_ip_bgp_summary[0]["local_as"]) + bgp_neighbors = {"global": {"router_id": router_id, "peers": {}}} + for neighbor in show_ip_bgp_neighbors: + peer_addr = neighbor["peer_addr"] + bgp_neighbors["global"]["peers"][peer_addr] = { + "local_as": local_as, + "remote_as": int(neighbor["peer_as"]), + "remote_id": neighbor["peer_id"], + "is_up": (neighbor["peer_state"] == "ESTABLISHED"), + "is_enabled": (neighbor["peer_status_admin"] == "START"), + "description": "", + "uptime": -1, + "address_family": {}, + } + if neighbor["ipv4_ucast"] != "None": + bgp_neighbors["global"]["peers"][peer_addr]["address_family"][ + "ipv4" + ] = { + "sent_prefixes": int(neighbor["ipv4_pfx_adv_tx"]), + "accepted_prefixes": int(neighbor["ipv4_pfx_current_rx"]), + "received_prefixes": int(neighbor["ipv4_pfx_adv_rx"]), + } + if neighbor["ipv6_ucast"] != "None": + bgp_neighbors["global"]["peers"][peer_addr]["address_family"][ + "ipv6" + ] = { + "sent_prefixes": int(neighbor["ipv6_pfx_adv_tx"]), + "accepted_prefixes": int(neighbor["ipv6_pfx_current_rx"]), + "received_prefixes": int(neighbor["ipv6_pfx_adv_rx"]), + } + for neighbor in show_bgp_ipv6_neighbors: + peer_addr = neighbor["peer_addr"] + bgp_neighbors["global"]["peers"][peer_addr] = { + "local_as": local_as, + "remote_as": int(neighbor["peer_as"]), + "remote_id": neighbor["peer_id"], + "is_up": (neighbor["peer_state"] == "ESTABLISHED"), + "is_enabled": (neighbor["peer_status_admin"] == "START"), + "description": neighbor["desc"], + "uptime": -1, + "address_family": {}, + } + if neighbor["ipv4_ucast"] != "None": + bgp_neighbors["global"]["peers"][peer_addr]["address_family"][ + "ipv4" + ] = { + "sent_prefixes": int(neighbor["ipv4_pfx_adv_tx"]), + "accepted_prefixes": int(neighbor["ipv4_pfx_current_rx"]), + "received_prefixes": int(neighbor["ipv4_pfx_adv_rx"]), + } + if neighbor["ipv6_ucast"] != "None": + bgp_neighbors["global"]["peers"][peer_addr]["address_family"][ + "ipv6" + ] = { + "sent_prefixes": int(neighbor["ipv6_pfx_adv_tx"]), + "accepted_prefixes": int(neighbor["ipv6_pfx_current_rx"]), + "received_prefixes": int(neighbor["ipv6_pfx_adv_rx"]), + } + + return bgp_neighbors + def get_environment(self): """ Returns a dictionary where: diff --git a/napalm_dellos6/utils/textfsm_templates/show_bgp_ipv6_neighbors.tpl b/napalm_dellos6/utils/textfsm_templates/show_bgp_ipv6_neighbors.tpl new file mode 100644 index 0000000..b1ce389 --- /dev/null +++ b/napalm_dellos6/utils/textfsm_templates/show_bgp_ipv6_neighbors.tpl @@ -0,0 +1,130 @@ +Value DESC (\S+.*\S+) +Value Required PEER_ADDR (\S+) +Value Required INTERFACE (\S+) +Value Required PEER_AS (\d+) +Value Required PEER_ID (\S+) +Value Required PEER_STATUS_ADMIN (\S+) +Value Required PEER_STATE (\S+) +Value Required PEER_TYPE (\S+) +Value Required LOCAL_PORT (\d+) +Value Required PEER_PORT (\d+) +Value Required RETRY_INT (\d+) +Value Required PEER_CAPAB (\S+.*\S+) +Value Required IPV4_UCAST (\S+.*\S+) +Value Required IPV6_UCAST (\S+.*\S+) +Value Required RFC5549 (\S+) +Value UPD_SRC (\S+) +Value Required LOCAL_ADDR (\S+) +Value Required HOLD_TIME_ADMIN (\S+) +Value Required KEEPALIVE_ADMIN (\S+) +Value HOLD_TIME_OPER (\S+) +Value KEEPALIVE_OPER (\S+) +Value Required MD5 (\S+) +Value Required ERROR_LAST (\S+) +Value Required SUBERROR_LAST (\S+) +Value Required TIME_SINCE_ERROR (\S+) +Value Required ESTAB_TRANS (\d+) +Value Required ESTAB_TIME (\S+) +Value Required UPD_TIME (\S+) +Value Required UPD_GROUP (None|\d+) +Value Required MSG_TX_OPEN (\d+) +Value Required MSG_TX_UPD (\d+) +Value Required MSG_TX_KEEPALIVE (\d+) +Value Required MSG_TX_NOTIF (\d+) +Value Required MSG_TX_REFRESH (\d+) +Value Required MSG_TX_TOTAL (\d+) +Value Required MSG_RX_OPEN (\d+) +Value Required MSG_RX_UPD (\d+) +Value Required MSG_RX_KEEPALIVE (\d+) +Value Required MSG_RX_NOTIF (\d+) +Value Required MSG_RX_REFRESH (\d+) +Value Required MSG_RX_TOTAL (\d+) +Value Required QUEUE_SIZE (\d+) +Value Required QUEUE_MAX (\d+) +Value Required QUEUE_LIMIT (\d+) +Value Required QUEUE_DROPS (\d+) +Value IPV4_PFX_ADV_RX (\d+) +Value IPV4_PFX_ADV_TX (\d+) +Value IPV4_PFX_WITHDRAWN_RX (\d+) +Value IPV4_PFX_WITHDRAWN_TX (\d+) +Value IPV4_PFX_CURRENT_RX (\d+) +Value IPV4_PFX_CURRENT_TX (\d+) +Value IPV4_PFX_ACCEPT_RX (\d+) +Value IPV4_PFX_REJECT_RX (\d+) +Value IPV4_NLRI_MAX_RX (\d+) +Value IPV4_NLRI_MAX_TX (\d+) +Value IPV4_NLRI_MIN_RX (\d+) +Value IPV4_NLRI_MIN_TX (\d+) +Value IPV6_PFX_ADV_RX (\d+) +Value IPV6_PFX_ADV_TX (\d+) +Value IPV6_PFX_WITHDRAWN_RX (\d+) +Value IPV6_PFX_WITHDRAWN_TX (\d+) +Value IPV6_PFX_CURRENT_RX (\d+) +Value IPV6_PFX_CURRENT_TX (\d+) +Value IPV6_PFX_ACCEPT_RX (\d+) +Value IPV6_PFX_REJECT_RX (\d+) +Value IPV6_NLRI_MAX_RX (\d+) +Value IPV6_NLRI_MAX_TX (\d+) +Value IPV6_NLRI_MIN_RX (\d+) +Value IPV6_NLRI_MIN_TX (\d+) + +Start + ^Description\:\s* -> Continue.Record + ^Description\:\s*${DESC} + ^Remote Address\s*\.+\s*${PEER_ADDR} + ^Interface\s*\.+\s*${INTERFACE} + ^Remote AS\s*\.+\s*${PEER_AS} + ^Peer ID\s*\.+\s*${PEER_ID} + ^Peer Admin Status\s*\.+\s*${PEER_STATUS_ADMIN} + ^Peer State\s*\.+\s*${PEER_STATE} + ^Peer Type\s*\.+\s*${PEER_TYPE} + ^Local Port\s*\.+\s*${LOCAL_PORT} + ^Remote Port\s*\.+\s*${PEER_PORT} + ^Connection Retry Interval\s*\.+\s*${RETRY_INT}\s+sec + ^Neighbor Capabilities\s*\.+\s*${PEER_CAPAB} + ^IPv4 Unicast Support\s*\.+\s*${IPV4_UCAST} + ^IPv6 Unicast Support\s*\.+\s*${IPV6_UCAST} + ^RFC 5549 Support\s*\.+\s*${RFC5549} + ^Update Source\s*\.+\s*${UPD_SRC} + ^Local Interface Address\s*\.+\s*${LOCAL_ADDR} + ^Configured Hold Time\s*\.+\s*${HOLD_TIME_ADMIN} + ^Configured Keep Alive Time\s*\.+\s*${KEEPALIVE_ADMIN} + ^Negotiated Hold Time\s*\.+\s*${HOLD_TIME_OPER} + ^Keep Alive Time\s*\.+\s*${KEEPALIVE_OPER} + ^MD5 Password\s*\.+\s*${MD5} + ^Last Error \(Sent\)\s*\.+\s*${ERROR_LAST} + ^Last SubError\s*\.+\s*${SUBERROR_LAST} + ^Time Since Last Error\s*\.+\s*${TIME_SINCE_ERROR} + ^Established Transitions\s*\.+\s*${ESTAB_TRANS} + ^Established Time\s*\.+\s*${ESTAB_TIME} + ^Time Since Last Update\s*\.+\s*${UPD_TIME} + ^IPv6 Outbound Update Group\s*\.+\s*${UPD_GROUP} + ^\s+Open\s+Update\s+Keepalive\s+Notification\s+Refresh\s+Total + ^Msgs Sent\s+${MSG_TX_OPEN}\s+${MSG_TX_UPD}\s+${MSG_TX_KEEPALIVE}\s+${MSG_TX_NOTIF}\s+${MSG_TX_REFRESH}\s+${MSG_TX_TOTAL} + ^Msgs Rcvd\s+${MSG_RX_OPEN}\s+${MSG_RX_UPD}\s+${MSG_RX_KEEPALIVE}\s+${MSG_RX_NOTIF}\s+${MSG_RX_REFRESH}\s+${MSG_RX_TOTAL} + ^Received UPDATE Queue Size\:\s+${QUEUE_SIZE}\s+bytes\.\s+High\:\s+${QUEUE_MAX}\.\s+Limit\s+${QUEUE_LIMIT}\.\s+Drops\s+${QUEUE_DROPS}\. + ^IPv4 Prefix Statistics\: -> IPV4Prefixes + ^IPv6 Prefix Statistics\: -> IPV6Prefixes + ^. -> Error + +IPV4Prefixes + ^\s+Inbound\s+Outbound + ^Prefixes Advertised\s+${IPV4_PFX_ADV_RX}\s+${IPV4_PFX_ADV_TX} + ^Prefixes Withdrawn\s+${IPV4_PFX_WITHDRAWN_RX}\s+${IPV4_PFX_WITHDRAWN_TX} + ^Prefixes Current\s+${IPV4_PFX_CURRENT_RX}\s+${IPV4_PFX_CURRENT_TX} + ^Prefixes Accepted\s+${IPV4_PFX_ACCEPT_RX}\s+N\/A + ^Prefixes Rejected\s+${IPV4_PFX_REJECT_RX}\s+N\/A + ^Max NLRI per Update\s+${IPV4_NLRI_MAX_RX}\s+${IPV4_NLRI_MAX_TX} + ^Min NLRI per Update\s+${IPV4_NLRI_MIN_RX}\s+${IPV4_NLRI_MIN_TX} -> Start + ^. -> Error + +IPV6Prefixes + ^\s+Inbound\s+Outbound + ^Prefixes Advertised\s+${IPV6_PFX_ADV_RX}\s+${IPV6_PFX_ADV_TX} + ^Prefixes Withdrawn\s+${IPV6_PFX_WITHDRAWN_RX}\s+${IPV6_PFX_WITHDRAWN_TX} + ^Prefixes Current\s+${IPV6_PFX_CURRENT_RX}\s+${IPV6_PFX_CURRENT_TX} + ^Prefixes Accepted\s+${IPV6_PFX_ACCEPT_RX}\s+N\/A + ^Prefixes Rejected\s+${IPV6_PFX_REJECT_RX}\s+N\/A + ^Max NLRI per Update\s+${IPV6_NLRI_MAX_RX}\s+${IPV6_NLRI_MAX_TX} + ^Min NLRI per Update\s+${IPV6_NLRI_MIN_RX}\s+${IPV6_NLRI_MIN_TX} -> Start + ^. -> Error diff --git a/napalm_dellos6/utils/textfsm_templates/show_ip_bgp_neighbors.tpl b/napalm_dellos6/utils/textfsm_templates/show_ip_bgp_neighbors.tpl new file mode 100644 index 0000000..37000ff --- /dev/null +++ b/napalm_dellos6/utils/textfsm_templates/show_ip_bgp_neighbors.tpl @@ -0,0 +1,134 @@ +Value Required PEER_ADDR (\S+) +Value Required PEER_AS (\d+) +Value Required PEER_ID (\S+) +Value Required PEER_STATUS_ADMIN (\S+) +Value Required PEER_STATE (\S+) +Value Required LOCAL_ADDR (\S+) +Value Required LOCAL_PORT (\d+) +Value Required PEER_PORT (\d+) +Value Required RETRY_INT (\d+) +Value Required PEER_CAPAB (\S+.*\S+) +Value Required NHS (\S+) +Value Required IPV4_UCAST (\S+.*\S+) +Value Required IPV6_UCAST (\S+.*\S+) +Value Required TEMPLATE (\S+) +Value UPD_SRC (\S+) +Value Required HOLD_TIME_ADMIN (\S+) +Value Required KEEPALIVE_ADMIN (\S+) +Value HOLD_TIME_OPER (\S+) +Value KEEPALIVE_OPER (\S+) +Value Required PFX_LIMIT (None|\d+) +Value Required PFX_WARNING (\d+) +Value Required PFX_WARN_ONLY (\S+) +Value Required MD5 (\S+) +Value Required ORIG_DEFAULT (\S+) +Value Required ERROR_LAST (\S+) +Value Required SUBERROR_LAST (\S+) +Value Required TIME_SINCE_ERROR (\S+) +Value Required ESTAB_TRANS (\d+) +Value Required ESTAB_TIME (\S+) +Value Required UPD_TIME (\S+) +Value Required UPD_GROUP (None|\d+) +Value Required MSG_TX_OPEN (\d+) +Value Required MSG_TX_UPD (\d+) +Value Required MSG_TX_KEEPALIVE (\d+) +Value Required MSG_TX_NOTIF (\d+) +Value Required MSG_TX_REFRESH (\d+) +Value Required MSG_TX_TOTAL (\d+) +Value Required MSG_RX_OPEN (\d+) +Value Required MSG_RX_UPD (\d+) +Value Required MSG_RX_KEEPALIVE (\d+) +Value Required MSG_RX_NOTIF (\d+) +Value Required MSG_RX_REFRESH (\d+) +Value Required MSG_RX_TOTAL (\d+) +Value Required QUEUE_SIZE (\d+) +Value Required QUEUE_MAX (\d+) +Value Required QUEUE_LIMIT (\d+) +Value Required QUEUE_DROPS (\d+) +Value IPV4_PFX_ADV_RX (\d+) +Value IPV4_PFX_ADV_TX (\d+) +Value IPV4_PFX_WITHDRAWN_RX (\d+) +Value IPV4_PFX_WITHDRAWN_TX (\d+) +Value IPV4_PFX_CURRENT_RX (\d+) +Value IPV4_PFX_CURRENT_TX (\d+) +Value IPV4_PFX_ACCEPT_RX (\d+) +Value IPV4_PFX_REJECT_RX (\d+) +Value IPV4_NLRI_MAX_RX (\d+) +Value IPV4_NLRI_MAX_TX (\d+) +Value IPV4_NLRI_MIN_RX (\d+) +Value IPV4_NLRI_MIN_TX (\d+) +Value IPV6_PFX_ADV_RX (\d+) +Value IPV6_PFX_ADV_TX (\d+) +Value IPV6_PFX_WITHDRAWN_RX (\d+) +Value IPV6_PFX_WITHDRAWN_TX (\d+) +Value IPV6_PFX_CURRENT_RX (\d+) +Value IPV6_PFX_CURRENT_TX (\d+) +Value IPV6_PFX_ACCEPT_RX (\d+) +Value IPV6_PFX_REJECT_RX (\d+) +Value IPV6_NLRI_MAX_RX (\d+) +Value IPV6_NLRI_MAX_TX (\d+) +Value IPV6_NLRI_MIN_RX (\d+) +Value IPV6_NLRI_MIN_TX (\d+) + +Start + ^Remote Address\s*\.+\s -> Continue.Record + ^Remote Address\s*\.+\s*${PEER_ADDR} + ^Remote AS\s*\.+\s*${PEER_AS} + ^Peer ID\s*\.+\s*${PEER_ID} + ^Peer Admin Status\s*\.+\s*${PEER_STATUS_ADMIN} + ^Peer State\s*\.+\s*${PEER_STATE} + ^Local Interface Address\s*\.+\s*${LOCAL_ADDR} + ^Local Port\s*\.+\s*${LOCAL_PORT} + ^Remote Port\s*\.+\s*${PEER_PORT} + ^Connection Retry Interval\s*\.+\s*${RETRY_INT}\s+sec + ^Neighbor Capabilities\s*\.+\s*${PEER_CAPAB} + ^Next Hop Self\s*\.+\s*${NHS} + ^IPv4 Unicast Support\s*\.+\s*${IPV4_UCAST} + ^IPv6 Unicast Support\s*\.+\s*${IPV6_UCAST} + ^Template Name\s*\.+\s*${TEMPLATE} + ^Update Source\s*\.+\s*${UPD_SRC} + ^Configured Hold Time\s*\.+\s*${HOLD_TIME_ADMIN} + ^Configured Keep Alive Time\s*\.+\s*${KEEPALIVE_ADMIN} + ^Negotiated Hold Time\s*\.+\s*${HOLD_TIME_OPER} + ^Keep Alive Time\s*\.+\s*${KEEPALIVE_OPER} + ^Prefix Limit\s*\.+\s*${PFX_LIMIT} + ^Prefix Warning Threshold\s*\.+\s*${PFX_WARNING} + ^Warning Only On Prefix Limit\s*\.+\s*${PFX_WARN_ONLY} + ^MD5 Password\s*\.+\s*${MD5} + ^Originate Default\s*\.+\s*${ORIG_DEFAULT} + ^Last Error \(Sent\)\s*\.+\s*${ERROR_LAST} + ^Last SubError\s*\.+\s*${SUBERROR_LAST} + ^Time Since Last Error\s*\.+\s*${TIME_SINCE_ERROR} + ^Established Transitions\s*\.+\s*${ESTAB_TRANS} + ^Established Time\s*\.+\s*${ESTAB_TIME} + ^Time Since Last Update\s*\.+\s*${UPD_TIME} + ^IPv4 Outbound Update Group\s*\.+\s*${UPD_GROUP} + ^\s+Open\s+Update\s+Keepalive\s+Notification\s+Refresh\s+Total + ^Msgs Sent\s+${MSG_TX_OPEN}\s+${MSG_TX_UPD}\s+${MSG_TX_KEEPALIVE}\s+${MSG_TX_NOTIF}\s+${MSG_TX_REFRESH}\s+${MSG_TX_TOTAL} + ^Msgs Rcvd\s+${MSG_RX_OPEN}\s+${MSG_RX_UPD}\s+${MSG_RX_KEEPALIVE}\s+${MSG_RX_NOTIF}\s+${MSG_RX_REFRESH}\s+${MSG_RX_TOTAL} + ^Received UPDATE Queue Size\:\s+${QUEUE_SIZE}\s+bytes\.\s+High\:\s+${QUEUE_MAX}\s+Limit\:\s+${QUEUE_LIMIT}\s+Drops\:\s+${QUEUE_DROPS} + ^IPv4 Prefix Statistics\: -> IPV4Prefixes + ^IPv6 Prefix Statistics\: -> IPV6Prefixes + ^. -> Error + +IPV4Prefixes + ^\s+Inbound\s+Outbound + ^Prefixes Advertised\s+${IPV4_PFX_ADV_RX}\s+${IPV4_PFX_ADV_TX} + ^Prefixes Withdrawn\s+${IPV4_PFX_WITHDRAWN_RX}\s+${IPV4_PFX_WITHDRAWN_TX} + ^Prefixes Current\s+${IPV4_PFX_CURRENT_RX}\s+${IPV4_PFX_CURRENT_TX} + ^Prefixes Accepted\s+${IPV4_PFX_ACCEPT_RX}\s+N\/A + ^Prefixes Rejected\s+${IPV4_PFX_REJECT_RX}\s+N\/A + ^Max NLRI per Update\s+${IPV4_NLRI_MAX_RX}\s+${IPV4_NLRI_MAX_TX} + ^Min NLRI per Update\s+${IPV4_NLRI_MIN_RX}\s+${IPV4_NLRI_MIN_TX} -> Start + ^. -> Error + +IPV6Prefixes + ^\s+Inbound\s+Outbound + ^Prefixes Advertised\s+${IPV6_PFX_ADV_RX}\s+${IPV6_PFX_ADV_TX} + ^Prefixes Withdrawn\s+${IPV6_PFX_WITHDRAWN_RX}\s+${IPV6_PFX_WITHDRAWN_TX} + ^Prefixes Current\s+${IPV6_PFX_CURRENT_RX}\s+${IPV6_PFX_CURRENT_TX} + ^Prefixes Accepted\s+${IPV6_PFX_ACCEPT_RX}\s+N\/A + ^Prefixes Rejected\s+${IPV6_PFX_REJECT_RX}\s+N\/A + ^Max NLRI per Update\s+${IPV6_NLRI_MAX_RX}\s+${IPV6_NLRI_MAX_TX} + ^Min NLRI per Update\s+${IPV6_NLRI_MIN_RX}\s+${IPV6_NLRI_MIN_TX} -> Start + ^. -> Error diff --git a/napalm_dellos6/utils/textfsm_templates/show_ip_bgp_summary.tpl b/napalm_dellos6/utils/textfsm_templates/show_ip_bgp_summary.tpl new file mode 100644 index 0000000..dac3861 --- /dev/null +++ b/napalm_dellos6/utils/textfsm_templates/show_ip_bgp_summary.tpl @@ -0,0 +1,34 @@ +Value Required IPV4_ROUTING (\S+) +Value Required BGP_STATE_OPER (\S+) +Value Required BGP_ROUTER_ID (\S+) +Value Required LOCAL_AS (\d+) +Value Required TRAPS (\S+) +Value Required PATHS_MAX (\d+) +Value Required PATHS_IBGP_MAX (\d+) +Value Required KEEPALIVE_ADMIN (\d+) +Value Required HOLD_TIME_ADMIN (\d+) +Value Required NETWORK_ENTRIES (\d+) +Value Required AS_PATHS (\d+) +Value Required DYN_NEIGH_CUR (\d+) +Value Required DYN_NEIGH_MAX (\d+) +Value Required DYN_NEIGH_LIMIT (\d+) +Value Required METRIC_DEFAULT (\S+) +Value Required ORIG_DEFAULT (\S+) + +Start + ^IPv4 Routing\s*\.+\s*${IPV4_ROUTING} + ^BGP Admin Mode\s*\.+\s*${BGP_STATE_OPER} + ^BGP Router ID\s*\.+\s*${BGP_ROUTER_ID} + ^Local AS Number\s*\.+\s*${LOCAL_AS} + ^Traps\s*\.+\s*${TRAPS} + ^Maximum Paths\s*\.+\s*${PATHS_MAX} + ^Maximum Paths iBGP\s*\.+\s*${PATHS_IBGP_MAX} + ^Default Keep Alive Time\s*\.+\s*${KEEPALIVE_ADMIN} + ^Default Hold Time\s*\.+\s*${HOLD_TIME_ADMIN} + ^Number of Network Entries\s*\.+\s*${NETWORK_ENTRIES} + ^Number of AS Paths\s*\.+\s*${AS_PATHS} + ^Dynamic Neighbors Current/High/Limit\s*\.+\s*${DYN_NEIGH_CUR}\/${DYN_NEIGH_MAX}\/${DYN_NEIGH_LIMIT} + ^Default Metric\s*\.+\s*${METRIC_DEFAULT} + ^Default Route Advertise\s*\.+\s*${ORIG_DEFAULT} -> Record + +EOF \ No newline at end of file diff --git a/test/unit/mocked_data/test_get_bgp_neighbors/normal/expected_result.json b/test/unit/mocked_data/test_get_bgp_neighbors/normal/expected_result.json new file mode 100644 index 0000000..70cec08 --- /dev/null +++ b/test/unit/mocked_data/test_get_bgp_neighbors/normal/expected_result.json @@ -0,0 +1,81 @@ +{ + "global": { + "router_id": "0.0.0.100", + "peers": { + "10.10.10.10": { + "local_as": 65001, + "remote_as": 65000, + "remote_id": "0.0.0.0", + "is_up": false, + "is_enabled": true, + "description": "", + "uptime": -1, + "address_family": { + "ipv4": { + "sent_prefixes": 0, + "accepted_prefixes": 0, + "received_prefixes": 0 + }, + "ipv6": { + "sent_prefixes": 0, + "accepted_prefixes": 0, + "received_prefixes": 0 + } + } + }, + "172.20.1.100": { + "local_as": 65001, + "remote_as": 100, + "remote_id": "14.3.0.1", + "is_up": true, + "is_enabled": true, + "description": "", + "uptime": -1, + "address_family": { + "ipv4": { + "sent_prefixes": 0, + "accepted_prefixes": 1, + "received_prefixes": 1 + } + } + }, + "fe80::2": { + "local_as": 65001, + "remote_as": 100, + "remote_id": "14.3.0.1", + "is_up": true, + "is_enabled": true, + "description": "spine 1 router 1", + "uptime": -1, + "address_family": { + "ipv6": { + "sent_prefixes": 0, + "accepted_prefixes": 1, + "received_prefixes": 1 + } + } + }, + "fe80::3": { + "local_as": 65001, + "remote_as": 100, + "remote_id": "14.3.0.2", + "is_up": true, + "is_enabled": true, + "description": "spine 1 router 2", + "uptime": -1, + "address_family": { + "ipv4": { + "sent_prefixes": 5, + "accepted_prefixes": 1, + "received_prefixes": 10 + }, + "ipv6": { + "sent_prefixes": 0, + "accepted_prefixes": 1, + "received_prefixes": 1 + } + } + } + } + } +} \ No newline at end of file diff --git a/test/unit/mocked_data/test_get_bgp_neighbors/normal/show_bgp_ipv6_neighbors.txt b/test/unit/mocked_data/test_get_bgp_neighbors/normal/show_bgp_ipv6_neighbors.txt new file mode 100644 index 0000000..df38d37 --- /dev/null +++ b/test/unit/mocked_data/test_get_bgp_neighbors/normal/show_bgp_ipv6_neighbors.txt @@ -0,0 +1,108 @@ +Description: spine 1 router 1 + +Remote Address................................ fe80::2 +Interface..................................... 0/1 +Remote AS..................................... 100 +Peer ID....................................... 14.3.0.1 +Peer Admin Status............................. START +Peer State.................................... ESTABLISHED +Peer Type..................................... DYNAMIC +Local Port.................................... 179 +Remote Port................................... 58265 +Connection Retry Interval..................... 120 sec +Neighbor Capabilities......................... None +IPv4 Unicast Support.......................... None +IPv6 Unicast Support.......................... Both +RFC 5549 Support.............................. Enable +Update Source................................. None +Local Interface Address....................... fe80::2 +Configured Hold Time.......................... 90 sec +Configured Keep Alive Time.................... 30 sec +Negotiated Hold Time.......................... 30 sec +Keep Alive Time............................... 10 sec +MD5 Password.................................. password + +Last Error (Sent).............................. Hold Timer Expired +Last SubError.................................. None +Time Since Last Error.......................... 0 day 0 hr 4 min 27 sec +Established Transitions........................ 1 +Established Time............................... 0 day 0 hr 4 min 25 sec +Time Since Last Update......................... 0 day 0 hr 4 min 24 sec +IPv6 Outbound Update Group..................... 7 + + + Open Update Keepalive Notification Refresh Total +Msgs Sent 1 0 10 0 0 11 +Msgs Rcvd 1 1 11 0 0 12 + +Received UPDATE Queue Size: 0 bytes. High: 355. Limit 196096. Drops 0. + +IPv6 Prefix Statistics: + Inbound Outbound +Prefixes Advertised 1 0 +Prefixes Withdrawn 0 0 +Prefixes Current 1 0 +Prefixes Accepted 1 N/A +Prefixes Rejected 1 N/A +Max NLRI per Update 1 0 +Min NLRI per Update 1 0 + + +Description: spine 1 router 2 + +Remote Address................................ fe80::3 +Interface..................................... 0/1 +Remote AS..................................... 100 +Peer ID....................................... 14.3.0.2 +Peer Admin Status............................. START +Peer State.................................... ESTABLISHED +Peer Type..................................... DYNAMIC +Local Port.................................... 179 +Remote Port................................... 12345 +Connection Retry Interval..................... 120 sec +Neighbor Capabilities......................... None +IPv4 Unicast Support.......................... Both +IPv6 Unicast Support.......................... Both +RFC 5549 Support.............................. Enable +Update Source................................. None +Local Interface Address....................... fe80::3 +Configured Hold Time.......................... 90 sec +Configured Keep Alive Time.................... 30 sec +Negotiated Hold Time.......................... 30 sec +Keep Alive Time............................... 10 sec +MD5 Password.................................. password + +Last Error (Sent).............................. Hold Timer Expired +Last SubError.................................. None +Time Since Last Error.......................... 0 day 0 hr 4 min 27 sec +Established Transitions........................ 1 +Established Time............................... 0 day 0 hr 4 min 25 sec +Time Since Last Update......................... 0 day 0 hr 4 min 24 sec +IPv6 Outbound Update Group..................... 7 + + + Open Update Keepalive Notification Refresh Total +Msgs Sent 1 0 10 0 0 11 +Msgs Rcvd 1 1 11 0 0 12 + +Received UPDATE Queue Size: 0 bytes. High: 355. Limit 196096. Drops 0. + +IPv4 Prefix Statistics: + Inbound Outbound +Prefixes Advertised 10 5 +Prefixes Withdrawn 0 0 +Prefixes Current 1 0 +Prefixes Accepted 1 N/A +Prefixes Rejected 1 N/A +Max NLRI per Update 1 0 +Min NLRI per Update 1 0 + +IPv6 Prefix Statistics: + Inbound Outbound +Prefixes Advertised 1 0 +Prefixes Withdrawn 0 0 +Prefixes Current 1 0 +Prefixes Accepted 1 N/A +Prefixes Rejected 1 N/A +Max NLRI per Update 1 0 +Min NLRI per Update 1 0 diff --git a/test/unit/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors.txt b/test/unit/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors.txt new file mode 100644 index 0000000..ea8044d --- /dev/null +++ b/test/unit/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors.txt @@ -0,0 +1,107 @@ +Remote Address ................................ 10.10.10.10 +Remote AS ..................................... 65000 +Peer ID ....................................... 0.0.0.0 +Peer Admin Status ............................. START +Peer State .................................... IDLE +Local Interface Address ....................... 10.10.10.3 +Local Port .................................... 179 +Remote Port ................................... 54474 +Connection Retry Interval ..................... 2 sec +Neighbor Capabilities ......................... None +Next Hop Self ................................. Disable +IPv4 Unicast Support .......................... Sent +IPv6 Unicast Support .......................... Sent +Template Name ................................. None +Update Source ................................. None +Configured Hold Time .......................... None +Configured Keep Alive Time .................... None +Prefix Limit .................................. 8160 +Prefix Warning Threshold ...................... 75 +Warning Only On Prefix Limit .................. False +MD5 Password .................................. None +Originate Default ............................. False + +Last Error (Sent) ............................. OPEN Message Error +Last SubError ................................. Bad Peer AS +Time Since Last Error ......................... 0 days 00 hrs 00 mins 02 secs +Established Transitions ....................... 0 +Established Time .............................. 0 days 01 hrs 45 mins 20 secs +Time Since Last Update ........................ No UPDATE received +IPv4 Outbound Update Group .................... None + + + Open Update Keepalive Notification Refresh Total +Msgs Sent 2287 0 0 2122 0 4409 +Msgs Rcvd 2122 0 0 0 0 2122 + +Received UPDATE Queue Size: 0 bytes. High: 0 Limit: 392192 Drops: 0 + +IPv4 Prefix Statistics: + Inbound Outbound +Prefixes Advertised 0 0 +Prefixes Withdrawn 0 0 +Prefixes Current 0 0 +Prefixes Accepted 0 N/A +Prefixes Rejected 0 N/A +Max NLRI per Update 0 0 +Min NLRI per Update 0 0 + +IPv6 Prefix Statistics: + Inbound Outbound +Prefixes Advertised 0 0 +Prefixes Withdrawn 0 0 +Prefixes Current 0 0 +Prefixes Accepted 0 N/A +Prefixes Rejected 0 N/A +Max NLRI per Update 0 0 +Min NLRI per Update 0 0 + + +Remote Address ................................ 172.20.1.100 +Remote AS ..................................... 100 +Peer ID ....................................... 14.3.0.1 +Peer Admin Status ............................. START +Peer State .................................... ESTABLISHED +Local Interface Address ....................... 172.20.1.2 +Local Port .................................... 179 +Remote Port ................................... 58265 +Connection Retry Interval ..................... 120 sec +Neighbor Capabilities ......................... None +Next Hop Self ................................. Disable +IPv4 Unicast Support .......................... Sent +IPv6 Unicast Support .......................... None +Template Name ................................. None +Update Source.................................. +Configured Hold Time .......................... 90 sec +Configured Keep Alive Time..................... 30 sec +Negotiated Hold Time .......................... 30 sec +Keep Alive Time ............................... 10 sec +Prefix Limit................................... None +Prefix Warning Threshold....................... 75% +Warning Only On Prefix Limit................... TRUE +MD5 Password................................... password +Originate Default.............................. TRUE +Last Error (Sent).............................. Hold Timer Expired +Last SubError.................................. None +Time Since Last Error.......................... 0 day 0 hr 4 min 27 sec +Established Transitions ....................... 1 +Established Time .............................. 0 day 0 hr 4 min 25 sec +Time Since Last Update ........................ 0 day 0 hr 4 min 25 sec +IPv4 Outbound Update Group .................... 3 + + + Open Update Keepalive Notification Refresh Total +Msgs Sent 1 0 10 0 0 11 +Msgs Rcvd 1 1 11 0 0 12 + +Received UPDATE Queue Size: 0 bytes. High: 0 Limit: 123456 Drops: 0 + +IPv4 Prefix Statistics: + Inbound Outbound +Prefixes Advertised 1 0 +Prefixes Withdrawn 0 0 +Prefixes Current 1 0 +Prefixes Accepted 0 N/A +Prefixes Rejected 0 N/A +Max NLRI per Update 1 0 +Min NLRI per Update 1 0 diff --git a/test/unit/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_summary.txt b/test/unit/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_summary.txt new file mode 100644 index 0000000..ef7e54b --- /dev/null +++ b/test/unit/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_summary.txt @@ -0,0 +1,28 @@ + +IPv4 Routing .................................. Enable +BGP Admin Mode ................................ Enable +BGP Router ID ................................. 0.0.0.100 +Local AS Number ............................... 65001 +Traps ......................................... Disable +Maximum Paths ................................. 1 +Maximum Paths iBGP ............................ 1 +Default Keep Alive Time ....................... 30 +Default Hold Time ............................. 90 +Number of Network Entries ..................... 3 +Number of AS Paths ............................ 0 +Dynamic Neighbors Current/High/Limit .......... 1/1/20 +Default Metric ................................ Not Configured +Default Route Advertise ....................... No + +Redistributing: +Source Metric Dist List Route Map +--------- ---------- -------------------------------- ---------------------- +static +ospf 300 + ospf match: int + + +Neighbor ASN MsgRcvd MsgSent State Up/Down Time Pfx Rcvd +---------------- ----- -------- -------- ------------- -------------- ------ +10.10.10.10 65000 2269 4666 IDLE 0:00:45:20 0 +172.20.1.100 100 12 11 ESTABLISHED 0:00:04:25 0