遍历 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
我正在编写一个 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