前言
lookup 插件可以配合 loop 关键词循环实现 with_x 循环
lookup 查询插件
通过不同的参数,返回结果集,结果集是一个列表。
query 插件与 lookup 插件一样,区别在于 query 默认情况下,启用了wantlist=true。
wantlist 的意思是将返回的字符串构成一个列表
另外,query 可以简写为q
loop 关键词
loop 作用是将一个列表循环输出,每次循环时,将列表子元素赋值给 item 变量. 官方用来替代 with_xxx
lookup和loop结合
loop用来遍历 lookup 结果集。
自定义loop循环中的子元素变量为 xxx,代替item
loop_control: loop_var: xxx
loop_control 还有其它控制,比如
- index_var: var_name 循环索引.
- pause: time 循环间隔时间
- label: var_name 去掉 var_name 之外的不相干信息输出
lookup常用参数示例
file 参数
多个文件内容合并在一起,或以字符串逗号分隔输出,或以列表形式输出
ini 参数
获取 ini 配置信息
# ~/test.ini
[testA]
a1=zhangsan
a2=lisi
[testB]
b1=wangwu
---
- hosts: localhost
gather_facts: no
remote_user: zyh
tasks:
- name: get ini
debug:
msg: "{{ q('ini', 'a1 section=testA file=~/test.ini') }}"
ok: [localhost] => {
"msg": [
"zhangsan"
]
}
当配置是 properties,可以追加 type=properties
dict参数
生成一个字典列表
# 结果集
[{key: xxx, value: xxx}, {key: xxx, value: xxx}]
---
- hosts: local
gather_facts: no
connection: local
vars:
users:
male: Bob
female: Maris
tasks:
- name: test vars 1
loop: "{{ lookup('dict', users) }}"
debug:
msg: "{{ item.key }}: {{ item.value }}"
ok: [localhost] => (item={'key': u'male', 'value': u'Bob'}) => {
"msg": "male: Bob"
}
ok: [localhost] => (item={'key': u'female', 'value': u'Maris'}) => {
"msg": "female: Maris"
}
subelements参数
# 写法:
{{ lookup('subelements',list,'content') }}
# 一个由相同结构字典组成的列表list,将字典中某一个元素key(值必须是列表)与字典剩余的元素(剩余的元素作为一个整体新字典),构建笛卡尔积。从而形成 item。每一个字典拆分组合后的 item 构建结果集 items
# 结果集
items=[
[{list.0.剩余kv}, list.0.key.0],
[{list.0.剩余kv}, list.0.key.1],
[{list.1.剩余kv}, list.1.key.0],
[{list.1.剩余kv}, list.1.key.1],
]
---
- hosts: local
gather_facts: no
connection: local
vars:
users:
- name: Bob
gender: male
age: 18
content:
- eating
- sleeping
- play ogre
- name: Maris
gender: female
age: 20
content:
- eating
- sleeping
- shopping
tasks:
- name: test vars 2
debug:
msg: "{{ item.0.name }} - {{ item.0.gender }} - {{ item.1 }}"
loop: "{{ lookup('subelements',users,'content') }}"
ok: [localhost] => (item=[{u'gender': u'male', u'age': 18, u'name': u'Bob'}, u'eating']) => {
"msg": "Bob - male - eating"
}
ok: [localhost] => (item=[{u'gender': u'male', u'age': 18, u'name': u'Bob'}, u'sleeping']) => {
"msg": "Bob - male - sleeping"
}
ok: [localhost] => (item=[{u'gender': u'male', u'age': 18, u'name': u'Bob'}, u'play ogre']) => {
"msg": "Bob - male - play ogre"
}
ok: [localhost] => (item=[{u'gender': u'female', u'age': 20, u'name': u'Maris'}, u'eating']) => {
"msg": "Maris - female - eating"
}
ok: [localhost] => (item=[{u'gender': u'female', u'age': 20, u'name': u'Maris'}, u'sleeping']) => {
"msg": "Maris - female - sleeping"
}
ok: [localhost] => (item=[{u'gender': u'female', u'age': 20, u'name': u'Maris'}, u'shopping']) => {
"msg": "Maris - female - shopping"
}
若有多个key需要附加,需要 nested 与 include_tasks 的组合实现
nested参数
将多个列表进行笛卡尔积运算
- test3.yml 中拿到 users循环单体 user
- 针对循环单体 user引入附加任务 test3_1.yml
- 通过lookup插件nested,将 user字典中各key的value相互遍历,构建新列表 item
################ test3.yml
---
- hosts: local
gather_facts: no
connection: local
vars:
users:
- name: Bob
gender: male
age: 18
content:
- eating
- sleeping
- play ogre
specialty:
- english
- game
- name: Maris
gender: female
age: 20
content:
- eating
- sleeping
- shopping
specialty:
- history
- cooking
tasks:
- include_tasks: test3_1.yml
loop: "{{ users }}"
loop_control:
loop_var: user
################ test3_1.yml
- loop: "{{ lookup('nested',user.name, user.age, user.content, user.specialty) }}"
debug:
msg: "name:{{ item.0 }}, age:{{ item.1 }}, {{ item.2 }}, {{ item.3 }}"
ok: [localhost] => (item=[u'Bob', 18, u'eating', u'english']) => {
"msg": "name:Bob, age:18, eating, english"
}
ok: [localhost] => (item=[u'Bob', 18, u'eating', u'game']) => {
"msg": "name:Bob, age:18, eating, game"
}
ok: [localhost] => (item=[u'Bob', 18, u'sleeping', u'english']) => {
"msg": "name:Bob, age:18, sleeping, english"
}
ok: [localhost] => (item=[u'Bob', 18, u'sleeping', u'game']) => {
"msg": "name:Bob, age:18, sleeping, game"
}
ok: [localhost] => (item=[u'Bob', 18, u'play ogre', u'english']) => {
"msg": "name:Bob, age:18, play ogre, english"
}
ok: [localhost] => (item=[u'Bob', 18, u'play ogre', u'game']) => {
"msg": "name:Bob, age:18, play ogre, game"
}
ok: [localhost] => (item=[u'Maris', 20, u'eating', u'history']) => {
"msg": "name:Maris, age:20, eating, history"
}
ok: [localhost] => (item=[u'Maris', 20, u'eating', u'cooking']) => {
"msg": "name:Maris, age:20, eating, cooking"
}
ok: [localhost] => (item=[u'Maris', 20, u'sleeping', u'history']) => {
"msg": "name:Maris, age:20, sleeping, history"
}
ok: [localhost] => (item=[u'Maris', 20, u'sleeping', u'cooking']) => {
"msg": "name:Maris, age:20, sleeping, cooking"
}
ok: [localhost] => (item=[u'Maris', 20, u'shopping', u'history']) => {
"msg": "name:Maris, age:20, shopping, history"
}
ok: [localhost] => (item=[u'Maris', 20, u'shopping', u'cooking']) => {
"msg": "name:Maris, age:20, shopping, cooking"
}