diff --git a/reclass_tools/helpers/ssh_client.py b/reclass_tools/helpers/ssh_client.py
new file mode 100644
index 0000000..da3655d
--- /dev/null
+++ b/reclass_tools/helpers/ssh_client.py
@@ -0,0 +1,1147 @@
+#    Copyright 2013 - 2016 Mirantis, Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from __future__ import unicode_literals
+
+import base64
+import os
+import posixpath
+import stat
+import sys
+import threading
+import time
+import warnings
+
+import paramiko
+import six
+
+from reclass_tools.helpers import decorators
+from reclass_tools.helpers import exec_result
+from reclass_tools.helpers import proc_enums
+from reclass_tools import logger
+
+
+def get_private_keys(home, identity_files=None):
+    if not identity_files:
+        identity_files = ['.ssh/id_rsa']
+    keys = []
+    for i in identity_files:
+        with open(os.path.join(home, i)) as f:
+            keys.append(paramiko.RSAKey.from_private_key(f))
+    return keys
+
+
+class SSHAuth(object):
+    __slots__ = ['__username', '__password', '__key', '__keys']
+
+    def __init__(
+            self,
+            username=None, password=None, key=None, keys=None):
+        """SSH authorisation object
+
+        Used to authorize SSHClient.
+        Single SSHAuth object is associated with single host:port.
+        Password and key is private, other data is read-only.
+
+        :type username: str
+        :type password: str
+        :type key: paramiko.RSAKey
+        :type keys: list
+        """
+        self.__username = username
+        self.__password = password
+        self.__key = key
+        self.__keys = [None]
+        if key is not None:
+            # noinspection PyTypeChecker
+            self.__keys.append(key)
+        if keys is not None:
+            for key in keys:
+                if key not in self.__keys:
+                    self.__keys.append(key)
+
+    @property
+    def username(self):
+        """Username for auth
+
+        :rtype: str
+        """
+        return self.__username
+
+    @staticmethod
+    def __get_public_key(key):
+        """Internal method for get public key from private
+
+        :type key: paramiko.RSAKey
+        """
+        if key is None:
+            return None
+        return '{0} {1}'.format(key.get_name(), key.get_base64())
+
+    @property
+    def public_key(self):
+        """public key for stored private key if presents else None
+
+        :rtype: str
+        """
+        return self.__get_public_key(self.__key)
+
+    def enter_password(self, tgt):
+        """Enter password to STDIN
+
+        Note: required for 'sudo' call
+
+        :type tgt: file
+        :rtype: str
+        """
+        # noinspection PyTypeChecker
+        return tgt.write('{}\n'.format(self.__password))
+
+    def connect(self, client, hostname=None, port=22, log=True):
+        """Connect SSH client object using credentials
+
+        :type client:
+            paramiko.client.SSHClient
+            paramiko.transport.Transport
+        :type log: bool
+        :raises paramiko.AuthenticationException
+        """
+        kwargs = {
+            'username': self.username,
+            'password': self.__password}
+        if hostname is not None:
+            kwargs['hostname'] = hostname
+            kwargs['port'] = port
+
+        keys = [self.__key]
+        keys.extend([k for k in self.__keys if k != self.__key])
+
+        for key in keys:
+            kwargs['pkey'] = key
+            try:
+                client.connect(**kwargs)
+                if self.__key != key:
+                    self.__key = key
+                    logger.debug(
+                        'Main key has been updated, public key is: \n'
+                        '{}'.format(self.public_key))
+                return
+            except paramiko.PasswordRequiredException:
+                if self.__password is None:
+                    logger.exception('No password has been set!')
+                    raise
+                else:
+                    logger.critical(
+                        'Unexpected PasswordRequiredException, '
+                        'when password is set!')
+                    raise
+            except paramiko.AuthenticationException:
+                continue
+        msg = 'Connection using stored authentication info failed!'
+        if log:
+            logger.exception(
+                'Connection using stored authentication info failed!')
+        raise paramiko.AuthenticationException(msg)
+
+    def __hash__(self):
+        return hash((
+            self.__class__,
+            self.username,
+            self.__password,
+            tuple(self.__keys)
+        ))
+
+    def __eq__(self, other):
+        return hash(self) == hash(other)
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __deepcopy__(self, memo):
+        return self.__class__(
+            username=self.username,
+            password=self.__password,
+            key=self.__key,
+            keys=self.__keys.copy()
+        )
+
+    def copy(self):
+        return self.__class__(
+            username=self.username,
+            password=self.__password,
+            key=self.__key,
+            keys=self.__keys
+        )
+
+    def __repr__(self):
+        _key = (
+            None if self.__key is None else
+            '<private for pub: {}>'.format(self.public_key)
+        )
+        _keys = []
+        for k in self.__keys:
+            if k == self.__key:
+                continue
+            # noinspection PyTypeChecker
+            _keys.append(
+                '<private for pub: {}>'.format(
+                    self.__get_public_key(key=k)) if k is not None else None)
+
+        return (
+            '{cls}(username={username}, '
+            'password=<*masked*>, key={key}, keys={keys})'.format(
+                cls=self.__class__.__name__,
+                username=self.username,
+                key=_key,
+                keys=_keys)
+        )
+
+    def __str__(self):
+        return (
+            '{cls} for {username}'.format(
+                cls=self.__class__.__name__,
+                username=self.username,
+            )
+        )
+
+
+class _MemorizedSSH(type):
+    """Memorize metaclass for SSHClient
+
+    This class implements caching and managing of SSHClient connections.
+    Class is not in public scope: all required interfaces is accessible throw
+      SSHClient classmethods.
+
+    Main flow is:
+      SSHClient() -> check for cached connection and
+        - If exists the same: check for alive, reconnect if required and return
+        - If exists with different credentials: delete and continue processing
+          create new connection and cache on success
+      * Note: each invocation of SSHClient instance will return current dir to
+        the root of the current user home dir ("cd ~").
+        It is necessary to avoid unpredictable behavior when the same
+        connection is used from different places.
+        If you need to enter some directory and execute command there, please
+        use the following approach:
+        cmd1 = "cd <some dir> && <command1>"
+        cmd2 = "cd <some dir> && <command2>"
+
+    Close cached connections is allowed per-client and all stored:
+      connection will be closed, but still stored in cache for faster reconnect
+
+    Clear cache is strictly not recommended:
+      from this moment all open connections should be managed manually,
+      duplicates is possible.
+    """
+    __cache = {}
+
+    def __call__(
+            cls,
+            host, port=22,
+            username=None, password=None, private_keys=None,
+            auth=None
+    ):
+        """Main memorize method: check for cached instance and return it
+
+        :type host: str
+        :type port: int
+        :type username: str
+        :type password: str
+        :type private_keys: list
+        :type auth: SSHAuth
+        :rtype: SSHClient
+        """
+        if (host, port) in cls.__cache:
+            key = host, port
+            if auth is None:
+                auth = SSHAuth(
+                    username=username, password=password, keys=private_keys)
+            if hash((cls, host, port, auth)) == hash(cls.__cache[key]):
+                ssh = cls.__cache[key]
+                # noinspection PyBroadException
+                try:
+                    ssh.execute('cd ~', timeout=5)
+                except BaseException:  # Note: Do not change to lower level!
+                    logger.debug('Reconnect {}'.format(ssh))
+                    ssh.reconnect()
+                return ssh
+            if sys.getrefcount(cls.__cache[key]) == 2:
+                # If we have only cache reference and temporary getrefcount
+                # reference: close connection before deletion
+                logger.debug('Closing {} as unused'.format(cls.__cache[key]))
+                cls.__cache[key].close()
+            del cls.__cache[key]
+        # noinspection PyArgumentList
+        return super(
+            _MemorizedSSH, cls).__call__(
+            host=host, port=port,
+            username=username, password=password, private_keys=private_keys,
+            auth=auth)
+
+    @classmethod
+    def record(mcs, ssh):
+        """Record SSH client to cache
+
+        :type ssh: SSHClient
+        """
+        mcs.__cache[(ssh.hostname, ssh.port)] = ssh
+
+    @classmethod
+    def clear_cache(mcs):
+        """Clear cached connections for initialize new instance on next call"""
+        n_count = 3 if six.PY3 else 4
+        # PY3: cache, ssh, temporary
+        # PY4: cache, values mapping, ssh, temporary
+        for ssh in mcs.__cache.values():
+            if sys.getrefcount(ssh) == n_count:
+                logger.debug('Closing {} as unused'.format(ssh))
+                ssh.close()
+        mcs.__cache = {}
+
+    @classmethod
+    def close_connections(mcs, hostname=None):
+        """Close connections for selected or all cached records
+
+        :type hostname: str
+        """
+        if hostname is None:
+            keys = [key for key, ssh in mcs.__cache.items() if ssh.is_alive]
+        else:
+            keys = [
+                (host, port)
+                for (host, port), ssh
+                in mcs.__cache.items() if host == hostname and ssh.is_alive]
+        # raise ValueError(keys)
+        for key in keys:
+            mcs.__cache[key].close()
+
+
+class SSHClient(six.with_metaclass(_MemorizedSSH, object)):
+    __slots__ = [
+        '__hostname', '__port', '__auth', '__ssh', '__sftp', 'sudo_mode',
+        '__lock'
+    ]
+
+    class __get_sudo(object):
+        """Context manager for call commands with sudo"""
+        def __init__(self, ssh, enforce=None):
+            """Context manager for call commands with sudo
+
+            :type ssh: SSHClient
+            :type enforce: bool
+            """
+            self.__ssh = ssh
+            self.__sudo_status = ssh.sudo_mode
+            self.__enforce = enforce
+
+        def __enter__(self):
+            self.__sudo_status = self.__ssh.sudo_mode
+            if self.__enforce is not None:
+                self.__ssh.sudo_mode = self.__enforce
+
+        def __exit__(self, exc_type, exc_val, exc_tb):
+            self.__ssh.sudo_mode = self.__sudo_status
+
+    # noinspection PyPep8Naming
+    class get_sudo(__get_sudo):
+        """Context manager for call commands with sudo"""
+
+        def __init__(self, ssh, enforce=True):
+            warnings.warn(
+                'SSHClient.get_sudo(SSHClient()) is deprecated in favor of '
+                'SSHClient().sudo(enforce=...) , which is much more powerful.')
+            super(self.__class__, self).__init__(ssh=ssh, enforce=enforce)
+
+    def __hash__(self):
+        return hash((
+            self.__class__,
+            self.hostname,
+            self.port,
+            self.auth))
+
+    def __init__(
+            self,
+            host, port=22,
+            username=None, password=None, private_keys=None,
+            auth=None
+    ):
+        """SSHClient helper
+
+        :type host: str
+        :type port: int
+        :type username: str
+        :type password: str
+        :type private_keys: list
+        :type auth: SSHAuth
+        """
+        self.__lock = threading.RLock()
+
+        self.__hostname = host
+        self.__port = port
+
+        self.sudo_mode = False
+        self.__ssh = paramiko.SSHClient()
+        self.__ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+        self.__sftp = None
+
+        self.__auth = auth if auth is None else auth.copy()
+
+        if auth is None:
+            msg = (
+                'SSHClient(host={host}, port={port}, username={username}): '
+                'initialization by username/password/private_keys '
+                'is deprecated in favor of SSHAuth usage. '
+                'Please update your code'.format(
+                    host=host, port=port, username=username
+                ))
+            warnings.warn(msg, DeprecationWarning)
+            logger.debug(msg)
+
+            self.__auth = SSHAuth(
+                username=username,
+                password=password,
+                keys=private_keys
+            )
+
+        self.__connect()
+        _MemorizedSSH.record(ssh=self)
+        if auth is None:
+            logger.info(
+                '{0}:{1}> SSHAuth was made from old style creds: '
+                '{2}'.format(self.hostname, self.port, self.auth))
+
+    @property
+    def lock(self):
+        """Connection lock
+
+        :rtype: threading.RLock
+        """
+        return self.__lock
+
+    @property
+    def auth(self):
+        """Internal authorisation object
+
+        Attention: this public property is mainly for inheritance,
+        debug and information purposes.
+        Calls outside SSHClient and child classes is sign of incorrect design.
+        Change is completely disallowed.
+
+        :rtype: SSHAuth
+        """
+        return self.__auth
+
+    @property
+    def hostname(self):
+        """Connected remote host name
+
+        :rtype: str
+        """
+        return self.__hostname
+
+    @property
+    def host(self):
+        """Hostname access for backward compatibility
+
+        :rtype: str
+        """
+        warnings.warn(
+            'host has been deprecated in favor of hostname',
+            DeprecationWarning
+        )
+        return self.hostname
+
+    @property
+    def port(self):
+        """Connected remote port number
+
+        :rtype: int
+        """
+        return self.__port
+
+    @property
+    def is_alive(self):
+        """Paramiko status: ready to use|reconnect required
+
+        :rtype: bool
+        """
+        return self.__ssh.get_transport() is not None
+
+    def __repr__(self):
+        return '{cls}(host={host}, port={port}, auth={auth!r})'.format(
+            cls=self.__class__.__name__, host=self.hostname, port=self.port,
+            auth=self.auth
+        )
+
+    def __str__(self):
+        return '{cls}(host={host}, port={port}) for user {user}'.format(
+            cls=self.__class__.__name__, host=self.hostname, port=self.port,
+            user=self.auth.username
+        )
+
+    @property
+    def _ssh(self):
+        """ssh client object getter for inheritance support only
+
+        Attention: ssh client object creation and change
+        is allowed only by __init__ and reconnect call.
+
+        :rtype: paramiko.SSHClient
+        """
+        return self.__ssh
+
+    @decorators.retry(paramiko.SSHException, count=3, delay=3)
+    def __connect(self):
+        """Main method for connection open"""
+        with self.lock:
+            self.auth.connect(
+                client=self.__ssh,
+                hostname=self.hostname, port=self.port,
+                log=True)
+
+    def __connect_sftp(self):
+        """SFTP connection opener"""
+        with self.lock:
+            try:
+                self.__sftp = self.__ssh.open_sftp()
+            except paramiko.SSHException:
+                logger.warning('SFTP enable failed! SSH only is accessible.')
+
+    @property
+    def _sftp(self):
+        """SFTP channel access for inheritance
+
+        :rtype: paramiko.sftp_client.SFTPClient
+        :raises: paramiko.SSHException
+        """
+        if self.__sftp is not None:
+            return self.__sftp
+        logger.debug('SFTP is not connected, try to connect...')
+        self.__connect_sftp()
+        if self.__sftp is not None:
+            return self.__sftp
+        raise paramiko.SSHException('SFTP connection failed')
+
+    def close(self):
+        """Close SSH and SFTP sessions"""
+        with self.lock:
+            # noinspection PyBroadException
+            try:
+                self.__ssh.close()
+                self.__sftp = None
+            except Exception:
+                logger.exception("Could not close ssh connection")
+                if self.__sftp is not None:
+                    # noinspection PyBroadException
+                    try:
+                        self.__sftp.close()
+                    except Exception:
+                        logger.exception("Could not close sftp connection")
+
+    @staticmethod
+    def clear():
+        warnings.warn(
+            "clear is removed: use close() only if it mandatory: "
+            "it's automatically called on revert|shutdown|suspend|destroy",
+            DeprecationWarning
+        )
+
+    @classmethod
+    def _clear_cache(cls):
+        """Enforce clear memorized records"""
+        warnings.warn(
+            '_clear_cache() is dangerous and not recommended for normal use!',
+            Warning
+        )
+        _MemorizedSSH.clear_cache()
+
+    @classmethod
+    def close_connections(cls, hostname=None):
+        """Close cached connections: if hostname is not set, then close all
+
+        :type hostname: str
+        """
+        _MemorizedSSH.close_connections(hostname=hostname)
+
+    def __del__(self):
+        """Destructor helper: close channel and threads BEFORE closing others
+
+        Due to threading in paramiko, default destructor could generate asserts
+        on close, so we calling channel close before closing main ssh object.
+        """
+        self.__ssh.close()
+        self.__sftp = None
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        pass
+
+    def reconnect(self):
+        """Reconnect SSH session"""
+        with self.lock:
+            self.close()
+
+            self.__ssh = paramiko.SSHClient()
+            self.__ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+
+            self.__connect()
+
+    def sudo(self, enforce=None):
+        """Call contextmanager for sudo mode change
+
+        :type enforce: bool
+        :param enforce: Enforce sudo enabled or disabled. By default: None
+        """
+        return self.__get_sudo(ssh=self, enforce=enforce)
+
+    def check_call(
+            self,
+            command, verbose=False, timeout=None,
+            error_info=None,
+            expected=None, raise_on_err=True, **kwargs):
+        """Execute command and check for return code
+
+        :type command: str
+        :type verbose: bool
+        :type timeout: int
+        :type error_info: str
+        :type expected: list
+        :type raise_on_err: bool
+        :rtype: ExecResult
+        :raises: DevopsCalledProcessError
+        """
+        if expected is None:
+            expected = [proc_enums.ExitCodes.EX_OK]
+        else:
+            expected = [
+                proc_enums.ExitCodes(code)
+                if (
+                    isinstance(code, int) and
+                    code in proc_enums.ExitCodes.__members__.values())
+                else code
+                for code in expected
+                ]
+        ret = self.execute(command, verbose, timeout, **kwargs)
+        if ret['exit_code'] not in expected:
+            message = (
+                "{append}Command '{cmd!r}' returned exit code {code!s} while "
+                "expected {expected!s}\n".format(
+                    append=error_info + '\n' if error_info else '',
+                    cmd=command,
+                    code=ret['exit_code'],
+                    expected=expected,
+                ))
+            logger.error(message)
+            if raise_on_err:
+                raise SSHCalledProcessError(
+                    command, ret['exit_code'],
+                    expected=expected,
+                    stdout=ret['stdout_brief'],
+                    stderr=ret['stdout_brief'])
+        return ret
+
+    def check_stderr(
+            self,
+            command, verbose=False, timeout=None,
+            error_info=None,
+            raise_on_err=True, **kwargs):
+        """Execute command expecting return code 0 and empty STDERR
+
+        :type command: str
+        :type verbose: bool
+        :type timeout: int
+        :type error_info: str
+        :type raise_on_err: bool
+        :rtype: ExecResult
+        :raises: DevopsCalledProcessError
+        """
+        ret = self.check_call(
+            command, verbose, timeout=timeout,
+            error_info=error_info, raise_on_err=raise_on_err, **kwargs)
+        if ret['stderr']:
+            message = (
+                "{append}Command '{cmd!r}' STDERR while not expected\n"
+                "\texit code: {code!s}\n".format(
+                    append=error_info + '\n' if error_info else '',
+                    cmd=command,
+                    code=ret['exit_code'],
+                ))
+            logger.error(message)
+            if raise_on_err:
+                raise SSHCalledProcessError(
+                    command,
+                    ret['exit_code'],
+                    stdout=ret['stdout_brief'],
+                    stderr=ret['stdout_brief'])
+        return ret
+
+    @classmethod
+    def execute_together(
+            cls, remotes, command, expected=None, raise_on_err=True, **kwargs):
+        """Execute command on multiple remotes in async mode
+
+        :type remotes: list
+        :type command: str
+        :type expected: list
+        :type raise_on_err: bool
+        :raises: DevopsCalledProcessError
+        """
+        if expected is None:
+            expected = [0]
+        futures = {}
+        errors = {}
+        for remote in set(remotes):  # Use distinct remotes
+            chan, _, _, _ = remote.execute_async(command, **kwargs)
+            futures[remote] = chan
+        for remote, chan in futures.items():
+            ret = chan.recv_exit_status()
+            chan.close()
+            if ret not in expected:
+                errors[remote.hostname] = ret
+        if errors and raise_on_err:
+            raise SSHCalledProcessError(command, errors)
+
+    @classmethod
+    def __exec_command(
+            cls, command, channel, stdout, stderr, timeout, verbose=False):
+        """Get exit status from channel with timeout
+
+        :type command: str
+        :type channel: paramiko.channel.Channel
+        :type stdout: paramiko.channel.ChannelFile
+        :type stderr: paramiko.channel.ChannelFile
+        :type timeout: int
+        :type verbose: bool
+        :rtype: ExecResult
+        :raises: TimeoutError
+        """
+        def poll_stream(src, verb_logger=None):
+            dst = []
+            try:
+                for line in src:
+                    dst.append(line)
+                    if verb_logger is not None:
+                        verb_logger(
+                            line.decode('utf-8',
+                                        errors='backslashreplace').rstrip()
+                        )
+            except IOError:
+                pass
+            return dst
+
+        def poll_streams(result, channel, stdout, stderr, verbose):
+            if channel.recv_ready():
+                result.stdout += poll_stream(
+                    src=stdout,
+                    verb_logger=logger.info if verbose else logger.debug)
+            if channel.recv_stderr_ready():
+                result.stderr += poll_stream(
+                    src=stderr,
+                    verb_logger=logger.error if verbose else logger.debug)
+
+        @decorators.threaded(started=True)
+        def poll_pipes(stdout, stderr, result, stop, channel):
+            """Polling task for FIFO buffers
+
+            :type stdout: paramiko.channel.ChannelFile
+            :type stderr: paramiko.channel.ChannelFile
+            :type result: ExecResult
+            :type stop: Event
+            :type channel: paramiko.channel.Channel
+            """
+
+            while not stop.isSet():
+                time.sleep(0.1)
+                poll_streams(
+                    result=result,
+                    channel=channel,
+                    stdout=stdout,
+                    stderr=stderr,
+                    verbose=verbose
+                )
+
+                if channel.status_event.is_set():
+                    result.exit_code = result.exit_code = channel.exit_status
+
+                    result.stdout += poll_stream(
+                        src=stdout,
+                        verb_logger=logger.info if verbose else logger.debug)
+                    result.stderr += poll_stream(
+                        src=stderr,
+                        verb_logger=logger.error if verbose else logger.debug)
+
+                    stop.set()
+
+        # channel.status_event.wait(timeout)
+        result = exec_result.ExecResult(cmd=command)
+        stop_event = threading.Event()
+        if verbose:
+            logger.info("\nExecuting command: {!r}".format(command.rstrip()))
+        else:
+            logger.debug("\nExecuting command: {!r}".format(command.rstrip()))
+        poll_pipes(
+            stdout=stdout,
+            stderr=stderr,
+            result=result,
+            stop=stop_event,
+            channel=channel
+        )
+
+        stop_event.wait(timeout)
+
+        # Process closed?
+        if stop_event.isSet():
+            stop_event.clear()
+            channel.close()
+            return result
+
+        stop_event.set()
+        channel.close()
+
+        wait_err_msg = ('Wait for {0!r} during {1}s: no return code!\n'
+                        .format(command, timeout))
+        output_brief_msg = ('\tSTDOUT:\n'
+                            '{0}\n'
+                            '\tSTDERR"\n'
+                            '{1}'.format(result.stdout_brief,
+                                         result.stderr_brief))
+        logger.debug(wait_err_msg)
+        raise SSHTimeoutError(wait_err_msg + output_brief_msg)
+
+    def execute(self, command, verbose=False, timeout=None, **kwargs):
+        """Execute command and wait for return code
+
+        :type command: str
+        :type verbose: bool
+        :type timeout: int
+        :rtype: ExecResult
+        :raises: TimeoutError
+        """
+        chan, _, stderr, stdout = self.execute_async(command, **kwargs)
+
+        result = self.__exec_command(
+            command, chan, stdout, stderr, timeout,
+            verbose=verbose
+        )
+
+        message = (
+            '\n{cmd!r} execution results: Exit code: {code!s}'.format(
+                cmd=command,
+                code=result.exit_code
+            ))
+        if verbose:
+            logger.info(message)
+        else:
+            logger.debug(message)
+        return result
+
+    def execute_async(self, command, get_pty=False):
+        """Execute command in async mode and return channel with IO objects
+
+        :type command: str
+        :type get_pty: bool
+        :rtype:
+            tuple(
+                paramiko.Channel,
+                paramiko.ChannelFile,
+                paramiko.ChannelFile,
+                paramiko.ChannelFile
+            )
+        """
+        logger.debug("Executing command: {!r}".format(command.rstrip()))
+
+        chan = self._ssh.get_transport().open_session()
+
+        if get_pty:
+            # Open PTY
+            chan.get_pty(
+                term='vt100',
+                width=80, height=24,
+                width_pixels=0, height_pixels=0
+            )
+
+        stdin = chan.makefile('wb')
+        stdout = chan.makefile('rb')
+        stderr = chan.makefile_stderr('rb')
+        cmd = "{}\n".format(command)
+        if self.sudo_mode:
+            encoded_cmd = base64.b64encode(cmd.encode('utf-8')).decode('utf-8')
+            cmd = ("sudo -S bash -c 'eval \"$(base64 -d "
+                   "<(echo \"{0}\"))\"'").format(
+                encoded_cmd
+            )
+            chan.exec_command(cmd)
+            if stdout.channel.closed is False:
+                self.auth.enter_password(stdin)
+                stdin.flush()
+        else:
+            chan.exec_command(cmd)
+        return chan, stdin, stderr, stdout
+
+    def execute_through_host(
+            self,
+            hostname,
+            cmd,
+            auth=None,
+            target_port=22,
+            timeout=None,
+            verbose=False
+    ):
+        """Execute command on remote host through currently connected host
+
+        :type hostname: str
+        :type cmd: str
+        :type auth: SSHAuth
+        :type target_port: int
+        :type timeout: int
+        :type verbose: bool
+        :rtype: ExecResult
+        :raises: TimeoutError
+        """
+        if auth is None:
+            auth = self.auth
+
+        intermediate_channel = self._ssh.get_transport().open_channel(
+            kind='direct-tcpip',
+            dest_addr=(hostname, target_port),
+            src_addr=(self.hostname, 0))
+        transport = paramiko.Transport(sock=intermediate_channel)
+
+        # start client and authenticate transport
+        auth.connect(transport)
+
+        # open ssh session
+        channel = transport.open_session()
+
+        # Make proxy objects for read
+        stdout = channel.makefile('rb')
+        stderr = channel.makefile_stderr('rb')
+
+        channel.exec_command(cmd)
+
+        # noinspection PyDictCreation
+        result = self.__exec_command(
+            cmd, channel, stdout, stderr, timeout, verbose=verbose)
+
+        intermediate_channel.close()
+
+        return result
+
+    def mkdir(self, path):
+        """run 'mkdir -p path' on remote
+
+        :type path: str
+        """
+        if self.exists(path):
+            return
+        logger.debug("Creating directory: {}".format(path))
+        # noinspection PyTypeChecker
+        self.execute("mkdir -p {}\n".format(path))
+
+    def rm_rf(self, path):
+        """run 'rm -rf path' on remote
+
+        :type path: str
+        """
+        logger.debug("rm -rf {}".format(path))
+        # noinspection PyTypeChecker
+        self.execute("rm -rf {}".format(path))
+
+    def open(self, path, mode='r'):
+        """Open file on remote using SFTP session
+
+        :type path: str
+        :type mode: str
+        :return: file.open() stream
+        """
+        return self._sftp.open(path, mode)
+
+    def upload(self, source, target):
+        """Upload file(s) from source to target using SFTP session
+
+        :type source: str
+        :type target: str
+        """
+        logger.debug("Copying '%s' -> '%s'", source, target)
+
+        if self.isdir(target):
+            target = posixpath.join(target, os.path.basename(source))
+
+        source = os.path.expanduser(source)
+        if not os.path.isdir(source):
+            self._sftp.put(source, target)
+            return
+
+        for rootdir, _, files in os.walk(source):
+            targetdir = os.path.normpath(
+                os.path.join(
+                    target,
+                    os.path.relpath(rootdir, source))).replace("\\", "/")
+
+            self.mkdir(targetdir)
+
+            for entry in files:
+                local_path = os.path.join(rootdir, entry)
+                remote_path = posixpath.join(targetdir, entry)
+                if self.exists(remote_path):
+                    self._sftp.unlink(remote_path)
+                self._sftp.put(local_path, remote_path)
+
+    def download(self, destination, target):
+        """Download file(s) to target from destination
+
+        :type destination: str
+        :type target: str
+        :rtype: bool
+        """
+        logger.debug(
+            "Copying '%s' -> '%s' from remote to local host",
+            destination, target
+        )
+
+        if os.path.isdir(target):
+            target = posixpath.join(target, os.path.basename(destination))
+
+        if not self.isdir(destination):
+            if self.exists(destination):
+                self._sftp.get(destination, target)
+            else:
+                logger.debug(
+                    "Can't download %s because it doesn't exist", destination
+                )
+        else:
+            logger.debug(
+                "Can't download %s because it is a directory", destination
+            )
+        return os.path.exists(target)
+
+    def exists(self, path):
+        """Check for file existence using SFTP session
+
+        :type path: str
+        :rtype: bool
+        """
+        try:
+            self._sftp.lstat(path)
+            return True
+        except IOError:
+            return False
+
+    def stat(self, path):
+        """Get stat info for path with following symlinks
+
+        :type path: str
+        :rtype: paramiko.sftp_attr.SFTPAttributes
+        """
+        return self._sftp.stat(path)
+
+    def isfile(self, path, follow_symlink=False):
+        """Check, that path is file using SFTP session
+
+        :type path: str
+        :type follow_symlink: bool (default=False), resolve symlinks
+        :rtype: bool
+        """
+        try:
+            if follow_symlink:
+                attrs = self._sftp.stat(path)
+            else:
+                attrs = self._sftp.lstat(path)
+            return attrs.st_mode & stat.S_IFREG != 0
+        except IOError:
+            return False
+
+    def isdir(self, path, follow_symlink=False):
+        """Check, that path is directory using SFTP session
+
+        :type path: str
+        :type follow_symlink: bool (default=False), resolve symlinks
+        :rtype: bool
+        """
+        try:
+            if follow_symlink:
+                attrs = self._sftp.stat(path)
+            else:
+                attrs = self._sftp.lstat(path)
+            return attrs.st_mode & stat.S_IFDIR != 0
+        except IOError:
+            return False
+
+    def walk(self, path):
+        files=[]
+        folders=[]
+        try:
+            for item in self._sftp.listdir_iter(path):
+                if item.st_mode & stat.S_IFDIR:
+                    folders.append(item.filename)
+                else:
+                    files.append(item.filename)
+        except IOError as e:
+            print("Error opening directory {0}: {1}".format(path, e))
+
+        yield path, folders, files
+        for folder in folders:
+            for res in self.walk(os.path.join(path, folder)):
+                yield res
+
+
+class SSHClientError(Exception):
+    """Base class for errors"""
+
+
+class SSHCalledProcessError(SSHClientError):
+    @staticmethod
+    def _makestr(data):
+        if isinstance(data, six.binary_type):
+            return data.decode('utf-8', errors='backslashreplace')
+        elif isinstance(data, six.text_type):
+            return data
+        else:
+            return repr(data)
+
+    def __init__(
+            self, command, returncode, expected=0, stdout=None, stderr=None):
+        self.returncode = returncode
+        self.expected = expected
+        self.cmd = command
+        self.stdout = stdout
+        self.stderr = stderr
+        message = (
+            "Command '{cmd}' returned exit code {code} while "
+            "expected {expected}".format(
+                cmd=self._makestr(self.cmd),
+                code=self.returncode,
+                expected=self.expected
+            ))
+        if self.stdout:
+            message += "\n\tSTDOUT:\n{}".format(self._makestr(self.stdout))
+        if self.stderr:
+            message += "\n\tSTDERR:\n{}".format(self._makestr(self.stderr))
+        super(SSHCalledProcessError, self).__init__(message)
+
+    @property
+    def output(self):
+        warnings.warn(
+            'output is deprecated, please use stdout and stderr separately',
+            DeprecationWarning)
+        return self.stdout + self.stderr
+
+
+class SSHTimeoutError(SSHClientError):
+    pass
+
+
+__all__ = ['SSHAuth', 'SSHClient', 'SSHClientError', 'SSHCalledProcessError', 'SSHTimeoutError']
