尝试使用 json 和 json_query 过滤器时模板化字符串时出现模板错误

Getting template error while templating string when trying to work with json and json_query filter

我尝试执行这个 ansible 命令:

 ansible localhost -m debug -a "var={{ db_config| to_json |json_query(*)}}" \
       -e 'db_config=[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]'

使用 json_query(*) 获取所有 json 元素 但我收到以下错误:

 fatal: [localhost]: FAILED! =>
  msg: 'template error while templating string: expected token ''end of print statement'', got ''name''. String: {{"[{\"name\":\"mydb1\",\"services\":[\"app1\",\"app2\"]},{\"name\":\"mydb12\",\"services\":[\"app1\"]}]"}}'

这个单行有几个问题:

  1. 在您的情况下用于调试的参数是 msg(输出模板或静态值的结果)而不是 var(用于调试单个变量而不进行任何转换) .请参阅 debug module documentation
  2. 您正在将 json 字符串表示形式作为参数传递。您要使用的过滤器是 from_json(将您的字符串转换为 dict/list)而不是 to_json(恰恰相反)。
  3. 您在 json_query 中的 jmespath expression 无效,原因有二:
    • 这不是一个字符串(只是一个简单的通配符)
    • 即使引用也不符合规范(按照上面的link)。

下面固定的一个衬里给出了你期望的结果(我相信......):

$ ansible localhost -m debug -a 'msg={{ db_config | from_json | json_query("[]") }}' \
-e 'db_config=[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]'
localhost | SUCCESS => {
    "msg": [
        {
            "name": "mydb1",
            "services": [
                "app1",
                "app2"
            ]
        },
        {
            "name": "mydb12",
            "services": [
                "app1"
            ]
        }
    ]
}

请注意,您甚至可以通过将您的论点作为完整内联 json:

传递来放弃 json 解码步骤
$ ansible localhost -m debug -a 'msg={{ db_config | json_query("[]") }}' \
-e '{"db_config":[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]}'
localhost | SUCCESS => {
    "msg": [
        {
            "name": "mydb1",
            "services": [
                "app1",
                "app2"
            ]
        },
        {
            "name": "mydb12",
            "services": [
                "app1"
            ]
        }
    ]
}

我怀疑您正在尝试所有这些以稍后测试 json_query 表达式以 select 您的数据。

  • 你应该知道ansible中还有很多其他核心过滤器(其中selectattrrejectattrselectrejectmap , dict2items, items2dict, first, last, unique, zip, subelements,...)组合在一起可以完成大部分工作 json_query 可以在没有开销的情况下完成(安装 python 模块和 ansible 集合)。 json_query 只有非常复杂的查询才真正需要。
  • 万一我错了,你的最终目标真的是显示输入数据的所有元素,你可以过度简化。来自以上两个例子:
$ ansible localhost -m debug -a 'msg={{ db_config | from_json }}' \
-e 'db_config=[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]'

# OR (the next one can work with `var` for debug)

$ ansible localhost -m debug -a 'var=db_config' \
-e '{"db_config":[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]}'

如果将数据放入文件

shell> cat test-data.yml
---
db_config:
  - {name: "mydb1", services: ["app1", "app2"]}
  - {name: "mydb12", services: ["app1"]}

如果您将代码放入剧本

shell> cat test.yml
---
- hosts: localhost
  tasks:
    - debug:
        msg: "{{ db_config|json_query('[]') }}"

该命令按预期工作

shell> ansible-playbook test.yml -e @test-data.yml
...
  msg:
  - name: mydb1
    services:
    - app1
    - app2
  - name: mydb12
    services:
    - app1