简体   繁体   中英

Yaml/Jinja2/Ansible Processing dict list with jinja template

How to process dict list like below, any method using jinja or ansible filter or any other way is welcome

From:

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

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

To:

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" }

Below is my best approach, but generated in string, not list of dicts:

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 %} 
  "

An easy solution is to pass the text generated by your template through the from_yaml filter. For example, this playbook:

- 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

Results in this output:

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   

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM