Skip to content

Commit cb5a259

Browse files
authored
Merge branch 'develop' into 2003-fix-nxos-ping
2 parents fdbbf4d + 077be75 commit cb5a259

File tree

106 files changed

+1920
-1787
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+1920
-1787
lines changed

.github/workflows/commit.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
max-parallel: 4
1212
matrix:
13-
python-version: [3.7, 3.8, 3.9, 3.10.9, 3.11]
13+
python-version: [3.8, 3.9, 3.10.9, 3.11, 3.12.0]
1414

1515
steps:
1616
- name: Checkout repository

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ Install
3131
pip install napalm
3232
```
3333

34+
*Note*: Beginning with release 5.0.0 and later, NAPALM offers support for
35+
Python 3.8+ only.
36+
3437
*Note*: Beginning with release 4.0.0 and later, NAPALM offers support for
3538
Python 3.7+ only.
3639

napalm/base/exceptions.py

+4
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ class ConnectionClosedException(ConnectionException):
6767
pass
6868

6969

70+
class UnsupportedVersion(ConnectionException):
71+
pass
72+
73+
7074
class ReplaceConfigException(NapalmException):
7175
pass
7276

napalm/eos/eos.py

+38-55
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,10 @@
4747
ReplaceConfigException,
4848
SessionLockedException,
4949
CommandErrorException,
50+
UnsupportedVersion,
5051
)
5152
from napalm.eos.constants import LLDP_CAPAB_TRANFORM_TABLE
52-
from napalm.eos.pyeapi_syntax_wrapper import Node
5353
from napalm.eos.utils.versions import EOSVersion
54-
from napalm.eos.utils.cli_syntax import cli_convert
5554
import napalm.base.constants as c
5655

5756
# local modules
@@ -123,15 +122,13 @@ def __init__(self, hostname, username, password, timeout=60, optional_args=None)
123122
self.timeout = timeout
124123
self.config_session = None
125124
self.locked = False
126-
self.cli_version = 1
127125

128126
self.platform = "eos"
129127
self.profile = [self.platform]
130128
self.optional_args = optional_args or {}
131129

132130
self.enablepwd = self.optional_args.pop("enable_password", "")
133131
self.eos_autoComplete = self.optional_args.pop("eos_autoComplete", None)
134-
self.fn0039_config = self.optional_args.pop("eos_fn0039_config", False)
135132

136133
# Define locking method
137134
self.lock_disable = self.optional_args.pop("lock_disable", False)
@@ -201,10 +198,6 @@ def open(self):
201198
device_type="arista_eos",
202199
netmiko_optional_args=self.netmiko_optional_args,
203200
)
204-
# let's try to determine if we need to use new EOS cli syntax
205-
sh_ver = self._run_commands(["show version"])
206-
if EOSVersion(sh_ver[0]["version"]) >= EOSVersion("4.23.0"):
207-
self.cli_version = 2
208201
else:
209202
try:
210203
connection = self.transport_class(
@@ -216,22 +209,24 @@ def open(self):
216209
)
217210

218211
if self.device is None:
219-
self.device = Node(connection, enablepwd=self.enablepwd)
212+
self.device = pyeapi.client.Node(
213+
connection, enablepwd=self.enablepwd
214+
)
220215
# does not raise an Exception if unusable
221216

222-
# let's try to determine if we need to use new EOS cli syntax
223-
sh_ver = self.device.run_commands(["show version"])
224-
self.cli_version = (
225-
2 if EOSVersion(sh_ver[0]["version"]) >= EOSVersion("4.23.0") else 1
226-
)
227-
228-
self.device.update_cli_version(self.cli_version)
229217
except ConnectionError as ce:
230218
# and this is raised either if device not avaiable
231219
# either if HTTP(S) agent is not enabled
232220
# show management api http-commands
233221
raise ConnectionException(str(ce))
234222

223+
# endif self.transport
224+
225+
sh_ver = self._run_commands(["show version"])
226+
self._eos_version = EOSVersion(sh_ver[0]["version"])
227+
if self._eos_version < EOSVersion("4.23.0"):
228+
raise UnsupportedVersion(self._eos_version)
229+
235230
def close(self):
236231
"""Implementation of NAPALM method close."""
237232
self.discard_config()
@@ -263,11 +258,6 @@ def is_alive(self):
263258

264259
def _run_commands(self, commands, **kwargs):
265260
if self.transport == "ssh":
266-
if self.fn0039_config:
267-
if isinstance(commands, str):
268-
commands = [cli_convert(commands, self.cli_version)]
269-
else:
270-
commands = [cli_convert(cmd, self.cli_version) for cmd in commands]
271261
ret = []
272262
for command in commands:
273263
if kwargs.get("encoding") == "text":
@@ -463,10 +453,9 @@ def _load_config(self, filename=None, config=None, replace=True):
463453
self._run_commands(
464454
commands,
465455
autoComplete=self.eos_autoComplete,
466-
fn0039_transform=self.fn0039_config,
467456
)
468457
else:
469-
self._run_commands(commands, fn0039_transform=self.fn0039_config)
458+
self._run_commands(commands)
470459
except pyeapi.eapilib.CommandError as e:
471460
self.discard_config()
472461
msg = str(e)
@@ -691,13 +680,16 @@ def get_re_group(res, key, default=None):
691680
except KeyError:
692681
return default
693682

694-
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
683+
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
695684
output_summary_cmds = self._run_commands(
696685
["show ipv6 bgp summary vrf all", "show ip bgp summary vrf all"],
697686
encoding="json",
698687
)
699688
output_neighbor_cmds = self._run_commands(
700-
["show ip " + NEIGHBOR_FILTER, "show ipv6 " + NEIGHBOR_FILTER],
689+
[
690+
"show ip bgp neighbors " + NEIGHBOR_FILTER,
691+
"show ipv6 bgp peers " + NEIGHBOR_FILTER,
692+
],
701693
encoding="text",
702694
)
703695

@@ -831,10 +823,13 @@ def extract_temperature_data(data):
831823
yield name, values
832824

833825
sh_version_out = self._run_commands(["show version"])
834-
is_veos = sh_version_out[0]["modelName"].lower() == "veos"
835-
commands = ["show environment cooling", "show environment temperature"]
826+
is_veos = sh_version_out[0]["modelName"].lower() in ["veos", "ceoslab"]
827+
commands = [
828+
"show system environment cooling",
829+
"show system environment temperature",
830+
]
836831
if not is_veos:
837-
commands.append("show environment power")
832+
commands.append("show system environment power")
838833
fans_output, temp_output, power_output = self._run_commands(commands)
839834
else:
840835
fans_output, temp_output = self._run_commands(commands)
@@ -1527,23 +1522,12 @@ def get_route_to(self, destination="", protocol="", longer=False):
15271522
nexthop_interface_map[nexthop_ip] = next_hop.get("interface")
15281523
metric = route_details.get("metric")
15291524
if _vrf not in vrf_cache.keys():
1530-
if self.cli_version == 1:
1531-
command = "show ip{ipv} bgp {dest} {longer} detail vrf {_vrf}".format(
1532-
ipv=ipv,
1533-
dest=destination,
1534-
longer="longer-prefixes" if longer else "",
1535-
_vrf=_vrf,
1536-
)
1537-
else:
1538-
# Newer EOS can't mix longer-prefix and detail
1539-
command = (
1540-
"show ip{ipv} bgp {dest} {longer} vrf {_vrf}".format(
1541-
ipv=ipv,
1542-
dest=destination,
1543-
longer="longer-prefixes" if longer else "",
1544-
_vrf=_vrf,
1545-
)
1546-
)
1525+
command = "show ip{ipv} bgp {dest} {longer} vrf {_vrf}".format(
1526+
ipv=ipv,
1527+
dest=destination,
1528+
longer="longer-prefixes" if longer else "",
1529+
_vrf=_vrf,
1530+
)
15471531
vrf_cache.update(
15481532
{
15491533
_vrf: self._run_commands([command])[0]
@@ -1656,7 +1640,11 @@ def get_snmp_information(self):
16561640
# Default values
16571641
snmp_dict = {"chassis_id": "", "location": "", "contact": "", "community": {}}
16581642

1659-
commands = ["show snmp chassis", "show snmp location", "show snmp contact"]
1643+
commands = [
1644+
"show snmp v2-mib chassis",
1645+
"show snmp v2-mib location",
1646+
"show snmp v2-mib contact",
1647+
]
16601648
snmp_config = self._run_commands(commands, encoding="json")
16611649
for line in snmp_config:
16621650
for k, v in line.items():
@@ -1691,7 +1679,7 @@ def _sshkey_type(sshkey):
16911679

16921680
users = {}
16931681

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

16971685
for user, user_details in user_items.items():
@@ -1950,7 +1938,7 @@ def _append(bgp_dict, peer_info):
19501938
summary_commands = []
19511939
if not neighbor_address:
19521940
commands.append("show ip bgp neighbors vrf all")
1953-
commands.append("show ipv6 bgp neighbors vrf all")
1941+
commands.append("show ipv6 bgp peers vrf all")
19541942
summary_commands.append("show ip bgp summary vrf all")
19551943
summary_commands.append("show ipv6 bgp summary vrf all")
19561944
else:
@@ -1963,7 +1951,7 @@ def _append(bgp_dict, peer_info):
19631951
commands.append("show ip bgp neighbors %s vrf all" % neighbor_address)
19641952
summary_commands.append("show ip bgp summary vrf all")
19651953
elif peer_ver == 6:
1966-
commands.append("show ipv6 bgp neighbors %s vrf all" % neighbor_address)
1954+
commands.append("show ipv6 bgp peers %s vrf all" % neighbor_address)
19671955
summary_commands.append("show ipv6 bgp summary vrf all")
19681956

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

21712159
def _show_vrf(self):
2172-
if self.cli_version == 2:
2173-
return self._show_vrf_json()
2174-
else:
2175-
return self._show_vrf_text()
2160+
return self._show_vrf_json()
21762161

21772162
def _get_vrfs(self):
21782163
output = self._show_vrf()
21792164

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

2182-
vrfs.append("default")
2183-
21842167
return vrfs
21852168

21862169
def get_network_instances(self, name=""):

napalm/eos/pyeapi_syntax_wrapper.py

-42
This file was deleted.

0 commit comments

Comments
 (0)