Omar Abdelrazik
Omar Abdelrazik

Reputation: 723

Can't parse JSON list in Ansible Jinja2

I am trying to parse the following JSON output and extract the volume_id_attributes.name and volume_space_attributes.size_total but it keeps saying that:

fatal: [localhost]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'str object' has no attribute 'volume_id_attributes'"}

Here is a snippet from the JSON output that I want to parse:

ok: [localhost] => {
    "msg": {
        "results": [
            {       
                "item": "Application_Backups",
                "ontap_info": {
                    "volume_info": {
                        "alfred_backup:Application_Backups": {
                            "volume_id_attributes": {                
                                "name": "alfred_backup"
                             },
                            "volume_space_attributes": {
                                "size_total": "357019156480",
                            }
                        },
                        "alfred_prod:Application_Backups": {
                            "volume_id_attributes": {                
                                "name": "alfred_prod"
                             },
                            "volume_space_attributes": {
                                "size_total": "397512166710",
                            }
                        }, 
 "item": "Database_backups",
                "ontap_info": {
                    "volume_info": {
                        "backup:Database_backups": {
                            "volume_id_attributes": {                
                                "name": "backup"
                             },
                            "volume_space_attributes": {
                                "size_total": "754219156480",
                            }
                        },
                        "prod:Database_backups": {
                            "volume_id_attributes": {                
                                "name": "prod"
                             },
                            "volume_space_attributes": {
                                "size_total": "398952211210",
                            }
                        }
]

Here is the jinja2 script:

 {% for svm in volumes.results %}
    {% set svm_name = svm.item %}
    <td style="text-align: center;" rowspan={{ volumes|length }} class="confluenceTd">{{ svm_name }}</td>
    {% for volume in svm.ontap_info.volume_info %}
        {% set volume_name = volume.volume_id_attributes.name %}
        {% set volume_size_total = volume.volume_space_attributes.size_total %}
   

When I print out just {{ volume }}, it prints alfred_backup:Application_Backups and alfred_prod:Application_Backups but it doesn't want to get inside their list.

Could you please point me out to what I am doing wrong?

Upvotes: 1

Views: 456

Answers (1)

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39304

When doing a for loop on a list in Jinja, you do have what you expect, this is why your loop {% for svm in volumes.results %} is working.

When you are looping over a dictionary, you will only get the key of the dictionary, if you are doing a loop like you do: {% for volume in svm.ontap_info.volume_info %}, so, volume would be your dictionary key.

Still what you want to achieve is be possible, in the form

{% for key, value in dict.items() %}

As indicated in Jinja's documentation: https://jinja.palletsprojects.com/en/2.11.x/templates/#for


So a full working playbook would be

- hosts: all
  gather_facts: no
      
  tasks:
    - debug:
        msg: |
          {% for svm in volumes.results %}
            {% set svm_name = svm.item %}
            <td style="text-align: center;" rowspan={{ volumes|length }} class="confluenceTd">{{ svm_name }}</td>
            {% for key, volume in svm.ontap_info.volume_info.items() %}
              {% set volume_name = volume.volume_id_attributes.name %}
              {% set volume_size_total = volume.volume_space_attributes.size_total %}
              <td>{{ volume_name }}</td>
              <td>{{ volume_size_total }}</td>
            {% endfor %}
          {% endfor %}
      vars:
        {
          "volumes": {
            "results": [{
                "item": "Application_Backups",
                "ontap_info": {
                  "volume_info": {
                    "alfred_backup:Application_Backups": {
                      "volume_id_attributes": {
                        "name": "alfred_backup"
                      },
                      "volume_space_attributes": {
                        "size_total": "357019156480"
                      }
                    },
                    "alfred_prod:Application_Backups": {
                      "volume_id_attributes": {
                        "name": "alfred_prod"
                      },
                      "volume_space_attributes": {
                        "size_total": "397512166710"
                      }
                    }
                  }
                }
              },
              {
                "item": "Database_backups",
                "ontap_info": {
                  "volume_info": {
                    "backup:Database_backups": {
                      "volume_id_attributes": {
                        "name": "backup"
                      },
                      "volume_space_attributes": {
                        "size_total": "754219156480"
                      }
                    },
                    "prod:Database_backups": {
                      "volume_id_attributes": {
                        "name": "prod"
                      },
                      "volume_space_attributes": {
                        "size_total": "398952211210"
                      }
                    }
                  }
                }
              }
            ]
          }
        }

Which gives, as a result the HTML snippet:

<td style="text-align: center;" rowspan=1 class="confluenceTd">Application_Backups</td>
<td>alfred_backup</td>
<td>357019156480</td>
<td>alfred_prod</td>
<td>397512166710</td>

<td style="text-align: center;" rowspan=1 class="confluenceTd">Database_backups</td>
<td>backup</td>
<td>754219156480</td>
<td>prod</td>
<td>398952211210</td>

Upvotes: 2

Related Questions