Execution
Date
22 Jul 2025 13:07:04 +0100
Duration
00:00:05.41
Controller
ssh-gw-4.layershift.com
User
root
Versions
Ansible
2.16.11
ara
1.7.2 / 1.7.2
Python
3.10.10
Summary
2
Hosts
16
Tasks
16
Results
1
Plays
1
Files
0
Records
File: /home/ssh-gateway/ansible/kuly/get_mac_addresses.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | --- - name: Gather all physical interfaces and write to single local file hosts: all become: true gather_facts: false # We'll collect results in a global fact on localhost vars: ignored_prefixes: - "lo" - "docker" - "veth" - "virbr" - "wl" - "wlan" - "tun" - "tap" # Pre-tasks: Gather data per host pre_tasks: - name: Get default route interface command: ip route show default register: default_route changed_when: false - name: Extract main interface from default route set_fact: main_interface: >- {{ (default_route.stdout.split('dev')[1].split()[0]) if 'dev' in default_route.stdout else '' }} when: default_route.stdout != "" - name: Fail if no default interface found fail: msg: "No default route found." when: default_route.stdout == "" or ("dev" not in default_route.stdout) # Check if managed by NetworkManager as a bridge - name: Check active nmcli connections (type:device) command: nmcli -t -f TYPE,DEVICE connection show --active register: nmcli_connections changed_when: false ignore_errors: yes - name: Determine if main_interface is a bridge set_fact: is_bridge: >- {% set result = [] %}{% for line in (nmcli_connections.stdout_lines | default([])) %}{% set parts = line.split(':') %}{% if parts[1] == main_interface and parts[0] == 'bridge' %}{% set _ = result.append(1) %}{% endif %}{% endfor %} {{ true if result else false }} when: nmcli_connections.rc == 0 - name: Set is_bridge to false if nmcli failed set_fact: is_bridge: false when: nmcli_connections.rc != 0 # Get slave interface via nmcli if it's a bridge - name: Get slave connections (name:device:master) command: nmcli -t -f NAME,DEVICE,MASTER connection show --active register: nmcli_slaves when: is_bridge | bool changed_when: false ignore_errors: yes - name: Find first physical slave interface for the bridge set_fact: physical_interface: >- {% set found = [] %}{% for line in (nmcli_slaves.stdout_lines | default([])) %}{% set parts = line.split(':') %}{% if parts[2] == main_interface %}{% set _ = found.append(parts[1]) %}{% break %}{% endif %}{% endfor %} {{ found[0] if found else '' }} when: is_bridge | bool - name: Use main interface as physical if not a bridge set_fact: physical_interface: "{{ main_interface }}" when: not (is_bridge | bool) - name: Fail if no physical interface found from bridge fail: msg: "Could not find physical interface enslaved to bridge {{ main_interface }}" when: is_bridge | bool and (physical_interface is undefined or physical_interface == '') # Validate interface is not ignored - name: Check if physical interface should be ignored set_fact: is_ignored: "{{ (ignored_prefixes | select('regex', '^' ~ physical_interface) | list | length) > 0 }}" - name: Fail if interface is ignored fail: msg: "Physical interface {{ physical_interface }} is ignored." when: is_ignored | bool - name: Verify physical interface exists stat: path: "/sys/class/net/{{ physical_interface }}" register: phys_stat failed_when: not phys_stat.stat.exists - name: Get MAC address command: "cat /sys/class/net/{{ physical_interface }}/address" register: mac_result changed_when: false - name: Set final facts for reporting set_fact: report_line: "{{ inventory_hostname }} - {{ physical_interface }} - {{ mac_result.stdout }}" # Actual task runs only on localhost at the end tasks: - name: Collect all report lines and write to single file delegate_to: localhost run_once: true copy: content: | # Hostname - Interface - MAC Address {% for host in groups['all'] %} {{ hostvars[host].report_line }} {% endfor %} dest: all_macs.txt force: yes - name: Confirm output delegate_to: localhost run_once: true debug: msg: "All MAC addresses written to all_macs.txt" |