Ansible - Создание словаря из списка
Я пытаюсь следовать этой теме, но мои результаты не соответствуют ожиданиям. каждый предыдущий элемент перезаписывается с добавлением нового элемента.
мой вход - это список, который я загружаю в переменные account_list:
account:
- PR_user1
- PR_user2
Во входном файле нет паролей. Мне нужно создать случайные пароли для каждой учетной записи пользователя, использовать их при настройке различных служб, а затем сбросить их в текстовый файл для использования человеком.
Моя первая задача, над которой я застрял, состоит в том, что, прочитав их в списке, я хочу перебрать их, создать пароль для каждой учетной записи, а затем сохранить его в словаре в виде пар ключ-значение.
Я попробовал оба метода, упомянутых выше, чтобы добавить элемент в существующий словарь, используя комбинацию, а также "+".
мои данные представляют собой простой список под названием "учетные записи".
- set_fact:
# domain_accounts: "{{ domain_accounts|default({}) | combine({item|trim: lookup(...)} ) }}"
domain_accounts: "{{ domain_accounts|default([]) + [{item|trim:lookup('...)}] }}"
with_items: "{{account_list.accounts}}"
Мой вывод выглядит следующим образом:
TASK [set account passwords]
******************************************************************
ok: [localhost] => (item=PR_user1) => {"ansible_facts": {"domain_accounts": [{"PR_user1": "u]oT,cU{"}]}, "changed": false, "item": "PR_user1"}
ok: [localhost] => (item=PR_user2) => {"ansible_facts": {"domain_accounts": [{"PR_user2": "b>npKZdi"}]}, "changed": false, "item": "PR_user2"}
1 ответ
Предположим, что списки переменных выглядят следующим образом (я полагаю, это не ваш случай):
accounts:
- user: PR_user1
password: "u]oT,cU{"
- user: PR_user2
password: "b>npKZdi"
С:
- name: debug
debug:
var: accounts
а также
- name: Populate dict
set_fact:
domain_accounts: "{{ domain_accounts|default({}) | combine( {item.user: item.password} ) }}"
with_items:
- "{{ accounts }}"
плюс:
- name: debug
debug:
var: domain_accounts
Ты получишь:
ok: [localhost] => {
"domain_accounts": {
"PR_user1": "u]oT,cU{",
"PR_user2": "b>npKZdi"
}
}
Но я думаю, у вас есть что-то вроде:
accounts:
- PR_user1: "u]oT,cU{"
- PR_user2: "b>npKZdi"
Так:
- name: Create dict
set_fact:
domain_accounts: "{{ domain_accounts|default({}) | combine(item.1) }}"
with_indexed_items: "{{accounts}}"
- name: debug
debug:
var: domain_accounts
Получите:
ok: [localhost] => {
"domain_accounts": {
"PR_user1": "u]oT,cU{",
"PR_user2": "b>npKZdi"
}
}
Это вся игра для вашей справки:
---
- hosts: localhost
gather_facts: False
vars:
accounts:
- user: PR_user1
password: "u]oT,cU{"
- user: PR_user2
password: "b>npKZdi"
accountslist:
- PR_user1: "u]oT,cU{"
- PR_user2: "b>npKZdi"
tasks:
- name: Debug Accounts
debug:
var: accounts
- name: Debug Accounts List
debug:
var: accountslist
- name: Populate dict
set_fact:
domain_accounts: "{{ domain_accounts|default({}) | combine( {item.user: item.password} ) }}"
with_items:
- "{{ accounts }}"
- name: Debug Domain Accounts
debug:
var: domain_accounts
- name: indexed loop demo
debug:
msg: "{{ item.1 }}"
with_indexed_items: "{{accountslist}}"
- name: Create Local Dict
set_fact:
local_accounts: "{{ local_accounts|default({}) | combine(item.1) }}"
with_indexed_items: "{{accountslist}}"
- name: Debug Local Accounts
debug:
var: local_accounts
И результаты:
PLAY [localhost] *********************************************************************************************************************
TASK [Debug Accounts] ****************************************************************************************************************
ok: [localhost] => {
"accounts": [
{
"password": "u]oT,cU{",
"user": "PR_user1"
},
{
"password": "b>npKZdi",
"user": "PR_user2"
}
]
}
TASK [Debug Accounts List] ***********************************************************************************************************
ok: [localhost] => {
"accountslist": [
{
"PR_user1": "u]oT,cU{"
},
{
"PR_user2": "b>npKZdi"
}
]
}
TASK [Populate dict] *****************************************************************************************************************
ok: [localhost] => (item={u'password': u'u]oT,cU{', u'user': u'PR_user1'})
ok: [localhost] => (item={u'password': u'b>npKZdi', u'user': u'PR_user2'})
TASK [Debug Domain Accounts] *********************************************************************************************************
ok: [localhost] => {
"domain_accounts": {
"PR_user1": "u]oT,cU{",
"PR_user2": "b>npKZdi"
}
}
TASK [indexed loop demo] *************************************************************************************************************
ok: [localhost] => (item=None) => {
"msg": {
"PR_user1": "u]oT,cU{"
}
}
ok: [localhost] => (item=None) => {
"msg": {
"PR_user2": "b>npKZdi"
}
}
TASK [Create Local Dict] *************************************************************************************************************
ok: [localhost] => (item=(0, {u'PR_user1': u'u]oT,cU{'}))
ok: [localhost] => (item=(1, {u'PR_user2': u'b>npKZdi'}))
TASK [Debug Local Accounts] **********************************************************************************************************
ok: [localhost] => {
"local_accounts": {
"PR_user1": "u]oT,cU{",
"PR_user2": "b>npKZdi"
}
}
PLAY RECAP ***************************************************************************************************************************
localhost : ok=7 changed=0 unreachable=0 failed=0
Самым чистым решением может быть создание собственного доступного фильтра:
- Создать папку
filter_plugins
в вашем доступном каталоге. - Создайте файл с именем
to_dict.py
.
Добавьте следующий контент.
class FilterModule(object):
def filters(self):
return {'to_dict': lambda _list: {key: value for key, value in [value.split('=') for value in _list]}}
Ansible vars:
account:
- PR_user1=value1
- PR_user2=value2
Задача:
"{{ account | to_dict }}"