Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eos: Require EOS 4.23+ #2015

Merged
merged 6 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions napalm/base/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ class ConnectionClosedException(ConnectionException):
pass


class UnsupportedVersion(ConnectionException):
pass


class ReplaceConfigException(NapalmException):
pass

Expand Down
93 changes: 38 additions & 55 deletions napalm/eos/eos.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@
ReplaceConfigException,
SessionLockedException,
CommandErrorException,
UnsupportedVersion,
)
from napalm.eos.constants import LLDP_CAPAB_TRANFORM_TABLE
from napalm.eos.pyeapi_syntax_wrapper import Node
from napalm.eos.utils.versions import EOSVersion
from napalm.eos.utils.cli_syntax import cli_convert
import napalm.base.constants as c

# local modules
Expand Down Expand Up @@ -123,15 +122,13 @@ def __init__(self, hostname, username, password, timeout=60, optional_args=None)
self.timeout = timeout
self.config_session = None
self.locked = False
self.cli_version = 1

self.platform = "eos"
self.profile = [self.platform]
self.optional_args = optional_args or {}

self.enablepwd = self.optional_args.pop("enable_password", "")
self.eos_autoComplete = self.optional_args.pop("eos_autoComplete", None)
self.fn0039_config = self.optional_args.pop("eos_fn0039_config", False)

# Define locking method
self.lock_disable = self.optional_args.pop("lock_disable", False)
Expand Down Expand Up @@ -201,10 +198,6 @@ def open(self):
device_type="arista_eos",
netmiko_optional_args=self.netmiko_optional_args,
)
# let's try to determine if we need to use new EOS cli syntax
sh_ver = self._run_commands(["show version"])
if EOSVersion(sh_ver[0]["version"]) >= EOSVersion("4.23.0"):
self.cli_version = 2
else:
try:
connection = self.transport_class(
Expand All @@ -216,22 +209,24 @@ def open(self):
)

if self.device is None:
self.device = Node(connection, enablepwd=self.enablepwd)
self.device = pyeapi.client.Node(
connection, enablepwd=self.enablepwd
)
# does not raise an Exception if unusable

# let's try to determine if we need to use new EOS cli syntax
sh_ver = self.device.run_commands(["show version"])
self.cli_version = (
2 if EOSVersion(sh_ver[0]["version"]) >= EOSVersion("4.23.0") else 1
)

self.device.update_cli_version(self.cli_version)
except ConnectionError as ce:
# and this is raised either if device not avaiable
# either if HTTP(S) agent is not enabled
# show management api http-commands
raise ConnectionException(str(ce))

# endif self.transport

sh_ver = self._run_commands(["show version"])
self._eos_version = EOSVersion(sh_ver[0]["version"])
if self._eos_version < EOSVersion("4.23.0"):
raise UnsupportedVersion(self._eos_version)

def close(self):
"""Implementation of NAPALM method close."""
self.discard_config()
Expand Down Expand Up @@ -263,11 +258,6 @@ def is_alive(self):

def _run_commands(self, commands, **kwargs):
if self.transport == "ssh":
if self.fn0039_config:
if isinstance(commands, str):
commands = [cli_convert(commands, self.cli_version)]
else:
commands = [cli_convert(cmd, self.cli_version) for cmd in commands]
ret = []
for command in commands:
if kwargs.get("encoding") == "text":
Expand Down Expand Up @@ -463,10 +453,9 @@ def _load_config(self, filename=None, config=None, replace=True):
self._run_commands(
commands,
autoComplete=self.eos_autoComplete,
fn0039_transform=self.fn0039_config,
)
else:
self._run_commands(commands, fn0039_transform=self.fn0039_config)
self._run_commands(commands)
except pyeapi.eapilib.CommandError as e:
self.discard_config()
msg = str(e)
Expand Down Expand Up @@ -691,13 +680,16 @@ def get_re_group(res, key, default=None):
except KeyError:
return default

NEIGHBOR_FILTER = "bgp neighbors vrf all | include IPv[46] (Unicast|6PE):.*[0-9]+ | grep -v ' IPv[46] Unicast:/.' | remote AS |^Local AS|Desc|BGP state |remote router ID" # noqa
NEIGHBOR_FILTER = "vrf all | include IPv[46] (Unicast|6PE):.*[0-9]+ | grep -v ' IPv[46] Unicast:/.' | remote AS |^Local AS|Desc|BGP state |remote router ID" # noqa
output_summary_cmds = self._run_commands(
["show ipv6 bgp summary vrf all", "show ip bgp summary vrf all"],
encoding="json",
)
output_neighbor_cmds = self._run_commands(
["show ip " + NEIGHBOR_FILTER, "show ipv6 " + NEIGHBOR_FILTER],
[
"show ip bgp neighbors " + NEIGHBOR_FILTER,
"show ipv6 bgp peers " + NEIGHBOR_FILTER,
],
encoding="text",
)

Expand Down Expand Up @@ -831,10 +823,13 @@ def extract_temperature_data(data):
yield name, values

sh_version_out = self._run_commands(["show version"])
is_veos = sh_version_out[0]["modelName"].lower() == "veos"
commands = ["show environment cooling", "show environment temperature"]
is_veos = sh_version_out[0]["modelName"].lower() in ["veos", "ceoslab"]
commands = [
"show system environment cooling",
"show system environment temperature",
]
if not is_veos:
commands.append("show environment power")
commands.append("show system environment power")
fans_output, temp_output, power_output = self._run_commands(commands)
else:
fans_output, temp_output = self._run_commands(commands)
Expand Down Expand Up @@ -1527,23 +1522,12 @@ def get_route_to(self, destination="", protocol="", longer=False):
nexthop_interface_map[nexthop_ip] = next_hop.get("interface")
metric = route_details.get("metric")
if _vrf not in vrf_cache.keys():
if self.cli_version == 1:
command = "show ip{ipv} bgp {dest} {longer} detail vrf {_vrf}".format(
ipv=ipv,
dest=destination,
longer="longer-prefixes" if longer else "",
_vrf=_vrf,
)
else:
# Newer EOS can't mix longer-prefix and detail
command = (
"show ip{ipv} bgp {dest} {longer} vrf {_vrf}".format(
ipv=ipv,
dest=destination,
longer="longer-prefixes" if longer else "",
_vrf=_vrf,
)
)
command = "show ip{ipv} bgp {dest} {longer} vrf {_vrf}".format(
ipv=ipv,
dest=destination,
longer="longer-prefixes" if longer else "",
_vrf=_vrf,
)
vrf_cache.update(
{
_vrf: self._run_commands([command])[0]
Expand Down Expand Up @@ -1656,7 +1640,11 @@ def get_snmp_information(self):
# Default values
snmp_dict = {"chassis_id": "", "location": "", "contact": "", "community": {}}

commands = ["show snmp chassis", "show snmp location", "show snmp contact"]
commands = [
"show snmp v2-mib chassis",
"show snmp v2-mib location",
"show snmp v2-mib contact",
]
snmp_config = self._run_commands(commands, encoding="json")
for line in snmp_config:
for k, v in line.items():
Expand Down Expand Up @@ -1691,7 +1679,7 @@ def _sshkey_type(sshkey):

users = {}

commands = ["show user-account"]
commands = ["show users accounts"]
user_items = self._run_commands(commands)[0].get("users", {})

for user, user_details in user_items.items():
Expand Down Expand Up @@ -1950,7 +1938,7 @@ def _append(bgp_dict, peer_info):
summary_commands = []
if not neighbor_address:
commands.append("show ip bgp neighbors vrf all")
commands.append("show ipv6 bgp neighbors vrf all")
commands.append("show ipv6 bgp peers vrf all")
summary_commands.append("show ip bgp summary vrf all")
summary_commands.append("show ipv6 bgp summary vrf all")
else:
Expand All @@ -1963,7 +1951,7 @@ def _append(bgp_dict, peer_info):
commands.append("show ip bgp neighbors %s vrf all" % neighbor_address)
summary_commands.append("show ip bgp summary vrf all")
elif peer_ver == 6:
commands.append("show ipv6 bgp neighbors %s vrf all" % neighbor_address)
commands.append("show ipv6 bgp peers %s vrf all" % neighbor_address)
summary_commands.append("show ipv6 bgp summary vrf all")

raw_output = self._run_commands(commands, encoding="text")
Expand Down Expand Up @@ -2169,18 +2157,13 @@ def _show_vrf_text(self):
return vrfs

def _show_vrf(self):
if self.cli_version == 2:
return self._show_vrf_json()
else:
return self._show_vrf_text()
return self._show_vrf_json()

def _get_vrfs(self):
output = self._show_vrf()

vrfs = [str(vrf["name"]) for vrf in output]

vrfs.append("default")

return vrfs

def get_network_instances(self, name=""):
Expand Down
42 changes: 0 additions & 42 deletions napalm/eos/pyeapi_syntax_wrapper.py

This file was deleted.

Loading