如何将 jinja2 变量传递给 json_query

How to pass jinja2 variable to 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: [

使用 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.

使用 Ansible 2.9.23.

对于字符串占位符 {}%s 我必须使用反引号,否则它不起作用:

json_query('results[?name==`{}`].version'.format(query))
json_query('results[?name==`%s`].version' % (query))

举个例子json:

{
    (...)
    "results": [
        {
            "envra": "0:ntp-4.2.6p5-29.el7_8.2.x86_64",
            "name": "ntp",
            "repo": "installed",
            "epoch": "0",
            "version": "4.2.6p5",
            "release": "29.el7_8.2",
            "yumstate": "installed",
            "arch": "x86_64"
        },
        (...)
    ],
    (...)
}

创建者:

- name: list installed packages
  yum:
    list: installed
  register: installed_list

使用定义的变量query: ntp,通过两种方式将此变量传递给json_query

- name: pass var to json_query - string formatting (1)
  debug:
    msg: "{{ installed_list|json_query('results[?name==`{}`].version'.format(query))|first }}"

- name: pass var to json_query - string formatting (2)
  debug:
    msg: "{{ installed_list|json_query('results[?name==`%s`].version' % (query))|first }}"

结果:

TASK [pass var to json_query - string formatting (1)] *****************************************************************************************************
ok: [host] => {
    "msg": "4.2.6p5"
}

TASK [pass var to json_query - string formatting (2)] *****************************************************************************************************
ok: [host] => {
    "msg": "4.2.6p5"
}