Search code examples
jsonansiblejmespathansible-awx

JMESPath - Ansible-AWX - JSON


I have the following json where i wish to extract the name based on externalId (2720135)

 {  
  "data": [
    {
      "id": "f15073f7-c934-479f-bed9-07b6c3402b60",
      "name": "360 Index",
      "description": "360 Index",
      "displayName": "360 Index",
      "fullName": "360 Index",
      "type": "Application",
      "tags": [],
      "fields": [
        {
          "name": "externalId",
          "data": {
            "type": "ExternalId",
            "externalId": "2720135",
            "comment": null,
            "status": "ACTIVE",
            "externalUrl": null
          },
          "dataType": null
        }
      ],
      "relations": [],
      "milestones": [],
      "createdAt": "2022-07-06T19:00:20.202009Z",
      "updatedAt": "2022-09-21T11:51:45.887413Z",
      "documents": [],
      "status": "ACTIVE",
      "lxState": "BROKEN_QUALITY_SEAL",
      "level": 1,
      "qualitySealStatus": "BROKEN",
      "score": "NaN",
      "rev": 51,
      "lxExcludeFromQuota": false,
      "naFields": [],
      "subscriptions": [],
      "permittedReadACL": [],
      "permittedWriteACL": []
    }
  ],
  "cursor": "bWl4OjAjRFhGMVpYSjVRVzVrUm1WMFkyZ0JBQUFBQUFCWkN6b1dlamhIYzBSd1pVeFVSUzFCTVdwT2NFZHpTMW95UVE9PSUxNjY0MzYzMTQ5NDM1"
}

What i have tried to only select the keys "name" and "fields"

   data[].{name:name,fields:fields}

Question: How can i filter to only get the name based on "externalId": "2720135"

Result should be: "360 Index"


Solution

  • Given the data for testing
    shell> cat data5.yml
    data:
      - createdAt: '2022-07-06T19:00:20.202009Z'
        fields:
        - data:
            externalId: '2720135'
            status: ACTIVE
          name: externalId
        level: 1
        name: 360 Index
      - createdAt: '2022-07-06T19:00:20.202009Z'
        fields:
        - data:
            externalId: '2720136'
            status: ACTIVE
          name: externalId
        level: 1
        name: 336 Index
      - createdAt: '2022-07-06T19:00:20.202009Z'
        fields:
        - data:
            externalId: '2720137'
            status: ACTIVE
          name: externalId
        level: 1
        name: 337 Index
    

    For example, the declarations below

    result: "{{ data|json_query(_query) }}"
    _query: '[?fields[?data.externalId == to_string(`2720135`)]].name'
    

    give

      result:
      - 360 Index
    

    Example of a complete playbook for testing

    - hosts: localhost
    
      vars_files:
        - data5.yml
    
      vars:
    
        result: "{{ data|json_query(_query) }}"
        _query: '[?fields[?data.externalId == to_string(`2720135`)]].name'
    
        resul2: "{{ data|json_query('[].{name: name,
                                         fields: fields[].data.externalId|[0] }') }}"
    
      tasks:
    
        - debug:
            var: result
        - debug:
            var: resul2|to_yaml
    

    gives (abridged)

      result:
        - 360 Index
    
      resul2|to_yaml: |-
        - {fields: '2720135', name: 360 Index}
        - {fields: '2720136', name: 336 Index}
        - {fields: '2720137', name: 337 Index}
    

    You can create a dictionary that would make the searching trivial, e.g.

    id_name: "{{ resul2|items2dict(key_name='fields', value_name='name') }}"
    

    gives

      id_name:
        '2720135': 360 Index
        '2720136': 336 Index
        '2720137': 337 Index