Files
haproxy/deploy/test/ct-test.sh
Scaffolder ea619ba456
All checks were successful
Build and Publish TechDocs (Helm Chart Resource) / build-and-publish-helm-chart (push) Successful in 1m12s
initial commit
Change-Id: If67c32e979b6d03a135072c836ca54ee01c99e66
2026-04-15 16:23:13 +00:00

206 lines
5.7 KiB
Bash
Executable File

#!/bin/bash
#
# Chart-testing (ct) wrapper for local development.
#
# Uses ct to lint and optionally install Helm charts, matching what
# CircleCI runs but locally against a Kind cluster.
#
# Prerequisites:
# - ct (https://github.com/helm/chart-testing)
# - kind (https://kind.sigs.k8s.io/) — only for install tests
# - kubectl, helm
#
# Usage:
# ./test/ct-test.sh # lint all charts
# ./test/ct-test.sh lint # lint all charts
# ./test/ct-test.sh lint haproxy-unified-gateway # lint one chart
# ./test/ct-test.sh install # install all charts (creates Kind cluster)
# ./test/ct-test.sh install haproxy-unified-gateway # install one chart
#
# Options (env vars):
# KIND_CLUSTER_NAME=name Custom cluster name (default: ct-dev)
# KIND_KEEP_CLUSTER=1 Don't delete the Kind cluster after tests
# SKIP_KIND=1 Skip Kind cluster management (use existing kubeconfig)
# CT_ARGS="..." Extra arguments passed to ct (e.g. "--debug")
#
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CT_CONFIG="${SCRIPT_DIR}/ct.yaml"
CT_VERSION="${CT_VERSION:-v3.10.0}"
KIND_CLUSTER_NAME="${KIND_CLUSTER_NAME:-ct-dev}"
KIND_KEEP_CLUSTER="${KIND_KEEP_CLUSTER:-0}"
SKIP_KIND="${SKIP_KIND:-0}"
CT_ARGS="${CT_ARGS:-}"
KIND_CREATED=false
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BOLD='\033[1m'
NC='\033[0m'
# --- prerequisites ---
check_tool() {
if ! command -v "$1" &>/dev/null; then
echo -e "${RED}ERROR:${NC} '$1' not found in PATH" >&2
return 1
fi
}
# --- ct config files ---
# Download chart_schema.yaml and lintconf.yaml from the ct release matching CT_VERSION.
ensure_ct_configs() {
local base_url="https://raw.githubusercontent.com/helm/chart-testing/${CT_VERSION}/etc"
local files=(chart_schema.yaml lintconf.yaml)
for f in "${files[@]}"; do
if [ ! -f "${SCRIPT_DIR}/${f}" ]; then
echo -e "Downloading ${f} (ct ${CT_VERSION})..."
if ! curl -sSfL "${base_url}/${f}" -o "${SCRIPT_DIR}/${f}"; then
echo -e "${RED}ERROR:${NC} failed to download ${f}" >&2
exit 1
fi
fi
done
}
# --- Kind cluster management ---
create_kind_cluster() {
if [ "$SKIP_KIND" = "1" ]; then
echo -e "${YELLOW}SKIP_KIND=1, using existing kubeconfig${NC}"
return
fi
check_tool kind
if kind get clusters 2>/dev/null | grep -q "^${KIND_CLUSTER_NAME}$"; then
echo -e "Kind cluster ${BOLD}${KIND_CLUSTER_NAME}${NC} already exists, reusing"
kubectl cluster-info --context "kind-${KIND_CLUSTER_NAME}" &>/dev/null || {
echo -e "${RED}ERROR:${NC} cluster exists but is not reachable" >&2
exit 1
}
kubectl config use-context "kind-${KIND_CLUSTER_NAME}" &>/dev/null || true
return
fi
echo -e "Creating Kind cluster ${BOLD}${KIND_CLUSTER_NAME}${NC}..."
kind create cluster --name "${KIND_CLUSTER_NAME}" --wait 120s
KIND_CREATED=true
echo -e "${GREEN}Kind cluster created${NC}"
}
delete_kind_cluster() {
if [ "$SKIP_KIND" = "1" ]; then
return
fi
if [ "$KIND_KEEP_CLUSTER" = "1" ]; then
echo -e "\n${YELLOW}KIND_KEEP_CLUSTER=1, keeping cluster '${KIND_CLUSTER_NAME}'${NC}"
echo -e " Delete: kind delete cluster --name ${KIND_CLUSTER_NAME}"
return
fi
if $KIND_CREATED || kind get clusters 2>/dev/null | grep -q "^${KIND_CLUSTER_NAME}$"; then
echo -e "\nDeleting Kind cluster ${BOLD}${KIND_CLUSTER_NAME}${NC}..."
kind delete cluster --name "${KIND_CLUSTER_NAME}"
echo -e "${GREEN}Kind cluster deleted${NC}"
fi
}
# --- ct commands ---
do_lint() {
local chart_arg="$1"
echo -e "\n${BOLD}=== ct lint ===${NC}"
local ct_cmd=(ct lint --config "$CT_CONFIG")
if [ -n "$chart_arg" ]; then
ct_cmd+=(--charts "$REPO_ROOT/$chart_arg")
else
ct_cmd+=(--all)
fi
# shellcheck disable=SC2086
"${ct_cmd[@]}" $CT_ARGS
echo -e "${GREEN}ct lint passed${NC}"
}
do_install() {
local chart_arg="$1"
echo -e "\n${BOLD}=== ct install ===${NC}"
check_tool kubectl
check_tool helm
create_kind_cluster
trap delete_kind_cluster EXIT
# Verify cluster is reachable
if ! kubectl cluster-info &>/dev/null; then
echo -e "${RED}ERROR:${NC} cannot connect to Kubernetes cluster" >&2
exit 1
fi
echo "Cluster: $(kubectl config current-context 2>/dev/null || echo 'unknown')"
local ct_cmd=(ct install --config "$CT_CONFIG")
if [ -n "$chart_arg" ]; then
ct_cmd+=(--charts "$REPO_ROOT/$chart_arg")
else
ct_cmd+=(--all)
fi
# shellcheck disable=SC2086
"${ct_cmd[@]}" $CT_ARGS
echo -e "${GREEN}ct install passed${NC}"
}
# --- main ---
main() {
local mode="${1:-lint}"
local chart="${2:-}"
check_tool ct
check_tool helm
ensure_ct_configs
echo -e "${BOLD}Chart Testing (ct) — local${NC}"
echo "Repo: $REPO_ROOT"
echo "Config: $CT_CONFIG"
echo "ct: $(ct version 2>&1 | head -1)"
echo "Helm: $(helm version --short 2>/dev/null)"
echo "Mode: $mode"
[ -n "$chart" ] && echo "Chart: $chart"
cd "$REPO_ROOT"
case "$mode" in
lint)
do_lint "$chart"
;;
install)
do_install "$chart"
;;
all)
do_lint "$chart"
do_install "$chart"
;;
*)
echo -e "${RED}Unknown mode:${NC} $mode"
echo "Usage: $0 [lint|install|all] [chart-name]"
exit 1
;;
esac
}
main "$@"