¿Cómo verificar la respuesta JSON de una solicitud de uri con Ansible?

15

Tengo una tarea Ansible que realiza una solicitud de URI a un sitio web para obtener una respuesta JSON. Quiero que Ansible haga algo si la variable JSON anidada está definida, y otra cosa si no lo está.

- name: Get JSON from the Interwebs
  uri: url="http://whatever.com/jsonresponse" return_content=yes
  register: json_response

- name: Write nested JSON variable to disk
  copy: content={{json_response.json.nested1.nested2}} dest="/tmp/foo.txt"

Tenga en cuenta que el uso ignore_errorssolo funciona para el fallo de comando de la tarea, no para verificar valores indefinidos en estructuras de datos anidados dentro de una plantilla Jinja. Entonces, si json_response.json.nested1.nested2no se define, esta tarea seguirá fallando a pesar de ignore_errors=yesestar configurada.

¿Cómo consigo que este libro de jugadas almacene algún valor predeterminado /tmp/foo.txtsi la solicitud falla o si la solicitud no tiene definido el valor anidado correcto?

Neil
fuente

Respuestas:

20

Debe usar un filtro jinja2 ( http://docs.ansible.com/ansible/playbooks_filters.html ). En este caso, el nombre del filtro es from_json . En el siguiente ejemplo, tomaré una acción cuando se encuentre la clave y otra acción cuando no se pueda encontrar:

 ---                                                                                                            

 - hosts: somehost                                                                                               
   sudo: yes                                                                                                    

   tasks:                                                                                                       

   - name: Get JSON from the Interwebs                                                                          
     uri: url="https://raw.githubusercontent.com/ljharb/node-json-file/master/package.json" return_content=yes  
     register: json_response                                                                                    

   - debug: msg="Error - undefined tag"                                                                         
     when: json_response["non_existent_tag"] is not defined                                                     

   - debug: msg="Success - tag defined =>{{  (json_response.content|from_json)['scripts']['test'] }}<="  
     when:  (json_response.content|from_json)['scripts']['test']  is defined    

Ahora reemplace la depuración por la adecuada para realizar la acción deseada.

Espero eso ayude,

alfredocambera
fuente
3

Tropecé aquí después de buscar una forma de extraer un campo de json de la API de Github. Terminé con la siguiente solución.

uri: url="https://api.github.com/repos/.../.../releases/latest" return_contents=yes

register: github_json

y úsalo en otro lugar como este:

"{{ github_json.json.$key }}"
Samy Coenen
fuente
1
No estoy seguro de que esto realmente ayude al OP: realmente no explica de dónde proviene la clave $, y la pregunta es básicamente qué sucede cuando no hay un $keycampo en la respuesta, es decir, algo para lo que el defaultfiltro de jinja podría ser útil.
iwaseatenbyagrue
1
Esta no fue una respuesta directa al OP ya que la pregunta tiene más de un año y medio, pero esperaba que pudiera ser útil para las personas que querían obtener valores JSON de una API usando solo Ansible, que es cómo me topé con esto página.
Samy Coenen