我在ansible中有两种类型的输入数据。 首先是字符串列表:
- '1.1.1.1'
- '2.2.2.2'
第二个是字典列表。
- {'name': 'obj1', 'addr': '1.1.1.1'}
- {'name': 'objx', 'addr': 'x.x.x.x'}
我事先不知道第一个列表的项目是否在第二个列表的地址字段中。因此我必须执行评估,为此我必须使用嵌套循环。我需要循环遍历第一个列表并循环遍历第二个列表,然后执行条件检查第一个列表的 item 是否等于第二个列表的 item.addr 。但是我不知道如何在 ansible 条件下区分第一个列表的项目和第二个列表的项目。
在Python中我会通过使用以下表达式来实现类似的事情:
for add in my_list:
for obj in my_list2:
if add == obj['addr']:
new_list.append([obj])
在ansible中应该是这样的:
- set_fact:
new_list: "{{ new_list }} + [ {'name': '{{ item_second_list.name }}', 'address': '{{ item_second_list.addr }}'} ]"
when: item_first_list == item_second_list.addr
with_list: first_list
with_list: second_list
鉴于数据
my_list:
- 1.1.1.1
- 2.2.2.2
my_dict:
- {name: obj1, addr: 1.1.1.1}
- {name: objx, addr: x.x.x.x}
以下任务
- set_fact:
sel_list: "{{ my_dict | selectattr('addr', 'in', my_list) }}"
给你想要的
sel_list:
- addr: 1.1.1.1
name: obj1
用于测试的完整剧本示例
- hosts: localhost
vars:
my_list:
- 1.1.1.1
- 2.2.2.2
my_dict:
- {name: obj1, addr: 1.1.1.1}
- {name: objx, addr: x.x.x.x}
sel_list: "{{ my_dict | selectattr('addr', 'in', my_list) }}"
tasks:
- debug:
var: sel_list
- set_fact:
sel_list: "{{ my_dict | selectattr('addr', 'in', my_list) }}"
- debug:
var: sel_list
YAML 字典中存在两个相同的键是错误的。 换句话说,你不能像这样使用
with_list
两次:它应该 生成错误,否则,除了最后一个之外的所有内容都将被忽略。在大多数情况下,Ansible 不直接支持嵌套循环。
看起来您想要生成一个包含在字典列表中的地址列表。也就是说,给定:
list1:
- 1.1.1.1
- 2.2.2.2
- 3.3.3.3
list2:
- {'name': 'obj1', 'addr': '1.1.1.1'}
- {'name': 'objx', 'addr': '2.2.2.2'}
您想要生成一个新列表:
list3:
- 1.1.1.1
- 2.2.2.2
我们可以在没有嵌套列表的情况下做到这一点,方法是询问
list2
中的所有地址,然后仅选择那些 in list1
:
---
- hosts: localhost
gather_facts: false
vars:
list1:
- 1.1.1.1
- 2.2.2.2
- 3.3.3.3
list2:
- name: obj1
addr: 1.1.1.1
- name: obj2
addr: 2.2.2.2
tasks:
- set_fact:
list3: "{{ (list3|default([])) + [item.addr] }}"
when: item.addr in list1
loop: "{{ list2 }}"
- debug:
var: list3
这将输出:
[...]
TASK [debug] *************************************************************************
ok: [localhost] => {
"list3": [
"1.1.1.1",
"2.2.2.2"
]
}
您可以尝试使用with_nested。
下面是一个例子..(不是工作代码,仅供参考)
vars:
first_list:
- '1.1.1.1'
- '2.2.2.2'
second_list:
- {'name': 'obj1', 'addr': '1.1.1.1'}
- {'name': 'objx', 'addr': '2.3.4.5'}
- set_fact:
new_list: " {{new_list|default([])}} + {{ item.1}} "
when: item.0 == item.1.addr
with_nested:
- "{{first_list}}"
- "{{second_list}}"
参考:https://docs.ansible.com/ansible/latest/plugins/lookup/nested.html
输出:
ok: [localhost] => (item=[u'1.1.1.1', {u'name': u'obj1', u'addr': u'1.1.1.1'}]) => {
"ansible_facts": {
"new_list": " [] + {u'name': u'obj1', u'addr': u'1.1.1.1'} "
},