Ansible中如何对复杂对象数组进行不区分大小写匹配筛选
Ansible 筛选无匹配邮箱的用户解决方案
问题背景
我有两个结构如下的复杂对象:
ProgA_Users
{ "Resources": [ { "emails": [ { "type": "work", "value": "Oscar.Warren@domain.local" } ], "id": "2939XYZ", "userName": "Oscar.Warren@domain.local@SOMEREALM" }, { "emails": [ { "type": "work", "value": "Alexandra.Savage@domain.local" } ], "id": "2032XYZ", "userName": "Alexandra.Savage@domain.local@SOMEREALM" } ] }
ProgB_Usrs
[ { "DistinguishedName": "CN=Warren\\, Oscar J.,OU=Users,OU=Finance Division,OU=Departments,DC=domain,DC=local", "Name": "Warren, Oscar J.", "ObjectClass": "user", "mail": "Oscar.Warren@domain.local" }, { "DistinguishedName": "CN=Bodden\\, John B.,OU=Users,OU=Finance Division,OU=Departments,DC=domain,DC=local", "Name": "Bodden, John B.", "ObjectClass": "user", "mail": "John.Bodden@domain.local" } ]
需求是在Ansible Playbook中遍历ProgA_Users的列表,找出所有在ProgB_Users中无匹配mail属性的用户,匹配规则为不区分大小写比对ProgA_User的emails[0].value与ProgB_User的mail。
尝试的代码如下,但会对所有对象执行debug任务,即使存在匹配项:
- name: Process Users debug: msg: "{{ item.userName }}" loop: "{{ ProgA_Users.Resources }}" loop_control: loop_var: item when: "{{ ad_users.objects|selectattr('mail','equalto','{{ item.emails[0].value }}')|list|length == 0 }}"
解决方法
原代码存在语法错误、变量名错误以及匹配逻辑不满足大小写要求的问题,修正后即可实现需求:
修正后的Playbook代码
- name: 预处理ProgB的邮箱列表(统一转小写) set_fact: progB_mails_lower: "{{ ProgB_Usrs | map(attribute='mail') | map('lower') | list }}" - name: 输出ProgA中在ProgB无匹配的用户 debug: msg: "{{ item.userName }}" loop: "{{ ProgA_Users.Resources }}" when: item.emails[0].value | lower not in progB_mails_lower
关键修正点
- 统一大小写处理:通过
set_fact将ProgB_Usrs的所有mail值转为小写并存储为列表,比对时将ProgA的邮箱也转小写,实现不区分大小写的匹配。 - 简化判断逻辑:用
not in直接判断邮箱是否存在,替代原代码中复杂的selectattr+长度判断,更高效直观。 - 修正语法与变量:
when语句无需嵌套双大括号;修正变量名ad_users.objects为实际的ProgB_Usrs;移除不必要的loop_control(默认循环变量即为item)。
这样就能精准筛选出ProgA_Users中在ProgB_Usrs里没有匹配邮箱的用户,仅这类用户会触发debug输出。
内容的提问来源于stack exchange,提问作者user1913559
相关产品推荐
相关产品推荐

