【问题标题】:How to pass jinja2 variable to json_query如何将 jinja2 变量传递给 json_query
【发布时间】:2021-09-27 08:05:40
【问题描述】:

我有以下 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 %}
]

我需要将 services[0] 替换为变量 {{ loop.index0 }},我尝试了这种语法

"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: [

【问题讨论】:

    标签: ansible jinja2 ansible-template json-query


    【解决方案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

    【讨论】:

      【解决方案2】:

      使用 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"
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-07
        • 2014-05-05
        • 1970-01-01
        • 2012-12-24
        • 2015-10-23
        • 1970-01-01
        • 2021-05-25
        相关资源
        最近更新 更多