I try to connect to devices with python using telnet protocole to do some automation (for example somes old Cisco routers), For that i am using Napalm library (which based on Napalm library which based on telnetlib library)
The problem is that when i use directly telnetlib library it's works fine, but when i use Napalm or Netmiko it gives this error: get Telnet login failed.
Doeas anyone had this situation before?
PS: i tried some solution find in internet but nothing works.
Thank you in advance.
This code works (telnetlib library):
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)
This code return login error (napalm library):
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())
This code return login error (netmiko library):
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)
As you have already mentioned NAPALM
uses telnetlib
for telnet connections. But it uses it with the help of netmiko
.
Regarding your question, the issue could be raised due to some factors:
Try to add conn_timeout: 30
and auth_timeout: 30
in conn_method
variable (30 seconds is an example) to give time for your application to connect and authenticate to the network device.
Also a recommendation to set fast_cli
to False
(default value is True
). fast_cli
simply multiplies the delay factor by 0.1. So if you have a delay factor of 1 (100 seconds), it means the application has 10 seconds only to screen scrape what is happening on the remote network device which is not always enough in some cases. This behavior is only in the case of using CiscoBaseConnection
.
For
BaseConnection
,fast_cli
default value isFalse
.
Here is a complete working demo of your case
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)