Merge pull request #48339 from terminalmage/backport-tojson-filter

Backport tojson filter from #48309 to 2018.3
This commit is contained in:
Nicole Thomas 2018-07-02 13:52:52 -04:00 committed by GitHub
commit 5b38019ca0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 2 deletions

View file

@ -886,6 +886,10 @@ Example:
encoding (usually a ``unicode`` type). This filter was incorrectly-named
when it was added. ``json_decode_list`` will be supported until the Neon
release.
.. deprecated:: 2018.3.3,Fluorine
The :jinja_ref:`tojson` filter accomplishes what this filter was designed
to do, making this filter redundant.
Recursively encodes all string elements of the list to bytes.
@ -915,6 +919,9 @@ Returns:
encoding (usually a ``unicode`` type). This filter was incorrectly-named
when it was added. ``json_decode_dict`` will be supported until the Neon
release.
.. deprecated:: 2018.3.3,Fluorine
The :jinja_ref:`tojson` filter accomplishes what this filter was designed
to do, making this filter redundant.
Recursively encodes all string items in the dictionary to bytes.
@ -934,6 +941,22 @@ Returns:
{'a': '\xd0\x94'}
.. jinja_ref:: tojson
``tojson``
----------
.. versionadded:: 2018.3.3,Fluorine
Dumps a data structure to JSON.
This filter was added to provide this functionality to hosts which have a
Jinja release older than version 2.9 installed. If Jinja 2.9 or newer is
installed, then the upstream version of the filter will be used. See the
`upstream docs`__ for more information.
.. __: http://jinja.pocoo.org/docs/2.10/templates/#tojson
.. jinja_ref:: random_hash
``random_hash``

View file

@ -14,3 +14,20 @@ Improves timezone detection by using the pytz module.
Adds ``timezone.list`` to list supported timezones in either Windows or Unix
format.
New Jinja Filter
================
The :jinja_ref:`tojson` filter (from Jinja 2.9 and later) has been ported to
Salt, and will be used when this filter is not available. This allows older LTS
releases such as CentOS 7 and Ubuntu 14.04 to use this filter.
You should use this filter any time you wish to dump a list or dictionary into
an SLS file, to ensure that the result is able to be loaded by the YAML
renderer. For example:
.. code-block:: jinja
foo:
bar.baz:
- some_arg: {{ mydict|tojson }}

View file

@ -274,7 +274,7 @@ def encode(data, encoding=None, errors='strict', keep=False,
@jinja_filter('json_decode_dict') # Remove this for Neon
@jinja_filter('json_encode_dict')
@jinja_filter('json_encode_dict') # Remove this for Neon
def encode_dict(data, encoding=None, errors='strict', keep=False,
preserve_dict_class=False, preserve_tuples=False):
'''
@ -327,7 +327,7 @@ def encode_dict(data, encoding=None, errors='strict', keep=False,
@jinja_filter('json_decode_list') # Remove this for Neon
@jinja_filter('json_encode_list')
@jinja_filter('json_encode_list') # Remove this for Neon
def encode_list(data, encoding=None, errors='strict', keep=False,
preserve_dict_class=False, preserve_tuples=False):
'''

View file

@ -278,6 +278,26 @@ def to_bool(val):
return False
@jinja_filter('tojson')
def tojson(val, indent=None):
'''
Implementation of tojson filter (only present in Jinja 2.9 and later). If
Jinja 2.9 or later is installed, then the upstream version of this filter
will be used.
'''
options = {'ensure_ascii': True}
if indent is not None:
options['indent'] = indent
return (
salt.utils.json.dumps(
val, **options
).replace('<', '\\u003c')
.replace('>', '\\u003e')
.replace('&', '\\u0026')
.replace("'", '\\u0027')
)
@jinja_filter('quote')
def quote(txt):
'''

View file

@ -358,8 +358,12 @@ def render_jinja_tmpl(tmplstr, context, tmplpath=None):
jinja_env = jinja2.Environment(undefined=jinja2.StrictUndefined,
**env_args)
tojson_filter = jinja_env.filters.get('tojson')
jinja_env.tests.update(JinjaTest.salt_jinja_tests)
jinja_env.filters.update(JinjaFilter.salt_jinja_filters)
if tojson_filter is not None:
# Use the existing tojson filter, if present (jinja2 >= 2.9)
jinja_env.filters['tojson'] = tojson_filter
jinja_env.globals.update(JinjaGlobal.salt_jinja_globals)
# globals

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
'''
Tests for salt.utils.jinja
'''
# Import Python libs
from __future__ import absolute_import, unicode_literals, print_function
# Import Salt libs
import salt.utils.jinja
from tests.support.unit import TestCase
class JinjaTestCase(TestCase):
def test_tojson(self):
'''
Test the tojson filter for those using Jinja < 2.9. Non-ascii unicode
content should be dumped with ensure_ascii=True.
'''
data = {'Non-ascii words': ['süß', 'спам', 'яйца']}
result = salt.utils.jinja.tojson(data)
expected = '{"Non-ascii words": ["s\\u00fc\\u00df", "\\u0441\\u043f\\u0430\\u043c", "\\u044f\\u0439\\u0446\\u0430"]}'
assert result == expected, result