ansiblejson-query

"contains" filter on json_query keeps returning all data instead of what is specific in the filter


I have the following data that I'm trying to filter:

      "flags": [
        "inhibitor"
      ],
......(some data here)....
      "flags": [],
......(some other data here)...
      "flags": [],

The code below is supposed to filter through the data above and return only those "flags" that has the string "inhibitor" such that it should return:

ok: [localhost] => {
    "msg": [
        [ "inhibitor" ]
    ]
}

But instead, it returns all the "flags" including the empty ones:

ok: [localhost] => {
    "msg": [
        [
            "inhibitor"
        ],
        [],
        []
    ]
}

  - name: Set appropriate facts based on the report
    set_fact:
      leapp_preupgrade_report_inhibitors: >
        {{ leapp_preupgrade_report["entries"] | json_query("[*].flags[?contains(@, 'inhibitor')]") | list }}

  - debug:
      msg: "{{ leapp_preupgrade_report_inhibitors }}"

I have also tried the following iteration, to no avail:

{{ leapp_preupgrade_report["entries"] | to_json |from_json | json_query("[*].flags[?contains(@, 'inhibitor')]") | list }}

How should I properly filter the data that I need to get a list of?


Solution

  • Given the data

      report:
        entries:
          - flags: [inhibitor]
          - flags: []
          - flags: []
    

    the query below does the job

      inhibitors: "{{ report.entries|
                      json_query('[?contains(flags, `inhibitor`)]') }}"
    

    gives

      inhibitors:
        - flags: [inhibitor]
    

    Example of a complete playbook for testing

    - hosts: localhost
    
      vars:
    
        report:
          entries:
            - flags: [inhibitor]
            - flags: []
            - flags: []
    
        inhibitors: "{{ report.entries|
                        json_query('[?contains(flags, `inhibitor`)]') }}"
    
      tasks:
    
        - debug:
            var: inhibitors
    

    The filter selectattr and the Ansible test contains give the same result

      inhibitors: "{{ report.entries|
                      selectattr('flags', 'contains', 'inhibitor') }}"