Home > Net >  Parsed the key and values from Json nested object output in Ansible
Parsed the key and values from Json nested object output in Ansible

Time:05-27

I am pulling the information from the device and saving as json and yaml format and the going through the data then parse and generate a csv file for specific key and value.

Can you please help me to get these specific key/values (some key/values can be unknown, so we cannot call them by name)

Here is what I need into my CVS file

OPER_ID, TYPE, TAG, DATA SIZE REQ, SRC ADDR, DEST ADDR, DEST PORT, FREQUENCY, PACKET COUNT, PACKET INTERVAL
200, udp jitter, ABC, 500, 1.1.1.1, 2.2.2.2, 17000, 60, 1000, 20
200, icmp path-jitter, DEF, null, 3.3.3.3, 4.4.4.4, null, 30, 20, null

Here is the json file data saved in json file after my playbook run

"{
    "100": {
        "type": {
            "udp jitter": {
                "data_size_req": 500,
                "dest_addr": "2.2.2.2",
                "dest_port": 17000,
                "frequency": 60,
                "packet": {
                    "count": 1000,
                    "interval": 20
                },
                "src_addr": "1.1.1.1",
                "tag": "ABC"
            }
        }
    },
    "200": {
        "type": {
            "icmp path-jitter": {
                "dest_addr": "4.4.4.4",
                "frequency": 30,
                "packet": {
                    "count": 50
                },
                "src_addr": "3.3.3.3",
                "tag": "DEF"
            }
        }
    }"

Here is my playbook

---
- name: COLLECT SHOW RUN IPSLA OPERATION
  hosts: router1.example.com
  gather_facts: no
  connection: network_cli
  roles:
    - clay584.parse_genie

  tasks:
  - name: show running ipsla config 
    iosxr_command:
      commands: show run ipsla operation
    register: ipsla_output

  - name: Set fact with Genie parser
    set_fact:
      ipsla_config: "{{ ipsla_output['stdout'][0] | parse_genie(command='show run ipsla operation', os='iosxr') }}"

  - name: Copy the output into a json file 
    copy:
      content: |
        "{{ ipsla_config.ipsla.operations | to_nice_json }}"
      dest: "{{ inventory_hostname }}_ipsla.json"

# Here something is wrong 
  - name: Create a CSV file from the output 
    lineinfile:
      path: "{{ inventory_hostname }}_ipsla.csv"
      line: "{{ item.key }}, {{ item.value.type.key }} " ### this is where i am wrong 
      create: yes
    loop: "{{ ipsla_config.ipsla.operations | dict2items }}"

  - name: Add a header row on the above CSV file
    lineinfile:
      path: "{{ inventory_hostname }}_ipsla.csv"
      insertbefore: BOF
      line: OPER_ID,TYPE

Here is the error when I try to pull the "type" value key

TASK [Create a CSV file from the output] ********************************************************************************
fatal: [fra01-wxbb-crt01.webex.com]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'key'\n\nThe error appears to be in '/Users/murafi/webexansible/ipsla_plays.yml': line 45, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n  - name: Create a CSV file from the output\n    ^ here\n"}

Please let me know if you need more information and thanks for your help in advance :)

CodePudding user response:

use template module to create final csv:

create a template file csv.j2 in templates folder

OPER_ID, TYPE, TAG, DATA SIZE REQ, SRC ADDR, DEST ADDR, DEST PORT, FREQUENCY, PACKET COUNT, PACKET INTERVAL
{% for k0 in json %}
{% set oper_id = k0 %}
{% set type = json[k0]['type']|first %}
{% set data_size_req = json[k0]['type'][type]['data_size_req']|d("null") %}
{% set tag = json[k0]['type'][type]['tag']|d("null") %}
{% set src_addr = json[k0]['type'][type]['src_addr']|d("null") %}
{% set dest_addr = json[k0]['type'][type]['dest_addr']|d("null") %}
{% set dest_port = json[k0]['type'][type]['dest_port']|d("null") %}
{% set frequency = json[k0]['type'][type]['frequency']|d("null") %}
{% set packet_count = json[k0]['type'][type]['packet']['count']|d("null") %}
{% set packet_interval = json[k0]['type'][type]['packet']['interval']|d("null") %}
{{ oper_id }}, {{ type }}, {{ tag }}, {{ data_size_req }}, {{ src_addr }}, {{ dest_addr }}, {{ dest_port }}, {{ frequency }}, {{ packet_count }}, {{ packet_interval }}
{% endfor %}

the playbook to create the final csv file:

- name: testplaybook jinja2
  hosts: router1.example.com
  tasks:
    - name: Create a CSV file from the output 
      template:
        src: csv.j2
        dest: "{{ inventory_hostname }}_ipsla.csv"
      vars:
        fil: "{{ inventory_hostname }}_ipsla.json"
        json: "{{ lookup('file', fil) | from_json }}"
  • Related