blob: 56d4dadb3b0c3b887695fe6a5b96f3bc6f289ac7 [file] [log] [blame]
Peter D Phan72ce6b82021-06-03 06:18:26 -05001#!/usr/bin/env python
2
3import paramiko
Peter D Phan8462faf2021-06-16 12:24:15 -05004from paramiko.ssh_exception import AuthenticationException
5from paramiko.ssh_exception import NoValidConnectionsError
6from paramiko.ssh_exception import SSHException
7from paramiko.ssh_exception import BadHostKeyException
Peter D Phan72ce6b82021-06-03 06:18:26 -05008from paramiko.buffered_pipe import PipeTimeout as PipeTimeout
Peter D Phan733df632021-06-17 13:13:36 -05009from scp import SCPClient, SCPException
Peter D Phan8462faf2021-06-16 12:24:15 -050010import sys
Peter D Phanbabf2962021-07-07 11:24:40 -050011import time
Peter D Phan72ce6b82021-06-03 06:18:26 -050012import socket
13from socket import timeout as SocketTimeout
14
15
16class SSHRemoteclient:
17 r"""
18 Class to create ssh connection to remote host
19 for remote host command execution and scp.
20 """
21
22 def __init__(self, hostname, username, password):
23
24 r"""
25 Description of argument(s):
26
Peter D Phan8462faf2021-06-16 12:24:15 -050027 hostname Name/IP of the remote (targeting) host
28 username User on the remote host with access to FFCD files
29 password Password for user on remote host
Peter D Phan72ce6b82021-06-03 06:18:26 -050030 """
31
32 self.ssh_output = None
33 self.ssh_error = None
34 self.sshclient = None
35 self.scpclient = None
36 self.hostname = hostname
37 self.username = username
38 self.password = password
39
40 def ssh_remoteclient_login(self):
41
42 r"""
43 Method to create a ssh connection to remote host.
44 """
45
46 try:
47 # SSHClient to make connections to the remote server
48 self.sshclient = paramiko.SSHClient()
Peter D Phan8462faf2021-06-16 12:24:15 -050049 # setting set_missing_host_key_policy() to allow any host
Peter D Phan72ce6b82021-06-03 06:18:26 -050050 self.sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
51 # Connect to the server
52 self.sshclient.connect(hostname=self.hostname,
53 username=self.username,
George Keishing1c3d86b2021-06-16 22:29:30 -050054 password=self.password,
55 look_for_keys=False)
Peter D Phan72ce6b82021-06-03 06:18:26 -050056
Peter D Phan8462faf2021-06-16 12:24:15 -050057 except (BadHostKeyException, AuthenticationException,
58 SSHException, NoValidConnectionsError, socket.error) as e:
59 print("\n>>>>>\tERROR: Unable to SSH to %s %s %s\n\n" % (self.hostname, e.__class__, e))
60 sys.exit(-1)
Peter D Phan72ce6b82021-06-03 06:18:26 -050061
62 def ssh_remoteclient_disconnect(self):
63
64 r"""
65 Clean up.
66 """
67
68 if self.sshclient:
69 self.sshclient.close()
70
71 if self.scpclient:
72 self.scpclient.close()
73
Peter D Phan3beb02e2021-07-06 13:25:17 -050074 def execute_command(self, command, default_timeout=60):
Peter D Phan72ce6b82021-06-03 06:18:26 -050075 """
76 Execute command on the remote host.
77
78 Description of argument(s):
79 command Command string sent to remote host
80
81 """
82
Peter D Phanbabf2962021-07-07 11:24:40 -050083 empty = ''
84 cmd_start = time.time()
Peter D Phan72ce6b82021-06-03 06:18:26 -050085 try:
Peter D Phanbabf2962021-07-07 11:24:40 -050086 stdin, stdout, stderr = \
87 self.sshclient.exec_command(command, timeout=default_timeout)
88 start = time.time()
89 while time.time() < start + default_timeout:
90 if stdout.channel.exit_status_ready():
91 break
92 time.sleep(1)
93
94 return stderr.readlines(), stdout.readlines()
95
Peter D Phan72ce6b82021-06-03 06:18:26 -050096 except (paramiko.AuthenticationException, paramiko.SSHException,
Peter D Phanbabf2962021-07-07 11:24:40 -050097 paramiko.ChannelException, SocketTimeout) as e:
Peter D Phan8462faf2021-06-16 12:24:15 -050098 # Log command with error. Return to caller for next command, if any.
Peter D Phanbabf2962021-07-07 11:24:40 -050099 print("\n>>>>>\tERROR: Fail remote command %s %s" % (e.__class__, e))
100 print(">>>>>\tCommand '%s' Elapsed Time %s" %
101 (command, time.strftime("%H:%M:%S", time.gmtime(time.time() - cmd_start))))
102 return empty, empty
Peter D Phan72ce6b82021-06-03 06:18:26 -0500103
104 def scp_connection(self):
105
106 r"""
107 Create a scp connection for file transfer.
108 """
Peter D Phan733df632021-06-17 13:13:36 -0500109 try:
Peter D Phan56429a62021-06-23 08:38:29 -0500110 self.scpclient = SCPClient(self.sshclient.get_transport(), sanitize=lambda x: x)
Peter D Phan733df632021-06-17 13:13:36 -0500111 print("\n\t[Check] %s SCP transport established.\t [OK]" % self.hostname)
112 except (SCPException, SocketTimeout, PipeTimeout) as e:
113 self.scpclient = None
114 print("\n>>>>>\tERROR: SCP get_transport has failed. %s %s" % (e.__class__, e))
115 print(">>>>>\tScript continues generating FFDC on %s." % self.hostname)
116 print(">>>>>\tCollected data will need to be manually offloaded.")
Peter D Phan72ce6b82021-06-03 06:18:26 -0500117
118 def scp_file_from_remote(self, remote_file, local_file):
119
120 r"""
121 scp file in remote system to local with date-prefixed filename.
122
123 Description of argument(s):
124 remote_file Full path filename on the remote host
125
126 local_file Full path filename on the local host
127 local filename = date-time_remote filename
128
129 """
130
131 try:
Peter D Phan56429a62021-06-23 08:38:29 -0500132 self.scpclient.get(remote_file, local_file, recursive=True)
Peter D Phan733df632021-06-17 13:13:36 -0500133 except (SCPException, SocketTimeout, PipeTimeout) as e:
Peter D Phan8462faf2021-06-16 12:24:15 -0500134 # Log command with error. Return to caller for next file, if any.
135 print("\n>>>>>\tERROR: Fail scp %s from remotehost %s %s\n\n" % (remote_file, e.__class__, e))
Peter D Phan72ce6b82021-06-03 06:18:26 -0500136 return False
137
138 # Return True for file accounting
139 return True