--- - name: Check rsyslog configuration drift hosts: rsyslog_servers gather_facts: false # SIMPLE FILE CONTENT COMPARISON - No permission checks # Uses slurp to read files directly (no stat/watchers) # Exit code: 0 = SYNCED, non-zero = OUT_OF_SYNC tasks: - name: Initialize variables set_fact: drift_detected: false drifted_files: [] # ───────────────────────────────────────────────────────────────────────── # Compare rsyslog.conf content (with line ending normalization) # ───────────────────────────────────────────────────────────────────────── - name: Read Git rsyslog.conf slurp: src: "{{ playbook_dir }}/../../files/rsyslog.conf" delegate_to: localhost register: git_main_conf - name: Read server rsyslog.conf slurp: src: "{{ rsyslog_main_config }}" register: server_main_conf - name: Normalize line endings and compare rsyslog.conf set_fact: # Decode base64, normalize line endings (CRLF -> LF), compare git_main_content: "{{ (git_main_conf.content | b64decode | replace('\r\n', '\n')) }}" server_main_content: "{{ (server_main_conf.content | b64decode | replace('\r\n', '\n')) }}" - name: Check rsyslog.conf content match set_fact: main_conf_match: "{{ git_main_content == server_main_content }}" - name: Debug rsyslog.conf comparison debug: msg: | Git rsyslog.conf size: {{ git_main_content | length }} chars Server rsyslog.conf size: {{ server_main_content | length }} chars Match: {{ main_conf_match }} when: not main_conf_match - name: Mark drift if rsyslog.conf differs set_fact: drift_detected: true drifted_files: "{{ drifted_files + ['rsyslog.conf'] }}" when: not main_conf_match # ───────────────────────────────────────────────────────────────────────── # Compare rsyslog.d directory files # ───────────────────────────────────────────────────────────────────────── - name: List Git rsyslog.d files find: paths: "{{ playbook_dir }}/../../files/rsyslog.d" patterns: "*.conf" recurse: false delegate_to: localhost register: git_confd_list - name: List server rsyslog.d files find: paths: "{{ rsyslog_config_dir }}" patterns: "*.conf" recurse: false register: server_confd_list - name: Extract file names set_fact: git_confd_names: "{{ git_confd_list.files | map(attribute='path') | map('basename') | sort }}" server_confd_names: "{{ server_confd_list.files | map(attribute='path') | map('basename') | sort }}" - name: Check rsyslog.d file list match set_fact: confd_match: "{{ git_confd_names == server_confd_names }}" - name: Mark drift if rsyslog.d files differ set_fact: drift_detected: true drifted_files: "{{ drifted_files + ['rsyslog.d/'] }}" when: not confd_match # ───────────────────────────────────────────────────────────────────────── # Output markers for update-gitops-status.sh parsing # ───────────────────────────────────────────────────────────────────────── - name: Output drifted files list debug: msg: "DRIFTED_FILES={{ drifted_files | join(',') if drifted_files | length > 0 else '' }}" - name: Output SYNCED status debug: msg: "SYNC_STATUS=SYNCED" when: not drift_detected - name: Output OUT_OF_SYNC status debug: msg: "SYNC_STATUS=OUT_OF_SYNC" when: drift_detected - name: Display SYNCED debug: msg: | ╭─────────────────────────────╮ │ ✓ SYNCED │ │ Configuration is up-to-date │ ╰─────────────────────────────╯ when: not drift_detected - name: Display OUT_OF_SYNC debug: msg: | ╭─────────────────────────────╮ │ ✗ OUT OF SYNC │ │ Configuration has drifted │ ╰─────────────────────────────╯ when: drift_detected - name: Fail if drift detected fail: msg: "Configuration drift detected." when: drift_detected