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/common/exception.py b/cfg_checker/common/exception.py
index 2536099..4ee3a99 100644
--- a/cfg_checker/common/exception.py
+++ b/cfg_checker/common/exception.py
@@ -19,18 +19,50 @@
         self.message = "# Configuration error: {}".format(message)
 
 
+class CommandNotSupportedException(CheckerException):
+    def __init__(self, message, *args, **kwargs):
+        super(CommandNotSupportedException, self).__init__(
+            message,
+            *args,
+            **kwargs
+        )
+        self.message = "# Command not supported: {}".format(message)
+
+
+class CommandTypeNotSupportedException(CheckerException):
+    def __init__(self, message, *args, **kwargs):
+        super(CommandTypeNotSupportedException, self).__init__(
+            message,
+            *args,
+            **kwargs
+        )
+        self.message = "# Command type not supported: {}".format(message)
+
+
 class SaltException(CheckerException):
     def __init__(self, message, *args, **kwargs):
         super(SaltException, self).__init__(message, *args, **kwargs)
         self.message = "# Salt error: {}".format(message)
 
 
+class KubeException(CheckerException):
+    def __init__(self, message, *args, **kwargs):
+        super(KubeException, self).__init__(message, *args, **kwargs)
+        self.message = "# Kube client error: {}".format(message)
+
+
 class InvalidReturnException(CheckerException):
     def __init__(self, message, *args, **kwargs):
         super(InvalidReturnException, self).__init__(message, *args, **kwargs)
         self.message = "# Unexpected return value: {}".format(message)
 
 
+class TimeoutException(CheckerException):
+    def __init__(self, message, *args, **kwargs):
+        super(TimeoutException, self).__init__(message, *args, **kwargs)
+        self.message = "# Timed out waiting: {}".format(message)
+
+
 class ErrorMappingException(CheckerException):
     def __init__(self, message, *args, **kwargs):
         super(ErrorMappingException, self).__init__(message, *args, **kwargs)