Почему Ansible преобразовывает списки в строки? - PullRequest
0 голосов
/ 05 сентября 2018

Ansible неожиданно преобразует списки в строки при объединении списков, может кто-нибудь помочь мне объяснить, почему?

Книга пьес:

---
- hosts: localhost
  vars:
    list1:
      - aaa: 'aaa'
  tasks:
    - set_fact:
        a: 'asdfg'
    - set_fact:
        list2: "{{ list1|d([]) + [ hostvars['localhost']['a']] }}"
    - debug: var=list2
    - set_fact:
        list3: "{{ list1|d([]) + [ hostvars['localhost']['undefined variable']] }}"
    - debug: var=list3

и это результат воспроизведения (лишние части пропущены):

TASK [debug] *************************************************************************************************************************************************************************************************************************************************
Wednesday 05 September 2018  09:52:31 +0200 (0:00:00.071)       0:00:00.203 ***
ok: [localhost] => {
    "list2": [
        {
            "aaa": "aaa"
        },
        "asdfg"
    ]
}

...

TASK [debug] *************************************************************************************************************************************************************************************************************************************************
Wednesday 05 September 2018  09:52:31 +0200 (0:00:00.085)       0:00:00.345 ***
ok: [localhost] => {
    "list3": "[{'aaa': 'aaa'}, Undefined]"
}

PLAY RECAP ***************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=5    changed=0    unreachable=0    failed=0

Вторая задача отладки выводит строку вместо ожидаемого dict. Это правильное поведение, я просто не понимаю, или я должен сообщить об ошибке?

1 Ответ

0 голосов
/ 05 сентября 2018

Этот ответ описывает состояние вещей в Ansible до 2.6.x. Существует движение для поддержки нативных объектов Python в Ansible v2.7.


Почему Ansible преобразовывает списки в строки?

Ansible - это , а не , преобразующий любой список в строку в вашем примере.


Ansible получает данные:

  1. из парсера YAML

    Это могут быть: список, словарь, скаляр (строковое, логическое или числовое значение).

  2. из других источников (например: Jinja2, инвентарь, CLI extravars)

    Любые данные, поступающие из других источников, строка .


Поскольку Jinja2 всегда возвращает строку, вы можете вычислить результат в своей голове и передать значение в виде скаляра YAML в кавычках (интерпретируется Ansible как строка):

  • Первое задание выше эквивалентно:

    - set_fact:
        list2: "[{'aaa': 'aaa'}, 'asdfg']"
    

    Ansible получает строку (не список) и пытается ее интерпретировать. Он находит строку JSON, соответствующую списку, и создает объект списка.

  • Второе задание эквивалентно:

    - set_fact:
        list3: "[{'aaa': 'aaa'}, Undefined]"
    

    Здесь вы видите, как Jinja2 заменяет список элементом с неопределенным значением на строку Undefined (без указания этой строки).

    Ansible получает строку и пытается ее интерпретировать. Он не находит правильную структуру данных * и создает строковый объект.


* Существует особый случай, если существует переменная с именем Undefined, тогда Ansible заменит Undefined без кавычек этим значением переменной и создаст объект списка.

...