#ansible #ansible-facts
#ansible #ansible-факты
Вопрос:
Я пишу ansible playbook, который создает пользователей во внутренней системе посредством вызова API, где тело запроса содержит всю информацию о пользователе в формате json.
Прямо сейчас мой сборник содержит все эти переменные в списке словарей, подобных этому:
userInfoDict: "{{[ {'FirstName': 'John', 'LastName': 'Lennon', 'Number': '', 'email': 'john@example.com'}, {'FirstName': 'Paul', 'LastName': 'McCartney', 'Number': '', 'email': 'paul@example.com'} ]}}"
Там, где поле «Номер» пустое, у меня есть возможность получить доступные телефонные номера из внутренней базы данных, и этот список номеров хранится в переменной с именем numberList
Что я хочу сделать, так это выполнить итерацию через UserInfoDict и установить в поле Number следующее значение в моем списке чисел, но я не смог этого сделать.
Есть ли какой-нибудь способ сделать что-то подобное в ansible? Где вы получаете доступ к объекту по индексу списка?
- set_fact:
finalUserInfo: "{{userInfoDict[i].Number : item}}"
loop: "{{numberList}}
Что-то вроде этого ^
Ответ №1:
Вы можете использовать zip
фильтр для объединения двух списков вместе. Это означает, что у вас есть запись в вашем numberList
для каждого элемента в вашем userInfoDict
(примечание: это вводящее в заблуждение имя переменной IMO, поскольку это список). Я создал такой список ниже из того, что я понял из вашего вопроса.
Вы можете выполнять цикл непосредственно по архивированным спискам и получать доступ к их соответствующим значениям.
Если вам абсолютно необходимо создать новый список dicts с объединенной информацией, есть несколько способов сделать это. Я использовал json_query
фильтр в качестве демонстрации ниже (для этого требуется pip install jmespath
контроллер).
(Примечание: в приведенном ниже сборнике задач довольно уродливое ... to_json | from_json ...
решение необходимо для устранения ошибки в jmespath <-> ansible communication, где каждый элемент заархивированных списков иначе интерпретируется как строки.)
---
- 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
Комментарии:
1. Я сейчас звоню Джону, и у него есть французский номер телефона, так что я должен быть в состоянии все это понять . PS: в этой ссылке есть реальный, без шуток, совет.