如何在 Ansible 中的 JSON 查询中使用项目变量
How to use an item variable inside a JSON query in Ansible
我试图在 JSON 查询中使用项目变量,但结果是一个空数组。
下面是为此操作定义的任务。但是当我在列表中分别提到每个值而不是项目时,我得到了正确的值。问题仅出现在我使用 item 变量时。
- name: Get the GP id of a Network with VLAN abc
set_fact:
gpmgmt: "{{gplist | json_query(\"[?Netid == `{{item}}`].{gpid: GP[?gpname == `GP-abc`].gpID}\") }}"
with_items: "{{ gpnet }}"
register: gpidmgmt
输入JSON如下(gpnet):
[
[
"L_12345678",
"N_59786432"
]
]
输入JSON如下(gplist):
[
{
"GP": [],
"Netid": "L_12345678"
},
{
"GP": [
{
"gpID": "103",
"gpname": "GP-abc"
},
{
"gpID": "102",
"gpname": "GP-cde"
},
{
"gpID": "101",
"gpname": "efg"
}
],
"Netid": "N_59786432"
}
]
Output as below
TASK [debug] ****************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
{
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_facts": {
"gpmgmt": []
},
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"item": "L_12345678"
},
{
"ansible_facts": {
"gpmgmt": []
},
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"item": "N_59786432"
}
],
"skipped": false
}
]
}
你想要这样的东西吗?:
- name: test
hosts: localhost
vars:
gpnet: [["L_12345678","N_59786432"]]
gplist: [{"GP":[],"Netid":"L_12345678"},{"GP":[{"gpID":"103","gpname":"GP-abc"},{"gpID":"102","gpname":"GP-cde"},{"gpID":"101","gpname":"efg"}],"Netid":"N_59786432"}]
tasks:
- name: Get the GP id of a Network with VLAN abc
set_fact:
gpmgmt: "{{gpmgmt | d([]) + (gplist | json_query(query)) }}"
vars:
query: "[?Netid == '{{ item }}' ].{gpid: GP[?gpname == 'GP-abc'].gpID}"
loop: "{{ gpnet | flatten}}"
register: gpidmgmt
- name: Print register
debug:
msg: "{{ gpidmgmt }}"
- name: Print result
debug:
msg: "{{ gpmgmt }}"
结果:
TASK [Print register] ********************************
Sunday 07 November 2021 12:37:46 +0000 (0:00:00.058)
ok: [localhost] =>
msg:
changed: false
msg: All items completed
results:
- ansible_facts:
gpmgmt:
- gpid: []
ansible_loop_var: item
changed: false
failed: false
item: L_12345678
- ansible_facts:
gpmgmt:
- gpid: []
- gpid:
- '103'
ansible_loop_var: item
changed: false
failed: false
item: N_59786432
TASK [Print result] **********************
Sunday 07 November 2021 12:37:46 +0000 (0:00:00.094)
ok: [localhost] =>
msg:
- gpid: []
- gpid:
- '103'
我仍然非常不确定你到底想得到什么结果(你绝对应该编辑你的问题以添加你的精确期望)。
但基于@Frenchy 的尝试,这是我的看法,不涉及 json_query
也不涉及任务或循环:
---
- hosts: localhost
gather_facts: false
vars:
gpnet: [["L_12345678","N_59786432"]]
gplist: [{"GP":[],"Netid":"L_12345678"},{"GP":[{"gpID":"103","gpname":"GP-abc"},{"gpID":"102","gpname":"GP-cde"},{"gpID":"101","gpname":"efg"}],"Netid":"N_59786432"}]
matching_gpids_list: >-
{{
gplist |
selectattr('Netid', 'in', gpnet | flatten) |
map(attribute='GP') |
map('selectattr', 'gpname', '==', 'GP-abc') |
map('map', attribute='gpID') |
flatten
}}
tasks:
- name: Show result
debug:
var: matching_gpids_list
给出:
PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [Show result] *********************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"matching_gpids_list": [
"103"
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
我试图在 JSON 查询中使用项目变量,但结果是一个空数组。
下面是为此操作定义的任务。但是当我在列表中分别提到每个值而不是项目时,我得到了正确的值。问题仅出现在我使用 item 变量时。
- name: Get the GP id of a Network with VLAN abc
set_fact:
gpmgmt: "{{gplist | json_query(\"[?Netid == `{{item}}`].{gpid: GP[?gpname == `GP-abc`].gpID}\") }}"
with_items: "{{ gpnet }}"
register: gpidmgmt
输入JSON如下(gpnet):
[
[
"L_12345678",
"N_59786432"
]
]
输入JSON如下(gplist):
[
{
"GP": [],
"Netid": "L_12345678"
},
{
"GP": [
{
"gpID": "103",
"gpname": "GP-abc"
},
{
"gpID": "102",
"gpname": "GP-cde"
},
{
"gpID": "101",
"gpname": "efg"
}
],
"Netid": "N_59786432"
}
]
Output as below
TASK [debug] ****************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
{
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_facts": {
"gpmgmt": []
},
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"item": "L_12345678"
},
{
"ansible_facts": {
"gpmgmt": []
},
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"item": "N_59786432"
}
],
"skipped": false
}
]
}
你想要这样的东西吗?:
- name: test
hosts: localhost
vars:
gpnet: [["L_12345678","N_59786432"]]
gplist: [{"GP":[],"Netid":"L_12345678"},{"GP":[{"gpID":"103","gpname":"GP-abc"},{"gpID":"102","gpname":"GP-cde"},{"gpID":"101","gpname":"efg"}],"Netid":"N_59786432"}]
tasks:
- name: Get the GP id of a Network with VLAN abc
set_fact:
gpmgmt: "{{gpmgmt | d([]) + (gplist | json_query(query)) }}"
vars:
query: "[?Netid == '{{ item }}' ].{gpid: GP[?gpname == 'GP-abc'].gpID}"
loop: "{{ gpnet | flatten}}"
register: gpidmgmt
- name: Print register
debug:
msg: "{{ gpidmgmt }}"
- name: Print result
debug:
msg: "{{ gpmgmt }}"
结果:
TASK [Print register] ********************************
Sunday 07 November 2021 12:37:46 +0000 (0:00:00.058)
ok: [localhost] =>
msg:
changed: false
msg: All items completed
results:
- ansible_facts:
gpmgmt:
- gpid: []
ansible_loop_var: item
changed: false
failed: false
item: L_12345678
- ansible_facts:
gpmgmt:
- gpid: []
- gpid:
- '103'
ansible_loop_var: item
changed: false
failed: false
item: N_59786432
TASK [Print result] **********************
Sunday 07 November 2021 12:37:46 +0000 (0:00:00.094)
ok: [localhost] =>
msg:
- gpid: []
- gpid:
- '103'
我仍然非常不确定你到底想得到什么结果(你绝对应该编辑你的问题以添加你的精确期望)。
但基于@Frenchy 的尝试,这是我的看法,不涉及 json_query
也不涉及任务或循环:
---
- hosts: localhost
gather_facts: false
vars:
gpnet: [["L_12345678","N_59786432"]]
gplist: [{"GP":[],"Netid":"L_12345678"},{"GP":[{"gpID":"103","gpname":"GP-abc"},{"gpID":"102","gpname":"GP-cde"},{"gpID":"101","gpname":"efg"}],"Netid":"N_59786432"}]
matching_gpids_list: >-
{{
gplist |
selectattr('Netid', 'in', gpnet | flatten) |
map(attribute='GP') |
map('selectattr', 'gpname', '==', 'GP-abc') |
map('map', attribute='gpID') |
flatten
}}
tasks:
- name: Show result
debug:
var: matching_gpids_list
给出:
PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [Show result] *********************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"matching_gpids_list": [
"103"
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0