Reclass 'node' manipulation modules
diff --git a/_modules/reclass.py b/_modules/reclass.py
new file mode 100644
index 0000000..223bb84
--- /dev/null
+++ b/_modules/reclass.py
@@ -0,0 +1,205 @@
+# -*- coding: utf-8 -*-
+'''
+Module for handling reclass files.
+
+'''
+
+from __future__ import absolute_import
+
+import logging
+import os
+import sys
+import yaml
+
+LOG = logging.getLogger(__name__)
+
+RECLASS_NODES_DIR = "/srv/salt/reclass/nodes"
+RECLASS_CLASSES_DIR = "/srv/salt/reclass/classes"
+
+def __virtual__():
+    '''
+    Only load this module if reclass
+    is installed on this minion.
+    '''
+    return 'reclass'
+
+
+__opts__ = {}
+
+
+def node_create(name, path=None, cluster="default", environment="prd", classes=None, parameters=None, **kwargs):
+    '''
+    Create a reclass node
+
+    :param name: new node FQDN
+    :param path: custom path in nodes for new node
+    :param classes: classes given to the new node
+    :param parameters: parameters given to the new node
+    :param environment: node's environment
+    :param cluster: node's cluster
+
+    CLI Examples:
+
+    .. code-block:: bash
+
+        salt '*' reclass.node_create server.domain.com classes=[system.neco1, system.neco2]
+        salt '*' reclass.node_create namespace/test enabled=False
+    
+    '''
+    ret = {}
+
+    node = node_get(name=name)
+
+    if node and not "Error" in node:
+        LOG.debug("node {0} exists".format(name))
+        ret[name] = node
+        return ret
+
+    host_name = name.split('.')[0]
+    domain_name = '.'.join(name.split('.')[1:])
+
+    if classes == None:
+        meta_classes = []
+    else:
+        meta_classes = classes
+
+    if parameters == None:
+        meta_parameters = {}
+    else:
+        meta_parameters = parameters
+
+    node_meta = {
+        'classes': meta_classes,
+        'parameters': {
+            '_param': meta_parameters,
+            'linux': {
+                'system': {
+                    'name': host_name,
+                    'domain': domain_name,
+                    'cluster': cluster,
+                    'environment': environment,
+                }
+            }
+        }
+    }
+    LOG.debug(node_meta)
+
+    if path == None:
+        file_path = os.path.join(RECLASS_NODES_DIR, name + '.yml')
+    else:
+        file_path = os.path.join(RECLASS_NODES_DIR, path, name + '.yml')
+
+    with open(file_path, 'w') as node_file:
+        node_file.write(yaml.dump(node_meta, default_flow_style=False) )
+#    ret[new.get('path_with_namespace')] = new
+    return node_get(name)
+
+def node_delete(name, **kwargs):
+    '''
+    Delete a reclass node
+
+    :params node: Node name
+
+    CLI Examples:
+
+    .. code-block:: bash
+
+        salt '*' reclass.node_delete demo01.domain.com
+        salt '*' reclass.node_delete name=demo01.domain.com
+    '''
+
+    node = node_get(name=name)
+
+    if 'Error' in node:
+        return {'Error': 'Unable to retreive node'}
+
+    if node[name]['path'] == '':
+        file_path = os.path.join(RECLASS_NODES_DIR, name + '.yml')
+    else:
+        file_path = os.path.join(RECLASS_NODES_DIR, node[name]['path'], name + '.yml')
+
+    os.remove(file_path)
+
+    ret = 'Node {0} deleted'.format(name)
+
+    return ret
+
+
+def node_get(name, path=None, **kwargs):
+    '''
+    Return a specific node
+
+    CLI Examples:
+
+    .. code-block:: bash
+
+        salt '*' reclass.node_get host01.domain.com
+        salt '*' reclass.node_get name=host02.domain.com
+    '''
+    ret = {}
+    nodes = node_list(**kwargs)
+
+    if not name in nodes:
+        return {'Error': 'Error in retrieving node'}
+    ret[name] = nodes[name]
+    return ret
+
+
+def node_list(**connection_args):
+    '''
+    Return a list of available nodes
+
+    CLI Example:
+
+    .. code-block:: bash
+
+        salt '*' reclass.node_list
+    '''
+    ret = {}
+
+    for root, sub_folders, files in os.walk(RECLASS_NODES_DIR):
+        for file in files:
+            file_path = os.path.join(root, file)
+            file_content = open(file_path, 'r')
+            file_data = yaml.load(file_content.read())
+            file_content.close()
+            if 'classes' in file_data:
+                classes = file_data.get('classes')
+            else:
+                classes = []
+            if 'parameters' in file_data:
+                if '_param' in file_data.get('parameters'):
+                    parameters = file_data.get('parameters').get('_param')
+                else:
+                    parameters = []
+            else:
+                parameters = []
+            name = file.replace('.yml', '')
+            host_name = name.split('.')[0]
+            domain_name = '.'.join(name.split('.')[1:])
+            path = root.replace(RECLASS_NODES_DIR+'/', '')
+            ret[name] = {
+              'name': host_name,
+              'domain': domain_name,
+              'cluster': 'default',
+              'environment': 'prd',
+              'path': path,
+              'classes': classes,
+              'parameters': parameters
+            }
+
+    return ret
+
+def node_update(name, classes=None, parameters=None, **connection_args):
+    '''
+    Update a node metadata information, classes and parameters.
+
+    CLI Examples:
+
+    .. code-block:: bash
+
+        salt '*' reclass.node_update name=nodename classes="[clas1, class2]"
+    '''
+    node = node_get(name=name)
+    if not node.has_key('Error'):
+      node = node[name.split("/")[1]]
diff --git a/_states/reclass.py b/_states/reclass.py
new file mode 100644
index 0000000..134ec6d
--- /dev/null
+++ b/_states/reclass.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+'''
+Management of reclass metadata
+==============================
+
+.. code-block:: yaml
+
+    node01:
+      reclass.node_present:
+      - name: hostaname.domain.com
+      - path: _generated
+      - cluster: default
+      - environment: prd
+      - classes:
+        - neco.service.neco
+        - neco2.class.neco.dal
+      - parameters:
+          neco: value1
+          neco2: value2
+
+'''
+
+
+def __virtual__():
+    '''
+    Always present
+    '''
+    return 'reclass'
+