首页 > 解决方案 > Ansible - 从列表中删除具有特定键值的字典

问题描述

我在示例中具有如下数据结构。

我的目标是获取属于 group 的用户列表group_1。这就是我能够做的(如示例中所示)。但另外,
我想摆脱group_2. User_1而我不能那样做。

下面的 ansible playbook 及其结果:

- hosts: localhost

  vars:
    search_name: "group_1"
    users:
      - user_name: "User_1" 
        email: "user1@mail.com" 
        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: "user2@mail.com" 
        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: "user3@mail.com" 
        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 }}"

结果

        {
            "email": "user1@mail.com", 
            "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": "user2@mail.com", 
            "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"
        }
    ]

如何做到这一点?

标签: ansiblejinja2

解决方案


JMESPath 适用于简单的问题,但很难解决复杂的问题,特别是因为您的最终问题涉及有选择地建立一个新的“用户”字典(或改变 var,很难说出您想要的结果) . 如果您希望原始数据发生突变,只需删除| combine({})克隆用户字典的

    - 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 }}

推荐阅读