【问题标题】:Ansible - remove dictionary with specific key value from listAnsible - 从列表中删除具有特定键值的字典
【发布时间】:2021-01-14 14:10:13
【问题描述】:

我的数据结构如下所示。

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

下面的 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"
        }
    ]

如何做到这一点?

【问题讨论】:

    标签: ansible jinja2


    【解决方案1】:

    JMESPath 适用于简单的问题,但很难解决复杂的问题,特别是因为您的最终问题涉及有选择地构建一个新的“用户”字典(或改变 var,很难说出您的结果是什么) d想要)。如果您希望原始数据发生变异,只需删除克隆用户字典的| 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 }}
    

    【讨论】:

    • 感谢您的回答,但是当我运行您的代码时出现错误:object of type 'generator' has no len() 我正在使用 Ansible 2.7.8 没有必要使用 JMeshpath。可用于任何其他过滤器。我做了很多尝试,但没有成功
    • @krzyhon u.groups | selectattr("name", "eq", search_name) | list 因此selectattr 创建的生成器将被转换为列表,length 过滤器将起作用
    • @β.εηοιτ.βε - 它有效!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    相关资源
    最近更新 更多