Multi env support and Kube client integration

Kube friendly Beta

Package versions supports Kube env

Added:
  - Env type detection
  - New option: --use-env, for selecting env
    when function supports multiple detected envs
  - Updated config loading
  - Each module and command type has supported env check
    and stops execution if it is on unsupported env
  - Functions can support multiple envs
  - Kubernetes dependency
  - Kubenernetes API detection: local and remote
  - Package checking class hierachy for using Salt or Kube
  - Remote pod execution routine
  - Flexible SSH/SSH Forwarder classes: with, ssh,do(), etc
  - Multithreaded SSH script execution
  - Number of workers parameter, default 5

Fixed:
  - Config dependency
  - Command loading with supported envs list
  - Unittests structure and execution flow updated
  - Unittests fixes
  - Fixed debug mode handling
  - Unified command type/support routine
  - Nested attrs getter/setter

Change-Id: I3ade693ac21536e2b5dcee4b24d511749dc72759
Related-PROD: PROD-35811
diff --git a/cfg_checker/helpers/args_utils.py b/cfg_checker/helpers/args_utils.py
index 498ed30..7ac431c 100644
--- a/cfg_checker/helpers/args_utils.py
+++ b/cfg_checker/helpers/args_utils.py
@@ -2,7 +2,8 @@
 import os
 import sys
 
-from cfg_checker.common.exception import ConfigException
+from cfg_checker.common.exception import ConfigException, \
+    CommandTypeNotSupportedException, CheckerException
 
 
 class MyParser(argparse.ArgumentParser):
@@ -70,3 +71,61 @@
             return 'csv', args.csv
     else:
         raise ConfigException("Report type and filename not set")
+
+
+def check_supported_env(target_env, args, config):
+    def _raise_type_not_supported():
+        raise CommandTypeNotSupportedException(
+                "'{}' -> '{}' is not supported on any of "
+                "the currently detected environments: "
+                "{}".format(
+                    args.command,
+                    args.type,
+                    ",".join(config.detected_envs))
+        )
+
+    def _check_target_vs_used(_tenv):
+        if not hasattr(args, 'use_env'):
+            return _tenv
+        elif args.use_env == _tenv or not args.use_env:
+            return _tenv
+        else:
+            raise CommandTypeNotSupportedException(
+                    "'{}' -> '{}' is not supported "
+                    "for selected env of '{}'".format(
+                        args.command,
+                        args.type,
+                        args.use_env
+                        )
+            )
+
+    if isinstance(target_env, list):
+        _set = set(config.detected_envs).intersection(set(target_env))
+        if len(_set) < 1:
+            _raise_type_not_supported()
+        if len(_set) > 1:
+            if not hasattr(args, 'use_env'):
+                raise CheckerException(
+                    "Multiple envs detected: {}, use --use-env option".format(
+                        ",".join(list(_set))
+                    )
+                )
+            elif args.use_env and args.use_env in _set:
+                return args.use_env
+            else:
+                _raise_type_not_supported()
+        else:
+            return _check_target_vs_used(list(_set)[0])
+    elif isinstance(target_env, str):
+        if target_env not in config.detected_envs:
+            _raise_type_not_supported()
+        else:
+            return _check_target_vs_used(target_env)
+    else:
+        raise CheckerException(
+            "Unexpected target env type '{}' in '{}' -> '{}'".format(
+                target_env,
+                args.command,
+                args.type,
+            )
+        )