{{- /* NetworkPolicy for valkey (Gitea #5). THIS CHART AND stalwart ARE THE TWO THAT HAD A POLICY BEFORE #5, so the convention was derived from them rather than imposed on them. What changed here is the FORM and not a single rule: the reasoning moved out of "#" comments, which are part of the rendered object and travel into the cluster, into template comments, which render nothing. ci/run-networkpolicy-test.sh now fails on a rendered "#", and this file was one of the two that failed it. TWO THINGS THAT DELIBERATELY DID NOT CHANGE, because they are right and the convention was written to accommodate them: 1. INGRESS ONLY. This instance opens no outbound connection of its own - no replication, no cluster bus - so an egress rule here would constrain nothing while making the object look stricter than it is. policyTypes names only what there is something to restrict. homeassistant and satisfactory invoke the same rule in the other direction, for outbound traffic nobody can enumerate. 2. 6379 IS RESTRICTED BY SOURCE, with no probeSources value anywhere in this chart - and that combination is only safe because of a detail worth knowing: ALL THREE PROBES HERE ARE EXEC PROBES. An exec probe runs inside the container through the kubelet's runtime and puts no packet on the network, so there is no kubelet traffic to let through and nothing to accommodate. A chart with an httpGet or tcpSocket probe on this port could NOT restrict it this way - it would need the worker node's IP, which no chart can know, and the pod would never become Ready without it. minecraft-server is tight for the same reason; every web app in the sweep is not. So this policy is what the rest of the rollout aims at and mostly cannot reach: a port that is genuinely closed to everything but the namespaces named below. */ -}} {{- if .Values.networkPolicy.enabled }} {{- /* networkPolicy.ingress - the policy's INBOUND side, and not the same thing as the top-level .Values.ingress (the Ingress object) - both match a search for "ingress". */}} {{- $npIngress := .Values.networkPolicy.ingress | default dict }} {{- $ambientMesh := $npIngress.ambientMesh }} apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: {{ .Release.Name }}-{{ .Chart.Name }}-networkpolicy labels: app: {{ .Release.Name }}-{{ .Chart.Name }}-networkpolicy spec: podSelector: matchLabels: app: {{ .Release.Name }}-{{ .Chart.Name }}-sfs policyTypes: - Ingress ingress: {{- /* One rule with a list of sources. Note the shape: an empty "from" would allow EVERYTHING, so the namespaces are always spelled out - the release's own namespace first, then whatever networkPolicy.allowedNamespaces adds. An empty "from: []" is worse still, because it allows everything while reading as a restriction; ci/run-networkpolicy-test.sh rejects that form outright. */}} - from: - namespaceSelector: matchLabels: {{- /* Set by Kubernetes itself on every namespace (>= 1.21), so this needs no labelling work on the target namespaces. */}} kubernetes.io/metadata.name: {{ .Release.Namespace }} {{- range .Values.networkPolicy.allowedNamespaces }} - namespaceSelector: matchLabels: kubernetes.io/metadata.name: {{ . | quote }} {{- end }} ports: - protocol: TCP port: 6379 {{- if $ambientMesh }} {{- /* networkPolicy.ingress.ambientMesh (Gitea #143). 15008/TCP is ztunnel's HBONE tunnel, the port every inbound connection arrives on once the namespace carries istio.io/dataplane-mode - ambient "does not and will never bypass Kubernetes NetworkPolicy enforcement", so without it a pod in the mesh is unreachable. It is the one port here that is NOT a containerPort of the selected pod spec: ztunnel terminates it, not the application. ci/run-networkpolicy- test.sh holds a NAMED exception for exactly this number, gated on exactly this value, and proves on a second render that it stays the only such port and that it is absent while the value is false. THE PORT HALF ONLY, and that is not an omission. Elsewhere this switch also adds 169.254.7.127/32 as a probe source, because inside the mesh the kubelet's probes are redirected away from the worker node's address. This chart offers no networkPolicy.probeSources at all, so the rule carrying the probe port is never restricted by source - and an unrestricted rule needs no probe address. Measured in the render: three exec probes, which run inside the container through the kubelet's runtime and put no packet on the network at all. WHICH RULE IT JOINS: the only rule this policy has, the one carrying 6379. That rule is ALWAYS restricted to the release's own namespace plus allowedNamespaces, so 15008 is restricted with it - and whether ztunnel is reached by those peers is the open question of #143. ztunnel runs with its own pod IPs in istio-system (measured 2026-10-19: no hostNetwork on the DaemonSet, Istio 1.30.6), so if a peer of its own proves necessary it is expressible as a namespaceSelector plus podSelector and not as an unknowable node CIDR. It cannot be settled before a namespace joins the mesh, and none has. NOT MEASURED: that 15008 alone suffices comes from Istio's documentation. Measured on this cluster is only which listeners ztunnel opens. Provable at the first namespace to join the mesh; none has. */}} - protocol: TCP port: 15008 {{- end }} {{- end }}