首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python并行SSH - Netmiko/Napalm - Cisco SMB交换机在发送命令时卡住了

Python并行SSH - Netmiko/Napalm - Cisco SMB交换机在发送命令时卡住了
EN

Stack Overflow用户
提问于 2022-03-27 14:03:40
回答 1查看 1K关注 0票数 0

我试图确定网络交换机的供应商+版本(使用python凝固汽油和并行ssh)(华为VRP5 5/8、Cisco催化剂和Cisco SMB (SF/SG):

代码语言:javascript
复制
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)

代码语言:javascript
复制
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)

谢谢你的任何帮助!

EN

回答 1

Stack Overflow用户

发布于 2022-03-27 14:34:09

看起来提示符没有被正确识别。我对ParallelSSHClient和凝固汽油弹都不太熟悉,但我已经和netmiko合作过了,看上去就像出错的地方。以下是一些步骤,可以帮助您更好地了解正在发生的事情。我怀疑这是提示没有从设备中正确读取。

设置调试和netmiko会话并运行一个简单的命令

代码语言:javascript
复制
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,比如在提示符末尾所期望的内容:

代码语言:javascript
复制
session.send_command('show version', expect_string="#")

如果这得到了一个结果,那么它就是关于如何为这个设备设置提示符。

要查看在提示符中找到了什么:

代码语言:javascript
复制
session.find_prompt()

编辑:

根据您报告的内容,问题似乎是在提示符中包含了控制代码\x1b\[。这可能是可以被禁用的设备本身,但我不熟悉的平台。凝固汽油API不公开netmiko的send_command方法。它还是可以修复的。这个解决方案将是一个黑客,使事情工作,没有任何建议,我建议依赖。

建立一个类来充当您的修复程序。这将使用netmiko会话(device.device)实例化,并将用于替换send_command方法。

代码语言:javascript
复制
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()后面添加以下内容

代码语言:javascript
复制
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中测试的转义代码的行为:

代码语言:javascript
复制
$ 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修复了以下问题:

代码语言:javascript
复制
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值的结果。如果这样做有效,并且您希望迟早会得到结果,那么下面的修复方法要比上面的恶意修复更好。

代码语言:javascript
复制
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()

或者您可以获得司机 (更好的选项,除非这恰好是您已经尝试过的驱动程序)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71637029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档