Tes3awy
Tes3awy

Reputation: 2266

Telnetlib doesn't exit on huge output

I am trying to collect show tech-support from multiple devices using telnetlib only. And it works with a tiny issue. It collects the full output of the show tech-support command and exports it to a text file (export_text_support() is a simple with open() statement).

The entire output of the two switches in my lab is 32,768 and 16,325 lines for the show tech-support command. I get the entire output, BUT the tiny issue is that the session is not exited calling tn.write(b"exit\n") upon completion. It exits when exec-timeout is hit on the switch (when the session becomes idle), which is 10 minutes for both switches, not when there is nothing else to read from the tn.

I tried the same code below for shorter outputs like show running-config and I see the #exit (with a blank line at the end) in the file I export.

Short output

...
365 !
366 end
367
368 Switch#
369 Switch#exit
370 

Huge output

....
16321 423 entries printed
16322 
16323 
16324 
16325 Switch#

(As you can notice exit is not seen in the huge output sample and there is no blank line in the end)

This is my snippet

from telnetlib import Telnet


host = ""
username = ""
password = ""

def get_tech_support(host: str) -> None:

    with Telnet(host=host, port=23) as tn:
        # Check for credentials
        if username:
            tn.read_until(b"Username: ")
            tn.write(username.encode("ascii") + b"\n")
        if password:
            tn.read_until(b"Password: ")
            tn.write(password.encode("ascii") + b"\n")
        
        # Some commands
        commands = ["\n", "terminal width 115", "terminal length 0"]
        [tn.write(command.encode("ascii") + b"\n") for command in commands]
        
        # The main command
        cmd = "show tech-support"

        # Send the main command
        tn.write(cmd.encode("ascii") + b"\n")

        hostname = tn.read_until(b"#")

        tn.write(b"\nexit\n")
        command_output = tn.read_all().decode("ascii")

    result = dict(
        ip=host, hostname=hostname, command=cmd, command_output=command_output
    )

    export_tech_support(command_output=result)  # Export the show command output

How can I make the session exits automatically upon completion for verbose outputs and avoid waiting for the exec-timeout to be hit (10 minutes in my case)

Upvotes: 0

Views: 271

Answers (1)

Sachin
Sachin

Reputation: 1704

There is an issue with telnetlib and paramiko when we are extracting large output and configs.

This happens due to the console connection closing while running the script, so you have to look for a solution to maintain the console connection. I would suggest netmiko ,as netmiko version >= 1.0 also has Telnet support now.

For the example , you can check this script:

from pprint import pprint
import yaml
from netmiko import (
    ConnectHandler,
    NetmikoTimeoutException,
    NetmikoAuthenticationException,
)


def send_show_command(device, commands):
    result = {}
    try:
        with ConnectHandler(**device) as ssh:
            ssh.enable()
            for command in commands:
                output = ssh.send_command(command)
                result[command] = output
        return result
    except (NetmikoTimeoutException, NetmikoAuthenticationException) as error:
        print(error)


if __name__ == "__main__":
    device = {
        "device_type": "cisco_ios_telnet", #Refer netmiko device type
        "host": "192.168.100.1",
        "username": "cisco",
        "password": "cisco123",
        "secret": "cisco",  #if not required remove this
    }
    result = send_show_command(device, ["sh clock", "sh ip int br"])
    pprint(result, width=120)

Upvotes: -1

Related Questions