在Ansible中使用JSON查询过滤数据,从ansible_fact中提取数据



我已经创建了这个剧本来提取从变量whitelist中匹配type= ext2, ext3, ext4的任何元素开始的所有挂载点。

问题是我可以得到所有的mount_points,但我不能用变量过滤结果。

- hosts: all
gather_facts: True
become: True
vars:
whitelist:
- /boot
- /home
- /opt
- /var
- /bin
- /usr
tasks:
- name: extract mount_points 
set_fact:
mount_point: "{{ansible_facts.mounts | selectattr('fstype', 'in', ['ext2', 'ext3', 'ext4']) | map(attribute='mount') | list }}"
- debug:
var: mount_point
vars:
query: "[?starts_with(mount, whitelist)].mount"

当我执行剧本时,我得到这个

ok: [ansible@controller] => {
"mount_point": [
"/", 
"/boot", 
"/tmp", 
"/home", 
"/var", 
"/var/opt", 
"/var/tmp", 
"/var/log", 
"/var/log/audit", 
"/opt", 
]
}

包含/tmp,这意味着query: "[?starts_with(mount, whitelist)].mount"被跳过,我不知道如何实现剧本的目标。

在这里你真的不需要json查询。一个简单的方法是用match过滤列表,并构造一个包含所有可能前缀的regex:

- name: show my filtered mountpoints:
vars:
start_regex: "{{ whitelist | map('regex_escape') | join('|') }}"
degug:
msg: "{{ {{ansible_facts.mounts | selectattr('fstype', 'in', ['ext2', 'ext3', 'ext4'])
| map(attribute='mount') | select('match', start_regex) | list }}"

在测试时,我在json_query字符串中使用了一个过滤器表达式,这为我实现了与动态变量查询字符串相同的目标.在本例中,过滤器表达式与内置函数?starts_with一起使用。此函数使用动态变量{{whitelist}},根据与搜索字符串的匹配,在fstypemount_point中的任何元素上提供布尔结果。

- name: find mount_points
debug:
msg: "{{ ansible_mounts | to_json | from_json | json_query(mount_point) }}"
vars:
mount_point: " @[?starts_with(fstype, 'ext')] | @[?starts_with(mount, '{{item}}')].mount"
loop: "{{whitelist}}"

这是输出

ok: [ansible@ansible1] => (item=/var) => {
"msg": [
"/var", 
"/var/opt", 
"/var/tmp", 
"/var/log", 
"/var/log/audit"
}
ok: [ansible@ansible1] => (item=/usr) => {
"msg": []
}
ok: [ansible@ansible1] => (item=/home) => {
"msg": [
"/home"
>>>

最新更新