簡體   English   中英

如何遍歷 Ansible 中的 JSON 列表,按單獨列表中的值過濾?

[英]How to loop over a JSON list in Ansible, filtered by values from a separate list?

我有一個用戶字典列表,每個字典都包含用戶名、gecos 等,以及一個組字典列表,每個字典都包含一個組成員列表。 我需要一個 Ansible 任務來僅遍歷與組列表中特定組的成員列表匹配的用戶列表條目。

我懷疑我的問題與正確使用引號和 Jinja 分隔符有關,以便在 Ansible -> Jinja -> JMESPath 層次結構中的適當級別對所有內容進行評估,但我無法確定我在做什么錯誤地。 我在下面嘗試了幾十種變體,包括將子查詢分解為它們自己的變量,但沒有有意義的反饋,我沒有太多信息可以改進。

用戶。json:

{
  "aws_users": [
    {
      "name": "userA",
      "gecos": "User A"
    },
    {
      "name": "userB",
      "gecos": "User B"
    },
    {
      "name": "userC",
      "gecos": "User C"
    }
  ]
}

組。json:

{
  "aws_groups": [
    {
      "name": "groupA",
      "members": [
        "userA",
        "userC"
      ]
    }
  ]
}

ansible.yml:

---
- hosts: 127.0.0.1
  become: true
  connection: local
  gather_facts: no
  vars_files:
    - ../../config/groups.json
    - ../../config/users.json

  vars:
     groupARoster: "{{ aws_groups | json_query('[?name==`groupA`].members | [0]') }}"
     query: "aws_users[?contains(`{{ groupARoster }}`, name)]"
     groupAUsers: "{{ aws_users | json_query(query) }}"

  tasks:
    - debug:
        var: groupARoster

    - debug:
        var: query

    - debug:
        var: groupAUsers

#    - name: Some looping thing
#      command: ...
#      loop: "{{ groupAusers }}"

Output:

PLAY [127.0.0.1] ***********************************************************************************************************************************************************************************************

TASK [debug] ***************************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
    "groupARoster": [
        "userA", 
        "userC"
    ]
}

TASK [debug] ***************************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
    "query": "aws_users[?contains(`[u'userA', u'userC']`, name)]"
}

TASK [debug] ***************************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
    "groupAUsers": ""
}

PLAY RECAP *****************************************************************************************************************************************************************************************************
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

所需的 Output(用於傳遞到 Ansible 循環參數):

"groupAUsers": [
    {
      "name": "userA",
      "gecos": "User A"
    },
    {
      "name": "userC",
      "gecos": "User C"
    }
  ]

除非您真的想為此使用 jmespath ,否則 IMO 使用selectattr有一種更簡單的方法:

groupARoster: "{{ (aws_groups | selectattr('name', 'equalto', 'groupA') | list)[0].members }}"
groupAUsers: "{{ aws_users | selectattr('name', 'in', groupARoster) | list }}"

同時,這仍然可以使用json_query 你真的很親近。 問題是您的中間查詢。 您將變量aws_user傳遞給json_query 因此,您傳遞的值中沒有第一級"aws_user"鍵。 您必須從查詢中刪除它:

groupARoster: "{{ aws_groups | json_query('[?name==`groupA`].members | [0]') }}"
query: "[?contains(`{{ groupARoster }}`, name)]"
groupAUsers: "{{ aws_users | json_query(query) }}"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM