Ansible - 检查其他词典列表中是否存在词典列表中的项目

时间:2017-12-04 10:46:52

标签: list dictionary ansible

如何检查另一个词典列表中是否存在词典列表的对象(使用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

1 个答案:

答案 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"
}