--- - name: Determine removed users from previous export ansible.builtin.set_fact: _hysteria2_removed_users: >- {{ (_hysteria2_saved_server_info.users | default([]) | map(attribute='name') | list) | difference(hysteria2_resolved_users | map(attribute='name') | list) }} delegate_to: localhost become: false - name: Build list of export files to remove for deleted users ansible.builtin.set_fact: _hysteria2_removed_user_files: >- {{ _hysteria2_removed_user_files | default([]) + [ hysteria2_output_dir ~ '/' ~ hysteria2_output_name ~ '/' ~ item.0 ~ item.1 ] }} loop: "{{ _hysteria2_removed_users | default([]) | product(_hysteria2_user_export_suffixes) | list }}" vars: _hysteria2_user_export_suffixes: - ".url" - ".txt" - ".qr.txt" - ".png" when: _hysteria2_removed_users | default([]) | length > 0 delegate_to: localhost become: false - name: Remove export files for deleted users ansible.builtin.file: path: "{{ item }}" state: absent loop: "{{ _hysteria2_removed_user_files | default([]) }}" delegate_to: localhost become: false when: _hysteria2_removed_user_files | default([]) | length > 0 - name: Check local URL files for resolved users ansible.builtin.stat: path: "{{ hysteria2_output_dir }}/{{ hysteria2_output_name }}/{{ item.name }}.url" loop: "{{ hysteria2_resolved_users }}" register: _hysteria2_url_file_stats delegate_to: localhost become: false - name: Split users into full export and reuse existing export data ansible.builtin.set_fact: hysteria2_users_for_export: "{{ hysteria2_users_for_export | default([]) + ([item] if _needs_export else []) }}" hysteria2_users_for_reuse: "{{ hysteria2_users_for_reuse | default([]) + ([_reuse_entry] if not _needs_export else []) }}" loop: "{{ hysteria2_resolved_users }}" loop_control: label: "{{ item.name }}" vars: _saved_user: >- {{ (_hysteria2_saved_server_info.users | default([]) | selectattr('name', 'equalto', item.name) | list | first) | default({}, true) }} _url_stat: >- {{ ((_hysteria2_url_file_stats.results | selectattr('item.name', 'equalto', item.name) | list | first).stat) | default({}, true) }} _needs_export: >- {{ hysteria2_force_export | bool or (_saved_user | length == 0) or (item.password != (_saved_user.password | default(''))) or (hysteria2_domain != (_hysteria2_saved_server_info.domain | default(''))) or ((hysteria2_listen_port | string) != (_hysteria2_saved_server_info.port | default('') | string)) or ((hysteria2_obfs_password | default('')) != (_hysteria2_saved_server_info.obfs_password | default(''))) or not (_url_stat.exists | default(false)) }} _reuse_entry: name: "{{ item.name }}" password: "{{ item.password }}" url: "{{ _saved_user.url }}" has_png: "{{ _saved_user.has_png | default(false) | bool }}" delegate_to: localhost become: false