Skip to content

Commit

Permalink
Proposed Cisco WLC fix for session_preparation() problems (#2822)
Browse files Browse the repository at this point in the history
  • Loading branch information
ktbyers authored Jul 6, 2022
1 parent 859b439 commit 330d15e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 39 deletions.
82 changes: 44 additions & 38 deletions netmiko/cisco/cisco_wlc_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@
class CiscoWlcSSH(BaseConnection):
"""Netmiko Cisco WLC support."""

def __init__(self, *args: Any, **kwargs: Any) -> None:
# WLC/AireOS has an issue where you can get "No Existing Session" with
# the default conn_timeout (so increase conn_timeout to 10-seconds).
kwargs.setdefault("conn_timeout", 10)
return super().__init__(*args, **kwargs)
prompt_pattern = r"(?m:[>#]\s*$)" # force re.Multiline

def special_login_handler(self, delay_factor: float = 1.0) -> None:
"""WLC presents with the following on login (in certain OS versions)
Expand All @@ -28,25 +24,51 @@ def special_login_handler(self, delay_factor: float = 1.0) -> None:
Password:****
"""
delay_factor = self.select_delay_factor(delay_factor)
i = 0
time.sleep(delay_factor * 0.5)
output = ""
while i <= 12:
output = self.read_channel()
if output:
if "login as" in output or "User:" in output:
assert isinstance(self.username, str)
self.write_channel(self.username + self.RETURN)
elif "Password" in output:
assert isinstance(self.password, str)
self.write_channel(self.password + self.RETURN)
break
time.sleep(delay_factor * 1)
uname = "User:"
login = "login as"
password = "ssword"
pattern = rf"(?:{uname}|{login}|{password}|{self.prompt_pattern})"

while True:
new_data = self.read_until_pattern(pattern=pattern, read_timeout=25.0)
output += new_data
if re.search(self.prompt_pattern, new_data):
return

if uname in new_data or login in new_data:
assert isinstance(self.username, str)
self.write_channel(self.username + self.RETURN)
elif password in new_data:
assert isinstance(self.password, str)
self.write_channel(self.password + self.RETURN)
else:
# no output read, sleep and go for one more round of read channel
time.sleep(delay_factor * 1.5)
i += 1
msg = f"""
Failed to login to Cisco WLC Device.
Pattern not detected: {pattern}
output:
{output}
"""
raise NetmikoAuthenticationException(msg)

def session_preparation(self) -> None:
"""
Prepare the session after the connection has been established
Cisco WLC uses "config paging disable" to disable paging
"""

# _test_channel_read() will happen in the special_login_handler()
try:
self.set_base_prompt()
except ValueError:
msg = f"Authentication failed: {self.host}"
raise NetmikoAuthenticationException(msg)

self.disable_paging(command="config paging disable")

def send_command_w_enter(self, *args: Any, **kwargs: Any) -> str:
"""
Expand Down Expand Up @@ -145,22 +167,6 @@ def _send_command_w_yes(self, *args: Any, **kwargs: Any) -> str:
output = self.strip_prompt(output)
return output

def session_preparation(self) -> None:
"""
Prepare the session after the connection has been established
Cisco WLC uses "config paging disable" to disable paging
"""
self._test_channel_read(pattern=r"[>#]")

try:
self.set_base_prompt()
except ValueError:
msg = f"Authentication failed: {self.host}"
raise NetmikoAuthenticationException(msg)

self.disable_paging(command="config paging disable")

def cleanup(self, command: str = "logout") -> None:
"""Reset WLC back to normal paging and gracefully close session."""
self.send_command_timing("config paging enable")
Expand Down
2 changes: 1 addition & 1 deletion netmiko/extreme/extreme_ers_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def special_login_handler(self, delay_factor: float = 1.0) -> None:
self.write_channel(self.password + self.RETURN)
else:
msg = f"""
Failed to login to Extreme ERS Devices.
Failed to login to Extreme ERS Device.
Pattern not detected: {pattern}
output:
Expand Down

0 comments on commit 330d15e

Please sign in to comment.