On 02/29/2016 05:57 PM, Niranjan wrote:
> Greetings,
> 
> Attached wrong patch in my last mail. Request to review the patch 
> attached to this email
> 

Hello,
I've generalized the patch a bit to make it use existing host
attributes, and I added tests.
Could you check if it still works for you?


-- 
Petr Viktorin
From 7f8c83091d52d2aea509f90634ccb7f2b1a880d4 Mon Sep 17 00:00:00 2001
From: Niranjan MR <mrniran...@fedoraproject.org>
Date: Fri, 26 Feb 2016 15:30:25 +0530
Subject: [PATCH] Add support to specify usernames/password per host

Additional generalizations by Petr Viktorin

https://fedorahosted.org/python-pytest-multihost/ticket/5

Signed-off-by: Niranjan MR <mrniran...@fedoraproject.org>
Signed-off-by: Petr Viktorin <pvikt...@redhat.com>
---
 pytest_multihost/host.py               | 21 ++++++++---
 pytest_multihost/transport.py          |  9 +++--
 test_pytestmultihost/test_localhost.py | 65 ++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/pytest_multihost/host.py b/pytest_multihost/host.py
index f3346f6..15fb43c 100644
--- a/pytest_multihost/host.py
+++ b/pytest_multihost/host.py
@@ -27,9 +27,19 @@ class BaseHost(object):
     transport_class = None
 
     def __init__(self, domain, hostname, role, ip=None,
-                 external_hostname=None):
+                 external_hostname=None, username=None, password=None):
         self.domain = domain
         self.role = str(role)
+        if username is None:
+            self.ssh_username = self.config.ssh_username
+        else:
+            self.ssh_username = username
+        if password is None:
+            self.ssh_key_filename = self.config.ssh_key_filename
+            self.ssh_password = self.config.ssh_password
+        else:
+            self.ssh_key_filename = None
+            self.ssh_password = password
 
         shortname, dot, ext_domain = hostname.partition('.')
         self.shortname = shortname
@@ -65,9 +75,6 @@ class BaseHost(object):
                 raise RuntimeError('Could not determine IP address of %s' %
                                    self.external_hostname)
 
-        self.ssh_password = self.config.ssh_password
-        self.ssh_key_filename = self.config.ssh_key_filename
-        self.ssh_username = self.config.ssh_username
         self.host_key = None
         self.ssh_port = 22
 
@@ -109,9 +116,13 @@ class BaseHost(object):
         ip = dct.pop('ip', None)
         external_hostname = dct.pop('external_hostname', None)
 
+        username = dct.pop('username', None)
+        password = dct.pop('password', None)
+
         check_config_dict_empty(dct, 'host %s' % hostname)
 
-        return cls(domain, hostname, role, ip, external_hostname)
+        return cls(domain, hostname, role, ip, external_hostname,
+                   username, password)
 
     def to_dict(self):
         """Export info about this Host to a dict"""
diff --git a/pytest_multihost/transport.py b/pytest_multihost/transport.py
index eda71cd..8a36f02 100644
--- a/pytest_multihost/transport.py
+++ b/pytest_multihost/transport.py
@@ -178,13 +178,16 @@ class ParamikoTransport(Transport):
         self._transport = transport = paramiko.Transport(sock)
         transport.connect(hostkey=host.host_key)
         if host.ssh_key_filename:
-            self.log.debug('Authenticating with private RSA key')
             filename = os.path.expanduser(host.ssh_key_filename)
             key = paramiko.RSAKey.from_private_key_file(filename)
+            self.log.debug(
+                'Authenticating with private RSA key using user %s' %
+                host.ssh_username)
             transport.auth_publickey(username=host.ssh_username, key=key)
         elif host.ssh_password:
-            self.log.debug('Authenticating with password')
-            transport.auth_password(username='root',
+            self.log.debug('Authenticating with password using user %s' %
+                           host.ssh_username)
+            transport.auth_password(username=host.ssh_username,
                                     password=host.ssh_password)
         else:
             self.log.critical('No SSH credentials configured')
diff --git a/test_pytestmultihost/test_localhost.py b/test_pytestmultihost/test_localhost.py
index 265c3b8..0ec8216 100644
--- a/test_pytestmultihost/test_localhost.py
+++ b/test_pytestmultihost/test_localhost.py
@@ -31,6 +31,21 @@ def get_conf_dict():
                         'ip': '127.0.0.1',
                         'role': 'local',
                     },
+                    {
+                        'name': 'localhost',
+                        'external_hostname': 'localhost',
+                        'ip': '127.0.0.1',
+                        'username': '__nonexisting_test_username__',
+                        'role': 'badusername',
+                    },
+                    {
+                        'name': 'localhost',
+                        'external_hostname': 'localhost',
+                        'ip': '127.0.0.1',
+                        'username': 'root',
+                        'password': 'BAD PASSWORD',
+                        'role': 'badpassword',
+                    },
                 ],
             },
         ],
@@ -65,6 +80,42 @@ def multihost(request, transport_class):
     assert isinstance(mh.host.transport, transport_class)
     return mh.install()
 
+@pytest.fixture(scope='class')
+def multihost_baduser(request, transport_class):
+    conf = get_conf_dict()
+    mh = pytest_multihost.make_multihost_fixture(
+        request,
+        descriptions=[
+            {
+                'hosts': {
+                    'badusername': 1,
+                },
+            },
+        ],
+        _config=Config.from_dict(conf),
+    )
+    mh.host = mh.config.domains[0].hosts[0]
+    mh.host.transport_class = transport_class
+    return mh.install()
+
+@pytest.fixture(scope='class')
+def multihost_badpassword(request, transport_class):
+    conf = get_conf_dict()
+    mh = pytest_multihost.make_multihost_fixture(
+        request,
+        descriptions=[
+            {
+                'hosts': {
+                    'badpassword': 1,
+                },
+            },
+        ],
+        _config=Config.from_dict(conf),
+    )
+    mh.host = mh.config.domains[0].hosts[0]
+    mh.host.transport_class = transport_class
+    return mh.install()
+
 
 @contextlib.contextmanager
 def _first_command(host):
@@ -144,3 +195,17 @@ class TestLocalhost(object):
         with _first_command(host):
             host.transport.rmdir(filename)
         assert not os.path.exists(filename)
+
+
+    def test_baduser(self, multihost_baduser, tmpdir):
+        host = multihost_baduser.host
+        if host.transport_class == pytest_multihost.transport.OpenSSHTransport:
+            # Avoid the OpenSSH password prompt
+            return
+        with pytest.raises(AuthenticationException):
+            echo = host.run_command(['echo', 'hello', 'world'])
+
+    def test_badpassword(self, multihost_badpassword, tmpdir):
+        host = multihost_badpassword.host
+        with pytest.raises((AuthenticationException, RuntimeError)):
+            echo = host.run_command(['echo', 'hello', 'world'])
-- 
2.5.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to