--- - name: Validate Luanti identity and scalar settings ansible.builtin.assert: that: - luanti_wasm_name is string - luanti_wasm_name is match('^[a-z]([-a-z0-9]*[a-z0-9])?$') - luanti_wasm_name | length <= 53 - luanti_wasm_namespace is string - luanti_wasm_namespace is match('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$') - luanti_wasm_namespace | length <= 53 - luanti_wasm_replicas is integer and luanti_wasm_replicas is not boolean - luanti_wasm_replicas >= 1 - luanti_wasm_game_port is integer and luanti_wasm_game_port is not boolean - luanti_wasm_game_port >= 1 and luanti_wasm_game_port <= 65535 - luanti_wasm_websocket_timeout_seconds is integer and luanti_wasm_websocket_timeout_seconds is not boolean - luanti_wasm_websocket_timeout_seconds > 0 - luanti_wasm_wait_timeout is integer and luanti_wasm_wait_timeout is not boolean - luanti_wasm_wait_timeout > 0 - luanti_wasm_wait is boolean - luanti_wasm_ingress_enabled is boolean - luanti_wasm_tls_enabled is boolean - luanti_wasm_image_pull_policy in ['Always', 'IfNotPresent', 'Never'] - luanti_wasm_tmp_size_limit is string - luanti_wasm_tmp_size_limit is match('^[1-9][0-9]*(Ki|Mi|Gi)$') - luanti_wasm_node_selector is mapping - luanti_wasm_ingress_annotations is mapping fail_msg: Invalid Luanti identity, integer/boolean settings, image pull policy, or tmp size. - name: Validate explicit Luanti image references ansible.builtin.assert: that: - item is string - item | length > 0 - item is match('^(?:[a-z0-9]+(?:[.-][a-z0-9]+)*(?::[0-9]+)?/)?[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)*(?::[A-Za-z0-9_][A-Za-z0-9_.-]{0,127})?(?:@sha256:[a-f0-9]{64})?$') - item is search(':[A-Za-z0-9_][A-Za-z0-9_.-]*$') or item is search('@sha256:[a-f0-9]{64}$') fail_msg: Supply separate web/proxy image references with an explicit tag or sha256 digest. loop: "{{ [luanti_wasm_web_image, luanti_wasm_proxy_image] }}" - name: Validate Luanti list settings ansible.builtin.assert: that: - item is sequence and item is not string and item is not mapping loop: "{{ [luanti_wasm_image_pull_secrets, luanti_wasm_tolerations, luanti_wasm_ingress_peers, luanti_wasm_game_cidrs, luanti_wasm_https_cidrs, luanti_wasm_http_allowed_hosts] }}" - name: Require an explicit game destination ansible.builtin.assert: that: - luanti_wasm_game_cidrs | length > 0 fail_msg: Supply nonempty luanti_wasm_game_cidrs matching the game destination built into the web image. - name: Validate literal Luanti egress CIDRs ansible.builtin.assert: that: - item | luanti_wasm_valid_cidr fail_msg: Egress requires canonical IPv4/IPv6 CIDRs with no host bits, zone IDs, or /0 wildcard. loop: "{{ luanti_wasm_game_cidrs + luanti_wasm_https_cidrs }}" - name: Validate Luanti ingress peers ansible.builtin.assert: that: - item is mapping - item | length > 0 - item.keys() | difference(['namespaceSelector', 'podSelector', 'ipBlock']) | length == 0 - "'namespaceSelector' not in item or item.namespaceSelector is mapping" - "'podSelector' not in item or item.podSelector is mapping" - "'ipBlock' not in item or (item | length == 1 and item.ipBlock | luanti_wasm_valid_ip_block)" loop: "{{ luanti_wasm_ingress_peers }}" - name: Validate Luanti resources ansible.builtin.assert: that: - item is mapping - item.requests is defined - item.limits is defined - item.requests is mapping - item.limits is mapping - item.requests.cpu is defined and item.requests.memory is defined - item.limits.cpu is defined and item.limits.memory is defined loop: "{{ [luanti_wasm_web_resources, luanti_wasm_proxy_resources] }}" - name: Validate pull secret references ansible.builtin.assert: that: - item is mapping - item.name is defined - item.name is string - item.name | length <= 253 - item.name is match('^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$') loop: "{{ luanti_wasm_image_pull_secrets }}" - name: Validate toleration objects ansible.builtin.assert: that: - item is mapping loop: "{{ luanti_wasm_tolerations }}" - name: Validate Luanti annotations ansible.builtin.assert: that: - item.key is string - item.value is string loop: "{{ luanti_wasm_ingress_annotations | dict2items }}" - name: Validate proxy HTTP host allowlist ansible.builtin.assert: that: - item is string - item | length <= 253 - item is match('^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$') fail_msg: HTTP proxy allowlist accepts exact DNS names, not URLs or wildcards. loop: "{{ luanti_wasm_http_allowed_hosts }}" - name: Validate Luanti ingress TLS settings ansible.builtin.assert: that: - luanti_wasm_tls_enabled - luanti_wasm_hostname is string - luanti_wasm_hostname is match('^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$') - luanti_wasm_tls_secret_name is string - luanti_wasm_tls_secret_name | length <= 253 - luanti_wasm_tls_secret_name is match('^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$') - luanti_wasm_ingress_class is string - luanti_wasm_ingress_class | length == 0 or luanti_wasm_ingress_class is match('^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$') - luanti_wasm_cluster_issuer is string - luanti_wasm_cluster_issuer | length <= 253 - luanti_wasm_cluster_issuer | length == 0 or luanti_wasm_cluster_issuer is match('^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$') fail_msg: Ingress requires a valid DNS hostname and TLS secret; TLS cannot be disabled for WASM secure contexts. when: luanti_wasm_ingress_enabled