Loading search data...

Soutenez moi :) En achetant sur amazon via l'image ci-contre, je recevrai une toute petite commission.

Filtrer et rechercher des données au format Json

Json est le format de données utiliser par les Api Rest. Nous allons voir comment utiliser le filtre json_query pour rechercher des éléments dans une variable JSON. json_query utilise jmespath, un langage de requête pour analyser des contenu au format JSON.

Par exemple si vous utilisez Ansible pour manager des clusters kubernetes vous serez obligé de parser des données au format JSON.

Transformer des variables au format json

Avant de voir comment récupérer des données d’une API. Voyons comment transformer une variable en json. Vous avez deux filtres votre disposition to_json et to_nice_json.

---
- hosts: localhost
  vars:
    apps:
      - name: app1
        jvm: &jvm_opts
          opts: '-Xms1G -Xmx2G'
          port: 1000
          path: /usr/lib/app1
      - name: app2
        jvm:
          <<: *jvm_opts
          path: /usr/lib/app2

  tasks:
    - name: to_json
      debug:
        msg: "{{ apps | to_json }}"

    - name: to_nice_json
      debug:
        msg: "{{ apps | to_nice_json(indent=2) }}"

Ici une astuce permettant à app1 et app2 de partager les mêmes valeurs pour opts et port. On utilise l’ancre &jvm_opts et l’alias *jvm_opts. La valeur du chemin est fusionnée par <<.

Exemples de données au format JSON

Nous allons utiliser comme exemple les données du site jsonplaceholder. Nous prendrons les données du schéma users:

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
  ...
]

Pour récupérer les données nous allons utiliser le bon vieux module uri

---
 - name: Parse json
   hosts: localhost
   gather_facts: no
   tasks:
     - name: Obtention des users
       uri:
         url: https://jsonplaceholder.typicode.com/users
         return_content: yes
       register: jsondata
     - name: Business Card
       debug:
          msg: "{{ jsondata.json }}"

Extraire un champ particulier d’un json

Nous aimerions par exemple obtenir la liste de tous users de la liste. Pour cela nous allons utiliser une requete jmespath. Il faut dans un premier temps installer le module pip correspondant :

pip install jmespath --user

Maintenant transformons notre playbook en intégrant un vars à notre debug:

---
- name: Parse json
  hosts: localhost
  gather_facts: no
  tasks:
    - name: Obtention des users
      uri:
        url: https://jsonplaceholder.typicode.com/users
        return_content: yes
      register: jsondata
    - name: Business Card
      vars:
        jmesquery: "[*].{Name: name}"
      debug:
        msg: "{{ jsondata.json  | json_query(jmesquery) }}"

Retrouver une donnée particulière

Cette fois nous aimerions retrouver un user en particulier, par exemple celui avec l’id 1. Faites bien attention au format des quotes `

---
- name: Parse json
  hosts: localhost
  gather_facts: no
  tasks:
    - name: Obtention des users
      uri:
        url: https://jsonplaceholder.typicode.com/users
        return_content: yes
      register: jsondata
    - name: Business Card
      vars:
        jmesquery: "[? id==`1`]"
      debug:
        msg: "{{ jsondata.json  | json_query(jmesquery) }}"

Il est possible d’ajouter des ou et et pour sélectionner d’autres users. Ici nous allons demander à afficher seulement le nom de leur company:

    - name: Business Card
      vars:
        jmesquery: "[? id==`1` ||  id==`5`].{Company: company.name}"
      debug:
        msg: "{{ jsondata.json  | json_query(jmesquery) }}"

Utiliser combine pour créer ses propres données extraites du json

Plus tot nous avions vu l’utilisation de combine permettant de combiner des données. Nous allons ici extraire le nom et l’associer à son email :

    - name: user - Email
      set_fact:
        my_data: "{{my_data|default({}) | combine ( {item.name : item.email}) }}"
      with_items: "{{ jsondata.json | json_query('[? id==`1` || id==`5`]')}}"
    - name: debug
      debug:
        msg: "{{my_data}}"

Si vous voulez plus de tutorials Ansible je vous renvoie sur le billet de l'introduction à ansible

Mots clés :

devops, ansible, tutorials,

Autres Articles


Alimenter un blog comme celui-ci est aussi passionnant que chronophage. En passant votre prochaine commande (n'importe quel autre article) au travers du lien produit ci-contre, je touche une petite commission sans que cela ne vous coûte plus cher. Cela ne me permet pas de gagner ma vie, mais de couvrir les frais inhérents au fonctionnement du site. Merci donc à vous!