Initial commit
This commit is contained in:
Executable
+41
@@ -0,0 +1,41 @@
|
||||
---
|
||||
- name: Validate Luanti configuration before contacting Kubernetes
|
||||
ansible.builtin.import_tasks: validate.yml
|
||||
|
||||
- name: Render Luanti resources before contacting Kubernetes
|
||||
ansible.builtin.import_tasks: render.yml
|
||||
|
||||
- name: Create Luanti namespace
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: "{{ luanti_wasm_namespace }}"
|
||||
|
||||
# Apply isolation before creating any pods. Enforcement requires a capable CNI.
|
||||
- name: Apply mandatory Luanti network policy and configuration
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition: "{{ _luanti_wasm_manifests[item] }}"
|
||||
loop:
|
||||
- networkpolicy
|
||||
- configmap
|
||||
|
||||
- name: Deploy Luanti web and proxy sidecar
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition: "{{ _luanti_wasm_manifests.deployment }}"
|
||||
wait: "{{ luanti_wasm_wait }}"
|
||||
wait_timeout: "{{ luanti_wasm_wait_timeout }}"
|
||||
|
||||
- name: Create Luanti private web service
|
||||
kubernetes.core.k8s:
|
||||
state: present
|
||||
definition: "{{ _luanti_wasm_manifests.service }}"
|
||||
|
||||
- name: Reconcile optional Luanti TLS ingress
|
||||
kubernetes.core.k8s:
|
||||
state: "{{ 'present' if luanti_wasm_ingress_enabled else 'absent' }}"
|
||||
definition: "{{ _luanti_wasm_manifests.ingress }}"
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
---
|
||||
# Also used by the offline regression suite; no Kubernetes API access.
|
||||
- name: Render Luanti Kubernetes resources
|
||||
ansible.builtin.set_fact:
|
||||
_luanti_wasm_manifests:
|
||||
configmap: "{{ lookup('ansible.builtin.template', 'configmap.yml.j2') | from_yaml }}"
|
||||
deployment: "{{ lookup('ansible.builtin.template', 'deployment.yml.j2') | from_yaml }}"
|
||||
service: "{{ lookup('ansible.builtin.template', 'service.yml.j2') | from_yaml }}"
|
||||
networkpolicy: "{{ lookup('ansible.builtin.template', 'networkpolicy.yml.j2') | from_yaml }}"
|
||||
ingress: "{{ lookup('ansible.builtin.template', 'ingress.yml.j2') | from_yaml }}"
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
---
|
||||
- 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 versioned Luanti images
|
||||
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}$')
|
||||
- item is not search('(?i):latest(?:@|$)')
|
||||
fail_msg: Supply separate web/proxy image references with an explicit non-latest 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
|
||||
Reference in New Issue
Block a user