J'essaie de filtrer une liste en ansible dans Jinja2 lorsque les éléments contiennent une chaîne, mais la documentation de Jinja ne semble pas assez claire pour que je puisse la comprendre.
Voici ce que j'ai jusqu'à présent:
- name: run script
command: /usr/tmp/run_script.py
register: script_results
- name: display run info
debug:
var: "{{script_results.stdout_lines | select(\"'running script' in script_results.stdout_lines\") }}"
Mais tout ce que je reçois est l'erreur:
"<generator object _select_or_reject at 0x13851e0>": "VARIABLE IS NOT DEFINED!"
Ainsi, par exemple, si stdout_lines
contient ["apples","running script one","oranges","running script two"]
, Je veux imprimer
running script one
running script two
Ils ont documentation pour select et documentation pour les tests intégrés , mais ils n'affichent pas le test "in", et je ne sais pas comment ils fonctionnent dans le contexte de cette variable ansible.
J'ai essayé de le résoudre comme ceci:
- name: display run info
debug:
var: item
with_items: "{{script_results.stdout_lines}}"
when: "'running script' in item"
Mais cela affiche "sauter" pour chaque ligne qui ne réussit pas le test ... un peu contre le but!
Le filtre select
prendrait un autre filtre. Comme dans la documentation odd
, qui ne renverra que les éléments impairs de la liste. Le filtre avec lequel vous souhaitez combiner select
est equalto
.
Maintenant, voici la chose. Ansible regroupe une très ancienne version de Jinja2, qui ne contient tout simplement pas le filtre equalto
. Oui, cela le rend inutile, sauf si vous souhaitez filtrer les éléments impairs. (Ce que personne n'a jamais voulu dans l'histoire ...)
De plus, je n'ai pas encore réussi à faire fonctionner les plugins de filtre personnalisés dans Ansible 2. Vous êtes donc à peu près obligé de pirater quelque chose de laid ensemble.
helloV a déjà montré une option. Voici une autre idée:
- name: run script
Shell: /usr/tmp/run_script.py | grep "running script"
register: script_results
Mettre à jour:
J'ai récemment découvert que vous pouvez utiliser match
(pas un filtre Jinja2 standard mais ajouté par Ansible) avec select
. C'est un bon remplacement pour le filtre eualto
et vous pouvez utiliser des expressions régulières. Cela devrait fonctionner:
{{ script_results.stdout_lines | select("match", ".*running script.*") }}
Je comprends qu'il peut y avoir plus d'une façon de procéder. Est-ce que cela fonctionnera pour vous?
- debug: var={{item}}
when: item.find('running script') > -1
with_items: script_results.stdout_lines
J'ai fini par écrire un script python pour le faire, car je n'ai pas pu obtenir ansible ou ancient-jinja2 pour faire la coupe.
Tâches possibles:
- name: gather run info
command: "{{role_path}}/files/print_results.py {{script_results.stdout_lines}}"
register: script_print_results
delegate_to: 127.0.0.1
run_once: true
- name: display run info
debug:
var: script_print_results.stdout_lines
delegate_to: 127.0.0.1
run_once: true
Script Python:
for result_line in sys.argv[1:]:
if "running script:" in result_line:
print result_line[1:-1]
Vous pouvez créer une nouvelle liste avec set_fact
et imprimer les éléments d'une nouvelle liste.
- hosts: localhost
gather_facts: false
vars:
script_stdout_lines:
- apples
- running script one
- oranges
- running script two
tasks:
- set_fact:
new_list: "{{ new_list | default([]) + [item] }}"
with_items: "{{ script_stdout_lines }}"
when: '"running script" in item'
- debug: var=new_list
Résultat:
TASK [set_fact] *********************************************************************************************************************
skipping: [localhost] => (item=apples)
ok: [localhost] => (item=running script one)
skipping: [localhost] => (item=oranges)
ok: [localhost] => (item=running script two)
TASK [debug] ************************************************************************************************************************
ok: [localhost] => {
"new_list": [
"running script one",
"running script two"
]
}
Il imprime skipping
pendant set_fact
opération mais à la fin il fournit une nouvelle liste avec les seuls éléments correspondants.