saltstack/salt — Issue #405: more flexible context ("passthrough") for renderers
Author: ewsnow
Created: 2011-12-30 00:01:00+00:00
State: open

It would be nice if the context (or "passthrough") for renderers were more easily changed. For instance, it would be nice if I could add additional objects to be passed on to jinja. This would tie in nicely with Issue #404.

Here's an example of how it could work:

Add an extra config option, "renderer_context", that takes a mapping. The default value would be:

{
'salt': '__salt__',
'grains': '__grains__',
'env': 'env',
'sls': 'sls',
}

Then add in a _get_context function to the salt.renderers module:

class _Context(dict):
def __getattr__(self, name):
if name not in self:
raise AttributeError(name)
return self[name]

def _get_context(session, **names):
if not names:
names = session.opts.renderer_context
context = _Context()
for name, actualname in names.items():
if actualname not in session:
raise NameError(actualname)
context[name] = session[actualname]
return context

And update the renderers. For example, here's the change for yaml_jinja.py:

from salt.renderers import _get_context

def render(session, template):
if not os.path.isfile(template):
return {}

template = Template(open(template, 'r').read())
session.update(globals()) # XXX yank when session done properly
context = _get_context(session)
yaml_data = template.render(**context)

return yaml.safe_load(yaml_data)

And for py.py:

def render(session, template):
if not os.path.isfile(template):
return {}
mod = imp.load_source(
os.path.basename(template).split('.')[0],
template
)
session.update(globals()) # XXX yank when session done properly
context = _get_context(session)

return mod.run(context)

With this change it is pretty easy to customize the context that is passed to the renderer. As well, it makes it a little easier to merge the nice renderers into state/file.py...