0

I have task which calls an API and I register the o/p in a varaible;

- name: Get Object storage account ID
  uri:
    url: 'https://api.softlayer.com/rest/v3.1/SoftLayer_Network_Storage_Hub_Cleversafe_Account/getAllObjects.json?objectFilter={"username":{"operation":"{{ item }}"}}'
    method: GET
    user: abxc
    password: 66c94c447a6ed8a0cf058774fe38
    validate_certs: no
  register: old_existing_access_keys_sl
  with_items: '{{ info["personal"].sl_cos_accounts }}'

old_existing_access_keys_sl holds:

"old_existing_access_keys_sl.results": [
 {
            "json": [
                {
                    "accountId": 12345, 
                    "id": 70825621, 
                    "username": "xyz-11"
                }
            ]
},
{
            "json": [
                {
                    "accountId": 12345, 
                    "id": 70825621, 
                    "username": "abc-12"
                }
            ]
}

I want to make a list of id's for further processing an tried the following task but this did not work:

- name: Create a list of account ids
  set_fact: 
    admin_usernames = "{{ item.json[0].id | list }}"
  with_items: old_existing_access_keys_sl.results

I am not sure if that's even possible. I also tried this:

    - name: create a list
      set_fact:
         foo: "{% set foo = [] %}{% for i in old_existing_access_keys_sl.results %}{{ foo.append(i) }}{% endfor %}"

foo always comes as blank and as a string:


TASK [result] *****************************************************************************************************************************************
ok: [localhost] => {
    "foo": ""
}
codec
  • 7,978
  • 26
  • 71
  • 127

1 Answers1

1

Given your example data, you can extract a list of ids using the json_query filter, like this:

---
- hosts: localhost
  gather_facts: false
  vars:
    old_existing_access_keys_sl:
      results:
        [
          {
            "json": [
              {
                "accountId": 12345,
                "id": 70825621,
                "username": "xyz-11"
              }
            ]
          },
          {
            "json": [
              {
                "accountId": 12345,
                "id": 70825621,
                "username": "abc-12"
              }
            ]
          }
        ]
  tasks:
    - debug:
        var: old_existing_access_keys_sl|json_query('results[*].json[0].id')

This will output:

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "old_existing_access_keys_sl|json_query('results[*].json[0].id')": [
        70825621, 
        70825621
    ]
}

If you want to store these in a new variable, you can replace that debug task with set_fact:

    - set_fact:
        admin_ids: "{{ old_existing_access_keys_sl|json_query('results[*].json[0].id') }}"

Update

For a list of dictionaries, just change the json_query expression:

- debug:
    var: "old_existing_access_keys_sl|json_query('results[*].json[0].{id: id, username: username}')"

For more information, see the jmespath website for documentation and examples.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • Thanks it worked, but got this too: `{"msg": "You need to install \"jmespath\" prior to running json_query filter"}`. Had to install this first using pip. – codec Apr 08 '19 at 19:07
  • That's correct, some ansible modules and filters have prerequisites that may or may be installed by default. It depends on how you install Ansible and what sort of dependencies are configured by your installation tools. – larsks Apr 08 '19 at 19:09
  • I've added an example that creates a list of dictionaries, and links to additional information about the jmespath query language used by the `json_query` filter. – larsks Apr 08 '19 at 20:33