Collect the network's facts and get the list of interfaces. For example,
- setup:
gather_subset: network
- debug:
var: ansible_facts.interfaces
gives
ansible_facts.interfaces:
- lo0
- lo1
- pflog0
- wlan0
Put the declaration below as appropriate
_ifcs: "{{ ansible_facts.interfaces|map('extract', ansible_facts)|list }}"
_macs: "{{ _ifcs|json_query('[].macaddress') }}"
_devs: "{{ _ifcs|json_query('[].device') }}"
_macs_valid: "{{ _macs|map('ansible.utils.hwaddr', 'bool')|
map('ternary', true, false)|list }}"
_dev_mac_valid: "{{ _devs|zip(_macs)|zip(_macs_valid)|
map('flatten')|
selectattr(2) }}"
dev_mac_valid: "{{ _dev_mac_valid|map('zip', ['dev', 'mac', 'valid'])|
map('map', 'reverse')|
map('community.general.dict') }}"
dev_mac: "{{ dev_mac_valid|items2dict(key_name='dev', value_name='mac') }}"
mac_dev: "{{ dev_mac_valid|items2dict(key_name='mac', value_name='dev') }}"
For example, these evaluate to
_macs: [unknown, unknown, unknown, '00:12:00:34:56:78']
_macs_valid: [false, false, false, true]
_devs: [lo0, lo1, pflog0, wlan0]
_dev_mac_valid:
- [wlan0, '00:12:00:34:56:78', true]
dev_mac_valid:
- dev: wlan0
mac: 00:12:00:34:56:78
valid: true
dev_mac:
wlan0: 00:12:00:34:56:78
mac_dev:
00:12:00:34:56:78: wlan0
Q: "Check if the given macaddress match an existing one in the hosts"
A: Use the dictionary mac_dev. For example,
- pause:
prompt: "Enter MAC address"
register: result
- set_fact:
macaddress: "{{ result.user_input }}"
- assert:
that: macaddress|ansible.utils.hwaddr('bool')
fail_msg: Wrong MAC address
- assert:
that: macaddress in mac_dev.keys()|list
fail_msg: "No interfaces found with mac address {{ macaddress }}"
success_msg: "Interfaces {{ mac_dev[macaddress] }} found
with mac address {{ macaddress }}"
If there are more hosts declare a dictionary of all hosts
mac_dev_hosts: "{{ dict(ansible_play_hosts|
zip(ansible_play_hosts|
map('extract', hostvars, 'mac_dev'))) }}"
Then, putting it all together, for example, the playbook
- hosts: test_11,test_12,test_13
gather_facts: false
vars:
_ifcs: "{{ ansible_facts.interfaces|map('extract', ansible_facts)|list }}"
_macs: "{{ _ifcs|json_query('[].macaddress') }}"
_devs: "{{ _ifcs|json_query('[].device') }}"
_macs_valid: "{{ _macs|map('ansible.utils.hwaddr', 'bool')|
map('ternary', true, false)|list }}"
_dev_mac_valid: "{{ _devs|zip(_macs)|zip(_macs_valid)|
map('flatten')|
selectattr(2) }}"
dev_mac_valid: "{{ _dev_mac_valid|map('zip', ['dev', 'mac', 'valid'])|
map('map', 'reverse')|
map('community.general.dict') }}"
dev_mac: "{{ dev_mac_valid|items2dict(key_name='dev', value_name='mac') }}"
mac_dev: "{{ dev_mac_valid|items2dict(key_name='mac', value_name='dev') }}"
mac_dev_hosts: "{{ dict(ansible_play_hosts|
zip(ansible_play_hosts|
map('extract', hostvars, 'mac_dev'))) }}"
tasks:
- setup:
gather_subset: network
- set_fact:
mac_dev: "{{ mac_dev }}"
- block:
- debug:
var: mac_dev_hosts|to_nice_yaml
- pause:
prompt: "Enter MAC address"
register: result
- set_fact:
macaddress: "{{ result.user_input }}"
- assert:
that: macaddress|ansible.utils.hwaddr('bool')
fail_msg: Wrong MAC address
- assert:
that: macaddress in mac_dev_hosts|json_query('*.keys(@)')|flatten
fail_msg: "No interface found with mac address {{ macaddress }}"
- debug:
msg: "Interface {{ dev }} found with mac address {{ macaddress }}
at {{ hst }}"
vars:
itm: "{{ mac_dev_hosts|dict2items|
selectattr('value', 'contains', macaddress)|first }}"
hst: "{{ itm.key }}"
dev: "{{ itm.value[macaddress] }}"
run_once: true
gives
PLAY [test_11,test_12,test_13] ***************************************************************
TASK [setup] *********************************************************************************
ok: [test_13]
ok: [test_12]
ok: [test_11]
TASK [set_fact] ******************************************************************************
ok: [test_13]
ok: [test_11]
ok: [test_12]
TASK [debug] *********************************************************************************
ok: [test_11] =>
mac_dev_hosts|to_nice_yaml: |-
test_11:
00:12:00:34:56:AA: wlan0
test_12:
00:12:00:34:56:BB: wlan0
test_13:
00:12:00:34:56:CC: wlan0
TASK [pause] *********************************************************************************
[pause]
Enter MAC address:
00:12:00:34:56:CC^Mok: [test_11]
TASK [set_fact] ******************************************************************************
ok: [test_11]
TASK [assert] ********************************************************************************
ok: [test_11] => changed=false
msg: All assertions passed
TASK [assert] ********************************************************************************
ok: [test_11] => changed=false
msg: All assertions passed
TASK [debug] *********************************************************************************
ok: [test_11] =>
msg: Interface wlan0 found with mac address 00:12:00:34:56:CC at test_13
PLAY RECAP ***********************************************************************************
test_11: ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_12: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_13: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
If the MAC is missing the play will fail, for example
TASK [assert] ********************************************************************************
fatal: [test_11]: FAILED! => changed=false
assertion: macaddress in mac_dev_hosts|json_query('*.keys(@)')|flatten
evaluated_to: false
msg: No interface found with mac address 00:12:00:34:56:FF