feat(network): make interfaces[] canonical, normalize flat fields as AWX compat

This commit is contained in:
2026-02-12 22:17:02 +01:00
parent 5108e46a4c
commit 66057bc9b2
17 changed files with 222 additions and 159 deletions

View File

@@ -1,9 +1,4 @@
---
- name: Generate UUID for Network Profile
ansible.builtin.set_fact:
configuration_net_uuid: "{{ ('LAN-' ~ hostname) | ansible.builtin.to_uuid }}"
changed_when: false
- name: Read network interfaces
ansible.builtin.command:
argv:
@@ -15,81 +10,41 @@
changed_when: false
failed_when: false
- name: Resolve network interface and MAC address
- name: Detect available network interface names
vars:
configuration_net_inf_from_facts: "{{ (ansible_default_ipv4 | default({})).get('interface', '') }}"
configuration_net_inf_from_ip: >-
configuration_detected_interfaces: >-
{{
(
configuration_ip_link.stdout
| default('')
| regex_findall('^[0-9]+: ([^:]+):', multiline=True)
| reject('equalto', 'lo')
| list
| first
)
| default('')
}}
configuration_net_inf_detected: >-
{{ configuration_net_inf_from_facts | default(configuration_net_inf_from_ip, true) }}
configuration_net_inf_regex: "{{ configuration_net_inf_detected | ansible.builtin.regex_escape }}"
configuration_net_mac_from_virtualization: "{{ virtualization_mac_address | default('') }}"
configuration_net_mac_from_facts: >-
{{
(
(ansible_facts | default({})).get(configuration_net_inf_detected, {}).get('macaddress', '')
)
| default(
(ansible_facts | default({})).get('ansible_' + configuration_net_inf_detected, {}).get('macaddress', ''),
true
)
}}
configuration_net_mac_from_ip: >-
{{
(
configuration_ip_link.stdout
| default('')
| regex_findall(
'^\\d+: ' ~ configuration_net_inf_regex ~ ':.*?link/ether\\s+([0-9A-Fa-f:]{17})',
multiline=True
)
| first
)
configuration_ip_link.stdout
| default('')
| regex_findall('^[0-9]+: ([^:]+):', multiline=True)
| reject('equalto', 'lo')
| list
}}
ansible.builtin.set_fact:
configuration_net_inf: "{{ configuration_net_inf_detected }}"
configuration_net_mac: >-
{{
(
configuration_net_mac_from_virtualization
| default(configuration_net_mac_from_facts, true)
| default(configuration_net_mac_from_ip, true)
)
| upper
}}
changed_when: false
configuration_detected_interfaces: "{{ configuration_detected_interfaces }}"
- name: Validate Network Interface Name
- name: Validate at least one network interface detected
ansible.builtin.assert:
that:
- configuration_net_inf | length > 0
fail_msg: Failed to detect an active network interface.
- configuration_detected_interfaces | length > 0
fail_msg: Failed to detect any network interfaces.
- name: Validate Network Interface MAC Address
ansible.builtin.assert:
that:
- configuration_net_mac | length > 0
fail_msg: Failed to detect the MAC address for network interface {{ configuration_net_inf }}.
- name: Configure NetworkManager profile
- name: Configure NetworkManager profiles
when: os | lower not in ["alpine", "void"]
block:
- name: Copy NetworkManager keyfile
- name: Copy NetworkManager keyfile per interface
vars:
configuration_iface: "{{ item }}"
configuration_iface_name: "{{ configuration_detected_interfaces[idx] | default('eth' ~ idx) }}"
configuration_net_uuid: "{{ ('LAN-' ~ idx ~ '-' ~ hostname) | ansible.builtin.to_uuid }}"
ansible.builtin.template:
src: network.j2
dest: /mnt/etc/NetworkManager/system-connections/LAN.nmconnection
dest: "/mnt/etc/NetworkManager/system-connections/LAN-{{ idx }}.nmconnection"
mode: "0600"
loop: "{{ system_cfg.network.interfaces }}"
loop_control:
index_var: idx
label: "LAN-{{ idx }}"
- name: Fix Ubuntu unmanaged devices
when: os | lower in ["ubuntu", "ubuntu-lts"]
@@ -102,13 +57,6 @@
when: os | lower == "alpine"
vars:
configuration_dns_list: "{{ system_cfg.network.dns.servers | default([]) }}"
configuration_alpine_static: >-
{{
system_cfg.network.ip is defined
and system_cfg.network.ip | string | length > 0
and system_cfg.network.prefix is defined
and (system_cfg.network.prefix | string | length) > 0
}}
block:
- name: Write Alpine network interfaces
ansible.builtin.copy:
@@ -117,15 +65,19 @@
content: |
auto lo
iface lo inet loopback
{% for iface in system_cfg.network.interfaces %}
{% set iface_name = configuration_detected_interfaces[loop.index0] | default(iface.name | default('eth' ~ loop.index0)) %}
{% set has_static = (iface.ip | default('') | string | length) > 0 %}
auto {{ configuration_net_inf }}
iface {{ configuration_net_inf }} inet {{ 'static' if configuration_alpine_static | bool else 'dhcp' }}
{% if configuration_alpine_static | bool %}
address {{ system_cfg.network.ip }}/{{ system_cfg.network.prefix }}
{% if system_cfg.network.gateway is defined and system_cfg.network.gateway | string | length %}
gateway {{ system_cfg.network.gateway }}
auto {{ iface_name }}
iface {{ iface_name }} inet {{ 'static' if has_static else 'dhcp' }}
{% if has_static %}
address {{ iface.ip }}/{{ iface.prefix }}
{% if iface.gateway | default('') | string | length %}
gateway {{ iface.gateway }}
{% endif %}
{% endif %}
{% endfor %}
- name: Set Alpine DNS resolvers
when: configuration_dns_list | length > 0
@@ -141,25 +93,24 @@
when: os | lower == "void"
vars:
configuration_dns_list: "{{ system_cfg.network.dns.servers | default([]) }}"
configuration_void_static: >-
{{
system_cfg.network.ip is defined
and system_cfg.network.ip | string | length > 0
and system_cfg.network.prefix is defined
and (system_cfg.network.prefix | string | length) > 0
}}
block:
- name: Write dhcpcd configuration for static networking
when: configuration_void_static | bool
- name: Write dhcpcd configuration
ansible.builtin.copy:
dest: /mnt/etc/dhcpcd.conf
mode: "0644"
content: |
interface {{ configuration_net_inf }}
static ip_address={{ system_cfg.network.ip }}/{{ system_cfg.network.prefix }}
{% if system_cfg.network.gateway is defined and system_cfg.network.gateway | string | length %}
static routers={{ system_cfg.network.gateway }}
{% for iface in system_cfg.network.interfaces %}
{% set iface_name = configuration_detected_interfaces[loop.index0] | default(iface.name | default('eth' ~ loop.index0)) %}
{% set has_static = (iface.ip | default('') | string | length) > 0 %}
{% if has_static %}
interface {{ iface_name }}
static ip_address={{ iface.ip }}/{{ iface.prefix }}
{% if iface.gateway | default('') | string | length %}
static routers={{ iface.gateway }}
{% endif %}
{% if configuration_dns_list | length > 0 %}
{% if loop.index0 == 0 and configuration_dns_list | length > 0 %}
static domain_name_servers={{ configuration_dns_list | join(' ') }}
{% endif %}
{% endif %}
{% endfor %}

View File

@@ -18,7 +18,7 @@
changed_when: configuration_user_result.rc == 0
- name: Ensure .ssh directory exists
when: system_cfg.user.key | length > 0
when: system_cfg.user.keys | length > 0
ansible.builtin.file:
path: /mnt/home/{{ system_cfg.user.name }}/.ssh
state: directory
@@ -27,7 +27,7 @@
mode: "0700"
- name: Add SSH public keys to authorized_keys
when: system_cfg.user.key | length > 0
when: system_cfg.user.keys | length > 0
ansible.builtin.lineinfile:
path: /mnt/home/{{ system_cfg.user.name }}/.ssh/authorized_keys
line: "{{ item }}"
@@ -35,4 +35,4 @@
group: 1000
mode: "0600"
create: true
loop: "{{ system_cfg.user.key }}"
loop: "{{ system_cfg.user.keys }}"

View File

@@ -1,24 +1,26 @@
[connection]
id=LAN
id=LAN-{{ idx }}
uuid={{ configuration_net_uuid }}
type=ethernet
interface-name={{ configuration_iface_name }}
[ipv4]
{% set iface = configuration_iface %}
{% set dns_list = system_cfg.network.dns.servers | default([]) %}
{% set search_list = system_cfg.network.dns.search | default([]) %}
{% if system_cfg.network.ip is defined and system_cfg.network.ip | string | length %}
address1={{ system_cfg.network.ip }}/{{ system_cfg.network.prefix }}{{ (',' ~ system_cfg.network.gateway) if (system_cfg.network.gateway is defined and system_cfg.network.gateway | string | length) else '' }}
{% if iface.ip | default('') | string | length %}
address1={{ iface.ip }}/{{ iface.prefix }}{{ (',' ~ iface.gateway) if (iface.gateway | default('') | string | length) else '' }}
method=manual
{% else %}
method=auto
{% endif %}
{% if dns_list %}
{% if idx | int == 0 and dns_list %}
dns={{ dns_list | join(';') }}
{% endif %}
{% if dns_list %}
{% if idx | int == 0 and dns_list %}
ignore-auto-dns=true
{% endif %}
{% if search_list %}
{% if idx | int == 0 and search_list %}
dns-search={{ search_list | join(';') }}
{% endif %}