fix(vars): enforce strict list-only DNS and user.key format for IaC compatibility

This commit is contained in:
2026-02-12 21:50:55 +01:00
parent 673a9b6062
commit 67c320fcc2
4 changed files with 38 additions and 36 deletions

View File

@@ -31,7 +31,7 @@
system_user_input: "{{ (system_input.user | default({})) if (system_input.user is mapping) else {} }}" system_user_input: "{{ (system_input.user | default({})) if (system_input.user is mapping) else {} }}"
system_root_input: "{{ (system_input.root | default({})) if (system_input.root is mapping) else {} }}" system_root_input: "{{ (system_input.root | default({})) if (system_input.root is mapping) else {} }}"
prompt_user_name: "{{ user_name | default(system_user_name | default(''), true) | string }}" prompt_user_name: "{{ user_name | default(system_user_name | default(''), true) | string }}"
prompt_user_key: "{{ user_public_key | default(user_key | default(system_user_key | default(''), true), true) | string }}" prompt_user_key: "{{ user_public_key | default(user_key | default(system_user_key | default(''), true), true) | string | trim }}"
prompt_user_password: "{{ user_password | default(system_user_password | default(''), true) | string }}" prompt_user_password: "{{ user_password | default(system_user_password | default(''), true) | string }}"
prompt_root_password: "{{ root_password | default(system_root_password | default(''), true) | string }}" prompt_root_password: "{{ root_password | default(system_root_password | default(''), true) | string }}"
ansible.builtin.set_fact: ansible.builtin.set_fact:
@@ -45,8 +45,14 @@
(system_user_input.name | default('') | string | length) > 0 (system_user_input.name | default('') | string | length) > 0
) | ternary(system_user_input.name | string, prompt_user_name), ) | ternary(system_user_input.name | string, prompt_user_name),
'key': ( 'key': (
(system_user_input.key | default('') | string | length) > 0 system_user_input.key
) | ternary(system_user_input.key | string, prompt_user_key), if (system_user_input.key is iterable and system_user_input.key is not string and system_user_input.key | length > 0)
else (
[prompt_user_key]
if (prompt_user_key | length > 0)
else []
)
),
'password': ( 'password': (
(system_user_input.password | default('') | string | length) > 0 (system_user_input.password | default('') | string | length) > 0
) | ternary(system_user_input.password | string, prompt_user_password) ) | ternary(system_user_input.password | string, prompt_user_password)
@@ -60,7 +66,6 @@
recursive=True recursive=True
) )
}} }}
changed_when: false
- name: Load global defaults - name: Load global defaults
ansible.builtin.import_role: ansible.builtin.import_role:
@@ -109,7 +114,6 @@
and (ansible_host | default('') | string | length) > 0 and (ansible_host | default('') | string | length) > 0
) )
}} }}
changed_when: false
- name: Reset SSH connection before post-reboot tasks - name: Reset SSH connection before post-reboot tasks
when: when:

View File

@@ -26,12 +26,13 @@
group: 1000 group: 1000
mode: "0700" mode: "0700"
- name: Add SSH public key to authorized_keys - name: Add SSH public keys to authorized_keys
when: system_cfg.user.key | length > 0 when: system_cfg.user.key | length > 0
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /mnt/home/{{ system_cfg.user.name }}/.ssh/authorized_keys path: /mnt/home/{{ system_cfg.user.name }}/.ssh/authorized_keys
line: "{{ system_cfg.user.key }}" line: "{{ item }}"
owner: 1000 owner: 1000
group: 1000 group: 1000
mode: "0600" mode: "0600"
create: true create: true
loop: "{{ system_cfg.user.key }}"

View File

@@ -42,7 +42,7 @@ system_defaults:
user: user:
name: "" name: ""
password: "" password: ""
key: "" key: []
root: root:
password: "" password: ""
luks: luks:

View File

@@ -2,7 +2,7 @@
- name: Ensure system input is a dictionary - name: Ensure system input is a dictionary
ansible.builtin.set_fact: ansible.builtin.set_fact:
system: "{{ system | default({}) }}" system: "{{ system | default({}) }}"
changed_when: false
- name: Validate system input types - name: Validate system input types
ansible.builtin.assert: ansible.builtin.assert:
@@ -16,6 +16,23 @@
fail_msg: "system and its nested keys (network, user, root, luks, features) must be dictionaries." fail_msg: "system and its nested keys (network, user, root, luks, features) must be dictionaries."
quiet: true quiet: true
- name: Validate DNS and user.key are lists (not strings)
when: system.network is defined and system.network.dns is defined
ansible.builtin.assert:
that:
- system.network.dns.servers is not defined or (system.network.dns.servers is iterable and system.network.dns.servers is not string)
- system.network.dns.search is not defined or (system.network.dns.search is iterable and system.network.dns.search is not string)
fail_msg: "system.network.dns.servers and system.network.dns.search must be lists, not strings."
quiet: true
- name: Validate user.key is a list
when: system.user is defined and system.user.key is defined
ansible.builtin.assert:
that:
- system.user.key is iterable and system.user.key is not string
fail_msg: "system.user.key must be a list of SSH public key strings."
quiet: true
- name: Validate system features input types - name: Validate system features input types
when: system.features is defined when: system.features is defined
loop: "{{ system_defaults.features | dict2items | map(attribute='key') | list }}" loop: "{{ system_defaults.features | dict2items | map(attribute='key') | list }}"
@@ -69,28 +86,8 @@
}} }}
gateway: "{{ system_raw.network.gateway | default('') | string }}" gateway: "{{ system_raw.network.gateway | default('') | string }}"
dns: dns:
servers: >- servers: "{{ system_raw.network.dns.servers | default([]) }}"
{{ search: "{{ system_raw.network.dns.search | default([]) }}"
(
system_raw.network.dns.servers
if system_raw.network.dns.servers is iterable and system_raw.network.dns.servers is not string
else (system_raw.network.dns.servers | string).split(',')
)
| map('trim')
| reject('equalto', '')
| list
}}
search: >-
{{
(
system_raw.network.dns.search
if system_raw.network.dns.search is iterable and system_raw.network.dns.search is not string
else (system_raw.network.dns.search | string).split(',')
)
| map('trim')
| reject('equalto', '')
| list
}}
path: "{{ system_raw.path | default('') | string }}" path: "{{ system_raw.path | default('') | string }}"
packages: >- packages: >-
{{ {{
@@ -107,7 +104,7 @@
user: user:
name: "{{ system_raw.user.name | string }}" name: "{{ system_raw.user.name | string }}"
password: "{{ system_raw.user.password | string }}" password: "{{ system_raw.user.password | string }}"
key: "{{ system_raw.user.key | string }}" key: "{{ system_raw.user.key | default([]) }}"
root: root:
password: "{{ system_raw.root.password | string }}" password: "{{ system_raw.root.password | string }}"
luks: luks:
@@ -152,7 +149,7 @@
hostname: "{{ system_name }}" hostname: "{{ system_name }}"
os: "{{ system_os_input if system_os_input | length > 0 else ('archlinux' if system_type == 'physical' else '') }}" os: "{{ system_os_input if system_os_input | length > 0 else ('archlinux' if system_type == 'physical' else '') }}"
os_version: "{{ system_raw.version | default('') | string }}" os_version: "{{ system_raw.version | default('') | string }}"
changed_when: false
- name: Normalize system disks input - name: Normalize system disks input
vars: vars:
@@ -187,7 +184,7 @@
- name: Initialize normalized disk list - name: Initialize normalized disk list
ansible.builtin.set_fact: ansible.builtin.set_fact:
system_disks_cfg: [] system_disks_cfg: []
changed_when: false
- name: Build normalized system disk configuration - name: Build normalized system disk configuration
vars: vars:
@@ -247,7 +244,7 @@
- name: Update system configuration with normalized disks - name: Update system configuration with normalized disks
ansible.builtin.set_fact: ansible.builtin.set_fact:
system_cfg: "{{ system_cfg | combine({'disks': system_disks_cfg}, recursive=True) }}" system_cfg: "{{ system_cfg | combine({'disks': system_disks_cfg}, recursive=True) }}"
changed_when: false
- name: Set install_drive from primary disk - name: Set install_drive from primary disk
when: when:
@@ -255,4 +252,4 @@
- system_disks_cfg[0].device | string | length > 0 - system_disks_cfg[0].device | string | length > 0
ansible.builtin.set_fact: ansible.builtin.set_fact:
install_drive: "{{ system_disks_cfg[0].device }}" install_drive: "{{ system_disks_cfg[0].device }}"
changed_when: false