如何检查另一个词典列表中是否存在词典列表的对象(使用Ansible?)
您可以尝试使用jinja过滤器selectattr
- 我在使用它时遇到了问题,因此我确实恢复了简化但难看的解决方案 - 构建filtered list
并仅比较过滤后的属性({{1} })。
我不喜欢它,但它有效。
如果你知道其他方式,请告诉我。
剧本:
list-to-list
hosts_vars / prd-inner-mgmt202 #a词典列表
- name: find existing system_crontabs #would generate a list of dict
find:
path: /var/spool/cron/crontabs/
register: system_side_crontabs
become: True
- name: create lists of system_cron_names and repo_cron_names
set_fact:
system_cron_names: "[]"
repo_cron_names: "[]"
- name: build list of system_cron_names
set_fact:
system_cron_names: "{{ system_cron_names }} + [ '{{ item.path |basename }}' ]"
with_items: "{{ system_side_crontabs.files }}"
- name: build lists of repo_cron_names
set_fact:
repo_cron_names: "{{ repo_cron_names }} + [ '{{ item.user }}' ]"
with_items: "{{ crontabs }}"
- name: assert check if an object of system_crontab is defined in repo_crontab
assert:
that: "{{ [item] |intersect(repo_cron_names) | length }} == 1"
with_items: "{{ system_cron_names }}"
找到
的结果crontabs:
- user: root
crontab_rules: |
11 1 * * * find /home/ansible/.ansible/tmp/ -atime +10 -delete
生成易于比较的字符串列表
ok: [prd-inner-mgmt202] => {
"changed": false,
"examined": 1,
"files": [ ### List of dictionary
{
"path": "/var/spool/cron/crontabs/root",
},
{
"path": "/var/spool/cron/crontabs/another_file",
}
],
"invocation": {
"module_args": {
"age": null,
"age_stamp": "mtime",
"contains": null,
"file_type": "file",
"follow": false,
"get_checksum": false,
"hidden": false,
"path": "/var/spool/cron/crontabs/",
"paths": [
"/var/spool/cron/crontabs/"
],
"patterns": [
"*"
],
"recurse": false,
"size": null,
"use_regex": false
},
"module_name": "find"
},
"matched": 1,
"msg": ""
}
生成另一个字符串列表
TASK [mid_crontab : build list of system_cron_names] **************************
"ansible_facts": {
"system_cron_names": [
"root",
]
},
"changed": false,
"invocation": {
"module_args": {
"system_cron_names": [
"root"
]
},
"module_name": "set_fact"
},
断言所需的检查,使用TASK [mid_crontab : build list of repo_cron_names] *****************************
ok: [prd-inner-mgmt202] => (item={u'crontab_rules': u'11 1 * * * find /home/ansible/.ansible/tmp/ -atime +10 -delete\n', u'user': u'root'}) => {
"ansible_facts": {
"repo_cron_names": [
"root"
]
},
"changed": false,
"invocation": {
"module_args": {
"repo_cron_names": [
"root",
"other"
]
},
"module_name": "set_fact"
},
"item": {
"crontab_rules": "11 1 * * * find /home/ansible/.ansible/tmp/ -atime +10 -delete\n",
"user": "root"
}
}
jinja过滤器。在我的情况下,我的存储库中应该存在系统定义的对象(cron记录) - 因此列表应该有1个元素。
intersect
答案 0 :(得分:0)
似乎你想将原始字典缩减为字符串(名称)列表并比较差异:
---
- hosts: localhost
gather_facts: no
vars:
crontabs:
- user: root
crontab_rules: xxx
tasks:
- find:
path: /tmp/test
register: myfiles
- assert:
that: sys_crons_violation | count == 0
msg: "This crons are not defined in repo : {{ sys_crons_violation | join(', ') }}"
vars:
sys_crons: "{{ myfiles.files | map(attribute='path') | map('basename') | list }}"
repo_crons: "{{ crontabs | map(attribute='user') | list }}"
sys_crons_violation: "{{ sys_crons | difference(repo_crons) }}"
结果:
TASK [find] ************************
TASK [assert] **********************
fatal: [localhost]: FAILED! => {
"assertion": "sys_crons_violation | count == 0",
"changed": false,
"evaluated_to": false,
"msg": "This crons are not defined in repo : another_file"
}