Jinja2, Ansible, как создать вложенный для l oop оператор if и обновить список во время итерации? - PullRequest
0 голосов
/ 17 января 2020

Я пытаюсь l oop просмотреть список словарей и проверить, существует ли более одного источника для одной и той же группы в структуре такого типа:

[{"Device": "CM1LS-05B","Group": "239.216.12.8/32","Source": "10.144.12.8/32"},
 {"Device": "CM1LS-01A","Group": "239.192.9.100/32","Source": "10.144.69.7/32"}]

Так что в основном мне нужно взять каждый dict в списке и сравните его со всеми остальными в списке, для каждого сравнения, если совпадают dict.groups, затем проверьте, совпадают ли dict.sources, совпадают ли они dict.groups и не совпадают ли dict.sources мне нужно добавить оба слова в final_list

вот что у меня есть:

- name: Look for Multicast Groups with More than One Source
  hosts: localhost
  connection: local
  gather_facts: false
  vars:
    final_list: []
    my_list: [
        {
            "Device": "CM1LS-05B",
            "Group": "239.216.12.8/32",
            "Source": "10.144.12.8/32"
        },
        {
            "Device": "CM1LS-01A",
            "Group": "239.192.9.100/32",
            "Source": "10.144.69.7/32"
        },
        {
            "Device": "CM1LS-05B",
            "Group": "239.216.48.229/32",
            "Source": "10.144.48.15/32"
        },
        {
            "Device": "CM1LS-05B",
            "Group": "239.216.48.40/32",
            "Source": "10.144.65.161/32"
        },
        {
            "Device": "CM1LS-01A",
            "Group": "239.208.0.202/32",
            "Source": "172.23.59.16/32"
        },
        {
            "Device": "CM1LS-05B",
            "Group": "239.216.48.229/32",
            "Source": "10.144.48.229/32"
        },
        {
            "Device": "CM1LS-01A",
            "Group": "239.208.0.203/32",
            "Source": "172.23.59.16/32"
        }
    ]

  tasks:
    - read_csv:
        path: results.csv
      register: lines

    - set_fact:
        final_list:
           "{% for i in my_list %}
               {% for j in my_list %}
                  {% if i[ 'Group' ] == j[ 'Group' ] %}
                     {{ final_list + [ i['Group']] }}
                  {% endif %}
               {% endfor %}
            {% endfor %}"
    - debug: var=final_list

вывод:

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "final_list": "   [u'239.216.12.8/32']                    [u'239.192.9.100/32']                    [u'239.216.48.229/32']        [u'239.216.48.229/32']              [u'239.216.48.40/32']                    [u'239.208.0.202/32']              [u'239.216.48.229/32']        [u'239.216.48.229/32']                    [u'239.208.0.203/32']   "
}

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

Я думаю, что у меня что-то не так в jinja2 forl oop если сравнение заявления

есть идеи?

Ответы [ 2 ]

0 голосов
/ 18 января 2020

Вот что у меня сработало:

- set_fact:
        final_list: >-
          {%- for i in my_list -%}
            {%- for j in my_list -%}
              {%- if (i['Group'] == j['Group']) and (i['Source'] != j['Source']) -%}
                {{ my_result + [i,j] }}
              {%- endif -%}
            {%- endfor -%}
          {%- endfor -%}
  debug: var= finale_list

, но я не получил массив. Вместо этого я получил строку Unicode:

TASK [debug] **************************************************************************************************************************************************
ok: [localhost] => {
    "final_list": "[{u'Device': u'CM1LS-05B', u'Source': u'10.144.48.15/32', u'Group': u'239.216.48.229/32'}, {u'Device': u'CM1LS-20A', u'Source': u'10.144.48.229/32', u'Group': u'239.216.48.229/32'}][{u'Device': u'CM1LS-20A', u'Source': u'10.144.48.229/32', u'Group': u'239.216.48.229/32'}, {u'Device': u'CM1LS-05B', u'Source': u'10.144.48.15/32', u'Group': u'239.216.48.229/32'}]"
}

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

желаемый результат должен выглядеть следующим образом:

TASK [debug] **************************************************************************************************************************************************
ok: [localhost] => {
    "final_list": [
        {
            "Device": "CM1LS-05B",
            "Group": "239.216.48.229/32",
            "Source": "10.144.48.15/32"
        },
        {
            "Device": "CM1LS-20A",
            "Group": "239.216.48.229/32",
            "Source": "10.144.48.229/32"
        }
    ]
}

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

0 голосов
/ 17 января 2020

Вы были почти там! Между тем, обратите внимание, что это очень многословное шаблонное выражение. Возможно, будет проще разработать собственный фильтр, в котором вы сможете управлять своими данными непосредственно в python.

Но здесь мы go. Это возможное «ansible only» решение, только исправляющее вашу актуальную задачу. Я использовал скалярный блок yaml, чтобы мы могли отбрасывать внешние кавычки и писать в несколько строк, сбрасывая новые строки в конце. Я также ввел маркеры управления пробелами в шаблоне jinja2, чтобы убедиться, что мы не получаем в выводе лишних символов, которые могли бы раздувать созданный разбор переменных. Наконец, вы не можете объединить var напрямую, как вы пытались. Вам нужно вычислить результат и вывести его так, чтобы он был присвоен переменной.

    - set_fact:
        final_list: >-
          {%- set my_result = [] -%}
          {%- for i in my_list -%}
            {%- for j in my_list -%}
              {%- if i['Group'] == j['Group'] -%}
                {{ my_result.append(i['Group']) }}
              {%- endif -%}
            {%- endfor -%}
          {%- endfor -%}
          {{ my_result }}
...