Source code
-import time
-import re
+import re
from netmiko.cisco_base_connection import CiscoBaseConnection, CiscoFileTransfer
class CiscoXrBase(CiscoBaseConnection):
+ def __init__(self, *args, **kwargs):
+ # Cisco NX-OS defaults to fast_cli=True and legacy_mode=False
+ kwargs.setdefault("fast_cli", True)
+ kwargs.setdefault("_legacy_mode", False)
+ return super().__init__(*args, **kwargs)
+
def establish_connection(self):
"""Establish SSH connection to the network device"""
super().establish_connection(width=511, height=511)
def session_preparation(self):
"""Prepare the session after the connection has been established."""
- self._test_channel_read()
- self.set_base_prompt()
- self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ # IOS-XR has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
self.disable_paging()
- # Clear the read buffer
- time.sleep(0.3 * self.global_delay_factor)
- self.clear_buffer()
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
"""IOS-XR requires you not exit from configuration mode."""
@@ -145,17 +150,21 @@ Module netmiko.cisco.cisco_xr
output = output.replace("(admin)", "")
return check_string in output
- def exit_config_mode(self, exit_config="end"):
+ def exit_config_mode(self, exit_config="end", pattern=""):
"""Exit configuration mode."""
output = ""
if self.check_config_mode():
- output = self.send_command_timing(
- exit_config, strip_prompt=False, strip_command=False
- )
- if "Uncommitted changes found" in output:
- output += self.send_command_timing(
- "no", strip_prompt=False, strip_command=False
+ self.write_channel(self.normalize_cmd(exit_config))
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ if self.global_cmd_verify is not False:
+ output += self.read_until_pattern(
+ pattern=re.escape(exit_config.strip())
)
+ if "Uncommitted changes found" in output:
+ self.write_channel(self.normalize_cmd("no\n"))
+ output += self.read_until_pattern(pattern=r"[>#]")
+ if not re.search(pattern, output, flags=re.M):
+ output += self.read_until_pattern(pattern=pattern)
if self.check_config_mode():
raise ValueError("Failed to exit configuration mode")
return output
@@ -229,7 +238,7 @@
class CiscoXrBase
-(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)
+(*args, **kwargs)
-
Base Class for cisco-like behavior.
@@ -366,19 +375,25 @@
Source code
class CiscoXrBase(CiscoBaseConnection):
+ def __init__(self, *args, **kwargs):
+ # Cisco NX-OS defaults to fast_cli=True and legacy_mode=False
+ kwargs.setdefault("fast_cli", True)
+ kwargs.setdefault("_legacy_mode", False)
+ return super().__init__(*args, **kwargs)
+
def establish_connection(self):
"""Establish SSH connection to the network device"""
super().establish_connection(width=511, height=511)
def session_preparation(self):
"""Prepare the session after the connection has been established."""
- self._test_channel_read()
- self.set_base_prompt()
- self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ # IOS-XR has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
self.disable_paging()
- # Clear the read buffer
- time.sleep(0.3 * self.global_delay_factor)
- self.clear_buffer()
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
"""IOS-XR requires you not exit from configuration mode."""
@@ -483,17 +498,21 @@
output = output.replace("(admin)", "")
return check_string in output
- def exit_config_mode(self, exit_config="end"):
+ def exit_config_mode(self, exit_config="end", pattern=""):
"""Exit configuration mode."""
output = ""
if self.check_config_mode():
- output = self.send_command_timing(
- exit_config, strip_prompt=False, strip_command=False
- )
- if "Uncommitted changes found" in output:
- output += self.send_command_timing(
- "no", strip_prompt=False, strip_command=False
+ self.write_channel(self.normalize_cmd(exit_config))
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ if self.global_cmd_verify is not False:
+ output += self.read_until_pattern(
+ pattern=re.escape(exit_config.strip())
)
+ if "Uncommitted changes found" in output:
+ self.write_channel(self.normalize_cmd("no\n"))
+ output += self.read_until_pattern(pattern=r"[>#]")
+ if not re.search(pattern, output, flags=re.M):
+ output += self.read_until_pattern(pattern=pattern)
if self.check_config_mode():
raise ValueError("Failed to exit configuration mode")
return output
@@ -666,23 +685,27 @@ Methods
-def exit_config_mode(self, exit_config='end')
+def exit_config_mode(self, exit_config='end', pattern='')
-
Source code
-def exit_config_mode(self, exit_config="end"):
+def exit_config_mode(self, exit_config="end", pattern=""):
"""Exit configuration mode."""
output = ""
if self.check_config_mode():
- output = self.send_command_timing(
- exit_config, strip_prompt=False, strip_command=False
- )
- if "Uncommitted changes found" in output:
- output += self.send_command_timing(
- "no", strip_prompt=False, strip_command=False
+ self.write_channel(self.normalize_cmd(exit_config))
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ if self.global_cmd_verify is not False:
+ output += self.read_until_pattern(
+ pattern=re.escape(exit_config.strip())
)
+ if "Uncommitted changes found" in output:
+ self.write_channel(self.normalize_cmd("no\n"))
+ output += self.read_until_pattern(pattern=r"[>#]")
+ if not re.search(pattern, output, flags=re.M):
+ output += self.read_until_pattern(pattern=pattern)
if self.check_config_mode():
raise ValueError("Failed to exit configuration mode")
return output
@@ -723,13 +746,13 @@ Methods
Source code
def session_preparation(self):
"""Prepare the session after the connection has been established."""
- self._test_channel_read()
- self.set_base_prompt()
- self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ # IOS-XR has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
self.disable_paging()
- # Clear the read buffer
- time.sleep(0.3 * self.global_delay_factor)
- self.clear_buffer()
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
@@ -907,7 +930,7 @@ Inherited members
Cisco XR SSH driver.
@@ -1104,7 +1127,7 @@ Inherited members
class CiscoXrTelnet
-(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)
+(*args, **kwargs)
Cisco XR Telnet driver.
diff --git a/docs/netmiko/cisco/index.html b/docs/netmiko/cisco/index.html
index 8f748537d..b15d31ee8 100644
--- a/docs/netmiko/cisco/index.html
+++ b/docs/netmiko/cisco/index.html
@@ -31,6 +31,7 @@ Module netmiko.cisco
from netmiko.cisco.cisco_ios import CiscoIosFileTransfer
from netmiko.cisco.cisco_ios import InLineTransfer
from netmiko.cisco.cisco_asa_ssh import CiscoAsaSSH, CiscoAsaFileTransfer
+from netmiko.cisco.cisco_ftd_ssh import CiscoFtdSSH
from netmiko.cisco.cisco_nxos_ssh import CiscoNxosSSH, CiscoNxosFileTransfer
from netmiko.cisco.cisco_xr import CiscoXrSSH, CiscoXrTelnet, CiscoXrFileTransfer
from netmiko.cisco.cisco_wlc_ssh import CiscoWlcSSH
@@ -41,6 +42,7 @@ Module netmiko.cisco
"CiscoIosSSH",
"CiscoIosTelnet",
"CiscoAsaSSH",
+ "CiscoFtdSSH",
"CiscoNxosSSH",
"CiscoXrSSH",
"CiscoXrTelnet",
@@ -64,6 +66,10 @@
Subclass specific to Cisco ASA.
+netmiko.cisco.cisco_ftd_ssh
+
+Subclass specific to Cisco FTD.
+
netmiko.cisco.cisco_ios
@@ -635,6 +641,281 @@ Inherited members
+
+class CiscoFtdSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)
+
+
+Subclass specific to Cisco FTD.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+ :type ip: str
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+ :type host: str
+
+ :param username: Username to authenticate against target device if
+ required.
+ :type username: str
+
+ :param password: Password to authenticate against target device if
+ required.
+ :type password: str
+
+ :param secret: The enable password if target device requires one.
+ :type secret: str
+
+ :param port: The destination port used to connect to the target
+ device.
+ :type port: int or None
+
+ :param device_type: Class selection based on device type.
+ :type device_type: str
+
+ :param verbose: Enable additional messages to standard output.
+ :type verbose: bool
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+ :type global_delay_factor: int
+
+ :param use_keys: Connect to target device using SSH keys.
+ :type use_keys: bool
+
+ :param key_file: Filename path of the SSH key file to use.
+ :type key_file: str
+
+ :param pkey: SSH key object to use.
+ :type pkey: paramiko.PKey
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+ :type passphrase: str
+
+ :param allow_agent: Enable use of SSH key-agent.
+ :type allow_agent: bool
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+ :type ssh_strict: bool
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+ :type system_host_keys: bool
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+ :type alt_host_keys: bool
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+ :type alt_key_file: str
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+ :type ssh_config_file: str
+
+ :param timeout: Connection timeout.
+ :type timeout: float
+
+ :param session_timeout: Set a timeout for parallel requests.
+ :type session_timeout: float
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+ :type auth_timeout: float
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+ :type banner_timeout: float
+
+ :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+ Currently defaults to 0, for backwards compatibility (it will not attempt
+ to keep the connection alive).
+ :type keepalive: int
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+:type default_enter: str
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+:type response_return: str
+ :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+ to select smallest of global and specific. Sets default global_delay_factor to .1
+ (default: False)
+ :type fast_cli: boolean
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+ :type session_log: str
+
+ :param session_log_record_writes: The session log generally only records channel reads due
+ to eliminate command duplication due to command echo. You can enable this if you
+ want to record both channel reads and channel writes in the log (default: False).
+ :type session_log_record_writes: boolean
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+ :type session_log_file_mode: str
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+ :type allow_auto_change: bool
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+ :type encoding: str
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+ :type sock: socket
+
+ :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+ (default: None). Global attribute takes precedence over function `cmd_verify`
+ argument. Value of `None` indicates to use function `cmd_verify` argument.
+ :type global_cmd_verify: bool|None
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+ :type auto_connect: bool
+
+
+Source code
+class CiscoFtdSSH(CiscoSSHConnection):
+ """Subclass specific to Cisco FTD."""
+
+ def session_preparation(self):
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+
+ def send_config_set(self, *args, **kwargs):
+ """Canot change config on FTD via ssh"""
+ raise NotImplementedError
+
+ def enable(self, *args, **kwargs):
+ """No enable mode on firepower ssh"""
+ return ""
+
+ def config_mode(self, *args, **kwargs):
+ """No config mode on firepower ssh"""
+ return ""
+
+ def check_config_mode(self, *args, **kwargs):
+ """No config mode on firepower ssh"""
+ return False
+
+Ancestors
+
+Methods
+
+
+def check_config_mode(self, *args, **kwargs)
+
+-
+
No config mode on firepower ssh
+
+Source code
+def check_config_mode(self, *args, **kwargs):
+ """No config mode on firepower ssh"""
+ return False
+
+
+
+def config_mode(self, *args, **kwargs)
+
+-
+
No config mode on firepower ssh
+
+Source code
+def config_mode(self, *args, **kwargs):
+ """No config mode on firepower ssh"""
+ return ""
+
+
+
+def enable(self, *args, **kwargs)
+
+-
+
No enable mode on firepower ssh
+
+Source code
+def enable(self, *args, **kwargs):
+ """No enable mode on firepower ssh"""
+ return ""
+
+
+
+def send_config_set(self, *args, **kwargs)
+
+-
+
Canot change config on FTD via ssh
+
+Source code
+def send_config_set(self, *args, **kwargs):
+ """Canot change config on FTD via ssh"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self):
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+
+
+
+Inherited members
+
+
class CiscoIosBase
(*args, **kwargs)
@@ -1685,7 +1966,7 @@ Inherited members
class CiscoNxosSSH
-(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)
+(*args, **kwargs)
Base Class for cisco-like behavior.
@@ -1822,16 +2103,22 @@ Inherited members
Source code
class CiscoNxosSSH(CiscoSSHConnection):
+ def __init__(self, *args, **kwargs):
+ # Cisco NX-OS defaults to fast_cli=True and legacy_mode=False
+ kwargs.setdefault("fast_cli", True)
+ kwargs.setdefault("_legacy_mode", False)
+ return super().__init__(*args, **kwargs)
+
def session_preparation(self):
"""Prepare the session after the connection has been established."""
- self._test_channel_read(pattern=r"[>#]")
self.ansi_escape_codes = True
- self.set_base_prompt()
- self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ # NX-OS has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_terminal_width(
+ command="terminal width 511", pattern=r"terminal width 511"
+ )
self.disable_paging()
- # Clear the read buffer
- time.sleep(0.3 * self.global_delay_factor)
- self.clear_buffer()
+ self.set_base_prompt()
def normalize_linefeeds(self, a_string):
"""Convert '\r\n' or '\r\r\n' to '\n, and remove extra '\r's in the text."""
@@ -1890,14 +2177,14 @@ Methods
Source code
def session_preparation(self):
"""Prepare the session after the connection has been established."""
- self._test_channel_read(pattern=r"[>#]")
self.ansi_escape_codes = True
- self.set_base_prompt()
- self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ # NX-OS has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_terminal_width(
+ command="terminal width 511", pattern=r"terminal width 511"
+ )
self.disable_paging()
- # Clear the read buffer
- time.sleep(0.3 * self.global_delay_factor)
- self.clear_buffer()
+ self.set_base_prompt()
@@ -3329,7 +3616,7 @@ Inherited members
Cisco XR SSH driver.
@@ -3526,7 +3813,7 @@ Inherited members
class CiscoXrTelnet
-(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)
+(*args, **kwargs)
Cisco XR Telnet driver.
@@ -3991,6 +4278,7 @@ Index
+
+
+
+
save_config
diff --git a/docs/netmiko/cisco_base_connection.html b/docs/netmiko/cisco_base_connection.html
index 610fb4536..579cd59b8 100644
--- a/docs/netmiko/cisco_base_connection.html
+++ b/docs/netmiko/cisco_base_connection.html
@@ -54,7 +54,7 @@ Module netmiko.cisco_base_connection
"""
return super().check_config_mode(check_string=check_string, pattern=pattern)
- def config_mode(self, config_command="configure terminal", pattern=""):
+ def config_mode(self, config_command="configure terminal", pattern="", re_flags=0):
"""
Enter into configuration mode on remote device.
@@ -62,7 +62,9 @@ Module netmiko.cisco_base_connection
"""
if not pattern:
pattern = re.escape(self.base_prompt[:16])
- return super().config_mode(config_command=config_command, pattern=pattern)
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
def exit_config_mode(self, exit_config="end", pattern="#"):
"""Exit from configuration mode."""
@@ -436,7 +438,7 @@
"""
return super().check_config_mode(check_string=check_string, pattern=pattern)
- def config_mode(self, config_command="configure terminal", pattern=""):
+ def config_mode(self, config_command="configure terminal", pattern="", re_flags=0):
"""
Enter into configuration mode on remote device.
@@ -444,7 +446,9 @@
"""
if not pattern:
pattern = re.escape(self.base_prompt[:16])
- return super().config_mode(config_command=config_command, pattern=pattern)
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
def exit_config_mode(self, exit_config="end", pattern="#"):
"""Exit from configuration mode."""
@@ -712,14 +716,14 @@ Methods