refactor(samba): ambientMesh becomes an object carrying Istio's two constants

Gitea #143, maintainer's instruction. The HBONE port and the redirected probe
source are ISTIO CONSTANTS, not standards, so they move from template literals
into values with documented defaults - an operator can then correct them when
Istio changes a number, without waiting for a chart release.

One object under one "enabled", so the two halves still cannot be set
separately; two values could drift apart, which is what this design exists to
prevent. Every read is null-safe (#99), so a deleted object or one carrying
only "enabled: true" falls back to the defaults declared here rather than
dereferencing nil - the defect #136 shipped one value away.

Provenance now written on each constant: 15008 is Istio's HBONE port, not
IANA-registered for this and unknown to Kubernetes; 169.254.7.127 is link-local
(RFC 3927, never routed), its IPv6 counterpart carries the same digits plus
1337, and neither the NetworkPolicy API nor the kubelet knows the address -
only Istio's data plane rewrites the probe source onto it. Both read for
ztunnel 1.30.6, and a change in either fails silently.

The exception in ci/run-networkpolicy-test.sh stays pinned to the numbers that
test names, and additionally asserts this chart declares the same defaults -
never "whatever the value says", which would let a mistyped port in through a
configurable field.

No version change: nothing is published yet, the default is still off, and the
render at defaults is byte-identical - re-diffed against origin/main.

No redirectedProbeSources here, in neither values.yaml nor the schema: this
chart offers no networkPolicy.probeSources, so its probe rule is never
source-restricted and no ipBlock is ever rendered. The key would reach no rule
and read as a control that does nothing, which is worse than one that is
absent. ci/run-networkpolicy-test.sh asserts that absence rather than
tolerating it.
This commit is contained in:
jklein committed 2026-10-19 17:57:01 +00:00
1 parent 7e9b1ed08f
commit fba03d13f9
3 files changed
+66 -5

No files matched your search

+22 -3
View File
@@ -53,7 +53,15 @@ selects.
thing as the top-level .Values.ingress (the Ingress object) - both match thing as the top-level .Values.ingress (the Ingress object) - both match
a search for "ingress". */}} a search for "ingress". */}}
{{- $npIngress := $np.ingress | default dict }} {{- $npIngress := $np.ingress | default dict }}
{{- $ambientMesh := $npIngress.ambientMesh }} {{- /* NULL-SAFE ON PURPOSE (#99): ambientMesh is an OBJECT, so every read goes
through a fallback reproducing THIS chart's declared defaults. An
operator who deletes the object, or writes only "enabled: true", must
land on the defaults and not in a nil dereference - #136 shipped exactly
that defect one value away, where the NOTES.txt branch dereferenced
.networkPolicy.egress directly. */}}
{{- $ambient := $npIngress.ambientMesh | default dict }}
{{- $ambientEnabled := $ambient.enabled }}
{{- $ambientPort := $ambient.port | default 15008 }}
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: NetworkPolicy kind: NetworkPolicy
metadata: metadata:
@@ -95,7 +103,7 @@ spec:
port: 445 port: 445
- protocol: TCP - protocol: TCP
port: 139 port: 139
{{- if $ambientMesh }} {{- if $ambientEnabled }}
{{- /* networkPolicy.ingress.ambientMesh (Gitea #143). 15008/TCP is ztunnel's {{- /* networkPolicy.ingress.ambientMesh (Gitea #143). 15008/TCP is ztunnel's
HBONE tunnel, the port every inbound connection arrives on once the HBONE tunnel, the port every inbound connection arrives on once the
namespace carries istio.io/dataplane-mode - ambient "does not and will namespace carries istio.io/dataplane-mode - ambient "does not and will
@@ -118,11 +126,22 @@ spec:
restricted here, and 445 is additionally published as a NodePort. restricted here, and 445 is additionally published as a NodePort.
WHICH RULE IT JOINS: WHICH RULE IT JOINS:
the only rule this policy has, the one carrying 445 and 139. the only rule this policy has, the one carrying 445 and 139.
AN ISTIO CONSTANT, NOT A STANDARD: 15008 is not registered with
IANA for this, no protocol prescribes it, and Kubernetes knows
nothing about it - Istio picked it for HBONE and Istio can change
it. Hence a VALUE with a documented default rather than a literal
here, so an operator can correct it without a chart release. Read
for ztunnel 1.30.6. The exception ci/run-networkpolicy-test.sh
grants is pinned to the number THAT TEST names, plus a check that
this chart declares the same default - never to whatever the value
says, because that would let a mistyped port ride in through a
configurable field (design A of #143).
NOT MEASURED: that 15008 alone suffices comes from Istio's NOT MEASURED: that 15008 alone suffices comes from Istio's
documentation. Measured on this cluster is only which listeners ztunnel documentation. Measured on this cluster is only which listeners ztunnel
opens. Provable at the first namespace to join the mesh; none has. */}} opens. Provable at the first namespace to join the mesh; none has. */}}
- protocol: TCP - protocol: TCP
port: 15008 port: {{ int $ambientPort }}
{{- end }} {{- end }}
egress: egress:
{{- /* {{- /*
+14 -1
View File
@@ -23,8 +23,21 @@
"additionalProperties": false, "additionalProperties": false,
"properties": { "properties": {
"ambientMesh": { "ambientMesh": {
"description": "Opens the pod for Istio's ambient mesh; off by default and additive, so the render is byte-identical while it is false. Renders 15008/TCP inbound - ztunnel's HBONE tunnel, which ambient explicitly does not let bypass NetworkPolicy enforcement - AND, where probeSources is non-empty, 169.254.7.127/32 as an additional probe source, because inside the mesh the kubelet's probes are redirected away from the worker node's address. The two halves are inseparable on purpose: whoever opens 15008 by hand has not added the probe address, and the first narrowed probeSources then drops every probe, so the pod never becomes Ready and the symptom reads as a broken application rather than as a policy. Unproven in operation: that 15008 alone suffices comes from Istio's documentation, and no namespace of this cluster carries istio.io/dataplane-mode yet.", "description": "Opens the pod for Istio's ambient mesh; off by default and additive, so the render is byte-identical while enabled is false. Renders the HBONE port inbound AND, where networkPolicy.probeSources is non-empty, the redirected probe source in the same \"from\" list. The two halves live in one object under one switch on purpose: whoever opens the port by hand has not added the probe address, and the first narrowed probeSources then drops every probe, so the pod never becomes Ready and the symptom reads as a broken application rather than as a policy. Both numbers are ISTIO CONSTANTS rather than standards, which is why they are values with documented defaults and not template literals - a vendor constant can change, and an operator should be able to correct it without waiting for a chart release. Deleting the whole object is safe: every read falls back to the defaults the chart declares. Unproven in operation: that the HBONE port alone suffices comes from Istio's documentation, and no namespace of this cluster carries istio.io/dataplane-mode yet.",
"type": ["object", "null"],
"additionalProperties": false,
"properties": {
"enabled": {
"description": "The switch. Everything else in this object is inert while it is false.",
"type": ["boolean", "null"] "type": ["boolean", "null"]
},
"port": {
"description": "Istio's HBONE port, default 15008. A constant Istio chose, not a standard: not registered with IANA for this, prescribed by no protocol, and unknown to Kubernetes. Read for ztunnel 1.30.6. It is the one ingress port of these charts that is deliberately no containerPort - ztunnel terminates it, not the application - and the exception ci/run-networkpolicy-test.sh grants it is pinned to the number THAT TEST knows, plus an assertion that this chart declares the same default. Not to whatever this value says: a value-driven exception would let a mistyped port ride in through a configurable field.",
"type": ["integer", "null"],
"minimum": 1,
"maximum": 65535
}
}
} }
} }
}, },
+30 -1
View File
@@ -162,7 +162,36 @@ networkPolicy:
# NOT PROVEN: that 15008 alone is enough comes from Istio's documentation; # NOT PROVEN: that 15008 alone is enough comes from Istio's documentation;
# measured on this cluster is only which listeners ztunnel opens, and no # measured on this cluster is only which listeners ztunnel opens, and no
# namespace carries istio.io/dataplane-mode yet. # namespace carries istio.io/dataplane-mode yet.
ambientMesh: false # BOTH NUMBERS BELOW ARE ISTIO CONSTANTS, NOT STANDARDS, and they are values
# rather than template literals for exactly that reason: a vendor constant
# can change, and an operator should be able to correct it without waiting
# for a chart release. Their provenance is written on each one.
#
# DELETING THIS OBJECT IS SAFE. Every read falls back to the defaults
# declared here (#99), so "ambientMesh: null", or an object carrying only
# "enabled: true", renders the documented defaults instead of failing.
ambientMesh:
# The switch. Everything else here is inert while it is false, and the
# chart renders exactly as it did before the object existed.
enabled: false
# ISTIO'S HBONE PORT. A constant Istio chose, not a standard: not
# registered with IANA for this, prescribed by no protocol, and unknown to
# Kubernetes. Read for ztunnel 1.30.6 (measured on this cluster: ztunnel
# opens [::]:15008 as its inbound listener).
#
# If Istio changes it, a pod in the mesh cannot be reached. Change it here
# in all 30 charts AND in the pinned expectation inside
# ci/run-networkpolicy-test.sh - the test is deliberately what forces
# someone to look, because the exception it grants this port is pinned to
# the number IT knows and not to whatever this value says. A value-driven
# exception would let a mistyped port through, which is the hole design A
# of #143 was rejected for.
#
# NOT MEASURED: that this port ALONE suffices comes from Istio's
# documentation. Measured here is only which listeners ztunnel opens, and
# no namespace carries istio.io/dataplane-mode yet.
port: 15008
egress: egress:
# Additional outbound TCP ports. DNS (UDP and TCP 53) is always allowed and # Additional outbound TCP ports. DNS (UDP and TCP 53) is always allowed and