133 lines
4.5 KiB
YAML
133 lines
4.5 KiB
YAML
---
|
|
- name: Check change freeze
|
|
ansible.builtin.assert:
|
|
that:
|
|
- not (change_freeze | bool)
|
|
fail_msg: "FROZEN: {{ inventory_hostname }} is under a change freeze. Aborting."
|
|
success_msg: "Change freeze check passed"
|
|
|
|
- name: Check disk space on critical mountpoints
|
|
ansible.builtin.shell: |
|
|
df -P {{ item }} | tail -1 | awk '{print $5}' | tr -d '%' # POSIX flag — compatible with BusyBox (Alpine) and GNU coreutils
|
|
register: disk_usage
|
|
changed_when: false
|
|
loop:
|
|
- /
|
|
- /var
|
|
- /boot
|
|
ignore_errors: true
|
|
|
|
- name: Assert disk space is sufficient
|
|
ansible.builtin.assert:
|
|
that:
|
|
- item.stdout | int < (100 - min_free_disk_percent)
|
|
fail_msg: "DISK: {{ item.item }} is {{ item.stdout }}% full — minimum {{ min_free_disk_percent }}% free required"
|
|
success_msg: "Disk OK: {{ item.item }} is {{ item.stdout }}% used"
|
|
loop: "{{ disk_usage.results }}"
|
|
when: item.rc == 0 and item.stdout | int(-1) >= 0 # skip if stdout is not numeric (e.g. /boot missing on Alpine LXC)
|
|
|
|
- name: Get load average
|
|
ansible.builtin.shell: |
|
|
cat /proc/loadavg | awk '{print $3}'
|
|
register: load_avg
|
|
changed_when: false
|
|
|
|
- name: Get CPU count
|
|
ansible.builtin.shell: |
|
|
nproc
|
|
register: cpu_count
|
|
changed_when: false
|
|
|
|
- name: Assert load average is acceptable
|
|
ansible.builtin.assert:
|
|
that:
|
|
- load_avg.stdout | float < (cpu_count.stdout | int * max_load_multiplier)
|
|
fail_msg: "LOAD: 15min load average {{ load_avg.stdout }} exceeds threshold ({{ cpu_count.stdout }} CPUs x {{ max_load_multiplier }})"
|
|
success_msg: "Load average OK: {{ load_avg.stdout }} ({{ cpu_count.stdout }} CPUs)"
|
|
|
|
- name: Check for pending reboot (Debian/Ubuntu)
|
|
ansible.builtin.stat:
|
|
path: /var/run/reboot-required
|
|
register: reboot_required
|
|
when: ansible_os_family == "Debian"
|
|
|
|
- name: Warn if reboot is pending
|
|
ansible.builtin.debug:
|
|
msg: "WARNING: {{ inventory_hostname }} has a pending reboot. Patching will proceed but reboot required afterwards."
|
|
when:
|
|
- ansible_os_family == "Debian"
|
|
- reboot_required.stat.exists
|
|
|
|
- name: Set reboot_required fact (Debian)
|
|
ansible.builtin.set_fact:
|
|
host_reboot_required: "{{ reboot_required.stat.exists | default(false) }}"
|
|
when: ansible_os_family == "Debian"
|
|
|
|
- name: Check for pending reboot (RHEL/CentOS)
|
|
ansible.builtin.shell: |
|
|
needs-restarting -r
|
|
register: rhel_reboot_check
|
|
changed_when: false
|
|
failed_when: false
|
|
when: ansible_os_family == "RedHat"
|
|
|
|
- name: Set reboot_required fact (RHEL)
|
|
ansible.builtin.set_fact:
|
|
host_reboot_required: "{{ rhel_reboot_check.rc == 1 }}"
|
|
when: ansible_os_family == "RedHat"
|
|
|
|
- name: Preflight complete
|
|
ansible.builtin.debug:
|
|
msg: "Preflight passed for {{ inventory_hostname }} — proceeding with maintenance"
|
|
|
|
- name: Check for Proxmox helper script marker
|
|
ansible.builtin.stat:
|
|
path: /usr/bin/update
|
|
register: helper_script_marker
|
|
|
|
- name: Log helper script detection
|
|
ansible.builtin.debug:
|
|
msg: "INFO: This LXC was deployed via Proxmox helper script — built-in update script detected at /usr/bin/update. Ansible will manage updates instead."
|
|
when: helper_script_marker.stat.exists
|
|
|
|
|
|
# =============================================================================
|
|
# OPNsense Specific Preflight Checks
|
|
# =============================================================================
|
|
|
|
- name: OPN | Verify Required Variables for OPNsense
|
|
ansible.builtin.assert:
|
|
that:
|
|
- ansible_host is defined
|
|
- firewall_api_port is defined
|
|
fail_msg: "Required OPNsense variables (ansible_host or firewall_api_port) are missing."
|
|
when: "'opnsense' in group_names"
|
|
tags: [preflight, vars]
|
|
|
|
- name: OPN | Verify SSH Connectivity (Port {{ ansible_port | default(22) }})
|
|
ansible.builtin.wait_for:
|
|
host: "{{ ansible_host }}"
|
|
port: "{{ ansible_port | default(22) }}"
|
|
timeout: 5
|
|
msg: "SSH port is not reachable. Check firewall whitelisting."
|
|
when: "'opnsense' in group_names"
|
|
tags: [preflight, connection]
|
|
|
|
- name: OPN | Verify API Connectivity (Port {{ firewall_api_port }})
|
|
ansible.builtin.wait_for:
|
|
host: "{{ ansible_host }}"
|
|
port: "{{ firewall_api_port }}"
|
|
timeout: 5
|
|
msg: "Web GUI/API port is not reachable. Check OPNsense settings."
|
|
when: "'opnsense' in group_names"
|
|
tags: [preflight, connection, api]
|
|
|
|
- name: OPN | Verify httpx Library on Control Node
|
|
ansible.builtin.command: python3 -c "import httpx"
|
|
delegate_to: localhost
|
|
run_once: true
|
|
register: httpx_check
|
|
failed_when: httpx_check.rc != 0
|
|
changed_when: false
|
|
when: "'opnsense' in group_names"
|
|
tags: [preflight, dependencies] |