J'ai une variable nommée "réseau" enregistrée dans 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"
}
]
}
}
Est-il possible d'obtenir l'adresse IP ("addr") avec type = "floating" faisant quelque chose comme ceci?
- debug: var={{ network.addresses.private_man | filter type="fixed" | get "addr" }}
Je sais que la syntaxe est fausse mais vous voyez l'idée.
J'ai envoyé un demande d'extraction (disponible dans Ansible 2.2+) qui facilitera ce genre de situation en ajoutant jmespath support de requête sur Ansible. Dans votre cas, cela fonctionnerait comme:
- debug: msg="{{ addresses | json_query(\"private_man[?type=='fixed'].addr\") }}"
retournerais:
ok: [localhost] => {
"msg": [
"172.16.1.100"
]
}
Pour filtrer une liste de dict, vous pouvez utiliser le filtre selectattr avec le equalto test :
network.addresses.private_man | selectattr("type", "equalto", "fixed")
Ce qui précède nécessite Jinja2 v2.8 ou version ultérieure (quelle que soit la version de Ansible).
Ansible aussi a les tests match
et search
, qui prennent des expressions régulières:
match
nécessitera une correspondance complète dans la chaîne, tandis quesearch
nécessitera une correspondance à l'intérieur de la chaîne.
network.addresses.private_man | selectattr("type", "match", "^fixed$")
Pour réduire la liste des dessins à une liste de chaînes, afin que vous n'obteniez qu'une liste des champs addr
, vous pouvez utiliser le filtre de carte :
... | map(attribute='addr') | list
Ou si vous voulez une chaîne séparée par des virgules:
... | map(attribute='addr') | join(',')
Combiné, cela ressemblerait à ceci.
- debug: msg={{ network.addresses.private_man | selectattr("type", "equalto", "fixed") | map(attribute='addr') | join(',') }}
Pas nécessairement mieux, mais comme il est agréable d'avoir des options, voici comment le faire en utilisant déclarations Jinja :
- debug:
msg: "{% for address in network.addresses.private_man %}\
{% if address.type == 'fixed' %}\
{{ address.addr }}\
{% endif %}\
{% endfor %}"
Ou si vous préférez mettre tout cela sur une seule ligne:
- debug:
msg: "{% for address in network.addresses.private_man if address.type == 'fixed' %}{{ address.addr }}{% endfor %}"
Qui retourne:
ok: [localhost] => {
"msg": "172.16.1.100"
}