WIP for network check
diff --git a/cfg_checker/cfg_check.py b/cfg_checker/cfg_check.py
index b2e3886..8a05771 100644
--- a/cfg_checker/cfg_check.py
+++ b/cfg_checker/cfg_check.py
@@ -9,6 +9,7 @@
 from cfg_checker.clients import salt
 
 from cfg_checker.pkg_check import CloudPackageChecker
+from cfg_checker.network_checks import NetworkChecker
 
 pkg_dir = os.path.dirname(__file__)
 pkg_dir = os.path.normpath(pkg_dir)
@@ -47,13 +48,17 @@
 
 
 def net_check(args):
-    print("This is net check routine")
+    netChecker = NetworkChecker()
+    netChecker.collect_network_info()
+    netChecker.print_network_report()
 
     return
 
 
 def net_report(args):
-    print("This is net check routine")
+    netChecker = NetworkChecker()
+    netChecker.collect_network_info()
+    netChecker.create_html_report()
 
     return
 
diff --git a/cfg_checker/network_checks.py b/cfg_checker/network_checks.py
new file mode 100644
index 0000000..56b25de
--- /dev/null
+++ b/cfg_checker/network_checks.py
@@ -0,0 +1,81 @@
+import json
+import os
+import sys
+
+from copy import deepcopy
+
+import reporter
+
+from cfg_checker.common import utils, const
+from cfg_checker.common import config, logger, logger_cli, pkg_dir
+from cfg_checker.common import salt_utils
+from cfg_checker.nodes import SaltNodes, node_tmpl
+
+
+class NetworkChecker(SaltNodes):
+    def collect_network_info(self):
+        """
+        Collects info on the network using ifs_data.py script
+
+        :return: none
+        """
+        logger_cli.info("### Collecting network data")
+        _result = self.execute_script("ifs_data.py", args=["json"])
+
+        for key in self.nodes.keys():
+            # due to much data to be passed from salt, it is happening in order
+            if key in _result:
+                _text = _result[key]
+                _dict = json.loads(_text[_text.find('{'):])
+                self.nodes[key]['networks'] = _dict
+            else:
+                self.nodes[key]['networks'] = {}
+            logger_cli.debug("# {} has {} networks".format(
+                key,
+                len(self.nodes[key]['networks'].keys())
+            ))
+        logger_cli.info("-> Done collecting networks data")
+
+        return
+
+    def print_network_report(self):
+        """
+        Create text report for CLI
+
+        :return: none
+        """
+        
+        return
+    
+    def create_html_report(self, filename):
+        """
+        Create static html showing network schema-like report
+
+        :return: none
+        """
+        logger_cli.info("### Generating report to '{}'".format(filename))
+        _report = reporter.ReportToFile(
+            reporter.HTMLNetworkReport(),
+            filename
+        )
+        _report({
+            "nodes": self.nodes,
+            "diffs": {}
+        })
+        logger_cli.info("-> Done")
+
+
+if __name__ == '__main__':
+    # init connection to salt and collect minion data
+    cl = NetworkChecker()
+
+    # collect data on installed packages
+    cl.collect_network_info()
+
+    # diff installed and candidates
+    # cl.collect_packages()
+
+    # report it
+    cl.create_html_report("./pkg_versions.html")
+
+    sys.exit(0)
diff --git a/cfg_checker/nodes.py b/cfg_checker/nodes.py
new file mode 100644
index 0000000..1f2b9f6
--- /dev/null
+++ b/cfg_checker/nodes.py
@@ -0,0 +1,125 @@
+import json
+import os
+import sys
+
+from  copy import deepcopy
+
+from cfg_checker.common import utils, const
+from cfg_checker.common import config, logger, logger_cli, pkg_dir
+from cfg_checker.common import salt_utils
+
+node_tmpl = {
+    'role': '',
+    'node_group': '',
+    'status': const.NODE_DOWN,
+    'pillars': {},
+    'grains': {}
+}
+
+
+class SaltNodes(object):
+    def __init__(self):
+        logger_cli.info("### Collecting nodes for package check")
+        # simple salt rest client
+        self.salt = salt_utils.SaltRemote()
+
+        # Keys for all nodes
+        # this is not working in scope of 2016.8.3, will overide with list
+        # cls.node_keys = cls.salt.list_keys()
+
+        logger_cli.info("### Collecting node names existing in the cloud")
+        self.node_keys = {
+            'minions': config.all_nodes
+        }
+
+        # all that answer ping
+        _active = self.salt.get_active_nodes()
+        logger_cli.debug("-> Nodes responded: {}".format(_active))
+        # just inventory for faster interaction
+        # iterate through all accepted nodes and create a dict for it
+        self.nodes = {}
+        for _name in self.node_keys['minions']:
+            _nc = utils.get_node_code(_name)
+            _rmap = const.all_roles_map
+            _role = _rmap[_nc] if _nc in _rmap else 'unknown'
+            _status = const.NODE_UP if _name in _active else const.NODE_DOWN
+
+            self.nodes[_name] = deepcopy(node_tmpl)
+            self.nodes[_name]['node_group'] = _nc
+            self.nodes[_name]['role'] = _role
+            self.nodes[_name]['status'] = _status
+
+        logger_cli.info("-> {} nodes collected".format(len(self.nodes)))
+
+    def get_nodes(self):
+        return self.nodes
+    
+    def execute_script(self, script_filename, args=[]):
+        # form an all nodes compound string to use in salt
+        _active_nodes_string = self.salt.compound_string_from_list(
+            filter(
+                lambda nd: self.nodes[nd]['status'] == const.NODE_UP,
+                self.nodes
+            )
+        )
+        # Prepare script
+        _p = os.path.join(pkg_dir, 'scripts', script_filename)
+        with open(_p, 'rt') as fd:
+            _script = fd.read().splitlines()
+        _storage_path = os.path.join(
+            config.salt_file_root, config.salt_scripts_folder
+        )
+        logger_cli.debug(
+            "# Uploading script {} to master's file cache folder: '{}'".format(
+                script_filename,
+                _storage_path
+            )
+        )
+        _result = self.salt.mkdir("cfg01*", _storage_path)
+        # Form cache, source and target path
+        _cache_path = os.path.join(_storage_path, script_filename)
+        _source_path = os.path.join(
+            'salt://',
+            config.salt_scripts_folder,
+            script_filename
+        )
+        _target_path = os.path.join(
+            '/root',
+            config.salt_scripts_folder,
+            script_filename
+        )
+
+        logger_cli.debug("# Creating file in cache '{}'".format(_cache_path))
+        _result = self.salt.f_touch_master(_cache_path)
+        _result = self.salt.f_append_master(_cache_path, _script)
+        # command salt to copy file to minions
+        logger_cli.debug("# Creating script target folder '{}'".format(_cache_path))
+        _result = self.salt.mkdir(
+            _active_nodes_string,
+            os.path.join(
+                '/root',
+                config.salt_scripts_folder
+            ),
+            tgt_type="compound"
+        )
+        logger_cli.info("-> Running script to all active nodes")
+        _result = self.salt.get_file(
+            _active_nodes_string,
+            _source_path,
+            _target_path,
+            tgt_type="compound"
+        )
+        # execute pkg collecting script
+        logger.debug("Running script to all nodes")
+        # handle results for each node
+        _script_arguments = " ".join(args) if args else ""
+        _result = self.salt.cmd(
+            _active_nodes_string,
+            'cmd.run',
+            param='python {} {}'.format(_target_path, _script_arguments),
+            expr_form="compound"
+        )
+
+        # TODO: Handle error result
+
+        return _result
diff --git a/cfg_checker/pkg_check.py b/cfg_checker/pkg_check.py
index fe34f60..e9c312e 100644
--- a/cfg_checker/pkg_check.py
+++ b/cfg_checker/pkg_check.py
@@ -9,50 +9,10 @@
 from cfg_checker.common import utils, const
 from cfg_checker.common import config, logger, logger_cli, pkg_dir
 from cfg_checker.common import salt_utils
-
-node_tmpl = {
-    'role': '',
-    'node_group': '',
-    'status': const.NODE_DOWN,
-    'pillars': {},
-    'grains': {}
-}
+from cfg_checker.nodes import SaltNodes, node_tmpl
 
 
-class CloudPackageChecker(object):
-    def __init__(self):
-        logger_cli.info("### Collecting nodes for package check")
-        # simple salt rest client
-        self.salt = salt_utils.SaltRemote()
-
-        # Keys for all nodes
-        # this is not working in scope of 2016.8.3, will overide with list
-        # cls.node_keys = cls.salt.list_keys()
-
-        logger_cli.info("### Collecting node names existing in the cloud")
-        self.node_keys = {
-            'minions': config.all_nodes
-        }
-
-        # all that answer ping
-        _active = self.salt.get_active_nodes()
-        logger_cli.debug("-> Nodes responded: {}".format(_active))
-        # just inventory for faster interaction
-        # iterate through all accepted nodes and create a dict for it
-        self.nodes = {}
-        for _name in self.node_keys['minions']:
-            _nc = utils.get_node_code(_name)
-            _rmap = const.all_roles_map
-            _role = _rmap[_nc] if _nc in _rmap else 'unknown'
-            _status = const.NODE_UP if _name in _active else const.NODE_DOWN
-
-            self.nodes[_name] = deepcopy(node_tmpl)
-            self.nodes[_name]['node_group'] = _nc
-            self.nodes[_name]['role'] = _role
-            self.nodes[_name]['status'] = _status
-
-        logger_cli.info("-> {} nodes collected".format(len(self.nodes)))
-
+class CloudPackageChecker(SaltNodes):
     def collect_installed_packages(self):
         """
         Collect installed packages on each node
@@ -61,70 +21,8 @@
         :return: none
         """
         logger_cli.info("### Collecting installed packages")
-        # form an all nodes compound string to use in salt
-        _active_nodes_string = self.salt.compound_string_from_list(
-            filter(
-                lambda nd: self.nodes[nd]['status'] == const.NODE_UP,
-                self.nodes
-            )
-        )
-        # Prepare script
-        _script_filename = "pkg_versions.py"
-        _p = os.path.join(pkg_dir, 'scripts', _script_filename)
-        with open(_p, 'rt') as fd:
-            _script = fd.read().splitlines()
-        _storage_path = os.path.join(
-            config.salt_file_root, config.salt_scripts_folder
-        )
-        logger_cli.debug(
-            "# Uploading script {} to master's file cache folder: '{}'".format(
-                _script_filename,
-                _storage_path
-            )
-        )
-        _result = self.salt.mkdir("cfg01*", _storage_path)
-        # Form cache, source and target path
-        _cache_path = os.path.join(_storage_path, _script_filename)
-        _source_path = os.path.join(
-            'salt://',
-            config.salt_scripts_folder,
-            _script_filename
-        )
-        _target_path = os.path.join(
-            '/root',
-            config.salt_scripts_folder,
-            _script_filename
-        )
+        _result = self.execute_script("pkg_versions.py")
 
-        logger_cli.debug("# Creating file in cache '{}'".format(_cache_path))
-        _result = self.salt.f_touch_master(_cache_path)
-        _result = self.salt.f_append_master(_cache_path, _script)
-        # command salt to copy file to minions
-        logger_cli.debug("# Creating script target folder '{}'".format(_cache_path))
-        _result = self.salt.mkdir(
-            _active_nodes_string,
-            os.path.join(
-                '/root',
-                config.salt_scripts_folder
-            ),
-            tgt_type="compound"
-        )
-        logger_cli.info("-> Running script to all active nodes")
-        _result = self.salt.get_file(
-            _active_nodes_string,
-            _source_path,
-            _target_path,
-            tgt_type="compound"
-        )
-        # execute pkg collecting script
-        logger.debug("Running script to all nodes")
-        # handle results for each node
-        _result = self.salt.cmd(
-            _active_nodes_string,
-            'cmd.run',
-            param='python {}'.format(_target_path),
-            expr_form="compound"
-        )
         for key in self.nodes.keys():
             # due to much data to be passed from salt, it is happening in order
             if key in _result:
diff --git a/cfg_checker/reporter.py b/cfg_checker/reporter.py
index 3b21894..a0eb1b3 100644
--- a/cfg_checker/reporter.py
+++ b/cfg_checker/reporter.py
@@ -156,6 +156,14 @@
         data['counters']['mdl_diff'] = len(data["diffs"].keys())
 
 
+class HTMLNetworkReport(_TMPLBase):
+    tmpl = "network_check_tmpl.j2"
+
+    def _extend_data(self, data):
+
+        return
+
+
 class ReportToFile(object):
     def __init__(self, report, target):
         self.report = report