im试图解析yaml并过滤Ansible中的某些键来尝试做一件简单的事情(我认为这应该很容易)。
我的Yaml文件如下:
---
- 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
可以工作,但是会显示类似错误
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键,它将正常工作。
ok: [localhost] => {
"msg": [
{
"ip": "10.10.10.1",
"vm": "vm1"
}
]
}
如果我尝试搜索test_vm密钥,它将失败并显示:
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过滤自定义字典列表没有任何意义。
例如,如果我有一个更复杂的Yaml(不是该单位),我是否仅限于在Ansible中搜索和过滤?
例如,如果我有一个Yaml,看起来像这样:
---
- 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? 有办法吗?
非常感谢。
答案 0 :(得分:1)
selectattr
过滤器是否期望列表中的所有字典具有相同的键?
更准确地说,它期望列表中的所有字典都具有您选择的属性。这就是为什么它不适合您的情况。
幸运的是,还有其他过滤器可以完成这项工作。在这种情况下,我建议您看一下实现json_query
以下是您上述要求中的几个示例。您的最后一个片段不是正确的Yaml,所以我按我认为应该的样子进行了纠正。
剧本:
---
- 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
答案 1 :(得分:1)
更准确地说,它期望列表中的所有字典都具有您选择的属性。
并非所有过滤器功能都通过并非所有元素都定义的属性来选择对象,这并非100%正确:
{{ test_var | selectattr('vm','defined') |selectattr('vm','equalto','vm1') | list }}