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



у меня есть переменная с именем "сеть", зарегистрированная в 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" }}


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

1040   3  

3 ответов:

Я представила pull-запрос (доступно в Ansible 2.2+), что облегчит такие ситуации, добавив jmespath поддержка запросов на Ansible. В вашем случае это будет работать так:

- debug: msg="{{ addresses | json_query(\"private_man[?type=='fixed'].addr\") }}"

вернутся:

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

для фильтрации списка диктов вы можете использовать selectattr filter вместе с equalto test:

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$")

чтобы уменьшить список диктов к списку строк, так что вы получите только список addr поля, вы можете использовать фильтра карте:

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

или если вы хотите строку, разделенную запятыми:

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

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

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

не обязательно лучше, но так как это приятно иметь варианты вот как это сделать с помощью заявления Джимма:

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

Comments

    Ничего не найдено.