blob: a8c1253aedbb756cd91a8a21fd08014370a13504 [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 Phanbabf2962021-07-07 11:24:40 -050010import time
Peter D Phan72ce6b82021-06-03 06:18:26 -050011import socket
Peter D Phane86d9a52021-07-15 10:42:25 -050012import logging
Peter D Phan72ce6b82021-06-03 06:18:26 -050013from 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
Peter D Phan5963d632021-07-12 09:58:55 -050046 is_ssh_login = True
Peter D Phan72ce6b82021-06-03 06:18:26 -050047 try:
48 # SSHClient to make connections to the remote server
49 self.sshclient = paramiko.SSHClient()
Peter D Phan8462faf2021-06-16 12:24:15 -050050 # setting set_missing_host_key_policy() to allow any host
Peter D Phan72ce6b82021-06-03 06:18:26 -050051 self.sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
52 # Connect to the server
53 self.sshclient.connect(hostname=self.hostname,
54 username=self.username,
George Keishing1c3d86b2021-06-16 22:29:30 -050055 password=self.password,
56 look_for_keys=False)
Peter D Phan72ce6b82021-06-03 06:18:26 -050057
Peter D Phan8462faf2021-06-16 12:24:15 -050058 except (BadHostKeyException, AuthenticationException,
59 SSHException, NoValidConnectionsError, socket.error) as e:
Peter D Phan5963d632021-07-12 09:58:55 -050060 is_ssh_login = False
61
62 return is_ssh_login
Peter D Phan72ce6b82021-06-03 06:18:26 -050063
64 def ssh_remoteclient_disconnect(self):
65
66 r"""
67 Clean up.
68 """
69
70 if self.sshclient:
71 self.sshclient.close()
72
73 if self.scpclient:
74 self.scpclient.close()
75
Peter D Phan3beb02e2021-07-06 13:25:17 -050076 def execute_command(self, command, default_timeout=60):
Peter D Phan72ce6b82021-06-03 06:18:26 -050077 """
78 Execute command on the remote host.
79
80 Description of argument(s):
81 command Command string sent to remote host
82
83 """
84
Peter D Phanbabf2962021-07-07 11:24:40 -050085 empty = ''
86 cmd_start = time.time()
Peter D Phan72ce6b82021-06-03 06:18:26 -050087 try:
Peter D Phanbabf2962021-07-07 11:24:40 -050088 stdin, stdout, stderr = \
89 self.sshclient.exec_command(command, timeout=default_timeout)
90 start = time.time()
91 while time.time() < start + default_timeout:
92 if stdout.channel.exit_status_ready():
93 break
94 time.sleep(1)
95
96 return stderr.readlines(), stdout.readlines()
97
Peter D Phan72ce6b82021-06-03 06:18:26 -050098 except (paramiko.AuthenticationException, paramiko.SSHException,
Peter D Phanbabf2962021-07-07 11:24:40 -050099 paramiko.ChannelException, SocketTimeout) as e:
Peter D Phan8462faf2021-06-16 12:24:15 -0500100 # Log command with error. Return to caller for next command, if any.
Peter D Phane86d9a52021-07-15 10:42:25 -0500101 logging.error("\n>>>>>\tERROR: Fail remote command %s %s" % (e.__class__, e))
102 logging.error(">>>>>\tCommand '%s' Elapsed Time %s" %
103 (command, time.strftime("%H:%M:%S", time.gmtime(time.time() - cmd_start))))
Peter D Phanbabf2962021-07-07 11:24:40 -0500104 return empty, empty
Peter D Phan72ce6b82021-06-03 06:18:26 -0500105
106 def scp_connection(self):
107
108 r"""
109 Create a scp connection for file transfer.
110 """
Peter D Phan733df632021-06-17 13:13:36 -0500111 try:
Peter D Phan56429a62021-06-23 08:38:29 -0500112 self.scpclient = SCPClient(self.sshclient.get_transport(), sanitize=lambda x: x)
Peter D Phane86d9a52021-07-15 10:42:25 -0500113 logging.info("\n\t[Check] %s SCP transport established.\t [OK]" % self.hostname)
Peter D Phan733df632021-06-17 13:13:36 -0500114 except (SCPException, SocketTimeout, PipeTimeout) as e:
115 self.scpclient = None
Peter D Phane86d9a52021-07-15 10:42:25 -0500116 logging.error("\n>>>>>\tERROR: SCP get_transport has failed. %s %s" % (e.__class__, e))
117 logging.info(">>>>>\tScript continues generating FFDC on %s." % self.hostname)
118 logging.info(">>>>>\tCollected data will need to be manually offloaded.")
Peter D Phan72ce6b82021-06-03 06:18:26 -0500119
120 def scp_file_from_remote(self, remote_file, local_file):
121
122 r"""
123 scp file in remote system to local with date-prefixed filename.
124
125 Description of argument(s):
126 remote_file Full path filename on the remote host
127
128 local_file Full path filename on the local host
129 local filename = date-time_remote filename
130
131 """
132
133 try:
Peter D Phan56429a62021-06-23 08:38:29 -0500134 self.scpclient.get(remote_file, local_file, recursive=True)
Peter D Phan733df632021-06-17 13:13:36 -0500135 except (SCPException, SocketTimeout, PipeTimeout) as e:
Peter D Phan8462faf2021-06-16 12:24:15 -0500136 # Log command with error. Return to caller for next file, if any.
Peter D Phane86d9a52021-07-15 10:42:25 -0500137 logging.error(
138 "\n>>>>>\tERROR: Fail scp %s from remotehost %s %s\n\n" % (remote_file, e.__class__, e))
Peter D Phan72ce6b82021-06-03 06:18:26 -0500139 return False
140
141 # Return True for file accounting
142 return True