为什么Ansible将列表转换为字符串?

问题描述 投票:0回答:1

在合并列表时,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。这是一个我不理解的正确行为还是应该提交错误?

ansible jinja2
1个回答
2
投票

这个答案描述了Ansible中的事物状态,最高可达2.6.x.在Ansible v2.7中有一个movement支持native Python objects


为什么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并创建一个列表对象。

© www.soinside.com 2019 - 2024. All rights reserved.