Ansible - 如何在不同键的 yaml 中使用 selectattr [英] Ansible - how to use selectattr with yaml of different keys

查看:21
本文介绍了Ansible - 如何在不同键的 yaml 中使用 selectattr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过解析 yaml 并过滤 Ansible 中的某些键来做一件简单的事情(我认为这应该很容易).

im pulling my hairs trying to do a simple thing (i thought it should be easy) with parsing a yaml and filtering for some key in Ansible.

我的 yaml 文件如下所示:

My yaml file looks like this:

---

- vm: "vm1"
  ip: 10.10.10.1
- vm: "vm2"
  ip: 10.10.10.2
- test_vm: something
- another_vm: something_other

所以我认为不是像

lookup('file','my_file.yaml') | from_yaml | selectattr('vm','search','vm1')|list

可以工作,但会出现类似

would work but it gives an error like

fatal: [localhost]: FAILED! => {"msg": "Unexpected templating type error occurred on ({{ lookup('file','{{sysfile}}') | from_yaml | selectattr('vm','search','vm1')|list}}): expected string or bytes-like object"}

如果我删除 test_vm 和 another_vm 键,它就可以正常工作.

If i remove the test_vm and another_vm keys it works fine.

ok: [localhost] => {
    "msg": [
        {
            "ip": "10.10.10.1",
            "vm": "vm1"
        }
    ]
}

如果我尝试搜索 test_vm 键,它会失败:

If i try to search for the test_vm key it fails with:

fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'test_vm'\n\nThe error appears to be ...

selectattr 过滤器是否希望列表中的所有字典都具有相同的键?因为不能使用 Jinja2 过滤自定义字典列表没有任何意义.

Is selectattr filter expecting all the dicts in the list to have the same keys?Because it does not make any sense not to be able to filter a list of custom dicts with Jinja2.

例如,如果我有一个更复杂的 yaml(不是那么简单),我是否只能在 Ansible 中进行搜索和过滤?

For example if i had a more complicated yaml (not that flat) am i limited to search and filter within Ansible?

例如,如果我有一个 yaml 看起来像这样:

For example if i have a yaml looks like this:

---

- vm: "vm1"
  ip: 10.10.10.1
- vm: "vm2"
  ip: 10.10.10.2
- test_vm: something
   - process_1: X
   - process_2: Y
   - process_3: Z
- another_vm: something_other

例如,我如何快速过滤 process_2?有办法吗?

how can i quickly filter for the process_2 for example? Is there a way?

非常感谢.

推荐答案

selectattr 过滤器是否期望列表中的所有字典都具有相同的键?

Is selectattr filter expecting all the dicts in the list to have the same keys?

更准确地说,它希望列表中的所有字典都具有您正在选择的属性.这就是它不适合您的情况的原因.

More precisely, it is expecting all dicts in the list to have the attribute you are selecting on. This is why it is not adapted to your case.

幸运的是,还有其他过滤器可以完成这项工作.在这种情况下,我建议您查看 json_query 实现了 jmespath

Fortunately, there are other filters that can do the job. In this case, I suggest you have a look at json_query which implements jmespath

以下是从您的上述要求中提取的一些示例.你的最后一个片段不是一个正确的 yaml,所以我更正了我认为它应该看起来的样子.

Here are a few examples taken from your above requirements. Your last snippet is not a correct yaml so I corrected as I thought it should look like.

剧本:

---
- name: "Filter data with json_query"
  hosts: "localhost"
  gather_facts: false

  vars:
    test_var:
      - vm: "vm1"
        ip: 10.10.10.1
      - vm: "vm2"
        ip: 10.10.10.2
      - test_vm: something
        process_1: X
        process_2: Y
        process_3: Z
      - another_vm: something_other

  tasks:
    - name: Get object having vm==vm1
      debug:
        msg: "{{ test_var | json_query(\"[?vm=='vm1']\") | list }}"

    - name: Get all objects having vm attribute
      debug:
        msg: "{{ test_var | json_query(\"[?vm]\") | list }}"

    - name: Get all objects having process_2 attribute
      debug:
        msg: "{{ test_var | json_query(\"[?process_2]\") | list }}"

    - name: Get only a list of process_2 attributes
      debug:
        msg: "{{ test_var | json_query(\"[].process_2\") | list }}"

给出:

PLAY [Filter data with json_query] **************************************************************************************************************************************************************************************************************************************

TASK [Get object having vm==vm1] ****************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "ip": "10.10.10.1",
            "vm": "vm1"
        }
    ]
}

TASK [Get all objects having vm attribute] ******************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "ip": "10.10.10.1",
            "vm": "vm1"
        },
        {
            "ip": "10.10.10.2",
            "vm": "vm2"
        }
    ]
}

TASK [Get all objects having process_2 attribute] ***********************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "process_1": "X",
            "process_2": "Y",
            "process_3": "Z",
            "test_vm": "something"
        }
    ]
}

TASK [Get only a list of process_2 attributes] ***************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "Y"
    ]
}

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

这篇关于Ansible - 如何在不同键的 yaml 中使用 selectattr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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