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/cli/command.py b/cfg_checker/cli/command.py
index f98e608..566a498 100644
--- a/cfg_checker/cli/command.py
+++ b/cfg_checker/cli/command.py
@@ -2,8 +2,11 @@
 import sys
 import traceback
 
-from cfg_checker.common import config, logger, logger_cli
-from cfg_checker.common.exception import CheckerException
+from cfg_checker.cli.arguments import add_global_arguments
+from cfg_checker.common import logger, logger_cli
+from cfg_checker.common.exception import CheckerException, \
+    CommandNotSupportedException
+from cfg_checker.common.settings import CheckerConfiguration
 from cfg_checker.helpers.args_utils import MyParser
 
 main_pkg_name = __name__.split('.')[0]
@@ -12,6 +15,7 @@
 mods_prefix = mods_import_path + '.'
 
 commands = {}
+supports = {}
 parsers_inits = {}
 parsers = {}
 helps = {}
@@ -27,16 +31,16 @@
         # A package! Create it and add commands
         commands[mod_name] = \
             [_n[3:] for _n in dir(_p) if _n.startswith("do_")]
+        supports[mod_name] = _p.supported_envs
         parsers_inits[mod_name] = getattr(_p, 'init_parser')
         parsers[mod_name] = {}
         helps[mod_name] = getattr(_p, 'command_help')
 
 
-def execute_command(args, command):
+def execute_command(args, command, config):
     # Validate the commands
     # check commands
     if command not in commands:
-        
         logger_cli.info("\n# Please, type a command listed above")
         return 1
     if not hasattr(args, 'type') or not args.type:
@@ -53,6 +57,19 @@
         )
         return 1
     else:
+        # check if command is supported
+        if len(
+            set(supports[command]).intersection(set(config.detected_envs))
+        ) < 1:
+            raise CommandNotSupportedException(
+                "'{}' is not supported on any of the currently "
+                "detected environments: {}".format(
+                    command,
+                    ",".join(config.detected_envs)
+                )
+            )
+            return 1
+
         # form function name to call
         _method_name = "do_" + _type
         _target_module = __import__(
@@ -63,12 +80,16 @@
 
     # Execute the command
     try:
-        _method(args)
+        # Compatibility between entrypoints
+        if not hasattr(args, 'command'):
+            args.command = command
+        _method(args, config)
         return 0
+    except CommandNotSupportedException as e:
+        logger_cli.error("\n{}".format(e.message))
+        return 1
     except CheckerException as e:
-        logger_cli.error("\nERROR: {}".format(
-            e.message
-        ))
+        logger_cli.error("\n{}".format(e.message))
 
         exc_type, exc_value, exc_traceback = sys.exc_info()
         logger_cli.debug("\n{}".format(
@@ -87,6 +108,7 @@
 
     # parse arguments
     try:
+        add_global_arguments(my_parser)
         args, unknown = my_parser.parse_known_args()
     except TypeError:
         logger_cli.info("\n# Please, check arguments")
@@ -100,10 +122,18 @@
         )
         sys.exit(1)
 
+    # Init the config
+    config = CheckerConfiguration(args)
+
     # force use of sudo
     config.ssh_uses_sudo = True
 
     # Execute the command
-    result = execute_command(args, _name)
-    logger.debug(result)
+    try:
+        result = execute_command(args, _name, config)
+        logger.debug(result)
+    except CommandNotSupportedException as e:
+        logger_cli.error("\nERROR: {}".format(
+            e.message
+        ))
     sys.exit(result)