Updates to kube env interaction

 - local KUBECONFIG var detection
 - proper handling of env vars
 - fixes for KUBECONFIG loading when env file is given/not given
 - main IP extraction
 - wording fixes

 Related-PROD: PROD-35903

Change-Id: I68f1fd18a72a99502460d3b6158a43cd60d7cf1b
diff --git a/cfg_checker/common/kube_utils.py b/cfg_checker/common/kube_utils.py
index f6f499d..315f5ee 100644
--- a/cfg_checker/common/kube_utils.py
+++ b/cfg_checker/common/kube_utils.py
@@ -23,18 +23,18 @@
     # Init kube library locally
     _path = "local:{}".format(config.kube_config_path)
     try:
-        kconfig.load_kube_config()
+        kconfig.load_kube_config(config_file=config.kube_config_path)
         if config.insecure:
             kconfig.assert_hostname = False
             kconfig.client_side_validation = False
         logger_cli.debug(
-            "...found Kube env: core, {}". format(
+            "... found Kube env: core, {}". format(
                 ",".join(
                     kclient.CoreApi().get_api_versions().versions
                 )
             )
         )
-        return kconfig, kclient.ApiClient()
+        return kconfig, kclient.ApiClient(), _path
     except Exception as e:
         logger.warn("Failed to init local Kube client: {}".format(
                 str(e)
@@ -63,14 +63,15 @@
     """
     import yaml
     _path = ''
-    if not config.env_name == ENV_LOCAL:
+    # Try to load remote config only if it was not detected already
+    if not config.kube_config_detected and not config.env_name == ENV_LOCAL:
         _path = "{}@{}:{}".format(
             config.ssh_user,
             config.ssh_host,
             config.kube_config_path
         )
         _c_data = ssh_shell_p(
-            "sudo cat " + config.kube_config_path,
+            "cat " + config.kube_config_path,
             config.ssh_host,
             username=config.ssh_user,
             keypath=config.ssh_key,
@@ -116,7 +117,7 @@
         )
     else:
         logger_cli.debug(
-            "...'context' host extracted: '{}' via SSH@{}".format(
+            "... 'context' host extracted: '{}' via SSH@{}".format(
                 _host,
                 config.ssh_host
             )
@@ -128,7 +129,7 @@
         _tmp[0] + "://" + config.mcp_host + ":" + _tmp[2]
     config.kube_port = _tmp[2]
     logger_cli.debug(
-        "...kube remote host updated to {}".format(
+        "... kube remote host updated to {}".format(
             _kube_conf.host
         )
     )
@@ -169,9 +170,11 @@
                 self.config
             )
             self.is_local = True
-            # Load local config data
-            if os.path.exists(self.config.kube_config_path):
-                _c_data = shell("sudo cat " + self.config.kube_config_path)
+            # Try to load local config data
+            if self.config.kube_config_path and \
+               os.path.exists(self.config.kube_config_path):
+                _cmd = "cat " + self.config.kube_config_path
+                _c_data = shell(_cmd)
                 _conf = yaml.load(_c_data, Loader=yaml.SafeLoader)
                 self.user_keypath = create_temp_file_with_content(
                     base64.standard_b64decode(
@@ -277,7 +280,7 @@
         **kwargs
     ):
         logger_cli.debug(
-            "...searching for pods with the name '{}'".format(pod_name)
+            "... searching for pods with the name '{}'".format(pod_name)
         )
         _pods = {}
         _pods = self._coreV1.list_namespaced_pod(namespace)
@@ -288,8 +291,8 @@
             _pnames = [n for n in _names if n.startswith(pod_name)]
             if len(_pnames) > 1:
                 logger_cli.debug(
-                    "...more than one pod found for '{}': {}\n"
-                    "...using first one".format(
+                    "... more than one pod found for '{}': {}\n"
+                    "... using first one".format(
                         pod_name,
                         ", ".join(_pnames)
                     )
@@ -300,7 +303,7 @@
         else:
             _pname = pod_name
         logger_cli.debug(
-            "...cmd: [CoreV1] exec {} -n {} -- {}".format(
+            "... cmd: [CoreV1] exec {} -n {} -- {}".format(
                 _pname,
                 namespace,
                 cmd
diff --git a/cfg_checker/common/other.py b/cfg_checker/common/other.py
index e3a3271..3d0cc13 100644
--- a/cfg_checker/common/other.py
+++ b/cfg_checker/common/other.py
@@ -16,7 +16,7 @@
 
 # 'Dirty' and simple way to execute piped cmds
 def piped_shell(command):
-    logger_cli.debug("...cmd:'{}'".format(command))
+    logger_cli.debug("... cmd:'{}'".format(command))
     _code, _out = subprocess.getstatusoutput(command)
     if _code:
         logger_cli.error("Non-zero return code: {}, '{}'".format(_code, _out))
@@ -25,7 +25,7 @@
 
 # 'Proper way to execute shell
 def shell(command):
-    logger_cli.debug("...cmd:'{}'".format(command))
+    logger_cli.debug("... cmd:'{}'".format(command))
     _ps = subprocess.Popen(
         command.split(),
         stdout=subprocess.PIPE,
diff --git a/cfg_checker/common/settings.py b/cfg_checker/common/settings.py
index c654970..dac917e 100644
--- a/cfg_checker/common/settings.py
+++ b/cfg_checker/common/settings.py
@@ -2,6 +2,7 @@
 import json
 import pwd
 import sys
+import yaml
 
 from cfg_checker.common.const import ENV_TYPE_GLOB, ENV_TYPE_SALT
 from cfg_checker.common.const import ENV_TYPE_KUBE, ENV_TYPE_LINUX, ENV_LOCAL
@@ -26,14 +27,14 @@
 def _extract_salt_return(_raw):
     if not isinstance(_raw, str):
         _json = _raw
-        logger_cli.debug("...ambigious return detected")
+        logger_cli.debug("... ambigious return detected")
     else:
         try:
             _json = json.loads(_raw)
         except ValueError:
             _json = _raw
             logger_cli.debug(
-                "...return value is not a json: '{}'".format(_raw)
+                "... return value is not a json: '{}'".format(_raw)
             )
 
     return _json
@@ -53,7 +54,7 @@
             return None
 
     def _detect(self, _type):
-        logger_cli.debug("...detecting '{}'".format(_type))
+        logger_cli.debug("... detecting '{}'".format(_type))
         if _type is None:
             raise ConfigException("# Unexpected supported env type")
         elif _type == ENV_TYPE_SALT:
@@ -64,7 +65,7 @@
             )
             # Try to call salt API on target host
             _r = None
-            logger_cli.debug("...trying to detect env type '{}'".format(_type))
+            logger_cli.debug("... detecting env type '{}'".format(_type))
             if self.env_name == ENV_LOCAL:
                 _r = shell(" ".join(_detect_cmd))
             else:
@@ -90,7 +91,7 @@
             _kube = get_kube_remote(self)
             if not _kube.initialized:
                 logger_cli.debug(
-                    "... failed to load config from '{}'".format(
+                    "... failed to init kube using '{}'".format(
                         _kube.kConfigPath
                     )
                 )
@@ -107,12 +108,11 @@
                 if hasattr(_v, "platform") and \
                         hasattr(_v, "major") and \
                         hasattr(_v, "minor"):
-                    _host = "localhost" if _kube.is_local else _kube.kConf.host
                     logger_cli.info(
                         "# Kube server found: {}:{} on '{}'".format(
                             _v.major,
                             _v.minor,
-                            _host
+                            _kube.kConfigPath
                         )
                     )
                     return True
@@ -130,7 +130,7 @@
             from platform import system, release
             _s = system()
             _r = release()
-            logger_cli.debug("...running on {} {}".format(_s, _r))
+            logger_cli.debug("... running on {} {}".format(_s, _r))
             if _s in ['Linux', 'Darwin']:
                 return True
             else:
@@ -163,6 +163,10 @@
         self.salt_vars = []
         self.kube_vars = []
         for _key, _value in self.vars:
+            if _key in os.environ:
+                logger_cli.info(
+                    "-> Using env var '{}={}'".format(_key, os.environ[_key])
+                )
             if _key.startswith(ENV_TYPE_GLOB):
                 os.environ[_key] = _value
             elif _key.startswith(ENV_TYPE_SALT):
@@ -213,23 +217,28 @@
     def _init_env_values(self):
         if ENV_TYPE_SALT in self.detected_envs:
             for _key, _value in self.salt_vars:
-                os.environ[_key] = _value
+                if _key not in os.environ:
+                    os.environ[_key] = _value
 
             self.salt_user = os.environ.get('SALT_USER', 'salt')
             self.salt_timeout = os.environ.get('SALT_TIMEOUT', 30)
-            self.salt_file_root = os.environ.get('SALT_FILE_ROOT', None)
+            self.salt_file_root = os.environ.get(
+                'SALT_FILE_ROOT',
+                "/usr/share/salt-formulas/env/"
+            )
             self.salt_scripts_folder = os.environ.get(
                 'SALT_SCRIPTS_FOLDER',
                 'cfg_checker_scripts'
             )
         elif ENV_TYPE_KUBE in self.detected_envs:
             for _key, _value in self.kube_vars:
-                os.environ[_key] = _value
+                if _key not in os.environ:
+                    os.environ[_key] = _value
 
-            self.kube_config_root = os.environ.get('KUBE_CONFIG_ROOT', None)
+            self.kube_config_root = os.environ.get('KUBE_CONFIG_ROOT', "/root")
             self.kube_scripts_folder = os.environ.get(
                 'KUBE_SCRIPTS_FOLDER',
-                None
+                "cfg-checker-scripts"
             )
             self.kube_node_user = os.environ.get(
                 'KUBE_NODE_USER',
@@ -286,6 +295,57 @@
             ConfigException -- on IO error when loading env file
             ConfigException -- on env file failed validation
         """
+        # detect kubeconfig placement
+        _env_kubeconf_path = os.environ.get('KUBECONFIG', None)
+        if not os.path.exists(self.kube_config_path):
+            logger_cli.debug(
+                "... kubeconfig not detected at '{}'".format(
+                    self.kube_config_path
+                )
+            )
+            # not exists, get KUBECONFIG var
+            if _env_kubeconf_path:
+                # get the env var path
+                self.kube_config_path = _env_kubeconf_path
+                logger_cli.debug(
+                    "... KUBECONFIG var points to '{}'".format(
+                        self.kube_config_path
+                    )
+                )
+                self.kube_config_detected = True
+            else:
+                logger_cli.debug("... KUBECONFIG env var not found")
+                self.kube_config_path = None
+                self.kube_config_detected = False
+        else:
+            logger_cli.debug(
+                "... kubeconfig detected at '{}'".format(
+                    self.kube_config_path
+                )
+            )
+            self.kube_config_detected = True
+
+        # try to load values from KUBECONF
+        _kube_conf = None
+        if self.kube_config_path:
+            with open(self.kube_config_path) as kF:
+                _kube_conf = yaml.load(kF, Loader=yaml.SafeLoader)
+            # extract host ip
+            try:
+                _server = _kube_conf["clusters"][0]["cluster"]["server"]
+            except KeyError as e:
+                logger_cli.debug(
+                    "... failed to extract server ip: "
+                    "no '{}' key in 'clusters/[0]/cluster/server".format(e)
+                )
+            except IndexError:
+                logger_cli.debug(
+                    "... failed to extract server ip: empty cluster list"
+                )
+            _ip = _server.split(':')
+            self.remote_ip = _ip[1].replace('/', '')
+            logger_cli.debug("... detected ip: '{}'".format(self.remote_ip))
+
         # load env file as init os.environment with its values
         if os.path.isfile(config_path):
             with open(config_path) as _f:
@@ -326,7 +386,7 @@
             )
         else:
             logger_cli.debug(
-                "-> ...loaded total of '{}' vars".format(
+                "... loaded total of '{}' vars".format(
                     len(_list)
                 )
             )
diff --git a/cfg_checker/common/ssh_utils.py b/cfg_checker/common/ssh_utils.py
index fdf4c91..bdfe6b5 100644
--- a/cfg_checker/common/ssh_utils.py
+++ b/cfg_checker/common/ssh_utils.py
@@ -27,6 +27,7 @@
     # Build SSH cmd
     if keypath:
         _ssh_cmd.append("-i " + keypath)
+        _ssh_cmd.append("-o " + "IdentitiesOnly=yes")
     if port:
         _ssh_cmd.append("-p " + str(port))
     if username:
@@ -106,7 +107,8 @@
             self._options += ["-p", str(self.port)]
         self._extra_options = [
             "-o", "UserKnownHostsFile=/dev/null",
-            "-o", "StrictHostKeyChecking=no"
+            "-o", "StrictHostKeyChecking=no",
+            "-o", "IdentitiesOnly=yes"
         ]
 
         self._host_uri = ""
@@ -120,7 +122,7 @@
             raise CheckerException(
                 "Invalid SSH banner type: '{}'".format(type(banner))
             )
-        logger.debug("...connecting")
+        logger.debug("... connecting")
         while True:
             try:
                 line = self.outq.get(block=False)
@@ -136,11 +138,11 @@
                         "...timed out after {} sec".format(str(self.timeout))
                     )
                     return False
-        logger.debug("...connected")
+        logger.debug("... connected")
         return True
 
     def _wait_for_string(self, string):
-        logger.debug("...waiting for '{}'".format(string))
+        logger.debug("... waiting for '{}'".format(string))
         while True:
             try:
                 line = self.outq.get(block=False)
@@ -156,10 +158,10 @@
                 self.timeout -= 1
                 if not self.timeout:
                     logger.debug(
-                        "...timed out after {} sec".format(str(self.timeout))
+                        "... timed out after {} sec".format(str(self.timeout))
                     )
                     return False
-        logger.debug("...found")
+        logger.debug("... found")
         return True
 
     def _init_connection(self, cmd):
@@ -203,7 +205,7 @@
 
     def do(self, cmd, timeout=30, sudo=False, strip_cmd=True):
         cmd = cmd if isinstance(cmd, bytes) else bytes(cmd.encode('utf-8'))
-        logger.debug("...ssh: '{}'".format(cmd))
+        logger.debug("... ssh: '{}'".format(cmd))
         if sudo:
             _cmd = b"sudo " + cmd
         else:
@@ -376,7 +378,7 @@
         self._cmd += [self._host_uri]
 
         logger.debug(
-            "...port forwarding: '{}'".format(" ".join(self._cmd))
+            "... port forwarding: '{}'".format(" ".join(self._cmd))
         )
         self._init_connection(self._cmd)
         return self
diff --git a/cfg_checker/modules/network/checker.py b/cfg_checker/modules/network/checker.py
index b65e14d..c2de426 100644
--- a/cfg_checker/modules/network/checker.py
+++ b/cfg_checker/modules/network/checker.py
@@ -75,7 +75,7 @@
         skip_list=None,
         skip_list_file=None
     ):
-        super(SaltNetworkChecker, self).__init__()
+        super(KubeNetworkChecker, self).__init__()
         self.mapper = KubeNetworkMapper(
             config,
             errors_class=self.errors,
diff --git a/cfg_checker/modules/reclass/comparer.py b/cfg_checker/modules/reclass/comparer.py
index 3c308e0..c9cac60 100644
--- a/cfg_checker/modules/reclass/comparer.py
+++ b/cfg_checker/modules/reclass/comparer.py
@@ -66,7 +66,7 @@
                 # logger.warning("WARN: empty file '{}'".format(fname))
                 _yaml = {}
             else:
-                logger.debug("...loaded YAML '{}' ({}b)".format(fname, _size))
+                logger.debug("... loaded YAML '{}' ({}b)".format(fname, _size))
             return _yaml
         except yaml.YAMLError as exc:
             logger_cli.error(exc)
diff --git a/cfg_checker/nodes.py b/cfg_checker/nodes.py
index fde217f..f0b7b38 100644
--- a/cfg_checker/nodes.py
+++ b/cfg_checker/nodes.py
@@ -813,7 +813,7 @@
         self.not_responded = []
         _results = {}
         logger_cli.debug(
-            "...running '{}' on active nodes, {} worker threads".format(
+            "... running '{}' on active nodes, {} worker threads".format(
                 script_filename,
                 self.env_config.threads
             )
@@ -887,7 +887,7 @@
         if not _folder_exists:
             _sh.do("mkdir " + _folder)
         logger_cli.debug(
-            "...create data on node '{}':'{}'".format(node, _target_path)
+            "... create data on node '{}':'{}'".format(node, _target_path)
         )
         _code, _r, _e = _sh.scp(
             _source_path,