From a5447fd3f1b9350e5716a6c3f2ab6f1e6edde35b Mon Sep 17 00:00:00 2001 From: Scaffolder Date: Fri, 24 Apr 2026 11:25:39 +0000 Subject: [PATCH] initial commit Change-Id: I37c91673bc7093df7b976dae85e79afb627e8a5d --- .gitea/workflows/techdocs-helm-chart.yml | 112 ++++ .gitea/workflows/techdocs.yml | 107 ++++ .gitignore | 100 ++++ README.md | 0 catalog-info.yaml | 22 + charts/docs/index.md | 14 + charts/helm-chart-resource.yaml | 23 + charts/mkdocs.yml | 20 + deploy/.helmignore | 21 + deploy/Chart.yaml | 39 ++ deploy/README.md | 495 ++++++++++++++++++ .../ci/daemonset-customnodeport-values.yaml | 12 + deploy/ci/daemonset-default-values.yaml | 2 + deploy/ci/daemonset-extraargs-values.yaml | 5 + deploy/ci/daemonset-extraenvs-values.yaml | 7 + deploy/ci/daemonset-extraports-values.yaml | 21 + deploy/ci/daemonset-hostport-values.yaml | 8 + .../daemonset-serviceannotation-values.yaml | 5 + deploy/ci/daemonset-strategy-values.yaml | 7 + .../ci/deployment-customnodeport-values.yaml | 11 + deploy/ci/deployment-default-values.yaml | 1 + .../ci/deployment-disabled-jobs-values.yaml | 4 + deploy/ci/deployment-extraargs-values.yaml | 4 + deploy/ci/deployment-extraenvs-values.yaml | 6 + deploy/ci/deployment-extraports-values.yaml | 14 + deploy/ci/deployment-hpa-values.yaml | 6 + deploy/ci/deployment-hugconf-values.yaml | 8 + .../ci/deployment-keda-advanced-values.yaml | 34 ++ deploy/ci/deployment-keda-values.yaml | 18 + deploy/ci/deployment-metrics-none-values.yaml | 14 + deploy/ci/deployment-pdb-values.yaml | 5 + deploy/ci/deployment-podmonitor-values.yaml | 10 + .../ci/deployment-servicemonitor-values.yaml | 18 + deploy/ci/deployment-strategy-values.yaml | 6 + deploy/templates/NOTES.txt | 51 ++ deploy/templates/_helpers.tpl | 174 ++++++ deploy/templates/clusterrole.yaml | 138 +++++ deploy/templates/clusterrolebinding.yaml | 32 ++ deploy/templates/controller-crdjob-rbac.yaml | 72 +++ deploy/templates/controller-crdjob.yaml | 96 ++++ deploy/templates/controller-daemonset.yaml | 185 +++++++ deploy/templates/controller-deployment.yaml | 175 +++++++ deploy/templates/controller-gwapijob.yaml | 96 ++++ deploy/templates/controller-hpa.yaml | 53 ++ .../templates/controller-hugconf-cleanup.yaml | 125 +++++ deploy/templates/controller-hugconf.yaml | 45 ++ deploy/templates/controller-keda.yaml | 57 ++ .../controller-poddisruptionbudget.yaml | 35 ++ deploy/templates/controller-podmonitor.yaml | 37 ++ .../controller-podsecuritypolicy.yaml | 81 +++ deploy/templates/controller-role.yaml | 34 ++ deploy/templates/controller-rolebinding.yaml | 33 ++ .../templates/controller-service-metrics.yaml | 45 ++ deploy/templates/controller-service.yaml | 64 +++ .../templates/controller-serviceaccount.yaml | 29 + .../templates/controller-servicemonitor.yaml | 37 ++ deploy/templates/namespace.yaml | 24 + deploy/values.yaml | 390 ++++++++++++++ docs/index.md | 0 mkdocs.yml | 22 + 60 files changed, 3309 insertions(+) create mode 100644 .gitea/workflows/techdocs-helm-chart.yml create mode 100644 .gitea/workflows/techdocs.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 catalog-info.yaml create mode 100644 charts/docs/index.md create mode 100644 charts/helm-chart-resource.yaml create mode 100644 charts/mkdocs.yml create mode 100644 deploy/.helmignore create mode 100644 deploy/Chart.yaml create mode 100644 deploy/README.md create mode 100644 deploy/ci/daemonset-customnodeport-values.yaml create mode 100644 deploy/ci/daemonset-default-values.yaml create mode 100644 deploy/ci/daemonset-extraargs-values.yaml create mode 100644 deploy/ci/daemonset-extraenvs-values.yaml create mode 100644 deploy/ci/daemonset-extraports-values.yaml create mode 100644 deploy/ci/daemonset-hostport-values.yaml create mode 100644 deploy/ci/daemonset-serviceannotation-values.yaml create mode 100644 deploy/ci/daemonset-strategy-values.yaml create mode 100644 deploy/ci/deployment-customnodeport-values.yaml create mode 100644 deploy/ci/deployment-default-values.yaml create mode 100644 deploy/ci/deployment-disabled-jobs-values.yaml create mode 100644 deploy/ci/deployment-extraargs-values.yaml create mode 100644 deploy/ci/deployment-extraenvs-values.yaml create mode 100644 deploy/ci/deployment-extraports-values.yaml create mode 100644 deploy/ci/deployment-hpa-values.yaml create mode 100644 deploy/ci/deployment-hugconf-values.yaml create mode 100644 deploy/ci/deployment-keda-advanced-values.yaml create mode 100644 deploy/ci/deployment-keda-values.yaml create mode 100644 deploy/ci/deployment-metrics-none-values.yaml create mode 100644 deploy/ci/deployment-pdb-values.yaml create mode 100644 deploy/ci/deployment-podmonitor-values.yaml create mode 100644 deploy/ci/deployment-servicemonitor-values.yaml create mode 100644 deploy/ci/deployment-strategy-values.yaml create mode 100644 deploy/templates/NOTES.txt create mode 100644 deploy/templates/_helpers.tpl create mode 100644 deploy/templates/clusterrole.yaml create mode 100644 deploy/templates/clusterrolebinding.yaml create mode 100644 deploy/templates/controller-crdjob-rbac.yaml create mode 100644 deploy/templates/controller-crdjob.yaml create mode 100644 deploy/templates/controller-daemonset.yaml create mode 100644 deploy/templates/controller-deployment.yaml create mode 100644 deploy/templates/controller-gwapijob.yaml create mode 100644 deploy/templates/controller-hpa.yaml create mode 100644 deploy/templates/controller-hugconf-cleanup.yaml create mode 100644 deploy/templates/controller-hugconf.yaml create mode 100644 deploy/templates/controller-keda.yaml create mode 100644 deploy/templates/controller-poddisruptionbudget.yaml create mode 100644 deploy/templates/controller-podmonitor.yaml create mode 100644 deploy/templates/controller-podsecuritypolicy.yaml create mode 100644 deploy/templates/controller-role.yaml create mode 100644 deploy/templates/controller-rolebinding.yaml create mode 100644 deploy/templates/controller-service-metrics.yaml create mode 100644 deploy/templates/controller-service.yaml create mode 100644 deploy/templates/controller-serviceaccount.yaml create mode 100644 deploy/templates/controller-servicemonitor.yaml create mode 100644 deploy/templates/namespace.yaml create mode 100644 deploy/values.yaml create mode 100644 docs/index.md create mode 100644 mkdocs.yml diff --git a/.gitea/workflows/techdocs-helm-chart.yml b/.gitea/workflows/techdocs-helm-chart.yml new file mode 100644 index 0000000..0e4f36a --- /dev/null +++ b/.gitea/workflows/techdocs-helm-chart.yml @@ -0,0 +1,112 @@ +name: Build and Publish TechDocs (Helm Chart Resource) + +on: + push: + branches: + - main + paths: + - 'charts/**' + +env: + # ── Azure Blob Storage ─────────────────────────────────────────────────── + TECHDOCS_AZURE_BLOB_CONTAINER_NAME: + AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/azure/tokens/azure-identity-token + AZURE_ACCOUNT_NAME: "bstagecjotdevsttechdocs" + # ── TechDocs entity identity ───────────────────────────────────────────── + ENTITY_NAMESPACE: default + ENTITY_KIND: resource + ENTITY_NAME: haproxy-unified-gateway-jonathan-helm-chart + +jobs: + build-and-publish-helm-chart: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + # ── 1. Checkout ──────────────────────────────────────────────────────── + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # full history for git-revision-date-localized plugin + + - name: Read and set output + id: read_env + run: | + echo "$AZURE_FEDERATED_TOKEN_FILE" + env | grep AZURE + echo "$(cat $AZURE_FEDERATED_TOKEN_FILE)" + + # ── 2. Bootstrap pip ─────────────────────────────────────────────────── + - 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 + + # ── 3. Install TechDocs CLI + MkDocs dependencies ───────────────────── + - 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 + + # ── 4. Validate mkdocs.yml ───────────────────────────────────────────── + - name: Validate MkDocs config + run: mkdocs build --strict --site-dir /tmp/mkdocs-charts-validate --config-file charts/mkdocs.yml + + # ── 5. Build docs with TechDocs CLI ─────────────────────────────────── + - name: Build TechDocs site + run: | + techdocs-cli generate \ + --source-dir ./charts \ + --output-dir ./charts/site \ + --no-docker \ + --verbose + + # ── 6. Install Azure CLI ─────────────────────────────────────────────── + - 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 + + # ── 7. Authenticate to Azure ────────────────────────────────────────── + - 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" + + # ── 8. Publish to Azure Blob Storage ────────────────────────────────── + - 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" \ + --directory ./charts/site diff --git a/.gitea/workflows/techdocs.yml b/.gitea/workflows/techdocs.yml new file mode 100644 index 0000000..0060bd1 --- /dev/null +++ b/.gitea/workflows/techdocs.yml @@ -0,0 +1,107 @@ +name: Build and Publish TechDocs + +on: + workflow_run: + workflows: ["Build and Push to ACR"] + branches: [main] + types: [completed] + 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-gateway-jonathan +jobs: + build-and-publish: + if: >- + ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # full history for git-revision-date-localized plugin + + - name: read and set output + id: read_env + run: | + echo "$AZURE_FEDERATED_TOKEN_FILE" + env | grep AZURE + echo "$(cat $AZURE_FEDERATED_TOKEN_FILE)" + + + - 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 + + # 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" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b68c990 --- /dev/null +++ b/.gitignore @@ -0,0 +1,100 @@ +# Java / Maven +target/ +!.mvn/wrapper/maven-wrapper.jar +*.class +*.jar +*.war +*.ear + +# IDE +.idea/ +*.iml +.vscode/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log +logs/ + +# Build artifacts +build/ +dist/ +out/ + +# Helm Chart +helm/charts/ +helm/*.lock +Chart.lock +*.tgz + +# Kubernetes / Helm +k8s/values-*.yaml +k8s/generated/ +k8s/manifests/ + +# Environment-specific configs +.env +.env.local +.env.*.local +# Adding these two support multiple backstage environments with different values files +# values-development.yaml +# values-staging.yaml +# values-production.yaml + +# Secrets and credentials +secrets/ +*-secret.yaml +*.key +*.pem +.ssh/ + +# Test coverage +coverage/ +.coverage + +# Terraform (if using Helm provider) +.terraform/ +*.tfstate +*.tfstate.backup +terraform.tfvars +.terraformrc + +# Docker +docker-compose.override.yml +.dockerignore + +# IDE generated files +*.iws +*.ipr + +# Node dependencies (if UI component exists) +node_modules/ +npm-debug.log +yarn-error.log + +# Python environment +__pycache__/ +*.pyc +venv/ +env/ + +# IDEs +.vscode/ +.idea/ +*.sublime-project +*.sublime-workspace + +# Temp files +*.tmp +*.bak +.cache/ + +# Generated files +dist/ +build/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/catalog-info.yaml b/catalog-info.yaml new file mode 100644 index 0000000..1723e5f --- /dev/null +++ b/catalog-info.yaml @@ -0,0 +1,22 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: haproxy-unified-gateway-jonathan + description: haproxy-unified-gateway-joanthan + annotations: + backstage.io/techdocs-ref: dir:. + gitea.kyndemo.live/repo-slug: "validate/haproxy-unified-gateway-jonathan" + helm.backstage.io/chart-path: deploy + tags: + - migration + - helm + links: + - url: https://gitea.kyndemo.live/validate/haproxy-unified-gateway-jonathan + title: Source Repository + icon: github +spec: + type: service + owner: "group:default/platform-engineering" + lifecycle: production + dependsOn: + - resource:default/haproxy-unified-gateway-jonathan-helm-chart diff --git a/charts/docs/index.md b/charts/docs/index.md new file mode 100644 index 0000000..b9c3fb4 --- /dev/null +++ b/charts/docs/index.md @@ -0,0 +1,14 @@ +# haproxy unified gateway + +haproxy-unified-gateway-joanthan + +## Overview + +This is the Helm chart resource for the **haproxy-unified-gateway-jonathan** application. + +| Field | Value | +|------------|-----------------------------------------------------------------------------| +| Chart Repo | https://gitea.kyndemo.live/validate/haproxy-unified-gateway-jonathan | +| Owner | platform-engineering | +| Lifecycle | dev | +| System | haproxy-unified-gateway-jonathan | diff --git a/charts/helm-chart-resource.yaml b/charts/helm-chart-resource.yaml new file mode 100644 index 0000000..90ccfce --- /dev/null +++ b/charts/helm-chart-resource.yaml @@ -0,0 +1,23 @@ +apiVersion: backstage.io/v1alpha1 +kind: Resource +metadata: + name: haproxy-unified-gateway-jonathan-helm-chart + title: haproxy unified gateway + description: haproxy-unified-gateway-joanthan + annotations: + backstage.io/techdocs-ref: dir:. + gitea.kyndemo.live/repo-slug: "validate/haproxy-unified-gateway-jonathan" + helm.backstage.io/chart-path: deploy + tags: + - helm + - haproxy-unified-gateway-jonathan + - microservices +spec: + type: helm-chart + owner: group:default/platform-engineering + lifecycle: production + system: "system:default/haproxy-unified-gateway-jonathan" + links: + - url: https://gitea.kyndemo.live/validate/haproxy-unified-gateway-jonathan + title: Chart Repository + icon: repository diff --git a/charts/mkdocs.yml b/charts/mkdocs.yml new file mode 100644 index 0000000..cb34eef --- /dev/null +++ b/charts/mkdocs.yml @@ -0,0 +1,20 @@ +site_name: haproxy-unified-gateway-jonathan-helm-chart +site_description: haproxy-unified-gateway-joanthan + +nav: + - Home: index.md + +theme: + name: material + palette: + primary: indigo + accent: indigo + +plugins: + - search + +markdown_extensions: + - admonition + - codehilite + - toc: + permalink: true diff --git a/deploy/.helmignore b/deploy/.helmignore new file mode 100644 index 0000000..5206f4e --- /dev/null +++ b/deploy/.helmignore @@ -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/ diff --git a/deploy/Chart.yaml b/deploy/Chart.yaml new file mode 100644 index 0000000..6799f13 --- /dev/null +++ b/deploy/Chart.yaml @@ -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.2 +appVersion: 1.0.2 +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.2 version for base image diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000..86d362e --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,495 @@ +# ![HAProxy](https://github.com/haproxytech/kubernetes-ingress/raw/master/assets/images/haproxy-weblogo-210x49.png "HAProxy") + +## 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://: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. diff --git a/deploy/ci/daemonset-customnodeport-values.yaml b/deploy/ci/daemonset-customnodeport-values.yaml new file mode 100644 index 0000000..c5381db --- /dev/null +++ b/deploy/ci/daemonset-customnodeport-values.yaml @@ -0,0 +1,12 @@ +controller: + kind: DaemonSet + service: + type: NodePort + http: + port: 8080 + targetPort: 8080 + nodePort: 30080 + https: + port: 8443 + targetPort: 8443 + nodePort: 30443 diff --git a/deploy/ci/daemonset-default-values.yaml b/deploy/ci/daemonset-default-values.yaml new file mode 100644 index 0000000..ddb2562 --- /dev/null +++ b/deploy/ci/daemonset-default-values.yaml @@ -0,0 +1,2 @@ +controller: + kind: DaemonSet diff --git a/deploy/ci/daemonset-extraargs-values.yaml b/deploy/ci/daemonset-extraargs-values.yaml new file mode 100644 index 0000000..986afa6 --- /dev/null +++ b/deploy/ci/daemonset-extraargs-values.yaml @@ -0,0 +1,5 @@ +controller: + kind: DaemonSet + extraArgs: + - --controller-name=gate.haproxy.org/hug + - --namespaces=default diff --git a/deploy/ci/daemonset-extraenvs-values.yaml b/deploy/ci/daemonset-extraenvs-values.yaml new file mode 100644 index 0000000..35294fa --- /dev/null +++ b/deploy/ci/daemonset-extraenvs-values.yaml @@ -0,0 +1,7 @@ +controller: + kind: DaemonSet + extraEnvs: + - name: TEST_STR1 + value: foo + - name: TEST_STR2 + value: baz diff --git a/deploy/ci/daemonset-extraports-values.yaml b/deploy/ci/daemonset-extraports-values.yaml new file mode 100644 index 0000000..3b5f316 --- /dev/null +++ b/deploy/ci/daemonset-extraports-values.yaml @@ -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 diff --git a/deploy/ci/daemonset-hostport-values.yaml b/deploy/ci/daemonset-hostport-values.yaml new file mode 100644 index 0000000..45042ea --- /dev/null +++ b/deploy/ci/daemonset-hostport-values.yaml @@ -0,0 +1,8 @@ +controller: + kind: DaemonSet + daemonset: + useHostPort: true + hostPorts: + http: 80 + https: 443 + stat: 1024 diff --git a/deploy/ci/daemonset-serviceannotation-values.yaml b/deploy/ci/daemonset-serviceannotation-values.yaml new file mode 100644 index 0000000..b538cb5 --- /dev/null +++ b/deploy/ci/daemonset-serviceannotation-values.yaml @@ -0,0 +1,5 @@ +controller: + kind: DaemonSet + service: + annotations: + service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0 diff --git a/deploy/ci/daemonset-strategy-values.yaml b/deploy/ci/daemonset-strategy-values.yaml new file mode 100644 index 0000000..ed45d7a --- /dev/null +++ b/deploy/ci/daemonset-strategy-values.yaml @@ -0,0 +1,7 @@ +controller: + kind: DaemonSet + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 1 diff --git a/deploy/ci/deployment-customnodeport-values.yaml b/deploy/ci/deployment-customnodeport-values.yaml new file mode 100644 index 0000000..cb0025c --- /dev/null +++ b/deploy/ci/deployment-customnodeport-values.yaml @@ -0,0 +1,11 @@ +controller: + service: + type: NodePort + http: + port: 8080 + targetPort: 8080 + nodePort: 30080 + https: + port: 8443 + targetPort: 8443 + nodePort: 30443 diff --git a/deploy/ci/deployment-default-values.yaml b/deploy/ci/deployment-default-values.yaml new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/deploy/ci/deployment-default-values.yaml @@ -0,0 +1 @@ +# diff --git a/deploy/ci/deployment-disabled-jobs-values.yaml b/deploy/ci/deployment-disabled-jobs-values.yaml new file mode 100644 index 0000000..b909770 --- /dev/null +++ b/deploy/ci/deployment-disabled-jobs-values.yaml @@ -0,0 +1,4 @@ +crdjob: + enabled: false +gwapijob: + enabled: false diff --git a/deploy/ci/deployment-extraargs-values.yaml b/deploy/ci/deployment-extraargs-values.yaml new file mode 100644 index 0000000..df17758 --- /dev/null +++ b/deploy/ci/deployment-extraargs-values.yaml @@ -0,0 +1,4 @@ +controller: + extraArgs: + - --controller-name=gate.haproxy.org/hug + - --namespaces=default diff --git a/deploy/ci/deployment-extraenvs-values.yaml b/deploy/ci/deployment-extraenvs-values.yaml new file mode 100644 index 0000000..1f9e30c --- /dev/null +++ b/deploy/ci/deployment-extraenvs-values.yaml @@ -0,0 +1,6 @@ +controller: + extraEnvs: + - name: TEST_STR1 + value: foo + - name: TEST_STR2 + value: baz diff --git a/deploy/ci/deployment-extraports-values.yaml b/deploy/ci/deployment-extraports-values.yaml new file mode 100644 index 0000000..8064008 --- /dev/null +++ b/deploy/ci/deployment-extraports-values.yaml @@ -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 diff --git a/deploy/ci/deployment-hpa-values.yaml b/deploy/ci/deployment-hpa-values.yaml new file mode 100644 index 0000000..3b55066 --- /dev/null +++ b/deploy/ci/deployment-hpa-values.yaml @@ -0,0 +1,6 @@ +controller: + autoscaling: + enabled: true + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 diff --git a/deploy/ci/deployment-hugconf-values.yaml b/deploy/ci/deployment-hugconf-values.yaml new file mode 100644 index 0000000..844d2a3 --- /dev/null +++ b/deploy/ci/deployment-hugconf-values.yaml @@ -0,0 +1,8 @@ +hugconf: + logging: + defaultLevel: Debug + categoryLevelList: + - category: "gate" + level: "Debug" + - category: "k8s" + level: "Info" diff --git a/deploy/ci/deployment-keda-advanced-values.yaml b/deploy/ci/deployment-keda-advanced-values.yaml new file mode 100644 index 0000000..c96586b --- /dev/null +++ b/deploy/ci/deployment-keda-advanced-values.yaml @@ -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 diff --git a/deploy/ci/deployment-keda-values.yaml b/deploy/ci/deployment-keda-values.yaml new file mode 100644 index 0000000..c5de8de --- /dev/null +++ b/deploy/ci/deployment-keda-values.yaml @@ -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])) diff --git a/deploy/ci/deployment-metrics-none-values.yaml b/deploy/ci/deployment-metrics-none-values.yaml new file mode 100644 index 0000000..e9f76bd --- /dev/null +++ b/deploy/ci/deployment-metrics-none-values.yaml @@ -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 diff --git a/deploy/ci/deployment-pdb-values.yaml b/deploy/ci/deployment-pdb-values.yaml new file mode 100644 index 0000000..408479b --- /dev/null +++ b/deploy/ci/deployment-pdb-values.yaml @@ -0,0 +1,5 @@ +controller: + replicaCount: 2 + podDisruptionBudget: + enabled: true + minAvailable: 1 diff --git a/deploy/ci/deployment-podmonitor-values.yaml b/deploy/ci/deployment-podmonitor-values.yaml new file mode 100644 index 0000000..74c0dd7 --- /dev/null +++ b/deploy/ci/deployment-podmonitor-values.yaml @@ -0,0 +1,10 @@ +controller: + podMonitor: + enabled: true + extraLabels: + release: prometheus + endpoints: + - port: stat + path: /metrics + scheme: http + interval: 30s diff --git a/deploy/ci/deployment-servicemonitor-values.yaml b/deploy/ci/deployment-servicemonitor-values.yaml new file mode 100644 index 0000000..e11578b --- /dev/null +++ b/deploy/ci/deployment-servicemonitor-values.yaml @@ -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 diff --git a/deploy/ci/deployment-strategy-values.yaml b/deploy/ci/deployment-strategy-values.yaml new file mode 100644 index 0000000..939312a --- /dev/null +++ b/deploy/ci/deployment-strategy-values.yaml @@ -0,0 +1,6 @@ +controller: + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 1 diff --git a/deploy/templates/NOTES.txt b/deploy/templates/NOTES.txt new file mode 100644 index 0000000..59b75d3 --- /dev/null +++ b/deploy/templates/NOTES.txt @@ -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 diff --git a/deploy/templates/_helpers.tpl b/deploy/templates/_helpers.tpl new file mode 100644 index 0000000..ac6ba1f --- /dev/null +++ b/deploy/templates/_helpers.tpl @@ -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 }} diff --git a/deploy/templates/clusterrole.yaml b/deploy/templates/clusterrole.yaml new file mode 100644 index 0000000..916c42a --- /dev/null +++ b/deploy/templates/clusterrole.yaml @@ -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 }} diff --git a/deploy/templates/clusterrolebinding.yaml b/deploy/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..c71a4f6 --- /dev/null +++ b/deploy/templates/clusterrolebinding.yaml @@ -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 }} diff --git a/deploy/templates/controller-crdjob-rbac.yaml b/deploy/templates/controller-crdjob-rbac.yaml new file mode 100644 index 0000000..850ce53 --- /dev/null +++ b/deploy/templates/controller-crdjob-rbac.yaml @@ -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 }} diff --git a/deploy/templates/controller-crdjob.yaml b/deploy/templates/controller-crdjob.yaml new file mode 100644 index 0000000..6011c40 --- /dev/null +++ b/deploy/templates/controller-crdjob.yaml @@ -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 }} diff --git a/deploy/templates/controller-daemonset.yaml b/deploy/templates/controller-daemonset.yaml new file mode 100644 index 0000000..756d2ed --- /dev/null +++ b/deploy/templates/controller-daemonset.yaml @@ -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 }} diff --git a/deploy/templates/controller-deployment.yaml b/deploy/templates/controller-deployment.yaml new file mode 100644 index 0000000..3ae6cd2 --- /dev/null +++ b/deploy/templates/controller-deployment.yaml @@ -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 }} diff --git a/deploy/templates/controller-gwapijob.yaml b/deploy/templates/controller-gwapijob.yaml new file mode 100644 index 0000000..9dafad2 --- /dev/null +++ b/deploy/templates/controller-gwapijob.yaml @@ -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 }} diff --git a/deploy/templates/controller-hpa.yaml b/deploy/templates/controller-hpa.yaml new file mode 100644 index 0000000..b614ba7 --- /dev/null +++ b/deploy/templates/controller-hpa.yaml @@ -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 }} diff --git a/deploy/templates/controller-hugconf-cleanup.yaml b/deploy/templates/controller-hugconf-cleanup.yaml new file mode 100644 index 0000000..b7e50ae --- /dev/null +++ b/deploy/templates/controller-hugconf-cleanup.yaml @@ -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 }} diff --git a/deploy/templates/controller-hugconf.yaml b/deploy/templates/controller-hugconf.yaml new file mode 100644 index 0000000..7603ad0 --- /dev/null +++ b/deploy/templates/controller-hugconf.yaml @@ -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 }} diff --git a/deploy/templates/controller-keda.yaml b/deploy/templates/controller-keda.yaml new file mode 100644 index 0000000..5a33624 --- /dev/null +++ b/deploy/templates/controller-keda.yaml @@ -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 }} diff --git a/deploy/templates/controller-poddisruptionbudget.yaml b/deploy/templates/controller-poddisruptionbudget.yaml new file mode 100644 index 0000000..6644b2e --- /dev/null +++ b/deploy/templates/controller-poddisruptionbudget.yaml @@ -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 }} diff --git a/deploy/templates/controller-podmonitor.yaml b/deploy/templates/controller-podmonitor.yaml new file mode 100644 index 0000000..1d6d06e --- /dev/null +++ b/deploy/templates/controller-podmonitor.yaml @@ -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 }} diff --git a/deploy/templates/controller-podsecuritypolicy.yaml b/deploy/templates/controller-podsecuritypolicy.yaml new file mode 100644 index 0000000..dec3ba2 --- /dev/null +++ b/deploy/templates/controller-podsecuritypolicy.yaml @@ -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 }} diff --git a/deploy/templates/controller-role.yaml b/deploy/templates/controller-role.yaml new file mode 100644 index 0000000..388b4a9 --- /dev/null +++ b/deploy/templates/controller-role.yaml @@ -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 -}} diff --git a/deploy/templates/controller-rolebinding.yaml b/deploy/templates/controller-rolebinding.yaml new file mode 100644 index 0000000..e7ef98f --- /dev/null +++ b/deploy/templates/controller-rolebinding.yaml @@ -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 -}} diff --git a/deploy/templates/controller-service-metrics.yaml b/deploy/templates/controller-service-metrics.yaml new file mode 100644 index 0000000..4c22386 --- /dev/null +++ b/deploy/templates/controller-service-metrics.yaml @@ -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 }} diff --git a/deploy/templates/controller-service.yaml b/deploy/templates/controller-service.yaml new file mode 100644 index 0000000..3907b68 --- /dev/null +++ b/deploy/templates/controller-service.yaml @@ -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 }} diff --git a/deploy/templates/controller-serviceaccount.yaml b/deploy/templates/controller-serviceaccount.yaml new file mode 100644 index 0000000..328401e --- /dev/null +++ b/deploy/templates/controller-serviceaccount.yaml @@ -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 }} diff --git a/deploy/templates/controller-servicemonitor.yaml b/deploy/templates/controller-servicemonitor.yaml new file mode 100644 index 0000000..6c32f8c --- /dev/null +++ b/deploy/templates/controller-servicemonitor.yaml @@ -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 }} diff --git a/deploy/templates/namespace.yaml b/deploy/templates/namespace.yaml new file mode 100644 index 0000000..b2118d9 --- /dev/null +++ b/deploy/templates/namespace.yaml @@ -0,0 +1,24 @@ +{{/* +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 }} +{{- end }} diff --git a/deploy/values.yaml b/deploy/values.yaml new file mode 100644 index 0000000..4ae33ea --- /dev/null +++ b/deploy/values.yaml @@ -0,0 +1,390 @@ +# 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 as part of the release. +# NOTE: do not combine this with `helm install --create-namespace`. +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 "/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://: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: {} diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..e69de29 diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..edecf14 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,22 @@ +site_name: haproxy-unified-gateway-jonathan +site_description: haproxy-unified-gateway-joanthan + +nav: + - Home: index.md + - OpenTelemetry: opentelemetry.md + - Databases: databases.md + +theme: + name: material + palette: + primary: indigo + accent: indigo + +plugins: + - search + +markdown_extensions: + - admonition + - codehilite + - toc: + permalink: true