ktbyers / netmiko

Multi-vendor library to simplify Paramiko SSH connections to network devices
MIT License
3.61k stars 1.31k forks source link

The result of "check_enable_mode" is inaccurated when the device name have "#" character? #3250

Open ousui opened 1 year ago

ousui commented 1 year ago

I hava some cisco_ios like network devices and their hostname contain "#" character (alias: pound key, hash key, hash tag, number sign, # sign),

for example:

  • SWITCH-F1#1
  • ROUTER-F2#3
  • FIREWALL-F3#1

I use salt-statck as netmiko executor to manage network devices.

But this problem has nothing to do with salt-statck.

When salt-statck or scripts call function "check_enable_mode",

it always can found check string ("#") in output, so the result always must be "True"

    def check_enable_mode(self, check_string: str = "") -> bool:
        """Check if in enable mode. Return boolean.

        :param check_string: Identification of privilege mode from device
        :type check_string: str
        """
        self.write_channel(self.RETURN)
        output = self.read_until_prompt(read_entire_line=True)
        return check_string in output

How can I use "check_enable_mode" correct to check enable mode with out modify source code?

All of netmiko versions have this problem.

P.S. Version info:

  • netmiko version: 3.4.0
  • salt version: 3004
  • python version: 3.6.8
  • os version: centos 7

Ref:

JunHCha commented 2 months ago

Although I haven't used 'salt' before, there is a workaround to enter enable mode without calling check_enable_mode. By passing the check_state parameter as False when calling enable, you can bypass the process of determining the current enable mode and force the attempt to enter enable mode. I have also encountered issues with many of netmiko's functionalities due to the presence of '#' in the hostname of my Cisco IOS devices. However, I have been using the aforementioned workaround successfully. If there is a part in the 'salt netmiko module' or your script where you can directly call the enable() method, this workaround might be applicable. Below is an example:

from netmiko import ConnectHandler

connection = ConnectHandler(
    device_type="cisco_ios",
    host="10.1.1.1",
    username="user",
    password="password",
    secret="enable",
    port=22,
)

print(connection.find_prompt())
# My device contains '#' in hostname.
#
# 3F_SWITCH_LAN2_#1>

connection.enable()
print(connection.send_command("show run"))
# It doesn't work.
#
#                        ^
# % Invalid input detected at '^' marker.

connection.enable(check_state=False)
print(connection.send_command("sh run"))
# It works.
#
# Building configuration...
#
# Current configuration : 13819 bytes
# !
# ...
ktbyers commented 2 months ago

I would say you really should change your hostname, you are likely going to have a lot of pain/extra work (if you try and keep the # in your hostname).