如何在 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