Files
OpenShell/deploy/helm/test-gateway-config-parser.sh
Gaizka MenendezandTaylor Mutch fe3942f2da feat(helm): migrate gateway configuration to gatewayConfig (#3384)
* feat(helm): add generic gateway TOML serializer

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* docs(architecture): define Helm gateway configuration boundary

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* feat(helm): define default gateway configuration map

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* refactor(helm): render gateway config from values map

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* test(helm): cover generic gateway TOML rendering

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* feat(helm): protect gateway config secret boundary

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* docs(helm): classify legacy gateway configuration values

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* refactor(helm): derive dual-use resources from gateway config

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* test(helm): migrate gateway config scenarios

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* refactor(helm): derive credential resources from gateway config

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* refactor(helm): migrate gateway config overlays

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* refactor(helm): remove gateway configuration shadow values

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* refactor(helm): align runtime config with resources

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* docs(helm): add gateway config migration guide

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* test(helm): validate rendered gateway config

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* test(helm): cover config resource coherence

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* fix(helm): make Kubernetes E2E deployable

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* fix(e2e): pass host aliases through gateway config

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* docs(e2e): reference gateway config host alias

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* fix(helm): enforce gateway resource ownership

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* test(e2e): cover chart host gateway input

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* fix(helm): address gateway config review findings

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* fix(helm): repair RFC 0012 migration integration

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* fix(e2e): align Kubernetes parity with RFC 0012

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* fix(helm): complete gateway config migration

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* chore(helm): add SPDX header to TOML template

* fix(helm): preserve legacy gateway configuration aliases

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* fix(helm): complete legacy gateway config compatibility

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* feat(helm): support gateway config arrays of tables

* fix(helm): preserve sandbox identity aliases

* fix(helm): address gateway config review findings

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>

* fix(helm): preserve gateway config migration settings

Signed-off-by: Taylor Mutch <taylormutch@gmail.com>

* test(helm): validate extension arrays in CI values

Signed-off-by: Taylor Mutch <taylormutch@gmail.com>

* fix(helm): restore unconditional SPDX headers

Signed-off-by: Taylor Mutch <taylormutch@gmail.com>

* fix(helm): restore route SPDX header placement

Signed-off-by: Taylor Mutch <taylormutch@gmail.com>

* docs(helm): simplify configuration and migration examples

Signed-off-by: Taylor Mutch <taylormutch@gmail.com>

* docs(helm): remove redundant flag explanations

Signed-off-by: Taylor Mutch <taylormutch@gmail.com>

* docs(helm): move chart configuration guidance to Kubernetes setup

Signed-off-by: Taylor Mutch <taylormutch@gmail.com>

---------

Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Taylor Mutch <taylormutch@gmail.com>
Co-authored-by: Taylor Mutch <taylormutch@gmail.com>
2026-10-08 18:39:59 +00:00

114 lines
4.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Render the chart exactly as an operator would, then validate gateway.toml
# with the gateway binary. Helm unit tests cover template-level assertions;
# this test makes the Rust loader the compatibility authority.
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"
chart="${repo_root}/deploy/helm/openshell"
fixture="${chart}/tests/fixtures/parser-validation-values.yaml"
work_dir="$(mktemp -d)"
trap 'rm -rf "${work_dir}"' EXIT
cargo build --quiet --package openshell-gateway
gateway_bin="${repo_root}/target/debug/openshell-gateway"
render() {
local output="$1"
shift
helm template parser-validation "${chart}" \
--namespace parser-namespace \
--set agentSandbox.preflight.enabled=false \
"$@" >"${output}"
}
extract_toml() {
local manifest="$1"
local toml="$2"
yq ea -e -r \
'select(.kind == "ConfigMap" and (.data | has("gateway.toml"))) | .data."gateway.toml"' \
"${manifest}" >"${toml}"
}
preflight() {
local toml="$1"
"${gateway_bin}" config preflight --path "${toml}"
}
# The runtime default must render and pass the Rust loader validation.
render "${work_dir}/default.yaml"
extract_toml "${work_dir}/default.yaml" "${work_dir}/default.toml"
preflight "${work_dir}/default.toml"
# Exercise all serializer shapes through a raw driver table and prove that
# literal strings, TOML escaping, and null omission survive parsing.
render "${work_dir}/shapes.yaml" --values "${fixture}"
extract_toml "${work_dir}/shapes.yaml" "${work_dir}/shapes.toml"
preflight "${work_dir}/shapes.toml"
grep -F 'rendered_name = "{{ .Release.Namespace }}/{{ .Release.Name }}"' "${work_dir}/shapes.toml" >/dev/null
grep -F 'empty_value = ""' "${work_dir}/shapes.toml" >/dev/null
if grep -Fq 'omitted_value' "${work_dir}/shapes.toml"; then
echo "null gatewayConfig values must be omitted from gateway.toml" >&2
exit 1
fi
# The chart gives absent and empty credential-driver selection deliberately
# different meanings: absent retains encrypted storage, while an empty list is
# invalid before a manifest is rendered.
render "${work_dir}/credential-drivers-absent.yaml" \
--set-json 'gatewayConfig.openshell\.gateway.credential_drivers=null'
extract_toml "${work_dir}/credential-drivers-absent.yaml" "${work_dir}/credential-drivers-absent.toml"
preflight "${work_dir}/credential-drivers-absent.toml"
if grep -Fq 'credential_drivers' "${work_dir}/credential-drivers-absent.toml"; then
echo "null credential_drivers must be absent from gateway.toml" >&2
exit 1
fi
if render "${work_dir}/credential-drivers-empty.yaml" \
--set-json 'gatewayConfig.openshell\.gateway.credential_drivers=[]' >"${work_dir}/credential-drivers-empty.err" 2>&1; then
echo "the chart accepted empty credential_drivers" >&2
exit 1
fi
# Unknown non-secret values are intentionally serializable by Helm, but must
# fail at the Rust schema boundary rather than being silently ignored.
render "${work_dir}/unknown.yaml" \
--set-string 'gatewayConfig.openshell\.gateway.unknown_non_secret=accepted-by-helm'
extract_toml "${work_dir}/unknown.yaml" "${work_dir}/unknown.toml"
if preflight "${work_dir}/unknown.toml" >"${work_dir}/unknown.err" 2>&1; then
echo "the gateway loader accepted an unknown non-secret field" >&2
exit 1
fi
# Secrets remain outside the ConfigMap even when their Secret reference is
# rendered into the workload environment.
render "${work_dir}/secret-boundary.yaml" --set server.externalDbSecret=parser-database
extract_toml "${work_dir}/secret-boundary.yaml" "${work_dir}/secret-boundary.toml"
if grep -Eqi 'parser-database|postgresql:|password' "${work_dir}/secret-boundary.toml"; then
echo "gateway.toml contains Secret-backed database material" >&2
exit 1
fi
# A ConfigMap-only mutation must change the StatefulSet checksum and trigger a
# rollout. Check this against full Helm output, not just a template fragment.
default_checksum="$(yq ea -e -r 'select(.kind == "StatefulSet") | .spec.template.metadata.annotations."checksum/gateway-config"' "${work_dir}/default.yaml")"
render "${work_dir}/checksum.yaml" \
--set-string 'gatewayConfig.openshell\.gateway.log_level=debug'
changed_checksum="$(yq ea -e -r 'select(.kind == "StatefulSet") | .spec.template.metadata.annotations."checksum/gateway-config"' "${work_dir}/checksum.yaml")"
if [[ -z "${default_checksum}" || "${default_checksum}" == "${changed_checksum}" ]]; then
echo "gateway ConfigMap changes must update the StatefulSet checksum" >&2
exit 1
fi
# All maintained CI/dev overlays must render a loader-valid configuration.
for values in "${chart}"/ci/values-*.yaml; do
name="$(basename "${values}" .yaml)"
render "${work_dir}/${name}.yaml" --values "${values}"
extract_toml "${work_dir}/${name}.yaml" "${work_dir}/${name}.toml"
preflight "${work_dir}/${name}.toml"
done
echo "rendered gateway TOML passed Rust loader validation"