krzyhon
krzyhon

Reputation: 15

Ansible - remove dictionary with specific key value from list

I have data structure as below in example.

My goal is to get a list of users who belong to group group_1. And that's what I am able to do (as in the example).
But additionally, I want to get rid of group_2 in User_1. And I can't do that.

Below ansible playbook and its result:

- hosts: localhost

  vars:
    search_name: "group_1"
    users:
      - user_name: "User_1" 
        email: "[email protected]" 
        login: "user.1"
        groups:
          - name: group_1
            servers:
              - server: 
                  name: 'SERVER-01'
                  ip: '192.168.x.x'
                  port: 5656
              - server: 
                  name: 'SERVER-02'
                  ip: '192.168.x.x'
                  port: 5656
          - name: group_2
            servers:
              - server: 
                  name: 'SERVER-03'
                  ip: '192.168.x.x'
                  port: 5656
              - server:   
                  name: 'SERVER-01'
                  ip: '192.168.x.x'
                  port: 5656
              - server:   
                  name: 'SERVER-02'
                  ip: '192.168.x.x'
                  port: 5656
      - user_name: "User_2" 
        email: "[email protected]" 
        login: "user.2"
        groups:
          - name: group_1
            servers:
              - server: 
                  name: 'SERVER-01'
                  ip: '192.168.x.x'
                  port: 5656
              - server:   
                  name: 'SERVER-02'
                  ip: '192.168.x.x'
                  port: 5656
      - user_name: "User_3" 
        email: "[email protected]" 
        login: "user.3"
        groups:
          - name: group_3
            servers:
              - server: 
                  name: 'SERVER-03'
                  ip: '192.168.x.x'
                  port: 5656
  
  tasks:
    - name: Initialize an empty list for servers
      set_fact:
        filtered_users: []

    - name: Filter users by group name
      set_fact:
        filtered_users: "{{ users | json_query(query) }}"
      vars:
        query: "[? groups[? name==`group_1`]] | []"        

    - name: Display users
      debug:
        msg: "{{ filtered_users }}"

Result

        {
            "email": "[email protected]", 
            "groups": [
                {
                    "name": "group_1", 
                    "servers": [
                        {
                            "server": {
                                "ip": "192.168.x.x", 
                                "name": "SERVER-01", 
                                "port": 5656
                            }
                        }, 
                        {
                            "server": {
                                "ip": "192.168.x.x", 
                                "name": "SERVER-02", 
                                "port": 5656
                            }
                        }
                    ]
                }, 
                {
                    "name": "group_2", 
                    "servers": [
                        {
                            "server": {
                                "ip": "192.168.x.x", 
                                "name": "SERVER-03", 
                                "port": 5656
                            }
                        }, 
                        {
                            "server": {
                                "ip": "192.168.x.x", 
                                "name": "SERVER-01", 
                                "port": 5656
                            }
                        }, 
                        {
                            "server": {
                                "ip": "192.168.x.x", 
                                "name": "SERVER-02", 
                                "port": 5656
                            }
                        }
                    ]
                }
            ], 
            "login": "user.1", 
            "user_name": "User_1"
        }, 
        {
            "email": "[email protected]", 
            "groups": [
                {
                    "name": "group_1", 
                    "servers": [
                        {
                            "server": {
                                "ip": "192.168.x.x", 
                                "name": "SERVER-01", 
                                "port": 5656
                            }
                        }, 
                        {
                            "server": {
                                "ip": "192.168.x.x", 
                                "name": "SERVER-02", 
                                "port": 5656
                            }
                        }
                    ]
                }
            ], 
            "login": "user.2", 
            "user_name": "User_2"
        }
    ]

How can this be achieved?

Upvotes: 0

Views: 1114

Answers (1)

mdaniel
mdaniel

Reputation: 33158

JMESPath is fine for simple questions, but is hard to wrap one's head around complex stuff, especially since your ultimate question involves selectively building up a new "user" dict (or mutating the var, it's hard to tell which outcome you'd want). If you want the original data mutated, just remove the | combine({}) that clones the user dict

    - name: Filter users by group name
      set_fact:
        filtered_users: >-
          {%- set results = [] -%}
          {%- for ur in users -%}
          {%-  set u = ur | combine({}) -%}
          {%-  set g1 = u.groups | selectattr("name", "eq", search_name) -%}
          {%-  if g1 | length > 0 -%}
          {%-    set _ = u.update({"groups": g1}) -%}
          {%-    set _ = results.append(u) -%}
          {%-   endif -%}
          {%- endfor -%}
          {{ results }}

Upvotes: 1

Related Questions