SSH connection related cleanups

Catching only the SSHException the AuthenticationException is
 a subclass of the SSHException in the ssh.py.

test_connection_auth method changed to exception raiser method, in order
to avid unwanted catch-and-raise-new-exception code from the
RemoteClient.

Use similar ssh connectivity check with the test_network_basic_ops,
as with all other test cases, so using the implicit
connection validation of the RemoteClient.

Improve ssh connection logging by logging the reason of the connection
failure.

Change-Id: Ia2599f7f2c2fdc6fcbf7ad3337d82adcc50e4d16
diff --git a/tempest/common/ssh.py b/tempest/common/ssh.py
index c397b7c..bca2f9e 100644
--- a/tempest/common/ssh.py
+++ b/tempest/common/ssh.py
@@ -23,6 +23,7 @@
 import warnings
 
 from tempest import exceptions
+from tempest.openstack.common import log as logging
 
 
 with warnings.catch_warnings():
@@ -30,6 +31,9 @@
     import paramiko
 
 
+LOG = logging.getLogger(__name__)
+
+
 class Client(object):
 
     def __init__(self, host, username, password=None, timeout=300, pkey=None,
@@ -49,33 +53,44 @@
 
     def _get_ssh_connection(self, sleep=1.5, backoff=1.01):
         """Returns an ssh connection to the specified host."""
-        _timeout = True
         bsleep = sleep
         ssh = paramiko.SSHClient()
         ssh.set_missing_host_key_policy(
             paramiko.AutoAddPolicy())
         _start_time = time.time()
-
-        while not self._is_timed_out(_start_time):
+        if self.pkey is not None:
+            LOG.info("Creating ssh connection to '%s' as '%s'"
+                     " with public key authentication",
+                     self.host, self.username)
+        else:
+            LOG.info("Creating ssh connection to '%s' as '%s'"
+                     " with password %s",
+                     self.host, self.username, str(self.password))
+        attempts = 0
+        while True:
             try:
                 ssh.connect(self.host, username=self.username,
                             password=self.password,
                             look_for_keys=self.look_for_keys,
                             key_filename=self.key_filename,
                             timeout=self.channel_timeout, pkey=self.pkey)
-                _timeout = False
-                break
+                LOG.info("ssh connection to %s@%s sucessfuly created",
+                         self.username, self.host)
+                return ssh
             except (socket.error,
-                    paramiko.AuthenticationException,
                     paramiko.SSHException):
+                attempts += 1
                 time.sleep(bsleep)
                 bsleep *= backoff
-                continue
-        if _timeout:
-            raise exceptions.SSHTimeout(host=self.host,
-                                        user=self.username,
-                                        password=self.password)
-        return ssh
+                if not self._is_timed_out(_start_time):
+                    continue
+                else:
+                    LOG.exception("Failed to establish authenticated ssh"
+                                  " connection to %s@%s after %d attempts",
+                                  self.username, self.host, attempts)
+                    raise exceptions.SSHTimeout(host=self.host,
+                                                user=self.username,
+                                                password=self.password)
 
     def _is_timed_out(self, start_time):
         return (time.time() - self.timeout) > start_time
@@ -144,11 +159,6 @@
         return ''.join(out_data)
 
     def test_connection_auth(self):
-        """Returns true if ssh can connect to server."""
-        try:
-            connection = self._get_ssh_connection()
-            connection.close()
-        except paramiko.AuthenticationException:
-            return False
-
-        return True
+        """Raises an exception when we can not connect to server via ssh."""
+        connection = self._get_ssh_connection()
+        connection.close()