Skip nodes functionality for Package and Network modules

Added to main entrypoint
- Skip nodes using simple argument with '*' as a trailing wildcard
- Skip nodes using file list

Usability improovement
- Node list preview in status line
- Node stats alignment in net report

Minor fixes:
- Python version detection (3.5+)
- Node counter for each status
- Proper node skip handling

Change-Id: I086ef501bc06f0e739df25349257f1c63a2e2fcf
Related-PROD: PROD-35009
diff --git a/cfg_checker/modules/network/__init__.py b/cfg_checker/modules/network/__init__.py
index 71df82d..28d08c4 100644
--- a/cfg_checker/modules/network/__init__.py
+++ b/cfg_checker/modules/network/__init__.py
@@ -71,7 +71,11 @@
     # should not print map, etc...
     # Just bare summary and errors
     logger_cli.info("# Network check to console")
-    netChecker = checker.NetworkChecker()
+    _skip, _skip_file = args_utils.get_skip_args(args)
+    netChecker = checker.NetworkChecker(
+        skip_list=_skip,
+        skip_list_file=_skip_file
+    )
     netChecker.check_networks()
 
     # save what was collected
@@ -93,8 +97,11 @@
     logger_cli.info("# Network report (check, node map")
 
     _filename = args_utils.get_arg(args, 'html')
-
-    netChecker = checker.NetworkChecker()
+    _skip, _skip_file = args_utils.get_skip_args(args)
+    netChecker = checker.NetworkChecker(
+        skip_list=_skip,
+        skip_list_file=_skip_file
+    )
     netChecker.check_networks(map=False)
 
     # save what was collected
@@ -108,8 +115,11 @@
     # Network Map
     # Should generate network map to console or HTML
     logger_cli.info("# Network report")
-
-    networkMap = mapper.NetworkMapper()
+    _skip, _skip_file = args_utils.get_skip_args(args)
+    networkMap = mapper.NetworkMapper(
+        skip_list=_skip,
+        skip_list_file=_skip_file
+    )
     networkMap.prepare_all_maps()
     networkMap.create_map()
     networkMap.print_map()
@@ -120,7 +130,11 @@
 def do_list(args):
     # Network List
     # Should generate network map to console or HTML
-    _map = mapper.NetworkMapper()
+    _skip, _skip_file = args_utils.get_skip_args(args)
+    _map = mapper.NetworkMapper(
+        skip_list=_skip,
+        skip_list_file=_skip_file
+    )
     reclass = _map.map_network(_map.RECLASS)
     runtime = _map.map_network(_map.RUNTIME)
 
@@ -141,7 +155,13 @@
     if not args.cidr:
         logger_cli.error("\n# Use mcp-check network list to get list of CIDRs")
     _cidr = args_utils.get_arg(args, "cidr")
-    _pinger = pinger.NetworkPinger(mtu=args.mtu, detailed=args.detailed)
+    _skip, _skip_file = args_utils.get_skip_args(args)
+    _pinger = pinger.NetworkPinger(
+        mtu=args.mtu,
+        detailed=args.detailed,
+        skip_list=_skip,
+        skip_list_file=_skip_file
+    )
 
     _ret = _pinger.ping_nodes(_cidr)
 
diff --git a/cfg_checker/modules/network/checker.py b/cfg_checker/modules/network/checker.py
index acd3bb1..c590d13 100644
--- a/cfg_checker/modules/network/checker.py
+++ b/cfg_checker/modules/network/checker.py
@@ -5,10 +5,18 @@
 
 
 class NetworkChecker(object):
-    def __init__(self):
+    def __init__(
+        self,
+        skip_list=None,
+        skip_list_file=None
+    ):
         logger_cli.debug("... init error logs folder")
         self.errors = NetworkErrors()
-        self.mapper = NetworkMapper(self.errors)
+        self.mapper = NetworkMapper(
+            self.errors,
+            skip_list=skip_list,
+            skip_list_file=skip_list_file
+        )
 
     def check_networks(self, map=True):
         self.mapper.map_network(self.mapper.RECLASS)
@@ -41,6 +49,7 @@
             filename
         )
         _report({
+            "domain": self.mapper.domain,
             "nodes": self.mapper.nodes,
             "map": self.mapper.map,
             "mcp_release": self.mapper.cluster['mcp_release'],
diff --git a/cfg_checker/modules/network/mapper.py b/cfg_checker/modules/network/mapper.py
index 483c11f..51f52bb 100644
--- a/cfg_checker/modules/network/mapper.py
+++ b/cfg_checker/modules/network/mapper.py
@@ -31,12 +31,21 @@
     CONFIG = "config"
     RUNTIME = "runtime"
 
-    def __init__(self, errors_class=None):
+    def __init__(
+        self,
+        errors_class=None,
+        skip_list=None,
+        skip_list_file=None
+    ):
         logger_cli.info("# Initializing mapper")
         # init networks and nodes
         self.networks = {}
-        self.nodes = salt_master.get_nodes()
+        self.nodes = salt_master.get_nodes(
+            skip_list=skip_list,
+            skip_list_file=skip_list_file
+        )
         self.cluster = salt_master.get_info()
+        self.domain = salt_master.domain
         # init and pre-populate interfaces
         self.interfaces = {k: {} for k in self.nodes}
         # Init errors class
diff --git a/cfg_checker/modules/network/pinger.py b/cfg_checker/modules/network/pinger.py
index 0500284..5b12a94 100644
--- a/cfg_checker/modules/network/pinger.py
+++ b/cfg_checker/modules/network/pinger.py
@@ -10,10 +10,21 @@
 
 # This is independent class with a salt.nodes input
 class NetworkPinger(object):
-    def __init__(self, mtu=None, detailed=False, errors_class=None):
+    def __init__(
+        self,
+        mtu=None,
+        detailed=False,
+        errors_class=None,
+        skip_list=None,
+        skip_list_file=None
+    ):
         logger_cli.info("# Initializing")
         # all active nodes in the cloud
-        self.target_nodes = salt_master.get_nodes()
+        self.target_nodes = salt_master.get_nodes(
+            skip_list=skip_list,
+            skip_list_file=skip_list_file
+        )
+
         # default MTU value
         self.target_mtu = mtu if mtu else 64
         # only data
diff --git a/cfg_checker/modules/packages/__init__.py b/cfg_checker/modules/packages/__init__.py
index 41dfca1..2d0cc79 100644
--- a/cfg_checker/modules/packages/__init__.py
+++ b/cfg_checker/modules/packages/__init__.py
@@ -112,9 +112,12 @@
         _kw = [args.exclude_keywords]
 
     # init connection to salt and collect minion data
+    _skip, _skip_file = args_utils.get_skip_args(args)
     pChecker = checker.CloudPackageChecker(
         force_tag=args.force_tag,
-        exclude_keywords=_kw
+        exclude_keywords=_kw,
+        skip_list=_skip,
+        skip_list_file=_skip_file
     )
     # collect data on installed packages
     pChecker.collect_installed_packages()
diff --git a/cfg_checker/modules/packages/checker.py b/cfg_checker/modules/packages/checker.py
index 8f30f3c..fb02db2 100644
--- a/cfg_checker/modules/packages/checker.py
+++ b/cfg_checker/modules/packages/checker.py
@@ -12,10 +12,19 @@
 
 
 class CloudPackageChecker(object):
-    def __init__(self, force_tag=None, exclude_keywords=[]):
+    def __init__(
+        self,
+        force_tag=None,
+        exclude_keywords=[],
+        skip_list=None,
+        skip_list_file=None
+    ):
         # Init salt master info
         if not salt_master.nodes:
-            salt_master.nodes = salt_master.get_nodes()
+            salt_master.nodes = salt_master.get_nodes(
+                skip_list=skip_list,
+                skip_list_file=skip_list_file
+            )
 
         # check that this env tag is present in Manager
         self.rm = RepoManager()
@@ -57,6 +66,7 @@
         _data['status_err'] = const.VERSION_ERR
         _data['status_warn'] = const.VERSION_WARN
         _data['status_down'] = const.VERSION_DOWN
+        _data['status_skip'] = const.VERSION_NA
 
         # Presort packages
         _data['critical'] = {}
diff --git a/cfg_checker/modules/reclass/comparer.py b/cfg_checker/modules/reclass/comparer.py
index 47e4baf..3c308e0 100644
--- a/cfg_checker/modules/reclass/comparer.py
+++ b/cfg_checker/modules/reclass/comparer.py
@@ -151,11 +151,15 @@
             # ignore _source key
             if k == "_source":
                 continue
-            # ignore secrets
+            # ignore secrets and other secure stuff
             if isinstance(k, str) and k == "secrets.yml":
                 continue
             if isinstance(k, str) and k.find("_password") > 0:
                 continue
+            if isinstance(k, str) and k.find("_key") > 0:
+                continue
+            if isinstance(k, str) and k.find("_token") > 0:
+                continue
             # check if this is an env name cluster entry
             if dict2 is not None and \
                     k == self.model_name_1 and \