Yaml/Jinja2/Ansible 使用 jinja 模板处理字典列表

Yaml/Jinja2/Ansible Processing dict list with jinja template

如何像下面那样处理字典列表,欢迎使用任何使用 jinja 或 ansible 过滤器或任何其他方式的方法

发件人:

test_dict:
  USA:
    New York:
      - Alice
      - Bob
    Dallas:
      - James
      - Kim

  UK:
    London:
      - Johnson
      - Charles
    Leeds:
      - Clark
      - Geoge

收件人:

test_dict_processed:
  - {'country': "USA", 'city': "New York", 'name': "Johnson" }
  - {'country': "USA", 'city': "New York", 'name': "Alice" }
  - {'country': "USA", 'city': "New York", 'name': "Bob" }
  - {'country': "USA", 'city': "Dallas", 'name': "James" }
  ...
  - {'country': "UK", 'city': "London", 'name': "Charles" }

下面是我的最佳方法,但生成的是字符串,而不是字典列表:

test_dict_processed:
  "
    {% set name_list_ = [] %}
    {% for country in names.keys() %}
      {% for city in names[country].keys() %}
        {% for name in names[country][city] %}
          - {'country': country, 'city': city, 'name': name } \n
        {% endfor %}
      {% endfor %}
    {% endfor %} 
  "

一个简单的解决方案是将模板生成的文本通过 from_yaml 过滤器。例如,这个剧本:

- hosts: localhost
  gather_facts: false
  vars:
    test_dict:
      USA:
        New York:
          - Alice
          - Bob
        Dallas:
          - James
          - Kim

      UK:
        London:
          - Johnson
          - Charles
        Leeds:
          - Clark
          - Geoge
  tasks:
    - set_fact:
        test_dict_processed_text: |
          {% for country in test_dict.keys() %}
          {% for city in test_dict[country].keys() %}
          {% for name in test_dict[country][city] %}
          - country: {{country}}
            city: {{city}}
            name: {{name}}
          {% endfor %}
          {% endfor %}
          {% endfor %}

    - set_fact:
        test_dict_processed: "{{ test_dict_processed_text|from_yaml }}"

    - debug:
        var: test_dict_processed|from_yaml

此输出结果:

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

TASK [set_fact] ******************************************************************************
ok: [localhost]

TASK [set_fact] ******************************************************************************
ok: [localhost]

TASK [debug] *********************************************************************************
ok: [localhost] => {
    "test_dict_processed": [
        {
            "city": "New York",
            "country": "USA",
            "name": "Alice"
        },
        {
            "city": "New York",
            "country": "USA",
            "name": "Bob"
        },
        {
            "city": "Dallas",
            "country": "USA",
            "name": "James"
        },
        {
            "city": "Dallas",
            "country": "USA",
            "name": "Kim"
        },
        {
            "city": "London",
            "country": "UK",
            "name": "Johnson"
        },
        {
            "city": "London",
            "country": "UK",
            "name": "Charles"
        },
        {
            "city": "Leeds",
            "country": "UK",
            "name": "Clark"
        },
        {
            "city": "Leeds",
            "country": "UK",
            "name": "Geoge"
        }
    ]
}

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