Ansible:包含带有JMESPath的字符串的过滤器元素 [英] Ansible : filter elements containing string with JMESPath

查看:98
本文介绍了Ansible:包含带有JMESPath的字符串的过滤器元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获取已定义接口类型的地址列表.
我在此处找到了一些信息.

I want to get a list of addresses of a defined interface type.
I found some info here.

这是我的剧本:

- name: Test JMESPath
  hosts: localhost
  gather_facts: no

  vars:
    interfaces:
    - name: em0
      address: 10.127.37.89/29
    - name: bge0
      address: 10.112.171.81/28
    - name: bge1
      address: 10.112.171.65/28
    - name: bge2
      address: 10.112.171.97/28
  tasks:
    - name: JMESPath query
      set_fact:
        result: "{{ interfaces | json_query(query) }}"
      vars:
        query: "[?name.contains(@, 'bge')].address"

    - debug:
        var: result

我想要得到:

[
  "10.112.171.81/28",
  "10.112.171.65/28",
  "10.112.171.97/28"
]

它可以在JMESPath网站上运行,但是我的剧本却失败了:

It works on JMESPath website, but my playbook fails :

ansible-playbook play-testJMESPath.yml [WARNING]: provided hosts list
is empty, only localhost is available. Note that the implicit
localhost does not match 'all'

PLAY [Test JMESPath]
**************************************************************************************************************************************************************************************************

TASK [JMESPath query]
************************************************************************************************************************************************************************************************* fatal: [localhost]: FAILED! => {"msg": "JMESPathError in json_query
filter plugin:\nIn function contains(), invalid type for value:
external, expected one of: ['array', 'string'], received:
\"unknown\""}

PLAY RECAP
************************************************************************************************************************************************************************************************************ localhost                  : ok=0    changed=0    unreachable=0   
failed=1    skipped=0    rescued=0    ignored=0

有人可以解释一下为什么吗?

Could someone explain me why?

推荐答案

对于您看到的JMESPath问题,在这里进行了解释:

For the JMESPath issue you are seeing, this is explained here:

该问题与以下事实有关:Ansible使用自己的字符串类型: AnsibleUnicode AnsibleUnsafeText .而且,只要jmespath库具有非常严格的类型检查,它就不能接受这种类型作为字符串文字.

The problem is related to the fact that Ansible uses own types for strings: AnsibleUnicode and AnsibleUnsafeText. And as long as jmespath library has very strict type-checking, it fails to accept this types as string literals.

来源: https://github.com/ansible/ansible/issues/27299#issuecomment-331068246

使之起作用的技巧是使用 to_json |.from_json 过滤器对,以强制返回正确的类型.

The trick to make it work, as explained in the same issue, is to use a to_json | from_json filter pair, in order to force back the right type.

因此,剧本:

- hosts: localhost
  gather_facts: no

  tasks:
    - debug:
        msg: "{{ interfaces | to_json | from_json | json_query(query) }}"
      vars:
        query: "[?name.contains(@, 'bge')].address"
        interfaces:
          - name: em0
            address: 10.127.37.89/29
          - name: bge0
            address: 10.112.171.81/28
          - name: bge1
            address: 10.112.171.65/28
          - name: bge2
            address: 10.112.171.97/28

给出预期的结果:

TASK [debug] *****************************************************************************************************
ok: [localhost] => {
    "msg": [
        "10.112.171.81/28",
        "10.112.171.65/28",
        "10.112.171.97/28"
    ]
}

PLAY RECAP *******************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

这篇关于Ansible:包含带有JMESPath的字符串的过滤器元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆