refactor(schema): simplify dict normalization and schema checks
This commit is contained in:
@@ -82,3 +82,12 @@ system_defaults:
|
|||||||
sudo: true
|
sudo: true
|
||||||
chroot:
|
chroot:
|
||||||
tool: "arch-chroot" # arch-chroot|chroot|systemd-nspawn
|
tool: "arch-chroot" # arch-chroot|chroot|systemd-nspawn
|
||||||
|
|
||||||
|
system_disk_defaults:
|
||||||
|
size: 0
|
||||||
|
device: ""
|
||||||
|
mount:
|
||||||
|
path: ""
|
||||||
|
fstype: ""
|
||||||
|
label: ""
|
||||||
|
opts: "defaults"
|
||||||
|
|||||||
@@ -14,9 +14,7 @@
|
|||||||
quiet: true
|
quiet: true
|
||||||
|
|
||||||
- name: Normalize hypervisor configuration
|
- name: Normalize hypervisor configuration
|
||||||
vars:
|
|
||||||
hypervisor_cfg_normalized: "{{ hypervisor_defaults | combine(hypervisor, recursive=True) }}"
|
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
hypervisor_cfg: "{{ hypervisor_cfg_normalized }}"
|
hypervisor_cfg: "{{ hypervisor_defaults | combine(hypervisor, recursive=True) }}"
|
||||||
hypervisor_type: "{{ hypervisor_cfg_normalized.type | string | lower }}"
|
hypervisor_type: "{{ (hypervisor_defaults | combine(hypervisor, recursive=True)).type | string | lower }}"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|||||||
@@ -18,70 +18,82 @@
|
|||||||
system_os_input: "{{ system_raw.os | default('') | string | lower }}"
|
system_os_input: "{{ system_raw.os | default('') | string | lower }}"
|
||||||
system_name: >-
|
system_name: >-
|
||||||
{{
|
{{
|
||||||
system_raw.name | string
|
system_raw.name | string | trim
|
||||||
if (system_raw.name | default('') | string | length) > 0
|
if (system_raw.name | default('') | string | trim | length) > 0
|
||||||
else inventory_hostname
|
else inventory_hostname
|
||||||
}}
|
}}
|
||||||
|
system_dns: >-
|
||||||
system_dns_raw: "{{ system_raw.dns if system_raw.dns is mapping else {} }}"
|
|
||||||
system_dns_servers_input: "{{ system_dns_raw.servers | default([]) }}"
|
|
||||||
system_dns_search_input: "{{ system_dns_raw.search | default([]) }}"
|
|
||||||
|
|
||||||
system_user_raw: "{{ system_raw.user if system_raw.user is mapping else {} }}"
|
|
||||||
system_root_raw: "{{ system_raw.root if system_raw.root is mapping else {} }}"
|
|
||||||
system_luks_raw: "{{ system_raw.luks if system_raw.luks is mapping else {} }}"
|
|
||||||
system_luks_tpm2_raw: "{{ system_luks_raw.tpm2 if system_luks_raw.tpm2 is mapping else {} }}"
|
|
||||||
system_features_raw: "{{ system_raw.features if system_raw.features is mapping else {} }}"
|
|
||||||
|
|
||||||
system_feature_cis_raw: >-
|
|
||||||
{{
|
{{
|
||||||
system_features_raw.cis
|
system_defaults.dns
|
||||||
if system_features_raw.cis is defined and system_features_raw.cis is mapping
|
| combine((system_raw.dns if system_raw.dns is mapping else {}), recursive=True)
|
||||||
else {}
|
|
||||||
}}
|
}}
|
||||||
system_feature_selinux_raw: >-
|
system_user: >-
|
||||||
{{
|
{{
|
||||||
system_features_raw.selinux
|
system_defaults.user
|
||||||
if system_features_raw.selinux is defined and system_features_raw.selinux is mapping
|
| combine((system_raw.user if system_raw.user is mapping else {}), recursive=True)
|
||||||
else {}
|
|
||||||
}}
|
}}
|
||||||
system_feature_firewall_raw: >-
|
system_root: >-
|
||||||
{{
|
{{
|
||||||
system_features_raw.firewall
|
system_defaults.root
|
||||||
if system_features_raw.firewall is defined and system_features_raw.firewall is mapping
|
| combine((system_raw.root if system_raw.root is mapping else {}), recursive=True)
|
||||||
else {}
|
|
||||||
}}
|
}}
|
||||||
system_feature_ssh_raw: >-
|
system_luks: >-
|
||||||
{{
|
{{
|
||||||
system_features_raw.ssh
|
system_defaults.luks
|
||||||
if system_features_raw.ssh is defined and system_features_raw.ssh is mapping
|
| combine((system_raw.luks if system_raw.luks is mapping else {}), recursive=True)
|
||||||
else {}
|
|
||||||
}}
|
}}
|
||||||
system_feature_zstd_raw: >-
|
system_luks_tpm2: >-
|
||||||
{{
|
{{
|
||||||
system_features_raw.zstd
|
system_defaults.luks.tpm2
|
||||||
if system_features_raw.zstd is defined and system_features_raw.zstd is mapping
|
| combine((system_luks.tpm2 if system_luks.tpm2 is mapping else {}), recursive=True)
|
||||||
else {}
|
|
||||||
}}
|
}}
|
||||||
system_feature_swap_raw: >-
|
system_features: >-
|
||||||
{{
|
{{
|
||||||
system_features_raw.swap
|
system_defaults.features
|
||||||
if system_features_raw.swap is defined and system_features_raw.swap is mapping
|
| combine((system_raw.features if system_raw.features is mapping else {}), recursive=True)
|
||||||
else {}
|
|
||||||
}}
|
}}
|
||||||
system_feature_banner_raw: >-
|
system_feature_cis: >-
|
||||||
{{
|
{{
|
||||||
system_features_raw.banner
|
system_defaults.features.cis
|
||||||
if system_features_raw.banner is defined and system_features_raw.banner is mapping
|
| combine((system_features.cis if system_features.cis is mapping else {}), recursive=True)
|
||||||
else {}
|
|
||||||
}}
|
}}
|
||||||
system_feature_chroot_raw: >-
|
system_feature_selinux: >-
|
||||||
{{
|
{{
|
||||||
system_features_raw.chroot
|
system_defaults.features.selinux
|
||||||
if system_features_raw.chroot is defined and system_features_raw.chroot is mapping
|
| combine((system_features.selinux if system_features.selinux is mapping else {}), recursive=True)
|
||||||
else {}
|
|
||||||
}}
|
}}
|
||||||
|
system_feature_firewall: >-
|
||||||
|
{{
|
||||||
|
system_defaults.features.firewall
|
||||||
|
| combine((system_features.firewall if system_features.firewall is mapping else {}), recursive=True)
|
||||||
|
}}
|
||||||
|
system_feature_ssh: >-
|
||||||
|
{{
|
||||||
|
system_defaults.features.ssh
|
||||||
|
| combine((system_features.ssh if system_features.ssh is mapping else {}), recursive=True)
|
||||||
|
}}
|
||||||
|
system_feature_zstd: >-
|
||||||
|
{{
|
||||||
|
system_defaults.features.zstd
|
||||||
|
| combine((system_features.zstd if system_features.zstd is mapping else {}), recursive=True)
|
||||||
|
}}
|
||||||
|
system_feature_swap: >-
|
||||||
|
{{
|
||||||
|
system_defaults.features.swap
|
||||||
|
| combine((system_features.swap if system_features.swap is mapping else {}), recursive=True)
|
||||||
|
}}
|
||||||
|
system_feature_banner: >-
|
||||||
|
{{
|
||||||
|
system_defaults.features.banner
|
||||||
|
| combine((system_features.banner if system_features.banner is mapping else {}), recursive=True)
|
||||||
|
}}
|
||||||
|
system_feature_chroot: >-
|
||||||
|
{{
|
||||||
|
system_defaults.features.chroot
|
||||||
|
| combine((system_features.chroot if system_features.chroot is mapping else {}), recursive=True)
|
||||||
|
}}
|
||||||
|
system_dns_servers_input: "{{ system_dns.servers | default([]) }}"
|
||||||
|
system_dns_search_input: "{{ system_dns.search | default([]) }}"
|
||||||
system_packages_input: "{{ system_raw.packages | default([]) }}"
|
system_packages_input: "{{ system_raw.packages | default([]) }}"
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
system_cfg:
|
system_cfg:
|
||||||
@@ -140,50 +152,50 @@
|
|||||||
}}
|
}}
|
||||||
disks: "{{ system_raw.disks | default([]) }}"
|
disks: "{{ system_raw.disks | default([]) }}"
|
||||||
user:
|
user:
|
||||||
name: "{{ system_user_raw.name | default('') | string }}"
|
name: "{{ system_user.name | string }}"
|
||||||
password: "{{ system_user_raw.password | default('') | string }}"
|
password: "{{ system_user.password | string }}"
|
||||||
key: "{{ system_user_raw.key | default('') | string }}"
|
key: "{{ system_user.key | string }}"
|
||||||
root:
|
root:
|
||||||
password: "{{ system_root_raw.password | default('') | string }}"
|
password: "{{ system_root.password | string }}"
|
||||||
luks:
|
luks:
|
||||||
enabled: "{{ system_luks_raw.enabled | default(system_defaults.luks.enabled) | bool }}"
|
enabled: "{{ system_luks.enabled | bool }}"
|
||||||
passphrase: "{{ system_luks_raw.passphrase | default(system_defaults.luks.passphrase) | string }}"
|
passphrase: "{{ system_luks.passphrase | string }}"
|
||||||
mapper: "{{ system_luks_raw.mapper | default(system_defaults.luks.mapper) | string }}"
|
mapper: "{{ system_luks.mapper | string }}"
|
||||||
auto: "{{ system_luks_raw.auto | default(system_defaults.luks.auto) | bool }}"
|
auto: "{{ system_luks.auto | bool }}"
|
||||||
method: "{{ system_luks_raw.method | default(system_defaults.luks.method) | string | lower }}"
|
method: "{{ system_luks.method | string | lower }}"
|
||||||
tpm2:
|
tpm2:
|
||||||
device: "{{ system_luks_tpm2_raw.device | default(system_defaults.luks.tpm2.device) | string }}"
|
device: "{{ system_luks_tpm2.device | string }}"
|
||||||
pcrs: "{{ system_luks_tpm2_raw.pcrs | default(system_defaults.luks.tpm2.pcrs) | string }}"
|
pcrs: "{{ system_luks_tpm2.pcrs | string }}"
|
||||||
keysize: "{{ system_luks_raw.keysize | default(system_defaults.luks.keysize) | int }}"
|
keysize: "{{ system_luks.keysize | int }}"
|
||||||
options: "{{ system_luks_raw.options | default(system_defaults.luks.options) | string }}"
|
options: "{{ system_luks.options | string }}"
|
||||||
type: "{{ system_luks_raw.type | default(system_defaults.luks.type) | string }}"
|
type: "{{ system_luks.type | string }}"
|
||||||
cipher: "{{ system_luks_raw.cipher | default(system_defaults.luks.cipher) | string }}"
|
cipher: "{{ system_luks.cipher | string }}"
|
||||||
hash: "{{ system_luks_raw.hash | default(system_defaults.luks.hash) | string }}"
|
hash: "{{ system_luks.hash | string }}"
|
||||||
iter: "{{ system_luks_raw.iter | default(system_defaults.luks.iter) | int }}"
|
iter: "{{ system_luks.iter | int }}"
|
||||||
bits: "{{ system_luks_raw.bits | default(system_defaults.luks.bits) | int }}"
|
bits: "{{ system_luks.bits | int }}"
|
||||||
pbkdf: "{{ system_luks_raw.pbkdf | default(system_defaults.luks.pbkdf) | string }}"
|
pbkdf: "{{ system_luks.pbkdf | string }}"
|
||||||
urandom: "{{ system_luks_raw.urandom | default(system_defaults.luks.urandom) | bool }}"
|
urandom: "{{ system_luks.urandom | bool }}"
|
||||||
verify: "{{ system_luks_raw.verify | default(system_defaults.luks.verify) | bool }}"
|
verify: "{{ system_luks.verify | bool }}"
|
||||||
features:
|
features:
|
||||||
cis:
|
cis:
|
||||||
enabled: "{{ system_feature_cis_raw.enabled | default(system_defaults.features.cis.enabled) | bool }}"
|
enabled: "{{ system_feature_cis.enabled | bool }}"
|
||||||
selinux:
|
selinux:
|
||||||
enabled: "{{ system_feature_selinux_raw.enabled | default(system_defaults.features.selinux.enabled) | bool }}"
|
enabled: "{{ system_feature_selinux.enabled | bool }}"
|
||||||
firewall:
|
firewall:
|
||||||
enabled: "{{ system_feature_firewall_raw.enabled | default(system_defaults.features.firewall.enabled) | bool }}"
|
enabled: "{{ system_feature_firewall.enabled | bool }}"
|
||||||
backend: "{{ system_feature_firewall_raw.backend | default(system_defaults.features.firewall.backend) | string | lower }}"
|
backend: "{{ system_feature_firewall.backend | string | lower }}"
|
||||||
toolkit: "{{ system_feature_firewall_raw.toolkit | default(system_defaults.features.firewall.toolkit) | string | lower }}"
|
toolkit: "{{ system_feature_firewall.toolkit | string | lower }}"
|
||||||
ssh:
|
ssh:
|
||||||
enabled: "{{ system_feature_ssh_raw.enabled | default(system_defaults.features.ssh.enabled) | bool }}"
|
enabled: "{{ system_feature_ssh.enabled | bool }}"
|
||||||
zstd:
|
zstd:
|
||||||
enabled: "{{ system_feature_zstd_raw.enabled | default(system_defaults.features.zstd.enabled) | bool }}"
|
enabled: "{{ system_feature_zstd.enabled | bool }}"
|
||||||
swap:
|
swap:
|
||||||
enabled: "{{ system_feature_swap_raw.enabled | default(system_defaults.features.swap.enabled) | bool }}"
|
enabled: "{{ system_feature_swap.enabled | bool }}"
|
||||||
banner:
|
banner:
|
||||||
motd: "{{ system_feature_banner_raw.motd | default(system_defaults.features.banner.motd) | bool }}"
|
motd: "{{ system_feature_banner.motd | bool }}"
|
||||||
sudo: "{{ system_feature_banner_raw.sudo | default(system_defaults.features.banner.sudo) | bool }}"
|
sudo: "{{ system_feature_banner.sudo | bool }}"
|
||||||
chroot:
|
chroot:
|
||||||
tool: "{{ system_feature_chroot_raw.tool | default(system_defaults.features.chroot.tool) | string }}"
|
tool: "{{ system_feature_chroot.tool | string }}"
|
||||||
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 }}"
|
||||||
@@ -192,14 +204,6 @@
|
|||||||
- name: Normalize system disks input
|
- name: Normalize system disks input
|
||||||
vars:
|
vars:
|
||||||
system_disks: "{{ system_cfg.disks | default([]) }}"
|
system_disks: "{{ system_cfg.disks | default([]) }}"
|
||||||
system_disk_defaults:
|
|
||||||
size: 0
|
|
||||||
device: ""
|
|
||||||
mount:
|
|
||||||
path: ""
|
|
||||||
fstype: ""
|
|
||||||
label: ""
|
|
||||||
opts: "defaults"
|
|
||||||
system_disk_letter_map: "abcdefghijklmnopqrstuvwxyz"
|
system_disk_letter_map: "abcdefghijklmnopqrstuvwxyz"
|
||||||
system_disk_device_prefix: >-
|
system_disk_device_prefix: >-
|
||||||
{{
|
{{
|
||||||
|
|||||||
@@ -28,17 +28,7 @@
|
|||||||
|
|
||||||
- name: Validate hypervisor schema
|
- name: Validate hypervisor schema
|
||||||
vars:
|
vars:
|
||||||
hypervisor_allowed_keys:
|
hypervisor_allowed_keys: "{{ hypervisor_defaults | dict2items | map(attribute='key') | list }}"
|
||||||
- type
|
|
||||||
- url
|
|
||||||
- username
|
|
||||||
- password
|
|
||||||
- host
|
|
||||||
- storage
|
|
||||||
- datacenter
|
|
||||||
- cluster
|
|
||||||
- certs
|
|
||||||
- ssh
|
|
||||||
hypervisor_keys: "{{ (hypervisor | default({})) | dict2items | map(attribute='key') | list }}"
|
hypervisor_keys: "{{ (hypervisor | default({})) | dict2items | map(attribute='key') | list }}"
|
||||||
hypervisor_unknown_keys: "{{ hypervisor_keys | difference(hypervisor_allowed_keys) }}"
|
hypervisor_unknown_keys: "{{ hypervisor_keys | difference(hypervisor_allowed_keys) }}"
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
@@ -49,192 +39,129 @@
|
|||||||
|
|
||||||
- name: Validate system schema
|
- name: Validate system schema
|
||||||
vars:
|
vars:
|
||||||
system_allowed_keys:
|
system_allowed_keys: "{{ system_defaults | dict2items | map(attribute='key') | list }}"
|
||||||
- type
|
|
||||||
- os
|
|
||||||
- version
|
|
||||||
- name
|
|
||||||
- id
|
|
||||||
- cpus
|
|
||||||
- memory
|
|
||||||
- balloon
|
|
||||||
- network
|
|
||||||
- vlan
|
|
||||||
- ip
|
|
||||||
- prefix
|
|
||||||
- gateway
|
|
||||||
- dns
|
|
||||||
- path
|
|
||||||
- packages
|
|
||||||
- disks
|
|
||||||
- user
|
|
||||||
- root
|
|
||||||
- luks
|
|
||||||
- features
|
|
||||||
system_keys: "{{ (system | default({})) | dict2items | map(attribute='key') | list }}"
|
system_keys: "{{ (system | default({})) | dict2items | map(attribute='key') | list }}"
|
||||||
system_unknown_keys: "{{ system_keys | difference(system_allowed_keys) }}"
|
system_unknown_keys: "{{ system_keys | difference(system_allowed_keys) }}"
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- system_unknown_keys | length == 0
|
- system_unknown_keys | length == 0
|
||||||
fail_msg: "Unsupported system keys: {{ system_unknown_keys | join(', ') }}"
|
fail_msg: "Unsupported system keys: {{ system_unknown_keys | join(', ') }}."
|
||||||
quiet: true
|
quiet: true
|
||||||
|
|
||||||
- name: Validate nested system schema
|
- name: Validate nested system mappings
|
||||||
|
loop:
|
||||||
|
- dns
|
||||||
|
- user
|
||||||
|
- root
|
||||||
|
- luks
|
||||||
|
- features
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item }}"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system[item] is not defined or system[item] is mapping
|
||||||
|
fail_msg: "system.{{ item }} must be a dictionary."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate system.dns schema
|
||||||
vars:
|
vars:
|
||||||
dns_allowed_keys: [servers, search]
|
dns_allowed_keys: "{{ system_defaults.dns | dict2items | map(attribute='key') | list }}"
|
||||||
user_allowed_keys: [name, password, key]
|
dns_unknown: >-
|
||||||
root_allowed_keys: [password]
|
|
||||||
luks_allowed_keys:
|
|
||||||
- enabled
|
|
||||||
- passphrase
|
|
||||||
- mapper
|
|
||||||
- auto
|
|
||||||
- method
|
|
||||||
- tpm2
|
|
||||||
- keysize
|
|
||||||
- options
|
|
||||||
- type
|
|
||||||
- cipher
|
|
||||||
- hash
|
|
||||||
- iter
|
|
||||||
- bits
|
|
||||||
- pbkdf
|
|
||||||
- urandom
|
|
||||||
- verify
|
|
||||||
features_allowed_keys:
|
|
||||||
- cis
|
|
||||||
- selinux
|
|
||||||
- firewall
|
|
||||||
- ssh
|
|
||||||
- zstd
|
|
||||||
- swap
|
|
||||||
- banner
|
|
||||||
- chroot
|
|
||||||
feature_leaf_allowed:
|
|
||||||
cis: [enabled]
|
|
||||||
selinux: [enabled]
|
|
||||||
firewall: [enabled, backend, toolkit]
|
|
||||||
ssh: [enabled]
|
|
||||||
zstd: [enabled]
|
|
||||||
swap: [enabled]
|
|
||||||
banner: [motd, sudo]
|
|
||||||
chroot: [tool]
|
|
||||||
dns_keys: "{{ (system.dns | default({})) | dict2items | map(attribute='key') | list }}"
|
|
||||||
user_keys: "{{ (system.user | default({})) | dict2items | map(attribute='key') | list }}"
|
|
||||||
root_keys: "{{ (system.root | default({})) | dict2items | map(attribute='key') | list }}"
|
|
||||||
luks_keys: "{{ (system.luks | default({})) | dict2items | map(attribute='key') | list }}"
|
|
||||||
tpm2_keys: >-
|
|
||||||
{{
|
{{
|
||||||
(
|
((system.dns | default({})) | dict2items | map(attribute='key') | list)
|
||||||
(system.luks if (system.luks is defined and system.luks is mapping) else {}).tpm2
|
| difference(dns_allowed_keys)
|
||||||
| default({})
|
|
||||||
) | dict2items | map(attribute='key') | list
|
|
||||||
}}
|
}}
|
||||||
tpm2_allowed_keys: [device, pcrs]
|
|
||||||
features_keys: "{{ (system.features | default({})) | dict2items | map(attribute='key') | list }}"
|
|
||||||
dns_unknown: "{{ dns_keys | difference(dns_allowed_keys) }}"
|
|
||||||
user_unknown: "{{ user_keys | difference(user_allowed_keys) }}"
|
|
||||||
root_unknown: "{{ root_keys | difference(root_allowed_keys) }}"
|
|
||||||
luks_unknown: "{{ luks_keys | difference(luks_allowed_keys) }}"
|
|
||||||
tpm2_unknown: "{{ tpm2_keys | difference(tpm2_allowed_keys) }}"
|
|
||||||
features_unknown: "{{ features_keys | difference(features_allowed_keys) }}"
|
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- system.dns is not defined or system.dns is mapping
|
|
||||||
- system.user is not defined or system.user is mapping
|
|
||||||
- system.root is not defined or system.root is mapping
|
|
||||||
- system.luks is not defined or system.luks is mapping
|
|
||||||
- system.luks is not defined or system.luks.tpm2 is not defined or system.luks.tpm2 is mapping
|
|
||||||
- system.features is not defined or system.features is mapping
|
|
||||||
- dns_unknown | length == 0
|
- dns_unknown | length == 0
|
||||||
- user_unknown | length == 0
|
fail_msg: "Unsupported system.dns keys: {{ dns_unknown | join(', ') }}"
|
||||||
- root_unknown | length == 0
|
|
||||||
- luks_unknown | length == 0
|
|
||||||
- tpm2_unknown | length == 0
|
|
||||||
- features_unknown | length == 0
|
|
||||||
fail_msg: >-
|
|
||||||
Invalid nested system schema.
|
|
||||||
dns_unknown={{ dns_unknown | join(',') }},
|
|
||||||
user_unknown={{ user_unknown | join(',') }},
|
|
||||||
root_unknown={{ root_unknown | join(',') }},
|
|
||||||
luks_unknown={{ luks_unknown | join(',') }},
|
|
||||||
tpm2_unknown={{ tpm2_unknown | join(',') }},
|
|
||||||
features_unknown={{ features_unknown | join(',') }}
|
|
||||||
quiet: true
|
quiet: true
|
||||||
|
|
||||||
- name: Validate feature leaf schemas
|
- name: Validate system.user schema
|
||||||
vars:
|
vars:
|
||||||
system_features: "{{ system.features | default({}) }}"
|
user_allowed_keys: "{{ system_defaults.user | dict2items | map(attribute='key') | list }}"
|
||||||
feature_keys: "{{ system_features | dict2items | map(attribute='key') | list }}"
|
user_unknown: >-
|
||||||
feature_leaf_allowed:
|
{{
|
||||||
cis: [enabled]
|
((system.user | default({})) | dict2items | map(attribute='key') | list)
|
||||||
selinux: [enabled]
|
| difference(user_allowed_keys)
|
||||||
firewall: [enabled, backend, toolkit]
|
}}
|
||||||
ssh: [enabled]
|
|
||||||
zstd: [enabled]
|
|
||||||
swap: [enabled]
|
|
||||||
banner: [motd, sudo]
|
|
||||||
chroot: [tool]
|
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- >-
|
- user_unknown | length == 0
|
||||||
(
|
fail_msg: "Unsupported system.user keys: {{ user_unknown | join(', ') }}"
|
||||||
feature_keys
|
quiet: true
|
||||||
| map('extract', system_features)
|
|
||||||
| select('mapping')
|
- name: Validate system.root schema
|
||||||
| list
|
vars:
|
||||||
| length
|
root_allowed_keys: "{{ system_defaults.root | dict2items | map(attribute='key') | list }}"
|
||||||
)
|
root_unknown: >-
|
||||||
== (feature_keys | length)
|
{{
|
||||||
- >-
|
((system.root | default({})) | dict2items | map(attribute='key') | list)
|
||||||
(
|
| difference(root_allowed_keys)
|
||||||
(
|
}}
|
||||||
system_features.cis | default({})
|
ansible.builtin.assert:
|
||||||
) | dict2items | map(attribute='key') | list | difference(feature_leaf_allowed.cis)
|
that:
|
||||||
) | length == 0
|
- root_unknown | length == 0
|
||||||
- >-
|
fail_msg: "Unsupported system.root keys: {{ root_unknown | join(', ') }}"
|
||||||
(
|
quiet: true
|
||||||
(
|
|
||||||
system_features.selinux | default({})
|
- name: Validate system.luks schema
|
||||||
) | dict2items | map(attribute='key') | list | difference(feature_leaf_allowed.selinux)
|
vars:
|
||||||
) | length == 0
|
luks_allowed_keys: "{{ system_defaults.luks | dict2items | map(attribute='key') | list }}"
|
||||||
- >-
|
luks_unknown: >-
|
||||||
(
|
{{
|
||||||
(
|
((system.luks | default({})) | dict2items | map(attribute='key') | list)
|
||||||
system_features.firewall | default({})
|
| difference(luks_allowed_keys)
|
||||||
) | dict2items | map(attribute='key') | list | difference(feature_leaf_allowed.firewall)
|
}}
|
||||||
) | length == 0
|
ansible.builtin.assert:
|
||||||
- >-
|
that:
|
||||||
(
|
- luks_unknown | length == 0
|
||||||
(
|
fail_msg: "Unsupported system.luks keys: {{ luks_unknown | join(', ') }}"
|
||||||
system_features.ssh | default({})
|
quiet: true
|
||||||
) | dict2items | map(attribute='key') | list | difference(feature_leaf_allowed.ssh)
|
|
||||||
) | length == 0
|
- name: Validate system.luks.tpm2 schema
|
||||||
- >-
|
vars:
|
||||||
(
|
tpm2_input: >-
|
||||||
(
|
{{
|
||||||
system_features.zstd | default({})
|
(system.luks if (system.luks is defined and system.luks is mapping) else {}).tpm2
|
||||||
) | dict2items | map(attribute='key') | list | difference(feature_leaf_allowed.zstd)
|
| default({})
|
||||||
) | length == 0
|
}}
|
||||||
- >-
|
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:
|
||||||
system_features.swap | default({})
|
that:
|
||||||
) | dict2items | map(attribute='key') | list | difference(feature_leaf_allowed.swap)
|
- system.luks is not defined or system.luks.tpm2 is not defined or system.luks.tpm2 is mapping
|
||||||
) | length == 0
|
- tpm2_unknown | length == 0
|
||||||
- >-
|
fail_msg: "Unsupported system.luks.tpm2 keys: {{ tpm2_unknown | join(', ') }}"
|
||||||
(
|
quiet: true
|
||||||
(
|
|
||||||
system_features.banner | default({})
|
- name: Validate system.features schema
|
||||||
) | dict2items | map(attribute='key') | list | difference(feature_leaf_allowed.banner)
|
vars:
|
||||||
) | length == 0
|
features_allowed_keys: "{{ system_defaults.features | dict2items | map(attribute='key') | list }}"
|
||||||
- >-
|
features_unknown: >-
|
||||||
(
|
{{
|
||||||
(
|
((system.features | default({})) | dict2items | map(attribute='key') | list)
|
||||||
system_features.chroot | default({})
|
| difference(features_allowed_keys)
|
||||||
) | dict2items | map(attribute='key') | list | difference(feature_leaf_allowed.chroot)
|
}}
|
||||||
) | length == 0
|
ansible.builtin.assert:
|
||||||
fail_msg: "Invalid system.features schema detected."
|
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 }}"
|
||||||
|
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
|
quiet: true
|
||||||
|
|
||||||
- name: Validate OS and version inputs
|
- name: Validate OS and version inputs
|
||||||
|
|||||||
Reference in New Issue
Block a user