Ansible - 네거티브 필터링 문제

Ansible - 네거티브 필터링 문제

저는 특정 디렉터리에 대한 액세스를 허용하고 거부하기 위한 Ansible 플레이북을 작성 중입니다. Base는 사용자 사전 목록입니다.

users:
  - {name: 'user1', dirs: ['dir1', 'dir2']}
  - {name: 'user2', dirs: ['dir1', 'dir3']} 
  - {name: 'user3', dirs: []}

보조 사실로 모든 사용자 기록에 나타나는 모든 디렉터리 목록을 만들었습니다.

이제 이 목록을 두 개의 새로운 목록으로 변환하고 싶습니다.

dirs_allowed:
  - {'dir1': ['user1', 'user2']}
  - {'dir2': ['user1']}
  - {'dir3': ['user2']}

이것은 간단하지만 이 문제에 대한 해결책을 찾을 수 없습니다.

dirs_forbidden:
 - {'dir1': ['user3']}
 - {'dir2': ['user2', 'user3']}
 - {'dir3': ['user1', 'user3']}

그래서 내 질문은: "dirs" 속성에서 현재 디렉터리(=모든 디렉터리의 with_items 루프에 있는 항목)가 없는 모든 사용자 목록을 어떻게 얻을 수 있습니까?

작업에서 보조 변수/사실 또는 "언제" 조건을 사용하여 이 작업을 수행하는 것은 확실히 가능하지만 이러한 복잡한 변환을 처리하는 방법을 배우고 싶기 때문에 목록을 직접 변환하고 싶습니다. 그 뒤에 있는 아이디어는 사전을 입력으로 제공하고 중간에 많은 set_fact-task를 사용하지 않고 해당 사전에서 특정 작업에 필요한 모든 것을 추출하는 것입니다. 이렇게 하면 플레이북을 읽기 어렵게 만들고 정의되지 않은 변수로 인해 잠재적으로 오류가 발생할 수 있습니다. 변수가 아직 설정되지 않은 중간 변수로 작업이 이동되면 실패합니다.

답변1

필터 사용차이점. 예를 들어

    - set_fact:
        users_all: "{{ users|json_query('[].name') }}"
    - set_fact:
        dirs_forbidden: "{{ dirs_forbidden|default([]) + [
          {(item.keys()|list|first):
           (users_all|difference(item.values()|list|first))}] }}"
      loop: "{{ dirs_allowed }}"
    - debug:
        var: dirs_forbidden

주다

    "dirs_forbidden": [
        {
            "dir1": [
                "user3"
            ]
        }, 
        {
            "dir2": [
                "user2", 
                "user3"
            ]
        }, 
        {
            "dir3": [
                "user1", 
                "user3"
            ]
        }
    ]

FWIW. 이 경우 사전을 사용하면 코드가 더 간단해집니다. 예를 들어

    - set_fact:
        users_all: "{{ users|json_query('[].name') }}"
    - set_fact:
        dirs_all: "{{ users|
                       json_query('[].dirs')|flatten|unique }}"
    - set_fact:
        dirs_allowed: "{{ dirs_allowed|default({})|
                          combine({item: users|json_query(query)}) }}"
      vars:
        query: "[?dirs.contains(@, '{{ item }}')].name"
      loop: "{{ dirs_all }}"
    - debug:
        var: dirs_allowed
    - set_fact:
        dirs_forbidden: "{{ dirs_forbidden|default({})|
                            combine({item: (users_all|difference(dirs_allowed[item]))}) }}"
      loop: "{{ dirs_all }}"
    - debug:
        var: dirs_forbidden

주다

    "dirs_allowed": {
        "dir1": [
            "user1", 
            "user2"
        ], 
        "dir2": [
            "user1"
        ], 
        "dir3": [
            "user2"
        ]
    }
    "dirs_forbidden": {
        "dir1": [
            "user3"
        ], 
        "dir2": [
            "user2", 
            "user3"
        ], 
        "dir3": [
            "user1", 
            "user3"
        ]
    }

관련 정보