如何将 jinja2 变量传递给 json_query

时间:2021-07-19 16:47:00

标签: ansible jinja2 ansible-template json-query

我有以下 jinja2 模板

[
{% for items in hosts %}
{
    "name":"{{ items.name }}",
    "display_name":"{{ items.display_name }}",
    "services": {{ host_group | from_json | json_query('[*].services[0]') | to_json }},
}
{% endfor %}
]

我需要用变量{{ loop.index0 }}替换services[0],我试过这个语法

"services": {{ host_group | from_json | json_query('[*].services[loop.index0]') | to_json }}

但我收到一个错误:

AnsibleFilterError: JMESPathError in json_query filter plugin:
    Expecting: star, got: unquoted_identifier: Parse error at column 13, token "loop" (UNQUOTED_IDENTIFIER), for expression:
    "[*].services[loop.index0]"

我尝试了另一种语法:

"services": {{ host_group | from_json | json_query('[*].services[' + {{ loop.index0 }} +']') | to_json }},

它也给出了一个错误:

AnsibleError: template error while templating string: expected token ':', got '}'. String: [

1 个答案:

答案 0 :(得分:1)

使用 Jinja 时需要记住两件事:

  1. 永远不要嵌套 {{...}} 模板标记。
  2. 如果你把一些东西放在引号里,它就是一个文字字符串。

所以当你写:

json_query('[*].services[loop.index0]')

您正在传递 json_query 文字字符串 [*].services[loop.index0],这不是有效的 JMESPath 查询。如果要替换字符串中变量的值,则需要通过串联构建字符串,或者使用字符串格式化逻辑。

串联

使用串联可能看起来像:

json_query('[*].services[' ~ loop.index0 ` ']')

这里,~ 是字符串连接运算符——它类似于 +,但它确保将所有内容转换为字符串。比较一下:

ansible localhost -m debug -a 'msg={{ "there are " + 4 + " lights" }}'

为此:

ansible localhost -m debug -a 'msg={{ "there are " ~ 4 ~ " lights" }}'

字符串格式

使用字符串格式可能如下所示:

json_query('[*].services[%s]' % (loop.index0))

或者:

json_query('[*].services[{}]'.format(loop.index0))

这是 Python 中可用的两种字符串格式;要了解更多详情,请开始 here