Repository: napalm-automation/napalm

Issue:
get_bgp_neighbors() gets corrupted if 6PE is enabled in eos
In the case of processing of these lines, if ipv6 is invalid, there will be a gap in the number of processing lines.
As a result, local_asn regex different lines.

https://github.com/napalm-automation/napalm/blob/2e98a86bc8f967256fdc38255a856d2fae40fd68/napalm/eos/eos.py#L484-L509

In my eos environment, I confirmed neighbors where ipv6 stats like below are not displayed.

```
['BGP neighbor is 10.8.176.1, remote AS 64540, internal link', '  BGP version 4, remote router ID 10.8.176.1, VRF default', '  BGP state is Established, up for 172d03h', '    IPv4 Unicast:           0        58', 'Local AS is 38651, local router ID 10.8.176.11']
```

`v6_stats` should also be branched like `desc`'s `next_line`.


Discussion:
Error Info
```
2019-03-18 11:27:47,429 - napalm - ERROR - method - Failed: 'NoneType' object has no attribute 'group'

================= Traceback =================

Traceback (most recent call last):
  File "/usr/local/bin/napalm", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.6/dist-packages/napalm/base/clitools/cl_napalm.py", line 309, in main
    run_tests(args)
  File "/usr/local/lib/python3.6/dist-packages/napalm/base/clitools/cl_napalm.py", line 292, in run_tests
    call_getter(device, args.method, **method_kwargs)
  File "/usr/local/lib/python3.6/dist-packages/napalm/base/clitools/cl_napalm.py", line 31, in wrapper
    r = func(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/napalm/base/clitools/cl_napalm.py", line 256, in call_getter
    r = func(**kwargs)
  File "/usr/local/lib/python3.6/dist-packages/napalm/eos/eos.py", line 518, in get_bgp_neighbors
    "local_as": int(local_as.group("as")),
AttributeError: 'NoneType' object has no attribute 'group'
```
The cause was using 6PE on EOS's router.
If you use 6PE, it will be the following form before using Regexp.
```
  Prefix Statistics:
                         Sent      Rcvd
    IPv4 Unicast:           0        58
    IPv6 6PE:               1         1
```

Before the code is omitted, 6PE is omitted at the command level.
following parts.
https://github.com/napalm-automation/napalm/blob/2e98a86bc8f967256fdc38255a856d2fae40fd68/napalm/eos/eos.py#L429

Even in the case of 6 PE, we consider that it should be included in sent / received in ipv6, or ipv6 should be omitted (sent, received should be -1), or either action should be taken.

Resolving patch:
diff --git a/napalm/eos/eos.py b/napalm/eos/eos.py
--- a/napalm/eos/eos.py
+++ b/napalm/eos/eos.py
@@ -76,7 +76,7 @@ class EOSDriver(NetworkDriver):
     _RE_BGP_DESC = re.compile(r"\s+Description: (?P<description>.*?)$")
     _RE_BGP_LOCAL = re.compile(r"Local AS is (?P<as>.*?),.*")
     _RE_BGP_PREFIX = re.compile(
-        r"(\s*?)(?P<af>IPv[46]) Unicast:\s*(?P<sent>\d+)\s*(?P<received>\d+)"
+        r"(\s*?)(?P<af>IPv[46]) (Unicast|6PE):\s*(?P<sent>\d+)\s*(?P<received>\d+)"
     )  # noqa
     _RE_SNMP_COMM = re.compile(
         r"""^snmp-server\s+community\s+(?P<community>\S+)
@@ -426,7 +426,7 @@ def get_re_group(res, key, default=None):
             except KeyError:
                 return default
 
-        NEIGHBOR_FILTER = "bgp neighbors vrf all | include remote AS | remote router ID |IPv[46] Unicast:.*[0-9]+|^Local AS|Desc|BGP state"  # noqa
+        NEIGHBOR_FILTER = "bgp neighbors vrf all | include remote AS | remote router ID |IPv[46] (Unicast|6PE):.*[0-9]+|^Local AS|Desc|BGP state"  # noqa
         output_summary_cmds = self.device.run_commands(
             ["show ipv6 bgp summary vrf all", "show ip bgp summary vrf all"],
             encoding="json",


Test patch:
diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46__Unicast____0_9____Local_AS_Desc_BGP_state.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
similarity index 100%
rename from test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46__Unicast____0_9____Local_AS_Desc_BGP_state.text
rename to test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46__Unicast____0_9____Local_AS_Desc_BGP_state.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
similarity index 100%
rename from test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46__Unicast____0_9____Local_AS_Desc_BGP_state.text
rename to test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue944/expected_result.json b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/expected_result.json
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/expected_result.json
@@ -0,0 +1,91 @@
+{
+  "global": {
+    "router_id": "192.168.56.3",
+    "peers": {
+      "192.168.56.4": {
+        "is_enabled": true,
+        "uptime": "...",
+        "remote_as": 65001,
+        "description": "",
+        "remote_id": "192.168.56.3",
+        "local_as": 65002,
+        "is_up": false,
+        "address_family": {
+          "ipv4": {
+            "sent_prefixes": 0,
+            "accepted_prefixes": -1,
+            "received_prefixes": 0
+          },
+          "ipv6": {
+            "sent_prefixes": 0,
+            "accepted_prefixes": -1,
+            "received_prefixes": 0
+          }
+        }
+      },
+      "192.168.56.2": {
+        "is_enabled": true,
+        "uptime": "...",
+        "remote_as": 65002,
+        "description": "",
+        "remote_id": "192.168.56.2",
+        "local_as": 65001,
+        "is_up": true,
+        "address_family": {
+          "ipv4": {
+            "sent_prefixes": 0,
+            "accepted_prefixes": -1,
+            "received_prefixes": 0
+          },
+          "ipv6": {
+            "sent_prefixes": 0,
+            "accepted_prefixes": -1,
+            "received_prefixes": 0
+          }
+        }
+      },
+      "2001:7f8::f10:0:2": {
+        "is_enabled": true,
+        "uptime": "...",
+        "remote_as": 65002,
+        "description": "",
+        "remote_id": "192.168.56.2",
+        "local_as": 65001,
+        "is_up": true,
+        "address_family": {
+          "ipv4": {
+            "sent_prefixes": 0,
+            "accepted_prefixes": -1,
+            "received_prefixes": 0
+          },
+          "ipv6": {
+            "sent_prefixes": 0,
+            "accepted_prefixes": -1,
+            "received_prefixes": 0
+          }
+        }
+      },
+      "2001:7f8::f10:0:3": {
+        "is_enabled": true,
+        "uptime": "...",
+        "remote_as": 65001,
+        "description": "",
+        "remote_id": "192.168.56.3",
+        "local_as": 65002,
+        "is_up": false,
+        "address_family": {
+          "ipv4": {
+            "sent_prefixes": 0,
+            "accepted_prefixes": -1,
+            "received_prefixes": 0
+          },
+          "ipv6": {
+            "sent_prefixes": 0,
+            "accepted_prefixes": -1,
+            "received_prefixes": 0
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
@@ -0,0 +1,12 @@
+BGP neighbor is 192.168.56.2, remote AS 65002, external link
+  BGP version 4, remote router ID 192.168.56.2, VRF default
+  BGP state is Established, up for   32d16h
+    IPv4 Unicast:           0         0
+    IPv6 6PE:               0         0
+Local AS is 65001, local router ID 192.168.56.3
+BGP neighbor is 192.168.56.4, remote AS 65001, external link
+  BGP version 4, remote router ID 192.168.56.3, VRF default
+  BGP state is Established, up for   32d16h
+    IPv4 Unicast:           0         0
+    IPv6 6PE:               0         0
+Local AS is 65002, local router ID 192.168.56.2
diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ip_bgp_summary_vrf_all.json b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ip_bgp_summary_vrf_all.json
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ip_bgp_summary_vrf_all.json
@@ -0,0 +1,37 @@
+{
+"vrfs": {
+"default": {
+"routerId": "192.168.56.3",
+"peers": {
+"192.168.56.2": {
+"msgSent": 6,
+"inMsgQueue": 0,
+"prefixReceived": 0,
+"upDownTime": 1452680643.198489,
+"version": 4,
+"msgReceived": 5,
+"prefixAccepted": 0,
+"peerState": "Established",
+"outMsgQueue": 0,
+"underMaintenance": false,
+"asn": 65002
+},
+"192.168.56.4": {
+"msgSent": 267,
+"inMsgQueue": 0,
+"prefixReceived": 0,
+"upDownTime": 1452696202.499104,
+"version": 4,
+"msgReceived": 263,
+"prefixAccepted": 0,
+"peerState": "Active",
+"outMsgQueue": 0,
+"underMaintenance": false,
+"asn": 65001
+}
+},
+"vrf": "default",
+"asn": 65001
+}
+}
+}
diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46__Unicast____0_9____Local_AS_Desc_BGP_state.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
similarity index 100%
rename from test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46__Unicast____0_9____Local_AS_Desc_BGP_state.text
rename to test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ipv6_bgp_summary_vrf_all.json b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ipv6_bgp_summary_vrf_all.json
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ipv6_bgp_summary_vrf_all.json
@@ -0,0 +1,37 @@
+{
+"vrfs": {
+"default": {
+"routerId": "192.168.56.3",
+"peers": {
+"2001:7f8::f10:0:2": {
+"msgSent": 5,
+"inMsgQueue": 0,
+"prefixReceived": 0,
+"upDownTime": 1452681618.167685,
+"version": 4,
+"msgReceived": 5,
+"prefixAccepted": 0,
+"peerState": "Established",
+"outMsgQueue": 0,
+"underMaintenance": false,
+"asn": 65002
+},
+"2001:7f8::f10:0:3": {
+"msgSent": 267,
+"inMsgQueue": 0,
+"prefixReceived": 0,
+"upDownTime": 1452696202.499104,
+"version": 4,
+"msgReceived": 263,
+"prefixAccepted": 0,
+"peerState": "Active",
+"outMsgQueue": 0,
+"underMaintenance": false,
+"asn": 65001
+}
+},
+"vrf": "default",
+"asn": 65001
+}
+}
+}
diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46__Unicast____0_9____Local_AS_Desc_BGP_state.text b/test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
similarity index 100%
rename from test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46__Unicast____0_9____Local_AS_Desc_BGP_state.text
rename to test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text b/test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text
@@ -0,0 +1,12 @@
+BGP neighbor is 2001:7f8::f10:0:2, remote AS 65002, external link
+  BGP version 4, remote router ID 192.168.56.2, VRF default
+  BGP state is Established, up for   32d16h
+    IPv4 Unicast:           0         0
+    IPv6 Unicast:           0         0
+Local AS is 65001, local router ID 192.168.56.3
+BGP neighbor is 2001:7f8::f10:0:3, remote AS 65001, external link
+  BGP version 4, remote router ID 192.168.56.3, VRF default
+  BGP state is Established, up for   32d16h
+    IPv4 Unicast:           0         0
+    IPv6 Unicast:           0         0
+Local AS is 65002, local router ID 192.168.56.2