예제 #1
0
    def test_019_init_auth_pass_no_key(self, client, policy, logger):
        connect = mock.Mock(
            side_effect=[paramiko.AuthenticationException,
                         mock.Mock()])

        _ssh = mock.Mock()
        _ssh.attach_mock(connect, 'connect')
        client.return_value = _ssh
        key = gen_private_keys(1).pop()

        ssh = exec_helpers.SSHClient(host=host,
                                     auth=exec_helpers.SSHAuth(
                                         username=username,
                                         password=password,
                                         key=key))

        client.assert_called_once()
        policy.assert_called_once()

        logger.assert_has_calls((mock.call.debug(
            'Main key has been updated, public key is: \nNone'), ))

        self.assertEqual(
            ssh.auth,
            exec_helpers.SSHAuth(username=username,
                                 password=password,
                                 keys=[key]))

        sftp = ssh._sftp
        self.assertEqual(sftp, client().open_sftp())

        self.assertEqual(ssh._ssh, client())
예제 #2
0
    def test_014_init_reconnect(self, client, policy, logger):
        """Test reconnect

        :type client: mock.Mock
        :type policy: mock.Mock
        :type logger: mock.Mock
        """
        ssh = exec_helpers.SSHClient(host=host, auth=exec_helpers.SSHAuth())
        client.assert_called_once()
        policy.assert_called_once()

        logger.assert_not_called()

        self.assertEqual(ssh.auth, exec_helpers.SSHAuth())

        sftp = ssh._sftp
        self.assertEqual(sftp, client().open_sftp())

        self.assertEqual(ssh._ssh, client())

        client.reset_mock()
        policy.reset_mock()

        self.assertEqual(ssh.hostname, host)
        self.assertEqual(ssh.port, port)

        ssh.reconnect()

        _ssh = mock.call()

        expected_calls = [
            _ssh.close(),
            _ssh,
            _ssh.set_missing_host_key_policy('AutoAddPolicy'),
            _ssh.connect(
                hostname='127.0.0.1',
                password=None,
                pkey=None,
                port=22,
                username=None,
            ),
        ]
        self.assertIn(expected_calls, client.mock_calls)

        client.assert_called_once()
        policy.assert_called_once()

        logger.assert_not_called()

        self.assertEqual(ssh.auth, exec_helpers.SSHAuth())

        sftp = ssh._sftp
        self.assertEqual(sftp, client().open_sftp())

        self.assertEqual(ssh._ssh, client())
예제 #3
0
    def test_013_init_clear_failed(self, client, policy, logger):
        """Test reconnect

        :type client: mock.Mock
        :type policy: mock.Mock
        :type logger: mock.Mock
        """
        _ssh = mock.Mock()
        _ssh.attach_mock(
            mock.Mock(
                side_effect=[Exception('Mocked SSH close()'),
                             mock.Mock()]), 'close')
        _sftp = mock.Mock()
        _sftp.attach_mock(
            mock.Mock(
                side_effect=[Exception('Mocked SFTP close()'),
                             mock.Mock()]), 'close')
        client.return_value = _ssh
        _ssh.attach_mock(mock.Mock(return_value=_sftp), 'open_sftp')

        with mock.patch('logging.getLogger', autospec=True) as get_logger:
            ssh_logger = get_logger(exec_helpers.SSHClient.__name__)

            ssh = exec_helpers.SSHClient(host=host,
                                         auth=exec_helpers.SSHAuth())
            client.assert_called_once()
            policy.assert_called_once()

            ssh_logger.assert_not_called()

            self.assertEqual(ssh.auth, exec_helpers.SSHAuth())

            sftp = ssh._sftp
            self.assertEqual(sftp, _sftp)

            self.assertEqual(ssh._ssh, _ssh)

            self.assertEqual(ssh.hostname, host)
            self.assertEqual(ssh.port, port)

            ssh_logger.reset_mock()

            ssh.close()

            log = ssh_logger.getChild('{host}:{port}'.format(host=host,
                                                             port=port))
            log.assert_has_calls((
                mock.call.exception('Could not close ssh connection'),
                mock.call.exception('Could not close sftp connection'),
            ))
예제 #4
0
def test_002_equality_copy():
    """Equality is calculated using hash, copy=deepcopy."""
    auth1 = exec_helpers.SSHAuth(username="******")

    auth2 = exec_helpers.SSHAuth(username="******")

    auth3 = exec_helpers.SSHAuth(username="******")

    assert auth1 == auth2
    assert auth1 != auth3
    assert auth3 == copy.copy(auth3)
    assert auth3 is not copy.copy(auth3)
    assert auth3 == copy.deepcopy(auth3)
    assert auth3 is not copy.deepcopy(auth3)
예제 #5
0
    def test_equality_copy(self):
        """Equality is calculated using hash, copy=deepcopy."""
        auth1 = exec_helpers.SSHAuth(username='******', )

        auth2 = exec_helpers.SSHAuth(username='******', )

        auth3 = exec_helpers.SSHAuth(username='******', )

        self.assertEqual(auth1, auth2)
        self.assertNotEqual(auth1, auth3)
        self.assertEqual(auth3, copy.copy(auth3))
        self.assertIsNot(auth3, copy.copy(auth3))
        self.assertEqual(auth3, copy.deepcopy(auth3))
        self.assertIsNot(auth3, copy.deepcopy(auth3))
    def test_mkdir(self, execute, exists, *args):
        exists.side_effect = [False, True]

        dst = "~/tst dir"
        escaped_dst = r"~/tst\ dir"

        # noinspection PyTypeChecker
        ssh = exec_helpers.SSHClient(host=host,
                                     port=port,
                                     auth=exec_helpers.SSHAuth(
                                         username=username, password=password))

        # Path not exists
        # noinspection PyTypeChecker
        ssh.mkdir(dst)
        exists.assert_called_once_with(dst)
        execute.assert_called_once_with(f"mkdir -p {escaped_dst}\n")

        # Path exists
        exists.reset_mock()
        execute.reset_mock()

        # noinspection PyTypeChecker
        ssh.mkdir(dst)
        exists.assert_called_once_with(dst)
        execute.assert_not_called()
예제 #7
0
def test_001_init_checks(run_parameters) -> None:
    """Object create validation."""
    auth = exec_helpers.SSHAuth(**run_parameters)
    int_keys = get_internal_keys(**run_parameters)

    assert auth.username == username
    with contextlib.closing(io.BytesIO()) as tgt:
        auth.enter_password(tgt)
        assert tgt.getvalue(
        ) == f"{run_parameters.get('password', '')}\n".encode("utf-8")

    key = int_keys[0]

    if key is not None:
        assert auth.public_key == gen_public_key(key)
    else:
        assert auth.public_key is None

    _key = None if auth.public_key is None else f"<private for pub: {auth.public_key}>"
    _keys = []
    for k in int_keys:
        if k is key or (k is not None and key is not None and k == key):
            continue
        _keys.append(f"<private for pub: {gen_public_key(k)}>"
                     if k is not None else None)

    assert repr(auth) == (f"{exec_helpers.SSHAuth.__name__}("
                          f"username={auth.username!r}, "
                          f"password=<*masked*>, "
                          f"key={_key}, "
                          f"keys={_keys}, "
                          f"key_filename={auth.key_filename!r}, "
                          f"passphrase=<*masked*>,"
                          f")")
    assert str(auth) == f"{exec_helpers.SSHAuth.__name__} for {auth.username}"
def test_012_re_connect(paramiko_ssh_client, auto_add_policy, ssh_auth_logger):
    """Re-connect."""
    # Test
    ssh = exec_helpers.SSHClient(host=host, auth=exec_helpers.SSHAuth())

    paramiko_ssh_client.reset_mock()
    auto_add_policy.reset_mock()

    ssh.reconnect()

    _ssh = mock.call()

    expected_calls = [
        _ssh.close(),
        _ssh,
        _ssh.set_missing_host_key_policy("AutoAddPolicy"),
        _ssh.connect(hostname="127.0.0.1",
                     password=None,
                     pkey=None,
                     port=22,
                     username=None,
                     key_filename=()),
        _ssh.get_transport(),
        _ssh.get_transport().set_keepalive(1),
    ]

    assert paramiko_ssh_client.mock_calls == expected_calls
예제 #9
0
    def test_022_init_sftp_repair(self, client, policy, logger):
        _sftp = mock.Mock()
        open_sftp = mock.Mock(
            side_effect=[paramiko.SSHException, _sftp, _sftp])

        _ssh = mock.Mock()
        _ssh.attach_mock(open_sftp, 'open_sftp')
        client.return_value = _ssh

        with mock.patch('logging.getLogger', autospec=True) as get_logger:
            ssh_logger = get_logger(exec_helpers.SSHClient.__name__)

            ssh = exec_helpers.SSHClient(
                host=host, auth=exec_helpers.SSHAuth(password=password))

            with self.assertRaises(paramiko.SSHException):
                # pylint: disable=pointless-statement
                # noinspection PyStatementEffect
                ssh._sftp
                # pylint: enable=pointless-statement

            ssh_logger.reset_mock()

            sftp = ssh._sftp
            self.assertEqual(sftp, open_sftp())
            log = ssh_logger.getChild('{host}:{port}'.format(host=host,
                                                             port=port))
            log.assert_has_calls((
                mock.call.debug('SFTP is not connected, try to connect...'), ))
def test_014_sftp_repair(paramiko_ssh_client, auto_add_policy, ssh_auth_logger,
                         get_logger):
    """No sftp available."""
    # Helper code
    _sftp = mock.Mock()
    open_sftp = mock.Mock(side_effect=[paramiko.SSHException, _sftp, _sftp])

    _ssh = mock.Mock()
    _ssh.attach_mock(open_sftp, "open_sftp")
    paramiko_ssh_client.return_value = _ssh

    ssh_logger = get_logger(exec_helpers.SSHClient.__name__)
    log = ssh_logger.getChild(f"{host}:{port}")
    # Test
    ssh = exec_helpers.SSHClient(host=host,
                                 auth=exec_helpers.SSHAuth(password=password))

    with pytest.raises(paramiko.SSHException):
        # noinspection PyStatementEffect
        ssh._sftp  # pylint: disable=pointless-statement

    log.assert_has_calls((
        mock.call.debug("SFTP is not connected, try to connect..."),
        mock.call.warning("SFTP enable failed! SSH only is accessible."),
    ))
    ssh_logger.reset_mock()
    log.reset_mock()

    sftp = ssh._sftp
    assert sftp == open_sftp()
    log.assert_has_calls(
        (mock.call.debug("SFTP is not connected, try to connect..."), ))
def test_010_check_stdin_closed(paramiko_ssh_client, chan_makefile,
                                auto_add_policy, get_logger):
    chan = mock.Mock(makefile=chan_makefile, closed=True)
    chan_makefile.channel = chan
    chan.attach_mock(mock.Mock(return_value=FakeFileStream(*stderr_src)),
                     "makefile_stderr")
    chan.configure_mock(exit_status=0)
    chan.status_event.attach_mock(mock.Mock(return_value=True), "is_set")
    open_session = mock.Mock(return_value=chan)
    transport = mock.Mock()
    transport.attach_mock(open_session, "open_session")
    get_transport = mock.Mock(return_value=transport)
    _ssh = mock.Mock()
    _ssh.attach_mock(get_transport, "get_transport")
    paramiko_ssh_client.return_value = _ssh

    stdin_val = "this is a line"

    ssh = exec_helpers.SSHClient(host=host,
                                 port=port,
                                 auth=exec_helpers.SSHAuth(username=username,
                                                           password=password))
    ssh._execute_async(command=print_stdin, stdin=stdin_val)

    log = get_logger(ssh.__class__.__name__).getChild(f"{host}:{port}")
    log.warning.assert_called_once_with("STDIN Send failed: closed channel")
예제 #12
0
    def test_012_init_context(self, client, policy, logger):
        with exec_helpers.SSHClient(host=host,
                                    auth=exec_helpers.SSHAuth()) as ssh:
            client.assert_called_once()
            policy.assert_called_once()

            logger.assert_not_called()

            self.assertEqual(ssh.auth, exec_helpers.SSHAuth())

            sftp = ssh._sftp
            self.assertEqual(sftp, client().open_sftp())

            self.assertEqual(ssh._ssh, client())

            self.assertEqual(ssh.hostname, host)
            self.assertEqual(ssh.port, port)
def test_010_context(paramiko_ssh_client, auto_add_policy, ssh_auth_logger):
    """Context manager."""
    # Test
    with exec_helpers.SSHClient(host=host, auth=exec_helpers.SSHAuth()) as ssh:
        paramiko_ssh_client.assert_called_once()
        auto_add_policy.assert_called_once()

        ssh_auth_logger.assert_not_called()

        assert ssh.auth == exec_helpers.SSHAuth()

        sftp = ssh._sftp
        assert sftp == paramiko_ssh_client().open_sftp()

        assert ssh._ssh == paramiko_ssh_client()

        assert ssh.hostname == host
        assert ssh.port == port
예제 #14
0
 def test_010_init_auth(self, client, policy, logger):
     self.init_checks(client,
                      policy,
                      logger,
                      host=host,
                      auth=exec_helpers.SSHAuth(
                          username=username,
                          password=password,
                          key=gen_private_keys(1).pop()))
def test_init_base(paramiko_ssh_client, auto_add_policy, run_parameters,
                   ssh_auth_logger):
    """Parametrized validation of SSH client initialization."""
    # Helper code
    _ssh = mock.call
    port = run_parameters.get("port", 22)

    username = run_parameters.get("username", None)
    password = run_parameters.get("password", None)

    auth = run_parameters.get("auth", None)

    # Test
    ssh = exec_helpers.SSHClient(**run_parameters)

    paramiko_ssh_client.assert_called_once()
    auto_add_policy.assert_called_once()

    if auth is None:
        expected_calls = [
            _ssh.set_missing_host_key_policy("AutoAddPolicy"),
            _ssh.connect(hostname=host,
                         password=password,
                         pkey=None,
                         port=port,
                         username=username,
                         key_filename=()),
            _ssh.get_transport(),
            _ssh.get_transport().set_keepalive(1),
        ]

        assert expected_calls == paramiko_ssh_client().mock_calls

        assert ssh.auth == exec_helpers.SSHAuth(username=username,
                                                password=password)
    else:
        ssh_auth_logger.assert_not_called()

    sftp = ssh._sftp
    assert sftp == paramiko_ssh_client().open_sftp()
    assert ssh._ssh == paramiko_ssh_client()
    assert ssh.hostname == host
    assert ssh.port == port
    assert repr(
        ssh) == "{cls}(host={host}, port={port}, auth={auth!r})".format(
            cls=ssh.__class__.__name__,
            host=ssh.hostname,
            port=ssh.port,
            auth=ssh.auth)
    # ssh config for main connection is synchronised with connection parameters
    expected_config_dict = {host: {"hostname": host, "port": ssh.port}}
    if ssh.auth.username:
        expected_config_dict[host]["user"] = ssh.auth.username

    assert ssh.ssh_config[host] == expected_config_dict[host]
    assert ssh.ssh_config == expected_config_dict
    assert ssh.ssh_config[host].hostname == host
def test_011_clear_failed(paramiko_ssh_client, auto_add_policy,
                          ssh_auth_logger, get_logger):
    """TearDown failed."""
    # Helper code
    _ssh = mock.Mock()
    _ssh.attach_mock(
        mock.Mock(side_effect=[Exception("Mocked SSH close()"),
                               mock.Mock()]), "close")
    _sftp = mock.Mock()
    _sftp.attach_mock(
        mock.Mock(side_effect=[Exception("Mocked SFTP close()"),
                               mock.Mock()]), "close")
    _ssh.attach_mock(mock.Mock(return_value=_sftp), "open_sftp")
    paramiko_ssh_client.return_value = _ssh

    ssh_logger = get_logger(exec_helpers.SSHClient.__name__)
    log = ssh_logger.getChild(f"{host}:{port}")

    # Test
    ssh = exec_helpers.SSHClient(host=host, auth=exec_helpers.SSHAuth())

    paramiko_ssh_client.assert_called_once()
    auto_add_policy.assert_called_once()

    ssh_logger.assert_not_called()
    ssh_auth_logger.assert_not_called()

    assert ssh.auth == exec_helpers.SSHAuth()

    sftp = ssh._sftp
    assert sftp == paramiko_ssh_client().open_sftp()

    assert ssh._ssh == paramiko_ssh_client()

    assert ssh.hostname == host
    assert ssh.port == port

    ssh_logger.reset_mock()

    ssh.close()
    log.assert_has_calls(
        (mock.call.exception("Could not close ssh connection"),
         mock.call.exception("Could not close sftp connection")))
예제 #17
0
    def test_015_init_password_required(self, sleep, client, policy, logger):
        connect = mock.Mock(side_effect=paramiko.PasswordRequiredException)
        _ssh = mock.Mock()
        _ssh.attach_mock(connect, 'connect')
        client.return_value = _ssh

        with self.assertRaises(paramiko.PasswordRequiredException):
            exec_helpers.SSHClient(host=host, auth=exec_helpers.SSHAuth())
        logger.assert_has_calls(
            (mock.call.exception('No password has been set!'), ))
    def test_rm_rf(self, execute, *args):
        dst = "~/tst"

        # noinspection PyTypeChecker
        ssh = exec_helpers.SSHClient(host=host,
                                     port=port,
                                     auth=exec_helpers.SSHAuth(
                                         username=username, password=password))

        # Path not exists
        # noinspection PyTypeChecker
        ssh.rm_rf(dst)
        execute.assert_called_once_with(f"rm -rf {dst}")
예제 #19
0
    def test_023_init_memorize(self, Result, client, policy, logger):
        port1 = 2222
        host1 = '127.0.0.2'

        # 1. Normal init
        ssh01 = exec_helpers.SSHClient(host=host)
        ssh02 = exec_helpers.SSHClient(host=host)
        ssh11 = exec_helpers.SSHClient(host=host, port=port1)
        ssh12 = exec_helpers.SSHClient(host=host, port=port1)
        ssh21 = exec_helpers.SSHClient(host=host1)
        ssh22 = exec_helpers.SSHClient(host=host1)

        self.assertTrue(ssh01 is ssh02)
        self.assertTrue(ssh11 is ssh12)
        self.assertTrue(ssh21 is ssh22)
        self.assertFalse(ssh01 is ssh11)
        self.assertFalse(ssh01 is ssh21)
        self.assertFalse(ssh11 is ssh21)

        # 2. Close connections check
        with mock.patch('exec_helpers.ssh_client.SSHClient.close_connections'
                        ) as no_call:
            exec_helpers.SSHClient.close()
            no_call.assert_not_called()
        # Mock returns false-connected state, so we just count close calls

        client().close.assert_has_calls((
            mock.call(),
            mock.call(),
            mock.call(),
        ))

        # change creds
        exec_helpers.SSHClient(host=host,
                               auth=exec_helpers.SSHAuth(username=username))

        # Change back: new connection differs from old with the same creds
        ssh004 = exec_helpers.SSHAuth(host)
        self.assertFalse(ssh01 is ssh004)
예제 #20
0
    def test_016_init_password_broken(self, sleep, client, policy, logger):
        connect = mock.Mock(side_effect=paramiko.PasswordRequiredException)
        _ssh = mock.Mock()
        _ssh.attach_mock(connect, 'connect')
        client.return_value = _ssh

        with self.assertRaises(paramiko.PasswordRequiredException):
            exec_helpers.SSHClient(
                host=host, auth=exec_helpers.SSHAuth(password=password))

        logger.assert_has_calls(
            (mock.call.critical('Unexpected PasswordRequiredException, '
                                'when password is set!'), ))
예제 #21
0
    def test_018_init_auth_impossible_key(self, sleep, client, policy, logger):
        connect = mock.Mock(side_effect=paramiko.AuthenticationException)

        _ssh = mock.Mock()
        _ssh.attach_mock(connect, 'connect')
        client.return_value = _ssh

        with self.assertRaises(paramiko.AuthenticationException):
            exec_helpers.SSHClient(
                host=host,
                auth=exec_helpers.SSHAuth(key=gen_private_keys(1).pop()))

        logger.assert_has_calls((mock.call.exception(
            'Connection using stored authentication info failed!'), ) * 3)
예제 #22
0
    def test_026_init_auth_impossible_key_no_verbose(self, sleep, client,
                                                     policy, logger):
        connect = mock.Mock(side_effect=paramiko.AuthenticationException)

        _ssh = mock.Mock()
        _ssh.attach_mock(connect, 'connect')
        client.return_value = _ssh

        with self.assertRaises(paramiko.AuthenticationException):
            exec_helpers.SSHClient(
                host=host,
                auth=exec_helpers.SSHAuth(key=gen_private_keys(1).pop()),
                verbose=False)

        logger.assert_not_called()
def test_005_auth_impossible_password(paramiko_ssh_client, auto_add_policy,
                                      ssh_auth_logger):
    """Reject password."""
    # Helper code
    connect = mock.Mock(side_effect=paramiko.AuthenticationException)
    _ssh_inst = mock.Mock()
    _ssh_inst.attach_mock(connect, "connect")
    paramiko_ssh_client.return_value = _ssh_inst

    # Test
    with pytest.raises(paramiko.AuthenticationException):
        exec_helpers.SSHClient(host=host,
                               auth=exec_helpers.SSHAuth(password=password))
    ssh_auth_logger.assert_has_calls((mock.call.exception(
        "Connection using stored authentication info failed!"), ))
예제 #24
0
 def test_024_init_memorize_close_unused(self, warn, client, policy,
                                         logger):
     ssh0 = exec_helpers.SSHClient(host=host)
     del ssh0  # remove reference - now it's cached and unused
     client.reset_mock()
     logger.reset_mock()
     # New connection on the same host:port with different auth
     ssh1 = exec_helpers.SSHClient(
         host=host, auth=exec_helpers.SSHAuth(username=username))
     client.assert_has_calls((mock.call().close(), ))
     del ssh1  # remove reference - now it's cached and unused
     client.reset_mock()
     logger.reset_mock()
     exec_helpers.SSHClient._clear_cache()
     client.assert_has_calls((mock.call().close(), ))
def test_002_use_next_key(paramiko_ssh_client, auto_add_policy,
                          ssh_auth_logger):
    """Reject 1 key and use next one."""
    # Helper code
    _ssh = mock.call

    connect = mock.Mock(side_effect=[
        paramiko.AuthenticationException, paramiko.AuthenticationException,
        mock.Mock()
    ])
    _ssh_inst = mock.Mock()
    _ssh_inst.attach_mock(connect, "connect")
    paramiko_ssh_client.return_value = _ssh_inst

    private_keys = gen_private_keys(2)

    # Test
    ssh = exec_helpers.SSHClient(host=host,
                                 auth=exec_helpers.SSHAuth(username=username,
                                                           keys=private_keys))

    paramiko_ssh_client.assert_called_once()
    auto_add_policy.assert_called_once()

    ssh_auth_logger.debug.assert_called_once_with(
        f"Main key has been updated, public key is: \n{ssh.auth.public_key}")

    kwargs_no_key = dict(hostname=host,
                         pkey=None,
                         port=port,
                         username=username,
                         password=None,
                         key_filename=())
    kwargs_key_0 = {key: kwargs_no_key[key] for key in kwargs_no_key}
    kwargs_key_0["pkey"] = private_keys[0]
    kwargs_key_1 = {key: kwargs_no_key[key] for key in kwargs_no_key}
    kwargs_key_1["pkey"] = private_keys[1]

    expected_calls = [
        _ssh.set_missing_host_key_policy("AutoAddPolicy"),
        _ssh.connect(**kwargs_key_0),
        _ssh.connect(**kwargs_key_1),
        _ssh.connect(**kwargs_no_key),
        _ssh.get_transport(),
        _ssh.get_transport().set_keepalive(1),
    ]

    assert expected_calls == paramiko_ssh_client().mock_calls
def test_008_auth_impossible_key_no_verbose(paramiko_ssh_client,
                                            auto_add_policy, ssh_auth_logger):
    """Reject auth without log."""
    # Helper code
    connect = mock.Mock(side_effect=paramiko.AuthenticationException)
    _ssh_inst = mock.Mock()
    _ssh_inst.attach_mock(connect, "connect")
    paramiko_ssh_client.return_value = _ssh_inst

    # Test
    with pytest.raises(paramiko.AuthenticationException):
        exec_helpers.SSHClient(
            host=host,
            auth=exec_helpers.SSHAuth(key=gen_private_keys(1).pop()),
            verbose=False)
    ssh_auth_logger.assert_not_called()
def test_003_password_required(paramiko_ssh_client, auto_add_policy,
                               ssh_auth_logger):
    """No password provided."""
    # Helper code
    connect = mock.Mock(side_effect=paramiko.PasswordRequiredException)
    _ssh_inst = mock.Mock()
    _ssh_inst.attach_mock(connect, "connect")
    paramiko_ssh_client.return_value = _ssh_inst

    private_keys = gen_private_keys(2)

    # Test
    with pytest.raises(paramiko.PasswordRequiredException):
        exec_helpers.SSHClient(host=host,
                               auth=exec_helpers.SSHAuth(username=username,
                                                         keys=private_keys))
    ssh_auth_logger.assert_has_calls(
        (mock.call.exception("No password has been set!"), ))
def test_004_unexpected_password_required(paramiko_ssh_client, auto_add_policy,
                                          ssh_auth_logger):
    """Password available, but requested anyway."""
    # Helper code
    connect = mock.Mock(side_effect=paramiko.PasswordRequiredException)
    _ssh_inst = mock.Mock()
    _ssh_inst.attach_mock(connect, "connect")
    paramiko_ssh_client.return_value = _ssh_inst

    private_keys = gen_private_keys(2)

    # Test
    with pytest.raises(paramiko.PasswordRequiredException):
        exec_helpers.SSHClient(host=host,
                               auth=exec_helpers.SSHAuth(username=username,
                                                         password=password,
                                                         keys=private_keys))
    ssh_auth_logger.assert_has_calls((mock.call.critical(
        "Unexpected PasswordRequiredException, when password is set!"), ))
    def prepare_sftp_file_tests(client):
        _ssh = mock.Mock()
        client.return_value = _ssh
        _sftp = mock.Mock()
        open_sftp = mock.Mock(parent=_ssh, return_value=_sftp)
        _ssh.attach_mock(open_sftp, "open_sftp")

        with mock.patch("exec_helpers._ssh_helpers.SSH_CONFIG_FILE_SYSTEM",
                        autospec=True) as conf_sys, mock.patch(
                            "exec_helpers._ssh_helpers.SSH_CONFIG_FILE_USER",
                            autospec=True) as conf_user:
            conf_sys.exists.return_value = False
            conf_user.exists.return_value = False

            # noinspection PyTypeChecker
            ssh = exec_helpers.SSHClient(host=host,
                                         port=port,
                                         auth=exec_helpers.SSHAuth(
                                             username=username,
                                             password=password))
            return ssh, _sftp
def test_009_auth_pass_no_key(paramiko_ssh_client, auto_add_policy,
                              ssh_auth_logger):
    """Reject key and use password."""
    # Helper code
    connect = mock.Mock(
        side_effect=[paramiko.AuthenticationException,
                     mock.Mock()])
    _ssh_inst = mock.Mock()
    _ssh_inst.attach_mock(connect, "connect")
    paramiko_ssh_client.return_value = _ssh_inst
    key = gen_private_keys(1).pop()

    # Test
    ssh = exec_helpers.SSHClient(host=host,
                                 auth=exec_helpers.SSHAuth(username=username,
                                                           password=password,
                                                           key=key))

    ssh_auth_logger.assert_has_calls((mock.call.debug(
        f"Main key has been updated, public key is: \n{ssh.auth.public_key}"),
                                      ))

    assert ssh.auth.public_key is None