#ansible
#ansible
Вопрос:
Я пытаюсь понять, как объединить два dicts разных размеров. Цель состоит в том, чтобы добавить дополнительных получателей в список получателей в третьем словаре.
mail_aliases_list:
- name: mailer-daemon
recipients:
- foo
- name: postmaster
recipients:
- bar
- name: bin
recipients:
- baz
...
и
mail_aliases_defaults:
- name: mailer-daemon
recipients:
- postmaster
- name: postmaster
recipients:
- root
- name: bin
recipients:
- root
...
В результате
mail_aliases:
- name: mailer-daemon
recipients:
- postmaster
- foo
- name: postmaster
recipients:
- root
- bar
- name: bin
recipients:
- root
- baz
...
Это немного выходит за рамки моего понимания фильтров, и я разочарован тем, что мне даже приходится просить о помощи, но, надеюсь, я чему-нибудь научусь в процессе.
Ответ №1:
Нет простого способа сделать именно то, что вы хотите, а то, как структурированы ваши данные, немного усложняет задачу. Если вы включите mail_aliases_list
и mail_aliases_defaults
в словари, станет проще достичь желаемого конечного состояния.
Что-то вроде:
- hosts: localhost
gather_facts: false
become: true
vars:
mail_aliases_overrides:
mailer-daemon:
recipients:
- foo
postmaster:
recipients:
- bar
bin:
recipients:
- baz
not_in_defaults:
recipients:
- bob
mail_aliases_defaults:
mailer-daemon:
recipients:
- postmaster
postmaster:
recipients:
- root
bin:
recipients:
- root
only_in_defaults:
recipients:
- alice
tasks:
- set_fact:
mail_aliases: >-
{{ mail_aliases|default({})|combine({item:
(mail_aliases_overrides[item]|default({'recipients': []})).recipients
(mail_aliases_defaults[item]|default({'recipients': []})).recipients
})
}}
loop: "{{ (mail_aliases_overrides.keys()|list mail_aliases_defaults.keys()|list)|unique }}"
- debug:
var: mail_aliases
Это будет сгенерировано в качестве вывода:
PLAY [localhost] ******************************************************************************************************************************************************************************
TASK [set_fact] *******************************************************************************************************************************************************************************
ok: [localhost] => (item=mailer-daemon)
ok: [localhost] => (item=postmaster)
ok: [localhost] => (item=bin)
ok: [localhost] => (item=not_in_defaults)
ok: [localhost] => (item=only_in_defaults)
TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"mail_aliases": {
"bin": [
"baz",
"root"
],
"mailer-daemon": [
"foo",
"postmaster"
],
"not_in_defaults": [
"bob"
],
"only_in_defaults": [
"alice"
],
"postmaster": [
"bar",
"root"
]
}
}
PLAY RECAP ************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0
Я убедился, что это работает с ключами, которые существуют только в одном из mail_aliases_defaults
or mail_aliases_overrides
.
Комментарии:
1. Спасибо, я собираюсь попробовать это и отчитаться. Это выглядит очень многообещающе и на самом деле может быть полезным шаблоном, который я могу использовать для некоторых других ролей. Я читал, что в ansible сложно объединить словари, поэтому я избегал их, но я думаю, что это может быть решением, которое я искал.
2. Это будет использоваться в шаблоне jinja2 для записи псевдонимов почты, поэтому оно должно быть итеративным. Я думал, что способ сделать это — просто установить факт с помощью mail_aliases_overrides.keys() mail_aliases_defaults.keys() , но это не сработает, поскольку является неподдерживаемым операндом для dict_keys . Я думаю объединить два словаря, а затем изменить шаблон, чтобы использовать ключи из полученного объединенного словаря.
3. Обновление: я обновил playbook, чтобы он также работал с python3. Попробуйте. Я также добавил
|unique
фильтр, который отсутствовал в первом проекте, чтобы вы не получали повторяющиеся результаты.4. Это выглядит хорошо. Можете ли вы установить результирующий словарь как факт, а затем отладить переменную факта, вместо того, чтобы отлаживать ее напрямую, у меня возникли проблемы с пониманием того, как превратить это в переменную.
5. Смотрите мое обновление, которое теперь создает новую переменную из исходных данных.