Python Ansible-如何将selectattr与不同键的yaml一起使用
我正在努力做一件简单的事情(我认为这应该很容易),解析yaml并过滤Ansible中的一些键 我的yaml文件如下所示:Python Ansible-如何将selectattr与不同键的yaml一起使用,python,ansible,jinja2,Python,Ansible,Jinja2,我正在努力做一件简单的事情(我认为这应该很容易),解析yaml并过滤Ansible中的一些键 我的yaml文件如下所示: --- - vm: "vm1" ip: 10.10.10.1 - vm: "vm2" ip: 10.10.10.2 - test_vm: something - another_vm: something_other --- - vm: "vm1" ip: 10.10.10.1 - vm: "vm2" ip: 10.10.10.2 - test_vm:
---
- vm: "vm1"
ip: 10.10.10.1
- vm: "vm2"
ip: 10.10.10.2
- test_vm: something
- another_vm: something_other
---
- 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
所以我觉得比一个表情更像
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和另一个_-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 filter是否希望列表中的所有DICT都具有相同的键?因为不能使用Jinja2筛选自定义DICT列表没有任何意义
例如,如果我有一个更复杂的yaml(不是那个平面),我是否仅限于在Ansible中搜索和过滤
例如,如果我有一个yaml,如下所示:
---
- vm: "vm1"
ip: 10.10.10.1
- vm: "vm2"
ip: 10.10.10.2
- test_vm: something
- another_vm: something_other
---
- 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
例如,如何快速筛选流程_2?
有办法吗
先谢谢你
selectattr
filter是否希望列表中的所有dict都具有相同的键
更准确地说,它期望列表中的所有dict都具有您选择的属性。这就是为什么它不适合你的情况
幸运的是,还有其他过滤器可以完成这项工作。在这种情况下,我建议您看看哪些实现
以下是从您的上述要求中选取的一些示例。您的最后一个代码片段不是正确的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
更准确地说,它期望列表中的所有dict都具有您选择的属性
并非所有过滤器函数都是100%正确的,通过并非所有元素都定义的属性选择对象:
{{ test_var | selectattr('vm','defined') |selectattr('vm','equalto','vm1') | list }}
thx@Zeitounator。我已经看过json_查询并解决了我的问题。但我很高兴你的回答。很好的例子。糟糕的是,jmespath中的过滤器不太具有解释性。例如,我在用逻辑或字典进行过滤时遇到了麻烦。无论如何,最终我找到了它,使用contains,但仍然…Jinja2和jmespath可能会更好。