Aller au contenu

Parser les commandes shell Ansible avec JC

logo ansible

Il faut aussi désormais surveiller le travail de la communauté Ansible, sinon on passe à côté de pépites qui vous simplifie le travail.

Il existe bien des cas où le module ansible n’existe pas et qui nous oblige à utiliser le module shell. Mais quelle prise de tête que de parser le retour, si la sortie au format json n’existe pas. JC va vous sauver.

Jc est outil écrit en python qui se charge de parser le retour d’une trentaine de commandes shell dont arp, crontab, dif, date, df, systemctl, … mais aussi de parser des fichiers csv, xml, ini, yaml

Installation de JC

Dans l’environnement virtuel où vous avez installé ansible il suffit de :

Terminal window
pip install jc

Utilisation de jc en ligne de commande

Pour tester jc il suffit de lancer une simple commande et de la piper avec jc suivi du parser + un petit jq pour formater le json.

Exemple ping :

Terminal window
ping -c 1 localhost | jc --ping | jq
{
"destination_ip": "127.0.0.1",
"data_bytes": 56,
"pattern": null,
"destination": "localhost",
"packets_transmitted": 1,
"packets_received": 1,
"packet_loss_percent": 0,
"duplicates": 0,
"time_ms": 0,
"round_trip_ms_min": 0.049,
"round_trip_ms_avg": 0.049,
"round_trip_ms_max": 0.049,
"round_trip_ms_stddev": 0,
"responses": [
{
"type": "reply",
"timestamp": null,
"bytes": 64,
"response_ip": "127.0.0.1",
"icmp_seq": 1,
"ttl": 64,
"time_ms": 0.049,
"duplicate": false
}
]
}

Pour afficher la liste des parsers disponibles un simple jc -h.

Utiliser JC avec Ansible

Dans la collection de la communauté Ansible, il existe toute une série de filtres qui viennent compléter ceux qui sont disponibles par défaut avec Ansible. Dont notre jc

Voici un exemple de playbook :

---
- hosts: localhost
connection: local
gather_facts: no
become: true
vars:
ansible_python_interpreter: /usr/bin/python3
tasks:
- name: dig command
shell: dig example.com
register: result
- name: format output
ansible.builtin.set_fact:
ip: "{{ result.stdout | community.general.jc('dig') }}"
- name : display ip
ansible.builtin.debug:
msg: "{{ ip[0].answer[0].data }}"

Vous remarquez l’utilisation du filtre jc dans le set_fact : ip: "{{ result.stdout | community.general.jc('dig') }}" ? Cool. Voyons la sortie du playbook :

ansible-playbook -i localhost, test.yml
PLAY [localhost] ***************************************************************************************************************************************************************************
TASK [dig command] *************************************************************************************************************************************************************************
changed: [localhost]
TASK [format output] ***********************************************************************************************************************************************************************
ok: [localhost]
TASK [display ip] **************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "93.184.216.34"
}
PLAY RECAP *********************************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

On a récupéré tout simplement l’ip du domaine example.com. Finis les awks, cut, pipe …

Merci JC !

Source : JC