Ansible-如何将selectattr与不同密钥的Yaml一起使用 [英] Ansible - how to use selectattr with yaml of different keys

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

问题描述

im试图分析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-如何将selectattr与不同密钥的Yaml一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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