Fix using key for ssh

Before this fix manila used only password or private key from default
.ssh directory. In this patch, calling the create function will use
one of this methods for authentication. Authentication is attempted
in the following order of priority:
* The private key;
* Any key we can find through an SSH agent;
* Any "id_rsa" or "id_dsa" key discoverable in ~/.ssh/;
* Plain username/password auth.

Change-Id: I74e00dabe5b5a93fb4fbbdcfef4969971af6d0a7
Closes-Bug: #1369913
This commit is contained in:
Vladimir Vechkanov 2014-09-18 08:14:51 -04:00
parent 4d439987bf
commit 3d47181a2e
2 changed files with 42 additions and 14 deletions

View File

@ -656,6 +656,39 @@ class SSHPoolTestCase(test.TestCase):
self.assertEqual(first_id, second_id)
paramiko.SSHClient.assert_called_once_with()
def test_create_ssh_with_password(self):
fake_ssh_client = mock.Mock()
ssh_pool = utils.SSHPool("127.0.0.1", 22, 10, "test",
password="test")
with mock.patch.object(paramiko, "SSHClient",
return_value=fake_ssh_client):
ssh_pool.create()
fake_ssh_client.connect.assert_called_once_with(
"127.0.0.1", port=22, username="test",
password="test", pkey=None, timeout=10)
def test_create_ssh_with_key(self):
key = os.path.expanduser("fake_key")
fake_ssh_client = mock.Mock()
ssh_pool = utils.SSHPool("127.0.0.1", 22, 10, "test",
privatekey="fake_key")
with mock.patch.object(paramiko, "SSHClient",
return_value=fake_ssh_client):
with mock.patch.object(paramiko.RSAKey, "from_private_key_file",
return_value=key) as from_private_key_mock:
ssh_pool.create()
from_private_key_mock.assert_called_once_with(key)
fake_ssh_client.connect.assert_called_once_with(
"127.0.0.1", port=22, username="test",
password=None, pkey=key, timeout=10)
def test_create_ssh_with_nothing(self):
ssh_pool = utils.SSHPool("127.0.0.1", 22, 10, "test")
with mock.patch.object(paramiko, "SSHClient"):
self.assertRaises(paramiko.SSHException, ssh_pool.create)
def test_closed_reopend_ssh_connections(self):
with mock.patch.object(paramiko, "SSHClient",
mock.Mock(return_value=FakeSSHClient())):

View File

@ -130,23 +130,18 @@ class SSHPool(pools.Pool):
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
if self.password:
ssh.connect(self.ip,
port=self.port,
username=self.login,
password=self.password,
timeout=self.conn_timeout)
elif self.privatekey:
if self.privatekey:
pkfile = os.path.expanduser(self.privatekey)
privatekey = paramiko.RSAKey.from_private_key_file(pkfile)
ssh.connect(self.ip,
port=self.port,
username=self.login,
pkey=privatekey,
timeout=self.conn_timeout)
else:
self.privatekey = paramiko.RSAKey.from_private_key_file(pkfile)
elif not self.password:
msg = _("Specify a password or private_key")
raise exception.ManilaException(msg)
ssh.connect(self.ip,
port=self.port,
username=self.login,
password=self.password,
pkey=self.privatekey,
timeout=self.conn_timeout)
# Paramiko by default sets the socket timeout to 0.1 seconds,
# ignoring what we set thru the sshclient. This doesn't help for