Aller au contenu principal

Parser les commandes shell Ansible avec JC

· 3 minutes de lecture
Stéphane ROBERT
Consultant DevOps

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 :

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 :

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