feat(global_defaults): validate user input against one argument spec on both paths
This commit is contained in:
@@ -26,111 +26,6 @@
|
||||
fail_msg: "hypervisor.type must be one of: libvirt, proxmox, vmware, xen when system.type=virtual."
|
||||
quiet: true
|
||||
|
||||
- name: Validate hypervisor schema
|
||||
vars:
|
||||
hypervisor_allowed_keys: "{{ hypervisor_defaults | dict2items | map(attribute='key') | list }}"
|
||||
hypervisor_keys: "{{ (hypervisor | default({})) | dict2items | map(attribute='key') | list }}"
|
||||
hypervisor_unknown_keys: "{{ hypervisor_keys | difference(hypervisor_allowed_keys) }}"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- hypervisor_unknown_keys | length == 0
|
||||
fail_msg: "Unsupported hypervisor keys: {{ hypervisor_unknown_keys | join(', ') }}"
|
||||
quiet: true
|
||||
|
||||
- name: Validate system schema
|
||||
vars:
|
||||
system_allowed_keys: "{{ system_defaults | dict2items | map(attribute='key') | list }}"
|
||||
system_keys: "{{ (system | default({})) | dict2items | map(attribute='key') | list }}"
|
||||
system_unknown_keys: "{{ system_keys | difference(system_allowed_keys) }}"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- system_unknown_keys | length == 0
|
||||
fail_msg: "Unsupported system keys: {{ system_unknown_keys | join(', ') }}."
|
||||
quiet: true
|
||||
|
||||
- name: Validate system sub-dict schemas
|
||||
loop:
|
||||
- network
|
||||
- root
|
||||
- luks
|
||||
loop_control:
|
||||
label: "system.{{ item }}"
|
||||
vars:
|
||||
sub_input: "{{ (system[item] | default({})) | dict2items | map(attribute='key') | list }}"
|
||||
sub_allowed: "{{ system_defaults[item] | dict2items | map(attribute='key') | list }}"
|
||||
sub_unknown: "{{ sub_input | difference(sub_allowed) }}"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- sub_unknown | length == 0
|
||||
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: >-
|
||||
{{
|
||||
(system.luks if (system.luks is defined and system.luks is mapping) else {}).tpm2
|
||||
| default({})
|
||||
}}
|
||||
tpm2_allowed_keys: "{{ system_defaults.luks.tpm2 | dict2items | map(attribute='key') | list }}"
|
||||
tpm2_unknown: "{{ (tpm2_input | dict2items | map(attribute='key') | list) | difference(tpm2_allowed_keys) }}"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- system.luks is not defined or system.luks.tpm2 is not defined or system.luks.tpm2 is mapping
|
||||
- tpm2_unknown | length == 0
|
||||
fail_msg: "Unsupported system.luks.tpm2 keys: {{ tpm2_unknown | join(', ') }}"
|
||||
quiet: true
|
||||
|
||||
- name: Validate system.features schema
|
||||
vars:
|
||||
features_allowed_keys: "{{ system_defaults.features | dict2items | map(attribute='key') | list }}"
|
||||
features_unknown: >-
|
||||
{{
|
||||
((system.features | default({})) | dict2items | map(attribute='key') | list)
|
||||
| difference(features_allowed_keys)
|
||||
}}
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- features_unknown | length == 0
|
||||
fail_msg: "Unsupported system.features keys: {{ features_unknown | join(', ') }}"
|
||||
quiet: true
|
||||
|
||||
- name: Validate system.features leaf schemas
|
||||
loop: "{{ system_defaults.features | dict2items | selectattr('value', 'mapping') }}"
|
||||
loop_control:
|
||||
label: "system.features.{{ item.key }}"
|
||||
vars:
|
||||
feature_input: "{{ (system.features | default({}))[item.key] | default({}) }}"
|
||||
feature_allowed_keys: "{{ item.value | dict2items | map(attribute='key') | list }}"
|
||||
feature_unknown: "{{ (feature_input | dict2items | map(attribute='key') | list) | difference(feature_allowed_keys) }}"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- feature_input is mapping
|
||||
- feature_unknown | length == 0
|
||||
fail_msg: "Unsupported system.features.{{ item.key }} keys: {{ feature_unknown | join(', ') }}"
|
||||
quiet: true
|
||||
|
||||
- name: Validate OS and version inputs
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
@@ -383,18 +278,6 @@
|
||||
as the first such user after the reboot.
|
||||
quiet: true
|
||||
|
||||
- name: Validate DNS servers is a list
|
||||
when:
|
||||
- system_cfg.network.dns.servers is defined
|
||||
- system_cfg.network.dns.servers | length > 0
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- system_cfg.network.dns.servers is iterable
|
||||
- system_cfg.network.dns.servers is not string
|
||||
- system_cfg.network.dns.servers is not mapping
|
||||
fail_msg: "system.network.dns.servers must be a list."
|
||||
quiet: true
|
||||
|
||||
- name: Validate all virtual disks have a positive size
|
||||
when: system_cfg.type == "virtual"
|
||||
ansible.builtin.assert:
|
||||
@@ -486,13 +369,10 @@
|
||||
loop_control:
|
||||
label: "{{ item | to_json }}"
|
||||
|
||||
# A string here would iterate into one address per character in every network renderer.
|
||||
- name: Validate network interfaces extra_addresses
|
||||
when: item.extra_addresses is defined
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- item.extra_addresses is not string
|
||||
- item.extra_addresses is iterable
|
||||
- item.ip | default('') | string | length > 0
|
||||
- item.extra_addresses | reject('match', '^(\\d{1,3}\\.){3}\\d{1,3}/\\d{1,2}$') | list | length == 0
|
||||
fail_msg: "system.network.interfaces[].extra_addresses must be a list of IPv4 CIDRs (192.0.2.10/24) on an entry that also sets 'ip'."
|
||||
|
||||
Reference in New Issue
Block a user