John
John

Reputation: 11

Parsing json output retrieved from an API using Ansbile

I am new to Ansible. I am trying to fetch some API info from a centralized server in the json format, parse the json and set "certificate" to "yes" for each and every server and make a PUT operation back. GET and PUT operations in my code are working fine.

I am not able to find correct syntax to parse listofservers.json. What is the syntax to display a specific json element??

Can you help me on how to parse the json to change "Certificate" value to Yes for all the servers?

My script

- hosts: serverlist

vars_prompt:
- name: "USER"
  prompt: "Enter Admin Username"
  private: no
- name: "PASS"
  prompt: "Enter Admin Password"
  private: yes

  tasks:
- name: "Get the current values of all Servers"
  delegate_to: localhost
  register: listofservers
  check_mode: no


  uri:
    validate_certs: "no"
    user: "{{USER}}"
    password: "{{PASS}}"
    url: "https://console.exmaple.com/adminapi/serverlist"
    method: "GET"
    body_format: "json"
    return_content: "no"
    status_code: "200"

- name: Print json dictionary
  debug:
    var: listofservers.json

Output

TASK [Print json dictionary] *****************************************************************************************
ok: [centalServer.example.com] =>
{
"listofservers.json": {
   "serverlist": [
{
  "id": 1,
  "servername": "redhat.example.com",
  "apachestatus": "running",
  "certificate": "no"
},
{
  "id": 2,
  "servername": "solaris.example.com",
  "apachestatus": "down",
  "certificate": "yes"
}  ] } }

Upvotes: 1

Views: 107

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 68004

Q: "Change "certificate" value to "yes" for all servers."

A: The task below does the job

    - set_fact:
        listofservers: "{{ {'json':
                           {'serverlist': serverlist}} }}"
      vars:
        serverlist: "{{ listofservers.json.serverlist|
                        map('combine', {'certificate': 'yes'})|
                        list }}"
    - debug:
        var: listofservers.json

give

{
    "listofservers.json": {
        "serverlist": [
            {
                "apachestatus": "running",
                "certificate": "yes",
                "id": 1,
                "servername": "redhat.example.com"
            },
            {
                "apachestatus": "down",
                "certificate": "yes",
                "id": 2,
                "servername": "solaris.example.com"
            }
        ]
    }
}

Q: "What is the syntax to display a specific JSON element?"

A: There are two main options 1) Ansible filters and 2) json_query, and many variations which depend on the structure of the data and requested query

For example, display first servername where id is equal to 1

    - debug:
        msg: "{{ listofservers.json.serverlist|
                 selectattr('id', 'eq', 1)|
                 map(attribute='servername')|
                 first }}"

gives

    "msg": "redhat.example.com"

The same result will give json_query below

    - debug:
        msg: "{{ listofservers.json.serverlist|
                 json_query('[?id == `1`].servername')|
                 first }}"

Upvotes: 1

Related Questions