blob: 4ffa98fdc79a3ac168221bf00938ac43fda67c5d [file] [log] [blame]
Peter D Phane732f772021-07-01 10:16:35 -05001#!/usr/bin/env python
2
Peter D Phan5963d632021-07-12 09:58:55 -05003
4import time
Peter D Phane732f772021-07-01 10:16:35 -05005import socket
Peter D Phane86d9a52021-07-15 10:42:25 -05006import logging
Peter D Phane732f772021-07-01 10:16:35 -05007import telnetlib
8from collections import deque
9
10
11class TelnetRemoteclient:
12
13 r"""
14 Class to create telnet connection to remote host for command execution.
15 """
16
17 def __init__(self, hostname, username, password, port=23, read_timeout=None):
18
19 r"""
20 Description of argument(s):
21
22 hostname Name/IP of the remote (targeting) host
23 username User on the remote host with access to FFCD files
24 password Password for user on remote host
25 read_timeout New read timeout value to override default one
26 """
27
28 self.hostname = hostname
29 self.username = username
30 self.password = password
31 self.tnclient = None
32 self.port = port
33 self.read_timeout = read_timeout
34
35 def tn_remoteclient_login(self):
36
37 is_telnet = True
38 try:
39 self.tnclient = telnetlib.Telnet(self.hostname, self.port, timeout=15)
40 if b'login:' in self.tnclient.read_until(b'login:', timeout=self.read_timeout):
41 self.tnclient.write(self.username.encode('utf-8') + b"\n")
42
43 if b'Password:' in self.tnclient.read_until(b'Password:', timeout=self.read_timeout):
44 self.tnclient.write(self.password.encode('utf-8') + b"\n")
45
46 n, match, pre_match = \
47 self.tnclient.expect(
48 [b'Login incorrect', b'invalid login name or password.', br'\#', br'\$'],
49 timeout=self.read_timeout)
50 if n == 0 or n == 1:
Peter D Phane86d9a52021-07-15 10:42:25 -050051 logging.error(
George Keishing7bf55092021-07-22 12:33:34 -050052 "\n\tERROR: Telnet Authentication Failed. Check userid and password.\n\n")
Peter D Phane732f772021-07-01 10:16:35 -050053 is_telnet = False
54 else:
55 # login successful
56 self.fifo = deque()
57 else:
58 # Anything else, telnet server is not running
George Keishing7bf55092021-07-22 12:33:34 -050059 logging.error("\n\tERROR: Telnet Connection Refused.\n\n")
Peter D Phane732f772021-07-01 10:16:35 -050060 is_telnet = False
61 else:
62 is_telnet = False
63 except Exception:
64 # Any kind of exception, skip telnet protocol
65 is_telnet = False
66
67 return is_telnet
68
69 def __del__(self):
70 self.tn_remoteclient_disconnect()
71
72 def tn_remoteclient_disconnect(self):
73 try:
74 self.tnclient.close()
75 except Exception:
76 # the telnet object might not exist yet, so ignore this one
77 pass
78
79 def execute_command(self, cmd,
Peter D Phane732f772021-07-01 10:16:35 -050080 i_timeout=300):
81
82 r'''
83 Executes commands on the remote host
84
85 Description of argument(s):
86 cmd Command to run on remote host
87 rtnpartial Set to True to return command output even
88 if we haven't read the command prompt
89 wait_cnt Number of times to check for command output
90 default is 5
91 i_timeout Timeout for command output
92 default is 300 seconds
93 '''
94
95 # Execute the command and read the command output
Peter D Phan5963d632021-07-12 09:58:55 -050096 return_buffer = b''
Peter D Phane732f772021-07-01 10:16:35 -050097 try:
98
Peter D Phane86d9a52021-07-15 10:42:25 -050099 # Do at least one non-blocking read
100 # to flush whatever data is in the read buffer.
101 while self.tnclient.read_very_eager():
102 continue
Peter D Phane732f772021-07-01 10:16:35 -0500103
104 # Execute the command
Peter D Phan5963d632021-07-12 09:58:55 -0500105 self.tnclient.write(cmd.encode('utf-8') + b'\n')
106 time.sleep(i_timeout)
Peter D Phane732f772021-07-01 10:16:35 -0500107
Peter D Phane86d9a52021-07-15 10:42:25 -0500108 local_buffer = b''
109 # Read the command output one block at a time.
Peter D Phan5963d632021-07-12 09:58:55 -0500110 return_buffer = self.tnclient.read_very_eager()
Peter D Phane86d9a52021-07-15 10:42:25 -0500111 while return_buffer:
112 local_buffer = b''.join([local_buffer, return_buffer])
113 time.sleep(3) # let the buffer fill up a bit
114 return_buffer = self.tnclient.read_very_eager()
Peter D Phane732f772021-07-01 10:16:35 -0500115
Peter D Phane732f772021-07-01 10:16:35 -0500116 except (socket.error, EOFError) as e:
117 self.tn_remoteclient_disconnect()
118
119 if str(e).__contains__("Connection reset by peer"):
120 msg = e
121 elif str(e).__contains__("telnet connection closed"):
122 msg = "Telnet connection closed."
123 else:
Peter D Phan5963d632021-07-12 09:58:55 -0500124 msg = "Some other issue.%s %s %s\n\n" % (cmd, e.__class__, e)
Peter D Phane732f772021-07-01 10:16:35 -0500125
Peter D Phane86d9a52021-07-15 10:42:25 -0500126 logging.error("\t\t ERROR %s " % msg)
Peter D Phane732f772021-07-01 10:16:35 -0500127
Peter D Phanb76e1752021-08-03 12:50:05 -0500128 # Return ASCII string data with ending PROMPT stripped
129 return local_buffer.decode('ascii', 'ignore').replace('$ ', '\n')