Repository: ManageIQ/integration_tests

Issue:
Add SCP support
The ssh_client fixture supports running a rake command. Some of these commands presuppose a local file exists on the appliance, such as when importing an Automate custom namespace. Extending ssh_client would be ideal.

Here's my os.system hack:

```
import os
...
os.system("sshpass -p '%s' scp %s@%s:/root/" % \
            (mozwebqa.credentials['ssh']['password'],      
             mozwebqa.credentials['ssh']['username'], 
             soap_client.evm_server_hostname))
```



Discussion:

Resolving patch:
diff --git a/utils/ssh.py b/utils/ssh.py
--- a/utils/ssh.py
+++ b/utils/ssh.py
@@ -1,4 +1,5 @@
 import paramiko
+from scp import SCPClient
 
 class SSHClient(paramiko.SSHClient):
     """paramiko.SSHClient wrapper
@@ -15,6 +16,8 @@ def __init__(self, **connect_kwargs):
             connect_kwargs['timeout'] = 10
         if 'allow_agent' not in connect_kwargs:
             connect_kwargs['allow_agent'] = False
+        if 'look_for_keys' not in connect_kwargs:
+            connect_kwargs['look_for_keys'] = False
         self._connect_kwargs = connect_kwargs
 
     def __call__(self, **connect_kwargs):
@@ -41,6 +44,11 @@ def run_rails_command(self, command):
     def run_rake_command(self, command):
         return rake_runner(self, command)
 
+    def put_file(self, local_file, remote_file = '.'):
+        return scp_putter(self, local_file, remote_file)
+
+    def get_file(self, remote_file, local_path = ''):
+        return scp_getter(self, remote_file, local_path)
 
 def command_runner(client, command):
     template = '%s\n'
@@ -65,3 +73,13 @@ def rake_runner(client, command):
     template = '/var/www/miq/vmdb/script/rake -f /var/www/miq/vmdb/Rakefile %s'
     return rails_runner(client, template % command)
 
+def scp_putter(client, local_file, remote_file):
+    with client as ctx:
+        transport = ctx.get_transport()
+        SCPClient(transport).put(local_file, remote_file)
+
+def scp_getter(client, remote_file, local_path):
+    with client as ctx:
+        transport = ctx.get_transport()
+        SCPClient(transport).get(remote_file, local_path)
+


Test patch:
diff --git a/utils/tests/test_ssh_client.py b/utils/tests/test_ssh_client.py
--- a/utils/tests/test_ssh_client.py
+++ b/utils/tests/test_ssh_client.py
@@ -12,7 +12,7 @@ def test_ssh_client_run_command(ssh_client):
     # Make sure the ssh command runner works
     exit_status, output = ssh_client.run_command('echo Testing!')
     Assert.equal(exit_status, 0)
-    Assert.contains(output, 'Testing!')
+    Assert.contains('Testing!', output)
 
 def test_ssh_client_copies(ssh_client):
     ssh_client_kwargs = {
@@ -36,3 +36,16 @@ def test_ssh_client_copies(ssh_client):
     Assert.equal(orig_kwargs['password'], copy_kwargs['password'])
     Assert.not_equal(orig_kwargs['hostname'], copy_kwargs['hostname'])
 
+def test_scp_client_can_put_a_file(ssh_client, tmpdir):
+    # Make sure we can put a file, get a file, and they all match
+    tmpfile = tmpdir.mkdir("sub").join("temp.txt")
+    tmpfile.write("content")
+    ssh_client.put_file(str(tmpfile), '/tmp')
+    exit_status, output = ssh_client.run_command(
+            "ls /tmp/%s" % tmpfile.basename)
+    Assert.equal(exit_status, 0)
+    Assert.contains(tmpfile.basename, output)
+    ssh_client.get_file("/tmp/%s" % tmpfile.basename, str(tmpdir))
+    Assert.contains("content", tmpfile.read())
+    # Clean up the server
+    ssh_client.run_command("rm -f /tmp/%s" % tmpfile.basename)
\ No newline at end of file