Command execution structure and error handling
diff --git a/cfg_checker/cfg_check.py b/cfg_checker/cfg_check.py
index 02205ea..a10d4a0 100644
--- a/cfg_checker/cfg_check.py
+++ b/cfg_checker/cfg_check.py
@@ -5,6 +5,7 @@
 from logging import INFO,  DEBUG
 
 import reporter
+from cfg_checker.common.exception import ConfigException
 from cfg_checker.common import utils, const
 from cfg_checker.common import config, logger, logger_cli, pkg_dir
 from cfg_checker.clients import salt
@@ -15,6 +16,11 @@
 pkg_dir = os.path.dirname(__file__)
 pkg_dir = os.path.normpath(pkg_dir)
 
+commands = {
+    'packages': ['report'],
+    'network': ['check', 'report'],
+    'reclass': ['list', 'diff']
+}
 
 class MyParser(argparse.ArgumentParser):
     def error(self, message):
@@ -31,13 +37,22 @@
     """
     return
 
-def pkg_check(args):
-    # create package versions report
+
+def get_file_arg(args):
     if args.file:
-        _filename = args.file
+        return args.file
     else:
-        logger_cli.error("ERROR: no report filename supplied")
-        return
+        raise ConfigException("No report filename supplied")
+
+
+def packages_report(args):
+    """Create package versions report
+
+    :args: - parser arguments
+    :return: - no return value
+    """
+    _filename = get_file_arg(args)
+
     # init connection to salt and collect minion data
     pChecker = CloudPackageChecker()
     # collect data on installed packages
@@ -48,7 +63,8 @@
     pChecker.create_html_report(_filename)
 
 
-def net_check(args):
+def network_check(args):
+    logger_cli.info("# Network check (CLI output)")
     netChecker = NetworkChecker()
     netChecker.collect_network_info()
     netChecker.print_network_report()
@@ -56,23 +72,64 @@
     return
 
 
-def net_report(args):
+def network_report(args):
+    logger_cli.info("# Network check (HTML report: '{}')".format(args.file))
+    _filename = get_file_arg(args)
+
     netChecker = NetworkChecker()
     netChecker.collect_network_info()
-    netChecker.create_html_report()
+    netChecker.create_html_report(_filename)
+
+    return
+
+
+def reclass_list(args):
+    logger_cli.info("Reclass list: to be implemented")
+
+    return
+
+
+def reclass_diff(args):
+    logger_cli.info("Reclass comparer (HTML report: '{}'".format(args.file))
+    _filename = get_file_arg(args)
 
     return
 
 
 def config_check_entrypoint():
+    """
+    Main entry point. Uses nested parsers structure 
+    with a default function to execute the comand
+
+    :return: - no return value
+    """
     # Main entrypointр
     parser = MyParser(prog="Cloud configuration checker")
+    
+    # Parsers (each parser can have own arguments)
+    # - subparsers (command)
+    #   |- pkg_parser
+    #   |  - pkg_subparsers (type)
+    #   |    - pkg_report_parser (default func - pkg_check)
+    #   |- net_parser
+    #   |  - net_subparsers (type)
+    #   |    - net_check_parser (default func - net_check)
+    #   |    - net_report_parser (default func - net_report)
+    #    - reclass_parser
+    #      - reclass_list (default func - reclass_list)
+    #      - reclass_compare (default func - reclass_diff)
+
     parser.add_argument(
         "-d",
         "--debug",
         action="store_true", default=False,
         help="Set CLI logging level to DEBUG"
     )
+    parser.add_argument(
+        '-f',
+        '--file',
+        help="HTML filename to save report"
+    )
     subparsers = parser.add_subparsers(dest='command')
     # packages
     pkg_parser = subparsers.add_parser(
@@ -85,17 +142,11 @@
         'report',
         help="Report package versions to HTML file"
     )
-    pkg_report_parser.add_argument(
-        '-f',
-        '--file',
-        help="HTML filename to save report"
-    )
-    pkg_report_parser.set_defaults(func=pkg_check)
 
     # networking
     net_parser = subparsers.add_parser(
         'network',
-        help="Network infrastructure checks"
+        help="Network infrastructure checks and reports"
     )
     net_subparsers = net_parser.add_subparsers(dest='type')
 
@@ -103,21 +154,34 @@
         'check',
         help="Do network check and print the result"
     )
-    net_check_parser.set_defaults(func=net_check)
 
     net_report_parser = net_subparsers.add_parser(
         'report',
         help="Generate network check report"
     )
-    net_report_parser.add_argument(
-        '-f',
-        '--file',
-        help="HTML filename to save report"
-    )
-    net_report_parser.set_defaults(func=net_report)
     
+    # reclass
+    reclass_parser = subparsers.add_parser(
+        'reclass',
+        help="Reclass related checks and reports"
+    )
+    reclass_subparsers = reclass_parser.add_subparsers(dest='type')
+    reclass_list_parser = reclass_subparsers.add_parser(
+        'list',
+        help="List models available to compare"
+    )
+
+    reclass_diff_parser = reclass_subparsers.add_parser(
+        'diff',
+        help="List models available to compare"
+    )
+
     #parse arguments
-    args = parser.parse_args()
+    try:
+        args = parser.parse_args()
+    except TypeError as e:
+        logger_cli.info("\nPlease, check arguments")
+        return
 
     # Handle options
     if args.debug:
@@ -125,16 +189,34 @@
     else:
         logger_cli.setLevel(INFO)
 
+    # Validate the commands
+    # check command
+    if args.command not in commands:
+        logger_cli.info("\nPlease, type a command listed above")
+        return
+    elif args.type not in commands[args.command]:
+        # check type
+        logger_cli.info(
+            "\nPlease, select '{}' command type listed above".format(
+                args.command
+            )
+        )
+        return
+    else:
+        # form function name to call
+        _method_name = args.command + "_" + args.type
+        _this_module = sys.modules[__name__]
+        _method = getattr(_this_module, _method_name)
+    
     # Execute the command
-    result = args.func(args)
+    result = _method(args)
 
     logger.debug(result)
-    return
 
 if __name__ == '__main__':
     try:
         config_check_entrypoint()
-    except Exception as e:
+    except ConfigException as e:
         exc_type, exc_value, exc_traceback = sys.exc_info()
         logger_cli.error("\nERROR: {}\n\n{}".format(
             e.message,
diff --git a/cfg_checker/network_checks.py b/cfg_checker/network_checks.py
index 7c2e69d..7daa673 100644
--- a/cfg_checker/network_checks.py
+++ b/cfg_checker/network_checks.py
@@ -89,6 +89,11 @@
         # save collected info
         self.all_networks = _all_nets
 
+        # Get networks from reclass
+        # TODO: 
+
+        return
+
     def print_network_report(self):
         """
         Create text report for CLI