Ansible-如何将selectattr与不同密钥的Yaml一起使用 [英] Ansible - how to use selectattr with yaml of different keys
问题描述
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屋!