jsonansiblejinja2lookup

Jinja2 apply regex_replace when setting variable and perform lookup against json file


I have a json file that includes node IDs along with other data, and another file that includes node IDs and node names. The requirement is to extract the node ID from a longer string, and then do a lookup for the node name within the other json file.

psuoutput.json

  "result": [
    {
      "env": {
        "data": {
          "id": "chassis-5/node-8/psu/psuA",
          "status": "ok",
        }
      }
    },

chassisinv.json

  "result": [
    {
      "chassis": {
        "data": {
          "id": "8",
          "name": "ecuserver",
        }
      }
    },

I can extract the node ID and have an idea of the json_query required to retrieve the node name, however, I cannot make everything work.

    - name: Load inv
      set_fact:
        chassisinv: "{{ lookup('file', 'chassisinv.json') }}"

    - name: Extract data
      vars:
        input: "{{ lookup('file',psuoutput.json) | from_json }}"
      set_fact:
        csv_content: |
          {% for server in input.result %}
          {% set nodeid = server.env.data.id | regex_replace('.*node-([^\/]*).*', '\1') %}
          {% set nodename = {{ chassisinv | from_json | json_query(".result[] | select (.chassis.data.id=="{{ nodeid }}").chassis.data.name") }}
          {{ nodeid }},{{ nodename }},{{ server.env.data.status }}
          {% endfor %}
      delegate_to: localhost

Jinja2 doesn't seem to apply the regex_replace while setting nodeid, so {{ nodeid }} results in an empty variable and the json_query errors as it cannot run using empty lookup data.

I'm also not sure this is the optimal way to decode data (name), taking as input a regexp-manipulated json field (id), looking for it within another json file.

Would you be able to assist, please?


Solution

  • With valid JSON structures a minimal example playbook

    - hosts: localhost
      become: false
      gather_facts: false
    
      vars:
    
        input:
          result: [
            {
              "env": {
                "data": {
                  "id": "chassis-5/node-8/psu/psuA",
                  "status": "ok",
                }
              }
            }
          ]
    
        chassisinv:
          result: [
            {
              "chassis": {
                "data": {
                  "id": "8",
                  "name": "eight",
                }
              }
            }
          ]
    
      tasks:
    
      - debug:
          msg: |
            {% for i in input.result %}
            {% set nodeid = (i.env.data.id | split('/') )[1] | split('-') | last %}
            {% set nodename = (chassisinv.result | selectattr("chassis.data.id", 'match', nodeid) | first ).chassis.data.name %}
            {{ nodeid }}, {{ nodename }}, {{ i.env.data.status }}
            {% endfor %}
    

    will result into an output of

    TASK [debug] *****
    ok: [localhost] =>
      msg: |-
        8, eight, ok
    

    Thanks To