0

I'm trying to loop through some PDU servers to check entries are following our naming conventions.

I'm writing a python script to check all these servers. However, I'm running into a problem where if the server is down, it makes my script error out and fail.

I don't know how to deal with the gaierror I'm getting on some servers that are unreachable or non-existent. I thought I handled it in the "finally" block but apparently not.

Here's my code.

try:
    tn = telnetlib.Telnet()
    tn.open(pdu_host)
    print(tn.read_until(b'Username: '))
    tn.write(PDU_USER + b"\n")
    print(tn.read_until(b'Password: '))
    tn.write(PDU_PASSWORD + b"\n")
    _, _, data = tn.expect([br'Switched .DU:'])
finally:
    # close the connection
    if tn is not None:
        tn.write(b'logout\n')
        print(tn.read_all())
        tn.close()
        print ('logged out')
        time.sleep(2)  # give the connection time to close

It seems like when I get a gaierror, tn is not None and still tries to run the commands in the finally block, which makes my script fail. When I manually try to telnet to the server, it says:

could not resolve serverX/telnet: Name or service not known

How do I handle this error case when my existing code didn't handle it?

EDIT: This is the error I'm getting when running my script.

Traceback (most recent call last):
  File "check_pdu_outlets.py", line 58, in <module>
    tn.write(b'logout\n')
  File "/usr/lib/python2.7/telnetlib.py", line 283, in write
    self.sock.sendall(buffer)
AttributeError: 'NoneType' object has no attribute 'sendall'

When I run the script thru pdb and I step through the code line by line, it says I get the gaierror when it tries to open a non-existent or down server

-> tn.open(pdu_host)
(Pdb) n
gaierror: (-2, 'Name or service not known')
Classified
  • 5,759
  • 18
  • 68
  • 99

1 Answers1

1

A simple way to resolve this is to change your if statement in finally() to check if an open socket exists for the connection.

if tn.get_socket():

If no connection is open, it will return None

Example


from telnetlib import Telnet

tn = Telnet()

print(type(tn.get_socket()))
#<class 'NoneType'>

tn.open('192.168.0.1')

tn.get_socket()
#<socket.socket fd=764, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.1.1', 54489), raddr=('192.168.0.1', 23)>

tn.close()

print(type(tn.get_socket()))
#<class 'NoneType'>

From telnetlib.py:

def get_socket(self):
        """Return the socket object used internally."""
        return self.sock
PacketLoss
  • 5,561
  • 1
  • 9
  • 27
  • I still get a Traceback when I use what you suggested BUT because of your suggestion, I am doing a socket.gethostbyname(pdu_host) check in the try block which seems to make my script work :) Upvote for pointing me in this direction to find a solution :) – Classified Mar 11 '21 at 03:49
  • @Classified You could also check if the socket exists immediately after opening the connection. If it exists, do what you need to do. If not continue looping to the next one. – PacketLoss Mar 11 '21 at 03:58