遍历 Ansible 中的两个列表

Iterating through two lists in Ansible

我正在编写一个 ansible 剧本,它通过调用 API 在内部系统中创建用户,其中请求正文包含 json 格式的所有用户信息。

现在我的剧本将所有这些变量保存在一个字典列表中,如下所示:

userInfoDict: "{{[ {'FirstName': 'John', 'LastName': 'Lennon', 'Number': '', 'email': 'john@example.com'}, {'FirstName': 'Paul', 'LastName': 'McCartney', 'Number': '', 'email': 'paul@example.com'} ]}}" 

在“号码”字段为空白的地方,我有一个从内部数据库中获取可用 phone 号码的游戏,并且该号码列表保存在名为 numberList

的变量中

我想做的是遍历 UserInfoDict,并将 Number 字段设置为我的数字列表中的下一个值,但我无法做到这一点。

有没有办法在ansible中做这样的事情?您在哪里访问列表索引处的对象?

 - set_fact:
      finalUserInfo: "{{userInfoDict[i].Number : item}}"
   loop: "{{numberList}}

像这样^

您可以使用 zip filter 将两个列表组合在一起。这意味着您在 numberList 中为 userInfoDict 中的每个元素都有一个条目(旁注:这是一个误导性的 var 名称 IMO,因为它是一个列表)。根据我从您的问题中了解到的内容,我在下面创建了这样一个列表。

您可以直接循环压缩列表并访问它们的相关值。

如果您绝对需要使用组合信息创建一个新的字典列表,有几种方法可以做到这一点。我在下面使用 json_query filter 作为演示(这需要控制器上的 pip install jmespath)。

(注意:在下面的剧本中,需要相当丑陋的 ... to_json | from_json ... 来克服 jmespath <-> ansible 通信中的错误,其中压缩列表的每个元素都被解释为字符串。)

---
- name: Zip demo
  hosts: localhost
  gather_facts: false

  vars:
    userInfoDict: [{'FirstName':'John','LastName':'Lennon','Number':'','email':'john@example.com'},{'FirstName':'Paul','LastName':'McCartney','Number':'','email':'paul@example.com'}]
    numberList: ["+33123456789", "+33612345678"]

  tasks:
    - name: Looping over zipped lists directly
      vars:
        fancy_message: |-
          User first name is: {{ item.0.FirstName }}
          User last name is: {{ item.0.LastName }}
          User number is: {{ item.1 }}
          User email is: {{ item.0.email }}
      debug:
        msg: "{{ fancy_message.split('\n') }}"
      loop: "{{ userInfoDict | zip(numberList) | list }}"
      loop_control:
        label: "{{ item.0.FirstName }} {{ item.0.LastName }}"

    - name: Creating a new list of dicts with json_query
      vars:
        new_dict_query: >-
          [*].{
            "FirstName": [0].FirstName,
            "LastName": [0].LastName,
            "Number": [1],
            "email": [0].email
          }
        new_dict_list: >-
          {{
             userInfoDict
             | zip(numberList)
             | list
             | to_json
             | from_json
             | json_query(new_dict_query)
           }}
      debug:
        var: new_dict_list

给出:

PLAY [Zip demo] *****************************************************************************************************************************************************************************************************************************

TASK [Looping over zipped lists directly] ***************************************************************************************************************************************************************************************************
ok: [localhost] => (item=John Lennon) => {
    "msg": [
        "User first name is: John",
        "User last name is: Lennon",
        "User number is: +33123456789",
        "User email is: john@example.com"
    ]
}
ok: [localhost] => (item=Paul McCartney) => {
    "msg": [
        "User first name is: Paul",
        "User last name is: McCartney",
        "User number is: +33612345678",
        "User email is: paul@example.com"
    ]
}

TASK [Creating a new list of dicts with json_query] *****************************************************************************************************************************************************************************************
ok: [localhost] => {
    "new_dict_list": [
        {
            "FirstName": "John",
            "LastName": "Lennon",
            "Number": "+33123456789",
            "email": "john@example.com"
        },
        {
            "FirstName": "Paul",
            "LastName": "McCartney",
            "Number": "+33612345678",
            "email": "paul@example.com"
        }
    ]
}

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0