mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-24 05:40:23 -07:00
Don't convert numbers and booleans to strings.
Before this change if a variable was of type int or bool and the variable was referenced by another variable, the type would change to string. eg. defaults/main.yml ``` PORT: 4567 OTHER_CONFIG: secret1: "so_secret" secret2: "even_more_secret" CONFIG: hostname: "some_hostname" port: "{{ PORT }}" secrets: "{{ OTHER_CONFIG }}" ``` If you output `CONFIG` to json or yaml, the port would get represented in the output as a string instead of as a number, but secrets would get represented as a dictionary. This is a mis-match in behaviour where some "types" are retained and others are not. This change should fix the issue. Update template test to also test var retainment. Make the template changes in v2. Update to only short-circuit for booleans and numbers. Added an entry to the changelog.
This commit is contained in:
parent
a6084f9fd8
commit
0abcebf1e4
6 changed files with 71 additions and 7 deletions
|
@ -32,8 +32,17 @@ from ansible.template.template import AnsibleJ2Template
|
|||
from ansible.template.vars import AnsibleJ2Vars
|
||||
from ansible.utils.debug import debug
|
||||
|
||||
from numbers import Number
|
||||
|
||||
__all__ = ['Templar']
|
||||
|
||||
# A regex for checking to see if a variable we're trying to
|
||||
# expand is just a single variable name.
|
||||
SINGLE_VAR = re.compile(r"^{{\s*(\w*)\s*}}$")
|
||||
|
||||
# Primitive Types which we don't want Jinja to convert to strings.
|
||||
NON_TEMPLATED_TYPES = ( bool, Number )
|
||||
|
||||
JINJA2_OVERRIDE = '#jinja2:'
|
||||
JINJA2_ALLOWED_OVERRIDES = ['trim_blocks', 'lstrip_blocks', 'newline_sequence', 'keep_trailing_newline']
|
||||
|
||||
|
@ -125,6 +134,18 @@ class Templar:
|
|||
if isinstance(variable, basestring):
|
||||
result = variable
|
||||
if self._contains_vars(variable):
|
||||
|
||||
# Check to see if the string we are trying to render is just referencing a single
|
||||
# var. In this case we don't wont to accidentally change the type of the variable
|
||||
# to a string by using the jinja template renderer. We just want to pass it.
|
||||
only_one = SINGLE_VAR.match(variable)
|
||||
if only_one:
|
||||
var_name = only_one.group(1)
|
||||
if var_name in self._available_vars:
|
||||
resolved_val = self._available_vars[var_name]
|
||||
if isinstance(resolved_val, NON_TEMPLATED_TYPES):
|
||||
return resolved_val
|
||||
|
||||
result = self._do_template(variable, preserve_trailing_newlines=preserve_trailing_newlines)
|
||||
|
||||
# if this looks like a dictionary or list, convert it to such using the safe_eval method
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue