Netmiko - 如何保持或断开 telnet 连接?

Netmiko - How to hold or disconnect a telnet connection?

问题

如何保持或断开 telnet 连接而不出错?

情况

我想使用Nornir重新加载路由器,但是触发时,终端会显示错误信息EOFError: telnet connection closed

动作

重装telnet连接后尝试使用r1.close_connections(),但还是触发了之前的EOFError

环境

Python 3.9.6
nornir==3.1.1
nornir-jinja2==0.2.0
nornir-napalm==0.1.2
nornir-netmiko==0.1.1
nornir-rich==0.1.2
nornir-utils==0.1.2
netmiko==3.4.0
nornir-netmiko==0.1.1

预期结果

  1. 重新加载路由器。
    • 触发重载命令时,路由器必须重启系统,因此telnet会话将断开。
  2. 等待路由器重载时间
  3. 显示路由器版本。

执行代码

from time import sleep
from nornir import InitNornir
from nornir_netmiko import netmiko_send_command as send_cmd, netmiko_send_config


def reboot_device(task):
    task.run(
        task=netmiko_send_command,
        use_timing=True,
        command_string="reload",
    )
    task.run(
        task=netmiko_send_command,
        use_timing=True,
        command_string='y',
    )


def main():
    nr = InitNornir(config_file="config.yaml")
    r1 = nr.filter(device_name="R1")
    reload_time = 60

    r1.run(task=reboot_device)
    sleep(reload_time)
    r1.run(
        task=netmiko_send_command,
        use_timing=True,
        command_string="show version"
    )


if __name__ == "__main__":
    main()

错误信息

2022-05-21 18:35:34,126 - nornir.core.task -    ERROR -      start() - Host 'R1': task 'netmiko_send_command' failed with traceback:
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/nornir/core/task.py", line 99, in start
    r = self.task(self, **self.params)
  File "/usr/local/lib/python3.9/site-packages/nornir_netmiko/tasks/netmiko_send_command.py", line 30, in netmiko_send_command
    result = net_connect.send_command_timing(command_string, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/netmiko/utilities.py", line 500, in wrapper_decorator
    return func(self, *args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/netmiko/base_connection.py", line 1303, in send_command_timing
    new_data = self.read_until_pattern(pattern=re.escape(cmd))
  File "/usr/local/lib/python3.9/site-packages/netmiko/base_connection.py", line 655, in read_until_pattern
    return self._read_channel_expect(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/netmiko/base_connection.py", line 589, in _read_channel_expect
    output += self.read_channel()
  File "/usr/local/lib/python3.9/site-packages/netmiko/base_connection.py", line 526, in read_channel
    output = self._read_channel()
  File "/usr/local/lib/python3.9/site-packages/netmiko/base_connection.py", line 508, in _read_channel
    output = self.remote_conn.read_very_eager().decode("utf-8", "ignore")
  File "/usr/local/lib/python3.9/telnetlib.py", line 368, in read_very_eager
    return self.read_very_lazy()
  File "/usr/local/lib/python3.9/telnetlib.py", line 405, in read_very_lazy
    raise EOFError('telnet connection closed')
EOFError: telnet connection closed

我发现问题了,在我执行.send_command('y')之前telnet连接断开,在我的路由中,输入reload命令后如果收到\n就会立即reload系统,所以它在发送 .send_command('y')

后触发了错误
from nornir import InitNornir
from nornir.core.task import Task, Result 
from nornir_netmiko.tasks.netmiko_send_command import netmiko_send_command

def main():
    
    def task_reboot(task):

      task.run(
          task=netmiko_send_command,
          use_timing=True,
          command_string="reload",
       )
       task.host.close_connections()

    nr = InitNornir(config_file="config.yaml")        
    r1 = nr.filter(device_name="R1")

    try:
        r = r1.run(
            task=task_reboot,
        )
    except EOFError:
        r1.close_connections()
        
if __name__ == "__main__":
    main()