initial commit
All checks were successful
Build and Publish TechDocs / build-and-publish (push) Successful in 1m15s
All checks were successful
Build and Publish TechDocs / build-and-publish (push) Successful in 1m15s
Change-Id: I2e2564a72b6be9af536235fc3795fd788fd9257b
This commit is contained in:
67
.circleci/config.yml
Normal file
67
.circleci/config.yml
Normal file
@@ -0,0 +1,67 @@
|
||||
version: 2
|
||||
jobs:
|
||||
lint-scripts:
|
||||
docker:
|
||||
- image: koalaman/shellcheck-alpine
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: |
|
||||
shellcheck -x .circleci/install_charts.sh
|
||||
shellcheck -x .circleci/install_tools.sh
|
||||
shellcheck -x .circleci/release.sh
|
||||
lint-charts:
|
||||
docker:
|
||||
- image: quay.io/helmpack/chart-testing:latest
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: |
|
||||
ct lint --all --validate-maintainers=false --config .circleci/ct.yaml
|
||||
install-charts:
|
||||
machine: true
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
no_output_timeout: 20m
|
||||
command: .circleci/install_charts.sh
|
||||
release-charts:
|
||||
machine: true
|
||||
steps:
|
||||
- checkout
|
||||
- add_ssh_keys:
|
||||
fingerprints:
|
||||
- "7f:84:3b:70:a1:c8:63:8e:dc:5f:51:51:b8:f4:7c:76"
|
||||
- run:
|
||||
command: |
|
||||
echo "export GIT_REPOSITORY_URL=$CIRCLE_REPOSITORY_URL" >> $BASH_ENV
|
||||
echo "export GIT_USERNAME=$CIRCLE_PROJECT_USERNAME" >> $BASH_ENV
|
||||
.circleci/install_tools.sh
|
||||
.circleci/release.sh
|
||||
workflows:
|
||||
version: 2
|
||||
lint-test-release:
|
||||
jobs:
|
||||
- lint-scripts:
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
- lint-charts:
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
- install-charts:
|
||||
requires:
|
||||
- lint-charts
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
- release-charts:
|
||||
requires:
|
||||
- lint-charts
|
||||
- install-charts
|
||||
filters:
|
||||
tags:
|
||||
ignore: /.*/
|
||||
branches:
|
||||
only: main
|
||||
1
.circleci/ct.yaml
Normal file
1
.circleci/ct.yaml
Normal file
@@ -0,0 +1 @@
|
||||
chart-dirs: .
|
||||
126
.circleci/install_charts.sh
Executable file
126
.circleci/install_charts.sh
Executable file
@@ -0,0 +1,126 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
readonly CT_VERSION=latest
|
||||
readonly KIND_VERSION=v0.31.0
|
||||
readonly CLUSTER_NAME=chart-testing
|
||||
readonly REPO_ROOT="${REPO_ROOT:-$(git rev-parse --show-toplevel)}"
|
||||
readonly KEDA_VERSION=2.19.0
|
||||
|
||||
find_latest_tag() {
|
||||
if ! git describe --tags --abbrev=0 2>/dev/null; then
|
||||
git rev-list --max-parents=0 --first-parent HEAD
|
||||
fi
|
||||
}
|
||||
|
||||
create_ct_container() {
|
||||
echo "Starting Chart Testing container"
|
||||
docker run --rm --interactive --detach --network host --name ct \
|
||||
--volume "$(pwd)/.circleci/ct.yaml:/etc/ct/ct.yaml" \
|
||||
--volume "$(pwd):/workdir" \
|
||||
--workdir /workdir \
|
||||
"quay.io/helmpack/chart-testing:${CT_VERSION}" \
|
||||
cat
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
echo "Removing ct container"
|
||||
docker kill ct >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
docker_exec() {
|
||||
docker exec --interactive --tty ct "$@"
|
||||
}
|
||||
|
||||
create_kind_cluster() {
|
||||
echo "Installing kind"
|
||||
curl -sSLo kind "https://github.com/kubernetes-sigs/kind/releases/download/${KIND_VERSION}/kind-linux-amd64"
|
||||
chmod +x kind
|
||||
sudo mv kind /usr/local/bin/kind
|
||||
|
||||
echo "Creating cluster"
|
||||
kind create cluster --name "${CLUSTER_NAME}" --wait 5m -q
|
||||
|
||||
echo "Copying kubeconfig to container"
|
||||
local kubeconfig
|
||||
kubeconfig="$(pwd)/kube-config"
|
||||
kind get kubeconfig --name "${CLUSTER_NAME}" | tee "${kubeconfig}"
|
||||
docker_exec mkdir -p /root/.kube
|
||||
docker cp "${kubeconfig}" ct:/root/.kube/config
|
||||
|
||||
docker_exec kubectl cluster-info
|
||||
docker_exec kubectl get nodes
|
||||
}
|
||||
|
||||
install_local_path_provisioner() {
|
||||
docker_exec kubectl delete storageclass standard
|
||||
docker_exec kubectl apply -f "https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml"
|
||||
}
|
||||
|
||||
install_keda() {
|
||||
docker_exec kubectl apply -f "https://github.com/kedacore/keda/releases/download/v${KEDA_VERSION}/keda-${KEDA_VERSION}-core.yaml" || true
|
||||
}
|
||||
|
||||
install_charts() {
|
||||
docker_exec ct install --all
|
||||
echo
|
||||
}
|
||||
|
||||
main() {
|
||||
pushd "${REPO_ROOT}" >/dev/null
|
||||
|
||||
echo "Fetching tags"
|
||||
git fetch --tags
|
||||
|
||||
local latest_tag
|
||||
latest_tag=$(find_latest_tag)
|
||||
|
||||
local latest_tag_rev
|
||||
latest_tag_rev=$(git rev-parse --verify "${latest_tag}")
|
||||
echo "${latest_tag_rev} ${latest_tag} (latest tag)"
|
||||
|
||||
local head_rev
|
||||
head_rev=$(git rev-parse --verify HEAD)
|
||||
echo "${head_rev} HEAD"
|
||||
|
||||
if [[ "${latest_tag_rev}" == "${head_rev}" ]]; then
|
||||
echo "No code changes. Nothing to release."
|
||||
exit
|
||||
fi
|
||||
|
||||
echo "Identifying changed charts since tag ${latest_tag}"
|
||||
|
||||
local changed_charts=()
|
||||
readarray -t changed_charts <<< "$(git diff --find-renames --name-only "${latest_tag_rev}" | grep '\.yaml$' | cut -d '/' -f 1 | sort -u)"
|
||||
|
||||
if [[ -n "${changed_charts[*]}" ]]; then
|
||||
local changes_pending=no
|
||||
for chart in "${changed_charts[@]}"; do
|
||||
if [[ -f "${chart}/Chart.yaml" ]]; then
|
||||
changes_pending=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${changes_pending}" == "yes" ]]; then
|
||||
create_ct_container
|
||||
trap cleanup EXIT
|
||||
|
||||
create_kind_cluster
|
||||
install_local_path_provisioner
|
||||
install_keda
|
||||
install_charts
|
||||
else
|
||||
echo "Nothing to do. No chart changes detected."
|
||||
fi
|
||||
else
|
||||
echo "Nothing to do. No chart changes detected."
|
||||
fi
|
||||
|
||||
popd >/dev/null
|
||||
}
|
||||
|
||||
main
|
||||
33
.circleci/install_tools.sh
Executable file
33
.circleci/install_tools.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
|
||||
readonly HELM_VERSION=3.19.4
|
||||
readonly CHART_RELEASER_VERSION=1.8.1
|
||||
|
||||
install_helm() {
|
||||
echo "Installing Helm"
|
||||
curl -sSLO "https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz"
|
||||
sudo mkdir -p "/usr/local/helm-v${HELM_VERSION}"
|
||||
sudo tar -xzf "helm-v${HELM_VERSION}-linux-amd64.tar.gz" -C "/usr/local/helm-v${HELM_VERSION}"
|
||||
sudo ln -s "/usr/local/helm-v${HELM_VERSION}/linux-amd64/helm" /usr/local/bin/helm
|
||||
sudo chmod +x /usr/local/helm-v${HELM_VERSION}/linux-amd64/helm
|
||||
rm -f "helm-v${HELM_VERSION}-linux-amd64.tar.gz"
|
||||
}
|
||||
|
||||
install_cr() {
|
||||
echo "Installing Chart Releaser"
|
||||
curl -sSLO "https://github.com/helm/chart-releaser/releases/download/v${CHART_RELEASER_VERSION}/chart-releaser_${CHART_RELEASER_VERSION}_linux_amd64.tar.gz"
|
||||
sudo mkdir -p "/usr/local/chart-releaser-v${CHART_RELEASER_VERSION}"
|
||||
sudo tar -xzf "chart-releaser_${CHART_RELEASER_VERSION}_linux_amd64.tar.gz" -C "/usr/local/chart-releaser-v${CHART_RELEASER_VERSION}"
|
||||
sudo ln -s "/usr/local/chart-releaser-v${CHART_RELEASER_VERSION}/cr" /usr/local/bin/cr
|
||||
sudo chmod +x "/usr/local/chart-releaser-v${CHART_RELEASER_VERSION}/cr"
|
||||
rm -f "chart-releaser_${CHART_RELEASER_VERSION}_linux_amd64.tar.gz"
|
||||
}
|
||||
|
||||
main() {
|
||||
install_helm
|
||||
install_cr
|
||||
}
|
||||
|
||||
main
|
||||
105
.circleci/release.sh
Executable file
105
.circleci/release.sh
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o nounset
|
||||
|
||||
: "${CR_TOKEN:?Environment variable CR_TOKEN must be set}"
|
||||
: "${GIT_REPOSITORY_URL:?Environment variable GIT_REPOSITORY_URL must be set}"
|
||||
: "${GIT_USERNAME:?Environment variable GIT_USERNAME must be set}"
|
||||
: "${GIT_EMAIL:?Environment variable GIT_EMAIL must be set}"
|
||||
|
||||
readonly OWNER=haproxytech
|
||||
readonly GIT_REPO=helm-charts
|
||||
readonly PACKAGE_PATH=.deploy
|
||||
readonly CHARTS_URL=https://haproxytech.github.io/helm-charts
|
||||
readonly REPO_ROOT="${REPO_ROOT:-$(git rev-parse --show-toplevel)}"
|
||||
|
||||
find_latest_tag() {
|
||||
if ! git describe --tags --abbrev=0 2>/dev/null; then
|
||||
git rev-list --max-parents=0 --first-parent HEAD
|
||||
fi
|
||||
}
|
||||
|
||||
package_chart() {
|
||||
local chart="$1"
|
||||
helm dependency build "${chart}"
|
||||
helm package "${chart}" --destination "${PACKAGE_PATH}"
|
||||
}
|
||||
|
||||
release_charts() {
|
||||
echo "Upload Helm chart packages to GitHub"
|
||||
cr upload -o "${OWNER}" -r "${GIT_REPO}" -p "${PACKAGE_PATH}"
|
||||
|
||||
echo "Upload Helm chart packages to GHCR OCI"
|
||||
echo "${HELM_GH_TOKEN}" | helm registry login ghcr.io --username "${OWNER}" --password-stdin
|
||||
|
||||
for chart in "${PACKAGE_PATH}"/*.tgz; do
|
||||
helm push "${chart}" "oci://ghcr.io/${OWNER}/${GIT_REPO}"
|
||||
done
|
||||
}
|
||||
|
||||
update_index() {
|
||||
echo "Generating Helm chart index"
|
||||
git config user.email "${GIT_EMAIL}"
|
||||
git config user.name "${GIT_USERNAME}"
|
||||
git checkout gh-pages
|
||||
|
||||
cr index -i index.yaml -o "${OWNER}" -r "${GIT_REPO}" -c "${CHARTS_URL}" -p "${PACKAGE_PATH}"
|
||||
|
||||
git add index.yaml
|
||||
git commit --message="Update index.yaml" --signoff
|
||||
git push "${GIT_REPOSITORY_URL}" gh-pages
|
||||
}
|
||||
|
||||
main() {
|
||||
pushd "${REPO_ROOT}" >/dev/null || exit 1
|
||||
|
||||
echo "Fetching tags"
|
||||
git fetch --tags
|
||||
|
||||
local latest_tag
|
||||
latest_tag=$(find_latest_tag)
|
||||
|
||||
local latest_tag_rev
|
||||
latest_tag_rev=$(git rev-parse --verify "${latest_tag}")
|
||||
echo "${latest_tag_rev} ${latest_tag} (latest tag)"
|
||||
|
||||
local head_rev
|
||||
head_rev=$(git rev-parse --verify HEAD)
|
||||
echo "${head_rev} HEAD"
|
||||
|
||||
if [[ "${latest_tag_rev}" == "${head_rev}" ]]; then
|
||||
echo "No code changes. Nothing to release."
|
||||
exit
|
||||
fi
|
||||
|
||||
mkdir -p "${PACKAGE_PATH}"
|
||||
|
||||
echo "Identifying changed charts since tag ${latest_tag}"
|
||||
|
||||
local changed_charts=()
|
||||
readarray -t changed_charts <<< "$(git diff --find-renames --name-only "${latest_tag_rev}" | grep 'Chart.yaml$' | cut -d '/' -f 1 | sort -u)"
|
||||
|
||||
if [[ -n "${changed_charts[*]}" ]]; then
|
||||
local release_pending=no
|
||||
for chart in "${changed_charts[@]}"; do
|
||||
if [[ -f "${chart}/Chart.yaml" ]]; then
|
||||
release_pending=yes
|
||||
echo "Packaging chart ${chart}"
|
||||
package_chart "${chart}"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${release_pending}" == "yes" ]]; then
|
||||
release_charts
|
||||
update_index
|
||||
else
|
||||
echo "Nothing to do. No chart changes detected."
|
||||
fi
|
||||
else
|
||||
echo "Nothing to do. No chart changes detected."
|
||||
fi
|
||||
|
||||
popd >/dev/null || exit 1
|
||||
}
|
||||
|
||||
main
|
||||
84
.gitea/workflows/build-push.yml
Normal file
84
.gitea/workflows/build-push.yml
Normal file
@@ -0,0 +1,84 @@
|
||||
name: Build and Push to ACR
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ dev ]
|
||||
workflow_dispatch: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/azure/tokens/azure-identity-token
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and Push
|
||||
runs-on: ubuntu-latest
|
||||
if: >-
|
||||
github.ref != 'refs/heads/main' && (
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(github.event_name == 'push' && github.event.before != '0000000000000000000000000000000000000000')
|
||||
)
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Azure CLI
|
||||
run: |
|
||||
command -v az &>/dev/null || curl -sL https://aka.ms/InstallAzureCLIDeb | bash
|
||||
|
||||
- name: Install Docker CLI
|
||||
run: |
|
||||
command -v docker &>/dev/null || (apt-get update -qq && apt-get install -y docker.io)
|
||||
docker --version
|
||||
|
||||
- name: Azure login (OIDC)
|
||||
run: |
|
||||
az login \
|
||||
--service-principal \
|
||||
--username "$AZURE_CLIENT_ID" \
|
||||
--tenant "$AZURE_TENANT_ID" \
|
||||
--federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)"
|
||||
echo "✓ Azure login successful"
|
||||
|
||||
- name: Get ACR details
|
||||
run: |
|
||||
ACR_NAME=$(az acr list --query "[0].name" -o tsv)
|
||||
ACR_NAME="${ACR_NAME:-bstagecjotdevacr}"
|
||||
echo "ACR_NAME=$ACR_NAME" >> $GITHUB_ENV
|
||||
echo "ACR_LOGIN_SERVER=${ACR_NAME}.azurecr.io" >> $GITHUB_ENV
|
||||
echo "✓ Using ACR: ${ACR_NAME}.azurecr.io"
|
||||
|
||||
- name: ACR Login
|
||||
run: |
|
||||
ACR_TOKEN=$(az acr login --name "$ACR_NAME" --expose-token --output tsv --query accessToken)
|
||||
docker login "$ACR_LOGIN_SERVER" \
|
||||
--username 00000000-0000-0000-0000-000000000000 \
|
||||
--password "$ACR_TOKEN"
|
||||
echo "✓ ACR login successful"
|
||||
|
||||
- name: Build and Push Docker image
|
||||
run: |
|
||||
IMAGE_TAG="${{ gitea.sha }}"
|
||||
IMAGE_FULL="${ACR_LOGIN_SERVER}/haproxy-unified:${IMAGE_TAG}"
|
||||
IMAGE_LATEST="${ACR_LOGIN_SERVER}/haproxy-unified:latest"
|
||||
docker build -t "$IMAGE_FULL" -t "$IMAGE_LATEST" .
|
||||
docker push "$IMAGE_FULL"
|
||||
docker push "$IMAGE_LATEST"
|
||||
echo "IMAGE_FULL=$IMAGE_FULL" >> $GITHUB_ENV
|
||||
echo "✓ Pushed: $IMAGE_FULL"
|
||||
|
||||
- name: Build Summary
|
||||
run: |
|
||||
echo "### ✅ Build Successful" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| | |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|---|---|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| **Service** | haproxy-unified |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| **Commit** | ${{ gitea.sha }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| **Image** | $IMAGE_FULL |" >> $GITHUB_STEP_SUMMARY
|
||||
138
.gitea/workflows/integration-test.yml
Normal file
138
.gitea/workflows/integration-test.yml
Normal file
@@ -0,0 +1,138 @@
|
||||
|
||||
name: Integration Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
workflow_dispatch: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# ── Job 1: Platform Conformance ───────────────────────────────────────────
|
||||
platform-check:
|
||||
name: Platform Conformance
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Validate catalog-info.yaml
|
||||
run: |
|
||||
if [ ! -f catalog-info.yaml ]; then
|
||||
echo "✗ catalog-info.yaml not found"
|
||||
exit 1
|
||||
fi
|
||||
python3 -c "import yaml; list(yaml.safe_load_all(open('catalog-info.yaml')))" 2>/dev/null \
|
||||
|| (pip install pyyaml -q && python3 -c "import yaml; list(yaml.safe_load_all(open('catalog-info.yaml')))")
|
||||
echo "✓ catalog-info.yaml is valid YAML"
|
||||
|
||||
- name: Check platform files
|
||||
run: |
|
||||
ERRORS=0
|
||||
for f in catalog-info.yaml; do
|
||||
if [ ! -f "$f" ]; then
|
||||
echo "✗ Missing: $f"
|
||||
ERRORS=$((ERRORS+1))
|
||||
else
|
||||
echo "✓ Found: $f"
|
||||
fi
|
||||
done
|
||||
if [ $ERRORS -gt 0 ]; then exit 1; fi
|
||||
|
||||
# ── Job 2: Unit Tests + Container Smoke ───────────────────────────────────
|
||||
smoke-test:
|
||||
name: Unit Tests + Container Smoke
|
||||
runs-on: ubuntu-latest
|
||||
needs: platform-check
|
||||
timeout-minutes: 20
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Free disk space
|
||||
run: |
|
||||
docker system prune -f 2>/dev/null || true
|
||||
df -h / 2>/dev/null || true
|
||||
|
||||
- name: Install Docker CLI
|
||||
run: command -v docker &>/dev/null || (apt-get update -qq && apt-get install -y docker.io)
|
||||
|
||||
- name: Build container image
|
||||
run: |
|
||||
if [ -f Dockerfile ]; then
|
||||
docker build -t ci-image:test .
|
||||
else
|
||||
echo "No Dockerfile found — skipping container smoke test"
|
||||
echo "SKIP_SMOKE=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Start service and wait for health
|
||||
if: env.SKIP_SMOKE != 'true'
|
||||
run: |
|
||||
CONTAINER_NAME="ci-${GITHUB_RUN_ID}"
|
||||
PORT="${CONTAINER_PORT:-8080}"
|
||||
HEALTH_PATH="${HEALTH_ENDPOINT:-/health}"
|
||||
echo "CONTAINER_NAME=${CONTAINER_NAME}" >> $GITHUB_ENV
|
||||
echo "CONTAINER_PORT=${PORT}" >> $GITHUB_ENV
|
||||
echo "HEALTH_PATH=${HEALTH_PATH}" >> $GITHUB_ENV
|
||||
|
||||
docker run -d --name "${CONTAINER_NAME}" -e OTEL_SDK_DISABLED=true ci-image:test
|
||||
|
||||
for i in $(seq 1 10); do
|
||||
CONTAINER_IP=$(docker inspect "${CONTAINER_NAME}" --format '{{.NetworkSettings.IPAddress}}' 2>/dev/null)
|
||||
[ -n "${CONTAINER_IP}" ] && break
|
||||
sleep 1
|
||||
done
|
||||
echo "CONTAINER_IP=${CONTAINER_IP}" >> $GITHUB_ENV
|
||||
|
||||
echo "Waiting for ${HEALTH_PATH} on ${CONTAINER_IP}:${PORT} (up to 180s)..."
|
||||
DEADLINE=$(($(date +%s) + 180))
|
||||
while true; do
|
||||
if curl -sf "http://${CONTAINER_IP}:${PORT}${HEALTH_PATH}" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
if [ $(date +%s) -ge $DEADLINE ]; then
|
||||
echo "Timeout waiting for health check"
|
||||
docker logs "${CONTAINER_NAME}" 2>&1 | tail -30
|
||||
exit 1
|
||||
fi
|
||||
if ! docker ps --filter "name=${CONTAINER_NAME}" --format '{{.Status}}' | grep -q Up; then
|
||||
echo "Container exited:"
|
||||
docker logs "${CONTAINER_NAME}" 2>&1 | tail -30
|
||||
exit 1
|
||||
fi
|
||||
echo " still waiting..."; sleep 3
|
||||
done
|
||||
echo "✓ Service healthy at ${CONTAINER_IP}:${PORT}${HEALTH_PATH}"
|
||||
|
||||
- name: Validate health response
|
||||
if: env.SKIP_SMOKE != 'true'
|
||||
run: |
|
||||
curl -sf "http://${CONTAINER_IP}:${CONTAINER_PORT}${HEALTH_PATH}" > /tmp/health.json
|
||||
echo "Health response:"
|
||||
cat /tmp/health.json
|
||||
echo ""
|
||||
echo "✓ Container smoke test: PASSED"
|
||||
|
||||
- name: Cleanup
|
||||
if: always()
|
||||
run: docker rm -f "ci-${GITHUB_RUN_ID}" 2>/dev/null || true
|
||||
|
||||
- name: Post commit status
|
||||
if: always()
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
JOB_STATUS: ${{ job.status }}
|
||||
run: |
|
||||
STATE=$([[ "$JOB_STATUS" == "success" ]] && echo "success" || echo "failure")
|
||||
DESC=$([[ "$STATE" == "success" ]] && echo "All checks passed" || echo "Some checks failed")
|
||||
curl -sf -X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/statuses/${GITHUB_SHA}" \
|
||||
-d "{\"state\":\"${STATE}\",\"context\":\"Integration Test / Unit Tests + Container Smoke (workflow_dispatch)\",\"description\":\"${DESC}\"}" \
|
||||
|| true
|
||||
149
.gitea/workflows/security-scan.yml
Normal file
149
.gitea/workflows/security-scan.yml
Normal file
@@ -0,0 +1,149 @@
|
||||
name: Security Scanning
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
TRIVY_VERSION: "0.51.1"
|
||||
GITLEAKS_VERSION: "8.18.4"
|
||||
COMPONENT_ID: haproxy-unified
|
||||
|
||||
jobs:
|
||||
# ─────────────────────────────────────────────
|
||||
# 1. FILESYSTEM & DEPENDENCY SCAN
|
||||
# Trivy auto-detects lockfiles (pom.xml,
|
||||
# package-lock.json, go.sum, requirements.txt, etc.)
|
||||
# and scans for vulns, secrets, and misconfigs.
|
||||
# ─────────────────────────────────────────────
|
||||
trivy-scan:
|
||||
name: Trivy — Filesystem & Dependency Scan
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Trivy
|
||||
run: |
|
||||
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \
|
||||
| sh -s -- -b /usr/local/bin v
|
||||
|
||||
- name: Run Trivy filesystem scan
|
||||
run: |
|
||||
trivy fs \
|
||||
--exit-code 0 \
|
||||
--severity HIGH,CRITICAL \
|
||||
--format sarif \
|
||||
--output trivy-results.sarif \
|
||||
--scanners vuln,secret,misconfig \
|
||||
--dependency-tree \
|
||||
.
|
||||
|
||||
- name: Upload SARIF report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: trivy-sarif
|
||||
path: trivy-results.sarif
|
||||
retention-days: 30
|
||||
|
||||
- name: Print human-readable summary
|
||||
run: |
|
||||
trivy fs \
|
||||
--exit-code 0 \
|
||||
--severity MEDIUM,HIGH,CRITICAL \
|
||||
--format table \
|
||||
--scanners vuln,secret,misconfig \
|
||||
.
|
||||
|
||||
- name: Enforce quality gate (CRITICAL fails build)
|
||||
run: |
|
||||
trivy fs \
|
||||
--exit-code 1 \
|
||||
--severity CRITICAL \
|
||||
--scanners vuln,misconfig \
|
||||
.
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# 2. SECRET SCAN — detect leaked credentials
|
||||
# across full git history.
|
||||
# ─────────────────────────────────────────────
|
||||
gitleaks-scan:
|
||||
name: Gitleaks — Secret Scan
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout source (full history)
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# Install Gitleaks binary directly — the GitHub Action
|
||||
# relies on GITHUB_TOKEN which is unavailable on Gitea Act runners.
|
||||
- name: Install Gitleaks
|
||||
run: |
|
||||
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v/gitleaks__linux_x64.tar.gz" \
|
||||
| tar -xz -C /usr/local/bin gitleaks
|
||||
|
||||
- name: Run Gitleaks
|
||||
run: |
|
||||
gitleaks detect \
|
||||
--source . \
|
||||
--report-format sarif \
|
||||
--report-path gitleaks-results.sarif \
|
||||
--exit-code 1 \
|
||||
--log-level warn
|
||||
|
||||
- name: Upload SARIF report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: gitleaks-sarif
|
||||
path: gitleaks-results.sarif
|
||||
retention-days: 30
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# 3. SUMMARY — aggregate all SARIF reports
|
||||
# ─────────────────────────────────────────────
|
||||
security-summary:
|
||||
name: Security Summary
|
||||
needs:
|
||||
- trivy-scan
|
||||
- gitleaks-scan
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Download all SARIF artefacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: "*-sarif"
|
||||
merge-multiple: true
|
||||
path: sarif-reports/
|
||||
|
||||
- name: List collected reports
|
||||
run: ls -lh sarif-reports/
|
||||
|
||||
- name: Generate summary
|
||||
run: |
|
||||
echo "## Security Scan Results — " >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Report | Size |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
|
||||
for f in sarif-reports/*.sarif; do
|
||||
name=$(basename "$f")
|
||||
size=$(du -sh "$f" | cut -f1)
|
||||
echo "| $name | $size |" >> $GITHUB_STEP_SUMMARY
|
||||
done
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Commit: \`\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Branch: \`\`" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Bundle all SARIF reports
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: all-sarif-reports
|
||||
path: sarif-reports/
|
||||
retention-days: 90
|
||||
108
.gitea/workflows/techdocs.yml
Normal file
108
.gitea/workflows/techdocs.yml
Normal file
@@ -0,0 +1,108 @@
|
||||
name: Build and Publish TechDocs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "docs/**"
|
||||
- "mkdocs.yml"
|
||||
- "catalog-info.yaml"
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
TECHDOCS_AZURE_BLOB_CONTAINER_NAME:
|
||||
AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/azure/tokens/azure-identity-token
|
||||
AZURE_ACCOUNT_NAME: "bstagecjotdevsttechdocs"
|
||||
ENTITY_NAMESPACE: default
|
||||
ENTITY_KIND: component
|
||||
ENTITY_NAME: haproxy-unified
|
||||
jobs:
|
||||
build-and-publish:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: read and set output
|
||||
id: read_env
|
||||
run: |
|
||||
echo "$AZURE_FEDERATED_TOKEN_FILE"
|
||||
env | grep AZURE
|
||||
echo "$(cat $AZURE_FEDERATED_TOKEN_FILE)"
|
||||
|
||||
# act-based Gitea runners run as root — sudo is not available.
|
||||
# apt-get is called directly; works whether root or not.
|
||||
- name: Bootstrap pip
|
||||
run: |
|
||||
python3 --version
|
||||
if python3 -m pip --version 2>/dev/null; then
|
||||
echo "pip already available"
|
||||
elif python3 -m ensurepip --version 2>/dev/null; then
|
||||
python3 -m ensurepip --upgrade
|
||||
else
|
||||
apt-get update -qq
|
||||
apt-get install -y python3-pip
|
||||
fi
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip --version
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install \
|
||||
mkdocs-techdocs-core==1.* \
|
||||
mkdocs-git-revision-date-localized-plugin \
|
||||
mkdocs-awesome-pages-plugin
|
||||
|
||||
npm install -g @techdocs/cli
|
||||
npm cache clean --force
|
||||
|
||||
# mkdocs has no dry-run flag — build into a temp dir to validate config
|
||||
# and catch any broken links or missing pages early.
|
||||
- name: Validate MkDocs config
|
||||
run: mkdocs build --strict --site-dir /tmp/mkdocs-validate
|
||||
|
||||
- name: Build TechDocs site
|
||||
run: |
|
||||
techdocs-cli generate \
|
||||
--source-dir . \
|
||||
--output-dir ./site \
|
||||
--no-docker \
|
||||
--verbose
|
||||
|
||||
# act runners don't include az by default — install via Microsoft's
|
||||
# official script which works on Debian/Ubuntu without sudo.
|
||||
- name: Install Azure CLI
|
||||
run: |
|
||||
if command -v az &>/dev/null; then
|
||||
echo "Azure CLI already installed: $(az version --query '"azure-cli"' -o tsv)"
|
||||
else
|
||||
curl -sL https://aka.ms/InstallAzureCLIDeb | bash
|
||||
fi
|
||||
|
||||
- name: Azure login (OIDC)
|
||||
run: |
|
||||
az login \
|
||||
--service-principal \
|
||||
--username "$AZURE_CLIENT_ID" \
|
||||
--tenant "$AZURE_TENANT_ID" \
|
||||
--federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)"
|
||||
|
||||
echo "✓ Azure login successful"
|
||||
|
||||
- name: Publish TechDocs site
|
||||
run: |
|
||||
echo "$AZURE_ACCOUNT_NAME"
|
||||
echo "$ENTITY_NAMESPACE"
|
||||
echo "$ENTITY_KIND"
|
||||
echo "$ENTITY_NAME"
|
||||
techdocs-cli publish \
|
||||
--publisher-type azureBlobStorage \
|
||||
--storage-name "techdocs" \
|
||||
--azureAccountName "$AZURE_ACCOUNT_NAME" \
|
||||
--entity "$ENTITY_NAMESPACE/$ENTITY_KIND/$ENTITY_NAME"
|
||||
22
.github/workflows/inactive.yml
vendored
Normal file
22
.github/workflows/inactive.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Close inactive issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
days-before-issue-stale: 30
|
||||
days-before-issue-close: 30
|
||||
stale-issue-label: "stale"
|
||||
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
|
||||
close-issue-message: "This issue was closed because it has been inactive for 30 days since being marked as stale."
|
||||
days-before-pr-stale: -1
|
||||
days-before-pr-close: -1
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
34
.gitignore
vendored
Normal file
34
.gitignore
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# General files
|
||||
*.tgz
|
||||
.project
|
||||
.deploy
|
||||
|
||||
# MacOS
|
||||
._*
|
||||
.DS_Store
|
||||
|
||||
# JetBrains
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
# VSC
|
||||
.vscode
|
||||
|
||||
# Emacs
|
||||
*~
|
||||
\#*\#
|
||||
.\#*
|
||||
|
||||
# Vim
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
*.un~
|
||||
Session.vim
|
||||
.netrwhist
|
||||
|
||||
# ct config files (auto-downloaded by test/ct-test.sh)
|
||||
test/chart_schema.yaml
|
||||
test/lintconf.yaml
|
||||
|
||||
# TODO
|
||||
TODO
|
||||
254
CLAUDE.md
Normal file
254
CLAUDE.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Commands
|
||||
|
||||
### Linting and Template Validation (no cluster needed)
|
||||
|
||||
```bash
|
||||
# Test all charts
|
||||
./test/local-test.sh
|
||||
|
||||
# Test a single chart
|
||||
./test/local-test.sh haproxy-unified-gateway
|
||||
./test/local-test.sh kubernetes-ingress
|
||||
|
||||
# Helm lint a chart directly
|
||||
helm lint kubernetes-ingress/
|
||||
helm lint haproxy-unified-gateway/ -f haproxy-unified-gateway/ci/deployment-default-values.yaml
|
||||
|
||||
# Render templates to stdout
|
||||
helm template test-release kubernetes-ingress/
|
||||
helm template test-release haproxy-unified-gateway/ --set controller.kind=DaemonSet
|
||||
helm template test-release haproxy-unified-gateway/ --api-versions monitoring.coreos.com/v1
|
||||
```
|
||||
|
||||
### Chart-testing (ct) — matches CircleCI
|
||||
|
||||
```bash
|
||||
# Lint all charts
|
||||
./test/ct-test.sh lint
|
||||
|
||||
# Lint a single chart
|
||||
./test/ct-test.sh lint haproxy-unified-gateway
|
||||
|
||||
# Install (creates a Kind cluster automatically)
|
||||
./test/ct-test.sh install haproxy-unified-gateway
|
||||
|
||||
# Keep the Kind cluster after install tests
|
||||
KIND_KEEP_CLUSTER=1 ./test/ct-test.sh install
|
||||
```
|
||||
|
||||
### Integration Tests (real Kind cluster)
|
||||
|
||||
```bash
|
||||
# Test all charts
|
||||
./test/integration-test.sh
|
||||
|
||||
# Test a single chart
|
||||
./test/integration-test.sh haproxy-unified-gateway
|
||||
|
||||
# Run a specific test scenario (defaults, daemonset, hpa, pdb, metrics-port, monitoring, hugconf-cleanup, ci)
|
||||
TEST_FILTER=monitoring ./test/integration-test.sh haproxy-unified-gateway
|
||||
|
||||
# Keep namespaces after failure for debugging
|
||||
KEEP_NS=1 ./test/integration-test.sh
|
||||
```
|
||||
|
||||
## Contribution Requirements
|
||||
|
||||
- All commits require a `Signed-off-by` line (DCO): `git commit -s -m "message"`
|
||||
- Any change to a chart requires a chart **version bump** in `Chart.yaml` following semver
|
||||
- Submit changes to multiple charts in **separate PRs**
|
||||
|
||||
## Project Structure
|
||||
|
||||
This repo contains Helm charts for HAProxy products:
|
||||
|
||||
- `kubernetes-ingress/` - HAProxy Kubernetes Ingress Controller chart (mature, feature-rich)
|
||||
- `haproxy/` - HAProxy community chart
|
||||
- `haproxy-unified-gateway/` - HAProxy Unified Gateway (HUG) chart
|
||||
|
||||
## kubernetes-ingress Chart
|
||||
|
||||
- **Chart version**: follows its own semver (currently 1.49.x)
|
||||
- **Image**: `haproxytech/kubernetes-ingress`
|
||||
- **Supports**: Deployment + DaemonSet modes, IngressClass, Gateway API, HPA, KEDA, ServiceMonitor/PodMonitor, PDB, proxy service (fetch sync mode), ConfigMap-based HAProxy config, publish-service, default TLS cert generation
|
||||
- **Templates**: 25 files in `templates/`
|
||||
- **CI tests**: 38 test value files in `ci/`
|
||||
- **Kubernetes**: >=1.23
|
||||
- **Maintainer**: Dinko Korunic
|
||||
|
||||
## haproxy-unified-gateway Chart
|
||||
|
||||
- **Chart version**: 0.1.0 (appVersion 0.9.1)
|
||||
- **Image**: `haproxytech/haproxy-unified-gateway`
|
||||
- **Purpose**: Kubernetes Gateway API controller powered by HAProxy
|
||||
- **Kubernetes**: >=1.26
|
||||
- **Binary**: `/usr/local/sbin/hug` inside the container
|
||||
- **Entry point**: `/start.sh`
|
||||
- **Key flag**: `--hugconf-crd=<namespace>/<name>` for HugConf CRD reference
|
||||
|
||||
### Templates
|
||||
|
||||
| Template | Purpose |
|
||||
|---|---|
|
||||
| `_helpers.tpl` | Name, labels, image, serviceAccount, hugconfCrd, serviceMonitorName, podMonitorName helpers |
|
||||
| `controller-deployment.yaml` | Deployment (when controller.kind=Deployment) |
|
||||
| `controller-daemonset.yaml` | DaemonSet with hostNetwork/hostPort support (when controller.kind=DaemonSet) |
|
||||
| `controller-service.yaml` | NodePort Service (HTTP 31080, HTTPS 31443, Stats 31024) |
|
||||
| `controller-serviceaccount.yaml` | ServiceAccount |
|
||||
| `clusterrole.yaml` | RBAC: Gateway API resources, HUG CRDs (gate.v3.haproxy.org incl. globals/defaults), core K8s resources, auth/authz for kube-rbac metrics |
|
||||
| `clusterrolebinding.yaml` | ClusterRoleBinding |
|
||||
| `controller-hugconf.yaml` | HugConf CR (logging, globalRef, defaultsRef configuration) — post-install hook (weight 5) |
|
||||
| `controller-hugconf-cleanup.yaml` | Pre-delete hook Job that deletes the HugConf CR on `helm uninstall` |
|
||||
| `controller-crdjob.yaml` | Helm hook Job: installs HUG CRDs (`--job-check-crd`) — post-install hook (weight 0) |
|
||||
| `controller-crdjob-rbac.yaml` | SA + ClusterRole + Binding for CRD/GWAPI jobs |
|
||||
| `controller-gwapijob.yaml` | Helm hook Job: installs Gateway API CRDs (`--job-gwapi=VERSION`) |
|
||||
| `controller-hpa.yaml` | HPA (disabled by default, mutually exclusive with KEDA) |
|
||||
| `controller-keda.yaml` | KEDA ScaledObject (disabled by default, Deployment only) |
|
||||
| `controller-servicemonitor.yaml` | ServiceMonitor for Prometheus Operator (disabled by default, gated behind `.Capabilities.APIVersions`) |
|
||||
| `controller-podmonitor.yaml` | PodMonitor for Prometheus Operator (disabled by default, gated behind `.Capabilities.APIVersions`) |
|
||||
| `controller-service-metrics.yaml` | ClusterIP metrics Service with stat + metrics ports (created when serviceMonitor is enabled) |
|
||||
| `controller-poddisruptionbudget.yaml` | PDB (disabled by default) |
|
||||
| `controller-podsecuritypolicy.yaml` | PSP (disabled by default, K8s <1.25 only) |
|
||||
| `controller-role.yaml` | Role for PSP usage |
|
||||
| `controller-rolebinding.yaml` | RoleBinding for PSP Role |
|
||||
| `namespace.yaml` | Optional namespace creation (pre-install hook) |
|
||||
| `NOTES.txt` | Post-install instructions |
|
||||
|
||||
### Values Structure
|
||||
|
||||
- `rbac.create` - RBAC resources
|
||||
- `namespace.create` - optional namespace
|
||||
- `serviceAccount` - create, name, annotations
|
||||
- `controller` - kind (Deployment/DaemonSet), image, replicaCount, hugconfCrd, metricsAuth, extraArgs, containerPort, resources, securityContext, probes, scheduling (nodeSelector/tolerations/affinity/topologySpreadConstraints), extraEnvs/Volumes/Containers, daemonset (useHostNetwork/useHostPort/hostPorts/hostIP), service config (incl. metrics service), serviceMonitor, podMonitor, autoscaling, keda (ScaledObject), PDB
|
||||
- `hugconf` - create, name, logging (defaultLevel, categoryLevelList), globalRef, defaultsRef
|
||||
- `crdjob` - enabled, podAnnotations, ttl, scheduling, resources, image override
|
||||
- `gwapijob` - enabled, version (Gateway API CRD version), same options as crdjob
|
||||
|
||||
### Metrics
|
||||
|
||||
HUG exposes two separate metrics endpoints:
|
||||
|
||||
| Port | Name | Source | Default |
|
||||
|---|---|---|---|
|
||||
| 31024 | `stat` | HAProxy stats (via `--stats-port`) | Always exposed |
|
||||
| 31060 | `metrics` | Controller metrics (via `--controller-port`) | Always exposed |
|
||||
|
||||
- `controller.metricsAuth` controls `--metrics-auth` flag; default is `kube-rbac`
|
||||
- Supported values: `none`, `kube-rbac`, `basic`
|
||||
- When `kube-rbac`: controller serves HTTPS, validates bearer tokens via TokenReview API
|
||||
- When `none`: plain HTTP, no authentication
|
||||
- ClusterRole includes `tokenreviews` and `subjectaccessreviews` for kube-rbac auth
|
||||
- The metrics Service (`controller-service-metrics.yaml`) exposes both `stat` and `metrics` ports, created only when ServiceMonitor is enabled
|
||||
|
||||
### What HUG chart intentionally does NOT have (compared to kubernetes-ingress)
|
||||
|
||||
- No IngressClass
|
||||
- No ConfigMap-based HAProxy configuration
|
||||
- No proxy service / fetch sync mode
|
||||
- No publish-service
|
||||
- No default TLS cert generation
|
||||
|
||||
### HUG Source Project
|
||||
|
||||
Source code lives at: `/home/zlatko/src/gitlab.int.haproxy.com/zbratkovic/unified-k8s-gateway`
|
||||
|
||||
Key paths in source:
|
||||
- `cmd/controller/main.go` - controller entry point
|
||||
- `hug/configuration/configuration.go` - CLI flags definition
|
||||
- `build/Dockerfile` - container image build
|
||||
- `api/definition/` - CRD definitions
|
||||
- `example/dev-init/` - example Gateway/HTTPRoute manifests
|
||||
- `documentation/metrics*.md` - metrics documentation
|
||||
|
||||
### HUG Controller Flags
|
||||
|
||||
All flags (for `extraArgs`):
|
||||
|
||||
| Flag | Default | Description |
|
||||
|---|---|---|
|
||||
| `--hugconf-crd` | | `namespace/name` of the HugConf CRD |
|
||||
| `--controller-name` | `gate.haproxy.org/hug` | `spec.controllerName` GatewayClass selector |
|
||||
| `--ipv4-bind-address` | | IPv4 address to bind to |
|
||||
| `--ipv6-bind-address` | | IPv6 address to bind to |
|
||||
| `--log-type` | `json` | Log output type (`text` or `json`) |
|
||||
| `--job-gwapi` | | Install Gateway API experimental CRDs for given version (e.g. `1.3.0`) and exit |
|
||||
| `--namespaces` | | Comma-separated list of namespaces to monitor |
|
||||
| `--stats-port` | `1024` | Port for HAProxy stats |
|
||||
| `--controller-port` | `31060` | Port for controller metrics (prometheus) |
|
||||
| `--sync-period` | `0` | Period for HAProxy config computation (e.g. `5s`, `1m`) |
|
||||
| `--startup-sync-period` | `0` | Startup period for HAProxy config computation |
|
||||
| `--cache-resync-period` | `0` | Controller-runtime manager cache SyncPeriod (default: 10 hours) |
|
||||
| `--add-stats-port` | `true` | Add stats port bind to existing stats frontend |
|
||||
| `--force-restart-haproxy` | `false` | Force HAProxy restart at controller startup |
|
||||
| `--leader-election-enabled` | `false` | Enable leader election |
|
||||
| `--with-s6-overlay` | `false` | Use s6 overlay to start/stop/restart HAProxy |
|
||||
| `--with-pebble` | `false` | Use pebble to start/stop/restart HAProxy |
|
||||
| `--disable-ipv4` | `false` | Disable IPv4 support |
|
||||
| `--disable-ipv6` | `false` | Disable IPv6 support |
|
||||
| `--job-check-crd` | `false` | Run CRD refresh job and exit |
|
||||
| `-e` / `--external` | `false` | Use as external controller (out of k8s cluster) |
|
||||
| `--external-config-dir` | | Path to HAProxy configuration directory |
|
||||
| `--external-haproxy-binary` | | Path to HAProxy binary |
|
||||
| `--external-runtime-dir` | | Path to HAProxy runtime directory |
|
||||
| `--external-state-dir` | | Path to HAProxy state directory |
|
||||
| `--external-aux-dir` | | Path to HAProxy aux directory |
|
||||
| `--metrics-auth` | `none` | Metrics endpoint auth mode: `none`, `kube-rbac`, `basic` |
|
||||
| `--metrics-basic-auth-user` | | Basic auth username (when `--metrics-auth=basic`) |
|
||||
| `--metrics-basic-auth-password` | | Basic auth password (when `--metrics-auth=basic`) |
|
||||
| `-t` | `false` | Simulate running HAProxy (test mode) |
|
||||
|
||||
Note: The HUG binary default for `--metrics-auth` is `none`, but the Helm chart overrides this to `kube-rbac` via `controller.metricsAuth`.
|
||||
|
||||
## CI Values Files
|
||||
|
||||
23 test value files in `haproxy-unified-gateway/ci/`:
|
||||
- 8 DaemonSet variants (default, customnodeport, extraargs, extraenvs, extraports, hostport, serviceannotation, strategy)
|
||||
- 15 Deployment variants (default, customnodeport, disabled-jobs, extraargs, extraenvs, extraports, hpa, hugconf, keda, keda-advanced, metrics-none, pdb, podmonitor, servicemonitor, strategy)
|
||||
|
||||
Naming convention: `<mode>-<feature>-values.yaml`
|
||||
|
||||
## Testing
|
||||
|
||||
Three test scripts in `test/`:
|
||||
|
||||
| Script | Purpose |
|
||||
|---|---|
|
||||
| `test/local-test.sh` | Offline lint + template validation (no cluster needed) |
|
||||
| `test/integration-test.sh` | Deploy to a real Kind cluster and verify resources |
|
||||
| `test/ct-test.sh` | Wrapper around `ct` (chart-testing), matches CircleCI pipeline |
|
||||
|
||||
### local-test.sh
|
||||
|
||||
Tests: Chart.yaml metadata, helm lint, helm template, Deployment vs DaemonSet switching, HugConf cleanup hooks, metrics port rendering + `--metrics-auth` flag, ServiceMonitor/PodMonitor rendering, all ci/ values files.
|
||||
|
||||
### integration-test.sh
|
||||
|
||||
Tests on a real Kind cluster: default install, DaemonSet mode, HPA, PDB, metrics port (container port 31060, `--metrics-auth=kube-rbac` arg), ServiceMonitor/PodMonitor with metrics Service port verification, HugConf cleanup on uninstall, all ci/ values files.
|
||||
|
||||
`TEST_FILTER` values: `defaults`, `daemonset`, `hpa`, `pdb`, `metrics-port`, `monitoring`, `hugconf-cleanup`, `ci`
|
||||
|
||||
### ct-test.sh
|
||||
|
||||
Runs `ct lint` and `ct install` locally, same as CircleCI. Auto-downloads `chart_schema.yaml` and `lintconf.yaml` from the ct release on first run (files are gitignored).
|
||||
|
||||
Modes: `lint`, `install`, `all`
|
||||
|
||||
### CircleCI Pipeline
|
||||
|
||||
`.circleci/config.yml` workflow: `lint-scripts` (shellcheck) -> `lint-charts` (ct lint) -> `install-charts` (ct install on Kind) -> `release-charts` (helm package + push to GitHub Releases, GHCR OCI, update gh-pages index).
|
||||
|
||||
## Conventions
|
||||
|
||||
- Template names prefixed with `controller-` for controller-specific resources
|
||||
- All templates use `include "<chart>.fullname"` for resource naming
|
||||
- All templates use `include "<chart>.namespace"` for namespace
|
||||
- Helm hooks used for CRD installation jobs (post-install, pre-upgrade)
|
||||
- ArgoCD hook annotations included alongside Helm hooks
|
||||
- HugConf CR is a post-install hook (weight 5) that runs after the CRD job (weight 0)
|
||||
- HugConf cleanup is a pre-delete hook Job
|
||||
- Security context: non-root (UID 1000), CAP_NET_BIND_SERVICE, seccomp RuntimeDefault
|
||||
- ServiceMonitor/PodMonitor gated behind `.Capabilities.APIVersions "monitoring.coreos.com/v1"`
|
||||
89
CONTRIBUTING.md
Normal file
89
CONTRIBUTING.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Contributing Guidelines
|
||||
|
||||
Contributions are welcome via GitHub pull requests.
|
||||
This document outlines the process to help get your contribution accepted.
|
||||
|
||||
## Sign off Your Work
|
||||
|
||||
The Developer Certificate of Origin (DCO) is a lightweight way for contributors to certify that they wrote or otherwise have the right to submit the code they are contributing to the project.
|
||||
Here is the full text of the [DCO](http://developercertificate.org/):
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
1 Letterman Drive
|
||||
Suite D4700
|
||||
San Francisco, CA, 94129
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
Contributors must sign-off that they adhere to these requirements by adding a `Signed-off-by` line to commit messages.
|
||||
|
||||
```
|
||||
This is my commit message
|
||||
|
||||
Signed-off-by: Random J Developer <random@developer.example.org>
|
||||
```
|
||||
|
||||
Git has a `-s` command line option to append this automatically to your commit message:
|
||||
|
||||
```console
|
||||
$ git commit -s -m 'This is my commit message'
|
||||
```
|
||||
|
||||
## How to Contribute
|
||||
|
||||
1. Fork this repository, develop, and test your changes.
|
||||
1. Remember to sign off your commits as described above.
|
||||
1. Submit a pull request.
|
||||
|
||||
**_NOTE_**: In order to make testing and merging of PRs easier, please submit changes to multiple charts in separate PRs.
|
||||
|
||||
### Technical Requirements
|
||||
|
||||
- Must pass linting and installing with the [chart-testing](https://github.com/helm/chart-testing) tool
|
||||
- Must follow [best practices](https://helm.sh/docs/chart_best_practices/) and [review guidelines](https://github.com/helm/charts/blob/master/REVIEW_GUIDELINES.md)
|
||||
|
||||
### Documentation Requirements
|
||||
|
||||
- A chart's `README.md` must include configuration options
|
||||
- A chart's `NOTES.txt` must include relevant post-installation information
|
||||
|
||||
### Merge Approval and Release Process
|
||||
|
||||
- Must pass DCO check
|
||||
- Must pass CI jobs for linting and installing changed charts
|
||||
- Any change to a chart requires a version bump following [semver](https://semver.org/) principles
|
||||
|
||||
Once changes have been merged, the release job will automatically run to package and release changed charts.
|
||||
176
LICENSE
Normal file
176
LICENSE
Normal file
@@ -0,0 +1,176 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
51
README.md
Normal file
51
README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# 
|
||||
|
||||
## HAProxy Helm Charts
|
||||
|
||||

|
||||
[](https://circleci.com/gh/haproxytech/helm-charts/tree/main)
|
||||
[](https://artifacthub.io/packages/search?repo=haproxytech)
|
||||
|
||||
This repository hosts official [HAProxy Technologies](https://www.haproxy.com/) Helm Charts for deploying [HAProxy Load Balancer](https://github.com/haproxy/haproxy) and [Ingress controller](https://github.com/haproxytech/kubernetes-ingress) on [Kubernetes](https://kubernetes.io/).
|
||||
|
||||
### Changelogs
|
||||
|
||||
Changelog for **Helm charts** in this repository are maintained automatically at ArtifactHub separately for [HAProxy](https://artifacthub.io/packages/helm/haproxytech/haproxy?modal=changelog) and [Ingress controller](https://artifacthub.io/packages/helm/haproxytech/kubernetes-ingress?modal=changelog)
|
||||
|
||||
Changelog for the packaged projects are available separately for [HAProxy](https://github.com/haproxy/haproxy/blob/master/CHANGELOG) and [HAProxy Technologies Ingress controller](https://github.com/haproxytech/kubernetes-ingress/releases/), with release notes and other documentation available at their respective project pages.
|
||||
|
||||
## Before you begin
|
||||
|
||||
### Setup a Kubernetes Cluster
|
||||
|
||||
The quickest way to setup a Kubernetes cluster is with [Azure Kubernetes Service](https://azure.microsoft.com/en-us/services/kubernetes-service/), [AWS Elastic Kubernetes Service](https://aws.amazon.com/eks/) or [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) using their respective quick-start guides.
|
||||
|
||||
For setting up Kubernetes on other cloud platforms or bare-metal servers refer to the Kubernetes [getting started guide](http://kubernetes.io/docs/getting-started-guides/).
|
||||
|
||||
### Install Helm
|
||||
|
||||
Get the latest [Helm release](https://github.com/helm/helm#install).
|
||||
|
||||
### Add Helm chart repo
|
||||
|
||||
Once you have Helm installed, add the repo as follows:
|
||||
|
||||
```console
|
||||
helm repo add haproxytech https://haproxytech.github.io/helm-charts
|
||||
helm repo update
|
||||
```
|
||||
|
||||
HAProxy Helm charts can be also found on [ArtifactHub](https://artifacthub.io/packages/search?repo=haproxytech).
|
||||
|
||||
## Search and install charts
|
||||
|
||||
```console
|
||||
helm search repo haproxytech/
|
||||
helm install my-release haproxytech/<chart>
|
||||
```
|
||||
|
||||
**_NOTE_**: For instructions on how to install a chart follow instructions in its `README.md`.
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome all contributions. Please refer to [guidelines](CONTRIBUTING.md) on how to make a contribution.
|
||||
101
catalog-info.yaml
Normal file
101
catalog-info.yaml
Normal file
@@ -0,0 +1,101 @@
|
||||
# ─── System: groups all per-service Components for this application ───
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: System
|
||||
metadata:
|
||||
name: haproxy-unified
|
||||
description: "haproxy-unified — deployed via ArgoCD into demo-apps"
|
||||
labels:
|
||||
backstage.io/environment: "dev"
|
||||
app.kubernetes.io/managed-by: "backstage"
|
||||
tags:
|
||||
- deployment
|
||||
- argocd
|
||||
|
||||
annotations:
|
||||
argocd/app-name: "haproxy-unified"
|
||||
argocd/app-namespace: "argocd"
|
||||
argocd/instance-name: ""
|
||||
backstage.io/techdocs-ref: dir:.
|
||||
backstage.io/source-location: "url:https://gitea.kyndemo.live/validate/haproxy-unified/src/branch/main"
|
||||
backstage.io/kubernetes-namespace: "demo-apps"
|
||||
backstage.io/kubernetes-label-selector: "app.kubernetes.io/managed-by=backstage"
|
||||
gitea.kyndemo.live/repo-slug: "validate/haproxy-unified"
|
||||
|
||||
links:
|
||||
- url: https://haproxy-unified.kyndemo.live
|
||||
title: Live Application
|
||||
icon: web
|
||||
- url: https://gitea.kyndemo.live/validate/haproxy-unified
|
||||
title: Repository
|
||||
icon: github
|
||||
- url: https://argocd.kyndemo.live/applications/haproxy-unified
|
||||
title: ArgoCD App
|
||||
icon: dashboard
|
||||
|
||||
spec:
|
||||
owner: "platform-engineering"
|
||||
domain: platform
|
||||
dependsOn:
|
||||
- component:default/argocd-service
|
||||
|
||||
|
||||
- resource:default/k6-operator
|
||||
|
||||
# ─── Primary Component (always present, matches component_id) ───────
|
||||
---
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: haproxy-unified
|
||||
description: "haproxy-unified — deployed via ArgoCD into demo-apps"
|
||||
labels:
|
||||
backstage.io/environment: "dev"
|
||||
app.kubernetes.io/managed-by: "backstage"
|
||||
tags:
|
||||
- deployment
|
||||
- argocd
|
||||
|
||||
- load-testing
|
||||
- k6
|
||||
|
||||
|
||||
annotations:
|
||||
argocd/app-name: "haproxy-unified"
|
||||
argocd/app-namespace: "argocd"
|
||||
argocd/instance-name: ""
|
||||
backstage.io/techdocs-ref: dir:.
|
||||
backstage.io/source-location: "url:https://gitea.kyndemo.live/validate/haproxy-unified/src/branch/main"
|
||||
backstage.io/kubernetes-namespace: "demo-apps"
|
||||
backstage.io/kubernetes-label-selector: "app=haproxy-unified"
|
||||
gitea.kyndemo.live/repo-slug: "validate/haproxy-unified"
|
||||
|
||||
k6/enabled: "true"
|
||||
k6/test-configmap: "k6-test-haproxy-unified"
|
||||
k6/test-namespace: "demo-apps"
|
||||
k6/target-service: "frontend"
|
||||
|
||||
links:
|
||||
- url: https://haproxy-unified.kyndemo.live
|
||||
title: Live Application
|
||||
icon: web
|
||||
- url: https://gitea.kyndemo.live/validate/haproxy-unified
|
||||
title: Repository
|
||||
icon: github
|
||||
- url: https://argocd.kyndemo.live/applications/haproxy-unified
|
||||
title: ArgoCD App
|
||||
icon: dashboard
|
||||
|
||||
spec:
|
||||
type: service
|
||||
owner: "platform-engineering"
|
||||
lifecycle: experimental
|
||||
|
||||
system: haproxy-unified
|
||||
dependsOn:
|
||||
- component:default/argocd-service
|
||||
|
||||
|
||||
- resource:default/k6-operator
|
||||
|
||||
# ─── Per-service Components (from Watcher discovery) ─────────────────
|
||||
|
||||
65
docs/index.md
Normal file
65
docs/index.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# haproxy-unified
|
||||
|
||||
Deployed from **custom** via the Backstage Hello Demo template.
|
||||
|
||||
| Property | Value |
|
||||
|---|---|
|
||||
| **Environment** | `dev` |
|
||||
| **Namespace** | `demo-apps` |
|
||||
| **ArgoCD Project** | `` |
|
||||
| **Branch** | `main` |
|
||||
| **Observability** | Disabled |
|
||||
|
||||
## Quick Links
|
||||
|
||||
- **Repository**: [https://gitea.kyndemo.live/validate/haproxy-unified](https://gitea.kyndemo.live/validate/haproxy-unified)
|
||||
- **ArgoCD**: [https://argocd.kyndemo.live/applications/haproxy-unified](https://argocd.kyndemo.live/applications/haproxy-unified)
|
||||
- **Live App**: [https://haproxy-unified.kyndemo.live](https://haproxy-unified.kyndemo.live)
|
||||
|
||||
|
||||
## Architecture
|
||||
|
||||
This service was scaffolded using the **Application Migration Factory** Backstage template.
|
||||
|
||||
**Deployment flow:**
|
||||
|
||||
1. Source cloned from `custom`
|
||||
2. Catalog entity and CI workflows overlaid by Backstage
|
||||
|
||||
4. ArgoCD Application created targeting the `demo-apps` namespace
|
||||
5. ArgoCD continuously syncs from the `main` branch
|
||||
|
||||
**ArgoCD sync path:** `kubernetes-manifests`
|
||||
|
||||
## Development Workflow
|
||||
|
||||
```bash
|
||||
git clone https://gitea.kyndemo.live/validate/haproxy-unified.git
|
||||
cd haproxy-unified
|
||||
# make changes, then:
|
||||
git add . && git commit -m "your change" && git push origin main
|
||||
```
|
||||
|
||||
ArgoCD monitors the repository and automatically syncs changes to the `demo-apps` namespace.
|
||||
|
||||
## Rollback
|
||||
|
||||
To roll back to a previous version:
|
||||
|
||||
1. Open the [ArgoCD UI](https://argocd.kyndemo.live/applications/haproxy-unified)
|
||||
2. Click **History and Rollback**
|
||||
3. Select the desired revision and click **Rollback**
|
||||
|
||||
Alternatively, revert the commit in Git and push — ArgoCD will auto-sync the rollback.
|
||||
|
||||
|
||||
|
||||
## SLOs and Monitoring
|
||||
|
||||
Define your service level objectives here once the service is stable:
|
||||
|
||||
| SLI | Target | Dashboard |
|
||||
|---|---|---|
|
||||
| Availability | 99.9% | [Grafana](https://grafana.kyndemo.live) |
|
||||
| Latency (p99) | < 500ms | [Grafana](https://grafana.kyndemo.live) |
|
||||
| Error rate | < 1% | [Grafana](https://grafana.kyndemo.live) |
|
||||
21
haproxy-unified-gateway/.helmignore
Normal file
21
haproxy-unified-gateway/.helmignore
Normal file
@@ -0,0 +1,21 @@
|
||||
# Patterns to ignore when building packages.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
39
haproxy-unified-gateway/Chart.yaml
Normal file
39
haproxy-unified-gateway/Chart.yaml
Normal file
@@ -0,0 +1,39 @@
|
||||
# Copyright 2026 HAProxy Technologies LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
apiVersion: v2
|
||||
name: haproxy-unified-gateway
|
||||
description: A Helm chart for HAProxy Unified Gateway - Kubernetes Gateway API Controller
|
||||
type: application
|
||||
version: 1.0.0
|
||||
appVersion: 1.0.1
|
||||
kubeVersion: ">=1.26.0-0"
|
||||
keywords:
|
||||
- haproxy
|
||||
- gateway-api
|
||||
- gateway
|
||||
- load-balancer
|
||||
home: https://github.com/haproxytech/helm-charts/tree/main/haproxy-unified-gateway
|
||||
sources:
|
||||
- https://github.com/haproxytech/haproxy-unified-gateway
|
||||
icon: https://raw.githubusercontent.com/haproxytech/helm-charts/main/kubernetes-ingress/chart-icon.png
|
||||
maintainers:
|
||||
- name: Zlatko Bratkovic
|
||||
email: zbratkovic@haproxy.com
|
||||
- name: Dinko Korunic
|
||||
email: dkorunic@haproxy.com
|
||||
annotations:
|
||||
artifacthub.io/license: Apache-2.0
|
||||
artifacthub.io/changes: |-
|
||||
- Use HAProxy Unified Gateway 1.0.1 version for base image
|
||||
495
haproxy-unified-gateway/README.md
Normal file
495
haproxy-unified-gateway/README.md
Normal file
@@ -0,0 +1,495 @@
|
||||
# 
|
||||
|
||||
## HAProxy Unified Gateway
|
||||
|
||||
A Kubernetes Gateway API controller powered by HAProxy. HAProxy Unified Gateway (HUG) implements the [Gateway API](https://gateway-api.sigs.k8s.io/) specification to provide advanced traffic management capabilities.
|
||||
|
||||
## Introduction
|
||||
|
||||
This chart bootstraps a HAProxy Unified Gateway deployment/daemonset on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Kubernetes 1.26+
|
||||
- Helm 3.6+ (recommended 3.7+)
|
||||
|
||||
## Before you begin
|
||||
|
||||
### Setting up a Kubernetes Cluster
|
||||
|
||||
The quickest way to setup a Kubernetes cluster is with [Azure Kubernetes Service](https://azure.microsoft.com/en-us/services/kubernetes-service/), [AWS Elastic Kubernetes Service](https://aws.amazon.com/eks/) or [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) using their respective quick-start guides.
|
||||
|
||||
For setting up Kubernetes on other cloud platforms or bare-metal servers refer to the Kubernetes [getting started guide](http://kubernetes.io/docs/getting-started-guides/).
|
||||
|
||||
### Install Helm
|
||||
|
||||
Get the latest [Helm release](https://github.com/helm/helm#install).
|
||||
|
||||
### Adding Helm chart repo
|
||||
|
||||
Once you have Helm installed, add the haproxytech Chart Repository as follows:
|
||||
|
||||
```console
|
||||
helm repo add haproxytech https://haproxytech.github.io/helm-charts
|
||||
|
||||
helm repo update
|
||||
```
|
||||
|
||||
## Installing the chart
|
||||
|
||||
To install the chart with Helm v3 as _my-release_ deployment:
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy-unified-gateway
|
||||
```
|
||||
|
||||
### Installing with unique name
|
||||
|
||||
To auto-generate controller and its resources names when installing, use the following:
|
||||
|
||||
```console
|
||||
helm install haproxytech/haproxy-unified-gateway \
|
||||
--generate-name
|
||||
```
|
||||
|
||||
### Installing from a private registry
|
||||
|
||||
To install the chart using a private registry for controller into a separate namespace _prod_.
|
||||
|
||||
**_NOTE_**: Helm v3 requires namespace to be precreated (eg. with `kubectl create namespace prod`)
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy-unified-gateway \
|
||||
--namespace prod \
|
||||
--set controller.image.tag=SOMETAG \
|
||||
--set controller.imagePullSecrets[0].name=my-pull-secret
|
||||
```
|
||||
|
||||
### Using values from YAML file
|
||||
|
||||
As opposed to using many `--set` invocations, much simpler approach is to define value overrides in a separate YAML file and specify them when invoking Helm:
|
||||
|
||||
_myhug.yaml_:
|
||||
|
||||
```yaml
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
service:
|
||||
type: LoadBalancer
|
||||
annotations:
|
||||
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
|
||||
service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
|
||||
```
|
||||
|
||||
And invoking Helm becomes:
|
||||
|
||||
```console
|
||||
helm install my-release -f myhug.yaml haproxytech/haproxy-unified-gateway
|
||||
```
|
||||
|
||||
### Installing as DaemonSet
|
||||
|
||||
Default controller mode is [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), but it is possible to use [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) as well:
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy-unified-gateway \
|
||||
--set controller.kind=DaemonSet
|
||||
```
|
||||
|
||||
### Installing with host networking (DaemonSet)
|
||||
|
||||
When using DaemonSet mode, you can enable host networking and host ports:
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy-unified-gateway \
|
||||
--set controller.kind=DaemonSet \
|
||||
--set controller.daemonset.useHostNetwork=true \
|
||||
--set controller.dnsPolicy=ClusterFirstWithHostNet
|
||||
```
|
||||
|
||||
### Installing with service annotations
|
||||
|
||||
On some environments like EKS and GKE there might be a need to pass service annotations. Syntax can become a little tedious however:
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy-unified-gateway \
|
||||
--set controller.service.type=LoadBalancer \
|
||||
--set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-internal"="0.0.0.0/0" \
|
||||
--set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-cross-zone-load-balancing-enabled"="true"
|
||||
```
|
||||
|
||||
**_NOTE_**: With helm `--set` it is needed to put quotes and escape dots in the annotation key and commas in the value string.
|
||||
|
||||
### Installing with Horizontal Pod Autoscaler (HPA)
|
||||
|
||||
[HPA](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) automatically scales number of replicas in Deployment and adjusts replica count for the controller:
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy-unified-gateway \
|
||||
--set controller.autoscaling.enabled=true
|
||||
```
|
||||
|
||||
### Enabling Prometheus monitoring
|
||||
|
||||
HUG exposes two separate metrics endpoints:
|
||||
|
||||
- **`stat`** (port 31024) — HAProxy native metrics (`haproxy_*` prefix): connections, request rates, backend health, latency, error codes
|
||||
- **`metrics`** (port 31060) — HUG controller metrics (`hug_*` prefix): event batch processing, config generation, cert/map operations, HAProxy reloads
|
||||
|
||||
The chart supports both [ServiceMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md) and [PodMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/design.md#podmonitor) for Prometheus Operator integration. These are mutually exclusive — enable only one. By default, both endpoints are scraped.
|
||||
|
||||
**Note:** Requires Prometheus Operator installed in the cluster. The `monitoring.coreos.com/v1` API must be available.
|
||||
|
||||
#### Metrics authentication
|
||||
|
||||
The controller metrics endpoint (`metrics` port) supports three authentication modes via `controller.metricsAuth`:
|
||||
|
||||
| Mode | Default | Protocol | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `kube-rbac` | **yes** | HTTPS | Kubernetes TokenReview/SubjectAccessReview — Prometheus authenticates with its ServiceAccount token |
|
||||
| `none` | | HTTP | No authentication |
|
||||
| `basic` | | HTTPS | HTTP Basic Authentication with username/password |
|
||||
|
||||
#### Default setup (kube-rbac)
|
||||
|
||||
By default the chart uses `kube-rbac` authentication. The controller serves metrics over HTTPS and validates bearer tokens via the Kubernetes API. To set it up:
|
||||
|
||||
**Step 1.** Create a ClusterRole that grants access to the `/metrics` endpoint and bind it to the Prometheus ServiceAccount:
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: hug-metrics-reader
|
||||
rules:
|
||||
- nonResourceURLs: ["/metrics"]
|
||||
verbs: ["get"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: hug-metrics-reader
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: hug-metrics-reader
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: prometheus # adjust to your Prometheus SA name
|
||||
namespace: monitoring # adjust to your Prometheus namespace
|
||||
```
|
||||
|
||||
**Step 2.** Enable the ServiceMonitor (or PodMonitor). The default endpoints are pre-configured for kube-rbac — `stat` uses plain HTTP, `metrics` uses HTTPS with the Prometheus pod's ServiceAccount token:
|
||||
|
||||
```yaml
|
||||
controller:
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
extraLabels:
|
||||
release: prometheus # match your Prometheus serviceMonitorSelector
|
||||
```
|
||||
|
||||
That's it. The default `values.yaml` endpoints already include the correct HTTPS + bearer token configuration for the `metrics` port:
|
||||
|
||||
```yaml
|
||||
# Default endpoints (already set in values.yaml):
|
||||
endpoints:
|
||||
- port: stat
|
||||
path: /metrics
|
||||
scheme: http
|
||||
interval: 30s
|
||||
- port: metrics
|
||||
path: /metrics
|
||||
scheme: https
|
||||
interval: 30s
|
||||
tlsConfig:
|
||||
insecureSkipVerify: true
|
||||
bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
```
|
||||
|
||||
#### Using no authentication
|
||||
|
||||
To disable metrics authentication:
|
||||
|
||||
```yaml
|
||||
controller:
|
||||
metricsAuth: none
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
endpoints:
|
||||
- port: stat
|
||||
path: /metrics
|
||||
scheme: http
|
||||
interval: 30s
|
||||
- port: metrics
|
||||
path: /metrics
|
||||
scheme: http
|
||||
interval: 30s
|
||||
```
|
||||
|
||||
#### Using basic authentication
|
||||
|
||||
```yaml
|
||||
controller:
|
||||
metricsAuth: basic
|
||||
extraArgs:
|
||||
- --metrics-basic-auth-user=prometheus
|
||||
- --metrics-basic-auth-password=secret
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
endpoints:
|
||||
- port: stat
|
||||
path: /metrics
|
||||
scheme: http
|
||||
interval: 30s
|
||||
- port: metrics
|
||||
path: /metrics
|
||||
scheme: https
|
||||
interval: 30s
|
||||
tlsConfig:
|
||||
insecureSkipVerify: true
|
||||
basicAuth:
|
||||
username:
|
||||
name: hug-metrics-basic-auth
|
||||
key: username
|
||||
password:
|
||||
name: hug-metrics-basic-auth
|
||||
key: password
|
||||
```
|
||||
|
||||
#### Using PodMonitor instead of ServiceMonitor
|
||||
|
||||
PodMonitor scrapes pods directly without creating an extra metrics Service. Replace `serviceMonitor` with `podMonitor` in any of the examples above:
|
||||
|
||||
```yaml
|
||||
controller:
|
||||
podMonitor:
|
||||
enabled: true
|
||||
extraLabels:
|
||||
release: prometheus
|
||||
```
|
||||
|
||||
### Configuring HugConf
|
||||
|
||||
The chart creates a HugConf custom resource for controller configuration. You can customize logging, and optionally reference Global and Defaults custom resources:
|
||||
|
||||
```yaml
|
||||
hugconf:
|
||||
logging:
|
||||
defaultLevel: Debug
|
||||
categoryLevelList:
|
||||
- category: "gate"
|
||||
level: "Debug"
|
||||
- category: "k8s"
|
||||
level: "Info"
|
||||
# Reference a Global CR for HAProxy global section customization
|
||||
globalRef:
|
||||
group: gate.v3.haproxy.org
|
||||
kind: Global
|
||||
name: global
|
||||
# Reference a Defaults CR for HAProxy defaults section customization
|
||||
defaultsRef:
|
||||
group: gate.v3.haproxy.org
|
||||
kind: Defaults
|
||||
name: haproxytech
|
||||
```
|
||||
|
||||
The Global and Defaults CRDs are automatically installed by the CRD job. When a `globalRef` or `defaultsRef` is set, the controller uses the referenced CR to configure the HAProxy global/defaults sections. When removed, built-in defaults are restored.
|
||||
|
||||
### Adding extra ports
|
||||
|
||||
By default the chart exposes four container ports: `http` (31080), `https` (31443), `stat` (31024) and `metrics` (31060). Additional ports can be added in two places:
|
||||
|
||||
1. **`controller.containerPort`** — exposes the port on the container (pod spec)
|
||||
2. **`controller.service.extraPorts`** — exposes the port on the Service
|
||||
|
||||
#### Using `--set` flags
|
||||
|
||||
To add a container port only (e.g. for a sidecar or internal use):
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy-unified-gateway \
|
||||
--set controller.containerPort.custom=8080
|
||||
```
|
||||
|
||||
To also expose it on the Service:
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy-unified-gateway \
|
||||
--set controller.containerPort.custom=8080 \
|
||||
--set controller.service.extraPorts[0].name=custom \
|
||||
--set controller.service.extraPorts[0].port=8080 \
|
||||
--set controller.service.extraPorts[0].targetPort=8080 \
|
||||
--set controller.service.extraPorts[0].protocol=TCP
|
||||
```
|
||||
|
||||
#### Using a values file
|
||||
|
||||
For multiple extra ports, a values file is cleaner:
|
||||
|
||||
```yaml
|
||||
controller:
|
||||
containerPort:
|
||||
http: 31080
|
||||
https: 31443
|
||||
stat: 31024
|
||||
custom: 8080
|
||||
grpc: 9090
|
||||
service:
|
||||
extraPorts:
|
||||
- name: custom
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
- name: grpc
|
||||
port: 9090
|
||||
targetPort: 9090
|
||||
protocol: TCP
|
||||
```
|
||||
|
||||
#### DaemonSet with host ports
|
||||
|
||||
For DaemonSet mode with host ports, also add matching entries in `controller.daemonset.hostPorts`:
|
||||
|
||||
```yaml
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
containerPort:
|
||||
http: 31080
|
||||
https: 31443
|
||||
stat: 31024
|
||||
custom: 8080
|
||||
daemonset:
|
||||
useHostPort: true
|
||||
hostPorts:
|
||||
http: 80
|
||||
https: 443
|
||||
stat: 1024
|
||||
custom: 8080
|
||||
service:
|
||||
extraPorts:
|
||||
- name: custom
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
```
|
||||
|
||||
### Passing extra arguments
|
||||
|
||||
Additional controller flags can be passed via `extraArgs`:
|
||||
|
||||
```yaml
|
||||
controller:
|
||||
extraArgs:
|
||||
- --controller-name=gate.haproxy.org/hug
|
||||
- --namespaces=default,production
|
||||
- --leader-election-enabled
|
||||
```
|
||||
|
||||
#### Available controller flags
|
||||
|
||||
| Flag | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `--controller-name` | `gate.haproxy.org/hug` | `spec.controllerName` GatewayClass selector |
|
||||
| `--namespaces` | | Comma-separated list of namespaces to monitor |
|
||||
| `--ipv4-bind-address` | | IPv4 address to bind to |
|
||||
| `--ipv6-bind-address` | | IPv6 address to bind to |
|
||||
| `--disable-ipv4` | `false` | Disable IPv4 support |
|
||||
| `--disable-ipv6` | `false` | Disable IPv6 support |
|
||||
| `--stats-port` | `1024` | Port for HAProxy stats |
|
||||
| `--controller-port` | `31060` | Port for controller metrics (prometheus) |
|
||||
| `--log-type` | `json` | Log output type (`text` or `json`) |
|
||||
| `--sync-period` | `0` | Period at which the controller computes HAProxy configuration (e.g. `5s`, `1m`) |
|
||||
| `--startup-sync-period` | `0` | Startup period for HAProxy config computation |
|
||||
| `--cache-resync-period` | `0` | Controller-runtime manager cache SyncPeriod (defaults to 10 hours if not set) |
|
||||
| `--leader-election-enabled` | `false` | Enable leader election |
|
||||
| `--add-stats-port` | `true` | Add stats port bind to existing stats frontend |
|
||||
| `--metrics-auth` | `none` | Metrics endpoint auth mode: `none`, `kube-rbac`, `basic` |
|
||||
| `--metrics-basic-auth-user` | | Basic auth username (when `--metrics-auth=basic`) |
|
||||
| `--metrics-basic-auth-password` | | Basic auth password (when `--metrics-auth=basic`) |
|
||||
|
||||
**Note:** The `--hugconf-crd` flag is set automatically by the chart via the `hugconfCrd` helper. The `--job-check-crd` and `--job-gwapi` flags are used internally by the CRD/Gateway API installation jobs.
|
||||
|
||||
### Installing with KEDA autoscaling
|
||||
|
||||
[KEDA](https://keda.sh/) provides event-driven autoscaling. It is mutually exclusive with HPA — when KEDA is enabled, HPA is automatically disabled even if `autoscaling.enabled` is set to `true`.
|
||||
|
||||
```yaml
|
||||
controller:
|
||||
keda:
|
||||
enabled: true
|
||||
minReplicas: 2
|
||||
maxReplicas: 20
|
||||
pollingInterval: 30
|
||||
cooldownPeriod: 300
|
||||
restoreToOriginalReplicaCount: false
|
||||
scaledObject:
|
||||
annotations: {}
|
||||
triggers:
|
||||
- type: prometheus
|
||||
metadata:
|
||||
serverAddress: http://<prometheus-host>:9090
|
||||
metricName: haproxy_process_idle_time_percent
|
||||
threshold: '50'
|
||||
query: avg(100-avg_over_time(haproxy_process_idle_time_percent{job="haproxy-unified-gateway"}[2m]))
|
||||
```
|
||||
|
||||
Optional advanced configuration:
|
||||
|
||||
```yaml
|
||||
controller:
|
||||
keda:
|
||||
enabled: true
|
||||
# ...triggers, minReplicas, maxReplicas...
|
||||
fallback:
|
||||
failureThreshold: 3
|
||||
replicas: 5
|
||||
horizontalPodAutoscalerConfig:
|
||||
behavior:
|
||||
scaleDown:
|
||||
stabilizationWindowSeconds: 300
|
||||
policies:
|
||||
- type: Pods
|
||||
value: 1
|
||||
periodSeconds: 300
|
||||
```
|
||||
|
||||
### Disabling CRD/Gateway API installation jobs
|
||||
|
||||
By default, the chart includes Helm hook jobs that install HUG CRDs and Gateway API CRDs. To disable them:
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy-unified-gateway \
|
||||
--set crdjob.enabled=false \
|
||||
--set gwapijob.enabled=false
|
||||
```
|
||||
|
||||
## Upgrading the chart
|
||||
|
||||
To upgrade the _my-release_ deployment:
|
||||
|
||||
```console
|
||||
helm upgrade my-release haproxytech/haproxy-unified-gateway
|
||||
```
|
||||
|
||||
## Uninstalling the chart
|
||||
|
||||
To uninstall/delete the _my-release_ deployment:
|
||||
|
||||
```console
|
||||
helm delete my-release
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
It is possible to generate a set of YAML files for testing/debugging:
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy-unified-gateway \
|
||||
--debug \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome all contributions. Please refer to [guidelines](../CONTRIBUTING.md) on how to make a contribution.
|
||||
@@ -0,0 +1,12 @@
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
service:
|
||||
type: NodePort
|
||||
http:
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
nodePort: 30080
|
||||
https:
|
||||
port: 8443
|
||||
targetPort: 8443
|
||||
nodePort: 30443
|
||||
2
haproxy-unified-gateway/ci/daemonset-default-values.yaml
Normal file
2
haproxy-unified-gateway/ci/daemonset-default-values.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
@@ -0,0 +1,5 @@
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
extraArgs:
|
||||
- --controller-name=gate.haproxy.org/hug
|
||||
- --namespaces=default
|
||||
@@ -0,0 +1,7 @@
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
extraEnvs:
|
||||
- name: TEST_STR1
|
||||
value: foo
|
||||
- name: TEST_STR2
|
||||
value: baz
|
||||
21
haproxy-unified-gateway/ci/daemonset-extraports-values.yaml
Normal file
21
haproxy-unified-gateway/ci/daemonset-extraports-values.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
## Test: DaemonSet with extra container and service ports, including host ports
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
containerPort:
|
||||
http: 31080
|
||||
https: 31443
|
||||
stat: 31024
|
||||
custom: 8080
|
||||
daemonset:
|
||||
useHostPort: true
|
||||
hostPorts:
|
||||
http: 80
|
||||
https: 443
|
||||
stat: 1024
|
||||
custom: 8080
|
||||
service:
|
||||
extraPorts:
|
||||
- name: custom
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
@@ -0,0 +1,8 @@
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
daemonset:
|
||||
useHostPort: true
|
||||
hostPorts:
|
||||
http: 80
|
||||
https: 443
|
||||
stat: 1024
|
||||
@@ -0,0 +1,5 @@
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
service:
|
||||
annotations:
|
||||
service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
|
||||
@@ -0,0 +1,7 @@
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 0
|
||||
maxSurge: 1
|
||||
@@ -0,0 +1,11 @@
|
||||
controller:
|
||||
service:
|
||||
type: NodePort
|
||||
http:
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
nodePort: 30080
|
||||
https:
|
||||
port: 8443
|
||||
targetPort: 8443
|
||||
nodePort: 30443
|
||||
@@ -0,0 +1 @@
|
||||
#
|
||||
@@ -0,0 +1,4 @@
|
||||
crdjob:
|
||||
enabled: false
|
||||
gwapijob:
|
||||
enabled: false
|
||||
@@ -0,0 +1,4 @@
|
||||
controller:
|
||||
extraArgs:
|
||||
- --controller-name=gate.haproxy.org/hug
|
||||
- --namespaces=default
|
||||
@@ -0,0 +1,6 @@
|
||||
controller:
|
||||
extraEnvs:
|
||||
- name: TEST_STR1
|
||||
value: foo
|
||||
- name: TEST_STR2
|
||||
value: baz
|
||||
14
haproxy-unified-gateway/ci/deployment-extraports-values.yaml
Normal file
14
haproxy-unified-gateway/ci/deployment-extraports-values.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
## Test: Deployment with extra container and service ports
|
||||
controller:
|
||||
kind: Deployment
|
||||
containerPort:
|
||||
http: 31080
|
||||
https: 31443
|
||||
stat: 31024
|
||||
custom: 8080
|
||||
service:
|
||||
extraPorts:
|
||||
- name: custom
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
6
haproxy-unified-gateway/ci/deployment-hpa-values.yaml
Normal file
6
haproxy-unified-gateway/ci/deployment-hpa-values.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
controller:
|
||||
autoscaling:
|
||||
enabled: true
|
||||
minReplicas: 1
|
||||
maxReplicas: 5
|
||||
targetCPUUtilizationPercentage: 80
|
||||
@@ -0,0 +1,8 @@
|
||||
hugconf:
|
||||
logging:
|
||||
defaultLevel: Debug
|
||||
categoryLevelList:
|
||||
- category: "gate"
|
||||
level: "Debug"
|
||||
- category: "k8s"
|
||||
level: "Info"
|
||||
@@ -0,0 +1,34 @@
|
||||
controller:
|
||||
keda:
|
||||
enabled: true
|
||||
minReplicas: 1
|
||||
maxReplicas: 10
|
||||
pollingInterval: 15
|
||||
cooldownPeriod: 600
|
||||
restoreToOriginalReplicaCount: true
|
||||
scaledObject:
|
||||
annotations: {}
|
||||
fallback:
|
||||
failureThreshold: 3
|
||||
replicas: 5
|
||||
horizontalPodAutoscalerConfig:
|
||||
behavior:
|
||||
scaleDown:
|
||||
stabilizationWindowSeconds: 300
|
||||
policies:
|
||||
- type: Pods
|
||||
value: 1
|
||||
periodSeconds: 300
|
||||
triggers:
|
||||
- type: prometheus
|
||||
metadata:
|
||||
serverAddress: http://prometheus:9090
|
||||
metricName: haproxy_process_idle_time_percent
|
||||
threshold: '50'
|
||||
query: avg(100-avg_over_time(haproxy_process_idle_time_percent{job="haproxy-unified-gateway"}[2m]))
|
||||
# HPA should be ignored when KEDA is enabled
|
||||
autoscaling:
|
||||
enabled: true
|
||||
minReplicas: 1
|
||||
maxReplicas: 5
|
||||
targetCPUUtilizationPercentage: 80
|
||||
18
haproxy-unified-gateway/ci/deployment-keda-values.yaml
Normal file
18
haproxy-unified-gateway/ci/deployment-keda-values.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
controller:
|
||||
keda:
|
||||
enabled: true
|
||||
minReplicas: 2
|
||||
maxReplicas: 20
|
||||
pollingInterval: 30
|
||||
cooldownPeriod: 300
|
||||
restoreToOriginalReplicaCount: false
|
||||
scaledObject:
|
||||
annotations:
|
||||
test-annotation: "test-value"
|
||||
triggers:
|
||||
- type: prometheus
|
||||
metadata:
|
||||
serverAddress: http://prometheus:9090
|
||||
metricName: haproxy_process_idle_time_percent
|
||||
threshold: '50'
|
||||
query: avg(100-avg_over_time(haproxy_process_idle_time_percent{job="haproxy-unified-gateway"}[2m]))
|
||||
@@ -0,0 +1,14 @@
|
||||
## Test: Deployment with metricsAuth=none (plain HTTP controller metrics)
|
||||
controller:
|
||||
metricsAuth: none
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
endpoints:
|
||||
- port: stat
|
||||
path: /metrics
|
||||
scheme: http
|
||||
interval: 30s
|
||||
- port: metrics
|
||||
path: /metrics
|
||||
scheme: http
|
||||
interval: 30s
|
||||
5
haproxy-unified-gateway/ci/deployment-pdb-values.yaml
Normal file
5
haproxy-unified-gateway/ci/deployment-pdb-values.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
controller:
|
||||
replicaCount: 2
|
||||
podDisruptionBudget:
|
||||
enabled: true
|
||||
minAvailable: 1
|
||||
10
haproxy-unified-gateway/ci/deployment-podmonitor-values.yaml
Normal file
10
haproxy-unified-gateway/ci/deployment-podmonitor-values.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
controller:
|
||||
podMonitor:
|
||||
enabled: true
|
||||
extraLabels:
|
||||
release: prometheus
|
||||
endpoints:
|
||||
- port: stat
|
||||
path: /metrics
|
||||
scheme: http
|
||||
interval: 30s
|
||||
@@ -0,0 +1,18 @@
|
||||
## Test: Deployment with ServiceMonitor (both stat and controller metrics endpoints)
|
||||
controller:
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
extraLabels:
|
||||
release: prometheus
|
||||
endpoints:
|
||||
- port: stat
|
||||
path: /metrics
|
||||
scheme: http
|
||||
interval: 30s
|
||||
- port: metrics
|
||||
path: /metrics
|
||||
scheme: https
|
||||
interval: 30s
|
||||
tlsConfig:
|
||||
insecureSkipVerify: true
|
||||
bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
@@ -0,0 +1,6 @@
|
||||
controller:
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 0
|
||||
maxSurge: 1
|
||||
51
haproxy-unified-gateway/templates/NOTES.txt
Normal file
51
haproxy-unified-gateway/templates/NOTES.txt
Normal file
@@ -0,0 +1,51 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
HAProxy Unified Gateway has been installed.
|
||||
|
||||
{{- if .Values.controller.service.enabled }}
|
||||
|
||||
The controller is exposed via a {{ .Values.controller.service.type }} Service:
|
||||
- HTTP: {{ .Values.controller.service.http.port }}
|
||||
- HTTPS: {{ .Values.controller.service.https.port }}
|
||||
- Stats: {{ .Values.controller.service.stat.port }}
|
||||
|
||||
{{- if eq .Values.controller.service.type "NodePort" }}
|
||||
Access the gateway using your node IP and the configured NodePort:
|
||||
export NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="ExternalIP")].address}')
|
||||
echo "HTTP: http://$NODE_IP:{{ .Values.controller.service.http.nodePort }}"
|
||||
echo "HTTPS: https://$NODE_IP:{{ .Values.controller.service.https.nodePort }}"
|
||||
{{- else if eq .Values.controller.service.type "LoadBalancer" }}
|
||||
It may take a few minutes for the LoadBalancer IP to be available.
|
||||
Watch the status with:
|
||||
kubectl get svc {{ include "haproxy-unified-gateway.fullname" . }} -n {{ include "haproxy-unified-gateway.namespace" . }} -w
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.crdjob.enabled }}
|
||||
|
||||
A post-install/pre-upgrade Job will install/update the HUG CRDs automatically.
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.gwapijob.enabled }}
|
||||
|
||||
A post-install/pre-upgrade Job will install Gateway API CRDs (v{{ .Values.gwapijob.version }}).
|
||||
{{- end }}
|
||||
|
||||
To check the controller status:
|
||||
kubectl get pods -n {{ include "haproxy-unified-gateway.namespace" . }} -l "{{ include "haproxy-unified-gateway.selectorLabels" . | replace "\n" "," }}"
|
||||
|
||||
For more information, visit: https://github.com/haproxytech/haproxy-unified-gateway
|
||||
174
haproxy-unified-gateway/templates/_helpers.tpl
Normal file
174
haproxy-unified-gateway/templates/_helpers.tpl
Normal file
@@ -0,0 +1,174 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Namespace to use.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.namespace" -}}
|
||||
{{- default .Release.Namespace .Values.namespaceOverride }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "haproxy-unified-gateway.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Helm chart metadata labels.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.helmChartLabels" -}}
|
||||
helm.sh/chart: {{ include "haproxy-unified-gateway.chart" . }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels (selector + chart metadata).
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.labels" -}}
|
||||
{{ include "haproxy-unified-gateway.selectorLabels" . }}
|
||||
{{ include "haproxy-unified-gateway.helmChartLabels" . }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
ServiceAccount name.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "haproxy-unified-gateway.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Controller image.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.image" -}}
|
||||
{{- $tag := default .Chart.AppVersion .Values.controller.image.tag -}}
|
||||
{{- printf "%s:%s" .Values.controller.image.repository $tag }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
CRD Job ServiceAccount/RBAC name.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.crdjob.saName" -}}
|
||||
{{- printf "%s-crdjob" (include "haproxy-unified-gateway.fullname" .) | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Metrics Service name.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.metricsServiceName" -}}
|
||||
{{- printf "%s-metrics" (include "haproxy-unified-gateway.fullname" .) | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
HugConf cleanup Job name.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.hugconfCleanup.fullname" -}}
|
||||
{{- printf "%s-hugconf-cleanup" (include "haproxy-unified-gateway.fullname" .) | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
CRD Job labels.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.crdjobLabels" -}}
|
||||
{{ include "haproxy-unified-gateway.helmChartLabels" . }}
|
||||
app.kubernetes.io/name: {{ include "haproxy-unified-gateway.name" . }}-crdjob
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
CRD Job fullname (includes revision for uniqueness).
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.crdjob.fullname" -}}
|
||||
{{- printf "%s-crdjob-%d" (include "haproxy-unified-gateway.fullname" .) .Release.Revision | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Gateway API Job labels.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.gwapijobLabels" -}}
|
||||
{{ include "haproxy-unified-gateway.helmChartLabels" . }}
|
||||
app.kubernetes.io/name: {{ include "haproxy-unified-gateway.name" . }}-gwapijob
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Gateway API Job fullname (includes revision for uniqueness).
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.gwapijob.fullname" -}}
|
||||
{{- printf "%s-gwapijob-%d" (include "haproxy-unified-gateway.fullname" .) .Release.Revision | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
ServiceMonitor name.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.serviceMonitorName" -}}
|
||||
{{- default (include "haproxy-unified-gateway.fullname" .) .Values.controller.serviceMonitor.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
PodMonitor name.
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.podMonitorName" -}}
|
||||
{{- default (include "haproxy-unified-gateway.fullname" .) .Values.controller.podMonitor.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
HugConf CRD reference path (namespace/name).
|
||||
*/}}
|
||||
{{- define "haproxy-unified-gateway.hugconfCrd" -}}
|
||||
{{- if .Values.controller.hugconfCrd }}
|
||||
{{- .Values.controller.hugconfCrd }}
|
||||
{{- else }}
|
||||
{{- printf "%s/%s" (include "haproxy-unified-gateway.namespace" .) .Values.hugconf.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
138
haproxy-unified-gateway/templates/clusterrole.yaml
Normal file
138
haproxy-unified-gateway/templates/clusterrole.yaml
Normal file
@@ -0,0 +1,138 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.rbac.create }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "apiextensions.k8s.io"
|
||||
resources:
|
||||
- customresourcedefinitions
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- endpoints
|
||||
- nodes
|
||||
- pods
|
||||
- services
|
||||
- namespaces
|
||||
- events
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- "discovery.k8s.io"
|
||||
resources:
|
||||
- endpointslices
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- "apps"
|
||||
resources:
|
||||
- replicasets
|
||||
- deployments
|
||||
- daemonsets
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- apiGroups:
|
||||
- gateway.networking.k8s.io
|
||||
resources:
|
||||
- gatewayclasses
|
||||
- gateways
|
||||
- httproutes
|
||||
- referencegrants
|
||||
- grpcroutes
|
||||
- tlsroutes
|
||||
verbs:
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- gateway.networking.k8s.io
|
||||
resources:
|
||||
- gatewayclasses/status
|
||||
- gateways/status
|
||||
- httproutes/status
|
||||
- referencegrants/status
|
||||
- grpcroutes/status
|
||||
- tlsroutes/status
|
||||
verbs:
|
||||
- get
|
||||
- update
|
||||
- patch
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
resources:
|
||||
- leases
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- update
|
||||
- apiGroups:
|
||||
- gate.v3.haproxy.org
|
||||
resources:
|
||||
- huggates
|
||||
- hugconfs
|
||||
- backends
|
||||
- globals
|
||||
- defaults
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
# Required for kube-rbac metrics auth (TokenReview + SubjectAccessReview)
|
||||
- apiGroups:
|
||||
- authentication.k8s.io
|
||||
resources:
|
||||
- tokenreviews
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- authorization.k8s.io
|
||||
resources:
|
||||
- subjectaccessreviews
|
||||
verbs:
|
||||
- create
|
||||
{{- end }}
|
||||
32
haproxy-unified-gateway/templates/clusterrolebinding.yaml
Normal file
32
haproxy-unified-gateway/templates/clusterrolebinding.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.rbac.create }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "haproxy-unified-gateway.serviceAccountName" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,72 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if or .Values.crdjob.enabled .Values.gwapijob.enabled }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.crdjob.saName" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.crdjobLabels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.crdjob.saName" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.crdjobLabels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "apiextensions.k8s.io"
|
||||
resources:
|
||||
- customresourcedefinitions
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.crdjob.saName" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.crdjobLabels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "haproxy-unified-gateway.crdjob.saName" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "haproxy-unified-gateway.crdjob.saName" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
{{- end }}
|
||||
96
haproxy-unified-gateway/templates/controller-crdjob.yaml
Normal file
96
haproxy-unified-gateway/templates/controller-crdjob.yaml
Normal file
@@ -0,0 +1,96 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.crdjob.enabled }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.crdjob.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.crdjobLabels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "0"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
"argocd.argoproj.io/hook": PostSync
|
||||
{{- with .Values.crdjob.podAnnotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.crdjob.ttlSecondsAfterFinished }}
|
||||
ttlSecondsAfterFinished: {{ . }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.crdjobLabels" . | nindent 8 }}
|
||||
{{- with .Values.crdjob.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "haproxy-unified-gateway.crdjob.saName" . }}
|
||||
restartPolicy: Never
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
{{- with .Values.controller.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: crdjob
|
||||
{{- if .Values.crdjob.image.repository }}
|
||||
image: {{ printf "%s:%s" .Values.crdjob.image.repository (default .Chart.AppVersion .Values.crdjob.image.tag) }}
|
||||
{{- else }}
|
||||
image: {{ include "haproxy-unified-gateway.image" . }}
|
||||
{{- end }}
|
||||
imagePullPolicy: {{ .Values.controller.image.pullPolicy }}
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
command:
|
||||
- /usr/local/sbin/hug
|
||||
- --job-check-crd
|
||||
{{- with .Values.crdjob.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.crdjob.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.crdjob.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.crdjob.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
backoffLimit: 0
|
||||
{{- end }}
|
||||
185
haproxy-unified-gateway/templates/controller-daemonset.yaml
Normal file
185
haproxy-unified-gateway/templates/controller-daemonset.yaml
Normal file
@@ -0,0 +1,185 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if eq .Values.controller.kind "DaemonSet" }}
|
||||
{{- $useHostNetwork := .Values.controller.daemonset.useHostNetwork -}}
|
||||
{{- $useHostPort := .Values.controller.daemonset.useHostPort -}}
|
||||
{{- $hostPorts := .Values.controller.daemonset.hostPorts -}}
|
||||
{{- $hostIP := .Values.controller.daemonset.hostIP -}}
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
{{- with .Values.controller.extraLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "haproxy-unified-gateway.selectorLabels" . | nindent 6 }}
|
||||
{{- with .Values.controller.strategy }}
|
||||
updateStrategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.selectorLabels" . | nindent 8 }}
|
||||
{{- with .Values.controller.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "haproxy-unified-gateway.serviceAccountName" . }}
|
||||
{{- with .Values.controller.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.unprivileged }}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
{{- end }}
|
||||
{{- with .Values.controller.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.priorityClassName }}
|
||||
priorityClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- if $useHostNetwork }}
|
||||
hostNetwork: true
|
||||
{{- end }}
|
||||
{{- with .Values.controller.dnsPolicy }}
|
||||
dnsPolicy: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.dnsConfig }}
|
||||
dnsConfig:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.initContainers }}
|
||||
initContainers:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ include "haproxy-unified-gateway.name" . }}
|
||||
image: {{ include "haproxy-unified-gateway.image" . }}
|
||||
imagePullPolicy: {{ .Values.controller.image.pullPolicy }}
|
||||
args:
|
||||
{{- if or .Values.hugconf.create .Values.controller.hugconfCrd }}
|
||||
- --hugconf-crd={{ include "haproxy-unified-gateway.hugconfCrd" . }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.metricsAuth }}
|
||||
- --metrics-auth={{ . }}
|
||||
{{- end }}
|
||||
{{- range .Values.controller.extraArgs }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
ports:
|
||||
{{- range $key, $value := .Values.controller.containerPort }}
|
||||
- name: {{ $key }}
|
||||
containerPort: {{ $value }}
|
||||
protocol: TCP
|
||||
{{- if and $useHostPort (index $hostPorts $key) }}
|
||||
hostPort: {{ index $hostPorts $key }}
|
||||
{{- end }}
|
||||
{{- if $hostIP }}
|
||||
hostIP: {{ $hostIP }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
{{- with .Values.controller.extraEnvs }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.livenessProbe }}
|
||||
livenessProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.readinessProbe }}
|
||||
readinessProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.startupProbe }}
|
||||
startupProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.unprivileged }}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
allowPrivilegeEscalation: {{ .Values.controller.allowPrivilegeEscalation }}
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
{{- with .Values.controller.seccompProfile }}
|
||||
seccompProfile:
|
||||
{{- toYaml . | nindent 14 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.extraVolumeMounts }}
|
||||
volumeMounts:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.extraContainers }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.extraVolumes }}
|
||||
volumes:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
175
haproxy-unified-gateway/templates/controller-deployment.yaml
Normal file
175
haproxy-unified-gateway/templates/controller-deployment.yaml
Normal file
@@ -0,0 +1,175 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if eq .Values.controller.kind "Deployment" }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
{{- with .Values.controller.extraLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if not .Values.controller.autoscaling.enabled }}
|
||||
replicas: {{ .Values.controller.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "haproxy-unified-gateway.selectorLabels" . | nindent 6 }}
|
||||
{{- with .Values.controller.strategy }}
|
||||
strategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.selectorLabels" . | nindent 8 }}
|
||||
{{- with .Values.controller.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "haproxy-unified-gateway.serviceAccountName" . }}
|
||||
{{- with .Values.controller.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.unprivileged }}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
{{- end }}
|
||||
{{- with .Values.controller.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.priorityClassName }}
|
||||
priorityClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.dnsPolicy }}
|
||||
dnsPolicy: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.dnsConfig }}
|
||||
dnsConfig:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.initContainers }}
|
||||
initContainers:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ include "haproxy-unified-gateway.name" . }}
|
||||
image: {{ include "haproxy-unified-gateway.image" . }}
|
||||
imagePullPolicy: {{ .Values.controller.image.pullPolicy }}
|
||||
args:
|
||||
{{- if or .Values.hugconf.create .Values.controller.hugconfCrd }}
|
||||
- --hugconf-crd={{ include "haproxy-unified-gateway.hugconfCrd" . }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.metricsAuth }}
|
||||
- --metrics-auth={{ . }}
|
||||
{{- end }}
|
||||
{{- range .Values.controller.extraArgs }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
ports:
|
||||
{{- range $key, $value := .Values.controller.containerPort }}
|
||||
- name: {{ $key }}
|
||||
containerPort: {{ $value }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
{{- with .Values.controller.extraEnvs }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.livenessProbe }}
|
||||
livenessProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.readinessProbe }}
|
||||
readinessProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.startupProbe }}
|
||||
startupProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.unprivileged }}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
allowPrivilegeEscalation: {{ .Values.controller.allowPrivilegeEscalation }}
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
{{- with .Values.controller.seccompProfile }}
|
||||
seccompProfile:
|
||||
{{- toYaml . | nindent 14 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.extraVolumeMounts }}
|
||||
volumeMounts:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.extraContainers }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.extraVolumes }}
|
||||
volumes:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
96
haproxy-unified-gateway/templates/controller-gwapijob.yaml
Normal file
96
haproxy-unified-gateway/templates/controller-gwapijob.yaml
Normal file
@@ -0,0 +1,96 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.gwapijob.enabled }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.gwapijob.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.gwapijobLabels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "0"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
"argocd.argoproj.io/hook": PostSync
|
||||
{{- with .Values.gwapijob.podAnnotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.gwapijob.ttlSecondsAfterFinished }}
|
||||
ttlSecondsAfterFinished: {{ . }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.gwapijobLabels" . | nindent 8 }}
|
||||
{{- with .Values.gwapijob.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "haproxy-unified-gateway.crdjob.saName" . }}
|
||||
restartPolicy: Never
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
{{- with .Values.controller.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: gwapijob
|
||||
{{- if .Values.gwapijob.image.repository }}
|
||||
image: {{ printf "%s:%s" .Values.gwapijob.image.repository (default .Chart.AppVersion .Values.gwapijob.image.tag) }}
|
||||
{{- else }}
|
||||
image: {{ include "haproxy-unified-gateway.image" . }}
|
||||
{{- end }}
|
||||
imagePullPolicy: {{ .Values.controller.image.pullPolicy }}
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
command:
|
||||
- /usr/local/sbin/hug
|
||||
- --job-gwapi={{ .Values.gwapijob.version }}
|
||||
{{- with .Values.gwapijob.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gwapijob.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gwapijob.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.gwapijob.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
backoffLimit: 0
|
||||
{{- end }}
|
||||
53
haproxy-unified-gateway/templates/controller-hpa.yaml
Normal file
53
haproxy-unified-gateway/templates/controller-hpa.yaml
Normal file
@@ -0,0 +1,53 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and .Values.controller.autoscaling.enabled (not .Values.controller.keda.enabled) }}
|
||||
{{- if semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
apiVersion: autoscaling/v2
|
||||
{{- else }}
|
||||
apiVersion: autoscaling/v2beta2
|
||||
{{- end }}
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
minReplicas: {{ .Values.controller.autoscaling.minReplicas }}
|
||||
maxReplicas: {{ .Values.controller.autoscaling.maxReplicas }}
|
||||
metrics:
|
||||
{{- if .Values.controller.autoscaling.targetCPUUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.controller.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.controller.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,125 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.hugconf.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.hugconfCleanup.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-delete
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.hugconfCleanup.fullname" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-delete
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "gate.v3.haproxy.org"
|
||||
resources:
|
||||
- hugconfs
|
||||
verbs:
|
||||
- get
|
||||
- delete
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.hugconfCleanup.fullname" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-delete
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "haproxy-unified-gateway.hugconfCleanup.fullname" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "haproxy-unified-gateway.hugconfCleanup.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.hugconfCleanup.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-delete
|
||||
"helm.sh/hook-weight": "0"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 60
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 8 }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "haproxy-unified-gateway.hugconfCleanup.fullname" . }}
|
||||
restartPolicy: Never
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
{{- with .Values.controller.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: hugconf-cleanup
|
||||
image: {{ include "haproxy-unified-gateway.image" . }}
|
||||
imagePullPolicy: {{ .Values.controller.image.pullPolicy }}
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
APISERVER="https://kubernetes.default.svc"
|
||||
TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
|
||||
CACERT="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
|
||||
wget --header="Authorization: Bearer ${TOKEN}" \
|
||||
--ca-certificate="${CACERT}" \
|
||||
--method=DELETE \
|
||||
-q -O /dev/null \
|
||||
"${APISERVER}/apis/gate.v3.haproxy.org/v3/namespaces/{{ include "haproxy-unified-gateway.namespace" . }}/hugconfs/{{ .Values.hugconf.name }}" 2>/dev/null || true
|
||||
backoffLimit: 1
|
||||
{{- end }}
|
||||
45
haproxy-unified-gateway/templates/controller-hugconf.yaml
Normal file
45
haproxy-unified-gateway/templates/controller-hugconf.yaml
Normal file
@@ -0,0 +1,45 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.hugconf.create }}
|
||||
apiVersion: gate.v3.haproxy.org/v3
|
||||
kind: HugConf
|
||||
metadata:
|
||||
name: {{ .Values.hugconf.name }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation
|
||||
"argocd.argoproj.io/hook": PostSync
|
||||
spec:
|
||||
logging:
|
||||
defaultLevel: {{ .Values.hugconf.logging.defaultLevel | quote }}
|
||||
{{- with .Values.hugconf.logging.categoryLevelList }}
|
||||
categoryLevelList:
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with .Values.hugconf.globalRef }}
|
||||
globalRef:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.hugconf.defaultsRef }}
|
||||
defaultsRef:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
57
haproxy-unified-gateway/templates/controller-keda.yaml
Normal file
57
haproxy-unified-gateway/templates/controller-keda.yaml
Normal file
@@ -0,0 +1,57 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and (eq .Values.controller.kind "Deployment") .Values.controller.keda.enabled }}
|
||||
apiVersion: keda.sh/v1alpha1
|
||||
kind: ScaledObject
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
{{- if .Values.controller.keda.scaledObject.annotations }}
|
||||
annotations: {{ toYaml .Values.controller.keda.scaledObject.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
pollingInterval: {{ .Values.controller.keda.pollingInterval }}
|
||||
cooldownPeriod: {{ .Values.controller.keda.cooldownPeriod }}
|
||||
minReplicaCount: {{ .Values.controller.keda.minReplicas }}
|
||||
maxReplicaCount: {{ .Values.controller.keda.maxReplicas }}
|
||||
triggers:
|
||||
{{- with .Values.controller.keda.triggers }}
|
||||
{{ toYaml . | indent 2 }}
|
||||
{{ end }}
|
||||
{{- with .Values.controller.keda.fallback }}
|
||||
fallback:
|
||||
{{ toYaml . | indent 4 }}
|
||||
{{- end }}
|
||||
advanced:
|
||||
restoreToOriginalReplicaCount: {{ .Values.controller.keda.restoreToOriginalReplicaCount }}
|
||||
{{- if .Values.controller.keda.horizontalPodAutoscalerConfig }}
|
||||
horizontalPodAutoscalerConfig:
|
||||
{{- if .Values.controller.keda.horizontalPodAutoscalerConfig.name }}
|
||||
name: {{ .Values.controller.keda.horizontalPodAutoscalerConfig.name }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.keda.horizontalPodAutoscalerConfig.behavior }}
|
||||
behavior:
|
||||
{{ with .Values.controller.keda.horizontalPodAutoscalerConfig.behavior -}}
|
||||
{{ toYaml . | indent 8 }}
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,35 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.controller.podDisruptionBudget.enabled }}
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "haproxy-unified-gateway.selectorLabels" . | nindent 6 }}
|
||||
{{- if .Values.controller.podDisruptionBudget.minAvailable }}
|
||||
minAvailable: {{ .Values.controller.podDisruptionBudget.minAvailable }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.podDisruptionBudget.maxUnavailable }}
|
||||
maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
37
haproxy-unified-gateway/templates/controller-podmonitor.yaml
Normal file
37
haproxy-unified-gateway/templates/controller-podmonitor.yaml
Normal file
@@ -0,0 +1,37 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") .Values.controller.podMonitor.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: PodMonitor
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.podMonitorName" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
{{- with .Values.controller.podMonitor.extraLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
podMetricsEndpoints:
|
||||
{{- toYaml .Values.controller.podMonitor.endpoints | nindent 4 }}
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "haproxy-unified-gateway.selectorLabels" . | nindent 6 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,81 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if (semverCompare "<1.25.0-0" .Capabilities.KubeVersion.Version) }}
|
||||
{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled }}
|
||||
{{- $useHostNetwork := false }}
|
||||
{{- $useHostPort := false }}
|
||||
{{- if eq .Values.controller.kind "DaemonSet" }}
|
||||
{{- $useHostNetwork = .Values.controller.daemonset.useHostNetwork }}
|
||||
{{- $useHostPort = .Values.controller.daemonset.useHostPort }}
|
||||
{{- end }}
|
||||
{{- if or (.Capabilities.APIVersions.Has "policy/v1/PodSecurityPolicy") (semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version) }}
|
||||
apiVersion: policy/v1
|
||||
{{- else }}
|
||||
apiVersion: policy/v1beta1
|
||||
{{- end }}
|
||||
kind: PodSecurityPolicy
|
||||
metadata:
|
||||
{{- if .Values.podSecurityPolicy.annotations }}
|
||||
annotations:
|
||||
{{ toYaml .Values.podSecurityPolicy.annotations | indent 4 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
annotations:
|
||||
seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default'
|
||||
apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
|
||||
seccomp.security.alpha.kubernetes.io/defaultProfileName: 'runtime/default'
|
||||
apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
|
||||
spec:
|
||||
allowPrivilegeEscalation: {{ .Values.controller.allowPrivilegeEscalation }}
|
||||
allowedCapabilities:
|
||||
- NET_BIND_SERVICE
|
||||
defaultAllowPrivilegeEscalation: false
|
||||
fsGroup:
|
||||
rule: MustRunAs
|
||||
ranges:
|
||||
- max: 65535
|
||||
min: 1
|
||||
hostIPC: false
|
||||
{{- if $useHostNetwork }}
|
||||
hostNetwork: true
|
||||
{{- end }}
|
||||
{{- if or $useHostPort $useHostNetwork }}
|
||||
hostPorts:
|
||||
{{- range $key, $value := .Values.controller.containerPort }}
|
||||
- min: {{ $value }}
|
||||
max: {{ $value }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
hostPID: false
|
||||
privileged: false
|
||||
runAsUser:
|
||||
rule: RunAsAny
|
||||
seLinux:
|
||||
rule: RunAsAny
|
||||
supplementalGroups:
|
||||
rule: MustRunAs
|
||||
ranges:
|
||||
- max: 65535
|
||||
min: 1
|
||||
volumes:
|
||||
- configMap
|
||||
- downwardAPI
|
||||
- secret
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
34
haproxy-unified-gateway/templates/controller-role.yaml
Normal file
34
haproxy-unified-gateway/templates/controller-role.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "policy"
|
||||
resources:
|
||||
- podsecuritypolicies
|
||||
verbs:
|
||||
- use
|
||||
resourceNames:
|
||||
- {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,33 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "haproxy-unified-gateway.serviceAccountName" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,45 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and .Values.controller.serviceMonitor.enabled .Values.controller.service.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.metricsServiceName" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
{{- with .Values.controller.service.metrics.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.service.metrics.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.controller.service.metrics.type }}
|
||||
selector:
|
||||
{{- include "haproxy-unified-gateway.selectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
- name: stat
|
||||
port: {{ .Values.controller.service.stat.port }}
|
||||
targetPort: {{ .Values.controller.service.stat.targetPort }}
|
||||
protocol: TCP
|
||||
- name: metrics
|
||||
port: {{ index .Values.controller.service "controller-metrics" "port" }}
|
||||
targetPort: {{ index .Values.controller.service "controller-metrics" "targetPort" }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
64
haproxy-unified-gateway/templates/controller-service.yaml
Normal file
64
haproxy-unified-gateway/templates/controller-service.yaml
Normal file
@@ -0,0 +1,64 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.controller.service.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.fullname" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
{{- with .Values.controller.service.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.controller.service.type }}
|
||||
{{- with .Values.controller.service.externalTrafficPolicy }}
|
||||
externalTrafficPolicy: {{ . }}
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "haproxy-unified-gateway.selectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.controller.service.http.port }}
|
||||
targetPort: {{ .Values.controller.service.http.targetPort }}
|
||||
protocol: TCP
|
||||
{{- if and (eq .Values.controller.service.type "NodePort") .Values.controller.service.http.nodePort }}
|
||||
nodePort: {{ .Values.controller.service.http.nodePort }}
|
||||
{{- end }}
|
||||
- name: https
|
||||
port: {{ .Values.controller.service.https.port }}
|
||||
targetPort: {{ .Values.controller.service.https.targetPort }}
|
||||
protocol: TCP
|
||||
{{- if and (eq .Values.controller.service.type "NodePort") .Values.controller.service.https.nodePort }}
|
||||
nodePort: {{ .Values.controller.service.https.nodePort }}
|
||||
{{- end }}
|
||||
- name: stat
|
||||
port: {{ .Values.controller.service.stat.port }}
|
||||
targetPort: {{ .Values.controller.service.stat.targetPort }}
|
||||
protocol: TCP
|
||||
{{- if and (eq .Values.controller.service.type "NodePort") .Values.controller.service.stat.nodePort }}
|
||||
nodePort: {{ .Values.controller.service.stat.nodePort }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.service.extraPorts }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,29 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.serviceAccountName" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,37 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") .Values.controller.serviceMonitor.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.serviceMonitorName" . }}
|
||||
namespace: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
{{- with .Values.controller.serviceMonitor.extraLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
endpoints:
|
||||
{{- toYaml .Values.controller.serviceMonitor.endpoints | nindent 4 }}
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "haproxy-unified-gateway.selectorLabels" . | nindent 6 }}
|
||||
{{- end }}
|
||||
27
haproxy-unified-gateway/templates/namespace.yaml
Normal file
27
haproxy-unified-gateway/templates/namespace.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
{{/*
|
||||
Copyright 2026 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.namespace.create }}
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: {{ include "haproxy-unified-gateway.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy-unified-gateway.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install
|
||||
"helm.sh/hook-weight": "-1"
|
||||
{{- end }}
|
||||
389
haproxy-unified-gateway/values.yaml
Normal file
389
haproxy-unified-gateway/values.yaml
Normal file
@@ -0,0 +1,389 @@
|
||||
# Copyright 2026 HAProxy Technologies LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
## HAProxy Unified Gateway Helm Chart - values.yaml
|
||||
|
||||
# -- PodSecurityPolicy configuration (deprecated in K8s 1.21, removed in 1.25)
|
||||
podSecurityPolicy:
|
||||
## Specify pod annotations
|
||||
## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor
|
||||
## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp
|
||||
## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl
|
||||
annotations: {}
|
||||
# apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
|
||||
# apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
|
||||
# seccomp.security.alpha.kubernetes.io/allowedProfileNames: runtime/default
|
||||
# seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default
|
||||
enabled: false
|
||||
|
||||
# -- Create RBAC resources
|
||||
rbac:
|
||||
create: true
|
||||
|
||||
# -- Create a namespace (uses Helm pre-install hook)
|
||||
namespace:
|
||||
create: false
|
||||
|
||||
# -- ServiceAccount configuration
|
||||
serviceAccount:
|
||||
# -- Create a ServiceAccount
|
||||
create: true
|
||||
# -- ServiceAccount name (generated if not set)
|
||||
name: ""
|
||||
# -- Annotations to add to the ServiceAccount
|
||||
annotations: {}
|
||||
|
||||
# -- Controller configuration
|
||||
controller:
|
||||
# -- Controller name
|
||||
name: controller
|
||||
|
||||
# -- Container image configuration
|
||||
image:
|
||||
repository: docker.io/haproxytech/haproxy-unified-gateway
|
||||
tag: "" # defaults to appVersion
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# -- Image pull secrets
|
||||
imagePullSecrets: []
|
||||
|
||||
# -- Deployment or DaemonSet pod mode
|
||||
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
|
||||
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
|
||||
kind: Deployment # can be 'Deployment' or 'DaemonSet'
|
||||
|
||||
# -- Number of replicas (only for Deployment mode)
|
||||
replicaCount: 1
|
||||
|
||||
# -- HugConf CRD reference (namespace/name)
|
||||
# If empty, defaults to "<release-namespace>/hugconf"
|
||||
hugconfCrd: ""
|
||||
|
||||
# -- Metrics authentication mode for the controller metrics endpoint (port 31060)
|
||||
# Supported values: "none", "kube-rbac", "basic"
|
||||
# - none: HTTP, no authentication
|
||||
# - kube-rbac: HTTPS with Kubernetes TokenReview/SubjectAccessReview
|
||||
# - basic: HTTPS with HTTP Basic Authentication (set credentials via extraArgs)
|
||||
metricsAuth: kube-rbac
|
||||
|
||||
# -- Extra arguments to pass to the controller
|
||||
extraArgs: []
|
||||
|
||||
# -- Container ports
|
||||
containerPort:
|
||||
http: 31080
|
||||
https: 31443
|
||||
stat: 31024
|
||||
metrics: 31060
|
||||
|
||||
# -- Resource requests and limits
|
||||
resources:
|
||||
limits:
|
||||
memory: 2560Mi
|
||||
requests:
|
||||
memory: 2048Mi
|
||||
|
||||
## Running container without root privileges
|
||||
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
|
||||
unprivileged: true
|
||||
|
||||
## Privilege escalation
|
||||
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
|
||||
allowPrivilegeEscalation: false
|
||||
|
||||
## Restricts container syscalls
|
||||
## ref: https://kubernetes.io/docs/tutorials/security/seccomp/
|
||||
## Supported types: RuntimeDefault, Localhost, Unconfined
|
||||
## Set to empty ({}) to disable seccomp profile
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
# localhostProfile: my-profiles/profile.json # only for type: Localhost
|
||||
|
||||
# -- Pod-level security context
|
||||
podSecurityContext: {}
|
||||
|
||||
# -- Liveness probe configuration
|
||||
livenessProbe: {}
|
||||
|
||||
# -- Readiness probe configuration
|
||||
readinessProbe: {}
|
||||
|
||||
# -- Startup probe configuration
|
||||
startupProbe: {}
|
||||
|
||||
# -- Node selector for pod scheduling
|
||||
nodeSelector: {}
|
||||
|
||||
# -- Tolerations for pod scheduling
|
||||
tolerations: []
|
||||
|
||||
# -- Affinity rules for pod scheduling
|
||||
affinity: {}
|
||||
|
||||
# -- Topology spread constraints
|
||||
topologySpreadConstraints: []
|
||||
|
||||
# -- Extra environment variables
|
||||
extraEnvs: []
|
||||
|
||||
# -- Extra volume mounts
|
||||
extraVolumeMounts: []
|
||||
|
||||
# -- Extra volumes
|
||||
extraVolumes: []
|
||||
|
||||
# -- Extra init containers
|
||||
initContainers: []
|
||||
|
||||
# -- Extra sidecar containers
|
||||
extraContainers: []
|
||||
|
||||
# -- Pod annotations
|
||||
podAnnotations: {}
|
||||
|
||||
# -- Pod labels
|
||||
podLabels: {}
|
||||
|
||||
# -- Extra labels for the Deployment
|
||||
extraLabels: {}
|
||||
|
||||
# -- Update strategy
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
|
||||
# -- Priority class name
|
||||
priorityClassName: ""
|
||||
|
||||
# -- DNS policy
|
||||
dnsPolicy: ""
|
||||
|
||||
# -- DNS config
|
||||
dnsConfig: {}
|
||||
|
||||
# -- DaemonSet-specific configuration (only used when kind is 'DaemonSet')
|
||||
daemonset:
|
||||
useHostNetwork: false # also modify dnsPolicy accordingly
|
||||
useHostPort: false
|
||||
hostIP: null
|
||||
hostPorts:
|
||||
http: 80
|
||||
https: 443
|
||||
stat: 1024
|
||||
metrics: 31060
|
||||
|
||||
# -- Service configuration
|
||||
service:
|
||||
# -- Enable the Service
|
||||
enabled: true
|
||||
# -- Service type
|
||||
type: NodePort
|
||||
# -- Service annotations
|
||||
annotations: {}
|
||||
# -- Service labels
|
||||
labels: {}
|
||||
# -- External traffic policy
|
||||
externalTrafficPolicy: ""
|
||||
# -- HTTP port configuration
|
||||
http:
|
||||
port: 31080
|
||||
targetPort: 31080
|
||||
nodePort: 31080
|
||||
# -- HTTPS port configuration
|
||||
https:
|
||||
port: 31443
|
||||
targetPort: 31443
|
||||
nodePort: 31443
|
||||
# -- Stats port configuration
|
||||
stat:
|
||||
port: 31024
|
||||
targetPort: 31024
|
||||
nodePort: ""
|
||||
# -- Extra ports to expose
|
||||
extraPorts: []
|
||||
# -- Controller metrics port configuration (hug_* prometheus metrics)
|
||||
controller-metrics:
|
||||
port: 31060
|
||||
targetPort: 31060
|
||||
# -- Metrics service configuration (created when serviceMonitor is enabled)
|
||||
metrics:
|
||||
type: ClusterIP
|
||||
annotations: {}
|
||||
labels: {}
|
||||
|
||||
# -- ServiceMonitor configuration (requires Prometheus Operator)
|
||||
## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md
|
||||
## Note: requires Prometheus Operator to be able to work, for example:
|
||||
## helm install prometheus prometheus-community/kube-prometheus-stack \
|
||||
## --set prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues=false \
|
||||
## --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false
|
||||
serviceMonitor:
|
||||
# -- Enable ServiceMonitor (should not be enabled together with podMonitor)
|
||||
enabled: false
|
||||
# -- Extra labels for ServiceMonitor target discovery
|
||||
extraLabels: {}
|
||||
# -- ServiceMonitor endpoints configuration
|
||||
endpoints:
|
||||
- port: stat
|
||||
path: /metrics
|
||||
scheme: http
|
||||
interval: 30s
|
||||
- port: metrics
|
||||
path: /metrics
|
||||
scheme: https
|
||||
interval: 30s
|
||||
tlsConfig:
|
||||
insecureSkipVerify: true
|
||||
bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
|
||||
# -- PodMonitor configuration (requires Prometheus Operator)
|
||||
## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md
|
||||
podMonitor:
|
||||
# -- Enable PodMonitor (should not be enabled together with serviceMonitor)
|
||||
enabled: false
|
||||
# -- Extra labels for PodMonitor target discovery
|
||||
extraLabels: {}
|
||||
# -- PodMonitor endpoints configuration
|
||||
endpoints:
|
||||
- port: stat
|
||||
path: /metrics
|
||||
scheme: http
|
||||
interval: 30s
|
||||
- port: metrics
|
||||
path: /metrics
|
||||
scheme: https
|
||||
interval: 30s
|
||||
tlsConfig:
|
||||
insecureSkipVerify: true
|
||||
bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
|
||||
# -- HorizontalPodAutoscaler configuration
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 10
|
||||
targetCPUUtilizationPercentage: 80
|
||||
# targetMemoryUtilizationPercentage: 80
|
||||
|
||||
# -- KEDA ScaledObject configuration (mutually exclusive with autoscaling)
|
||||
keda:
|
||||
enabled: false
|
||||
minReplicas: 2
|
||||
maxReplicas: 20
|
||||
pollingInterval: 30
|
||||
cooldownPeriod: 300
|
||||
restoreToOriginalReplicaCount: false
|
||||
# fallback:
|
||||
# failureThreshold: 3
|
||||
# replicas: 11
|
||||
scaledObject:
|
||||
annotations: {}
|
||||
horizontalPodAutoscalerConfig: {}
|
||||
# name: ""
|
||||
# behavior:
|
||||
# scaleDown:
|
||||
# stabilizationWindowSeconds: 300
|
||||
# policies:
|
||||
# - type: Pods
|
||||
# value: 1
|
||||
# periodSeconds: 300
|
||||
triggers: []
|
||||
# - type: prometheus
|
||||
# metadata:
|
||||
# serverAddress: http://<prometheus-host>:9090
|
||||
# metricName: haproxy_process_idle_time_percent
|
||||
# threshold: '50'
|
||||
# query: avg(100-avg_over_time(haproxy_process_idle_time_percent{job="haproxy-unified-gateway"}[2m]))
|
||||
|
||||
# -- PodDisruptionBudget configuration
|
||||
podDisruptionBudget:
|
||||
enabled: false
|
||||
# minAvailable: 1
|
||||
# maxUnavailable: 1
|
||||
|
||||
# -- HugConf custom resource configuration
|
||||
hugconf:
|
||||
# -- Create a HugConf resource
|
||||
create: true
|
||||
# -- HugConf name
|
||||
name: hugconf
|
||||
# -- Logging configuration
|
||||
logging:
|
||||
# -- Default log level
|
||||
defaultLevel: Info
|
||||
# -- Per-category log level overrides
|
||||
categoryLevelList:
|
||||
- category: "k8s"
|
||||
level: "Error"
|
||||
- category: "gate"
|
||||
level: "Info"
|
||||
- category: "status"
|
||||
level: "Info"
|
||||
- category: "batch"
|
||||
level: "Error"
|
||||
- category: "app"
|
||||
level: "Info"
|
||||
- category: "certs-storage"
|
||||
level: "Info"
|
||||
# -- Global configuration reference (group, kind, name, namespace)
|
||||
globalRef: {}
|
||||
# group: gate.v3.haproxy.org
|
||||
# kind: Global
|
||||
# name: global
|
||||
# namespace: haproxy-unified-gateway
|
||||
# -- Defaults configuration reference (group, kind, name, namespace)
|
||||
defaultsRef: {}
|
||||
# group: gate.v3.haproxy.org
|
||||
# kind: Defaults
|
||||
# name: haproxytech
|
||||
# namespace: haproxy-unified-gateway
|
||||
|
||||
# -- CRD Job configuration
|
||||
crdjob:
|
||||
# -- Enable the CRD installation Job (Helm hook)
|
||||
enabled: true
|
||||
# -- Additional pod annotations
|
||||
podAnnotations: {}
|
||||
# -- TTL for completed jobs (seconds)
|
||||
ttlSecondsAfterFinished: 60
|
||||
# -- Node selector
|
||||
nodeSelector: {}
|
||||
# -- Tolerations
|
||||
tolerations: []
|
||||
# -- Affinity
|
||||
affinity: {}
|
||||
# -- Resources for CRD job
|
||||
resources: {}
|
||||
# -- Image override (defaults to controller image)
|
||||
image: {}
|
||||
|
||||
# -- Gateway API Job configuration
|
||||
gwapijob:
|
||||
# -- Enable the Gateway API CRD installation Job (Helm hook)
|
||||
enabled: true
|
||||
# -- Gateway API version to install
|
||||
version: "1.3.0"
|
||||
# -- Additional pod annotations
|
||||
podAnnotations: {}
|
||||
# -- TTL for completed jobs (seconds)
|
||||
ttlSecondsAfterFinished: 60
|
||||
# -- Node selector
|
||||
nodeSelector: {}
|
||||
# -- Tolerations
|
||||
tolerations: []
|
||||
# -- Affinity
|
||||
affinity: {}
|
||||
# -- Resources for Gateway API job
|
||||
resources: {}
|
||||
# -- Image override (defaults to controller image)
|
||||
image: {}
|
||||
23
haproxy/.helmignore
Normal file
23
haproxy/.helmignore
Normal file
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
35
haproxy/Chart.yaml
Normal file
35
haproxy/Chart.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
# Copyright 2020 HAProxy Technologies LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
apiVersion: v2
|
||||
name: haproxy
|
||||
description: A Helm chart for HAProxy on Kubernetes
|
||||
type: application
|
||||
version: 1.28.1
|
||||
appVersion: 3.3.6
|
||||
kubeVersion: ">=1.17.0-0"
|
||||
keywords:
|
||||
- haproxy
|
||||
home: https://github.com/haproxytech/helm-charts/tree/main/haproxy
|
||||
sources:
|
||||
- http://www.haproxy.org/
|
||||
icon: https://raw.githubusercontent.com/haproxytech/helm-charts/main/haproxy/chart-icon.png
|
||||
maintainers:
|
||||
- name: Dinko Korunic
|
||||
email: dkorunic@haproxy.com
|
||||
engine: gotpl
|
||||
annotations:
|
||||
artifacthub.io/changes: |
|
||||
- Update base image to HAProxy 3.3.6
|
||||
- Fix newline issue with YAML normalisation (#344)
|
||||
378
haproxy/README.md
Normal file
378
haproxy/README.md
Normal file
@@ -0,0 +1,378 @@
|
||||
# 
|
||||
|
||||
## HAProxy Helm Chart
|
||||
|
||||
## Introduction
|
||||
|
||||
This chart bootstraps an HAProxy load balancer as deployment/daemonset on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. As oposed to [HAProxy Kubernetes Ingress Controller](https://github.com/haproxytech/helm-charts/tree/main/kubernetes-ingress) Chart, HAProxy is installed as a regular application and not as an Ingress Controller.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Kubernetes 1.17+ (recommended 1.20+)
|
||||
- Helm 3.6+ (recommended 3.7+)
|
||||
|
||||
## Before you begin
|
||||
|
||||
### Setup a Kubernetes Cluster
|
||||
|
||||
The quickest way to setup a Kubernetes cluster is with [Azure Kubernetes Service](https://azure.microsoft.com/en-us/services/kubernetes-service/), [AWS Elastic Kubernetes Service](https://aws.amazon.com/eks/) or [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) using their respective quick-start guides.
|
||||
|
||||
For setting up Kubernetes on other cloud platforms or bare-metal servers refer to the Kubernetes [getting started guide](http://kubernetes.io/docs/getting-started-guides/).
|
||||
|
||||
### Install Helm
|
||||
|
||||
Get the latest [Helm release](https://github.com/helm/helm#install).
|
||||
|
||||
### Add Helm chart repo
|
||||
|
||||
Once you have Helm installed, add the haproxytech Chat Repository as follows:
|
||||
|
||||
```console
|
||||
helm repo add haproxytech https://haproxytech.github.io/helm-charts
|
||||
helm repo update
|
||||
```
|
||||
|
||||
Alternatively if you want to proceed with just OCI-based repository, skip this step and follow the installation with OCI.
|
||||
|
||||
## Install the chart
|
||||
|
||||
To install the chart with Helm v3 as _my-release_ deployment:
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy
|
||||
```
|
||||
|
||||
**_NOTE_**: To install the chart with Helm v2 (legacy Helm) the syntax requires adding deployment name to `--name` parameter:
|
||||
|
||||
```console
|
||||
helm install haproxytech/haproxy \
|
||||
--name my-release
|
||||
```
|
||||
|
||||
Alternatively also have OCI-based repository available for simplified access:
|
||||
|
||||
```console
|
||||
helm install oci://ghcr.io/haproxytech/helm-charts/haproxy --version 1.24.0
|
||||
```
|
||||
|
||||
### Installing with unique name
|
||||
|
||||
To auto-generate resource names when installing, use the following:
|
||||
|
||||
```console
|
||||
helm install haproxytech/haproxy \
|
||||
--generate-name
|
||||
```
|
||||
|
||||
### Installing from a private registry
|
||||
|
||||
To install the chart using a private registry for HAProxy (for instance to use a HAProxy Enterprise image) into a separate namespace _prod_.
|
||||
|
||||
**_NOTE_**: Helm v3 requires namespace to be precreated (eg. with `kubectl create namespace prod`)
|
||||
|
||||
```console
|
||||
helm install my-haproxy haproxytech/haproxy \
|
||||
--namespace prod \
|
||||
--set image.tag=latest \
|
||||
--set image.repository=myregistry.domain.com/imagename \
|
||||
--set imageCredentials.registry=myregistry.domain.com \
|
||||
--set imageCredentials.username=MYUSERNAME \
|
||||
--set imageCredentials.password=MYPASSWORD
|
||||
```
|
||||
|
||||
Alternatively, use a pre-configured (existing) imagePullSecret in the same namespace:
|
||||
|
||||
```console
|
||||
helm install my-ingress haproxytech/haproxy \
|
||||
--namespace prod \
|
||||
--set image.tag=SOMETAG \
|
||||
--set existingImagePullSecret name-of-existing-image-pull-secret
|
||||
```
|
||||
|
||||
**_NOTE_**: Enterprise images using S6 overlay need default CMD arguments disabled (more about YAML configuration file for Helm can be found in a separate paragraph below):
|
||||
|
||||
```yaml
|
||||
args:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
### Installing as DaemonSet
|
||||
|
||||
Default image mode is [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), but it is possible to use [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) as well:
|
||||
|
||||
```console
|
||||
helm install my-haproxy2 haproxytech/haproxy \
|
||||
--set kind=DaemonSet
|
||||
```
|
||||
|
||||
**_NOTE_**: With helm `--set` it is needed to put quotes and escape dots in the annotation key and commas in the value string.
|
||||
|
||||
### Installing with Horizontal Pod Autoscaler
|
||||
|
||||
[HPA](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) automatically scales number of replicas in Deployment or Replication Controller and adjusts replica count. Therefore we want to unset default replicaCount by setting corresponding key value to null and enable autoscaling:
|
||||
|
||||
```console
|
||||
helm install my-haproxy3 haproxytech/haproxy \
|
||||
--set kind=Deployment \
|
||||
--set replicaCount=null \
|
||||
--set autoscaling.enabled=true \
|
||||
--set autoscaling.targetCPUUtilizationPercentage=80
|
||||
```
|
||||
|
||||
**_NOTE_**: Make sure to look into other tunable values for HPA documented in [values.yaml](values.yaml).
|
||||
|
||||
### Installing with service annotations
|
||||
|
||||
On some environments like EKS and GKE there might be a need to pass service annotations. Syntax can become a little tedious however:
|
||||
|
||||
```console
|
||||
helm install my-haproxy4 haproxytech/haproxy \
|
||||
--set kind=DaemonSet \
|
||||
--set service.type=LoadBalancer \
|
||||
--set service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-internal"="0.0.0.0/0" \
|
||||
--set service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-cross-zone-load-balancing-enabled"="true"
|
||||
```
|
||||
|
||||
**_NOTE_**: With helm `--set` it is needed to put quotes and escape dots in the annotation key and commas in the value string.
|
||||
|
||||
### Using values from YAML file
|
||||
|
||||
As opposed to using many `--set` invocations, much simpler approach is to define value overrides in a separate YAML file and specify them when invoking Helm.
|
||||
The `config` block can also support using helm templates to populate dynamic values, e.g. `{{ .Release.Name }}`.
|
||||
|
||||
_mylb.yaml_:
|
||||
|
||||
```yaml
|
||||
kind: DaemonSet
|
||||
config: |
|
||||
global
|
||||
log stdout format raw local0
|
||||
daemon
|
||||
maxconn 1024
|
||||
defaults
|
||||
log global
|
||||
timeout client 60s
|
||||
timeout connect 60s
|
||||
timeout server {{ .Values.global.serverTimeout }}
|
||||
frontend fe_main
|
||||
bind :80
|
||||
default_backend be_main
|
||||
backend be_main
|
||||
server web1 10.0.0.1:8080 check
|
||||
server web2 {{ .Release.Name }}-web:8080 check
|
||||
service:
|
||||
type: LoadBalancer
|
||||
annotations:
|
||||
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
|
||||
service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
|
||||
```
|
||||
|
||||
And invoking Helm becomes (compare to the previous example):
|
||||
|
||||
```console
|
||||
helm install my-haproxy5 -f mylb.yml haproxytech/haproxy
|
||||
```
|
||||
|
||||
### Using secrets in additional volume mounts
|
||||
|
||||
In order to e.g. support SSL certificates, you can mount additional volumes from secrets:
|
||||
|
||||
_mylb.yaml_:
|
||||
|
||||
```yaml
|
||||
service:
|
||||
type: LoadBalancer
|
||||
config: |
|
||||
global
|
||||
log stdout format raw local0
|
||||
daemon
|
||||
maxconn 1024
|
||||
defaults
|
||||
log global
|
||||
timeout client 60s
|
||||
timeout connect 60s
|
||||
timeout server 60s
|
||||
frontend fe_main
|
||||
mode http
|
||||
bind :80
|
||||
bind :443 ssl crt /usr/local/etc/ssl/tls.crt
|
||||
http-request redirect scheme https code 301 unless { ssl_fc }
|
||||
default_backend be_main
|
||||
backend be_main
|
||||
mode http
|
||||
server web1 10.0.0.1:8080 check
|
||||
mountedSecrets:
|
||||
- volumeName: ssl-certificate
|
||||
secretName: star-example-com
|
||||
mountPath: /usr/local/etc/ssl
|
||||
```
|
||||
|
||||
The above example assumes that there is a certificate in key `tls.crt` of a secret called `star-example-com`.
|
||||
|
||||
### Using additional volumes and volumeMounts
|
||||
|
||||
In order to load data from other sources (e.g. to preload something inside an init-container) you can mount additional volumes to the container:
|
||||
|
||||
```yaml
|
||||
extraVolumes:
|
||||
- name: tls
|
||||
emptyDir: {}
|
||||
- name: tmp
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
|
||||
extraVolumeMounts:
|
||||
- name: tls
|
||||
mountPath: /etc/tls
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
```
|
||||
|
||||
### Using additional environment variables
|
||||
|
||||
In order to expose extra data (e.g. node and pod IP addresses) to haproxy, you can populate extra environment variables on the container:
|
||||
|
||||
```yaml
|
||||
extraEnvs:
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
```
|
||||
|
||||
### Automatic configuration reloading
|
||||
|
||||
In some cases, configuration changes are frequent and constantly restarting HAProxy is not optimal. For those cases the HAProxy hot-reload feature
|
||||
can be used.
|
||||
|
||||
In master-worker mode, sending a USR2 signal to the HAProxy process will trigger a configuration reload.
|
||||
|
||||
```yaml
|
||||
config: |
|
||||
global
|
||||
log stdout format raw local0
|
||||
master-worker
|
||||
daemon
|
||||
maxconn 1024
|
||||
defaults
|
||||
log global
|
||||
timeout client 60s
|
||||
timeout connect 60s
|
||||
timeout server 60s
|
||||
frontend fe_main
|
||||
mode http
|
||||
bind :80
|
||||
http-request redirect scheme https code 301 unless { ssl_fc }
|
||||
default_backend be_main
|
||||
backend be_main
|
||||
mode http
|
||||
server web1 10.0.0.1:8080 check
|
||||
```
|
||||
|
||||
Make sure you are not specifying subPath for any of your volumeMounts so that Kubernetes will automatically update the volumes created from
|
||||
ConfigMaps.
|
||||
|
||||
And finally, use some sidecar container which will be delivering the signal to the process. The shareProcessNamespace Pod property is required
|
||||
for the sidecars to be able to access other containers' processes.
|
||||
|
||||
```yaml
|
||||
shareProcessNamespace:
|
||||
enabled: true
|
||||
sidecarContainers:
|
||||
- name: reflex
|
||||
image: acim/go-reflex:1.17.3
|
||||
command: ["reflex", "-d", "fancy"]
|
||||
workingDir: /usr/local/etc/haproxy
|
||||
args:
|
||||
- -svr
|
||||
- "..data"
|
||||
- --
|
||||
- bash
|
||||
- -c
|
||||
- 'pkill -SIGUSR2 "haproxy|hapee-lb"'
|
||||
volumeMounts:
|
||||
- name: haproxy-config
|
||||
mountPath: /usr/local/etc/haproxy
|
||||
resources:
|
||||
limits:
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
```
|
||||
|
||||
## Installing as non-root with binding to privileged ports
|
||||
|
||||
To be able to bind to privileged ports such as tcp/80 and tcp/443 without root privileges (UID and GID are set to 1000 in the example, as HAProxy Docker image has UID/GID of 1000 reserved for HAProxy), there is a special workaround required as `NET_BIND_SERVICE` capability is [not propagated](https://github.com/kubernetes/kubernetes/issues/56374), so we need to use `initContainers` feature as well:
|
||||
|
||||
```yaml
|
||||
kind: DaemonSet
|
||||
containerPorts:
|
||||
http: 80
|
||||
https: 443
|
||||
stat: 1024
|
||||
daemonset:
|
||||
useHostNetwork: true
|
||||
useHostPort: true
|
||||
hostPorts:
|
||||
http: 80
|
||||
https: 443
|
||||
stat: 1024
|
||||
config: |
|
||||
global
|
||||
log stdout format raw local0
|
||||
maxconn 1024
|
||||
defaults
|
||||
log global
|
||||
timeout client 60s
|
||||
timeout connect 60s
|
||||
timeout server 60s
|
||||
frontend fe_main
|
||||
bind :80
|
||||
default_backend be_main
|
||||
backend be_main
|
||||
server web1 127.0.0.1:8080 check
|
||||
securityContext:
|
||||
enabled: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
initContainers:
|
||||
- name: sysctl
|
||||
image: "busybox:musl"
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- sysctl -w net.ipv4.ip_unprivileged_port_start=0
|
||||
securityContext:
|
||||
privileged: true
|
||||
```
|
||||
|
||||
## Upgrading the chart
|
||||
|
||||
To upgrade the _my-release_ deployment:
|
||||
|
||||
```console
|
||||
helm upgrade my-release haproxytech/haproxy
|
||||
```
|
||||
|
||||
## Uninstalling the chart
|
||||
|
||||
To uninstall/delete the _my-release_ deployment:
|
||||
|
||||
```console
|
||||
helm delete my-release
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
It is possible to generate a set of YAML files for testing/debugging:
|
||||
|
||||
```console
|
||||
helm install my-release haproxytech/haproxy \
|
||||
--debug \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome all contributions. Please refer to [guidelines](../CONTRIBUTING.md) on how to make a contribution.
|
||||
BIN
haproxy/chart-icon.png
Normal file
BIN
haproxy/chart-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
2
haproxy/ci/daemonset-basic-values.yaml
Normal file
2
haproxy/ci/daemonset-basic-values.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
kind: DaemonSet
|
||||
replicaCount: 2
|
||||
13
haproxy/ci/daemonset-hostnet-values.yaml
Normal file
13
haproxy/ci/daemonset-hostnet-values.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
kind: DaemonSet
|
||||
containerPorts:
|
||||
http: 8080
|
||||
https: 8443
|
||||
stat: 8024
|
||||
daemonset:
|
||||
useHostNetwork: true
|
||||
useHostPort: true
|
||||
hostPorts:
|
||||
http: 8080
|
||||
https: 8443
|
||||
stat: 8024
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
3
haproxy/ci/daemonset-ingress-values.yaml
Normal file
3
haproxy/ci/daemonset-ingress-values.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
kind: DaemonSet
|
||||
ingress:
|
||||
enabled: true
|
||||
4
haproxy/ci/daemonset-ipfamily-values.yaml
Normal file
4
haproxy/ci/daemonset-ipfamily-values.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
kind: DaemonSet
|
||||
service:
|
||||
ipFamilies: [IPv4]
|
||||
ipFamilyPolicy: SingleStack
|
||||
26
haproxy/ci/daemonset-probes-values.yaml
Normal file
26
haproxy/ci/daemonset-probes-values.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
kind: DaemonSet
|
||||
replicaCount: 2
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
initialDelaySeconds: 0
|
||||
timeoutSeconds: 1
|
||||
tcpSocket:
|
||||
port: 80
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
initialDelaySeconds: 0
|
||||
timeoutSeconds: 1
|
||||
tcpSocket:
|
||||
port: 80
|
||||
periodSeconds: 10
|
||||
startupProbe:
|
||||
failureThreshold: 20
|
||||
successThreshold: 1
|
||||
initialDelaySeconds: 0
|
||||
timeoutSeconds: 1
|
||||
tcpSocket:
|
||||
port: 80
|
||||
periodSeconds: 1
|
||||
1
haproxy/ci/deployment-basic-values.yaml
Normal file
1
haproxy/ci/deployment-basic-values.yaml
Normal file
@@ -0,0 +1 @@
|
||||
kind: Deployment
|
||||
18
haproxy/ci/deployment-config-values.yaml
Normal file
18
haproxy/ci/deployment-config-values.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
config: |
|
||||
global
|
||||
log stdout format raw local0
|
||||
daemon
|
||||
maxconn 1024
|
||||
|
||||
defaults
|
||||
log global
|
||||
timeout client 60s
|
||||
timeout connect 60s
|
||||
timeout server 60s
|
||||
|
||||
frontend fe_main
|
||||
bind :80
|
||||
default_backend be_main
|
||||
|
||||
backend be_main
|
||||
server web1 10.0.0.1:8080 check
|
||||
19
haproxy/ci/deployment-hpa-values.yaml
Normal file
19
haproxy/ci/deployment-hpa-values.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
kind: Deployment
|
||||
replicaCount: null
|
||||
autoscaling:
|
||||
enabled: true
|
||||
minReplicas: 1
|
||||
maxReplicas: 5
|
||||
targetCPUUtilizationPercentage: 80
|
||||
behavior:
|
||||
scaleUp:
|
||||
policies:
|
||||
- type: Percent
|
||||
value: 900
|
||||
periodSeconds: 60
|
||||
scaleDown:
|
||||
stabilizationWindowSeconds: 600
|
||||
policies:
|
||||
- type: Pods
|
||||
value: 1
|
||||
periodSeconds: 600
|
||||
3
haproxy/ci/deployment-ingress-values.yaml
Normal file
3
haproxy/ci/deployment-ingress-values.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
kind: Deployment
|
||||
ingress:
|
||||
enabled: true
|
||||
4
haproxy/ci/deployment-ipfamily-values.yaml
Normal file
4
haproxy/ci/deployment-ipfamily-values.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
kind: Deployment
|
||||
service:
|
||||
ipFamilies: [IPv4]
|
||||
ipFamilyPolicy: SingleStack
|
||||
25
haproxy/ci/deployment-probes-values.yaml
Normal file
25
haproxy/ci/deployment-probes-values.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
kind: Deployment
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
initialDelaySeconds: 0
|
||||
timeoutSeconds: 1
|
||||
tcpSocket:
|
||||
port: 80
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
initialDelaySeconds: 0
|
||||
timeoutSeconds: 1
|
||||
tcpSocket:
|
||||
port: 80
|
||||
periodSeconds: 10
|
||||
startupProbe:
|
||||
failureThreshold: 20
|
||||
successThreshold: 1
|
||||
initialDelaySeconds: 0
|
||||
timeoutSeconds: 1
|
||||
tcpSocket:
|
||||
port: 80
|
||||
periodSeconds: 1
|
||||
58
haproxy/templates/NOTES.txt
Normal file
58
haproxy/templates/NOTES.txt
Normal file
@@ -0,0 +1,58 @@
|
||||
HAProxy has been has been successfully installed. This Chart is used to run HAProxy as a regular application,
|
||||
as opposed to HAProxy Ingress Controller Chart.
|
||||
|
||||
Controller image deployed is: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}".
|
||||
Your HAProxy app is of a "{{ .Values.kind }}" kind.
|
||||
|
||||
Service ports mapped are:
|
||||
{{- $nodePorts := .Values.service.nodePorts }}
|
||||
{{- $servicePortType := .Values.service.type }}
|
||||
{{- if eq .Values.kind "Deployment" }}
|
||||
{{- range $key, $value := .Values.containerPorts }}
|
||||
- name: {{ $key }}
|
||||
containerPort: {{ $value }}
|
||||
protocol: TCP
|
||||
{{- if and (hasKey $nodePorts $key) (eq $servicePortType "NodePort") }}
|
||||
nodePort: {{ get $nodePorts $key }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq .Values.kind "DaemonSet" }}
|
||||
{{- $hostPorts := .Values.daemonset.hostPorts -}}
|
||||
{{- $useHostPort := .Values.daemonset.useHostPort -}}
|
||||
{{- range $key, $value := .Values.containerPorts }}
|
||||
- name: {{ $key }}
|
||||
containerPort: {{ $value }}
|
||||
protocol: TCP
|
||||
{{- if $useHostPort }}
|
||||
hostPort: {{ index $hostPorts $key | default $value }}
|
||||
{{- end }}
|
||||
{{- if and (hasKey $nodePorts $key) (eq $servicePortType "NodePort") }}
|
||||
nodePort: {{ get $nodePorts $key }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
To be able to bind to privileged ports as non-root, the following is required:
|
||||
|
||||
securityContext:
|
||||
enabled: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
initContainers:
|
||||
- name: sysctl
|
||||
image: "busybox:musl"
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- sysctl -w net.ipv4.ip_unprivileged_port_start=0
|
||||
securityContext:
|
||||
privileged: true
|
||||
|
||||
Node IP can be found with:
|
||||
$ kubectl --namespace {{ template "haproxy.namespace" . }} get nodes -o jsonpath="{.items[0].status.addresses[1].address}"
|
||||
|
||||
For more examples and up to date documentation, please visit:
|
||||
* Helm chart documentation: https://github.com/haproxytech/helm-charts/tree/main/haproxy
|
||||
* HAProxy Alpine Docker container documentation: https://github.com/haproxytech/haproxy-docker-alpine
|
||||
* HAProxy documentation: https://www.haproxy.org/download/2.7/doc/configuration.txt
|
||||
105
haproxy/templates/_helpers.tpl
Normal file
105
haproxy/templates/_helpers.tpl
Normal file
@@ -0,0 +1,105 @@
|
||||
{{/*
|
||||
Copyright 2020 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "haproxy.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Allow the release namespace to be overridden for multi-namespace deployments in combined charts
|
||||
*/}}
|
||||
{{- define "haproxy.namespace" -}}
|
||||
{{- if .Values.namespaceOverride -}}
|
||||
{{- .Values.namespaceOverride -}}
|
||||
{{- else -}}
|
||||
{{- .Release.Namespace -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "haproxy.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "haproxy.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "haproxy.labels" -}}
|
||||
helm.sh/chart: {{ include "haproxy.chart" . }}
|
||||
{{ include "haproxy.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "haproxy.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "haproxy.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "haproxy.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "haproxy.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create includes name
|
||||
*/}}
|
||||
{{- define "haproxy.includes" -}}
|
||||
{{- printf "%s-%s" (include "haproxy.fullname" .) "includes" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Encode an imagePullSecret string.
|
||||
*/}}
|
||||
{{- define "haproxy.imagePullSecret" }}
|
||||
{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.imageCredentials.registry (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }}
|
||||
{{- end }}
|
||||
|
||||
{{/* vim: set filetype=mustache: */}}
|
||||
41
haproxy/templates/configmap.yaml
Normal file
41
haproxy/templates/configmap.yaml
Normal file
@@ -0,0 +1,41 @@
|
||||
{{/*
|
||||
Copyright 2020 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.config }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
data:
|
||||
{{ .Values.configMount.subPath | default "haproxy.cfg" }}: |+
|
||||
{{ tpl .Values.config . | nindent 4 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.includes }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "haproxy.includes" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
data:
|
||||
{{- range $key, $val := .Values.includes }}
|
||||
{{ $key }}: | {{ $val | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
193
haproxy/templates/daemonset.yaml
Normal file
193
haproxy/templates/daemonset.yaml
Normal file
@@ -0,0 +1,193 @@
|
||||
{{/*
|
||||
Copyright 2020 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if eq .Values.kind "DaemonSet" }}
|
||||
{{- $useHostNetwork := .Values.daemonset.useHostNetwork -}}
|
||||
{{- $useHostPort := .Values.daemonset.useHostPort -}}
|
||||
{{- $hostPorts := .Values.daemonset.hostPorts -}}
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
spec:
|
||||
minReadySeconds: {{ .Values.minReadySeconds }}
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "haproxy.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "haproxy.selectorLabels" . | nindent 8 }}
|
||||
{{- if .Values.podLabels }}
|
||||
{{ toYaml .Values.podLabels | indent 8 }}
|
||||
{{- end }}
|
||||
annotations:
|
||||
{{- if .Values.checksumConfigMap.enabled }}
|
||||
checksum/environment: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
|
||||
{{- end }}
|
||||
{{- if .Values.podAnnotations }}
|
||||
{{ tpl (toYaml .Values.podAnnotations) . | indent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.shareProcessNamespace.enabled }}
|
||||
shareProcessNamespace: true
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "haproxy.serviceAccountName" . }}
|
||||
{{- if hasKey .Values.serviceAccount "automountServiceAccountToken" }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
|
||||
{{- end }}
|
||||
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
|
||||
{{- if $useHostNetwork }}
|
||||
hostNetwork: true
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
{{- if .Values.dnsConfig }}
|
||||
dnsConfig:
|
||||
{{ toYaml .Values.dnsConfig | indent 8 }}
|
||||
{{- end }}
|
||||
dnsPolicy: {{ .Values.dnsPolicy }}
|
||||
{{- if .Values.imageCredentials.registry }}
|
||||
imagePullSecrets:
|
||||
- name: {{ include "haproxy.fullname" . }}
|
||||
{{- else if .Values.existingImagePullSecret }}
|
||||
imagePullSecrets:
|
||||
- name: {{ .Values.existingImagePullSecret }}
|
||||
{{- end }}
|
||||
{{- if .Values.priorityClassName }}
|
||||
priorityClassName: {{ .Values.priorityClassName }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: haproxy-config
|
||||
configMap:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
{{- if .Values.includes }}
|
||||
- name: includes
|
||||
projected:
|
||||
sources:
|
||||
- configMap:
|
||||
name: {{ include "haproxy.includes" . }}
|
||||
{{- end }}
|
||||
{{- range $mountedSecret := .Values.mountedSecrets }}
|
||||
- name: {{ $mountedSecret.volumeName }}
|
||||
secret:
|
||||
secretName: {{ $mountedSecret.secretName }}
|
||||
{{- end }}
|
||||
{{- with.Values.extraVolumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
{{- with.Values.sidecarContainers }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
- name: {{ .Chart.Name }}
|
||||
{{- if .Values.securityContext.enabled }}
|
||||
securityContext: {{- omit .Values.securityContext "enabled" | toYaml | nindent 12 }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- if .Values.args.enabled }}
|
||||
args:
|
||||
{{- range .Values.args.defaults }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
{{- range .Values.args.extraArgs }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ports:
|
||||
{{- range $key, $value := .Values.containerPorts }}
|
||||
- name: {{ $key }}
|
||||
containerPort: {{ $value }}
|
||||
protocol: TCP
|
||||
{{- if and $useHostPort (index $hostPorts $key) }}
|
||||
hostPort: {{ index $hostPorts $key }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.rawContainerPorts }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.livenessProbe }}
|
||||
livenessProbe:
|
||||
{{- toYaml . | trim | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.readinessProbe }}
|
||||
readinessProbe:
|
||||
{{- toYaml . | trim | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.startupProbe }}
|
||||
startupProbe:
|
||||
{{- toYaml . | trim | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnvs }}
|
||||
env:
|
||||
{{- toYaml . | trim | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnvFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | trim | nindent 12 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- if .Values.lifecycle }}
|
||||
lifecycle:
|
||||
{{- if eq "string" (printf "%T" .Values.lifecycle) }}
|
||||
{{ tpl .Values.lifecycle . | indent 12 }}
|
||||
{{- else }}
|
||||
{{ toYaml .Values.lifecycle | indent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: haproxy-config
|
||||
mountPath: {{ .Values.configMount.mountPath }}
|
||||
{{- if .Values.configMount.subPath }}
|
||||
subPath: {{ .Values.configMount.subPath }}
|
||||
{{- end }}
|
||||
{{- if .Values.includes }}
|
||||
- name: includes
|
||||
mountPath: {{ .Values.includesMountPath }}
|
||||
{{- end }}
|
||||
{{- with.Values.extraVolumeMounts }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- range $mountedSecret := .Values.mountedSecrets }}
|
||||
- name: {{ $mountedSecret.volumeName }}
|
||||
mountPath: {{ $mountedSecret.mountPath }}
|
||||
{{- end }}
|
||||
{{- with.Values.initContainers }}
|
||||
initContainers:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
198
haproxy/templates/deployment.yaml
Normal file
198
haproxy/templates/deployment.yaml
Normal file
@@ -0,0 +1,198 @@
|
||||
{{/*
|
||||
Copyright 2020 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if eq .Values.kind "Deployment" }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
{{- if .Values.deploymentLabels }}
|
||||
{{ tpl (toYaml .Values.deploymentLabels) . | indent 4 }}
|
||||
{{- end }}
|
||||
annotations:
|
||||
{{- if .Values.deploymentAnnotations }}
|
||||
{{ tpl (toYaml .Values.deploymentAnnotations) . | indent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
minReadySeconds: {{ .Values.minReadySeconds }}
|
||||
{{- if and (not .Values.autoscaling.enabled) (not .Values.keda.enabled) }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "haproxy.selectorLabels" . | nindent 6 }}
|
||||
{{- with .Values.strategy }}
|
||||
strategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "haproxy.selectorLabels" . | nindent 8 }}
|
||||
{{- if .Values.podLabels }}
|
||||
{{ toYaml .Values.podLabels | indent 8 }}
|
||||
{{- end }}
|
||||
annotations:
|
||||
{{- if .Values.checksumConfigMap.enabled }}
|
||||
checksum/environment: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
|
||||
{{- end }}
|
||||
{{- if .Values.podAnnotations }}
|
||||
{{ tpl (toYaml .Values.podAnnotations) . | indent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.shareProcessNamespace.enabled }}
|
||||
shareProcessNamespace: true
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "haproxy.serviceAccountName" . }}
|
||||
{{- if hasKey .Values.serviceAccount "automountServiceAccountToken" }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
|
||||
{{- end }}
|
||||
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
{{- with .Values.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.dnsConfig }}
|
||||
dnsConfig:
|
||||
{{ toYaml .Values.dnsConfig | indent 8 }}
|
||||
{{- end }}
|
||||
dnsPolicy: {{ .Values.dnsPolicy }}
|
||||
{{- if .Values.imageCredentials.registry }}
|
||||
imagePullSecrets:
|
||||
- name: {{ include "haproxy.fullname" . }}
|
||||
{{- else if .Values.existingImagePullSecret }}
|
||||
imagePullSecrets:
|
||||
- name: {{ .Values.existingImagePullSecret }}
|
||||
{{- end }}
|
||||
{{- if .Values.priorityClassName }}
|
||||
priorityClassName: {{ .Values.priorityClassName }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: haproxy-config
|
||||
configMap:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
{{- if .Values.includes }}
|
||||
- name: includes
|
||||
projected:
|
||||
sources:
|
||||
- configMap:
|
||||
name: {{ include "haproxy.includes" . }}
|
||||
{{- end }}
|
||||
{{- range $mountedSecret := .Values.mountedSecrets }}
|
||||
- name: {{ $mountedSecret.volumeName }}
|
||||
secret:
|
||||
secretName: {{ $mountedSecret.secretName }}
|
||||
{{- end }}
|
||||
{{- with.Values.extraVolumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
{{- with.Values.sidecarContainers }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
- name: {{ .Chart.Name }}
|
||||
{{- if .Values.securityContext.enabled }}
|
||||
securityContext: {{- omit .Values.securityContext "enabled" | toYaml | nindent 12 }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- if .Values.args.enabled }}
|
||||
args:
|
||||
{{- range .Values.args.defaults }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
{{- range .Values.args.extraArgs }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ports:
|
||||
{{- range $key, $value := .Values.containerPorts }}
|
||||
- name: {{ $key }}
|
||||
containerPort: {{ $value }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
{{- with .Values.rawContainerPorts }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.livenessProbe }}
|
||||
livenessProbe:
|
||||
{{- toYaml . | trim | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.readinessProbe }}
|
||||
readinessProbe:
|
||||
{{- toYaml . | trim | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.startupProbe }}
|
||||
startupProbe:
|
||||
{{- toYaml . | trim | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnvs }}
|
||||
env:
|
||||
{{- toYaml . | trim | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnvFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | trim | nindent 12 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- if .Values.lifecycle }}
|
||||
lifecycle:
|
||||
{{- if eq "string" (printf "%T" .Values.lifecycle) }}
|
||||
{{ tpl .Values.lifecycle . | indent 12 }}
|
||||
{{- else }}
|
||||
{{ toYaml .Values.lifecycle | indent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: haproxy-config
|
||||
mountPath: {{ .Values.configMount.mountPath }}
|
||||
{{- if .Values.configMount.subPath }}
|
||||
subPath: {{ .Values.configMount.subPath }}
|
||||
{{- end }}
|
||||
{{- if .Values.includes }}
|
||||
- name: includes
|
||||
mountPath: {{ .Values.includesMountPath }}
|
||||
{{- end }}
|
||||
{{- with.Values.extraVolumeMounts }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- range $mountedSecret := .Values.mountedSecrets }}
|
||||
- name: {{ $mountedSecret.volumeName }}
|
||||
mountPath: {{ $mountedSecret.mountPath }}
|
||||
{{- end }}
|
||||
{{- with.Values.initContainers }}
|
||||
initContainers:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
63
haproxy/templates/hpa.yaml
Normal file
63
haproxy/templates/hpa.yaml
Normal file
@@ -0,0 +1,63 @@
|
||||
{{/*
|
||||
Copyright 2020 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and (eq .Values.kind "Deployment") .Values.autoscaling.enabled }}
|
||||
{{- if not .Values.keda.enabled }}
|
||||
{{- if .Capabilities.APIVersions.Has "autoscaling/v2" }}
|
||||
apiVersion: autoscaling/v2
|
||||
{{- else if .Capabilities.APIVersions.Has "autoscaling/v2beta2" }}
|
||||
apiVersion: autoscaling/v2beta2
|
||||
{{- else }}
|
||||
{{- fail "ERROR: You must have autoscaling/v2 or autoscaling/v2beta2 to use HorizontalPodAutoscaler" }}
|
||||
{{- end }}
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||
{{- if .Values.autoscaling.behavior }}
|
||||
behavior: {{- toYaml .Values.autoscaling.behavior | nindent 4 }}
|
||||
{{- end }}
|
||||
metrics:
|
||||
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- with .Values.autoscaling.additionalMetrics }}
|
||||
{{- toYaml . | trim | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
40
haproxy/templates/httproute.yaml
Normal file
40
haproxy/templates/httproute.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
{{- if .Values.httpRoute.enabled -}}
|
||||
{{- $fullName := include "haproxy.fullname" . -}}
|
||||
{{- $svcPort := .Values.httpRoute.servicePort -}}
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
{{- with .Values.httpRoute.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.httpRoute.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
parentRefs:
|
||||
{{- with .Values.httpRoute.parentRefs }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.httpRoute.hostnames }}
|
||||
hostnames:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.httpRoute.rules }}
|
||||
{{- with .matches }}
|
||||
- matches:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .filters }}
|
||||
filters:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
backendRefs:
|
||||
- name: {{ $fullName }}
|
||||
port: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
59
haproxy/templates/ingress.yaml
Normal file
59
haproxy/templates/ingress.yaml
Normal file
@@ -0,0 +1,59 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "haproxy.fullname" . -}}
|
||||
{{- $svcPort := .Values.ingress.servicePort -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- toYaml .Values.ingress.tls | nindent 4 }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
54
haproxy/templates/keda.yaml
Normal file
54
haproxy/templates/keda.yaml
Normal file
@@ -0,0 +1,54 @@
|
||||
{{/*
|
||||
Copyright 2021 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and (eq .Values.kind "Deployment") .Values.keda.enabled }}
|
||||
apiVersion: keda.sh/v1alpha1
|
||||
kind: ScaledObject
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
{{- if .Values.keda.scaledObject.annotations }}
|
||||
annotations: {{ toYaml .Values.keda.scaledObject.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
pollingInterval: {{ .Values.keda.pollingInterval }}
|
||||
cooldownPeriod: {{ .Values.keda.cooldownPeriod }}
|
||||
minReplicaCount: {{ .Values.keda.minReplicas }}
|
||||
maxReplicaCount: {{ .Values.keda.maxReplicas }}
|
||||
triggers:
|
||||
{{- with .Values.keda.triggers }}
|
||||
{{ toYaml . | indent 2 }}
|
||||
{{ end }}
|
||||
{{- with .Values.keda.fallback }}
|
||||
fallback:
|
||||
{{ toYaml . | indent 4 }}
|
||||
{{- end }}
|
||||
advanced:
|
||||
restoreToOriginalReplicaCount: {{ .Values.keda.restoreToOriginalReplicaCount }}
|
||||
{{- if .Values.keda.behavior }}
|
||||
horizontalPodAutoscalerConfig:
|
||||
behavior:
|
||||
{{ with .Values.keda.behavior -}}
|
||||
{{ toYaml . | indent 8 }}
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
41
haproxy/templates/poddisruptionbudget.yaml
Normal file
41
haproxy/templates/poddisruptionbudget.yaml
Normal file
@@ -0,0 +1,41 @@
|
||||
{{/*
|
||||
Copyright 2019 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.PodDisruptionBudget.enable }}
|
||||
{{- if .Capabilities.APIVersions.Has "policy/v1" }}
|
||||
apiVersion: policy/v1
|
||||
{{- else if .Capabilities.APIVersions.Has "policy/v1beta1" }}
|
||||
apiVersion: policy/v1beta1
|
||||
{{- else }}
|
||||
{{- fail "ERROR: You must have policy/v1 or policy/v1 to use PodDisruptionBudget" }}
|
||||
{{- end }}
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if .Values.PodDisruptionBudget.maxUnavailable }}
|
||||
maxUnavailable: {{ .Values.PodDisruptionBudget.maxUnavailable }}
|
||||
{{- end }}
|
||||
{{- if .Values.PodDisruptionBudget.minAvailable }}
|
||||
minAvailable: {{ .Values.PodDisruptionBudget.minAvailable }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "haproxy.selectorLabels" . | nindent 6 }}
|
||||
{{- end }}
|
||||
85
haproxy/templates/podsecuritypolicy.yaml
Normal file
85
haproxy/templates/podsecuritypolicy.yaml
Normal file
@@ -0,0 +1,85 @@
|
||||
{{/*
|
||||
Copyright 2020 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if (semverCompare "<1.25.0-0" .Capabilities.KubeVersion.Version) }}
|
||||
{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled -}}
|
||||
{{- $useHostNetwork := .Values.daemonset.useHostNetwork -}}
|
||||
{{- $useHostPort := .Values.daemonset.useHostPort -}}
|
||||
{{- $hostPorts := .Values.daemonset.hostPorts -}}
|
||||
{{- if .Capabilities.APIVersions.Has "policy/v1/PodSecurityPolicy" }}
|
||||
apiVersion: policy/v1
|
||||
{{- else }}
|
||||
apiVersion: policy/v1beta1
|
||||
{{- end }}
|
||||
kind: PodSecurityPolicy
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
{{- if .Values.podSecurityPolicy.annotations }}
|
||||
annotations:
|
||||
{{ toYaml .Values.podSecurityPolicy.annotations | indent 4 }}
|
||||
{{- else }}
|
||||
annotations:
|
||||
seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default'
|
||||
apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
|
||||
seccomp.security.alpha.kubernetes.io/defaultProfileName: 'runtime/default'
|
||||
apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
|
||||
{{- end }}
|
||||
spec:
|
||||
allowPrivilegeEscalation: true
|
||||
allowedCapabilities:
|
||||
- NET_BIND_SERVICE
|
||||
defaultAllowPrivilegeEscalation: false
|
||||
fsGroup:
|
||||
rule: MustRunAs
|
||||
ranges:
|
||||
- max: 65535
|
||||
min: 1
|
||||
{{- if $useHostNetwork }}
|
||||
hostNetwork: true
|
||||
{{- end }}
|
||||
{{- if or $useHostPort $useHostNetwork }}
|
||||
hostPorts:
|
||||
{{- range $key, $value := .Values.containerPorts }}
|
||||
- min: {{ $value }}
|
||||
max: {{ $value }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
hostIPC: false
|
||||
hostPID: false
|
||||
privileged: false
|
||||
runAsUser:
|
||||
rule: RunAsAny
|
||||
seLinux:
|
||||
rule: RunAsAny
|
||||
supplementalGroups:
|
||||
rule: MustRunAs
|
||||
ranges:
|
||||
- max: 65535
|
||||
min: 1
|
||||
volumes:
|
||||
- configMap
|
||||
- emptyDir
|
||||
- projected
|
||||
- secret
|
||||
{{- with .Values.podSecurityPolicy.allowedUnsafeSysctls }}
|
||||
allowedUnsafeSysctls:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
28
haproxy/templates/pullsecret.yaml
Normal file
28
haproxy/templates/pullsecret.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
{{/*
|
||||
Copyright 2020 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.imageCredentials.registry }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
data:
|
||||
.dockerconfigjson: {{ include "haproxy.imagePullSecret" . }}
|
||||
{{- end }}
|
||||
34
haproxy/templates/role.yaml
Normal file
34
haproxy/templates/role.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
{{/*
|
||||
Copyright 2019 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "policy"
|
||||
resources:
|
||||
- podsecuritypolicies
|
||||
verbs:
|
||||
- use
|
||||
resourceNames:
|
||||
- {{ include "haproxy.fullname" . }}
|
||||
{{- end -}}
|
||||
33
haproxy/templates/rolebinding.yaml
Normal file
33
haproxy/templates/rolebinding.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
{{/*
|
||||
Copyright 2019 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled -}}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "haproxy.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end -}}
|
||||
91
haproxy/templates/service.yaml
Normal file
91
haproxy/templates/service.yaml
Normal file
@@ -0,0 +1,91 @@
|
||||
{{/*
|
||||
Copyright 2020 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
{{- range $key, $value := .Values.service.labels }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{- end }}
|
||||
annotations:
|
||||
{{- range $key, $value := .Values.service.annotations }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
selector:
|
||||
{{- include "haproxy.selectorLabels" . | nindent 4 }}
|
||||
{{- if .Values.service.externalTrafficPolicy }}
|
||||
externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }}
|
||||
{{- end }}
|
||||
{{- if .Values.service.internalTrafficPolicy }}
|
||||
internalTrafficPolicy: {{ .Values.service.internalTrafficPolicy }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.clusterIP }}
|
||||
clusterIP: {{ . | quote}}
|
||||
{{- end }}
|
||||
{{- with .Values.service.loadBalancerIP }}
|
||||
loadBalancerIP: {{ . | quote }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.loadBalancerSourceRanges }}
|
||||
loadBalancerSourceRanges:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- if .Values.service.ipFamilies }}
|
||||
ipFamilies:
|
||||
{{- toYaml .Values.service.ipFamilies | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- if .Values.service.ipFamilyPolicy }}
|
||||
ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy | quote }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.externalIPs }}
|
||||
externalIPs:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- if or .Values.containerPorts .Values.service.additionalPorts .Values.service.rawAdditionalPorts }}
|
||||
{{- $nodePorts := .Values.service.nodePorts }}
|
||||
{{- $servicePortType := .Values.service.type }}
|
||||
ports:
|
||||
{{- with .Values.containerPorts }}
|
||||
{{- range $key, $port := . }}
|
||||
- name: {{ $key }}
|
||||
protocol: TCP
|
||||
port: {{ $port }}
|
||||
targetPort: {{ $key }}
|
||||
{{- if and (hasKey $nodePorts $key) (eq $servicePortType "NodePort") }}
|
||||
nodePort: {{ get $nodePorts $key }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.additionalPorts }}
|
||||
{{- range $key, $port := . }}
|
||||
- name: {{ $key }}
|
||||
protocol: TCP
|
||||
port: {{ $port }}
|
||||
targetPort: {{ $key }}
|
||||
{{- if and (hasKey $nodePorts $key) (eq $servicePortType "NodePort") }}
|
||||
nodePort: {{ get $nodePorts $key }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.rawAdditionalPorts }}
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
32
haproxy/templates/serviceaccount.yaml
Normal file
32
haproxy/templates/serviceaccount.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
{{/*
|
||||
Copyright 2020 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "haproxy.serviceAccountName" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if hasKey .Values.serviceAccount "automountServiceAccountToken" }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
37
haproxy/templates/servicemonitor.yaml
Normal file
37
haproxy/templates/servicemonitor.yaml
Normal file
@@ -0,0 +1,37 @@
|
||||
{{/*
|
||||
Copyright 2022 HAProxy Technologies LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/}}
|
||||
|
||||
{{- if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") .Values.serviceMonitor.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: {{ include "haproxy.fullname" . }}
|
||||
namespace: {{ include "haproxy.namespace" . }}
|
||||
labels:
|
||||
{{- include "haproxy.labels" . | nindent 4 }}
|
||||
{{- if .Values.serviceMonitor.extraLabels }}
|
||||
{{ toYaml .Values.serviceMonitor.extraLabels | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
endpoints:
|
||||
{{ .Values.serviceMonitor.endpoints | toYaml | nindent 4 }}
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- {{ .Release.Namespace }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "haproxy.selectorLabels" . | nindent 6 }}
|
||||
{{- end }}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user