when - ansible jinja2 template example
Ansible: filtra una lista por sus atributos (3)
He enviado una solicitud de extracción (disponible en Ansible 2.2+) que facilitará este tipo de situaciones al agregar jmespath consulta jmespath en Ansible. En su caso funcionaría así:
- debug: msg="{{ addresses | json_query(/"private_man[?type==''fixed''].addr/") }}"
volvería:
ok: [localhost] => {
"msg": [
"172.16.1.100"
]
}
Tengo una variable llamada "red" registrada en 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"
}
]
}
}
¿Es posible obtener la dirección IP ("addr") con type = "floating" haciendo algo como esto?
- debug: var={{ network.addresses.private_man | filter type="fixed" | get "addr" }}
Sé que la sintaxis está mal, pero se entiende la idea.
No necesariamente mejor, pero dado que es bueno tener opciones, aquí está cómo hacerlo usando las declaraciones de Jinja :
- debug:
msg: "{% for address in network.addresses.private_man %}/
{% if address.type == ''fixed'' %}/
{{ address.addr }}/
{% endif %}/
{% endfor %}"
O si prefiere poner todo en una línea:
- debug:
msg: "{% for address in network.addresses.private_man if address.type == ''fixed'' %}{{ address.addr }}{% endfor %}"
Que devuelve:
ok: [localhost] => {
"msg": "172.16.1.100"
}
Para filtrar una lista de dictados, puede usar el filtro selectattr junto con la prueba equalto :
network.addresses.private_man | selectattr("type", "equalto", "fixed")
Lo anterior requiere Jinja2 v2.8 o posterior (independientemente de la versión Ansible).
Ansible también
tiene las pruebas de
match
y
search
, que toman expresiones regulares:
match
requerirá una coincidencia completa en la cadena, mientras que lasearch
requerirá una coincidencia dentro de la cadena.
network.addresses.private_man | selectattr("type", "match", "^fixed$")
Para reducir la lista de dictados a una lista de cadenas, para que solo obtenga una lista de los campos
addr
, puede usar el
filtro de mapa
:
... | map(attribute=''addr'') | list
O si quieres una cadena separada por comas:
... | map(attribute=''addr'') | join('','')
Combinado, se vería así.
- debug: msg={{ network.addresses.private_man | selectattr("type", "equalto", "fixed") | map(attribute=''addr'') | join('','') }}