Telnet 设备自动化
Telnet device automation
我尝试使用 telnet 协议连接到 python 设备以进行一些自动化操作(例如一些旧的 Cisco 路由器),
为此,我正在使用 Napalm 库(基于基于 telnetlib 库的 Napalm 库)
问题是当我直接使用 telnetlib 库时它工作正常,但是当我使用 Napalm 或
Netmiko 它给出了这个错误:获取 Telnet 登录失败。
有没有人遇到过这种情况?
PS: 我尝试了一些在互联网上找到的解决方案,但没有任何效果。
提前致谢。
此代码有效(telnetlib 库):
import telnetlib
import time
from pprint import pprint
def to_bytes(line):
return f"{line}\n".encode("utf-8")
def send_show_command(ip, username, password, enable, commands):
with telnetlib.Telnet(ip) as telnet:
telnet.read_until(b"Username")
telnet.write(to_bytes(username))
telnet.read_until(b"Password")
telnet.write(to_bytes(password))
index, m, output = telnet.expect([b">", b"#"])
if index == 0:
telnet.write(b"enable\n")
telnet.read_until(b"Password")
telnet.write(to_bytes(enable))
telnet.read_until(b"#", timeout=5)
telnet.write(b"terminal length 0\n")
telnet.read_until(b"#", timeout=5)
time.sleep(3)
telnet.read_very_eager()
result = {}
for command in commands:
telnet.write(to_bytes(command))
output = telnet.read_until(b"#", timeout=5).decode("utf-8")
result[command] = output.replace("\r\n", "\n")
return result
if __name__ == "__main__":
devices = ["1.1.1.1"]
commands = ["sh ip int br"]
for ip in devices:
result = send_show_command(ip, "username", "password", "", commands)
pprint(result, width=120)
此代码return登录错误(napalm库):
from napalm import get_network_driver
from pprint import pprint
driver = get_network_driver('ios')
conn_method = {'port': 23, 'transport': 'telnet', 'global_delay_factor': 2, 'secret': ''}
host = '1.1.1.1'
user = 'username'
passwd = 'password'
with driver(hostname=host, username=user, password=passwd, optional_args=conn_method ) as device:
print('Getting facts')
pprint(device.get_facts())
此代码return登录错误(netmiko库):
import os
from netmiko import ConnectHandler
switch = {
'device_type': 'cisco_ios_telnet',
'ip': '1.1.1.1',
"username": "username",
"password": "password",
"timeout": 15
}
net_connect = ConnectHandler(**switch)
print(net_connect)
正如您已经提到的,NAPALM
使用 telnetlib
进行 telnet 连接。但是它在 netmiko
.
的帮助下使用它
关于您的问题,该问题可能是由于以下因素引起的:
- 连接超时
- 认证超时
尝试在conn_method
变量中添加conn_timeout: 30
和auth_timeout: 30
(以30秒为例)为您的申请留出时间连接并验证网络设备。
还建议将 fast_cli
设置为 False
(默认值为 True
)。 fast_cli
只是将 延迟因子 乘以 0.1。因此,如果您的延迟因子为 1(100 秒),则意味着应用程序只有 10 秒的时间来抓取远程网络设备上发生的事情,这在某些情况下并不总是足够的。 此行为仅在使用 CiscoBaseConnection
.
的情况下
For BaseConnection
, fast_cli
default value is False
.
这是您案例的完整工作演示
from pprint import pprint
from napalm import get_network_driver
driver = get_network_driver("ios")
creds = {
"hostname": "192.168.1.150",
"username": "cisco",
"password": "cisco",
}
optionals = {
"transport": "telnet", # no need for port 23. It implicilty knows what port to set
"secret": "",
"conn_timeout": 30,
"auth_timeout": 30,
"fast_cli": False, # no need for global_delay_factor now in case of get_facts() only
}
with driver(**creds, optional_args=optionals) as device:
print("Port:", device.device.port) # prints 23
print("Parsing facts...")
facts = device.get_facts()
pprint(facts)
我尝试使用 telnet 协议连接到 python 设备以进行一些自动化操作(例如一些旧的 Cisco 路由器), 为此,我正在使用 Napalm 库(基于基于 telnetlib 库的 Napalm 库)
问题是当我直接使用 telnetlib 库时它工作正常,但是当我使用 Napalm 或 Netmiko 它给出了这个错误:获取 Telnet 登录失败。
有没有人遇到过这种情况?
PS: 我尝试了一些在互联网上找到的解决方案,但没有任何效果。
提前致谢。
此代码有效(telnetlib 库):
import telnetlib
import time
from pprint import pprint
def to_bytes(line):
return f"{line}\n".encode("utf-8")
def send_show_command(ip, username, password, enable, commands):
with telnetlib.Telnet(ip) as telnet:
telnet.read_until(b"Username")
telnet.write(to_bytes(username))
telnet.read_until(b"Password")
telnet.write(to_bytes(password))
index, m, output = telnet.expect([b">", b"#"])
if index == 0:
telnet.write(b"enable\n")
telnet.read_until(b"Password")
telnet.write(to_bytes(enable))
telnet.read_until(b"#", timeout=5)
telnet.write(b"terminal length 0\n")
telnet.read_until(b"#", timeout=5)
time.sleep(3)
telnet.read_very_eager()
result = {}
for command in commands:
telnet.write(to_bytes(command))
output = telnet.read_until(b"#", timeout=5).decode("utf-8")
result[command] = output.replace("\r\n", "\n")
return result
if __name__ == "__main__":
devices = ["1.1.1.1"]
commands = ["sh ip int br"]
for ip in devices:
result = send_show_command(ip, "username", "password", "", commands)
pprint(result, width=120)
此代码return登录错误(napalm库):
from napalm import get_network_driver
from pprint import pprint
driver = get_network_driver('ios')
conn_method = {'port': 23, 'transport': 'telnet', 'global_delay_factor': 2, 'secret': ''}
host = '1.1.1.1'
user = 'username'
passwd = 'password'
with driver(hostname=host, username=user, password=passwd, optional_args=conn_method ) as device:
print('Getting facts')
pprint(device.get_facts())
此代码return登录错误(netmiko库):
import os
from netmiko import ConnectHandler
switch = {
'device_type': 'cisco_ios_telnet',
'ip': '1.1.1.1',
"username": "username",
"password": "password",
"timeout": 15
}
net_connect = ConnectHandler(**switch)
print(net_connect)
正如您已经提到的,NAPALM
使用 telnetlib
进行 telnet 连接。但是它在 netmiko
.
关于您的问题,该问题可能是由于以下因素引起的:
- 连接超时
- 认证超时
尝试在conn_method
变量中添加conn_timeout: 30
和auth_timeout: 30
(以30秒为例)为您的申请留出时间连接并验证网络设备。
还建议将 fast_cli
设置为 False
(默认值为 True
)。 fast_cli
只是将 延迟因子 乘以 0.1。因此,如果您的延迟因子为 1(100 秒),则意味着应用程序只有 10 秒的时间来抓取远程网络设备上发生的事情,这在某些情况下并不总是足够的。 此行为仅在使用 CiscoBaseConnection
.
For
BaseConnection
,fast_cli
default value isFalse
.
这是您案例的完整工作演示
from pprint import pprint
from napalm import get_network_driver
driver = get_network_driver("ios")
creds = {
"hostname": "192.168.1.150",
"username": "cisco",
"password": "cisco",
}
optionals = {
"transport": "telnet", # no need for port 23. It implicilty knows what port to set
"secret": "",
"conn_timeout": 30,
"auth_timeout": 30,
"fast_cli": False, # no need for global_delay_factor now in case of get_facts() only
}
with driver(**creds, optional_args=optionals) as device:
print("Port:", device.device.port) # prints 23
print("Parsing facts...")
facts = device.get_facts()
pprint(facts)