How do I register a custom Jinja filter in Salt, so it becomes available in the SLS files?

3,082 views
Skip to first unread message

Bernd N

unread,
Nov 16, 2012, 4:38:55 PM11/16/12
to salt-...@googlegroups.com
Has anyone ever written and registered a custom Jinja filter in Salt?

There is a built-in Jinja filter, "replace", that does a simple string replacement:

{{ grains['full_host_name']|replace('.com', '.bla') }}

This would replace "somehost.com" with "somehost.bla". What I need, though, is a filter that does regular expression replacement, as in the following hypothetical example to extract the host component from a FQDN:

/etc/hostname:
  file.sed:
    - before: .*
    - after: "{{ grains['full_host_name']|re_replace('\..*$', '') }}"

Writing the filter method itself is trivial using the "re" package. But I've been banging my head against the wall all day trying to register the filter in Salt. The Jinja docs say that I just need to "register it on the template environment by updating the filters dict on the environment" (http://jinja.pocoo.org/docs/api/#custom-filters) but I couldn't find out how that translates to how salt uses Jinja in the renderer.

Any pointers would be greatly appreciated. :)

Bernd.

Thomas S Hatch

unread,
Nov 16, 2012, 9:30:04 PM11/16/12
to salt-...@googlegroups.com
This is interesting,I think that you would need to register the filter from within the jinja libs that Salt uses. these are in the salt source under salt/utils/jinja.py

You might be able to use another grain, like host, or use a string operations since you can access the python string object directly

Pedro Algarvio

unread,
Nov 17, 2012, 4:40:09 PM11/17/12
to salt-...@googlegroups.com
An alternative to your filter option is writing a custom module take this one as an example.
And then you can use it like this.

Notice where we've put the custom module, under _modules on the state tree.

Hope this helps.

Best Regards,
Pedro Algarvio.

Bernd N

unread,
Nov 17, 2012, 9:12:14 PM11/17/12
to salt-...@googlegroups.com
Thanks for the quick response, guys!

Thomas,
I tried to avoid having an extra grain for the hostname, if I already have one for the FQDN. After seeing Pedro's suggestion, I did no longer bother to extend Jinja for this use case I had.

Pedro,
I can't believe it was that simple! I followed your suggestion and was able to solve my problem with 3 lines of Python code, stored in _modules/my_helpers.py:

import re

def re_replace(pattern, replacement, string):
        return re.sub(pattern, replacement, string)

And then use it in the SLS:

/etc/hostname:
  file.sed:
    - before: .*
    - after: "{{ salt['my_helpers.re_replace']('\..*$', '', grains['full_host_name']) }}"


Bernd.
Reply all
Reply to author
Forward
0 new messages