Files
rustfs/scripts/test_helm_tls_reload.sh
1266d4c270 feat(tls): reload and publish external certificate generations (#8467)
* feat(tls): reload external certificate snapshots coherently

Pin projected certificate generations, validate complete TLS material, coordinate server consumers, and invalidate outbound RPC caches coherently. Add externally managed TLS Secret support and rotation guidance.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* feat(tls): publish server certificates through a fenced admin API

Add opt-in server-leaf publication with dedicated IAM actions, actual TLS
transport checks, immutable generations, durable captured-token CAS and
idempotent receipts. Preserve independent trust and client identity sources
and distinguish visible publication state from the full serving chain.

Validate 64 TLS tests, 41 TLS-runtime tests, the focused IAM policy test,
and eight live local API scenarios including least privilege and restart.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(admin): route certificate handler types through S3 facade

Use the existing admin S3 facade to keep direct s3s imports within the footprint ratchet.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* test(admin): include TLS certificate routes in route matrix

Account for the registered certificate-state GET and certificate publication POST without changing route behavior or weakening matrix assertions.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(tls): reconcile startup trust before skipping reloads

Compare the initialized listener bundle with coherently published outbound material, retain startup trust and client identity when sources disappear, and cover independent startup rotations through real reload passes.

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* refactor(tls): reuse pinned generations and prepared listener state

Co-Authored-By: heihutu <heihutu@gmail.com>
Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(tls): preserve startup trust source requirements

---------

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Co-authored-by: overtrue <anzhengchao@gmail.com>
2026-10-12 08:53:11 +08:00

50 lines
2.8 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
CHART_DIR="$ROOT_DIR/helm/rustfs"
for distributed in false true; do
rendered=$(helm template tls-reload "$CHART_DIR" \
--set secret.allowInsecureDefaults=true \
--set mode.distributed.enabled="$distributed" \
--set mode.standalone.enabled="$([[ "$distributed" == false ]] && echo true || echo false)" \
--set tls.enabled=true --set tls.existingSecret=issued-tls)
workload=$(yq eval 'select(.kind == "Deployment" or .kind == "StatefulSet")' - <<<"$rendered")
mount=$(yq eval '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "tls-material")' - <<<"$workload")
[[ $(yq eval '.mountPath' - <<<"$mount") == /opt/tls ]]
[[ $(yq eval '.readOnly' - <<<"$mount") == true ]]
[[ $(yq eval 'has("subPath")' - <<<"$mount") == false ]]
keys=$(yq eval '.spec.template.spec.volumes[] | select(.name == "tls-material") | .projected.sources[].secret.items[].key' - <<<"$workload")
[[ "$keys" == $'tls.crt\ntls.key' ]]
[[ $(yq eval '.spec.template.spec.containers[0].readinessProbe.httpGet.scheme' - <<<"$workload") == HTTPS ]]
[[ $(yq eval '.spec.template.spec.containers[0].livenessProbe.tcpSocket.port' - <<<"$workload") == 9000 ]]
config=$(yq eval 'select(.kind == "ConfigMap") | .data' - <<<"$rendered")
[[ $(yq eval '.RUSTFS_TLS_RELOAD_ENABLE' - <<<"$config") == 1 ]]
[[ $(yq eval '.RUSTFS_TLS_KEYLOG' - <<<"$config") == 0 ]]
if [[ "$distributed" == true ]]; then
[[ $(yq eval '.RUSTFS_VOLUMES' - <<<"$config") == https://* ]]
fi
mtls=$(helm template tls-reload "$CHART_DIR" --set secret.allowInsecureDefaults=true \
--set mode.distributed.enabled="$distributed" \
--set mode.standalone.enabled="$([[ "$distributed" == false ]] && echo true || echo false)" \
--set mtls.enabled=true)
workload=$(yq eval 'select(.kind == "Deployment" or .kind == "StatefulSet")' - <<<"$mtls")
[[ $(yq eval '.spec.template.spec.volumes[] | select(.name == "tls-material") | .projected.sources | length' - <<<"$workload") == 2 ]]
[[ $(yq eval '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "tls-material") | has("subPath")' - <<<"$workload") == false ]]
[[ $(yq eval '.spec.template.spec.containers[0].livenessProbe.tcpSocket.port' - <<<"$workload") == 9000 ]]
done
if helm template tls-reload "$CHART_DIR" --set secret.allowInsecureDefaults=true \
--set tls.enabled=true --set tls.existingSecret=issued-tls --set mtls.enabled=true >/dev/null 2>&1; then
echo "Public TLS must not silently enable global client authentication" >&2
exit 1
fi
if helm template tls-reload "$CHART_DIR" --set secret.allowInsecureDefaults=true \
--set tls.enabled=true >/dev/null 2>&1; then
echo "Native TLS requires an explicitly configured serving Secret" >&2
exit 1
fi
echo "TLS Secret projection, rotation settings, topology and probes passed"