Rework CLI, add list-domains
diff --git a/README.md b/README.md
index 91557b2..f2d6c1d 100644
--- a/README.md
+++ b/README.md
@@ -12,9 +12,20 @@
 
     This tool can be used to create a new class 'environment' generated from custom inventory.
 
-    # 1. See the nodes in reclass inventory:
+    # See all the nodes available from reclass inventory (including generated nodes):
+    reclass-tools list-nodes
 
-    reclass-inventory-list
+    # See only VCP nodes for specific domain:
+    reclass-tools list-nodes -d mcp11-ovs-dpdk.local --vcp-only
+
+    # See only non-VCP nodes for specific domain (baremetal nodes):
+    reclass-tools list-nodes -d mcp11-ovs-dpdk.local --non-vcp-only
+
+    # Find specific key in the path (without reclass render):
+    reclass-tools get-key parameters._param.cluster_domain /srv/salt/reclass/classes/cluster/physical_mcp11_ovs_dpdk/
+
+    # Collect all parameters._param into a single dict, to track _param changes from commit to commit:
+    reclass-tools list-params /srv/salt/reclass/classes/
 
 Requirements
 ------------
@@ -26,39 +37,44 @@
 Create 'environment' class
 --------------------------
 
-    # This is a PoC of creating the 'environment' class.
-    # For CI tests, please generate your 'inventory.yaml' for step #3 and create
-    # the cookiecutter template based on example template from /examples directory.
+This is a PoC of creating the 'environment' class.
+For CI tests, please generate your 'inventory.yaml' for step #3 and create
+the cookiecutter template based on example template from /examples directory.
 
-    # Below will be used 'cluster' model from 'mcp-baremetal-lab' repo
-    # and the cluster name 'mcp11-ovs-dpdk.local'.
+For this example will be used the 'cluster' model 'mcp11-ovs-dpdk.local'
+from 'mcp-baremetal-lab' repo.
 
-    # 1. Create a context file from the current reclass inventory:
+All steps should be performed on the installed salt-master node, when all
+nodes have been generated with 'reclass.storage' state.
 
-    reclass-create-inventory-context -d mcp11-ovs-dpdk.local > /tmp/context-mcp11-ovs-dpdk.local.yaml
+1. Create a context file with nodes list and 'linux.network.interface' configuration
+from the current reclass inventory.
 
-    # 2. Remove existing hardware-related objects from 'cluster', 'system' and 'service' classes:
+    reclass-tools show-context -d mcp11-ovs-dpdk.local parameters.linux.network.interface > /tmp/context-mcp11-ovs-dpdk.local.yaml
 
-    reclass-remove-key parameters.linux.network.interface /srv/salt/reclass/classes/cluster/physical_mcp11_ovs_dpdk
-    reclass-remove-key parameters.linux.network.interface /srv/salt/reclass/classes/system/
-    reclass-remove-key parameters.linux.network.interface /usr/share/salt-formulas/reclass/
+2. Remove existing hardware-related 'linux.network.interface' object from 'cluster', 'system' and 'service' classes.
+WARNING! Make sure that you have created the context file with 'linux.network.interface' as a backup.
 
-    # 3. Render the 'environment' class using example template based on cookiecutter:
+    reclass-tools del-key parameters.linux.network.interface /srv/salt/reclass/classes/cluster/physical_mcp11_ovs_dpdk
+    reclass-tools del-key parameters.linux.network.interface /srv/salt/reclass/classes/system/
+    reclass-tools del-key parameters.linux.network.interface /usr/share/salt-formulas/reclass/
+
+3. Render the 'environment' class using example template based on cookiecutter:
 
     git clone https://github.com/dis-xcom/reclass_tools ~/reclass_tools
-    reclass-render-dir -t ~/reclass_tools/examples/environment -o /tmp/environment -c /tmp/context-mcp11-ovs-dpdk.local.yaml  # You can add multiple YAMLs here
+    reclass-tools render -t ~/reclass_tools/examples/environment -o /tmp/environment -c /tmp/context-mcp11-ovs-dpdk.local.yaml  # You can add multiple YAMLs here
 
-    # 4. Check that the 'environment' has been created
+4. Check that the 'environment' has been created
 
     tree /tmp/environment/
 
-    # 5. Symlink 'environment' to the /srv/salt/reclass/classes
+5. Symlink 'environment' to the /srv/salt/reclass/classes
 
     ln -s /tmp/environment /srv/reclass/salt/classes
 
-    # 6. Add new class '- environment.mcp11-ovs-dpdk.local' to the classes/cluster/<cluster_model>/infra/config.yml
-    # (edit the file manually for now)
+6. Add new class '- environment.mcp11-ovs-dpdk.local' to the classes/cluster/<cluster_model>/infra/config.yml
+(edit the file manually for now)
 
-    # 7. Update the nodes for reclass inventory
+7. Update the nodes for reclass inventory
 
     salt-call state.sls reclass.storage
diff --git "a/examples/environment/\173\173 cookiecutter.cluster_name \175\175/init.yml" "b/examples/environment/\173\173 cookiecutter.cluster_name \175\175/init.yml"
index 633ed40..d1b5b7f 100644
--- "a/examples/environment/\173\173 cookiecutter.cluster_name \175\175/init.yml"
+++ "b/examples/environment/\173\173 cookiecutter.cluster_name \175\175/init.yml"
@@ -9,7 +9,13 @@
             linux_network_interfaces:
               ens3: ${_param:linux_single_interface}
 {%- else %}
-            linux_network_interfaces: None  # Create interfaces configuration from your inventory
+            # Use interfaces configuration from the context file,
+            # or generate your own 'linux.network.interface' object using
+            # additional inventory.
+            # For example, you can take the 'inventory_node_name' and find it's config
+            # in an additional dict inventory[inventory_node_name] loaded from custom_inventory.yaml,
+            # or skip the original context from 'cookiecutter' object and iterate only custom inventory.
+            linux_network_interfaces: {{ node['parameters']['linux']['network']['interface'] }}
 {%- endif %}
           classes:
           - environment.{{ cookiecutter.cluster_name }}.networking
diff --git a/reclass_tools/__init__.py b/reclass_tools/__init__.py
index 0418604..e69de29 100644
--- a/reclass_tools/__init__.py
+++ b/reclass_tools/__init__.py
@@ -1,38 +0,0 @@
-import os
-import time
-import logging.config
-
-
-LOGGER_SETTINGS = {
-    'version': 1,
-    'disable_existing_loggers': False,
-    'loggers': {
-        'reclass_tools': {
-            'level': 'DEBUG',
-            'handlers': ['console_output'],
-        },
-        'paramiko': {'level': 'WARNING'},
-        'iso8601': {'level': 'WARNING'},
-        'keystoneauth': {'level': 'WARNING'},
-    },
-    'handlers': {
-        'console_output': {
-            'class': 'logging.StreamHandler',
-            'level': 'INFO',
-            'formatter': 'default',
-            'stream': 'ext://sys.stdout',
-        },
-    },
-    'formatters': {
-        'default': {
-            'format': '%(asctime)s - %(levelname)s - %(filename)s:'
-                      '%(lineno)d -- %(message)s',
-            'datefmt': '%Y-%m-%d %H:%M:%S',
-        },
-    },
-}
-
-logging.config.dictConfig(LOGGER_SETTINGS)
-# set logging timezone to GMT
-logging.Formatter.converter = time.gmtime
-logger = logging.getLogger(__name__)
diff --git a/reclass_tools/cli.py b/reclass_tools/cli.py
index becff4e..c696400 100644
--- a/reclass_tools/cli.py
+++ b/reclass_tools/cli.py
@@ -1,4 +1,4 @@
-#    Copyright 2013 - 2016 Mirantis, Inc.
+#    Copyright 2013 - 2017 Mirantis, Inc.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
 #    not use this file except in compliance with the License. You may obtain
@@ -22,157 +22,206 @@
 from reclass_tools import walk_models
 
 
-def execute(params):
+class Shell(object):
+    def __init__(self, args):
+        self.args = args
+        self.params = self.get_params()
 
-    results = walk_models.get_all_reclass_params(
-        params.paths,
-        verbose=params.verbose)
+    def execute(self):
+        command_name = 'do_{}'.format(self.params.command.replace('-', '_'))
+        command_method = getattr(self, command_name)
+        command_method()
 
-    print(yaml.dump(results))
+    def do_get_key(self):
+        results = walk_models.remove_reclass_parameter(
+            self.params.path,
+            self.params.key_name,
+            verbose=self.params.verbose,
+            pretend=True)
+
+    def do_del_key(self):
+        results = walk_models.remove_reclass_parameter(
+            self.params.path,
+            self.params.key_name,
+            verbose=self.params.verbose,
+            pretend=False)
+
+    def do_list_params(self):
+        results = walk_models.get_all_reclass_params(
+            self.params.path,
+            verbose=self.params.verbose)
+        print(yaml.dump(results))
+
+    def do_list_domains(self):
+        try:
+            from reclass_tools import reclass_models
+        except ImportError:
+            sys.exit("Please run this tool on the salt-master node "
+                     "with installed 'reclass'")
+        inventory = reclass_models.inventory_list()
+        reclass_storage = reclass_models.reclass_storage(inventory=inventory)
+        print('\n'.join(sorted(reclass_storage.keys())))
 
 
-def dump_params(args=None):
+    def do_list_nodes(self):
+        try:
+            from reclass_tools import reclass_models
+        except ImportError:
+            sys.exit("Please run this tool on the salt-master node "
+                     "with installed 'reclass'")
+
+        inventory = reclass_models.inventory_list(domain=self.params.domain)
+        vcp_nodes = reclass_models.vcp_list(domain=self.params.domain,
+                                            inventory=inventory)
+        vcp_node_names = ['{0}.{1}'.format(name, domain)
+                          for name, domain in vcp_nodes]
+
+        if self.params.vcp_only:
+            print('\n'.join(sorted(vcp_node_names)))
+        elif self.params.non_vcp_only:
+            print('\n'.join(sorted((node_name for node_name in inventory.keys()
+                                    if node_name not in vcp_node_names))))
+        else:
+            print('\n'.join(sorted(inventory.keys())))
+
+    def do_show_context(self):
+        try:
+            from reclass_tools import create_inventory
+        except ImportError:
+            sys.exit("Please run this tool on the salt-master node "
+                     "with installed 'reclass'")
+
+        current_underlay_context = create_inventory.create_inventory_context(
+            domain=self.params.domain, keys=self.params.keys)
+
+        print(yaml.dump(current_underlay_context, default_flow_style=False))
+
+    def do_render(self):
+        try:
+            from reclass_tools import create_inventory
+        except ImportError:
+            sys.exit("Please run this tool on the salt-master node "
+                     "with installed 'reclass'")
+
+        if not self.params.template_dir or not self.params.output_dir \
+                or not self.params.contexts:
+            sys.exit("Missing parameters, see: reclass-tools render -h")
+
+        create_inventory.render_dir(template_dir=self.params.template_dir,
+                                    output_dir=self.params.output_dir,
+                                    contexts=self.params.contexts)
+
+    def get_params(self):
+
+        verbose_parser = argparse.ArgumentParser(add_help=False)
+        verbose_parser.add_argument('--verbose', dest='verbose',
+                                    action='store_const', const=True,
+                                    help='Show verbosed output', default=False)
+
+        key_parser = argparse.ArgumentParser(add_help=False)
+        key_parser_help = (
+                'Key name to find in reclass model files, for example:'
+                ' parameters.linux.network.interface')
+        key_parser.add_argument('key_name', help=key_parser_help, default=None)
+
+        keys_parser = argparse.ArgumentParser(add_help=False)
+        keys_parser.add_argument(
+            'keys',
+            help='Key names to find in reclass model files', nargs='*')
+
+        path_parser = argparse.ArgumentParser(add_help=False)
+        path_parser.add_argument(
+            'path',
+            help='Path to search for *.yml files.', nargs='+')
+
+        domain_parser = argparse.ArgumentParser(add_help=False)
+        domain_parser.add_argument(
+            '--domain', '-d', dest='domain',
+            help=('Show only the nodes which names are ended with the '
+                  'specified domain, for example: example.local'))
+
+        vcp_only_parser = argparse.ArgumentParser(add_help=False)
+        vcp_only_parser.add_argument(
+            '--vcp-only', dest='vcp_only',
+            action='store_const', const=True,
+            help=('Show only VCP nodes (present in '
+                  'parameters.salt.control.cluster.internal.node)'),
+            default=False)
+
+        non_vcp_only_parser = argparse.ArgumentParser(add_help=False)
+        non_vcp_only_parser.add_argument(
+            '--non-vcp-only', dest='non_vcp_only',
+            action='store_const', const=True,  default=False,
+            help=('Show only non-VCP nodes (absent in '
+                  'parameters.salt.control.cluster.internal.node)'))
+
+        render_parser = argparse.ArgumentParser(add_help=False)
+        render_parser.add_argument(
+            '--template-dir', '-t', dest='template_dir',
+            help=('Coockiecutter-based template directory'))
+        render_parser.add_argument(
+            '--output-dir', '-o', dest='output_dir',
+            help=('Path to the directory where the rendered '
+                  'template will be placed'))
+        render_parser.add_argument(
+            '--context', '-c', dest='contexts', nargs='+',
+            help=('YAML/JSON files with context data to render '
+                  'the template'))
+
+
+
+        parser = argparse.ArgumentParser(
+            description="Manage virtual environments. "
+                        "For additional help, use with -h/--help option")
+        subparsers = parser.add_subparsers(title="Operation commands",
+                                           help='available commands',
+                                           dest='command')
+
+        # TODO: add-class NNN [to] MMM.yml # can be used with 'render'
+        subparsers.add_parser('get-key',
+                              parents=[key_parser, path_parser,
+                                       verbose_parser],
+                              help="Find a key in YAMLs found in <path>",
+                              description=("Get a key collected from "
+                                           "different YAMLs"))
+        subparsers.add_parser('del-key',
+                              parents=[key_parser, path_parser,
+                                       verbose_parser],
+                              help="Delete a key from YAMLs found in <path>",
+                              description="Delete a key from different YAMLs")
+        subparsers.add_parser('list-params',
+                              parents=[path_parser, verbose_parser],
+                              help=("Collect all options for "
+                                    "'parameters._params' keys from YAMLs "
+                                    "found in <path>"))
+        subparsers.add_parser('list-nodes',
+                              parents=[domain_parser, vcp_only_parser,
+                                       non_vcp_only_parser],
+                              help=("List nodes that are available for "
+                                    "reclass. Use on salt-master node only!"))
+        subparsers.add_parser('list-domains',
+                              help=("List domains that are available from "
+                                    "reclass models. Use on salt-master "
+                                    "node only!"))
+        subparsers.add_parser('show-context',
+                              parents=[domain_parser, keys_parser],
+                              help=("Show domain nodes with rendered content "
+                                    "for specified keys. Use on salt-master "
+                                    "node for already generated inventory "
+                                    "only!"))
+        subparsers.add_parser('render',
+                              parents=[render_parser],
+                              help=("Render cookiecutter template using "
+                                    "multiple metadata sources"))
+
+        if len(self.args) == 0:
+            self.args = ['-h']
+        return parser.parse_args(self.args)
+
+
+def main(args=None):
     if args is None:
         args = sys.argv[1:]
 
-    parser = argparse.ArgumentParser(
-        formatter_class=argparse.RawTextHelpFormatter,
-        description="")
-    parser.add_argument('--verbose', dest='verbose', action='store_const', const=True,
-                        help='Show verbosed output.', default=False)
-    parser.add_argument('paths', help='Paths to search for *.yml files.', nargs='+')
-
-    if len(args) == 0:
-        args = ['-h']
-
-    params = parser.parse_args(args)
-    results = walk_models.get_all_reclass_params(
-        params.paths,
-        verbose=params.verbose)
-
-    print(yaml.dump(results))
-
-
-def show_key(args=None):
-    remove_key(args=args, pretend=True)
-
-
-def remove_key(args=None, pretend=False):
-    if args is None:
-        args = sys.argv[1:]
-
-    key_parser = argparse.ArgumentParser(add_help=False)
-    if pretend:
-        key_parser_help = (
-            'Key name to find in reclass model files, for example:'
-            ' reclass-show-key parameters.linux.network.interface'
-            ' /path/to/model/')
-    else:
-        key_parser_help = (
-            'Key name to remove from reclass model files, for example:'
-            ' reclass-remove-key parameters.linux.network.interface'
-            ' /path/to/model/')
-    key_parser.add_argument('key_name', help=key_parser_help)
-
-    parser = argparse.ArgumentParser(parents=[key_parser],
-        formatter_class=argparse.RawTextHelpFormatter,
-        description="")
-    parser.add_argument('--verbose', dest='verbose', action='store_const', const=True,
-                        help='Show verbosed output.', default=False)
-    parser.add_argument('paths', help='Paths to search for *.yml files.', nargs='+')
-
-    if len(args) == 0:
-        args = ['-h']
-
-    params = parser.parse_args(args)
-    results = walk_models.remove_reclass_parameter(
-        params.paths,
-        params.key_name,
-        verbose=params.verbose,
-        pretend=pretend)
-
-
-def inventory_list(args=None):
-    try:
-        from reclass_tools import reclass_models
-    except ImportError:
-        print("Please run this tool on the salt-master node with installed 'reclass'")
-        return
-
-    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter,
-                                     description="")
-    parser.add_argument('--domain', '-d', dest='domain',
-                        help=('Show only the nodes which names are ended with the specified domain, for example:'
-                              ' reclass-inventory-list -d example.local'))
-
-
-    params = parser.parse_args(args)
-
-    inventory = reclass_models.inventory_list(domain=params.domain)
-
-    print('\n'.join(sorted(inventory.keys())))
-
-def vcp_list(args=None):
-    try:
-        from reclass_tools import reclass_models
-    except ImportError:
-        print("Please run this tool on the salt-master node with installed 'reclass'")
-        return
-
-    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter,
-                                     description="")
-    parser.add_argument('--domain', '-d', dest='domain',
-                        help=('Show only the nodes which names are ended with the specified domain, for example:'
-                              ' reclass-inventory-list -d example.local'))
-
-    params = parser.parse_args(args)
-
-    vcp_node_names = reclass_models.vcp_list(domain=params.domain)
-    #print('\n'.join(sorted(vcp_node_names)))
-    print('\n'.join(sorted(('{0}.{1}'.format(name, domain) for name, domain in vcp_node_names))))
-
-
-def create_inventory_context(args=None):
-    try:
-        from reclass_tools import create_inventory
-    except ImportError:
-        print("Please run this tool on the salt-master node with installed 'reclass'")
-        return
-
-    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter,
-                                     description="Dumps nodes and specified node parameters from reclass, for example: create_inventory_context -d example.local parameters.linux.network.interface parameters.linux.storage")
-    parser.add_argument('--domain', '-d', dest='domain',
-                        help=('Show only the nodes which names are ended with the specified domain, for example:'
-                              ' reclass-inventory-list -d example.local'))
-    parser.add_argument('keys', help=(
-        'Reclass key names to dump with nodes'), nargs='*')
-
-    params = parser.parse_args(args)
-
-    current_underlay_context = create_inventory.create_inventory_context(domain=params.domain, keys=params.keys)
-
-    print(yaml.dump(current_underlay_context, default_flow_style=False))
-
-
-def render_dir(args=None):
-    try:
-        from reclass_tools import create_inventory
-    except ImportError:
-        print("Please run this tool on the salt-master node with installed 'reclass'")
-        return
-
-    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter,
-                                     description="Render a coockiecutter-based template directory using several different context files")
-    parser.add_argument('--template-dir', '-t', dest='template_dir',
-                        help=('Coockiecutter-based template directory'))
-    parser.add_argument('--output-dir', '-o', dest='output_dir',
-                        help=('Path to the directory where the rendered template will be placed'))
-    parser.add_argument('--context', '-c', dest='contexts',
-                        help=('Path to the directory where the rendered template will be placed'),
-                        nargs='+')
-
-    params = parser.parse_args(args)
-
-    create_inventory.render_dir(template_dir=params.template_dir, output_dir=params.output_dir, contexts=params.contexts)
-
-
+    shell = Shell(args)
+    shell.execute()
diff --git a/reclass_tools/create_inventory.py b/reclass_tools/create_inventory.py
index ce0d7a6..9b03632 100644
--- a/reclass_tools/create_inventory.py
+++ b/reclass_tools/create_inventory.py
@@ -1,9 +1,6 @@
 import yaml
 import json
-
-from cookiecutter import __version__
-#from cookiecutter.log import configure_logger
-#from cookiecutter.main import cookiecutter
+import sys
 
 from cookiecutter import generate
 from cookiecutter.exceptions import UndefinedVariableInTemplate
@@ -41,12 +38,7 @@
     reclass_storage = reclass_models.reclass_storage(domain=domain, inventory=inventory)
 
     if domain is None:
-        raise Exception("Please specify a domain name from: \n{}".format('\n'.join(reclass_storage.keys())))
-
-    #current_underlay_context = {
-    #    'current_clusters': {
-    #    }
-    #}
+        sys.exit("Error: please specify a domain name from: \n{}".format('\n'.join(reclass_storage.keys())))
 
     for storage_domain, storage_nodes in reclass_storage.items():
         if storage_domain != domain:
@@ -78,9 +70,6 @@
                     if reclass_key:
                         helpers.create_nested_key(current_cluster_nodes[inventory_node_name], path=key_path, value=reclass_key)
 
-        #current_underlay_context['current_clusters'][domain] = {
-        #    'nodes': current_cluster_nodes
-        #}
         current_underlay_context = {
             'cookiecutter': {
                 'cluster_name': storage_domain,
@@ -91,32 +80,6 @@
     return current_underlay_context
 
 
-    #1. Generate jinga interfaces / hw details based on node information provided to jinja
-
-    #2. Generate appropriate includes to reclass.storate model in config node
-    #configure_logger(
-    #    stream_level='DEBUG' if verbose else 'INFO',
-    #    debug_file=debug_file,
-    #)
-
-#current_clusters:
-#  <cluster_names>:
-#    nodes:
-#      <node_names>:
-#        name: ctl01
-#        reclass_storage_name: openstack_control_node01
-#        # if classes - then classes
-#        roles:
-#        - vcp  # to select wich interface type to use
-#        #- openstack_controller  # Don't forget to map the roles to corresponded classes if needed
-#        parameters: # there is just a DUMP of the existing model,
-#                    # which could be re-used complete or particulary for rendering new model
-#          linux:
-#            network:
-#              interfaces:
-#                ..
-
-
 def render_dir(template_dir, output_dir, contexts):
     """Coockiecutter echancement to use several source JSON files
 
@@ -128,23 +91,7 @@
                           dict is in the same order as files in the list.
     """
 
-#ipdb> repo_dir
-#u'/root/cookiecutter-templates/cluster_product/openstack'
-#ipdb> context
-#{u'cookiecutter': {u'openstack_telemetry_node02_hostname': u'mdb02', ... }}
-#ipdb> overwrite_if_exists
-#False
-#ipdb> output_dir
-#'/root/my_new_deployment/'
-
-    print(template_dir)
-    print(output_dir)
-    print(contexts)
-    #return
-    #repo_dir = '/root/cookiecutter-templates/cluster_product/openstack'
     overwrite_if_exists = True
-    #output_dir = '/root/my_new_deployment/'
-    #context = {'cookiecutter': {'openstack_telemetry_node02_hostname': 'mdb02' }}
 
     merged_context = {}
     for fcon in contexts:
@@ -153,16 +100,10 @@
         elif fcon.endswith('.json'):
             context = helpers.json_read(fcon)
         else:
-            print("Error: Please use YAML or JSON files for contexts")
-            return # should be exit 1
+            sys.exit("Error: Please use YAML or JSON files for contexts")
 
-
-        #merged_context.update(context)
-        #merged_context = dict(chain(merged_context.items(), context.items()))
         merged_context = helpers.merge_nested_objects(merged_context, context)
 
-    #print(yaml.dump(merged_context, default_flow_style=False))
-
     try:
         generate.generate_files(
             repo_dir=template_dir,
@@ -171,14 +112,11 @@
             output_dir=output_dir
         )
 
-
     except UndefinedVariableInTemplate as undefined_err:
-        print('>>> {}'.format(undefined_err.message))
-        print('>>> Error message: {}'.format(undefined_err.error.message))
-
         context_str = yaml.dump(
             undefined_err.context,
             default_flow_style=False
         )
         print('='*15 + ' Context: '+ '='*15 + '\n{}'.format(context_str) + '='*40)
-        return
+        print('>>> {}'.format(undefined_err.message))
+        sys.exit('>>> Error message: {}'.format(undefined_err.error.message))
diff --git a/reclass_tools/walk_models.py b/reclass_tools/walk_models.py
index 7017722..8b4d91f 100644
--- a/reclass_tools/walk_models.py
+++ b/reclass_tools/walk_models.py
@@ -148,11 +148,11 @@
                     if nested_key:
                         found_keys[fyml.fname] = copy.deepcopy(nested_key)
                         if pretend:
-                            print("\nFound {0} in {1}".format('.'.join(remove_key),
+                            print("\n---\n# Found {0} in {1}".format('.'.join(remove_key),
                                                                    fyml.fname))
                             print(yaml.dump(nested_key, default_flow_style=False))
                         else:
-                            print("\nRemoving {0} from {1}".format('.'.join(remove_key),
+                            print("\n---\n# Removing {0} from {1}".format('.'.join(remove_key),
                                                                    fyml.fname))
                             print(yaml.dump(nested_key, default_flow_style=False))
 
diff --git a/setup.cfg b/setup.cfg
index bad4709..7229900 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -26,10 +26,4 @@
 
 [entry_points]
 console_scripts =
-    reclass-dump-params = reclass_tools.cli:dump_params
-    reclass-remove-key = reclass_tools.cli:remove_key
-    reclass-show-key = reclass_tools.cli:show_key
-    reclass-inventory-list = reclass_tools.cli:inventory_list
-    reclass-vcp-list = reclass_tools.cli:vcp_list
-    reclass-create-inventory-context = reclass_tools.cli:create_inventory_context
-    reclass-render-dir = reclass_tools.cli:render_dir
+    reclass-tools = reclass_tools.cli:main
\ No newline at end of file