Repository: napalm-automation/napalm

Issue:
EOS: `get_route_to()` does not support confederations
Router output:
```
{
    "vrfs": {
        "default": {
            "routerId": "192.0.2.48",
            "vrf": "default",
            "bgpRouteEntries": {
                "192.0.2.0/24": {
                    "totalPaths": 2,
                    "bgpAdvertisedPeerGroups": {
                        "INTERNAL-TOR": {
                            "peerList": [
                                "192.0.2.223"
                            ]
                        }
                    },
                    "totalAdvertisedPeers": 1,
                    "maskLength": 16,
                    "bgpRoutePaths": [
                        {
                            "asPathEntry": {
                                "asPathType": "Confed-External",
                                "asPath": "(20901 21149)"
                            },
                            "med": 175,
                            "localPreference": 100,
                            "weight": 0,
                            "reasonNotBestpath": "noReason",
                            "timestamp": 1526591713,
                            "nextHop": "192.0.4.221",
                            "routeType": {
                                "atomicAggregator": false,
                                "origin": "Igp",
                                "suppressed": false,
                                "queued": false,
                                "valid": true,
                                "ecmpContributor": true,
                                "luRoute": false,
                                "active": true,
                                "stale": false,
                                "ecmp": true,
                                "backup": false,
                                "ecmpHead": true,
                                "ucmp": false
                            },
                            "routeDetail": {
                                "origin": "Igp",
                                "peerEntry": {
                                    "peerRouterId": "192.0.2.1",
                                    "peerAddr": "192.0.2.221"
                                },
                                "tunnelRibEligible": false,
                                "extCommunityList": [],
                                "communityList": [],
                                "rxSafi": "Unicast",
                                "aggregator": " (aggregated by 65001 192.0.255.49)",
                                "recvdFromRRClient": false,
                                "labelStack": []
                            }
                        },
                        {
                            "asPathEntry": {
                                "asPathType": "Confed-External",
                                "asPath": "(20902 21149)"
                            },
                            "med": 175,
                            "localPreference": 100,
                            "weight": 0,
                            "reasonNotBestpath": "ecmpFast",
                            "timestamp": 1526591756,
                            "nextHop": "192.0.4.223",
                            "routeType": {
                                "atomicAggregator": false,
                                "origin": "Igp",
                                "suppressed": false,
                                "queued": false,
                                "valid": true,
                                "ecmpContributor": true,
                                "luRoute": false,
                                "active": false,
                                "stale": false,
                                "ecmp": true,
                                "backup": false,
                                "ecmpHead": false,
                                "ucmp": false
                            },
                            "routeDetail": {
                                "origin": "Igp",
                                "peerEntry": {
                                    "peerRouterId": "192.0.2.2",
                                    "peerAddr": "192.0.2.223"
                                },
                                "tunnelRibEligible": false,
                                "extCommunityList": [],
                                "communityList": [],
                                "rxSafi": "Unicast",
                                "aggregator": " (aggregated by 65001 192.0.2.49)",
                                "recvdFromRRClient": false,
                                "labelStack": []
                            }
                        }
                    ],
                    "address": "192.0.2.0"
                }
            },
            "asn": 20948
        }
    }
}
```

Error message:
```python
ValueError                                Traceback (most recent call last)
<ipython-input-2-c5a9e185b0d9> in <module>()
      5
      6 with EOSDriver("router", "bewing", getpass()) as d:
----> 7     pprint(d.get_route_to("192.0.2.0/24"))
      8
      9

/mnt/c/Users/bewing/PycharmProjects/napalm/napalm/eos/eos.py in get_route_to(self, destination, protocol)
   1130                         bgp_route = route.copy()
   1131                         as_path = bgp_route_details.get('asPathEntry', {}).get('asPath', u'')
-> 1132                         remote_as = int(as_path.split()[-1])
   1133                         remote_address = napalm.base.helpers.ip(bgp_route_details.get(
   1134                             'routeDetail', {}).get('peerEntry', {}).get('peerAddr', ''))

ValueError: invalid literal for int() with base 10: '21149)'
```


Discussion:

Resolving patch:
diff --git a/napalm/eos/eos.py b/napalm/eos/eos.py
--- a/napalm/eos/eos.py
+++ b/napalm/eos/eos.py
@@ -1129,7 +1129,7 @@ def get_route_to(self, destination='', protocol=''):
                     for bgp_route_details in bgp_routes:
                         bgp_route = route.copy()
                         as_path = bgp_route_details.get('asPathEntry', {}).get('asPath', u'')
-                        remote_as = int(as_path.split()[-1])
+                        remote_as = int(as_path.strip("()").split()[-1])
                         remote_address = napalm.base.helpers.ip(bgp_route_details.get(
                             'routeDetail', {}).get('peerEntry', {}).get('peerAddr', ''))
                         local_preference = bgp_route_details.get('localPreference')


Test patch:
diff --git a/test/eos/mocked_data/test_get_route_to/iss_736/expected_result.json b/test/eos/mocked_data/test_get_route_to/iss_736/expected_result.json
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_route_to/iss_736/expected_result.json
@@ -0,0 +1 @@
+{"1.0.4.0/24": [{"current_active": true, "last_active": true, "age": 0, "next_hop": "1.0.4.221", "protocol": "eBGP", "outgoing_interface": "Ethernet51/1", "preference": 200, "inactive_reason": "noReason", "routing_table": "default", "selected_next_hop": true, "protocol_attributes": {"metric": 175, "as_path": "(20901 21149)", "local_preference": 100, "local_as": 20948, "remote_as": 21149, "remote_address": "1.0.4.221", "preference2": 0, "communities": []}}, {"current_active": false, "last_active": false, "age": 0, "next_hop": "1.0.4.223", "protocol": "eBGP", "outgoing_interface": "Ethernet52/1", "preference": 200, "inactive_reason": "ecmpFast", "routing_table": "default", "selected_next_hop": false, "protocol_attributes": {"metric": 175, "as_path": "(20902 21149)", "local_preference": 100, "local_as": 20948, "remote_as": 21149, "remote_address": "1.0.4.223", "preference2": 0, "communities": []}}]}
diff --git a/test/eos/mocked_data/test_get_route_to/iss_736/show_ip_bgp_1_0_4_0_24_detail_vrf_default.json b/test/eos/mocked_data/test_get_route_to/iss_736/show_ip_bgp_1_0_4_0_24_detail_vrf_default.json
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_route_to/iss_736/show_ip_bgp_1_0_4_0_24_detail_vrf_default.json
@@ -0,0 +1,108 @@
+{
+    "vrfs": {
+        "default": {
+            "routerId": "1.0.4.48",
+            "vrf": "default",
+            "bgpRouteEntries": {
+                "1.0.4.0/24": {
+                    "totalPaths": 2,
+                    "bgpAdvertisedPeerGroups": {
+                        "INTERNAL-TOR": {
+                            "peerList": [
+                                "1.0.4.223"
+                            ]
+                        }
+                    },
+                    "totalAdvertisedPeers": 1,
+                    "maskLength": 16,
+                    "bgpRoutePaths": [
+                        {
+                            "asPathEntry": {
+                                "asPathType": "Confed-External",
+                                "asPath": "(20901 21149)"
+                            },
+                            "med": 175,
+                            "localPreference": 100,
+                            "weight": 0,
+                            "reasonNotBestpath": "noReason",
+                            "timestamp": 1526591713,
+                            "nextHop": "1.0.4.221",
+                            "routeType": {
+                                "atomicAggregator": false,
+                                "origin": "Igp",
+                                "suppressed": false,
+                                "queued": false,
+                                "valid": true,
+                                "ecmpContributor": true,
+                                "luRoute": false,
+                                "active": true,
+                                "stale": false,
+                                "ecmp": true,
+                                "backup": false,
+                                "ecmpHead": true,
+                                "ucmp": false
+                            },
+                            "routeDetail": {
+                                "origin": "Igp",
+                                "peerEntry": {
+                                    "peerRouterId": "1.0.4.1",
+                                    "peerAddr": "1.0.4.221"
+                                },
+                                "tunnelRibEligible": false,
+                                "extCommunityList": [],
+                                "communityList": [],
+                                "rxSafi": "Unicast",
+                                "aggregator": " (aggregated by 65001 1.0.4.49)",
+                                "recvdFromRRClient": false,
+                                "labelStack": []
+                            }
+                        },
+                        {
+                            "asPathEntry": {
+                                "asPathType": "Confed-External",
+                                "asPath": "(20902 21149)"
+                            },
+                            "med": 175,
+                            "localPreference": 100,
+                            "weight": 0,
+                            "reasonNotBestpath": "ecmpFast",
+                            "timestamp": 1526591756,
+                            "nextHop": "1.0.4.223",
+                            "routeType": {
+                                "atomicAggregator": false,
+                                "origin": "Igp",
+                                "suppressed": false,
+                                "queued": false,
+                                "valid": true,
+                                "ecmpContributor": true,
+                                "luRoute": false,
+                                "active": false,
+                                "stale": false,
+                                "ecmp": true,
+                                "backup": false,
+                                "ecmpHead": false,
+                                "ucmp": false
+                            },
+                            "routeDetail": {
+                                "origin": "Igp",
+                                "peerEntry": {
+                                    "peerRouterId": "1.0.4.2",
+                                    "peerAddr": "1.0.4.223"
+                                },
+                                "tunnelRibEligible": false,
+                                "extCommunityList": [],
+                                "communityList": [],
+                                "rxSafi": "Unicast",
+                                "aggregator": " (aggregated by 65501 1.0.4.49)",
+                                "recvdFromRRClient": false,
+                                "labelStack": []
+                            }
+                        }
+                    ],
+                    "address": "1.0.4.0"
+                }
+            },
+            "asn": 20948
+        }
+    }
+}
diff --git a/test/eos/mocked_data/test_get_route_to/iss_736/show_ip_route_vrf_default_1_0_4_0_24_bgp_detail.json b/test/eos/mocked_data/test_get_route_to/iss_736/show_ip_route_vrf_default_1_0_4_0_24_bgp_detail.json
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_route_to/iss_736/show_ip_route_vrf_default_1_0_4_0_24_bgp_detail.json
@@ -0,0 +1,33 @@
+{
+    "vrfs": {
+        "default": {
+            "routes": {
+                "1.0.4.0/24": {
+                    "kernelProgrammed": true,
+                    "directlyConnected": false,
+                    "preference": 200,
+                    "routeAction": "forward",
+                    "vias": [
+                        {
+                            "interface": "Ethernet51/1",
+                            "interfaceDescription": "veos1:e5-21-1:",
+                            "nexthopAddr": "1.0.4.221"
+                        },
+                        {
+                            "interface": "Ethernet52/1",
+                            "interfaceDescription": "veos2:e5-21-1:",
+                            "nexthopAddr": "1.0.4.223"
+                        }
+                    ],
+                    "metric": 175,
+                    "hardwareProgrammed": true,
+                    "routeType": "eBGP"
+                }
+            },
+            "allRoutesProgrammedKernel": true,
+            "routingDisabled": false,
+            "allRoutesProgrammedHardware": true,
+            "defaultRouteState": "reachable"
+        }
+    }
+}
diff --git a/test/eos/mocked_data/test_get_route_to/iss_736/show_vrf.text b/test/eos/mocked_data/test_get_route_to/iss_736/show_vrf.text
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_route_to/iss_736/show_vrf.text
@@ -0,0 +1,3 @@
+Maximum number of vrfs allowed: 14
+ Vrf     RD           Protocols    State                    Interfaces
+------- ------------ ------------ ------------------------- -------------------