Wie überprüfe ich die JSON-Antwort von einer URI-Anfrage mit Ansible?

15

Ich habe eine Ansible-Task, die eine URI-Anforderung an eine Website sendet, um eine JSON-Antwort zu erhalten. Ich möchte, dass Ansible etwas unternimmt, wenn die verschachtelte JSON-Variable definiert ist, und etwas anderes, wenn dies nicht der Fall ist.

- 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"

Beachten Sie, dass die Verwendung ignore_errorsnur für den fehlgeschlagenen Taskbefehl funktioniert, nicht für die Überprüfung undefinierter Werte in verschachtelten Datenstrukturen in einer Jinja-Vorlage. Wenn dies json_response.json.nested1.nested2nicht definiert ist, schlägt diese Aufgabe trotz ignore_errors=yesder Einstellung weiterhin fehl .

Wie speichere ich in diesem Playbook einen Standardwert, /tmp/foo.txtwenn die Anforderung fehlschlägt oder wenn für die Anforderung nicht der richtige verschachtelte Wert definiert ist?

Neil
quelle

Antworten:

20

Sie müssen einen jinja2-Filter verwenden ( http://docs.ansible.com/ansible/playbooks_filters.html ). In diesem Fall lautet der Name des Filters from_json . Im folgenden Beispiel werde ich eine Aktion ausführen, wenn der Schlüssel gefunden wird, und eine andere Aktion, wenn der Schlüssel nicht gefunden werden konnte:

 ---                                                                                                            

 - 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    

Ersetzen Sie nun das Debug, damit das entsprechende die gewünschte Aktion ausführt.

Ich hoffe es hilft,

Alfredocambera
quelle
3

Ich bin hier gestolpert, nachdem ich nach einer Möglichkeit gesucht hatte, ein Feld aus Json aus der Github-API zu extrahieren. Ich endete mit der folgenden Lösung.

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

register: github_json

und benutze es woanders so:

"{{ github_json.json.$key }}"
Samy Coenen
quelle
1
Ich bin mir nicht sicher, ob dies dem OP tatsächlich hilft: Sie erklären nicht wirklich, woher $ key kommt, und die Frage lautet im Grunde, was passiert, wenn $keydie Antwort kein Feld enthält - dh, der defaultFilter von Jinja könnte nützlich sein.
iwaseatenbyagrue
1
Dies war keine direkte Antwort auf das OP, da die Frage mehr als eineinhalb Jahre alt ist, aber ich hatte gehofft, dass sie für Leute hilfreich sein könnte, die JSON-Werte nur mit Ansible von einer API abrufen wollten, worüber ich gestolpert bin Seite.
Samy Coenen