Peter D Phan | 72ce6b8 | 2021-06-03 06:18:26 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | import paramiko |
| 4 | from paramiko.ssh_exception import AuthenticationException, NoValidConnectionsError, SSHException |
| 5 | from paramiko.buffered_pipe import PipeTimeout as PipeTimeout |
| 6 | import scp |
| 7 | import socket |
| 8 | from socket import timeout as SocketTimeout |
| 9 | |
| 10 | |
| 11 | class SSHRemoteclient: |
| 12 | r""" |
| 13 | Class to create ssh connection to remote host |
| 14 | for remote host command execution and scp. |
| 15 | """ |
| 16 | |
| 17 | def __init__(self, hostname, username, password): |
| 18 | |
| 19 | r""" |
| 20 | Description of argument(s): |
| 21 | |
George Keishing | 7bc01e9 | 2021-06-15 11:07:14 -0500 | [diff] [blame^] | 22 | hostname name/ip of the remote (targeting) host |
Peter D Phan | 72ce6b8 | 2021-06-03 06:18:26 -0500 | [diff] [blame] | 23 | username user on the remote host with access to FFCD files |
| 24 | password password for user on remote host |
| 25 | """ |
| 26 | |
| 27 | self.ssh_output = None |
| 28 | self.ssh_error = None |
| 29 | self.sshclient = None |
| 30 | self.scpclient = None |
| 31 | self.hostname = hostname |
| 32 | self.username = username |
| 33 | self.password = password |
| 34 | |
| 35 | def ssh_remoteclient_login(self): |
| 36 | |
| 37 | r""" |
| 38 | Method to create a ssh connection to remote host. |
| 39 | """ |
| 40 | |
| 41 | try: |
| 42 | # SSHClient to make connections to the remote server |
| 43 | self.sshclient = paramiko.SSHClient() |
| 44 | # setting set_missing_host_key_policy() to allow any host. |
| 45 | self.sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |
| 46 | # Connect to the server |
| 47 | self.sshclient.connect(hostname=self.hostname, |
| 48 | username=self.username, |
| 49 | password=self.password) |
| 50 | |
| 51 | except AuthenticationException: |
| 52 | print("\n>>>>>\tERROR: Authentication failed, please verify your login credentials") |
| 53 | except SSHException: |
| 54 | print("\n>>>>>\tERROR: Failures in SSH2 protocol negotiation or logic errors.") |
| 55 | except NoValidConnectionsError: |
| 56 | print('\n>>>>>\tERROR: No Valid SSH Connection after multiple attempts.') |
| 57 | except socket.error: |
| 58 | print("\n>>>>>\tERROR: SSH Connection refused.") |
| 59 | except Exception: |
| 60 | raise Exception("\n>>>>>\tERROR: Unexpected Exception.") |
| 61 | |
| 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 | |
| 74 | def execute_command(self, command): |
| 75 | """ |
| 76 | Execute command on the remote host. |
| 77 | |
| 78 | Description of argument(s): |
| 79 | command Command string sent to remote host |
| 80 | |
| 81 | """ |
| 82 | |
| 83 | try: |
| 84 | stdin, stdout, stderr = self.sshclient.exec_command(command) |
| 85 | stdout.channel.recv_exit_status() |
| 86 | response = stdout.readlines() |
| 87 | return response |
| 88 | except (paramiko.AuthenticationException, paramiko.SSHException, |
| 89 | paramiko.ChannelException) as ex: |
| 90 | print("\n>>>>>\tERROR: Remote command execution fails.") |
| 91 | |
| 92 | def scp_connection(self): |
| 93 | |
| 94 | r""" |
| 95 | Create a scp connection for file transfer. |
| 96 | """ |
| 97 | self.scpclient = scp.SCPClient(self.sshclient.get_transport()) |
| 98 | |
| 99 | def scp_file_from_remote(self, remote_file, local_file): |
| 100 | |
| 101 | r""" |
| 102 | scp file in remote system to local with date-prefixed filename. |
| 103 | |
| 104 | Description of argument(s): |
| 105 | remote_file Full path filename on the remote host |
| 106 | |
| 107 | local_file Full path filename on the local host |
| 108 | local filename = date-time_remote filename |
| 109 | |
| 110 | """ |
| 111 | |
| 112 | try: |
| 113 | self.scpclient.get(remote_file, local_file) |
| 114 | except scp.SCPException: |
| 115 | print("scp.SCPException scp %s from remotehost" % remote_file) |
| 116 | return False |
| 117 | except (SocketTimeout, PipeTimeout) as ex: |
| 118 | # Future enhancement: multiple retries on these exceptions due to bad ssh connection |
| 119 | print("Timeout scp %s from remotehost" % remote_file) |
| 120 | return False |
| 121 | |
| 122 | # Return True for file accounting |
| 123 | return True |