fix(global_defaults): validate system.users as the documented dict on both paths

This commit is contained in:
2026-10-05 16:54:28 +02:00
parent 9aad42a4c2
commit 74caca915e
5 changed files with 213 additions and 22 deletions
@@ -8,11 +8,10 @@
that:
- system is mapping
- system.network is not defined or system.network is mapping
- system.users is not defined or system.users is mapping
- system.root is not defined or system.root is mapping
- system.luks is not defined or system.luks is mapping
- system.features is not defined or system.features is mapping
fail_msg: "system and its nested keys (network, root, luks, features, users) must be dictionaries."
fail_msg: "system and its nested keys (network, root, luks, features) must be dictionaries."
quiet: true
- name: Validate DNS lists (not strings)
@@ -24,19 +23,6 @@
fail_msg: "system.network.dns.servers and system.network.dns.search must be lists, not strings."
quiet: true
- name: Validate system.users entries
when: system.users is defined and system.users is mapping and system.users | length > 0
ansible.builtin.assert:
that:
- item.value is mapping
- item.key | string | length > 0
- ('keys' not in item.value) or (item.value['keys'] is iterable and item.value['keys'] is not string)
fail_msg: "Each system.users entry must be a dict keyed by username; 'keys' must be a list."
quiet: true
loop: "{{ system.users | dict2items }}"
loop_control:
label: "{{ item.key }}"
- name: Validate system features input types
when: system.features is defined
loop: "{{ system_defaults.features | dict2items | map(attribute='key') | list }}"
+26 -7
View File
@@ -65,6 +65,27 @@
fail_msg: "Unsupported system.{{ item }} keys: {{ sub_unknown | join(', ') }}"
quiet: true
- name: Validate system.users is a dict keyed by username
ansible.builtin.assert:
that:
- system_cfg.users is mapping
fail_msg: >-
system.users must be a dict keyed by username, e.g. users: {alice: {password: ...,
keys: [...], sudo: true}}. A list of {name: ...} entries is not accepted.
quiet: true
- name: Validate system.users entries
loop: "{{ system_cfg.users | dict2items }}"
loop_control:
label: "{{ item.key }}"
ansible.builtin.assert:
that:
- item.key | string | length > 0
- item.value is mapping
- ('keys' not in item.value) or (item.value['keys'] is iterable and item.value['keys'] is not string)
fail_msg: "system.users.{{ item.key }} must be a dict, and its keys a list of SSH public keys."
quiet: true
- name: Validate system.luks.tpm2 schema
vars:
tpm2_input: >-
@@ -317,7 +338,7 @@
_autologin: "{{ system_cfg.features.desktop.autologin | default(false) }}"
ansible.builtin.assert:
that:
- _autologin is boolean and not _autologin or (_autologin is string and _autologin | length > 0 and _autologin in system_cfg.users | map(attribute='name'))
- _autologin is boolean and not _autologin or (_autologin is string and _autologin | length > 0 and _autologin in system_cfg.users)
fail_msg: >-
desktop.autologin must be false or a username string present in
system.users; got '{{ _autologin }}'. Bool true is not accepted - the
@@ -354,15 +375,13 @@
quiet: true
- name: Validate at least one user with a password is defined
vars:
_pw_users: "{{ system_cfg.users | selectattr('password', 'defined') | map(attribute='password') | map('string') | reject('equalto', '') | list }}"
ansible.builtin.assert:
that:
- system_cfg.users | default([]) | length > 0
- _pw_users | length > 0
fail_msg: "At least one user with a non-empty password must be defined in system.users."
- bootstrap_primary_user | length > 0
fail_msg: >-
At least one user in system.users needs a non-empty password: bootstrap logs in
as the first such user after the reboot.
quiet: true
no_log: true
- name: Validate DNS servers is a list
when: