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'
+