0

I have following complex dictionary (this is just a sample). And I'm trying to grab a list of all ids which belong to server1. Name of the server1 is in mixed cases.

I tried jinja2 filters like match, search, equalto but none of them returns expected result. Also tried JSON query but still missing how to lower or upper case all for compare to work.

    ---
    - name: TEST
      hosts: localhost
      gather_facts: no
    
      vars:
        datacenters: {
          cabinets: {
            servers: [
              {
                name: Server1,
                id: 1
              },
              {
                name: SERVER1,
                id: 2
              },
              {
                name: Server2,
                id: 3
              },
              {
                name: server1,
                id: 4
              },
             ]
          }
        }
    
      tasks:
        - name: get ids for Server 1 
          set_fact:
            ids: "{{ datacenters.cabinets.servers
              | selectattr('name','match','Server1')
              | map(attribute='id')
              | list }}"
    
        - debug:
              var: ids
    
        - debug: msg="{{ datacenters | json_query(\"cabinets.servers[?name == 'Server1'].id\") }}"
xenlo
  • 761
  • 1
  • 7
  • 21
Marek
  • 127
  • 1
  • 8

1 Answers1

1

This can be achieved with when and lower filter of ansible. The below playbook works for me.

Playbook:

- name: Demo of restore plan
  hosts: localhost
  gather_facts: False
  vars:
    datacenters: {
        cabinets: {
          servers: [
            {
              name: Server1,
              id: 1
            },
            {
              name: SERVER1,
              id: 2
            },
            {
              name: Server2,
              id: 3
            },
            {
              name: server1,
              id: 4
            },
          ]
        }
      }
  tasks:
    - debug:
        msg: "{{ item.name }}"
      with_items:
        - "{{ datacenters.cabinets.servers }}"
      when: item.name|lower == "server1"

Output:

[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


PLAY [Demo of restore plan] ************************************************************************************************************************************************

TASK [debug] ***************************************************************************************************************************************************************
ok: [localhost] => (item={'name': 'Server1', 'id': 1}) => {
    "msg": "Server1"
}
ok: [localhost] => (item={'name': 'SERVER1', 'id': 2}) => {
    "msg": "SERVER1"
}
skipping: [localhost] => (item={'name': 'Server2', 'id': 3})
ok: [localhost] => (item={'name': 'server1', 'id': 4}) => {
    "msg": "server1"
}

PLAY RECAP *****************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Ansible lists only the server1 line and ignores the server2

Hope so this helps

error404
  • 2,684
  • 2
  • 13
  • 21
  • thats correct answer. do you know if there is a way to achieve the same without having using the loop but rather jinja2 syntax ? – Marek Jul 22 '20 at 03:07