Add option add_subdir_to_node

This allows files in different subfolders to have the same name

More information on README-extentions.rst
diff --git a/README-extentions.rst b/README-extentions.rst
index ec10e48..f57b760 100644
--- a/README-extentions.rst
+++ b/README-extentions.rst
@@ -228,7 +228,7 @@
   parameters:
     y: 1
 
-  
+
 The parameter ``a`` only depends on the parameter ``y`` through the reference set in class2. The fact that the parameter ``x`` referenced
 in class1 is not defined does not affect the final value of the parameter ``a``. For such overwritten missing references by default a warning is
 printed but no error is raised, providing the final value of the parameter being evaluated is a scalar. If the final value is a dictionary or list
@@ -507,3 +507,32 @@
 
 The above exports and parameter definitions could be put into a separate class and then included by nodes which require
 access to the database and included by the database server as well.
+
+
+Add subfolders to node name
+---------------------------
+
+Nodes can be defined in subdirectories. However, node names (filename) must be unique across all subdirectories.
+
+For example, the following file structure is invalid:
+
+.. code-block:: yaml
+
+  inventory/nodes/prod/mysql.yml
+  inventory/nodes/staging/mysql.yml
+
+With setting:
+
+.. code-block:: yaml
+
+  add_subdir_to_node: True       # default False
+
+This adds the subfolder to the node name and the structure above can then be used. It generates the following reclass objects:
+
+.. code-block:: yaml
+
+  nodes:
+    prod.mysql:
+      ...
+    staging.mysql:
+      ...
diff --git a/reclass/__init__.py b/reclass/__init__.py
index 3739b5e..82fa0ab 100644
--- a/reclass/__init__.py
+++ b/reclass/__init__.py
@@ -15,9 +15,9 @@
 from .storage.loader import StorageBackendLoader
 from .storage.memcache_proxy import MemcacheProxy
 
-def get_storage(storage_type, nodes_uri, classes_uri, **kwargs):
+def get_storage(storage_type, nodes_uri, classes_uri, add_subdir_to_node, **kwargs):
     storage_class = StorageBackendLoader(storage_type).load()
-    return MemcacheProxy(storage_class(nodes_uri, classes_uri, **kwargs))
+    return MemcacheProxy(storage_class(nodes_uri, classes_uri, add_subdir_to_node, **kwargs))
 
 def get_path_mangler(storage_type,**kwargs):
     return StorageBackendLoader(storage_type).path_mangler()
diff --git a/reclass/adapters/ansible.py b/reclass/adapters/ansible.py
index abf7df2..3ebe575 100755
--- a/reclass/adapters/ansible.py
+++ b/reclass/adapters/ansible.py
@@ -66,7 +66,10 @@
                               add_options_cb=add_ansible_options_group,
                               defaults=defaults)
 
-        storage = get_storage(options.storage_type, options.nodes_uri, options.classes_uri)
+        storage = get_storage(options.storage_type,
+                              options.nodes_uri,
+                              options.classes_uri,
+                              options.add_subdir_to_node)
         class_mappings = defaults.get('class_mappings')
         defaults.update(vars(options))
         settings = Settings(defaults)
diff --git a/reclass/adapters/salt.py b/reclass/adapters/salt.py
index ce4e792..10a6a43 100755
--- a/reclass/adapters/salt.py
+++ b/reclass/adapters/salt.py
@@ -31,11 +31,12 @@
                classes_uri=OPT_CLASSES_URI,
                class_mappings=None,
                propagate_pillar_data_to_reclass=False,
+               add_subdir_to_node=OPT_ADD_SUBDIR_TO_NODE,
                **kwargs):
 
     path_mangler = get_path_mangler(storage_type)
     nodes_uri, classes_uri = path_mangler(inventory_base_uri, nodes_uri, classes_uri)
-    storage = get_storage(storage_type, nodes_uri, classes_uri)
+    storage = get_storage(storage_type, nodes_uri, classes_uri, add_subdir_to_node)
     input_data = None
     if propagate_pillar_data_to_reclass:
         input_data = pillar
@@ -54,11 +55,12 @@
 
 def top(minion_id, storage_type=OPT_STORAGE_TYPE,
         inventory_base_uri=OPT_INVENTORY_BASE_URI, nodes_uri=OPT_NODES_URI,
-        classes_uri=OPT_CLASSES_URI, class_mappings=None, **kwargs):
+        classes_uri=OPT_CLASSES_URI, class_mappings=None, add_subdir_to_node=OPT_ADD_SUBDIR_TO_NODE,
+        **kwargs):
 
     path_mangler = get_path_mangler(storage_type)
     nodes_uri, classes_uri = path_mangler(inventory_base_uri, nodes_uri, classes_uri)
-    storage = get_storage(storage_type, nodes_uri, classes_uri)
+    storage = get_storage(storage_type, nodes_uri, classes_uri, add_subdir_to_node)
     settings = Settings(kwargs)
     reclass = Core(storage, class_mappings, settings, input_data=None)
 
diff --git a/reclass/cli.py b/reclass/cli.py
index 44694c5..89f3a8b 100644
--- a/reclass/cli.py
+++ b/reclass/cli.py
@@ -31,7 +31,10 @@
         defaults.update(find_and_read_configfile())
 
         options = get_options(RECLASS_NAME, VERSION, DESCRIPTION, defaults=defaults)
-        storage = get_storage(options.storage_type, options.nodes_uri, options.classes_uri)
+        storage = get_storage(options.storage_type,
+                              options.nodes_uri,
+                              options.classes_uri,
+                              options.add_subdir_to_node)
         class_mappings = defaults.get('class_mappings')
         defaults.update(vars(options))
         settings = Settings(defaults)
diff --git a/reclass/config.py b/reclass/config.py
index 1a6ba81..cc3c35e 100644
--- a/reclass/config.py
+++ b/reclass/config.py
@@ -36,6 +36,9 @@
     ret.add_option('-z', '--ignore-class-notfound', dest='ignore_class_notfound',
                    default=defaults.get('ignore_class_notfound', OPT_IGNORE_CLASS_NOTFOUND),
                    help='decision for not found classes [%default]')
+    ret.add_option('-a', '--add-subdir-to-node', dest='add_subdir_to_node', action="store_true",
+                   default=defaults.get('add_subdir_to_node', OPT_ADD_SUBDIR_TO_NODE),
+                   help='Add subdir when generating node names. [%default]')
     ret.add_option('-x', '--ignore-class-notfound-regexp', dest='ignore_class_notfound_regexp',
                    default=defaults.get('ignore_class_notfound_regexp', OPT_IGNORE_CLASS_NOTFOUND_REGEXP),
                    help='regexp for not found classes [%default]')
diff --git a/reclass/defaults.py b/reclass/defaults.py
index 1e50c0e..095ff36 100644
--- a/reclass/defaults.py
+++ b/reclass/defaults.py
@@ -21,6 +21,7 @@
 OPT_CLASSES_URI = 'classes'
 OPT_PRETTY_PRINT = True
 OPT_GROUP_ERRORS = True
+OPT_ADD_SUBDIR_TO_NODE = False
 OPT_NO_REFS = False
 OPT_OUTPUT = 'yaml'
 
diff --git a/reclass/settings.py b/reclass/settings.py
index 51c518f..f2a6e1b 100644
--- a/reclass/settings.py
+++ b/reclass/settings.py
@@ -32,6 +32,7 @@
         self.reference_sentinels = options.get('reference_sentinels', REFERENCE_SENTINELS)
         self.ignore_class_notfound = options.get('ignore_class_notfound', OPT_IGNORE_CLASS_NOTFOUND)
         self.strict_constant_parameters = options.get('strict_constant_parameters', OPT_STRICT_CONSTANT_PARAMETERS)
+        self.add_subdir_to_node = options.get('add_subdir_to_node', OPT_ADD_SUBDIR_TO_NODE)
 
         self.ignore_class_notfound_regexp = options.get('ignore_class_notfound_regexp', OPT_IGNORE_CLASS_NOTFOUND_REGEXP)
         if isinstance(self.ignore_class_notfound_regexp, string_types):
@@ -65,7 +66,8 @@
                and self.ignore_class_notfound == other.ignore_class_notfound \
                and self.ignore_class_notfound_regexp == other.ignore_class_notfound_regexp \
                and self.ignore_class_notfound_warning == other.ignore_class_notfound_warning \
-               and self.strict_constant_parameters == other.strict_constant_parameters
+               and self.strict_constant_parameters == other.strict_constant_parameters \
+               and self.add_subdir_to_node == other.add_subdir_to_node
 
     def __copy__(self):
         cls = self.__class__
diff --git a/reclass/storage/yaml_fs/__init__.py b/reclass/storage/yaml_fs/__init__.py
index a102f31..e511d44 100644
--- a/reclass/storage/yaml_fs/__init__.py
+++ b/reclass/storage/yaml_fs/__init__.py
@@ -55,12 +55,16 @@
 
 class ExternalNodeStorage(NodeStorageBase):
 
-    def __init__(self, nodes_uri, classes_uri):
+    def __init__(self, nodes_uri, classes_uri, add_subdir_to_node):
         super(ExternalNodeStorage, self).__init__(STORAGE_NAME)
 
         if nodes_uri is not None:
             self._nodes_uri = nodes_uri
-            self._nodes = self._enumerate_inventory(nodes_uri, NameMangler.nodes)
+            if add_subdir_to_node:
+                self._nodes = self._enumerate_inventory(nodes_uri, NameMangler.classes)
+            else:
+                self._nodes = self._enumerate_inventory(nodes_uri, NameMangler.nodes)
+
 
         if classes_uri is not None:
             self._classes_uri = classes_uri
diff --git a/reclass/tests/test_core.py b/reclass/tests/test_core.py
index 679d6ca..c79630a 100644
--- a/reclass/tests/test_core.py
+++ b/reclass/tests/test_core.py
@@ -27,8 +27,8 @@
         inventory_uri = os.path.dirname(os.path.abspath(__file__)) + '/data/' + dataset
         path_mangler = get_path_mangler('yaml_fs')
         nodes_uri, classes_uri = path_mangler(inventory_uri, 'nodes', 'classes')
-        storage = get_storage('yaml_fs', nodes_uri, classes_uri)
         settings = Settings(opts)
+        storage = get_storage('yaml_fs', nodes_uri, classes_uri, settings.add_subdir_to_node)
         return Core(storage, None, settings)
 
     def test_type_conversion(self):