Repository: napalm-automation/napalm

Issue:
get_bgp_config errors out on EOS
get_bgp_config errors out on some Arista devices.

Error:
        Traceback (most recent call last):
          File "/usr/lib/python2.7/dist-packages/salt/utils/napalm.py", line 178, in call
            out = getattr(napalm_device.get('DRIVER'), method)(*args, **kwargs)
          File "/usr/local/lib/python2.7/dist-packages/napalm/eos/eos.py", line 850, in get_bgp_config
            local_as = int(bgp_conf_line.replace("router bgp", "").strip())
        ValueError: invalid literal for int() with base 10: '65101.65101'


Looking at the code, the command "show running-config | section router bgp" gives the output as:
router bgp 65101.65101
.......

The code is trying to capture 11111.11111 as an integer and thats where its failing.


Discussion:
There are two possible ways to represent a BGP AS number:
> arista-test(config)#router bgp ?
  64512                Configure BGP AS 64512
  <1-4294967295>       AS Number
  <1-65535>.<0-65535>  AS Number in asdot notation

See [Cisco documentation](https://www.cisco.com/c/en/us/products/collateral/ios-nx-os-software/border-gateway-protocol-bgp/white_paper_c11_516829.html) for more information. The ASN can be represented as integer or when using the dotted notation as string. @mirceaulinic So what's the best approach here? Using a string so it will be compatible with both notations?
Only now seeing this, sorry... we have a helper in the napalm base: https://github.com/napalm-automation/napalm/blob/8deb8b6447098d16139c4fe77a67061838121fd6/napalm/base/helpers.py#L367

When used in the context @AmbicaY mentioned, for example, it'd give:

```python
>>> import napalm.base.helpers
>>> napalm.base.helpers.as_number('65101.65101')
4266524237
```

That should be an easy fix, let me PR that quickly.

Resolving patch:
diff --git a/napalm/eos/eos.py b/napalm/eos/eos.py
--- a/napalm/eos/eos.py
+++ b/napalm/eos/eos.py
@@ -530,11 +530,11 @@ def get_re_group(res, key, default=None):
             v6_stats = re.match(self._RE_BGP_PREFIX, lines.pop(0))
             local_as = re.match(self._RE_BGP_LOCAL, lines.pop(0))
             data = {
-                "remote_as": int(neighbor_info.group("as")),
+                "remote_as": napalm.base.helpers.as_number(neighbor_info.group("as")),
                 "remote_id": napalm.base.helpers.ip(
                     get_re_group(rid_info, "rid", "0.0.0.0")
                 ),
-                "local_as": int(local_as.group("as")),
+                "local_as": napalm.base.helpers.as_number(local_as.group("as")),
                 "description": str(desc),
                 "address_family": {
                     "ipv4": {
@@ -871,7 +871,9 @@ def parse_options(options, default_value=False):
             default_value = False
             bgp_conf_line = bgp_conf_line.strip()
             if bgp_conf_line.startswith("router bgp"):
-                local_as = int(bgp_conf_line.replace("router bgp", "").strip())
+                local_as = napalm.base.helpers.as_number(
+                    (bgp_conf_line.replace("router bgp", "").strip())
+                )
                 continue
             if not (
                 bgp_conf_line.startswith("neighbor")
@@ -1262,7 +1264,7 @@ def get_route_to(self, destination="", protocol="", longer=False):
                             )
 
                     vrf_details = vrf_cache.get(_vrf)
-                    local_as = vrf_details.get("asn")
+                    local_as = napalm.base.helpers.as_number(vrf_details.get("asn"))
                     bgp_routes = (
                         vrf_details.get("bgpRouteEntries", {})
                         .get(prefix, {})
@@ -1279,7 +1281,9 @@ def get_route_to(self, destination="", protocol="", longer=False):
                         if as_path_type in ["Internal", "Local"]:
                             remote_as = local_as
                         else:
-                            remote_as = int(as_path.strip("()").split()[-1])
+                            remote_as = napalm.base.helpers.as_number(
+                                as_path.strip("()").split()[-1]
+                            )
                         remote_address = napalm.base.helpers.ip(
                             bgp_route_details.get("routeDetail", {})
                             .get("peerEntry", {})


Test patch:
diff --git a/test/eos/mocked_data/test_get_bgp_config/issue_1113_dot_asn/expected_result.json b/test/eos/mocked_data/test_get_bgp_config/issue_1113_dot_asn/expected_result.json
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_bgp_config/issue_1113_dot_asn/expected_result.json
@@ -0,0 +1,82 @@
+{
+  "IPv4-PEERS-GROUP-NAME": {
+    "type": "",
+    "multipath": false,
+    "apply_groups": [],
+    "remove_private_as": true,
+    "multihop_ttl": 0,
+    "remote_as": 0,
+    "local_address": "",
+    "local_as": 4266524237,
+    "description": "",
+    "import_policy": "reject-all",
+    "export_policy": "4-public-peer-anycast-out",
+    "prefix_limit": {},
+    "neighbors": {
+      "192.168.0.1": {
+        "description": "",
+        "remote_as": 32934,
+        "local_address": "",
+        "local_as": 4266524237,
+        "nhs": false,
+        "route_reflector_client": false,
+        "import_policy": "",
+        "export_policy": "",
+        "authentication_key": "",
+        "prefix_limit": {}
+      },
+      "172.17.17.1": {
+        "description": "",
+        "remote_as": 13414,
+        "local_address": "",
+        "local_as": 4266524237,
+        "nhs": false,
+        "route_reflector_client": false,
+        "import_policy": "",
+        "export_policy": "",
+        "authentication_key": "",
+        "prefix_limit": {}
+      }
+    }
+  },
+  "IPv6-PEERS-GROUP-NAME": {
+    "type": "",
+    "multipath": false,
+    "apply_groups": [],
+    "remove_private_as": true,
+    "multihop_ttl": 0,
+    "remote_as": 0,
+    "local_address": "",
+    "local_as": 4266524237,
+    "description": "",
+    "import_policy": "reject-all",
+    "export_policy": "reject-all",
+    "prefix_limit": {},
+    "neighbors": {
+      "2001:db8::0:1": {
+        "description": "",
+        "remote_as": 8403,
+        "local_address": "",
+        "local_as": 4266524237,
+        "nhs": false,
+        "route_reflector_client": false,
+        "import_policy": "",
+        "export_policy": "",
+        "authentication_key": "",
+        "prefix_limit": {}
+      },
+      "2001:db8::0:2": {
+        "description": "",
+        "remote_as": 54113,
+        "local_address": "",
+        "local_as": 4266524237,
+        "nhs": false,
+        "route_reflector_client": false,
+        "import_policy": "",
+        "export_policy": "",
+        "authentication_key": "",
+        "prefix_limit": {}
+      }
+    }
+  }
+}
diff --git a/test/eos/mocked_data/test_get_bgp_config/issue_1113_dot_asn/show_running_config___section_router_bgp.text b/test/eos/mocked_data/test_get_bgp_config/issue_1113_dot_asn/show_running_config___section_router_bgp.text
new file mode 100644
--- /dev/null
+++ b/test/eos/mocked_data/test_get_bgp_config/issue_1113_dot_asn/show_running_config___section_router_bgp.text
@@ -0,0 +1,24 @@
+router bgp 65101.65101
+   maximum-paths 32
+   neighbor IPv4-PEERS-GROUP-NAME peer-group
+   neighbor IPv4-PEERS-GROUP-NAME remove-private-as
+   neighbor IPv4-PEERS-GROUP-NAME route-map reject-all in
+   neighbor IPv4-PEERS-GROUP-NAME route-map 4-public-peer-anycast-out out
+   neighbor IPv4-PEERS-GROUP-NAME maximum-routes 500
+   neighbor IPv6-PEERS-GROUP-NAME peer-group
+   neighbor IPv6-PEERS-GROUP-NAME remove-private-as
+   neighbor IPv6-PEERS-GROUP-NAME route-map reject-all in
+   neighbor IPv6-PEERS-GROUP-NAME route-map reject-all out
+   neighbor IPv6-PEERS-GROUP-NAME maximum-routes 100
+   neighbor 192.168.0.1 peer-group IPv4-PEERS-GROUP-NAME
+   neighbor 192.168.0.1 remote-as 32934
+   neighbor 192.168.0.1 maximum-routes 100
+   neighbor 172.17.17.1 peer-group IPv4-PEERS-GROUP-NAME
+   neighbor 172.17.17.1 remote-as 13414
+   neighbor 172.17.17.1 maximum-routes 500
+   neighbor 2001:db8::0:1 peer-group IPv6-PEERS-GROUP-NAME
+   neighbor 2001:db8::0:1 remote-as 8403
+   neighbor 2001:db8::0:1 maximum-routes 500
+   neighbor 2001:db8::0:2 peer-group IPv6-PEERS-GROUP-NAME
+   neighbor 2001:db8::0:2 remote-as 54113
+!