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" }}
Я знаю, что синтаксис неправильный, но вы поняли идею.
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