#    Author: Alex Savatieiev (osavatieiev@mirantis.com; a.savex@gmail.com)
#    Copyright 2019-2022 Mirantis, Inc.
import json
import os
import yaml
from copy import deepcopy
from multiprocessing.dummy import Pool
from time import sleep

from cfg_checker.clients import get_salt_remote, get_kube_remote
from cfg_checker.common.const import all_salt_roles_map, all_kube_roles_map
from cfg_checker.common.const import NODE_UP, NODE_DOWN, NODE_SKIP
from cfg_checker.common.const import ubuntu_versions, nova_openstack_versions
from cfg_checker.common import logger, logger_cli
from cfg_checker.common import utils
from cfg_checker.common.file_utils import create_temp_file_with_content
from cfg_checker.common.exception import SaltException, KubeException
from cfg_checker.common.ssh_utils import PortForward, SshShell
from cfg_checker.common.settings import pkg_dir, ENV_TYPE_KUBE, ENV_TYPE_SALT
from cfg_checker.helpers.console_utils import Progress


node_tmpl = {
    'role': '',
    'node_group': '',
    'status': NODE_DOWN,
    'pillars': {},
    'grains': {},
    'raw': {}
}


def _prepare_skipped_nodes(_names, skip_list, skip_list_file):
    _skipped_minions = []
    # skip list file
    if skip_list_file:
        _valid, _invalid = utils.get_nodes_list(skip_list_file)
        _skipped_minions.extend(_valid)
        if len(_invalid) < 1:
            logger_cli.info(
                "\n# WARNING: Detected invalid entries "
                "in nodes skip list:\n{}\n".format(
                    "\n".join(_invalid)
                )
            )

    # process wildcard, create node list out of mask
    if skip_list:
        _list = []
        _invalid = []
        for _item in skip_list:
            if '*' in _item:
                _str = _item[:_item.index('*')]
                _nodes = [_m for _m in _names if _m.startswith(_str)]
                if not _nodes:
                    logger_cli.warn(
                        "# WARNING: No nodes found for {}".format(_item)
                    )
                _list.extend(_nodes)
            else:
                if _item in _names:
                    _list += _item
                else:
                    logger_cli.warn(
                        "# WARNING: No node found for {}".format(_item)
                    )
        # removing duplicates
        _list = list(set(_list))
        _skipped_minions.extend(_list)

    return _skipped_minions


class Nodes(object):
    def __init__(self, config):
        self.nodes = None
        self.env_config = config

    def skip_node(self, node):
        # Add node to skip list
        # Fro example if it is fails to comply with the rules

        # check if we know such node
        if node in self.nodes.keys() and node not in self.skip_list:
            # yes, add it
            self.skip_list.append(node)
            return True
        else:
            return False

    def get_nodes(self, skip_list=None, skip_list_file=None):
        if not self.nodes:
            if not skip_list and self.env_config.skip_nodes:
                self.gather_node_info(
                    self.env_config.skip_nodes,
                    skip_list_file
                )
            else:
                self.gather_node_info(skip_list, skip_list_file)
        return self.nodes

    def get_info(self):
        _info = {
           'mcp_release': self.mcp_release,
           'openstack_release': self.openstack_release
        }
        return _info

    def is_node_available(self, node, log=True):
        if node in self.skip_list:
            if log:
                logger_cli.info("-> node '{}' not active".format(node))
            return False
        elif node in self.not_responded:
            if log:
                logger_cli.info("-> node '{}' not responded".format(node))
            return False
        else:
            return True


class SaltNodes(Nodes):
    def __init__(self, config):
        super(SaltNodes, self).__init__(config)
        logger_cli.info("# Gathering environment information")
        # simple salt rest client
        self.salt = None
        self.env_type = ENV_TYPE_SALT

    def gather_node_info(self, skip_list, skip_list_file):
        # Keys for all nodes
        # this is not working in scope of 2016.8.3, will overide with list
        logger_cli.debug("... collecting node names existing in the cloud")
        if not self.salt:
            self.salt = get_salt_remote(self.env_config)

        try:
            _keys = self.salt.list_keys()
            _str = []
            for _k, _v in _keys.items():
                _str.append("{}: {}".format(_k, len(_v)))
            logger_cli.info("-> keys collected: {}".format(", ".join(_str)))

            self.node_keys = {
                'minions': _keys['minions']
            }
        except Exception:
            _keys = None
            self.node_keys = None

        # List of minions with grains
        _minions = self.salt.list_minions()
        if _minions:
            logger_cli.info(
                "-> api reported {} active minions".format(len(_minions))
            )
        elif not self.node_keys:
            # this is the last resort
            _minions = self.env_config.load_nodes_list()
            logger_cli.info(
                "-> {} nodes loaded from list file".format(len(_minions))
            )
        else:
            _minions = self.node_keys['minions']

        # Skip nodes if needed
        _skipped_minions = \
            _prepare_skipped_nodes(_minions, skip_list, skip_list_file)

        # in case API not listed minions, we need all that answer ping
        _active = self.salt.get_active_nodes()
        logger_cli.info("-> nodes responded: {}".format(len(_active)))
        # iterate through all accepted nodes and create a dict for it
        self.nodes = {}
        self.skip_list = []
        _domains = set()
        for _name in _minions:
            _nc = utils.get_node_code(_name)
            _rmap = all_salt_roles_map
            _role = _rmap[_nc] if _nc in _rmap else 'unknown'
            if _name in _skipped_minions:
                _status = NODE_SKIP
                self.skip_list.append(_name)
            else:
                _status = NODE_UP if _name in _active else NODE_DOWN
                if _status == NODE_DOWN:
                    self.skip_list.append(_name)
                    logger_cli.info(
                        "-> '{}' is down, "
                        "added to skip list".format(
                            _name
                        )
                    )
            self.nodes[_name] = deepcopy(node_tmpl)
            self.nodes[_name]['shortname'] = _name.split(".", 1)[0]
            _domains.add(_name.split(".", 1)[1])
            self.nodes[_name]['node_group'] = _nc
            self.nodes[_name]['role'] = _role
            self.nodes[_name]['status'] = _status
        _domains = list(_domains)
        if len(_domains) > 1:
            logger_cli.warning(
                "Multiple domains detected: {}".format(",".join(_domains))
            )
            # TODO: Use domain with biggest node count by default
            # or force it via config option
        else:
            self.domain = _domains[0]
        logger_cli.info("-> {} nodes inactive".format(len(self.skip_list)))
        logger_cli.info("-> {} nodes collected".format(len(self.nodes)))

        # form an all nodes compound string to use in salt
        self.active_nodes_compound = self.salt.compound_string_from_list(
            filter(
                lambda nd: self.nodes[nd]['status'] == NODE_UP,
                self.nodes
            )
        )
        # get master node fqdn
        # _filtered = filter(
        #     lambda nd: self.nodes[nd]['role'] == const.all_roles_map['cfg'],
        #     self.nodes
        # )
        _role = all_salt_roles_map['cfg']
        _filtered = [n for n, v in self.nodes.items() if v['role'] == _role]
        if len(_filtered) < 1:
            raise SaltException(
                "No master node detected! Check/Update node role map."
            )
        else:
            self.salt.master_node = _filtered[0]

        # OpenStack versions
        self.mcp_release = self.salt.pillar_get(
            self.salt.master_node,
            "_param:apt_mk_version"
        )[self.salt.master_node]
        self.openstack_release = self.salt.pillar_get(
            self.salt.master_node,
            "_param:openstack_version"
        )[self.salt.master_node]
        # Preload codenames
        # do additional queries to get linux codename and arch for each node
        self.get_specific_pillar_for_nodes("_param:linux_system_codename")
        self.get_specific_pillar_for_nodes("_param:linux_system_architecture")
        for _name in self.nodes.keys():
            _n = self.nodes[_name]
            if _name not in self.skip_list:
                _p = _n['pillars']['_param']
                _n['linux_codename'] = _p['linux_system_codename']
                _n['linux_arch'] = _p['linux_system_architecture']

    def get_cmd_for_nodes(self, cmd, target_key, target_dict=None, nodes=None):
        """Function runs. cmd.run and parses result into place
        or into dict structure provided

        :return: no return value, data pulished internally
        """
        logger_cli.debug(
            "... collecting results for '{}'".format(cmd)
        )
        if target_dict:
            _nodes = target_dict
        else:
            _nodes = self.nodes
        _result = self.execute_cmd_on_active_nodes(cmd, nodes=nodes)
        for node, data in _nodes.items():

            if node in self.skip_list:
                logger_cli.debug(
                    "... '{}' skipped while collecting '{}'".format(
                        node,
                        cmd
                    )
                )
                continue
            # Prepare target key
            if target_key not in data:
                data[target_key] = None
            # Save data
            if data['status'] in [NODE_DOWN, NODE_SKIP]:
                data[target_key] = None
            elif node not in _result:
                continue
            elif not _result[node]:
                logger_cli.debug(
                    "... '{}' not responded after '{}'".format(
                        node,
                        self.env_config.salt_timeout
                    )
                )
                data[target_key] = None
            else:
                data[target_key] = _result[node]

    def get_specific_pillar_for_nodes(self, pillar_path):
        """Function gets pillars on given path for all nodes

        :return: no return value, data pulished internally
        """
        logger_cli.debug(
            "... collecting node pillars for '{}'".format(pillar_path)
        )
        _result = self.salt.pillar_get(self.active_nodes_compound, pillar_path)
        self.not_responded = []
        for node, data in self.nodes.items():
            if node in self.skip_list:
                logger_cli.debug(
                    "... '{}' skipped while collecting '{}'".format(
                        node,
                        pillar_path
                    )
                )
                continue
            _pillar_keys = pillar_path.split(':')
            _data = data['pillars']
            # pre-create nested dict
            for idx in range(0, len(_pillar_keys)-1):
                _key = _pillar_keys[idx]
                if _key not in _data:
                    _data[_key] = {}
                _data = _data[_key]
            if data['status'] in [NODE_DOWN, NODE_SKIP]:
                _data[_pillar_keys[-1]] = None
            elif not _result[node]:
                logger_cli.debug(
                    "... '{}' not responded after '{}'".format(
                        node,
                        self.env_config.salt_timeout
                    )
                )
                _data[_pillar_keys[-1]] = None
                self.not_responded.append(node)
            else:
                _data[_pillar_keys[-1]] = _result[node]

    def prepare_json_on_node(self, node, _dict, filename):
        if node in self.skip_list:
            logger_cli.debug(
                "... '{}' skipped while preparing json file of '{}'".format(
                    node,
                    filename
                )
            )

        # this function assumes that all folders are created
        _dumps = json.dumps(_dict, indent=2).splitlines()
        _storage_path = os.path.join(
            self.env_config.salt_file_root, self.env_config.salt_scripts_folder
        )
        logger_cli.debug(
            "... uploading data as '{}' "
            "to master's file cache folder: '{}'".format(
                filename,
                _storage_path
            )
        )
        _cache_path = os.path.join(_storage_path, filename)
        _source_path = os.path.join(
            'salt://',
            self.env_config.salt_scripts_folder,
            filename
        )
        _target_path = os.path.join(
            '/root',
            self.env_config.salt_scripts_folder,
            filename
        )

        logger_cli.debug("... creating file in cache '{}'".format(_cache_path))
        self.salt.f_touch_master(_cache_path)
        self.salt.f_append_master(_cache_path, _dumps)
        logger.debug("... syncing file to '{}'".format(node))
        self.salt.get_file(
            node,
            _source_path,
            _target_path,
            tgt_type="compound"
        )
        return _target_path

    def prepare_script_on_active_nodes(self, script_filename):
        # Prepare script
        _p = os.path.join(pkg_dir, 'scripts', script_filename)
        with open(_p, 'rt') as fd:
            _script = fd.read().splitlines()
        _storage_path = os.path.join(
            self.env_config.salt_file_root, self.env_config.salt_scripts_folder
        )
        logger_cli.debug(
            "... uploading script {} "
            "to master's file cache folder: '{}'".format(
                script_filename,
                _storage_path
            )
        )
        self.salt.mkdir(self.salt.master_node, _storage_path)
        # Form cache, source and target path
        _cache_path = os.path.join(_storage_path, script_filename)
        _source_path = os.path.join(
            'salt://',
            self.env_config.salt_scripts_folder,
            script_filename
        )
        _target_path = os.path.join(
            '/root',
            self.env_config.salt_scripts_folder,
            script_filename
        )

        logger_cli.debug("... creating file in cache '{}'".format(_cache_path))
        self.salt.f_touch_master(_cache_path)
        self.salt.f_append_master(_cache_path, _script)
        # command salt to copy file to minions
        logger_cli.debug(
            "... creating script target folder '{}'".format(
                _cache_path
            )
        )
        self.salt.mkdir(
            self.active_nodes_compound,
            os.path.join(
                '/root',
                self.env_config.salt_scripts_folder
            ),
            tgt_type="compound"
        )
        logger.debug("... syncing file to nodes")
        self.salt.get_file(
            self.active_nodes_compound,
            _source_path,
            _target_path,
            tgt_type="compound"
        )
        # return path on nodes, just in case
        return _target_path

    def execute_script_on_node(self, node, script_filename, args=[]):
        # Prepare path
        _target_path = os.path.join(
            '/root',
            self.env_config.salt_scripts_folder,
            script_filename
        )

        # execute script
        logger.debug("... running script on '{}'".format(node))
        # handle results for each node
        _script_arguments = " ".join(args) if args else ""
        self.not_responded = []
        _r = self.salt.cmd(
            node,
            'cmd.run',
            param='python {} {}'.format(_target_path, _script_arguments),
            expr_form="compound"
        )

        # all false returns means that there is no response
        self.not_responded = [_n for _n in _r.keys() if not _r[_n]]
        return _r

    def execute_script_on_active_nodes(self, script_filename, args=None):
        # Prepare path
        _target_path = os.path.join(
            '/root',
            self.env_config.salt_scripts_folder,
            script_filename
        )

        # execute script
        logger_cli.debug("... running script")
        # handle results for each node
        _script_arguments = args if args else ""
        self.not_responded = []
        _r = self.salt.cmd(
            self.active_nodes_compound,
            'cmd.run',
            param='python {} {}'.format(_target_path, _script_arguments),
            expr_form="compound"
        )

        # all false returns means that there is no response
        self.not_responded = [_n for _n in _r.keys() if not _r[_n]]
        return _r

    def execute_cmd_on_active_nodes(self, cmd, nodes=None):
        # execute cmd
        self.not_responded = []
        _r = self.salt.cmd(
            nodes if nodes else self.active_nodes_compound,
            'cmd.run',
            param=cmd,
            expr_form="compound"
        )

        # all false returns means that there is no response
        self.not_responded = [_n for _n in _r.keys() if not _r[_n]]
        return _r


class KubeNodes(Nodes):
    def __init__(self, config):
        super(KubeNodes, self).__init__(config)
        logger_cli.info("# Gathering environment information")
        # simple salt rest client
        self.kube = get_kube_remote(self.env_config)
        self.env_type = ENV_TYPE_KUBE
        self._namespace = "qa-space"
        self._configmap_name = self.env_config.kube_scripts_folder

        # prepare needed resources
        self._check_namespace()
        self._scripts = self._check_config_map()
        self.prepared_daemonsets = []

    def _check_namespace(self):
        # ensure namespace
        logger_cli.debug(
            "... checking namespace '{}'".format(self._namespace)
        )
        if not self.kube.ensure_namespace(self._namespace):
            raise KubeException(
                "Failed to manage namespace '{}'".format(self._namespace)
            )

    def _check_config_map(self):
        # ensure config map exists
        logger_cli.debug(
            "... checking config map '{}'".format(self._configmap_name)
        )
        _source = os.path.join(pkg_dir, 'scripts')
        return self.kube.create_config_map(
            self._namespace,
            self._configmap_name,
            _source
        )

    def gather_node_info(self, skip_list, skip_list_file):
        # Gather nodes info and query pod lists for each node
        logger_cli.debug("... collecting node names existing in the cloud")

        # Gather node names and info
        _nodes = self.kube.get_node_info()
        _node_names = list(_nodes.keys())
        # Skip nodes if needed
        _skipped_nodes = \
            _prepare_skipped_nodes(_node_names, skip_list, skip_list_file)

        # Count how many nodes active
        self._active = [n for n, v in _nodes.items()
                        if v['conditions']['ready']['status']]

        # iterate through all accepted nodes and create a dict for it
        self.nodes = {}
        self.skip_list = []
        for _name in _node_names:
            if _name in _skipped_nodes:
                _status = NODE_SKIP
                self.skip_list.append(_name)
            else:
                _status = NODE_UP if _name in self._active else NODE_DOWN
                if _status == NODE_DOWN:
                    self.skip_list.append(_name)
                    logger_cli.info(
                        "-> '{}' shows 'Ready' as 'False', "
                        "added to skip list".format(
                            _name
                        )
                    )
            _roles = {}
            _labels = {}
            for _label, _value in _nodes[_name]['labels'].items():
                if _label in all_kube_roles_map:
                    _roles[all_kube_roles_map[_label]] = _value
                else:
                    _labels[_label] = _value

            self.nodes[_name] = deepcopy(node_tmpl)
            self.nodes[_name].pop("grains")
            self.nodes[_name].pop("pillars")

            # hostname
            self.nodes[_name]['shortname'] = \
                _nodes[_name]['addresses']['hostname']['address']
            # internal
            self.nodes[_name]['internalip'] = \
                _nodes[_name]['addresses']['internalip']['address']
            # alternate
            if self.env_config.force_node_network is not None:
                iIP = self.nodes[_name]['internalip']
                # use last number
                aIP = self.env_config.force_node_network + iIP.split('.')[-1]
                self.nodes[_name]["altip"] = aIP
            self.nodes[_name]['node_group'] = None
            self.nodes[_name]['labels'] = _labels
            self.nodes[_name]['roles'] = _roles
            self.nodes[_name]['status'] = _status
            # Backward compatibility
            _info = _nodes[_name]['status']['node_info']
            self.nodes[_name]['linux_image'] = _info['os_image']
            self.nodes[_name]['linux_arch'] = _info['architecture']

            _codename = "unknown"
            _n, _v, _c = _info['os_image'].split()
            if _n.lower() == 'ubuntu':
                _v, _, _ = _v.rpartition('.') if '.' in _v else (_v, "", "")
                if _v in ubuntu_versions:
                    _codename = ubuntu_versions[_v].split()[0].lower()
            self.nodes[_name]['linux_codename'] = _codename

            # Consider per-data type transfer
            self.nodes[_name]["raw"] = _nodes[_name]
        # TODO: Investigate how to handle domains in Kube, probably - skip
        # _domains = list(_domains)
        # if len(_domains) > 1:
        #     logger_cli.warning(
        #         "Multiple domains detected: {}".format(",".join(_domains))
        #     )
        # else:
        self.domain = "no.domain.in.kube.yet"
        logger_cli.info(
            "-> {} nodes collected: {} - active, {} - not active".format(
                len(self.nodes),
                len(self._active),
                len(self.skip_list)
            )
        )

        _role = "k8s-master"
        _filtered = [n for n, v in self.nodes.items() if _role in v['roles']]
        if len(_filtered) < 1:
            raise KubeException(
                "No k8s-master nodes detected! Check/Update node role map."
            )
        else:
            _r = [n for n, v in self.nodes.items()
                  if v['status'] != NODE_UP and _role in v['roles']]
            if len(_r) > 0:
                logger_cli.warn(
                    "Master nodes are reporting 'NotReady:\n{}".format(
                        "\n".join(_r)
                    )
                )
            self.kube.master_node = _filtered[0]

        # get specific data upfront
        # OpenStack versions
        self.mcp_release = ""
        # Quick and Dirty way to detect OS release
        try:
            _nova_version = self.kube.exec_on_target_pod(
                "nova-manage --version",
                "nova-api-osapi",
                "openstack"
            )
            _nmajor = _nova_version.partition('.')[0]
            self.openstack_release = nova_openstack_versions[_nmajor]
        except KubeException as e:
            logger_cli.warn("Openstack not detected: {}".format(e.message))
            self.openstack_release = nova_openstack_versions["00"]

        return

    @staticmethod
    def _get_ssh_shell(_h, _u, _k, _p, _q, _pipe, timeout=15):
        _ssh = SshShell(
            _h,
            user=_u,
            keypath=_k,
            port=_p,
            silent=_q,
            piped=_pipe,
            timeout=timeout
        )
        return _ssh.connect()

    @staticmethod
    def _do_ssh_cmd(_cmd, _h, _u, _k, _p, _q, _pipe, timeout=None):
        with SshShell(
            _h,
            user=_u,
            keypath=_k,
            port=_p,
            silent=_q,
            piped=_pipe
        ) as ssh:
            if timeout is None:
                _r = ssh.do(_cmd)
            else:
                _r = ssh.do(_cmd, timeout=timeout)
            logger_cli.debug("'{}'".format(_r))
        return _r

    def node_shell(
        self,
        node,
        silent=True,
        piped=True,
        use_sudo=True,
        fport=None
    ):
        _u = self.env_config.kube_node_user
        _k = self.env_config.kube_node_keypath

        _n = self.nodes[node]
        _h = _n['altip'] if "altip" in _n else _n['internalip']
        _p = 22
        if self.kube.is_local or self.kube.config.ssh_direct:
            logger.debug("Getting shell with no port forward")
            return [None, self._get_ssh_shell(
                _h, _u, _k, _p, silent, piped,
                timeout=self.kube.config.ssh_connect_timeout
            )]
        else:
            logger.debug("Getting shell with with forward")
            _fh = "localhost"
            _p = 10022 if not fport else fport
            _pfwd = PortForward(
                self.env_config.ssh_host,
                _h,
                user=_u,
                keypath=self.env_config.ssh_key,
                loc_port=_p,
                timeout=self.kube.config.ssh_connect_timeout
            )
            _pfwd.connect()
            _ssh = self._get_ssh_shell(
                _fh,
                _u,
                _k,
                _p,
                silent,
                piped,
                timeout=self.kube.config.ssh_connect_timeout
            )
            return [_pfwd, _ssh]

    def execute_script_on_node(self, node, script_filename, args=[]):
        # Prepare path
        _target_path = os.path.join(
            self.env_config.kube_node_homepath,
            self.env_config.kube_scripts_folder,
            script_filename
        )

        # execute script
        logger_cli.debug("... running script on '{}'".format(node))
        # handle results for each node
        _script_arguments = " ".join(args) if args else ""
        self.not_responded = []
        # get result
        _nr = self.node_shell(
            node,
            "python {} {}".format(
                _target_path,
                _script_arguments
            )
        )

        if not _nr:
            self.not_responded.append(node)
            return {}
        else:
            return {node: _nr}

    def execute_cmd_on_active_nodes(self, cmd, nodes=None):
        # execute script
        logger_cli.debug("...running '{}' on active nodes".format(cmd))
        # handle results for each node
        self.not_responded = []
        _r = {}
        # TODO: Use threading and pool
        for node in self._active:
            _nr = self.node_shell(
                node,
                cmd
            )

            if not _nr:
                self.not_responded.append(node)
            else:
                _r[node] = _nr

        return _r

    def _ssh_exec_script(self, params):
        """
        Threadsafe method to get shell to node,
        check/copy script and get results
        [
            node_name,
            src_path,
            tgt_path,
            conf,
            args
        ]
        """
        _timeout = self.kube.config.script_execution_timeout
        _name = params[0]
        _src = params[1]
        _tgt = params[2]
        _conf = params[3]
        _args = params[4]
        _port = params[5]
        _log_name = "["+_name+"]:"
        _check = "echo $(if [[ -s '{}' ]]; then echo True; " \
                 "else echo False; fi)"
        _fwd_sh, _sh = self.node_shell(
            _name,
            use_sudo=False,
            fport=_port
        )
        # check python3
        _python = _sh.do("which python3")
        _python = utils.to_bool(
            _sh.do(_check.format(_python))
        )
        if not _python:
            _sh.do("apt install python3", sudo=True, timeout=_timeout)
        # check if script already there
        _folder = os.path.join(
            self.env_config.kube_node_homepath,
            _conf.kube_scripts_folder
        )
        # check if folder exists
        _folder_exists = utils.to_bool(
            _sh.do(_check.format(_folder))
        )
        if not _folder_exists:
            _sh.do("mkdir " + _folder)
        logger.info("{} Syncing file".format(_log_name))
        _code, _r, _e = _sh.scp(
            _src,
            _sh.get_host_path(_tgt),
        )
        # handle error code
        if _code:
            logger_cli.warn(
                "{} Error in scp:\n"
                "\tstdout:'{}'\n"
                "\tstderr:'{}'".format(_log_name, _r, _e)
            )

        # execute script
        logger.debug("{} Running script".format(_log_name))
        _out = _sh.do(
            "python3 {}{}".format(
                _tgt,
                _args
            ),
            sudo=True,
            timeout=_timeout
        )

        if _fwd_sh:
            _fwd_sh.kill()
        _sh.kill()

        return [_name, _out]

    def execute_script_on_active_nodes(self, script_filename, args=None):
        # Prepare script
        _source_path = os.path.join(pkg_dir, 'scripts', script_filename)
        _target_path = os.path.join(
            self.env_config.kube_node_homepath,
            self.env_config.kube_scripts_folder,
            script_filename
        )
        # handle results for each node
        _script_arguments = " ".join(args) if args else ""
        if _script_arguments:
            _script_arguments = " " + _script_arguments
        self.not_responded = []
        _results = {}
        logger_cli.debug(
            "... running '{}' on active nodes, {} worker threads".format(
                script_filename,
                self.env_config.threads
            )
        )
        # Workers pool
        pool = Pool(self.env_config.threads)

        # init the parameters
        # node_name,
        # src_path,
        # tgt_path,
        # conf,
        # args
        _params = []
        _port = 10022
        for node in self._active:
            # build parameter blocks
            _p_list = [
                node,
                _source_path,
                _target_path,
                self.env_config,
                _script_arguments,
                _port
            ]
            _params.append(_p_list)
            _port += 1

        _progress = Progress(len(_params))
        results = pool.imap_unordered(self._ssh_exec_script, _params)

        for ii in enumerate(results, start=1):
            if not ii[1][1]:
                self.not_responded.append(ii[1][0])
            else:
                _results[ii[1][0]] = ii[1][1]
            _progress.write_progress(ii[0])

        _progress.end()
        pool.close()
        pool.join()

        # return path on nodes, just in case
        return _results

    def prepare_json_on_node(self, node, _dict, filename):
        # this function assumes that all folders are created
        _dumps = json.dumps(_dict, indent=2).splitlines()

        _source_path = create_temp_file_with_content(_dumps)
        _target_path = os.path.join(
            self.env_config.kube_node_homepath,
            self.env_config.kube_scripts_folder,
            filename
        )
        _folder = os.path.join(
            self.env_config.kube_node_homepath,
            self.env_config.kube_scripts_folder
        )
        _check = "echo $(if [[ -s '{}' ]]; then echo True; " \
                 "else echo False; fi)"
        _fwd_sh, _sh = self.node_shell(
            node,
            use_sudo=False
        )

        # check if folder exists
        _folder_exists = utils.to_bool(
            _sh.do(_check.format(_folder))
        )
        if not _folder_exists:
            _sh.do("mkdir " + _folder)
        logger_cli.debug(
            "... create data on node '{}':'{}'".format(node, _target_path)
        )
        _code, _r, _e = _sh.scp(
            _source_path,
            _sh.get_host_path(_target_path),
        )
        # handle error code
        if _code:
            logger_cli.warn(
                "Error in scp:\n"
                "\tstdout:'{}'\n"
                "\tstderr:'{}'".format(_r, _e)
            )

        _fwd_sh.kill()
        _sh.kill()
        return _target_path

    def prepare_daemonset(self, template_filename):
        # load template
        _yaml_file = os.path.join(pkg_dir, 'templates', template_filename)
        logger_cli.debug("... loading template '{}'".format(_yaml_file))
        _ds = {}
        with open(_yaml_file) as dsFile:
            _ds = yaml.load(dsFile, Loader=yaml.SafeLoader)

        # Add scripts to pod template as volumeMounts
        _tspec = _ds['spec']['template']['spec']
        _tspec['containers'][0]['volumeMounts'] = [
            {
                "name": "scripts",
                "mountPath": os.path.join(
                    "/",
                    self.env_config.kube_scripts_folder
                )
            }
        ]

        _tspec['volumes'] = [
            {
                "name": "scripts",
                "configMap": {
                    "name": self._configmap_name
                }
            }
        ]

        # create daemonset
        logger_cli.debug("... preparing daemonset")
        _ds = self.kube.prepare_daemonset_from_yaml(self._namespace, _ds)
        # Save prepared daemonset
        self.prepared_daemonsets.append(_ds)
        # return it
        return _ds

    def wait_for_daemonset(self, ds, timeout=120):
        # iteration timeout
        _sleep_time = 5
        _timeout = timeout

        # query daemonset and check that desired=scheduled=ready
        _ds = self.kube.get_daemon_set_by_name(
            ds.metadata.namespace,
            ds.metadata.name
        )

        _total = len(self.nodes)
        # _scheduled = _ds.status.scheduled
        # _ready = _ds.status.ready

        # Init Progress bar to show daemonset readiness
        _progress = Progress(_total)
        while _timeout > 0:
            # get new status
            _ds = self.kube.get_daemon_set_by_name(
                ds.metadata.namespace,
                ds.metadata.name
            )
            _desired = _ds.status.desired_number_scheduled
            _scheduled = _ds.status.current_number_scheduled
            _ready = _ds.status.number_ready
            _updated = _ds.status.updated_number_scheduled
            # print it
            _progress.write_progress(
                _ready,
                note="desired: {}, scheduled: {}, ready: {},"
                     " up-to-date: {}".format(
                         _desired,
                         _scheduled,
                         _ready,
                         _updated
                     )
            )

            # check values and return
            # In case of Update, also checking _updated value
            if _ready == _updated and _ready == _total - len(self.skip_list):
                # close progress bar class
                _progress.end()
                logger_cli.debug("... daemonset is ready")
                return True
            # iterate
            _timeout -= _sleep_time
            # wait
            sleep(_sleep_time)

        # timed out
        _progress.end()
        # log it
        logger_cli.error("Timed out waiting for Daemonset to be ready")
        return False

    def exec_script_on_target_pod(self, pod_name, script_filename, args=None):
        """
        Run script from configmap on target pod assuming it is present
        """
        _arguments = args if args else ""
        _cmd = [
            "python3",
            os.path.join(
                "/",
                self.env_config.kube_scripts_folder,
                script_filename
            )
        ] + _arguments
        _result = self.kube.exec_on_target_pod(
            _cmd,
            pod_name,
            self._namespace,
            strict=True
        )
        return _result

    def exec_cmd_on_target_pod(self, pod_name, ns, command_str):
        """
        Run script from configmap on target pod assuming it is present
        """
        _result = self.kube.exec_on_target_pod(
            command_str,
            pod_name,
            ns,
            strict=True
        )
        return _result

    def execute_cmd_on_daemon_set(
        self,
        ds,
        cmd,
        _args=None,
        is_script=False
    ):
        """
        Query daemonset for pods and execute script on all of them
        """
        _results = self.exec_cmd_on_pods(
            self.kube.get_pods_for_daemonset(ds),
            cmd,
            _args=_args,
            is_script=is_script
        )
        # Update results
        _ds_results = {}
        for _n, _, _v in _results:
            _ds_results[_n] = _v
        return _ds_results

    def exec_on_labeled_pods_and_ns(
        self,
        label_str,
        cmd,
        _args=None,
        ns=None,
        silent=False
    ):
        if not ns:
            ns = self._namespace
        _results = self.exec_cmd_on_pods(
            self.kube.list_pods(ns, label_str=label_str),
            cmd,
            _args=_args,
            silent=silent
        )
        _pod_results = {}
        for _, _p, _v in _results:
            _pod_results[_p] = _v
        return _pod_results

    def exec_cmd_on_pods(
        self,
        pod_list,
        cmd,
        _args=None,
        is_script=False,
        silent=False
    ):
        def _kube_exec_on_pod(plist):
            return [
                plist[1],  # node
                plist[3],  # pod name
                plist[0].kube.exec_on_target_pod(  # pointer to function
                    plist[4],  # cmd
                    plist[3],  # pod name
                    plist[2],  # namespace
                    strict=True,
                    _request_timeout=120,
                    arguments=plist[5]
                )
            ]

        # Create map for threads: [[node_name, ns, pod_name, cmd]...]
        logger_cli.debug(
            "... runnning script on {} pods using {} threads at a time".format(
                len(pod_list.items),
                self.env_config.threads
            )
        )
        _plist = []
        _arguments = _args if _args else ""
        if is_script:
            _cmd = [
                "python3",
                os.path.join(
                    "/",
                    self.env_config.kube_scripts_folder,
                    cmd
                ),
                _arguments
            ]
            _cmd = " ".join(_cmd)
        else:
            # decide if we are to wrap it to bash
            if '|' in cmd:
                _cmd = "bash -c"
                _arguments = cmd
            else:
                _cmd = cmd
        for item in pod_list.items:
            _plist.append(
                [
                    self,
                    item.spec.node_name,
                    item.metadata.namespace,
                    item.metadata.name,
                    _cmd,
                    _arguments
                ]
            )

        # map func and cmd
        pool = Pool(self.env_config.threads)
        _results = []
        self.not_responded = []
        # create result list
        if not silent:
            _progress = Progress(len(_plist))
        ret = pool.imap_unordered(_kube_exec_on_pod, _plist)

        for ii in enumerate(ret, start=1):
            if not ii[1][1]:
                self.not_responded.append(ii[1][0])
            else:
                _results.append(ii[1])
            if not silent:
                _progress.write_progress(ii[0])

        if not silent:
            _progress.end()
        pool.close()
        pool.join()
        logger_cli.debug(
            "... done, {} total outputs; {} not responded".format(
                len(_results),
                len(self.not_responded)
            )
        )
        return _results

    def delete_daemonset(self, ds):
        # Try to delete daemonset
        try:
            _r = self.kube.delete_daemon_set_by_name(
                ds.metadata.namespace,
                ds.metadata.name
            )
        except Exception as e:
            logger_cli.warning("Failed to delete daemonset '{}': {}".format(
                ds.metadata.name,
                e.reason
            ))
            _r = None
        return _r

    def get_pod_name_in_daemonset_by_node(self, nodename, daemonset):
        _podname = None
        _pods = self.kube.get_pods_for_daemonset(daemonset)
        for item in _pods.items:
            if item.spec.node_name == nodename:
                _podname = item.metadata.name

        return _podname

    def prepare_json_in_pod(self, podname, namespace, targets, filename):
        # Iterate pods in daemonset and prepare json file on each one
        _target_path = os.path.join(
            "/",
            "tmp",
            filename
        )
        # check folder will probably not needed as the daemonset links
        # configmap there on creation
        # _folder = os.path.join(
        #     self.env_config.kube_node_homepath,
        #     self.env_config.kube_scripts_folder
        # )
        # prepare data
        buffer = json.dumps(targets, indent=2).encode('utf-8')

        # write data to pod using fancy websocket function
        self.kube.put_string_buffer_to_pod_as_textfile(
            podname,
            namespace,
            buffer,
            _target_path
        )

        # TODO: Exception handling

        return _target_path

    def get_cmd_for_nodes(self, cmd, target_key, target_dict=None, nodes=None):
        """Function runs command on daemonset and parses result into place
        or into dict structure provided

        :return: no return value, data pulished internally
        """
        logger_cli.debug(
            "... collecting results for '{}'".format(cmd)
        )
        if target_dict:
            _nodes = target_dict
        else:
            _nodes = self.nodes
        # Dirty way to get daemonset that was used in checker and not deleted
        _ds = self.prepared_daemonsets[0]
        _result = self.execute_cmd_on_daemon_set(_ds, cmd)
        for node, data in _nodes.items():

            if node in self.skip_list:
                logger_cli.debug(
                    "... '{}' skipped while collecting '{}'".format(
                        node,
                        cmd
                    )
                )
                continue
            # Prepare target key
            if target_key not in data:
                data[target_key] = None
            # Save data
            if data['status'] in [NODE_DOWN, NODE_SKIP]:
                data[target_key] = None
            elif node not in _result:
                continue
            elif not _result[node]:
                logger_cli.debug(
                    "... '{}' not responded after '{}'".format(
                        node,
                        self.env_config.salt_timeout
                    )
                )
                data[target_key] = None
            else:
                data[target_key] = _result[node]

    def prepare_benchmark_agent(self, index, path, sc, size, template):
        # Load pod template
        _yaml_file = os.path.join(pkg_dir, 'templates', template)
        logger_cli.debug("... loading template '{}'".format(_yaml_file))
        _pod = {}
        with open(_yaml_file) as podFile:
            _pod = yaml.load(podFile, Loader=yaml.SafeLoader)

        # set namings
        _n = "cfgagent-{:02}".format(index)
        _pvc_n = "cfgagent-pvc-{:02}".format(index)
        # _pv_n = "cfgagent-pv-{:02}".format(index)

        _pod["metadata"]["name"] = _n
        _pod["metadata"]["labels"]["name"] = _n
        # replace volumeMounts
        for _c in _pod["spec"]["containers"]:
            for _mnt in _c["volumeMounts"]:
                if "placeholder" in _mnt["name"]:
                    # _mnt["name"] = _pv_n
                    _mnt["mountPath"] = path
        # replace claim
        for _v in _pod["spec"]["volumes"]:
            if "cfgagent-pv" in _v["name"]:
                # _v["name"] = _pv_n
                _v["persistentVolumeClaim"]["claimName"] = _pvc_n

        # init volume resources
        # _pv_object = self.kube.init_pv_resource(_pv_n, sc, size, path)
        # _pv = self.kube.prepare_pv(_pv_object)
        # update size of the volume to be 15% larger
        _pvc_object = self.kube.init_pvc_resource(_pvc_n, sc, size)
        _pvc = self.kube.prepare_pvc(_pvc_object)

        # start pod
        _pod = self.kube.prepare_pod_from_yaml(_pod)

        # return _pod, _pv, _pvc
        return _pod, _pvc

    def expose_benchmark_agent(self, agent):
        return self.kube.expose_pod_port(agent, 8765)

    def cleanup_resource_by_name(self, res_type, name, ns=None, wait=False):
        """Cleansup resource using string res_type and the ns/name

        Args:
            res_type (string): resource type name: pod, pv, pvc, svc
            name (string): resource name to cleanup
            ns (string, optional): Namespace to use. Default is 'qa-space'

            return: (Bool) Is Success?
        """
        # fill defaults
        if not ns:
            ns = self._namespace
        # Handle res_type errors and choose resource type
        if not res_type:
            logger_cli.debug(
                "... resource type invalid: '{}'".format(res_type)
            )
            return False
        elif not name:
            logger_cli.debug("... resource name invalid: '{}'".format(name))
            return False
        elif res_type == "svc":
            # Delete service
            logger_cli.info("-> deleting svc {}/{}".format(ns, name))
            self.kube.CoreV1.delete_namespaced_service(name, ns)
            # TODO: Check if successfull
        elif res_type == "pod":
            # Delete a pod
            logger_cli.info("-> deleting pod {}/{}".format(ns, name))
            self.kube.CoreV1.delete_namespaced_pod(name, ns)
            if wait:
                self.kube.wait_for_phase(res_type, name, ns, ["Terminated"])
        elif res_type == "pvc":
            logger_cli.info("-> deleting pvc {}/{}".format(ns, name))
            self.kube.CoreV1.delete_namespaced_persistent_volume_claim(
                name,
                ns
            )
            if wait:
                self.kube.wait_for_phase(res_type, name, ns, ["Terminated"])
        elif res_type == "pv":
            logger_cli.info("-> deleting pv {}/{}".format(ns, name))
            self.kube.CoreV1.delete_persistent_volume(name)
            if wait:
                self.kube.wait_for_phase(res_type, name, None, ["Terminated"])

        return True

    def get_resource_phase_by_name(self, typ, name, ns="qa-space"):
        if typ == "pod":
            _t = self.kube.get_pod_by_name_and_ns(name, ns)
        elif typ == "svc":
            _t = self.kube.get_svc_by_name_and_ns(name, ns)
        elif typ == "pvc":
            _t = self.kube.get_pvc_by_name_and_ns(name, ns)
        elif typ == "pv":
            _t = self.kube.get_pv_by_name(name)
        else:
            logger_cli.error("ERROR: '{}' is not supported yet".format(typ))
            return None

        if _t:
            return _t.status.phase
        else:
            return None

    def list_resource_names_by_type_and_ns(self, typ, ns="qa-space"):
        if typ == "pod":
            _items = self.kube.list_pods(ns)
        elif typ == "svc":
            _items = self.kube.list_svc(ns)
        elif typ == "pvc":
            _items = self.kube.list_pvc(ns)
        elif typ == "pv":
            _items = self.kube.list_pv()
        else:
            logger_cli.error("ERROR: '{}' is not supported yet".format(typ))
            return None
        return [[i.metadata.namespace, i.metadata.name] for i in _items.items]

    def get_logs_for_pod(self, podname, namespace):
        return self.kube.get_pod_logs(podname, namespace)
