Ansible: filter an item from a list of object in a json file

886 Views Asked by At

I have in ansible the following code:

---
  - name: "Retrieve ID for group {{onboarding.repo.subGroup}}"
    uri:
      method: GET
      return_content: yes
      validate_certs: "{{gitlab_validate_certs}}"
      url: "{{ gitlab_api_url }}/api/v4/groups?search={{onboarding.repo.subGroup}}"
      headers:
        Private-Token: "{{ gitlab_api_token }}"
    register: uri_response

  - debug:
      msg: "{{ uri_response['content'] }}"

  - set_fact:
      groupID: "{{ uri_response['content'] | from_json | json_query([*].[?name=='{{onboarding.repo.subGroup}}'].id) }}"

The get method retrieve a json list like the following one:

[
  {
    "id":1,
    "name":"name1"
  },
  {
    "id":2,
    "name":"name2"
  },
  ...
]

With the set_fact module I am trying to get the id on an item that correspond to a specific name. I have tried many json_query syntax (for instance .[?name=='{{onboarding.repo.subGroup}}'].id or [?name=='{{onboarding.repo.subGroup}}'].id), without success. I saw many different examples online, but they were different because the list was the value of a key, like the following:

key:
    [
      {...},
      {...},
      ...
    ]

And I saw different examples working with a query syntax like key.[?name=='{{onboarding.repo.subGroup}}'].id

I cannot find a way to adapt that query to my case. Can anyone help me on finding the right syntax?

Regards, Giorgio

1

There are 1 best solutions below

3
Vladimir Botka On

Q: "Get the id on an item that corresponds to a specific name."

A: Convert the list to a dictionary

  content: "{{ uri_response.content|
               items2dict(key_name='name', value_name='id') }}"

gives

  content:
    name1: 1
    name2: 2

Use the dictionary

    - debug:
        msg: "{{ content[item]|default('undef') }}"
      loop:
        - name1
        - name2
        - name3

gives (abridged)

  msg: '1'
  msg: '2'
  msg: undef

Example of a complete playbook

- hosts: localhost
  vars:
    uri_response:
      content:
        [
          {
            "id":1,
            "name":"name1"
          },
          {
            "id":2,
            "name":"name2"
          }
        ]
    content: "{{ uri_response.content|items2dict(key_name='name', value_name='id') }}"
  tasks:
    - debug:
        msg: "{{ content[item]|default('undef') }}"
      loop:
        - name1
        - name2
        - name3