Внутренний цикл в цикле над dict в Ansible

#ansible

#ansible

Вопрос:

Как выполнить цикл над dict в этом примере? Я могу перебирать список строк (lorem:), но я не могу перебирать объекты: dict .

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

Я не уверен, что я делаю неправильно. Кто-нибудь может показать мне правильный пример?

Спасибо

 ---
- name: test
  hosts: localhost
  connection: local

  vars:
    persons:
      foo:
        name: john
        state: us
        objects:
          phone: samsung
          color: black
          capacity: 32
        lorem:
          - 1
          - 2
          - 3
      bar:
        name: helmut
        state: de
        objects:
          phone: lg
          color: red
          capacity: 16
        lorem:
          - 4
          - 5
          - 6

  tasks:

    - name: List of strings is OK
      debug:
        msg: "{{ item.0.value.name }} and object: {{ item.1 }}"
      loop: "{{ persons | dict2items |subelements('value.lorem',{ 'skip_missing': True }) }}"

    - name: Dict referencing key:value is not OK
      debug:
        msg: "Name: {{ item.0.value.name }} and object: {{ item.1.[value] }} with key name: {{ item.1.[key]}}"
      loop: "{{ persons | dict2items |subelements('value.objects',{ 'skip_missing': True }) }}"
  

Выдает ошибку: fatal: [localhost]: FAILED! => {"msg": "the key 'objects' should point to a list, got {u'color': u'black', u'phone': u'samsung', u'capacity': 32}"}

Комментарии:

1. I am using module which needs as input list and dict — Пожалуйста, уточните. Возможно, будет легче понять, что вам нужно, с большим контекстом.

Ответ №1:

Лучшее, что я могу придумать, это сделать что-то подобное. Использование jinja для создания списка, который возвращает то, что вам нужно.

 ---
- name: test
  hosts: localhost
  connection: local

  vars:
    persons:
      foo:
        name: john
        state: us
        objects:
          phone: samsung
          color: black
          capacity: 32
        lorem:
          - 1
          - 2
          - 3
      bar:
        name: helmut
        state: de
        objects:
          phone: lg
          color: red
          capacity: 16
        lorem:
          - 4
          - 5
          - 6

  tasks:

  - debug:
      msg: |
        [
        {% for p in persons %}
        {% for o in persons[p].objects %}
        {
        "name": "{{ persons[p].name }}",
        "key": "{{ o }}",
        "value": "{{ persons[p].objects[o] }}"
        },
        {% endfor %}
        {% endfor %}
        ]
  

Вывод

 TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": [
        {
            "key": "color", 
            "name": "john", 
            "value": "black"
        }, 
        {
            "key": "phone", 
            "name": "john", 
            "value": "samsung"
        }, 
        {
            "key": "capacity", 
            "name": "john", 
            "value": "32"
        }, 
        {
            "key": "color", 
            "name": "helmut", 
            "value": "red"
        }, 
        {
            "key": "phone", 
            "name": "helmut", 
            "value": "lg"
        }, 
        {
            "key": "capacity", 
            "name": "helmut", 
            "value": "16"
        }
    ]
}
  

О, и если вы хотите использовать это в цикле, просто что-то вроде этого.

   - debug:
      msg: "{{ item.name }} {{ item.key }} {{ item.value }}"
    loop_control:
      label: "{{ item.name }} {{ item.key }} {{ item.value }}"
    loop: |
      [
      {% for p in persons %}
      {% for o in persons[p].objects %}
      {
      "name": "{{ persons[p].name }}",
      "key": "{{ o }}",
      "value": "{{ persons[p].objects[o] }}"
      },
      {% endfor %}
      {% endfor %}
      ]
  

Вывод

 TASK [debug] *******************************************************************
ok: [localhost] => (item=john color black) => {
    "msg": "john color black"
}
ok: [localhost] => (item=john phone samsung) => {
    "msg": "john phone samsung"
}
ok: [localhost] => (item=john capacity 32) => {
    "msg": "john capacity 32"
}
ok: [localhost] => (item=helmut color red) => {
    "msg": "helmut color red"
}
ok: [localhost] => (item=helmut phone lg) => {
    "msg": "helmut phone lg"
}
ok: [localhost] => (item=helmut capacity 16) => {
    "msg": "helmut capacity 16"
}
  

Ответ №2:

Вы также можете использовать with_items .

Пожалуйста, обратитесь к приведенному ниже коду:

сборник пьес —>

  ---
 - name: test   hosts: localhost   gather_facts: no   tasks:
     - include_vars: vars.yml
     - name: debug
       debug:
         msg: "{{ item.vars.persons }}"
       with_items:
         - "{{ vars }}"
  

вывод —>

     "msg": {
        "bar": {
            "lorem": [
                4,
                5,
                6
            ],
            "name": "helmut",
            "objects": {
                "capacity": 16,
                "color": "red",
                "phone": "lg"
            },
            "state": "de"
        },
        "foo": {
            "lorem": [
                1,
                2,
                3
            ],
            "name": "john",
            "objects": {
                "capacity": 32,
                "color": "black",
                "phone": "samsung"
            },
            "state": "us"
        }
    }
}