jka*_*vas 3 python jinja2 ansible
我想通过解析 yaml 并过滤 Ansible 中的某些键来做一件简单的事情(我认为这应该很容易)。
我的 yaml 文件如下所示:
---
- vm: "vm1"
ip: 10.10.10.1
- vm: "vm2"
ip: 10.10.10.2
- test_vm: something
- another_vm: something_other
Run Code Online (Sandbox Code Playgroud)
所以我想不是像这样的表达
lookup('file','my_file.yaml') | from_yaml | selectattr('vm','search','vm1')|list
Run Code Online (Sandbox Code Playgroud)
会工作,但它给出了一个错误
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"}
Run Code Online (Sandbox Code Playgroud)
如果我删除 test_vm 和 another_vm 键,它工作正常。
ok: [localhost] => {
"msg": [
{
"ip": "10.10.10.1",
"vm": "vm1"
}
]
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试搜索 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 ...
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
例如,我如何快速过滤 process_2?有办法吗?
非常感谢。
过滤器是否
selectattr期望列表中的所有字典都具有相同的键?
更准确地说,它期望列表中的所有字典都具有您正在选择的属性。如果列表中并非所有字典都有它,您必须首先过滤掉未定义的项目。selectattr这也可以完成。(感谢@Randy 自我最初的回答以来使这一点变得更加清晰)。
在您的情况下,json_query过滤器(实现jmespath)有时也可以以更紧凑的方式完成这项工作。但它不是核心过滤器,需要安装community.general收集器。
以下是从您的上述需求中摘取的一些示例,这些示例均使用核心过滤器和json_query解决方案来解决。
剧本:
---
- name: "Filter data with core filters or json query"
hosts: "localhost"
gather_facts: false
vars:
# Your initial data on a single line for legibility
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 objects having vm==vm1
vars:
msg: |-
With core filters: {{ test_var | selectattr('vm', 'defined') | selectattr('vm', '==', 'vm1') | list }}
With json_query: {{ test_var | json_query("[?vm=='vm1']") | list }}
debug:
msg: "{{ msg.split('\n') }}"
- name: Get all objects having vm attribute
vars:
msg: |-
With core filters: {{ test_var | selectattr('vm', 'defined') | list }}
With json_query: {{ test_var | json_query("[?vm]") | list }}
debug:
msg: "{{ msg.split('\n') }}"
- name: Get all objects having process_2 attribute
vars:
msg: |-
With core filters: {{ test_var | selectattr('process_2', 'defined') | list }}
With json_query: {{ test_var | json_query("[?process_2]") | list }}
debug:
msg: "{{ msg.split('\n') }}"
- name: Get only a list of process_2 attributes
vars:
msg: |-
With core filters: {{ test_var | selectattr('process_2', 'defined') | map(attribute='process_2') | list }}
With json_query: {{ test_var | json_query("[].process_2") | list }}
debug:
msg: "{{ msg.split('\n') }}"
Run Code Online (Sandbox Code Playgroud)
这使:
PLAY [Filter data with core filters or json query] *********************************************************************
TASK [Get objects having vm==vm1] *********************************************************************
ok: [localhost] => {
"msg": [
"With core filters: [{'vm': 'vm1', 'ip': '10.10.10.1'}]",
"With json_query: [{'vm': 'vm1', 'ip': '10.10.10.1'}]"
]
}
TASK [Get all objects having vm attribute] *********************************************************************
ok: [localhost] => {
"msg": [
"With core filters: [{'vm': 'vm1', 'ip': '10.10.10.1'}, {'vm': 'vm2', 'ip': '10.10.10.2'}]",
"With json_query: [{'vm': 'vm1', 'ip': '10.10.10.1'}, {'vm': 'vm2', 'ip': '10.10.10.2'}]"
]
}
TASK [Get all objects having process_2 attribute] *********************************************************************
ok: [localhost] => {
"msg": [
"With core filters: [{'test_vm': 'something', 'process_1': 'X', 'process_2': 'Y', 'process_3': 'Z'}]",
"With json_query: [{'test_vm': 'something', 'process_1': 'X', 'process_2': 'Y', 'process_3': 'Z'}]"
]
}
TASK [Get only a list of process_2 attributes] *********************************************************************
ok: [localhost] => {
"msg": [
"With core filters: ['Y']",
"With json_query: ['Y']"
]
}
PLAY RECAP *********************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Run Code Online (Sandbox Code Playgroud)
小智 5
更准确地说,它期望列表中的所有字典都具有您正在选择的属性。
对于所有过滤器功能来说,并不是 100% 正确,通过不是由所有元素定义的属性来选择对象:
{{ test_var | selectattr('vm','defined') |selectattr('vm','equalto','vm1') | list }}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12588 次 |
| 最近记录: |