Salt Module: NodeCFG
This module worked similar to pillar.get() except that it was designed to operate on a shared pillar dictionary. It was rewritten because the old version had many bugs and broke the standard assumptions. This temporary module was eventually deprecated in favor of a system that doesn’t use shared dictionaries.
Original Version
This is not the original version. There were too many bugs that needed urgent fixing and then a repository reset lost the original.
# -*- coding: utf-8 -*-
'''
Custom module to lookup node config in pillar, if not found,
fall back to defaults values, if not found KeyError
'''
from __future__ import absolute_import
import logging
# Import salt libs
import salt
import salt.utils
from salt.defaults import DEFAULT_TARGET_DELIM
log = logging.getLogger(__name__)
def get(key, default=KeyError, default_lookup=True, missing_ok=False):
delimiter = DEFAULT_TARGET_DELIM
node_id = __grains__['id']
node_key = ':'.join(("nodes", node_id, key))
defaults_key = DEFAULT_TARGET_DELIM.join(("nodes{}defaults".format(DEFAULT_TARGET_DELIM), key))
log.debug("Node CFG Module: {0}/{1}".format(node_key, defaults_key))
ret = salt.utils.traverse_dict_and_list(__pillar__, node_key, KeyError, delimiter)
log.debug("Node Lookup key ({0}): {1}".format(node_key, ret))
if default_lookup is True:
if ret is KeyError or ret is None:
ret = salt.utils.traverse_dict_and_list(__pillar__, defaults_key, KeyError, delimiter)
log.debug("Default Lookup key ({0}): {1}".format(defaults_key, ret))
else:
log.debug("skipping default lookup.")
# assign the default value because we found nothing
if ret is KeyError and default is not KeyError:
ret = default
# if we don't pass a default value, we stop because it's a good guess that the lookup key is wrong
# and we'll want to know
if ret is KeyError and not missing_ok:
raise KeyError("Node pillar keys not found: {0} or {1}".format(node_key, defaults_key))
return ret
Biggest Issues
.get()behavior is extremely non-standard (was.get(hostname, key, default, missing_ok))Confusing
.get()usage created hidden bugs across entire repositoryOften swapped default value and lookup hostname
Lots of changing default in every config
Required every single pillar value (secret) to be exposed to every single host
Lots of code that didn’t do what was described
Imported delimeter but never used it
New Version
#!/usr/bin/env python
'''
Custom module to look up node config in pillar, if not found,
fall back to defaults values, if not found then return None.
'''
##
# TODO:
# - This should return None when nothing is found
# - missing_ok should be removed; replace with default=None
# ^^ requires first updating states
##
def get(key, default=KeyError, default_lookup=True, missing_ok=False):
result = __salt__['pillar.get']('nodes:{}:{}'.format(__grains__['id'], key), 'not-found')
if result == 'not-found' and default_lookup:
result = __salt__['pillar.get']('nodes:defaults:{}'.format(key), default)
elif result == 'not-found':
result = default
if result is KeyError and not missing_ok:
# legacy logic: assume at this point that the lookup key is probably wrong
raise KeyError("Node pillar keys not found: {0}".format(key))
return result