Files
helm-charts/samba/values.yaml
T
jklein fba03d13f9 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.
2026-10-19 17:57:01 +00:00

210 lines
9.9 KiB
YAML

# Scale the whole chart down without uninstalling it: scaleDown: true renders
# every Deployment/StatefulSet with replicas: 0 (and suspends CronJobs) and
# takes precedence over any per-workload replicas value. PVCs, Secrets and
# Services stay in place; scaleDown: false brings the workloads back up.
scaleDown: false
secrets:
# users.conf is mounted into the samba container from the Secret the 1Password
# operator materializes from this item.
#
# Known limitation (#82): changing the item in the vault does NOT restart
# samba, so added, removed or re-passworded users stay invisible to the
# running smbd. Helm cannot hash the content (it never sees it - the operator
# fills the Secret in-cluster after rendering), so the checksum/config
# mechanism used for smb.conf does not apply here. The operator's own
# "operator.1password.io/auto-restart" annotation is no help either: it only
# ever restarts Deployments, and this workload is a StatefulSet (verified
# against onepassword-operator 1.12.0). After changing the users item,
# restart samba by hand:
# kubectl rollout restart statefulset <release>-samba-sfs
sambaUsersSecretRef: null
samba:
# Replica count for this workload; 0 is allowed and scales it down.
# The chart-global scaleDown flag takes precedence.
replicas: 1
# NodePorts the SMB service is published on (service type NodePort).
smbNodePort: 30445
netbiosNodePort: 30139
shares:
- name: null
validUsers: null
description: null
size: null
# Extra environment variables for the samba container. Values are rendered
# through tpl; value, secretKeyRef and configMapKeyRef forms are supported.
env: []
# SMB is not an HTTP protocol, so probe the main SMB TCP port.
livenessProbe:
tcpSocket:
port: 445
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
tcpSocket:
port: 445
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
# The startup probe gates liveness/readiness. Startup budget = 5s * 30 = 150s.
startupProbe:
tcpSocket:
port: 445
periodSeconds: 5
timeoutSeconds: 5
failureThreshold: 30
resources:
# Limits are optional: memory and ephemeral-storage limits default to
# limitFactor x the request, an explicitly set limit always wins, and a
# CPU limit is only set when configured explicitly under "limits".
limitFactor: 3
requests:
memory: 50Mi
cpu: 0.1
ephemeralStorage: 50Mi
# Deviations from the repo's hardening baseline, forced by the
# ghcr.io/dockur/samba image (its entrypoint samba.sh):
# - no runAsNonRoot: the entrypoint creates the Unix users from users.conf
# (groupadd/adduser/usermod) and smbd impersonates the authenticated
# share user per session, both of which require starting as root.
# - readOnlyRootFilesystem: false: the entrypoint writes to the root
# filesystem at startup (/etc/passwd + /etc/group for user creation,
# the /etc/samba.conf healthcheck symlink, mkdir /shared and the Samba
# TDB databases under /var/lib/samba).
# - capabilities: ALL dropped except what a multi-user root file server
# needs: NET_BIND_SERVICE (ports 445/139), SETUID/SETGID (per-session
# user impersonation), CHOWN/FOWNER/DAC_OVERRIDE (managing share files
# on behalf of the users).
securityContext:
pod:
fsGroup: 1000
container:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
capabilities:
drop:
- ALL
add:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- NET_BIND_SERVICE
- SETGID
- SETUID
storageClass: longhorn
# ---------------------------------------------------------------------------
# NetworkPolicy (Gitea #5). On by default. The reference implementation with
# the full reasoning is template-chart; the convention is in README, "Chart
# style guidelines", and the operator's view on this chart's wiki page.
# ---------------------------------------------------------------------------
networkPolicy:
# THERE IS ONLY ONE VALUE HERE BESIDES enabled, AND THAT IS DELIBERATE.
# Both of this chart's inbound rules are open to any source (see below), so
# neither allowedNamespaces nor probeSources would reach a rule - and a value
# that silently does nothing is worse than a value that is absent: it reads
# as a control. If a source restriction is ever wanted here it needs a rule
# to attach to first.
#
# WHAT THIS POLICY ALLOWS: inbound 445 and 139 - the POD ports - open to any
# source, and outbound nothing but DNS.
#
# BOTH INBOUND RULES ARE OPEN ON PURPOSE. The ports are published as
# NodePorts and the clients are machines on the LAN; after NodePort
# masquerading the source address is a cluster node, so a source selector
# could only be a list of node IPs - a restriction in appearance and a
# maintenance trap in fact. 445 is also the probe port.
#
# AND THE NUMBERS ARE 445 AND 139, NOT samba.smbNodePort AND
# samba.netbiosNodePort. A NetworkPolicy is evaluated at the pod's interface
# after kube-proxy has translated the NodePort, so the NodePort numbers would
# match nothing while looking strict - and would block every client.
#
# Not covered, and it does not matter here: the NetBIOS name-service
# broadcasts on 137/138 UDP are not published by this chart's Service at all,
# and clients reach the share by address rather than by browse list.
enabled: true
# The policy's INBOUND side. Mind the three names that overlap as substrings,
# because a search for "ingress" matches all of them and they are different
# things:
#
# ingress (top level) the Ingress OBJECT this chart
# renders - host, TLS, className
# networkPolicy.ingress this block: what the policy lets IN
# networkPolicy.ingressController the SOURCE SELECTOR for the ingress
# controller's pods. A SIBLING of this block
# and NO PART OF IT, despite the name.
ingress:
# Opens the pod for Istio's ambient mesh (Gitea #143). OFF by default and
# additive: while it is false this chart renders byte for byte as it did
# before the value existed.
#
# It renders 15008/TCP inbound - ztunnel's HBONE tunnel. Every inbound mesh
# connection arrives on it, and ambient "does not and will never bypass
# Kubernetes NetworkPolicy enforcement", so without this port a pod whose
# namespace has joined the mesh is unreachable.
#
# ONE HALF SHORTER THAN ELSEWHERE, deliberately. In other charts 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 has 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. An ipBlock for one would match nothing while making the
# rule look like it did something, which is the kind of strict-looking empty
# rule ci/run-networkpolicy-test.sh exists to catch; that script ties the
# exemption to the absence of probeSources rather than to a chart name.
#
# NOT PROVEN: that 15008 alone is enough comes from Istio's documentation;
# measured on this cluster is only which listeners ztunnel opens, and no
# namespace carries istio.io/dataplane-mode yet.
# 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:
# Additional outbound TCP ports. DNS (UDP and TCP 53) is always allowed and
# has no switch - a knob whose only other setting breaks every name lookup
# in the pod is a trap, not a feature.
#
# PORTS, NOT DESTINATIONS, and that is a limit of the object rather than
# laziness: a NetworkPolicy matches CIDRs and selectors and never hostnames,
# so "only to the database host" cannot be written at all. Each entry
# permits its port to ANY destination. What the cap still buys is real: a
# compromised pod cannot open arbitrary outbound connections.
#
# A domain-joined Samba needs Kerberos (88) and LDAP (389 or 636) here. A
# standalone one needs nothing.
extraPorts: []