Some checks failed
ansible-lint / Ansible Lint (push) Failing after 10s
Improved the efficiency and readability of the WOL packet handling by refactoring the existing code. This includes restructuring the validation logic and optimizing the capture process.
147 lines
4.3 KiB
YAML
147 lines
4.3 KiB
YAML
---
|
|
# ============================================================
|
|
# Install required packages
|
|
# ============================================================
|
|
- name: Install required packages
|
|
ansible.builtin.apt:
|
|
name: ethtool
|
|
state: present
|
|
update_cache: true
|
|
|
|
# ============================================================
|
|
# Detect physical NICs with WOL support using Ansible facts
|
|
# ============================================================
|
|
- name: Gather network interface facts
|
|
ansible.builtin.setup:
|
|
gather_subset:
|
|
- network
|
|
when: ansible_facts.interfaces is not defined
|
|
|
|
- name: Display interfaces
|
|
ansible.builtin.debug:
|
|
msg: >
|
|
{{ ansible_facts.interfaces }}
|
|
|
|
# - name: Get interfaces starting with "en" or "eth"
|
|
# ansible.builtin.set_fact:
|
|
# en_interfaces: "{{ ansible_facts.interfaces | select('match', '^eth|^ens|^enp') | unique | list }}"
|
|
|
|
- name: Get interfaces starting with "en, "eth" or "nic"
|
|
ansible.builtin.set_fact:
|
|
en_interfaces: >-
|
|
{{
|
|
ansible_facts.interfaces
|
|
| select('match', '^(eth|en|nic)')
|
|
| list
|
|
}}
|
|
|
|
- name: Display debug selected interfaces
|
|
ansible.builtin.debug:
|
|
msg: >
|
|
{{ en_interfaces }}
|
|
|
|
- name: Check supported Wake-on-LAN modes
|
|
ansible.builtin.shell: |
|
|
set -o pipefail
|
|
ethtool {{ item }} | grep 'Supports Wake-on' | tail -1 | awk '{print $3}'
|
|
args:
|
|
executable: /bin/bash
|
|
changed_when: false
|
|
loop: "{{ en_interfaces }}"
|
|
register: wol_supported
|
|
when: en_interfaces | length > 0
|
|
|
|
- name: WOL | Check if enabled
|
|
ansible.builtin.shell: |
|
|
set -o pipefail
|
|
ethtool {{ item }} | grep 'Wake-on' | tail -1 | awk '{print substr($0,length,1)}'
|
|
args:
|
|
executable: /bin/bash
|
|
changed_when: false
|
|
failed_when: false
|
|
loop: "{{ en_interfaces }}"
|
|
register: wol_enabled
|
|
when: en_interfaces | length > 0
|
|
|
|
- name: "Set Wake-on-LAN to {{ wol_mode }}"
|
|
ansible.builtin.command: "ethtool -s {{ item.0 }} wol {{ wol_mode }}"
|
|
loop: "{{ en_interfaces | zip(wol_enabled.results, wol_supported.results) | list }}"
|
|
loop_control:
|
|
label: "{{ item.0 }}"
|
|
when:
|
|
- wol_mode not in item.1.stdout
|
|
- wol_mode in item.2.stdout
|
|
changed_when: true
|
|
|
|
- name: "Disable Wake-on-LAN"
|
|
ansible.builtin.command: "ethtool -s {{ item.0 }} wol {{ wol_mode }}"
|
|
loop: "{{ en_interfaces | zip(wol_enabled.results, wol_supported.results) | list }}"
|
|
loop_control:
|
|
label: "{{ item.0 }}"
|
|
when:
|
|
- wol_mode == 'd'
|
|
- wol_mode not in item.1.stdout
|
|
changed_when: true
|
|
|
|
- name: Deploy wol systemd template
|
|
ansible.builtin.template:
|
|
src: templates/wol@.service.j2
|
|
dest: /etc/systemd/system/wol@.service
|
|
mode: '0644'
|
|
notify: Reload systemd
|
|
when: en_interfaces | length > 0
|
|
|
|
- name: Enable WOL systemd unit for each interface
|
|
ansible.builtin.systemd:
|
|
name: "wol@{{ item }}.service"
|
|
enabled: true
|
|
state: started
|
|
loop: "{{ en_interfaces }}"
|
|
when: en_interfaces | length > 0
|
|
|
|
- name: Get MAC addresses
|
|
ansible.builtin.set_fact:
|
|
wol_mac_addresses: >-
|
|
{{ wol_mac_addresses | default([]) + [ hostvars[inventory_hostname]['ansible_' ~ item].macaddress ] }}
|
|
loop: "{{ en_interfaces }}"
|
|
when: en_interfaces | length > 0
|
|
|
|
- name: Report WOL configuration
|
|
ansible.builtin.debug:
|
|
msg: |
|
|
Wake-on-LAN Configuration Summary:
|
|
===================================
|
|
Physical Interfaces: {{ en_interfaces | join(', ') }}
|
|
WOL Mode: {{ wol_mode }}
|
|
MAC Addresses: {{ wol_mac_addresses | join(', ') }}
|
|
|
|
- name: Start tcpdump to capture WOL packet
|
|
become: true
|
|
ansible.builtin.shell: |
|
|
timeout 10 tcpdump -i {{ en_interfaces[0] }} -nn -c 1 \
|
|
'udp and port {{ wol_port }} and (udp[8:4] = 0xffffffff)'
|
|
register: tcpdump_result
|
|
async: 12
|
|
poll: 0
|
|
|
|
- name: Send Wake-on-LAN packet from localhost
|
|
community.general.wakeonlan:
|
|
mac: "{{ wol_mac_addresses[0] }}"
|
|
port: "{{ wol_port }}"
|
|
broadcast: 255.255.255.255
|
|
delegate_to: localhost
|
|
|
|
- name: Wait for tcpdump to finish
|
|
ansible.builtin.async_status:
|
|
jid: "{{ tcpdump_result.ansible_job_id }}"
|
|
register: tcpdump_status
|
|
until: tcpdump_status.finished
|
|
retries: 12
|
|
delay: 1
|
|
|
|
- name: Check if WOL packet was received
|
|
ansible.builtin.assert:
|
|
that:
|
|
- tcpdump_status.rc == 0
|
|
success_msg: "✅ Wake-on-LAN magic packet received by host"
|
|
fail_msg: "❌ Wake-on-LAN magic packet NOT detected" |