Ansible 循环遍历 json 输出并添加索引
Ansible loop through json output and add indexing
几个小时以来,我一直在努力弄清楚如何使用 Ansible 执行以下操作,并循环遍历 JSON 输出。
让我解释一下,这是我的剧本:
- hosts: myhosts
connection: local
gather_facts: yes
tasks:
- name: set_fact
set_fact:
disk_info: "{{ disks | json_query('[*].{disk_size: disksize}')}}"
- name: print set_fact
debug:
msg: "{{ disk_info }}"
- name: iterate on disk_info one and increase index 1..n
debug:
msg: "{{ item }} {{ my_idx }}"
loop:
- "{{ disk_info }}"
loop_control:
index_var: my_idx
这是任务 - name: print
输出的 json 输出:
TASK [print] ****************************************************
ok: [hostname1] => {
"msg": [
{
"disk_size": "200"
},
{
"disk_size": "200"
},
{
"disk_size": "200"
}
]
}
ok: [hostname2] => {
"msg": [
{
"disk_size": “300"
}
]
}
ok: [hostname3] => {
"msg": [
{
"disk_size": "250”
}
]
}
ok: [hostname4] => {
"msg": [
{
"disk_size": “500"
},
{
"disk_size": “600”
}
]
}
这是我从任务中得到的输出 (- name: iterate on disk_info one and increase index 1..n
)
ok: [hostname1] => (item=[{'disk_size': '200'}, {'disk_size': '200'}, {'disk_size': '200'}]) => {
"msg": "[{'disk_size': '200'}, {'disk_size': '200'}, {'disk_size': '200'}] 0"
}
ok: [hostname2] => (item=[{'disk_size': ‘300'}]) => {
"msg": "[{'disk_size': ‘300'}] 0"
}
ok: [hostname4] => (item=[{'disk_size': ‘500'}, {'disk_size': '600’}]) => {
"msg": "[{'disk_size': ’500'}, {'disk_size': '600’}] 0"
}
预期输出:
Hostname1:
disk_size1: 200
disk_size2: 200
disk_size3: 200
Hostname2:
disk_size1: 300
Hostname3:
disk_size1: 500
disk_size2: 600
预期输出可能与此类似,但添加了索引。
您是要将索引添加到结构还是文本输出?要获得预期的输出,您的最后一个任务应该遍历列表(而不是包含列表的列表)并以该形式输出数据:
- name: iterate on disk_info one and increase index 1..n
debug:
msg: "disk_size{{ my_idx }}: {{ item.disk_size }}"
loop: "{{ disk_info }}"
loop_control:
index_var: my_idx
创建结构比较困难,但并非不可能。我将在不使用 json_query
或 set_fact
的情况下进行演示,除非您正在做一些没有它们就不可能完成的事情。
- hosts: my_hosts
vars:
# You didn't provide an example of your input structure, so I'm assuming it
# looks something like this.
disks:
- name: foo
disksize: 200
- name: bar
disksize: 200
disk_info: "{{ dict(range(0, disks | length) | map('regex_replace', '^', 'disk_size') | zip(disks | map(attribute='disksize'))) }}"
tasks:
- debug:
msg: "{{ disk_info }}"
结果:
TASK [debug] *******************************************************************
ok: [harmless-ghoul.syslog.x.mail.umich.edu] => {
"msg": {
"disk_size0": 200,
"disk_size1": 200
}
}
几个小时以来,我一直在努力弄清楚如何使用 Ansible 执行以下操作,并循环遍历 JSON 输出。
让我解释一下,这是我的剧本:
- hosts: myhosts
connection: local
gather_facts: yes
tasks:
- name: set_fact
set_fact:
disk_info: "{{ disks | json_query('[*].{disk_size: disksize}')}}"
- name: print set_fact
debug:
msg: "{{ disk_info }}"
- name: iterate on disk_info one and increase index 1..n
debug:
msg: "{{ item }} {{ my_idx }}"
loop:
- "{{ disk_info }}"
loop_control:
index_var: my_idx
这是任务 - name: print
输出的 json 输出:
TASK [print] ****************************************************
ok: [hostname1] => {
"msg": [
{
"disk_size": "200"
},
{
"disk_size": "200"
},
{
"disk_size": "200"
}
]
}
ok: [hostname2] => {
"msg": [
{
"disk_size": “300"
}
]
}
ok: [hostname3] => {
"msg": [
{
"disk_size": "250”
}
]
}
ok: [hostname4] => {
"msg": [
{
"disk_size": “500"
},
{
"disk_size": “600”
}
]
}
这是我从任务中得到的输出 (- name: iterate on disk_info one and increase index 1..n
)
ok: [hostname1] => (item=[{'disk_size': '200'}, {'disk_size': '200'}, {'disk_size': '200'}]) => {
"msg": "[{'disk_size': '200'}, {'disk_size': '200'}, {'disk_size': '200'}] 0"
}
ok: [hostname2] => (item=[{'disk_size': ‘300'}]) => {
"msg": "[{'disk_size': ‘300'}] 0"
}
ok: [hostname4] => (item=[{'disk_size': ‘500'}, {'disk_size': '600’}]) => {
"msg": "[{'disk_size': ’500'}, {'disk_size': '600’}] 0"
}
预期输出:
Hostname1:
disk_size1: 200
disk_size2: 200
disk_size3: 200
Hostname2:
disk_size1: 300
Hostname3:
disk_size1: 500
disk_size2: 600
预期输出可能与此类似,但添加了索引。
您是要将索引添加到结构还是文本输出?要获得预期的输出,您的最后一个任务应该遍历列表(而不是包含列表的列表)并以该形式输出数据:
- name: iterate on disk_info one and increase index 1..n
debug:
msg: "disk_size{{ my_idx }}: {{ item.disk_size }}"
loop: "{{ disk_info }}"
loop_control:
index_var: my_idx
创建结构比较困难,但并非不可能。我将在不使用 json_query
或 set_fact
的情况下进行演示,除非您正在做一些没有它们就不可能完成的事情。
- hosts: my_hosts
vars:
# You didn't provide an example of your input structure, so I'm assuming it
# looks something like this.
disks:
- name: foo
disksize: 200
- name: bar
disksize: 200
disk_info: "{{ dict(range(0, disks | length) | map('regex_replace', '^', 'disk_size') | zip(disks | map(attribute='disksize'))) }}"
tasks:
- debug:
msg: "{{ disk_info }}"
结果:
TASK [debug] *******************************************************************
ok: [harmless-ghoul.syslog.x.mail.umich.edu] => {
"msg": {
"disk_size0": 200,
"disk_size1": 200
}
}