From b4efb5e10028e46809c06517f621ea1e917f92c0 Mon Sep 17 00:00:00 2001 From: Sven Feyerabend Date: Sat, 2 May 2026 16:07:26 +0200 Subject: [PATCH] chore(macros.j2): more robust handling of complex types Ansible sometimes passes variables with complex types other than list, dict or string. If they change something internally the macros just break with cryptic error messages. This commit replaces the explicit types with more general (builtin) checks. --- templates/macros.j2 | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/templates/macros.j2 b/templates/macros.j2 index 50d3118..0e6545b 100644 --- a/templates/macros.j2 +++ b/templates/macros.j2 @@ -1,11 +1,12 @@ {%- macro insert_value(value) -%}{#- Inserts the value correctly formatted and quoted for UCL -#} - {%- if value | type == "bool" -%} + {%- if value is boolean -%} {#- bool -#} {{ value | bool | lower }} - {%- elif value | type == "int" or value | type == "float" -%} + {%- elif value is number -%} {#- numeric -#} {{ value | string }} - {%- elif value | type == "unicode" or value | type == "AnsibleUnsafeText" or value | type == "str" or value | type == "AnsibleUnicode" -%} + {%- elif value is string -%} + {#- Catch-all for any string-like object, including Ansible tags/vaults -#} {%- if value | regex_search('^([0-9])+(.[0-9]+)?(s|m|h|d|min)$') -%} {#- time -#} {{ value }} @@ -20,16 +21,23 @@ {% macro is_complex(var) %}{#- Checks whether a list contains another list or dict -#} {%- for item in var -%} - {%- if item | type == "dict" or item | type == "dict" -%} - True + {%- if item is mapping or (item is sequence and item is not string) -%} + true {%- endif -%} {%- endfor -%} {% endmacro %} {%- macro insert_dict(key, value) -%}{#- Formats a variable for inserting it into UCL -#} - {%- if value | type == "list" -%} + {%- if value is mapping -%} + {#- dict -#} + {{ key }} { +{% for k, v in value.items() %} +{{ insert_dict(k, v) | indent(4, True) }} +{% endfor -%} + } + {%- elif value is sequence and value is not string -%} {#- list: If one of the items is complex, repeatedly define them, otherwise use an array -#} - {%- if is_complex(value) | length > 0 -%}{#- Implementing this by setting a variable is not possible because Jinja fails unexpectedly when using 'is defined' in this macro -#} + {%- if is_complex(value) -%}{#- Implementing this by setting a variable is not possible because Jinja fails unexpectedly when using 'is defined' in this macro -#} {%- for item in value %} {{ insert_dict(key, item) }} {% endfor -%} @@ -40,13 +48,6 @@ {%- endfor -%} ] {%- endif -%} - {%- elif value | type == "dict" -%} - {#- dict -#} - {{ key }} { -{% for k, v in value.items() %} -{{ insert_dict(k, v) | indent(4, True) }} -{% endfor -%} - } {%- else -%} {#- simple type like string, number, bool -#} {{ key }} = {{ insert_value(value) }};