Search code examples
pythonansiblesftpparamiko

Pass/fail result for Paramiko SFTPClient get() and put() functions?


I'm writing an Ansible module using Paramiko's SFTPClient class. I have the following code snippets

import paramiko
from ansible.module_utils.basic import *

def get_sftp_client(host, port, user, password):
  # Open a transport
  transport = paramiko.Transport((host,port))
  # Auth    
  transport.connect(None,user,password)
  # Get a client object
  sftp = paramiko.SFTPClient.from_transport(transport)
  return (transport, sftp)

def transfer_file(params):
  has_changed = False
  meta = {"upload": "not yet implemented"}
  user = params['user']
  password = params['password']
  host = params['host']
  port = params['port']
  direction = params['direction']
  src = params['src']
  dest = params['dest']

  transport, sftp = get_sftp_client(host, port, user, password)

  stdout = None
  stderr = None
  if direction == 'download':
    sftp.get(src, dest)
  else:
    sftp.put(src, dest)

  meta = {
    "source": src,
    "destination": dest,
    "direction": direction,
    "stdout": stdout,
    "stderr": stderr
  }

  # Close
  if sftp: sftp.close()
  if transport: transport.close()
  return (has_changed, meta)

def main():
  fields = {
    "user": {"required": True, "type": "str"},
    "password": {"required": True, "type": "str", "no_log": True},
    "host": {"required": True, "type": "str"},
    "port": {"type": "int", "default": 22},
    "direction": {
      "type": "str",
      "choices": ["upload", "download"],
      "default": "upload",
    },
    "src": {"type": "path", "required": True},
    "dest": {"type": "path", "required": True},
  }

  module = AnsibleModule(argument_spec=fields)

  # Do the work
  has_changed, result = transfer_file(module.params)

  module.exit_json(changed=has_changed, meta=result)

if __name__ == '__main__':
    main()

How can I capture the pass/fail result of the get() and put() functions? The docs don't mention the return value for get(), and the return value for put() is an SFTPAttribute class, which I don't need. I just want to know if the transaction passed or failed, and if failed, get the error. Thanks.


Solution

  • The Paramiko SFTPClient.put and .get throw an exception on error.

    If they do not throw, then the transfer succeeded.