我试图确定网络交换机的供应商+版本(使用python凝固汽油和并行ssh)(华为VRP5 5/8、Cisco催化剂和Cisco SMB (SF/SG):
admin@server:~$ python3
Python 3.8.10 (default, Nov 26 2021, 20:14:08)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from napalm import get_network_driver
>>> driver = get_network_driver('ios')
>>> device = driver('ip', 'username', 'password')
>>> device.open()
>>> print(device.get_facts())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/altepro/.local/lib/python3.8/site-packages/napalm/ios/ios.py", line 811, in get_facts
show_ver = self._send_command('show version')
File "/home/altepro/.local/lib/python3.8/site-packages/napalm/ios/ios.py", line 165, in _send_command
output = self.device.send_command(command)
File "/home/altepro/.local/lib/python3.8/site-packages/netmiko/utilities.py", line 600, in wrapper_decorator
return func(self, *args, **kwargs)
File "/home/altepro/.local/lib/python3.8/site-packages/netmiko/base_connection.py", line 1694, in send_command
raise ReadTimeout(msg)
netmiko.exceptions.ReadTimeout:
Pattern not detected: '\x1b\\[Ksg300\\-ab\\-1\\#' in output.
Things you might try to fix this:
1. Explicitly set your pattern using the expect_string argument.
2. Increase the read_timeout to a larger value.其中, of 300-ab-1是交换机的系统名称(本例中为Cisco sg300,但我已经在SMB系列的几个版本和类型上测试了这一点)。
我尝试过的东西:尝试了几种版本的netmiko、凝固汽油(以及它的驱动程序,包括ios-350)和并行-ssh。尝试了几个新的linux服务器,重新安装了凝固汽油弹和并行-ssh。
SSH使用相同的服务器和凭据进行测试,并且没有任何问题。
当我使用并行-ssh时,设备甚至不会引发异常或超时-它只是停留在命令中:
输出= client.run_command(cmd)
hosts = ['192.168.1.50']
client = ParallelSSHClient(hosts, user='my_user', password='my_pass')
cmd = 'show version'
output = client.run_command(cmd)
for host_out in output:
for line in host_out.stdout:
print(line)谢谢你的任何帮助!
发布于 2022-03-27 14:34:09
看起来提示符没有被正确识别。我对ParallelSSHClient和凝固汽油弹都不太熟悉,但我已经和netmiko合作过了,看上去就像出错的地方。以下是一些步骤,可以帮助您更好地了解正在发生的事情。我怀疑这是提示没有从设备中正确读取。
设置调试和netmiko会话并运行一个简单的命令
import logging
import netmiko
logging.basicConfig(level=logging.DEBUG)
session = netmiko.ConnectHandler(
host='192.168.1.50',
username='my_user',
password='my_pass',
device_type='cisco_ios')
results = session.send_command('show version')如果使用相同的错误失败,则是提示符(可能是\x1b转义字符)。再试一次,但是使用一个更简单的expect_string,比如在提示符末尾所期望的内容:
session.send_command('show version', expect_string="#")如果这得到了一个结果,那么它就是关于如何为这个设备设置提示符。
要查看在提示符中找到了什么:
session.find_prompt()编辑:
根据您报告的内容,问题似乎是在提示符中包含了控制代码\x1b\[。这可能是可以被禁用的设备本身,但我不熟悉的平台。凝固汽油API不公开netmiko的send_command方法。它还是可以修复的。这个解决方案将是一个黑客,使事情工作,没有任何建议,我建议依赖。
建立一个类来充当您的修复程序。这将使用netmiko会话(device.device)实例化,并将用于替换send_command方法。
class HackyFix:
def __init__(self, session):
self.session = session
self.original_send_command = session.send_command
def send_command(self, command):
original_prompt = self.session.find_prompt()
fixed_prompt = original_prompt.replace(r"\x1b[", "")
print(
f"send_command intercepted. {original_prompt} replaced with {fixed_prompt}"
)
return self.original_send_command(command, expect_string=fixed_prompt)然后,在您现有的napalm代码中,在device.open()后面添加以下内容
hackyfix = HackyFix(device.device)
device.device.send_command = hackyfix.send_command现在,凝固汽油弹对send_command的所有调用都将经过您的自定义修补程序,它将找到提示符并在将其传递给expect_string之前对其进行修改。
最后一次编辑。
这是一个ANSI逃逸代码,正在被SG300扔进来。具体来说,这就是从光标清除到行尾。。它也是一个带有已知问题的SG300。好消息是有人制造了一个汽油弹司机来支持它。SG300驱动程序和IOS驱动程序之间的一个巨大区别是netmiko device_type是cisco_s300。当使用此device_type时,将针对输出运行strip_ansi_escape_codes。
在bash中测试的转义代码的行为:
$ printf "This gets cleared\r"; code="\x1b[K"; printf "${code}This is what you see\n"
This is what you see您可以验证将cisco_s300设置为device_type修复了以下问题:
session = netmiko.ConnectHandler(
host='192.168.1.50',
username='my_user',
password='my_pass',
device_type='cisco_s300')
results = session.send_command('show version')这应该会给出一个不修改expect_string值的结果。如果这样做有效,并且您希望迟早会得到结果,那么下面的修复方法要比上面的恶意修复更好。
from napalm.ios import IOSDriver
class QuickCiscoSG300Driver(IOSDriver):
def __init__(self, hostname, username, password, timeout=60, optional_args=None):
super().__init__(hostname, username, password, timeout, optional_args)
def open(self):
device_type = "cisco_s300"
self.device = self._netmiko_open(
device_type, netmiko_optional_args=self.netmiko_optional_args
)
device = QuickCiscoSG300Driver("192.168.1.50", "my_user", "my_pass")
device.open()
device.get_facts()或者您可以获得司机 (更好的选项,除非这恰好是您已经尝试过的驱动程序)
https://stackoverflow.com/questions/71637029
复制相似问题