Repository: Juniper/py-junos-eznc

Issue:
Support for private key files in scp.py
As noted [here](https://github.com/Juniper/py-junos-eznc/blob/master/lib/jnpr/junos/utils/scp.py#L77), private key files aren't supported. I need this for a project I am working on.

Is it possible to get this fixed?

Cheers,

Discussion:

Patch:
diff --git a/lib/jnpr/junos/utils/scp.py b/lib/jnpr/junos/utils/scp.py
index adc49fd3..8a150d6c 100644
--- a/lib/jnpr/junos/utils/scp.py
+++ b/lib/jnpr/junos/utils/scp.py
@@ -73,11 +73,8 @@ class SCP(object):
 
         .. note:: This method uses the same username/password authentication
                    credentials as used by :class:`jnpr.junos.device.Device`.
-
-        .. warning:: The :class:`jnpr.junos.device.Device` ``ssh_private_key_file``
-                     option is currently **not** supported.
-
-        .. todo:: add support for ``ssh_private_key_file``.
+                   It can also use ``ssh_private_key_file`` option if provided
+                   to the :class:`jnpr.junos.device.Device` 
 
         :returns: SCPClient object
         """
@@ -92,6 +89,7 @@ class SCP(object):
         # through a jumphost.
 
         config = {}
+        kwargs = {}
         ssh_config = getattr(junos, '_sshconf_path')
         if ssh_config:
             config = paramiko.SSHConfig()
@@ -101,6 +99,9 @@ class SCP(object):
         if config.get("proxycommand"):
             sock = paramiko.proxy.ProxyCommand(config.get("proxycommand"))
 
+        if self._junos._ssh_private_key_file is not None:
+            kwargs['key_filename']=self._junos._ssh_private_key_file
+
         self._ssh.connect(hostname=junos._hostname,
                           port=(
                               22, int(
@@ -108,7 +109,7 @@ class SCP(object):
                               junos._hostname == 'localhost'],
                           username=junos._auth_user,
                           password=junos._auth_password,
-                          sock=sock
+                          sock=sock, **kwargs
                           )
         return SCPClient(self._ssh.get_transport(), **scpargs)
 


Test patch:
diff --git a/tests/unit/utils/test_scp.py b/tests/unit/utils/test_scp.py
index c0ddd22e..d72571c8 100644
--- a/tests/unit/utils/test_scp.py
+++ b/tests/unit/utils/test_scp.py
@@ -99,6 +99,22 @@ class TestScp(unittest.TestCase):
         self.assertEqual(mock_scpclient.mock_calls[0][2]['progress'].__name__,
                          '_scp_progress')
 
+    @patch('ncclient.manager.connect')
+    @patch('paramiko.SSHClient.connect')
+    @patch('scp.SCPClient.put')
+    @patch('scp.SCPClient.__init__')
+    def test_ssh_private_key_file(self, mock_scpclient, mock_put,
+                                  mock_sshclient, mock_ncclient):
+        mock_scpclient.return_value = None
+        package = 'test.tgz'
+        dev = Device(host='1.1.1.1', user='user',
+                     ssh_private_key_file='/Users/test/testkey')
+        dev.open(gather_facts=False)
+        with SCP(dev) as scp:
+            scp.put(package)
+        self.assertEqual(mock_sshclient.mock_calls[0][2]['key_filename'],
+                         '/Users/test/testkey')
+
     @contextmanager
     def capture(self, command, *args, **kwargs):
         out, sys.stdout = sys.stdout, StringIO()