Подтвердить что ты не робот

Ansible: фильтровать список по его атрибутам

У меня есть переменная с именем "network", зарегистрированная в Ansible:

{
    "addresses": {
        "private_ext": [
            {
                "type": "fixed",
                "addr": "172.16.2.100"
            }
        ],
        "private_man": [
            {
                "type": "fixed",
                "addr": "172.16.1.100"
            },
            {
                "type": "floating",
                "addr": "10.90.80.10"
            }
        ]
    }
}

Можно ли получить IP-адрес ( "addr" ) с типом = "плавающий", выполнив что-то вроде этого?

- debug: var={{ network.addresses.private_man | filter type="fixed" | get "addr" }}

Я знаю, что синтаксис неправильный, но вы получаете идею.

4b9b3361

Ответ 2

Чтобы отфильтровать список диктовок, вы можете использовать фильтр selectattr вместе с тестом equalto:

network.addresses.private_man | selectattr("type", "equalto", "fixed")

Выше требуется Jinja2 v2.8 или новее (независимо от версии Ansible).


Ansible также имеет тесты match и search, которые принимают регулярные выражения:

match потребуется полное совпадение в строке, тогда как для search потребуется совпадение внутри строки.

network.addresses.private_man | selectattr("type", "match", "^fixed$")

Чтобы свести список dicts к списку строк, чтобы вы получили только список полей addr, вы можете использовать фильтр карты:

... | map(attribute='addr') | list

Или, если вы хотите строку через запятую:

... | map(attribute='addr') | join(',')

В совокупности это будет выглядеть так.

- debug: msg={{ network.addresses.private_man | selectattr("type", "equalto", "fixed") | map(attribute='addr') | join(',') }}

Ответ 3

Не обязательно лучше, но поскольку здесь хорошо иметь параметры, как это сделать, используя Jinja statements:

- debug:
    msg: "{% for address in network.addresses.private_man %}\
        {% if address.type == 'fixed' %}\
          {{ address.addr }}\
        {% endif %}\
      {% endfor %}"

Или, если вы хотите разместить все в одной строке:

- debug:
    msg: "{% for address in network.addresses.private_man if address.type == 'fixed' %}{{ address.addr }}{% endfor %}"

Что возвращает:

ok: [localhost] => {
    "msg": "172.16.1.100"
}

Ответ 4

ищите помощи здесь, как бы выглядел фильтр jinja2, если бы я хотел сравнить 2 атрибута списка? пример: я хочу отфильтровать только записи, где host = dnsname

список_серверов: - {хост: сервер1, dnsname: server1.acme.com} - {хост: сервер2, dnsname: server2.acme.com} - {хост: сервер2, dnsname: сервер3}

Ответ 5

Как бы я передать переменную для фильтра?

отладка: msg = {{network.addresses.private_man | selectattr("type", "equalto", {{ x }}) }} selectattr ("type", "equalto", {{x}})}}

не работает