我在Ansible中注册了名为“network”的变量:
{
"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" }}
我知道语法错误,但你明白了。
答案 0 :(得分:94)
要过滤词典列表,您可以将selectattr filter与equalto test一起使用:
network.addresses.private_man | selectattr("type", "equalto", "fixed")
以上需要Jinja2 v2.8或更高版本(无论Ansible版本如何)。
Ansible has the tests match
and search
,它采用正则表达式:
match
将需要字符串中的完全匹配,而search
将需要字符串内的匹配。
network.addresses.private_man | selectattr("type", "match", "^fixed$")
要将字典列表缩减为字符串列表,以便只获取addr
字段列表,可以使用map filter:
... | map(attribute='addr') | list
或者如果你想要一个逗号分隔的字符串:
... | map(attribute='addr') | join(',')
结合起来,它看起来像这样。
- debug: msg={{ network.addresses.private_man | selectattr("type", "equalto", "fixed") | map(attribute='addr') | join(',') }}
答案 1 :(得分:28)
我已经提交了pull request(Ansible 2.2+中提供),可以通过在Ansible上添加jmespath查询支持来简化这种情况。在你的情况下,它将像:
- debug: msg="{{ addresses | json_query(\"private_man[?type=='fixed'].addr\") }}"
将返回:
ok: [localhost] => {
"msg": [
"172.16.1.100"
]
}
答案 2 :(得分:14)
不一定更好,但是因为在Jinja statements使用this UserVoice item如何选择它是很好的选择:
- 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"
}