Подтвердить что ты не робот

Слияние словарей в недоступных

В настоящее время я занимаюсь созданием роли для установки PHP с помощью незаменимого, и мне сложно слить словари. Я пробовал несколько способов сделать это, но я не могу заставить его работать, как я хочу:

# A vars file:
my_default_values:
  key = value

my_values:
  my_key = my_value


# In a playbook, I create a task to attempt merging the
# two dictionaries (which doesn't work):

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: my_default_values + my_values

# I have also tried:

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: my_default_values|union(my_values)

# I have /some/ success with using j2 update,
# but you can't use j2 syntax in "with_dict", it appears.
# This works:

- debug: msg="{{ my_default_values.update(my_values) }}"

# But this doesn't:

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: my_default_values.update(my_values)

Есть ли способ слить два словаря, поэтому я могу использовать его с "with_dict"?

4b9b3361

Ответ 1

В Ansible 2.0 есть фильтр Jinja, combine, для этого:

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: "{{ my_default_values | combine(my_values) }}"

Ответ 2

Если вы хотите слить хэш, я бы включил функцию слияния хэшей в недоступном. В вашем конфигурационном файле включить хеш слияния.

С hash_behaviour = merge вы можете иметь два файла var с тем же именем переменной:

defaults.yml:

values:
  key: value

overrides.yml:

values:
  my_key: my_value

Чтобы объединить два vars, вам нужно будет включить оба файла var:

ansible-playbook some-play.yml ... [email protected]  [email protected]

И вы закончите с этим:

TASK: [debug var=values] ********************************************************
ok: [localhost] => {
    "values": {
        "key": value,
        "my_key": my_value
    }
}

Вызов обновления для переменной может быть выполнен в Jinja, но в целом это будет грязно, я бы не сделал это за пределами ваших шаблонов и даже тогда попытаюсь избежать его вообще.

Ответ 3

Теперь можно использовать привязку и расширить возможности YAML:

---
- hosts: localhost
  vars:
    my_default_values: &def
      key: value
    my_values:
      <<: *def
      my_key: my_value
  tasks:
    - debug: var=my_default_values
    - debug: var=my_values

Результат:

TASK [debug]
ok: [localhost] => {
    "my_default_values": {
        "key": "value"
    }
}

TASK [debug] 
ok: [localhost] => {
    "my_values": {
        "key": "value", 
        "my_key": "my_value"
    }
}

Я понятия не имею, почему это не упоминалось раньше.

Ответ 4

Если вам нужен объединенный словарь несколько раз, вы можете установить его в новую "переменную":

- set_fact: _my_values="{{ my_default_values|combine(my_values) }}"

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: _my_values

Ответ 5

Попробуйте эту роль из Ansible Galaxy.

Я сделал это некоторое время назад по той же причине. Он может сглаживать словари из нескольких файлов vars и устанавливать пользовательский приоритет слияния.

Эта роль может работать под Ansible 2.0 +

Ответ 6

>>> key = 'default key'
>>> value = 'default value'
>>> my_key = 'my key'
>>> my_value = 'my value'
>>>
>>> my_default_values = {key: value}
>>> print my_default_values
{'default key': 'default value'}
>>>
>>> my_values = {my_key: my_value}
>>> print my_values
{'my key': 'my value'}
>>>
>>> with_dict = my_default_value.copy()
>>> print with_dict
{'default key': 'default value'}
>>> with_dict.update(my_values)
>>> print with_dict
{'default key': 'default value', 'my key': 'my value'}