我正在尝试编写一个角色来查找 DN 服务器中的记录和 Git 中的记录之间的差异。其中一些是通过 Web 界面手动添加的。 为此,在我的 Ansible 剧本中,我动态生成如下变量:
- hosts: dn_servers
vars:
domains:
int_domain: int.domain.com
ext_domain: domain.com
tasks:
- name: Generates list of hostnames for every domain present in var domain
ansible.builtin.set_fact:
"{{ item.key }}_git_records": "{{ list of A records generated with the help of item.value }}"
loop: "{{ domains | dict2items }}"
然后我尝试在 Ansible 过滤器中重用这些变量
rejectattr
:
- name: Find difference between remote hosts and Git file
ansible.builtin.set_fact:
"{{ item.key }}_inconsistent_hostnames": "{{ remote_records | selectattr('domain', '==', item.value) | rejectattr('hostname', 'in', (item.key ~ '_git_records')) }}"
loop: "{{ domains | dict2items }}"
但是过滤器
rejectattr
过滤失败。我确定问题就在这里(item.key ~ '_gitlab_hostnames')
,因为在我对第三个参数进行硬编码后它按预期工作。
也许问题是在变量和字符串连接后rejectattr
将第三个参数视为字符串而不是变量?
如果是的话,如何解决?
您正在寻找间接寻址。表达式
item.key ~ '_git_records'
创建变量的名称,但不传递值
rejectattr('hostname', 'in', (item.key ~ '_git_records'))
第三个参数必须是一个列表。例如,给定数据
domains:
int_domain: int.domain.com
ext_domain: domain.com
remote_records:
- {domain: int.domain.com, hostname: h1}
- {domain: int.domain.com, hostname: h9}
int_domain_git_records: [h1, h2, h3]
ext_domain_git_records: [h6, h7, h8]
您必须使用 vars 查找来寻址循环中的列表 int_domain_git_records, ext_domain_git_records, ... 下面
- debug:
msg: "{{ remote_records |
selectattr('domain', '==', item.value) |
rejectattr('hostname', 'in', lookup('vars', item.key ~ '_git_records')) }}"
loop: "{{ domains | dict2items }}"
给出(删节)
msg:
- domain: int.domain.com
hostname: h9
msg: []
用于测试的完整剧本示例
- hosts: localhost
vars:
domains:
int_domain: int.domain.com
ext_domain: domain.com
remote_records:
- {domain: int.domain.com, hostname: h1}
- {domain: int.domain.com, hostname: h9}
int_domain_git_records: [h1, h2, h3]
ext_domain_git_records: [h6, h7, h8]
tasks:
- debug:
msg: "{{ lookup('vars', 'int_domain' ~ '_git_records') }}"
- debug:
msg: "{{ remote_records |
selectattr('domain', '==', item.value) |
rejectattr('hostname', 'in', lookup('vars', item.key ~ '_git_records')) }}"
loop: "{{ domains | dict2items }}"