如何将字符串列表转换为字典列表?

时间:2021-07-02 19:18:22

标签: ansible jinja2

我有一个看起来像这样的字符串列表:

"forwarded_ports": [
    "123",
    "234",
    "456"
]

我想将此列表的值用作字典列表中的值,如下所示:

"mapped_ports": [
    {
        "external_port": "123",
        "internal_port": "123"
    },
    {
        "external_port": "234",
        "internal_port": "234"
    },
    {
        "external_port": "456",
        "internal_port": "456"
    }
]

有没有办法使用内联 Ansible/Jinja 过滤器来做到这一点?我知道我可以使用这样的 Ansible 循环轻松完成此操作:

- set_fact:
    mapped_ports: "{{ mapped_ports| default([]) + [{ 'internal_port' : item , 'external_port' : item }] }}"
  loop: "{{ forwarded_ports }}"

但理想情况下,此数据结构将在仅包含过滤器等的默认文件中即时创建。似乎有一种简单的方法可以使用 mapdict 过滤器来实现,但我可以好像没搞清楚感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

简而言之(但我并不真正推荐它,因为它使用 var 作为完整的 jinja2 模板,我会坚持使用您的实际 set_fact,这对于大多数用户来说可能更清晰......) :

---
- hosts: localhost
  gather_facts: false

  vars:
    forwarded_ports:
      - 123
      - 234
      - 456

    mapped_ports: >-
      {%- set mapped=[] -%}
      {%- for port in forwarded_ports -%}
        {{ mapped.append({'external_port': port, 'internal_port': port}) }}
      {%- endfor -%}
      {{ mapped }}

  tasks:
    - debug:
        var: mapped_ports

给出:

$ ansible-playbook my_playbook.yml

PLAY [localhost] **************************************************************************************************************************************************************************************************************

TASK [debug] ******************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "mapped_ports": [
        {
            "external_port": 123,
            "internal_port": 123
        },
        {
            "external_port": 234,
            "internal_port": 234
        },
        {
            "external_port": 456,
            "internal_port": 456
        }
    ]
}

PLAY RECAP ********************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

答案 1 :(得分:2)

通常,我不推荐 json_query,但在这种情况下,它非常适合您尝试执行的操作,因为它能够通过投影构建新节点:

- debug:
    msg: >-
      {{ forwarded_ports | json_query("[*].{external_port: @, internal_port: @}") }}
  vars:
    "forwarded_ports": [
      "123",
      "234",
      "456"
    ]

收益

ok: [localhost] => {
    "msg": [
        {
            "external_port": "123",
            "internal_port": "123"
        },
        {
            "external_port": "234",
            "internal_port": "234"
        },
        {
            "external_port": "456",
            "internal_port": "456"
        }
    ]
}