fix: vendor critical bootstrap charts
Deploy Cluster / Terraform (push) Successful in 30s
Deploy Cluster / Ansible (push) Failing after 20m0s

This commit is contained in:
2026-04-26 21:01:01 +00:00
parent 14462dd870
commit a2ed9555c0
175 changed files with 64772 additions and 57 deletions
@@ -0,0 +1,116 @@
{{/* Print release information */}}
{{- printf "\n\n" -}}
{{ .Release.Name }} with {{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }} has been deployed successfully on {{ template "traefik.namespace" . }} namespace!
{{- printf "\n" -}}
{{/* Warn about potential permission issue with persistence */}}
{{- if .Values.persistence -}}
{{- if and .Values.persistence.enabled (empty .Values.deployment.initContainers) -}}
{{- printf "\n" -}}
🚨 When enabling persistence for certificates, permissions on acme.json can be
lost when Traefik restarts. You can ensure correct permissions with an
initContainer. See https://github.com/traefik/traefik-helm-chart/blob/master/EXAMPLES.md#use-traefik-native-lets-encrypt-integration-without-cert-manager
for more info. 🚨
{{- printf "\n" -}}
{{- end -}}
{{- end -}}
{{/* Warn about non-matching potential labelSelector mismatch for CRD provider */}}
{{- with .Values.providers.kubernetesCRD.labelSelector -}}
{{- $labelsApplied := include "traefik.labels" $ -}}
{{- $labelSelectors := regexSplit "," . -1 }}
{{- range $labelSelectors -}}
{{- $labelSelectorRaw := regexSplit "=" . -1 -}}
{{- $labelSelector := printf "%s: %s" (first $labelSelectorRaw) (last $labelSelectorRaw) -}}
{{- if not (contains $labelSelector $labelsApplied) -}}
{{- printf "\n" -}}
🚨 Resources populated with this chart don't match with labelSelector `{{.}}` applied on kubernetesCRD provider. 🚨
{{- printf "\n" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Warn about non-matching potential labelSelector mismatch for Ingress provider */}}
{{- with .Values.providers.kubernetesIngress.labelSelector -}}
{{- $labelsApplied := include "traefik.labels" $ -}}
{{- $labelSelectors := regexSplit "," . -1 -}}
{{- range $labelSelectors -}}
{{- $labelSelectorRaw := regexSplit "=" . -1 -}}
{{- $labelSelector := printf "%s: %s" (first $labelSelectorRaw) (last $labelSelectorRaw) -}}
{{- if not (contains $labelSelector $labelsApplied) -}}
{{- printf "\n" -}}
🚨 Resources populated with this chart don't match with labelSelector `{{.}}` applied on kubernetesIngress provider. 🚨
{{- printf "\n" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Warn about renamed ports */}}
{{- range $name, $config := .Values.ports -}}
{{- $sanitizedPortName := include "traefik.portname" $name -}}
{{- if (ne $sanitizedPortName $name) -}}
{{- printf "\n" -}}
🚨 Port name `{{ $name }}` does not comply with Kubernetes standards and will be renamed to `{{ $sanitizedPortName }}` in services. 🚨
️ See the "traefik.portname" helper in this chart for additional details.
{{- printf "\n" -}}
{{- end -}}
{{- end -}}
{{/* Warn about hub not watching namespaces configured in providers */}}
{{- if and .Values.hub.token (and .Values.rbac.enabled .Values.rbac.namespaced) }}
{{- if .Values.hub.namespaces -}}
{{- range (list "kubernetesCRD" "kubernetesGateway" "kubernetesIngress") }}
{{- $provider := . -}}
{{- $providerNamespaces := get (get $.Values.providers .) "namespaces" -}}
{{- $providerEnabled := get (get $.Values.providers .) "enabled" -}}
{{- if $providerEnabled -}}
{{- if $providerNamespaces -}}
{{- $difference := (include "list.difference" (dict "a" $providerNamespaces "b" $.Values.hub.namespaces)) | fromYamlArray }}
{{- if $difference }}
{{- printf "WARNING: %s provider is configured to watch namespaces %s but those ones are not watched by Hub provider.\n" $provider $difference -}}
{{- end -}}
{{- else -}}
{{- printf "WARNING: %s provider is configured to watch all namespaces but Hub provider only watches %s.\n" $provider $.Values.hub.namespaces -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Warn about deprecated localPlugins */}}
{{- if include "traefik.hasDeprecatedLocalPlugins" . }}
{{- printf "\n" -}}
⚠️ DEPRECATION WARNING: You are using the deprecated legacy 'hostPath' configuration.
Please migrate to the new structured 'type.hostPathPlugin' configuration within localPlugins.
The legacy root-level hostPath configuration will be removed in the next major version.
Migration example:
experimental:
localPlugins:
your-plugin:
moduleName: github.com/example/yourplugin
mountPath: /plugins-local/src/github.com/example/yourplugin
# Choose one of the following types:
type: inlinePlugin # Recommended for small/medium plugins: secure ConfigMap-based
source: # Required for inlinePlugin
# your plugin files here
# type: hostPath # Use with caution for security reasons
# hostPath: /path/to/plugin
# type: localPath # Advanced: Uses additionalVolumes, can be used with PVC, CSI drivers (s3-csi-driver, FUSE), etc.
# volumeName: plugin-storage
{{- printf "\n" -}}
{{- end -}}
{{/* Warn about missing secret when enabling managed certificate with Hub admission controller */}}
{{- if and .Values.hub.token .Values.hub.apimanagement.enabled .Values.hub.apimanagement.admission.selfManagedCertificate }}
{{- $cert := lookup "v1" "Secret" (include "traefik.namespace" .) $.Values.hub.apimanagement.admission.secretName -}}
{{- if not $cert }}
{{- printf "\nWARNING: webhook secret %s for Traefik hub is self managed and was not found in %s namespace.\n" $.Values.hub.apimanagement.admission.secretName (include "traefik.namespace" .) -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,455 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "traefik.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "traefik.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create the chart image name.
*/}}
{{- define "traefik.image-name" -}}
{{- if .Values.oci_meta.enabled -}}
{{- if .Values.hub.token -}}
{{- printf "%s/%s:%s" .Values.oci_meta.repo .Values.oci_meta.images.hub.image .Values.oci_meta.images.hub.tag }}
{{- else -}}
{{- printf "%s/%s:%s" .Values.oci_meta.repo .Values.oci_meta.images.proxy.image .Values.oci_meta.images.proxy.tag }}
{{- end -}}
{{- else if .Values.global.azure.enabled -}}
{{- if .Values.hub.token -}}
{{- printf "%s/%s:%s" .Values.global.azure.images.hub.registry .Values.global.azure.images.hub.image .Values.global.azure.images.hub.tag }}
{{- else -}}
{{- printf "%s/%s:%s" .Values.global.azure.images.proxy.registry .Values.global.azure.images.proxy.image .Values.global.azure.images.proxy.tag }}
{{- end -}}
{{- else -}}
{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (.Values.image.tag | default .Chart.AppVersion) }}
{{- end -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "traefik.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 -}}
{{/*
Allow customization of the instance label value.
*/}}
{{- define "traefik.instance-name" -}}
{{- default (printf "%s-%s" .Release.Name (include "traefik.namespace" .)) .Values.instanceLabelOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/* Shared labels used for selector*/}}
{{/* This is an immutable field: this should not change between upgrade */}}
{{- define "traefik.labelselector" -}}
app.kubernetes.io/name: {{ template "traefik.name" . }}
app.kubernetes.io/instance: {{ template "traefik.instance-name" . }}
{{- end }}
{{/* Shared labels used in metada */}}
{{- define "traefik.labels" -}}
{{ include "traefik.labelselector" . }}
helm.sh/chart: {{ template "traefik.chart" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.commonLabels }}
{{ toYaml . }}
{{- end }}
{{- end }}
{{/*
Construct the namespace for all namespaced resources
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
Preserve the default behavior of the Release namespace if no override is provided
*/}}
{{- define "traefik.namespace" -}}
{{- if .Values.namespaceOverride -}}
{{- .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- end -}}
{{/*
The name of the service account to use
*/}}
{{- define "traefik.serviceAccountName" -}}
{{- default (include "traefik.fullname" .) .Values.serviceAccount.name -}}
{{- end -}}
{{/*
The name of the ClusterRole and ClusterRoleBinding to use.
Adds the namespace to name to prevent duplicate resource names when there
are multiple namespaced releases with the same release name.
*/}}
{{- define "traefik.clusterRoleName" -}}
{{- (printf "%s-%s" (include "traefik.fullname" .) (include "traefik.namespace" .)) | trunc 63 | trimSuffix "-" }}
{{- end -}}
{{/*
Change input to a valid name for a port.
This is a best effort to convert input to a valid port name for Kubernetes,
which per RFC 6335 only allows lowercase alphanumeric characters and '-',
and additionally imposes a limit of 15 characters on the length of the name.
See also https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services
and https://www.rfc-editor.org/rfc/rfc6335#section-5.1.
*/}}
{{- define "traefik.portname" -}}
{{- $portName := . -}}
{{- $portName = $portName | lower -}}
{{- $portName = $portName | trimPrefix "-" | trunc 15 | trimSuffix "-" -}}
{{- print $portName -}}
{{- end -}}
{{/*
Change input to a valid port reference.
See also the traefik.portname helper.
*/}}
{{- define "traefik.portreference" -}}
{{- if kindIs "string" . -}}
{{- print (include "traefik.portname" .) -}}
{{- else -}}
{{- print . -}}
{{- end -}}
{{- end -}}
{{/*
Construct the path for the providers.kubernetesingress.ingressendpoint.publishedservice.
By convention this will simply use the <namespace>/<service-name> to match the name of the
service generated.
Users can provide an override for an explicit service they want bound via `.Values.providers.kubernetesIngress.publishedService.pathOverride`
*/}}
{{- define "providers.kubernetesIngress.publishedServicePath" -}}
{{- $defServiceName := printf "%s/%s" (include "traefik.namespace" .) (include "traefik.fullname" .) -}}
{{- $servicePath := default $defServiceName .Values.providers.kubernetesIngress.publishedService.pathOverride }}
{{- print $servicePath | trimSuffix "-" -}}
{{- end -}}
{{- define "providers.kubernetesIngressNginx.publishServicePath" -}}
{{- $defServiceName := printf "%s/%s" (include "traefik.namespace" .) (include "traefik.fullname" .) -}}
{{- $servicePath := default $defServiceName .Values.providers.kubernetesIngressNginx.publishService.pathOverride }}
{{- print $servicePath | trimSuffix "-" -}}
{{- end -}}
{{/*
Construct a comma-separated list of whitelisted namespaces
*/}}
{{- define "providers.kubernetesCRD.namespaces" -}}
{{- default (include "traefik.namespace" .) (join "," .Values.providers.kubernetesCRD.namespaces) }}
{{- end -}}
{{- define "providers.kubernetesGateway.namespaces" -}}
{{- default (include "traefik.namespace" .) (join "," .Values.providers.kubernetesGateway.namespaces) }}
{{- end -}}
{{- define "providers.kubernetesIngress.namespaces" -}}
{{- default (include "traefik.namespace" .) (join "," .Values.providers.kubernetesIngress.namespaces) }}
{{- end -}}
{{- define "providers.kubernetesIngressNginx.namespaces" -}}
{{- default (include "traefik.namespace" .) (join "," .Values.providers.kubernetesIngressNginx.watchNamespace) }}
{{- end -}}
{{- define "providers.knative.namespaces" -}}
{{- default (include "traefik.namespace" .) (join "," .Values.providers.knative.namespaces) }}
{{- end -}}
{{/*
Renders a complete tree, even values that contains template.
*/}}
{{- define "traefik.render" -}}
{{- if typeIs "string" .value }}
{{- tpl .value .context }}
{{ else }}
{{- tpl (.value | toYaml) .context }}
{{- end }}
{{- end -}}
{{/*
This is a hack to avoid too much complexity when proxyVersion is required on Hub.
It requires a dict with "Version" and "Hub".
*/}}
{{- define "traefik.proxyVersionFromHub" -}}
{{- $version := .Version -}}
{{- if .Hub -}}
{{- $hubProxyVersion := "v3.6.7" }}
{{- if regexMatch "v[0-9]+.[0-9]+.[0-9]+" (default "" $version) }}
{{- if semverCompare "<v3.19.0-0" $version }}
{{- $hubProxyVersion = "v3.6.3" }}
{{- end -}}
{{- end -}}
{{- $hubProxyVersion }}
{{- else -}}
{{- $version }}
{{- end -}}
{{- end -}}
{{/*
The version can comes many sources: appVersion, image.tag, override, marketplace.
*/}}
{{- define "traefik.proxyVersion" -}}
{{- if $.Values.versionOverride }}
{{- include "traefik.proxyVersionFromHub" (dict "Version" $.Values.versionOverride "Hub" $.Values.hub.token) }}
{{- else if $.Values.hub.token -}}
{{- $version := ($.Values.oci_meta.enabled | ternary $.Values.oci_meta.images.hub.tag $.Values.image.tag) -}}
{{- $version = ($.Values.global.azure.enabled | ternary $.Values.global.azure.images.hub.tag $version) -}}
{{- include "traefik.proxyVersionFromHub" (dict "Version" $version "Hub" true) }}
{{- else -}}
{{- $imageVersion := ($.Values.oci_meta.enabled | ternary $.Values.oci_meta.images.proxy.tag $.Values.image.tag) -}}
{{- $imageVersion = ($.Values.global.azure.enabled | ternary $.Values.global.azure.images.proxy.tag $imageVersion) -}}
{{- (split "@" (default $.Chart.AppVersion $imageVersion))._0 | replace "latest-" "" | replace "experimental-" "" }}
{{- end -}}
{{- end -}}
{{/* Generate/load self-signed certificate for admission webhooks */}}
{{- define "traefik-hub.webhook_cert" -}}
{{- if $.Values.hub.apimanagement.admission.customWebhookCertificate }}
Cert: {{ index $.Values.hub.apimanagement.admission.customWebhookCertificate "tls.crt" }}
Key: {{ index $.Values.hub.apimanagement.admission.customWebhookCertificate "tls.key" }}
Hash: {{ sha1sum (index $.Values.hub.apimanagement.admission.customWebhookCertificate "tls.crt") }}
{{- else -}}
{{- $cert := lookup "v1" "Secret" (include "traefik.namespace" .) $.Values.hub.apimanagement.admission.secretName -}}
{{- if $cert }}
{{ if or (not (hasKey $cert.data "tls.crt")) (not (hasKey $cert.data "tls.key")) -}}
{{- fail (printf "ERROR: secret %s/%s exists but doesn't contain any certificate data. Please remove it or change hub.apimanagement.admission.secretName." (include "traefik.namespace" .) $.Values.hub.apimanagement.admission.secretName) }}
{{- end -}}
{{/* reusing value of existing cert */}}
Cert: {{ index $cert.data "tls.crt" }}
Key: {{ index $cert.data "tls.key" }}
Hash: {{ sha1sum (index $cert.data "tls.crt") }}
{{- else if not $.Values.hub.apimanagement.admission.selfManagedCertificate -}}
{{/* generate a new one */}}
{{- $altNames := list ( printf "admission.%s.svc" (include "traefik.namespace" .) ) -}}
{{- $cert := genSelfSignedCert ( printf "admission.%s.svc" (include "traefik.namespace" .) ) (list) $altNames 3650 -}}
Cert: {{ $cert.Cert | b64enc }}
Key: {{ $cert.Key | b64enc }}
Hash: {{ sha1sum ($cert.Cert | b64enc) }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "traefik.yaml2CommandLineArgsRec" -}}
{{- $path := .path -}}
{{- range $key, $value := .content -}}
{{- if kindIs "map" $value }}
{{- include "traefik.yaml2CommandLineArgsRec" (dict "path" (printf "%s.%s" $path $key) "content" $value) -}}
{{- else if ne $value nil }}
--{{ join "." (list $path $key)}}={{ if kindIs "slice" $value }}{{ join "," $value }}{{ else }}{{ $value }}{{ end }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "traefik.yaml2CommandLineArgs" -}}
{{- range ((regexSplit "\n" ((include "traefik.yaml2CommandLineArgsRec" (dict "path" .path "content" .content)) | trim) -1) | compact) -}}
{{ printf "- \"%s\"\n" . }}
{{- end -}}
{{- end -}}
{{- define "traefik.localPluginCmName" -}}
{{ include "traefik.fullname" .context }}-local-plugin-{{ .pluginName | replace "." "-" }}
{{- end -}}
{{- define "traefik.hasPluginsVolume" -}}
{{- $found := false -}}
{{- range . -}}
{{- if eq .name "plugins" -}}
{{ $found = true }}
{{- end -}}
{{- end -}}
{{- $found -}}
{{- end -}}
{{/*
Validate localPlugin configuration and determine plugin type
Returns: hostPath, inline, or localPath
*/}}
{{- define "traefik.getLocalPluginType" -}}
{{- $plugin := .plugin -}}
{{- if $plugin.type -}}
{{- if eq $plugin.type "hostPath" -}}
{{- printf "hostPath" -}}
{{- else if eq $plugin.type "inlinePlugin" -}}
{{- printf "inlinePlugin" -}}
{{- else if eq $plugin.type "localPath" -}}
{{- printf "localPath" -}}
{{- else -}}
{{- fail (printf "ERROR: localPlugin %s has invalid type configuration. Must specify one of: hostPath, inlinePlugin, localPath" .pluginName) -}}
{{- end -}}
{{- else if $plugin.hostPath -}}
{{- printf "hostPath" -}}
{{- else -}}
{{- fail (printf "ERROR: localPlugin %s must specify either legacy hostPath configuration or new type configuration!" .pluginName) -}}
{{- end -}}
{{- end -}}
{{/*
Get hostPath for a plugin (handles both old and new structure)
*/}}
{{- define "traefik.getLocalPluginHostPath" -}}
{{- $plugin := .plugin -}}
{{- if $plugin.type -}}
{{- if eq $plugin.type "hostPath" -}}
{{- $plugin.hostPath -}}
{{- end -}}
{{- else -}}
{{- $plugin.hostPath -}}
{{- end -}}
{{- end -}}
{{/*
Get inline plugin files (new structure only)
*/}}
{{- define "traefik.getLocalPluginInlineFiles" -}}
{{- $plugin := .plugin -}}
{{- if eq $plugin.type "inlinePlugin" -}}
{{- required (printf "ERROR: localPlugin %s with type inlinePlugin must have a source field!" .pluginName) $plugin.source | toYaml -}}
{{- end -}}
{{- end -}}
{{/*
Get localPath plugin configuration (new structure only)
*/}}
{{- define "traefik.getLocalPluginLocalPath" -}}
{{- $plugin := .plugin -}}
{{- if eq $plugin.type "localPath" -}}
{{- $localPathConfig := dict -}}
{{- range $key, $value := $plugin -}}
{{- if and (ne $key "type") (ne $key "moduleName") (ne $key "mountPath") -}}
{{- $_ := set $localPathConfig $key $value -}}
{{- end -}}
{{- end -}}
{{- toYaml $localPathConfig -}}
{{- end -}}
{{- end -}}
{{/*
Check if a volume name exists in additionalVolumes
*/}}
{{- define "traefik.volumeExistsInAdditionalVolumes" -}}
{{- $volumeName := .volumeName -}}
{{- $additionalVolumes := .additionalVolumes -}}
{{- $found := false -}}
{{- range $additionalVolumes -}}
{{- if eq .name $volumeName -}}
{{- $found = true -}}
{{- end -}}
{{- end -}}
{{- $found -}}
{{- end -}}
{{/*
Check if using old localPlugin hostPath structure (for deprecation warning)
*/}}
{{- define "traefik.hasDeprecatedLocalPlugins" -}}
{{- if .Values.experimental.localPlugins -}}
{{- range $pluginName, $plugin := .Values.experimental.localPlugins -}}
{{- if $plugin.hostPath -}}
{{- printf "true" -}}
{{- break -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "list.difference" -}}
{{- $a := .a }}
{{- $b := .b }}
{{- $diff := list }}
{{- range $a }}
{{- if not (has . $b) }}
{{- $diff = append $diff . }}
{{- end }}
{{- end }}
{{- toYaml $diff }}
{{- end }}
{{/*
This helper converts the input value of memory to Bytes.
Input needs to be a valid value as supported by k8s memory resource field.
This function aims to handle SI, IEC prefixes or no prefixes (cf. https://github.com/kubeflow/crd-validation/blob/master/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go#L44).
SI prefixes use power of 10 (e.g. 1e18 = 1 x 10^18) (m | "" | k | M | G | T | P | E).
IEC prefixes use power of 2 (e.g. 0x1p60 = 2^60) (Ki | Mi | Gi | Ti | Pi | Ei).
*/}}
{{- define "traefik.convertMemToBytes" }}
{{- $mem := lower . -}}
{{- if hasSuffix "e" $mem -}}
{{- $mem = mulf (trimSuffix "e" $mem | float64) 1e18 -}}
{{- else if hasSuffix "ei" $mem -}}
{{- $mem = mulf (trimSuffix "e" $mem | float64) 0x1p60 -}}
{{- else if hasSuffix "p" $mem -}}
{{- $mem = mulf (trimSuffix "p" $mem | float64) 1e15 -}}
{{- else if hasSuffix "pi" $mem -}}
{{- $mem = mulf (trimSuffix "pi" $mem | float64) 0x1p50 -}}
{{- else if hasSuffix "t" $mem -}}
{{- $mem = mulf (trimSuffix "t" $mem | float64) 1e12 -}}
{{- else if hasSuffix "ti" $mem -}}
{{- $mem = mulf (trimSuffix "ti" $mem | float64) 0x1p40 -}}
{{- else if hasSuffix "g" $mem -}}
{{- $mem = mulf (trimSuffix "g" $mem | float64) 1e9 -}}
{{- else if hasSuffix "gi" $mem -}}
{{- $mem = mulf (trimSuffix "gi" $mem | float64) 0x1p30 -}}
{{- else if hasSuffix "m" . -}}
{{- $mem = divf (trimSuffix "m" $mem | float64) 1e3 -}}
{{- else if hasSuffix "M" . -}}
{{- $mem = mulf (trimSuffix "m" $mem | float64) 1e6 -}}
{{- else if hasSuffix "mi" $mem -}}
{{- $mem = mulf (trimSuffix "mi" $mem | float64) 0x1p20 -}}
{{- else if hasSuffix "k" $mem -}}
{{- $mem = mulf (trimSuffix "k" $mem | float64) 1e3 -}}
{{- else if hasSuffix "ki" $mem -}}
{{- $mem = mulf (trimSuffix "ki" $mem | float64) 0x1p10 -}}
{{- end }}
{{- $mem }}
{{- end }}
{{- define "traefik.gomemlimit" }}
{{- $percentage := .percentage -}}
{{- $memlimitBytes := include "traefik.convertMemToBytes" .memory | mulf $percentage -}}
{{- printf "%dMiB" (divf $memlimitBytes 0x1p20 | floor | int64) -}}
{{- end }}
{{- define "traefik.oltpCommonParams" }}
{{- $path := .path -}}
{{- $otlpConfig := .oltp -}}
{{- if $otlpConfig.enabled }}
- "--{{$path}}=true"
{{- with $otlpConfig.http }}
{{- if .enabled }}
- "--{{$path}}.http=true"
{{ println }}
{{- include "traefik.yaml2CommandLineArgs" (dict "path" (printf "%s.http" $path) "content" (omit . "enabled")) | nindent 2 }}
{{- end }}
{{- end }}
{{- with $otlpConfig.grpc }}
{{- if .enabled }}
- "--{{$path}}.grpc=true"
{{ println }}
{{- include "traefik.yaml2CommandLineArgs" (dict "path" (printf "%s.grpc" $path) "content" (omit . "enabled")) | nindent 2 }}
{{- end }}
{{- end }}
{{- with $otlpConfig.serviceName }}
- "--{{$path}}.serviceName={{.}}"
{{- end }}
{{- range $name, $value := $otlpConfig.resourceAttributes }}
- "--{{$path}}.resourceAttributes.{{ $name }}={{ $value }}"
{{- end }}
{{- end }}
{{- end }}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,25 @@
{{- define "traefik.metrics-service-metadata" }}
labels:
{{- include "traefik.metricsservicelabels" . | nindent 4 -}}
{{- with .Values.metrics.prometheus.service.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
{{/* Labels used for metrics-relevant selector*/}}
{{/* This is an immutable field: this should not change between upgrade */}}
{{- define "traefik.metricslabelselector" -}}
{{- include "traefik.labelselector" . }}
app.kubernetes.io/component: metrics
{{- end }}
{{/* Shared labels used in metadata of metrics-service and servicemonitor */}}
{{- define "traefik.metricsservicelabels" -}}
{{ include "traefik.metricslabelselector" . }}
helm.sh/chart: {{ template "traefik.chart" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.commonLabels }}
{{ toYaml . }}
{{- end }}
{{- end }}
@@ -0,0 +1,85 @@
{{- define "traefik.service-name" -}}
{{- $fullname := printf "%s-%s" (include "traefik.fullname" .root) .name -}}
{{- if eq .name "default" -}}
{{- $fullname = include "traefik.fullname" .root -}}
{{- end -}}
{{- if ge (len $fullname) 60 -}} # 64 - 4 (udp-postfix) = 60
{{- fail "ERROR: Cannot create a service whose full name contains more than 60 characters" -}}
{{- end -}}
{{- $fullname -}}
{{- end -}}
{{- define "traefik.service-metadata" }}
labels:
{{- include "traefik.labels" .root | nindent 4 -}}
{{- with .service.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
{{- define "traefik.service-spec" -}}
{{- $type := default "LoadBalancer" .service.type }}
type: {{ $type }}
{{- with .service.loadBalancerClass }}
loadBalancerClass: {{ . }}
{{- end}}
{{- with .service.spec }}
{{- toYaml . | nindent 2 }}
{{- end }}
selector:
{{- include "traefik.labelselector" .root | nindent 4 }}
{{- if eq $type "LoadBalancer" }}
{{- with .service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{- toYaml . | nindent 2 }}
{{- end -}}
{{- end -}}
{{- with .service.externalIPs }}
externalIPs:
{{- toYaml . | nindent 2 }}
{{- end -}}
{{- with .service.ipFamilyPolicy }}
ipFamilyPolicy: {{ . }}
{{- end }}
{{- with .service.ipFamilies }}
ipFamilies:
{{- toYaml . | nindent 2 }}
{{- end -}}
{{- end }}
{{- define "traefik.service-ports" }}
{{- range $portName, $config := .ports }}
{{- $name := $portName | lower -}}
{{- if (index (default dict $config.expose) $.serviceName) }}
{{- $port := default $config.port $config.exposedPort }}
{{- if empty $port }}
{{- fail (print "ERROR: Cannot create " (trim $name) " port on Service without .port or .exposedPort") }}
{{- end }}
- port: {{ $port }}
name: {{ include "traefik.portname" $name }}
targetPort: {{ default $name $config.targetPort | include "traefik.portreference" }}
protocol: {{ default "TCP" $config.protocol }}
{{- if $config.nodePort }}
nodePort: {{ $config.nodePort }}
{{- end }}
{{- if $config.appProtocol }}
appProtocol: {{ $config.appProtocol }}
{{- end }}
{{- if and ($config.http3).enabled ($config.single) }}
{{- $http3Port := default $config.exposedPort $config.http3.advertisedPort }}
- port: {{ $http3Port }}
name: {{ printf "%s-http3" $name | include "traefik.portname" }}
targetPort: {{ default $name $config.targetPort | include "traefik.portreference" }}
protocol: UDP
{{- if $config.nodePort }}
nodePort: {{ $config.nodePort }}
{{- end }}
{{- if $config.appProtocol }}
appProtocol: {{ $config.appProtocol }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,59 @@
{{- if and .Values.deployment.enabled (eq .Values.deployment.kind "DaemonSet") -}}
{{- with .Values.additionalArguments -}}
{{- range . -}}
{{- if contains ".acme." . -}}
{{- fail (printf "ACME functionality is not supported when running Traefik as a DaemonSet") -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if eq (default .Chart.AppVersion .Values.image.tag) "latest" }}
{{- fail "\n\n ERROR: latest tag should not be used" }}
{{- end }}
{{- with .Values.updateStrategy }}
{{- if and (eq (.type) "RollingUpdate") (.rollingUpdate) }}
{{- if not (contains "%" (toString .rollingUpdate.maxUnavailable)) }}
{{- if and ($.Values.hostNetwork) (lt (float64 .rollingUpdate.maxUnavailable) 1.0) }}
{{- fail "maxUnavailable should be greater than 0 when using hostNetwork." }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- with .Values.deployment.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
annotations:
{{- if and .Values.providers.file.enabled (not .Values.providers.file.watch) }}
checksum/traefik-dynamic-conf: {{ include (print $.Template.BasePath "/provider-file-cm.yaml") . | sha256sum }}
{{- end }}
{{- with .Values.deployment.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
selector:
matchLabels:
{{- include "traefik.labelselector" . | nindent 6 }}
{{- with .Values.updateStrategy }}
updateStrategy:
type: {{ .type }}
{{- if (eq .type "RollingUpdate") }}
rollingUpdate:
maxUnavailable: {{ .rollingUpdate.maxUnavailable }}
maxSurge: {{ .rollingUpdate.maxSurge }}
{{- end }}
{{- end }}
minReadySeconds: {{ .Values.deployment.minReadySeconds }}
{{- if .Values.deployment.revisionHistoryLimit }}
revisionHistoryLimit: {{ .Values.deployment.revisionHistoryLimit }}
{{- end }}
{{/* This dual conversion is used to remove all spurious newlines */}}
template: {{ include "traefik.podTemplate" . | fromYaml | toYaml | nindent 4 }}
{{- end -}}
@@ -0,0 +1,67 @@
{{/* check helm version */}}
{{- if (semverCompare "<v3.9.0" (.Capabilities.HelmVersion.Version | default "v3.0.0")) -}}
{{- fail "ERROR: Helm >= 3.9.0 is required" -}}
{{- end -}}
{{- if and .Values.deployment.enabled (eq .Values.deployment.kind "Deployment") -}}
{{- if gt (int .Values.deployment.replicas) 1 -}}
{{- with .Values.additionalArguments -}}
{{- range . -}}
{{- if contains ".acme." . -}}
{{- fail (printf "You can not enable acme if you set more than one traefik replica") -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if eq (default .Chart.AppVersion .Values.image.tag) "latest" }}
{{- fail "\n\n ERROR: latest tag should not be used" }}
{{- end }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- with .Values.deployment.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
annotations:
{{- if and .Values.providers.file.enabled (not .Values.providers.file.watch) }}
checksum/traefik-dynamic-conf: {{ include (print $.Template.BasePath "/provider-file-cm.yaml") . | sha256sum }}
{{- end }}
{{- with .Values.deployment.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ default 1 .Values.deployment.replicas }}
{{- else if and
.Values.autoscaling.scaleTargetRef
(not (and
(eq .Values.autoscaling.scaleTargetRef.apiVersion "apps/v1")
(eq .Values.autoscaling.scaleTargetRef.kind "Deployment")
))
}}
replicas: {{ default 0 .Values.deployment.replicas }}
{{- end }}
{{- if ne .Values.deployment.revisionHistoryLimit nil }}
revisionHistoryLimit: {{ .Values.deployment.revisionHistoryLimit }}
{{- end }}
selector:
matchLabels:
{{- include "traefik.labelselector" . | nindent 6 }}
{{- with .Values.updateStrategy }}
strategy:
type: {{ .type }}
{{- if (eq .type "RollingUpdate") }}
rollingUpdate:
maxUnavailable: {{ .rollingUpdate.maxUnavailable }}
maxSurge: {{ .rollingUpdate.maxSurge }}
{{- end }}
{{- end }}
minReadySeconds: {{ .Values.deployment.minReadySeconds }}
{{/* This dual conversion is used to remove all spurious newlines */}}
template: {{ include "traefik.podTemplate" . | fromYaml | toYaml | nindent 4 }}
{{- end -}}
@@ -0,0 +1,4 @@
{{- range .Values.extraObjects }}
---
{{ include "traefik.render" (dict "value" . "context" $) }}
{{- end }}
@@ -0,0 +1,65 @@
{{- if and (.Values.gateway).enabled (.Values.providers.kubernetesGateway).enabled }}
{{- if not .Values.gateway.listeners }}
{{- fail "ERROR: gateway must have at least one listener or should be disabled" }}
{{- end }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: {{ default "traefik-gateway" .Values.gateway.name }}
namespace: {{ default ( include "traefik.namespace" . ) .Values.gateway.namespace }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- with .Values.gateway.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
gatewayClassName: {{ default "traefik" .Values.gatewayClass.name }}
{{- with .Values.gateway.infrastructure }}
infrastructure:
{{ toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.gateway.defaultScope }}
defaultScope: {{ . }}
{{- end }}
listeners:
{{- range $name, $config := .Values.gateway.listeners }}
- name: {{ $name }}
{{ if not .port }}
{{- fail "ERROR: port needs to be specified" }}
{{- end -}}
{{ $found := false }}
{{- range $portName, $portConfig := $.Values.ports -}}
{{- if eq $portConfig.port $config.port -}}
{{ $found = true }}
{{- end -}}
{{- end -}}
{{ if not $found }}
{{- fail (printf "ERROR: port %0.f is not declared in ports" .port ) }}
{{- end -}}
port: {{ .port }}
protocol: {{ .protocol }}
{{- with .hostname }}
hostname: {{ . | toYaml }}
{{- end }}
{{- with .namespacePolicy }}
allowedRoutes:
namespaces:
{{- toYaml . | nindent 10 }}
{{- end }}
{{ if and (eq .protocol "HTTPS") (not .certificateRefs) }}
{{- fail "ERROR: certificateRefs needs to be specified using HTTPS" }}
{{- end }}
{{ if or .certificateRefs .mode }}
tls:
{{ with .mode }}
mode: {{ . }}
{{- end }}
{{ with .certificateRefs }}
certificateRefs:
{{- toYaml . | nindent 10 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,14 @@
{{- if and (.Values.gatewayClass).enabled (.Values.providers.kubernetesGateway).enabled }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: {{ default "traefik" .Values.gatewayClass.name }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- with .Values.gatewayClass.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
controllerName: traefik.io/gateway-controller
{{- end }}
@@ -0,0 +1,35 @@
{{- if .Values.autoscaling.enabled }}
{{- if not .Values.autoscaling.maxReplicas }}
{{- fail "ERROR: maxReplicas is required on HPA" }}
{{- end }}
{{- if semverCompare ">=v1.23.0-0" .Capabilities.KubeVersion.Version }}
apiVersion: autoscaling/v2
{{- else }}
apiVersion: autoscaling/v2beta2
{{- end }}
kind: HorizontalPodAutoscaler
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: {{ .Values.autoscaling.scaleTargetRef.apiVersion }}
kind: {{ .Values.autoscaling.scaleTargetRef.kind }}
name: {{ tpl .Values.autoscaling.scaleTargetRef.name . }}
{{- if .Values.autoscaling.minReplicas }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
{{- end }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
{{- if .Values.autoscaling.metrics }}
metrics:
{{ toYaml .Values.autoscaling.metrics | indent 4 }}
{{- end }}
{{- if .Values.autoscaling.behavior }}
behavior:
{{ toYaml .Values.autoscaling.behavior | indent 4 }}
{{- end }}
{{- end }}
@@ -0,0 +1,123 @@
{{- if .Values.hub.token -}}
{{- if and .Values.hub.apimanagement.enabled (not .Values.hub.offline) }}
{{- $cert := include "traefik-hub.webhook_cert" . | fromYaml }}
{{- if or (not .Values.hub.apimanagement.admission.selfManagedCertificate) .Values.hub.apimanagement.admission.customWebhookCertificate}}
---
apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
name: {{ .Values.hub.apimanagement.admission.secretName }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
data:
tls.crt: {{ $cert.Cert }}
tls.key: {{ $cert.Key }}
{{- end }}
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: hub-acp-{{ template "traefik.instance-name" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
annotations:
{{- with .Values.hub.apimanagement.admission.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
webhooks:
- name: admission.traefik.svc
clientConfig:
service:
name: admission
namespace: {{ template "traefik.namespace" . }}
path: /acp
caBundle: {{ $cert.Cert }}
sideEffects: None
admissionReviewVersions:
- v1
rules:
- operations:
- CREATE
- UPDATE
- DELETE
apiGroups:
- hub.traefik.io
apiVersions:
- v1alpha1
resources:
- accesscontrolpolicies
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: hub-api-{{ template "traefik.instance-name" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
annotations:
{{- with .Values.hub.apimanagement.admission.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
webhooks:
{{- $resources := list
(dict "name" "hub-agent.traefik.api" "endpoint" "/api" "resource" "apis")
(dict "name" "hub-agent.traefik.bundle" "endpoint" "/api-bundle" "resource" "apibundles")
(dict "name" "hub-agent.traefik.catalog-item" "endpoint" "/api-catalog-item" "resource" "apicatalogitems")
(dict "name" "hub-agent.traefik.managed-subscription" "endpoint" "/managed-subscription" "resource" "managedsubscriptions")
(dict "name" "hub-agent.traefik.plan" "endpoint" "/api-plan" "resource" "apiplans")
(dict "name" "hub-agent.traefik.portal" "endpoint" "/api-portal" "resource" "apiportals")
(dict "name" "hub-agent.traefik.version" "endpoint" "/api-version" "resource" "apiversions")
}}
{{- range $resources }}
- name: hub-agent.traefik.{{ .name }}
clientConfig:
service:
name: admission
namespace: {{ template "traefik.namespace" $ }}
path: {{ .endpoint }}
caBundle: {{ $cert.Cert }}
sideEffects: None
admissionReviewVersions:
- v1
rules:
- operations:
- CREATE
- UPDATE
- DELETE
apiGroups:
- hub.traefik.io
apiVersions:
- v1alpha1
resources:
- {{ .resource }}
{{- if $.Values.hub.namespaces }}
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
{{- toYaml (uniq (concat (include "traefik.namespace" $ | list) $.Values.hub.namespaces)) | nindent 12 }}
{{- end }}
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: admission
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
ports:
- name: https
port: 443
targetPort: admission
selector:
{{- include "traefik.labelselector" . | nindent 4 }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,19 @@
{{- if .Values.hub.apimanagement.enabled }}
---
apiVersion: v1
kind: Service
metadata:
name: apiportal
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
ports:
- name: apiportal
port: 9903
protocol: TCP
targetPort: apiportal
selector:
{{- include "traefik.labelselector" . | nindent 4 }}
{{- end -}}
@@ -0,0 +1,11 @@
{{- if ge (len .Values.hub.token) 65 }}
---
apiVersion: v1
kind: Secret
metadata:
name: traefik-hub-license
namespace: {{ template "traefik.namespace" . }}
type: Opaque
data:
token: {{ .Values.hub.token | b64enc }}
{{- end }}
@@ -0,0 +1,12 @@
{{- if .Values.ingressClass.enabled -}}
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
annotations:
ingressclass.kubernetes.io/is-default-class: {{ .Values.ingressClass.isDefaultClass | quote }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
name: {{ .Values.ingressClass.name | default (include "traefik.fullname" .) }}
spec:
controller: traefik.io/ingress-controller
{{- end -}}
@@ -0,0 +1,45 @@
{{ range $name, $config := .Values.ingressRoute }}
{{ if $config.enabled }}
{{ $ingressClassAnnotations := dict }}
{{- if and $.Values.ingressClass.enabled $.Values.providers.kubernetesCRD.enabled $.Values.providers.kubernetesCRD.ingressClass }}
{{ $ingressClassAnnotations = dict "kubernetes.io/ingress.class" $.Values.providers.kubernetesCRD.ingressClass }}
{{- end }}
{{ $annotations := merge $ingressClassAnnotations (default $config.annotations dict) }}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: {{ $.Release.Name }}-{{ $name }}
namespace: {{ template "traefik.namespace" $ }}
{{- with $annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
{{- with $config.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
entryPoints:
{{- range $config.entryPoints }}
- {{ . }}
{{- end }}
routes:
- match: {{ $config.matchRule }}
kind: Rule
{{- with $config.services }}
services:
{{- toYaml . | nindent 6 }}
{{- end -}}
{{- with $config.middlewares }}
middlewares:
{{- toYaml . | nindent 6 }}
{{- end -}}
{{- with $config.tls }}
tls:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end -}}
{{ end }}
@@ -0,0 +1,21 @@
{{- if .Values.experimental.localPlugins }}
{{- range $localPluginName, $localPlugin := .Values.experimental.localPlugins }}
{{- $pluginType := include "traefik.getLocalPluginType" (dict "plugin" $localPlugin "pluginName" $localPluginName) }}
{{- if eq $pluginType "inlinePlugin" }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "traefik.localPluginCmName" (dict "context" $ "pluginName" $localPluginName) }}
namespace: {{ template "traefik.namespace" $ }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
data:
{{- $inlineFiles := include "traefik.getLocalPluginInlineFiles" (dict "plugin" $localPlugin "pluginName" $localPluginName) | fromYaml }}
{{- range $fileName, $fileContent := $inlineFiles }}
{{ $fileName }}: |
{{- $fileContent | nindent 4 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,23 @@
{{- if .Values.podDisruptionBudget.enabled -}}
{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }}
apiVersion: policy/v1
{{- else }}
apiVersion: policy/v1beta1
{{- end }}
kind: PodDisruptionBudget
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
{{- include "traefik.labelselector" . | nindent 6 }}
{{- if .Values.podDisruptionBudget.minAvailable }}
minAvailable: {{ .Values.podDisruptionBudget.minAvailable }}
{{- end }}
{{- if .Values.podDisruptionBudget.maxUnavailable }}
maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
{{- end }}
{{- end -}}
@@ -0,0 +1,28 @@
{{- if .Values.metrics.prometheus }}
{{- if (.Values.metrics.prometheus.prometheusRule).enabled }}
{{- if (not (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1")) }}
{{- if (not (.Values.metrics.prometheus.disableAPICheck)) }}
{{- fail "ERROR: You have to deploy monitoring.coreos.com/v1 first" }}
{{- end }}
{{- end }}
apiVersion: {{ .Values.metrics.prometheus.prometheusRule.apiVersion | default "monitoring.coreos.com/v1" }}
kind: PrometheusRule
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ .Values.metrics.prometheus.prometheusRule.namespace | default (include "traefik.namespace" .) }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- with .Values.metrics.prometheus.prometheusRule.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.metrics.prometheus.prometheusRule.rules }}
groups:
- name: {{ template "traefik.name" $ }}
rules:
{{- with .Values.metrics.prometheus.prometheusRule.rules }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,12 @@
{{- if .Values.providers.file.enabled -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "traefik.fullname" . }}-file-provider
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
data:
config.yml:
{{ toYaml .Values.providers.file.content | nindent 4 }}
{{- end -}}
@@ -0,0 +1,26 @@
{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ template "traefik.namespace" . }}
annotations:
{{- with .Values.persistence.annotations }}
{{ toYaml . | nindent 4 }}
{{- end }}
helm.sh/resource-policy: keep
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
accessModes:
- {{ .Values.persistence.accessMode | quote }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- if ne .Values.persistence.storageClass nil }}
storageClassName: {{ .Values.persistence.storageClass | quote }}
{{- end }}
{{- if .Values.persistence.volumeName }}
volumeName: {{ .Values.persistence.volumeName | quote }}
{{- end }}
{{- end -}}
@@ -0,0 +1,326 @@
{{- $version := include "traefik.proxyVersion" $ }}
{{- if and .Values.rbac.enabled (not .Values.rbac.namespaced) }}
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "traefik.clusterRoleName" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- range .Values.rbac.aggregateTo }}
rbac.authorization.k8s.io/aggregate-to-{{ . }}: "true"
{{- end }}
rules:
{{- if (semverCompare "<v3.1.0-0" $version) }}
- apiGroups:
- ""
resources:
- endpoints
- services
verbs:
- get
- list
- watch
{{- if $.Values.hub.token }}
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
{{- end }}
{{- else }}
- apiGroups:
- ""
resources:
{{- if and .Values.providers.kubernetesCRD.enabled (semverCompare ">=v3.4.0-0" $version) }}
- configmaps
{{- end }}
- nodes
- services
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
{{- end }}
{{- if (semverCompare ">=v3.5.0-0" $version) }}
- apiGroups:
- ""
resources:
- pods
verbs:
- get
{{- end }}
- apiGroups:
- ""
resources:
- secrets
{{- with .Values.rbac.secretResourceNames }}
resourceNames: {{ toYaml . | nindent 6 }}
{{- end }}
verbs:
- get
- list
- watch
{{- if and .Values.hub.token }}
- update
- create
- delete
- deletecollection
{{- end }}
{{- if .Values.podSecurityPolicy.enabled }}
- apiGroups:
- policy
resourceNames:
- {{ template "traefik.fullname" . }}
resources:
- podsecuritypolicies
verbs:
- use
{{- end -}}
{{- if or .Values.providers.kubernetesIngress.enabled .Values.providers.kubernetesIngressNginx.enabled }}
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingressclasses
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- ""
resources:
- namespaces
verbs:
- list
- watch
{{- end -}}
{{- if .Values.providers.kubernetesCRD.enabled }}
{{- if not .Values.providers.kubernetesIngress.enabled }}
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingressclasses
verbs:
- get
- list
- watch
{{- end }}
- apiGroups:
- traefik.io
resources:
- ingressroutes
- ingressroutetcps
- ingressrouteudps
- middlewares
- middlewaretcps
- serverstransports
- serverstransporttcps
- tlsoptions
- tlsstores
- traefikservices
verbs:
- get
- list
- watch
{{- end -}}
{{- if (.Values.providers.kubernetesGateway).enabled }}
- apiGroups:
- ""
resources:
- namespaces
{{- if (semverCompare "<v3.1.0-0" $version) }}
- endpoints
{{- end }}
- secrets
{{- if semverCompare ">=v3.2.0-0" $version }}
- configmaps
{{- end }}
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
{{- if semverCompare ">=v3.2.0-0" $version }}
- backendtlspolicies
{{- end }}
- gatewayclasses
- gateways
{{- if semverCompare ">=v3.2.0-0" $version }}
- grpcroutes
{{- end }}
- httproutes
- referencegrants
- tcproutes
- tlsroutes
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
{{- if semverCompare ">=v3.2.0-0" $version }}
- backendtlspolicies/status
{{- end }}
- gatewayclasses/status
- gateways/status
{{- if semverCompare ">=v3.2.0-0" $version }}
- grpcroutes/status
{{- end }}
- httproutes/status
- tcproutes/status
- tlsroutes/status
verbs:
- update
{{- end }}
{{- if (.Values.providers.knative).enabled }}
- apiGroups:
- networking.internal.knative.dev
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- networking.internal.knative.dev
resources:
- ingresses/status
verbs:
- update
{{- end }}
{{- if .Values.hub.token }}
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- hub.traefik.io
resources:
- aiservices
verbs:
- list
- watch
- get
{{- if or (semverCompare ">=v3.1.0-0" $version) .Values.hub.apimanagement.enabled }}
- apiGroups:
- ""
resources:
- endpoints
verbs:
- list
- watch
{{- end }}
- apiGroups:
- ""
resources:
- namespaces
{{- if .Values.hub.apimanagement.enabled }}
- pods
{{- end }}
verbs:
- get
- list
{{- if .Values.hub.apimanagement.enabled }}
- watch
{{- end }}
{{- if .Values.hub.apimanagement.enabled }}
- apiGroups:
- hub.traefik.io
resources:
- accesscontrolpolicies
- apiauths
- apiportals
- apiportalauths
- apiratelimits
- apis
- apiversions
- apibundles
- apiplans
- apicatalogitems
- managedsubscriptions
- managedapplications
verbs:
- get
- list
- watch
{{- if not .Values.hub.offline }}
- create
- update
- patch
- delete
{{- end }}
- apiGroups:
- hub.traefik.io
resources:
- apiauths/status
- apiportals/status
- apiportalauths/status
- apis/status
- apiversions/status
- apibundles/status
- apiplans/status
- apicatalogitems/status
- managedsubscriptions/status
- managedapplications/status
verbs:
- get
- update
- patch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- apps
resources:
- replicasets
verbs:
- get
- list
- watch
{{- if (semverCompare "<v3.1.0-0" $version) }}
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
{{- end -}}
{{- end -}}
{{- end }}
{{- end }}
@@ -0,0 +1,17 @@
{{- if and .Values.rbac.enabled (not .Values.rbac.namespaced) }}
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "traefik.clusterRoleName" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "traefik.clusterRoleName" . }}
subjects:
- kind: ServiceAccount
name: {{ include "traefik.serviceAccountName" . }}
namespace: {{ template "traefik.namespace" . }}
{{- end -}}
@@ -0,0 +1,68 @@
{{- if .Values.podSecurityPolicy.enabled }}
{{- if semverCompare ">=v1.25.0-0" .Capabilities.KubeVersion.Version }}
{{- fail "ERROR: PodSecurityPolicy has been removed in Kubernetes v1.25+" }}
{{- end }}
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: runtime/default
seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default
name: {{ template "traefik.fullname" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
privileged: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
{{- if not .Values.securityContext.runAsNonRoot }}
allowedCapabilities:
- NET_BIND_SERVICE
{{- end }}
hostNetwork: {{ .Values.hostNetwork }}
hostIPC: false
hostPID: false
fsGroup:
{{- if .Values.securityContext.runAsNonRoot }}
ranges:
- max: 65535
min: 1
rule: MustRunAs
{{- else }}
rule: RunAsAny
{{- end }}
{{- if .Values.hostNetwork }}
hostPorts:
- max: 65535
min: 1
{{- end }}
readOnlyRootFilesystem: true
runAsUser:
{{- if .Values.securityContext.runAsNonRoot }}
rule: MustRunAsNonRoot
{{- else }}
rule: RunAsAny
{{- end }}
seLinux:
rule: RunAsAny
supplementalGroups:
{{- if .Values.securityContext.runAsNonRoot }}
ranges:
- max: 65535
min: 1
rule: MustRunAs
{{- else }}
rule: RunAsAny
{{- end }}
volumes:
- configMap
- downwardAPI
- secret
- emptyDir
- projected
{{- if .Values.persistence.enabled }}
- persistentVolumeClaim
{{- end -}}
{{- end -}}
@@ -0,0 +1,257 @@
{{- $version := include "traefik.proxyVersion" $ }}
{{- $ingressNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.kubernetesIngress.namespaces -}}
{{- $CRDNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.kubernetesCRD.namespaces -}}
{{- $knativeNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.knative.namespaces -}}
{{- $hubNamespaces := concat (include "traefik.namespace" . | list) .Values.hub.namespaces -}}
{{- $allNamespaces := sortAlpha (uniq (concat $ingressNamespaces $CRDNamespaces $hubNamespaces $knativeNamespaces)) -}}
{{- if and .Values.rbac.enabled .Values.rbac.namespaced -}}
{{- range $allNamespaces }}
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "traefik.fullname" $ }}
namespace: {{ . }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
rules:
{{- if (semverCompare "<v3.1.0-0" $version) }}
- apiGroups:
- ""
resources:
- endpoints
- services
verbs:
- get
- list
- watch
{{- else }}
- apiGroups:
- ""
resources:
{{- if and $.Values.providers.kubernetesCRD.enabled (semverCompare ">=v3.4.0-0" $version) }}
- configmaps
{{- end }}
- services
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
{{- end }}
{{- if (semverCompare ">=v3.5.0-0" $version) }}
- apiGroups:
- ""
resources:
- pods
verbs:
- get
{{- end }}
# Required while https://github.com/traefik/traefik/issues/7097#issuecomment-1983581843
- apiGroups:
- ""
resources:
- secrets
verbs:
- list
- apiGroups:
- ""
resources:
- secrets
{{- if gt (len $.Values.rbac.secretResourceNames) 0 }}
resourceNames: {{ $.Values.rbac.secretResourceNames }}
{{- end }}
verbs:
- get
- list
- watch
{{- if or (and (has . $ingressNamespaces) $.Values.providers.kubernetesIngress.enabled) ($.Values.providers.kubernetesIngressNginx.enabled) }}
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
{{- end -}}
{{- if (and (has . $CRDNamespaces) $.Values.providers.kubernetesCRD.enabled) }}
- apiGroups:
- traefik.io
resources:
- ingressroutes
- ingressroutetcps
- ingressrouteudps
- middlewares
- middlewaretcps
- tlsoptions
- tlsstores
- traefikservices
- serverstransports
- serverstransporttcps
verbs:
- get
- list
- watch
{{- end -}}
{{- if (and (has . $knativeNamespaces) $.Values.providers.knative.enabled) }}
- apiGroups:
- networking.internal.knative.dev
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- networking.internal.knative.dev
resources:
- ingresses/status
verbs:
- update
{{- end }}
{{- if $.Values.podSecurityPolicy.enabled }}
- apiGroups:
- extensions
resourceNames:
- {{ template "traefik.fullname" $ }}
resources:
- podsecuritypolicies
verbs:
- use
{{- end -}}
{{- if (and (has . $hubNamespaces) $.Values.hub.token) }}
- apiGroups:
- ""
resources:
- services
- endpoints
- pods
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- update
- create
- delete
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- hub.traefik.io
resources:
- aiservices
verbs:
- get
- list
- watch
{{- if $.Values.hub.apimanagement.enabled }}
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- traefik.io
resources:
- ingressroutes
- traefikservices
verbs:
- get
- list
- watch
- apiGroups:
- hub.traefik.io
resources:
- apiauths
- apiportals
- apiportalauths
- apis
- apiversions
- apibundles
- apiplans
- apicatalogitems
- apiaccesses
- managedsubscriptions
- managedapplications
verbs:
- get
- list
- watch
{{- if not $.Values.hub.offline }}
- create
- update
- patch
- delete
{{- end }}
- apiGroups:
- hub.traefik.io
resources:
- apiauths/status
- apiportals/status
- apiportalauths/status
- apis/status
- apiversions/status
- apibundles/status
- apiplans/status
- apicatalogitems/status
- managedsubscriptions/status
- managedapplications/status
verbs:
- get
- update
- patch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- apps
resources:
- replicasets
verbs:
- get
- list
- watch
{{- end }}
{{- end }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,27 @@
{{- $ingressNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.kubernetesIngress.namespaces -}}
{{- $CRDNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.kubernetesCRD.namespaces -}}
{{- $gatewayNamespaces := concat (include "traefik.namespace" . | list) ((.Values.providers.kubernetesGateway).namespaces) -}}
{{- $knativeNamespaces := concat (include "traefik.namespace" . | list) ((.Values.providers.knative).namespaces) -}}
{{- $hubNamespaces := concat (include "traefik.namespace" . | list) .Values.hub.namespaces -}}
{{- $allNamespaces := sortAlpha (uniq (concat $ingressNamespaces $CRDNamespaces $gatewayNamespaces $knativeNamespaces $hubNamespaces)) -}}
{{- if and .Values.rbac.enabled .Values.rbac.namespaced }}
{{- range $allNamespaces }}
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "traefik.fullname" $ }}
namespace: {{ . }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ template "traefik.fullname" $ }}
subjects:
- kind: ServiceAccount
name: {{ include "traefik.serviceAccountName" $ }}
namespace: {{ template "traefik.namespace" $ }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,14 @@
{{- if not .Values.serviceAccount.name -}}
kind: ServiceAccount
apiVersion: v1
metadata:
name: {{ include "traefik.serviceAccountName" . }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
annotations:
{{- with .Values.serviceAccountAnnotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: false
{{- end -}}
@@ -0,0 +1,135 @@
{{- $version := include "traefik.proxyVersion" $ }}
{{- if (ne $version "experimental-v3.0") }}
{{- if (semverCompare "<v3.0.0-0" $version) }}
{{- fail "ERROR: This version of the Chart only supports Traefik Proxy v3" -}}
{{- end }}
{{- end }}
{{- if and .Values.hub.enabled (not (contains "traefik-hub" .Values.image.repository)) }}
{{- fail "ERROR: traefik-hub image is required when enabling Traefik Hub" -}}
{{- end }}
{{- if and (.Values.providers.kubernetesGateway).enabled (and (semverCompare "<v3.1.0-rc3" $version) (not .Values.experimental.kubernetesGateway.enabled)) }}
{{- fail "ERROR: Before traefik v3.1.0-rc3, kubernetesGateway is experimental. Enable it by setting experimental.kubernetesGateway.enabled to true" -}}
{{- end }}
{{- if and (.Values.providers.knative).enabled (not .Values.experimental.knative) }}
{{- fail "ERROR: Knative is experimental. Enable it by setting experimental.knative to true" -}}
{{- end }}
{{- if and (.Values.providers.kubernetesGateway.enabled) (.Values.gateway.defaultScope) (not .Values.providers.kubernetesGateway.experimentalChannel) }}
{{- fail "ERROR: The Gateway 'defaultScope' field is experimental. Enable it by setting providers.kubernetesGateway.experimentalChannel=true" }}
{{- end }}
{{- if .Values.rbac.namespaced }}
{{- if .Values.providers.kubernetesGateway.enabled }}
{{- fail "ERROR: Kubernetes Gateway provider requires ClusterRole. RBAC cannot be namespaced." }}
{{- end }}
{{- if and (not .Values.providers.kubernetesIngress.enabled) (not .Values.providers.kubernetesCRD.enabled) }}
{{- fail "ERROR: namespaced rbac requires Kubernetes CRD or Kubernetes Ingress provider." }}
{{- end }}
{{- end }}
{{- if and (semverCompare "<v3.2.0-0" $version) (.Values.experimental.fastProxy.enabled)}}
{{- fail "ERROR: fastProxy is an experimental feature only available for traefik >= v3.2.0." }}
{{- end }}
{{- if and (semverCompare "<v3.3.0-0" $version) (.Values.experimental.abortOnPluginFailure)}}
{{- fail "ERROR: abortOnPluginFailure is an experimental feature only available for traefik >= v3.3.0." }}
{{- end }}
{{- if and (semverCompare "<v3.6.0-0" $version) (.Values.experimental.knative)}}
{{- fail "ERROR: Knative provider is an experimental feature only available for traefik >= v3.6.0." }}
{{- end }}
{{- if and (semverCompare "<v3.6.2-0" $version) (.Values.providers.kubernetesIngressNginx).enabled}}
{{- fail "ERROR: Kubernetes Ingress NGINX provider is only available for traefik >= v3.6.2." }}
{{- end }}
{{- if and (semverCompare "<3.2.0-0" $version) (.Values.providers.kubernetesGateway.nativeLBByDefault)}}
{{- fail "ERROR: nativeLBByDefault has been introduced in Kubernetes Gateway provider in v3.2.0" }}
{{- end }}
{{- if and (semverCompare "<3.5.0-0" $version) (.Values.providers.kubernetesIngress.strictPrefixMatching)}}
{{- fail "ERROR: strictPrefixMatching is a feature only available for traefik >= v3.5.0." }}
{{- end }}
{{- if and (semverCompare "<3.5.2-0" $version) (eq .Values.logs.access.format "genericCLF")}}
{{- fail "ERROR: genericCLF is an accesslog format option only available for traefik >= v3.5.2." }}
{{- end }}
{{- if and (semverCompare "<v3.2.0-0" $version) (.Values.metrics.otlp.serviceName)}}
{{- fail "ERROR: serviceName is a feature only available for traefik >= v3.2.0." }}
{{- end }}
{{- if and (semverCompare "<v3.5.3-0" $version) (.Values.metrics.otlp.resourceAttributes)}}
{{- fail "ERROR: resourceAttributes with otlp on metrics is a feature only available for traefik >= v3.5.3." }}
{{- end }}
{{- if and (not .Values.experimental.otlpLogs) (or (.Values.logs.general.otlp.enabled) (.Values.logs.access.otlp.enabled))}}
{{- fail "ERROR: otlp on logs or access logs is an experimental feature and needs experimental.otlpLogs=true." }}
{{- end }}
{{- if and (semverCompare "<v3.3.0-0" $version) (.Values.logs.general.otlp.enabled)}}
{{- fail "ERROR: otlp on logs is a feature only available for traefik >= v3.3.0." }}
{{- end }}
{{- if and (semverCompare "<v3.3.0-0" $version) (.Values.logs.access.otlp.enabled)}}
{{- fail "ERROR: otlp on access logs is a feature only available for traefik >= v3.3.0." }}
{{- end }}
{{- if and (semverCompare "<v3.1.0-0" $version) .Values.tracing.safeQueryParams }}
{{ fail "ERROR: safeQueryParams is a feature only available for traefik >= v3.1.0."}}
{{- end }}
{{- range $portName, $config := .Values.ports }}
{{- if and (semverCompare "<v3.3.0-0" $version) (or (ne $config.observability.accessLogs nil) (ne $config.observability.metrics nil) (ne $config.observability.tracing nil) (ne $config.observability.tracingVerbosity nil)) }}
{{ fail "ERROR: per entrypoint observability is a feature only available for traefik >= v3.3.0."}}
{{- end }}
{{- if and (semverCompare "<v3.5.0-0" $version) (ne $config.observability.traceVerbosity nil) }}
{{ fail "ERROR: traceVerbosity is a feature only available for traefik >= v3.5.0."}}
{{- end }}
{{- end }}
{{- if and (semverCompare "<v3.6.4-0" $version) (or
(eq .Values.ports.websecure.http.sanitizePath false)
.Values.ports.websecure.http.encodedCharacters.allowEncodedSlash
.Values.ports.websecure.http.encodedCharacters.allowEncodedBackSlash
.Values.ports.websecure.http.encodedCharacters.allowEncodedNullCharacter
.Values.ports.websecure.http.encodedCharacters.allowEncodedSemicolon
.Values.ports.websecure.http.encodedCharacters.allowEncodedPercent
.Values.ports.websecure.http.encodedCharacters.allowEncodedQuestionMark
.Values.ports.websecure.http.encodedCharacters.allowEncodedHash )}}
{{- fail "ERROR: request path security options are only available for traefik >= v3.6.4." }}
{{- end }}
{{- if $.Values.hub.token -}}
{{ $hubVersion := $.Values.oci_meta.enabled | ternary $.Values.oci_meta.images.hub.tag $.Values.image.tag }}
{{ $hubVersion = ($.Values.global.azure.enabled | ternary $.Values.global.azure.images.hub.tag $hubVersion) }}
{{ if not $hubVersion }}
{{ fail "When using Traefik Hub image tag needs to be specified!" }}
{{- end -}}
{{ $hubVersion = (split "@" (default "v3" $hubVersion))._0 }}
{{/* Consider non semver versions as latest one */}}
{{- if not (regexMatch "v[0-9]+.[0-9]+.[0-9]+" (default "" $hubVersion)) -}}
{{ $hubVersion = "v3.99" }}
{{- end }}
{{- if semverCompare "<v3.19.0-0" $hubVersion }}
{{ fail "ERROR: this Chart supports *only* Traefik Hub >= v3.19.0."}}
{{- end }}
{{- if and (not $.Values.tracing.otlp.enabled) .Values.hub.tracing.additionalTraceHeaders.enabled }}
{{ fail "ERROR: additionalTraceHeaders needs tracing.otlp to be enabled."}}
{{- end }}
{{- with .Values.hub.pluginRegistry.sources }}
{{- range $pluginName, $pluginConf := . }}
{{- if not (hasKey $.Values.experimental.plugins $pluginName) }}
{{ fail (printf "ERROR: pluginRegistry source %s is not used in exprimental.plugins." $pluginName) }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,33 @@
{{- if .Values.metrics.prometheus }}
{{- if .Values.metrics.prometheus.service }}
{{- if (.Values.metrics.prometheus.service).enabled -}}
{{- $fullname := include "traefik.fullname" . }}
{{- if ge (len $fullname) 50 }}
{{- fail "ERROR: Cannot create a metrics service when name contains more than 50 characters" }}
{{- end }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "traefik.service-name" (dict "root" . "name" "metrics") }}
namespace: {{ template "traefik.namespace" . }}
{{- template "traefik.metrics-service-metadata" . }}
annotations:
{{- with .Values.metrics.prometheus.service.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: ClusterIP
selector:
{{- include "traefik.labelselector" . | nindent 4 }}
ports:
- port: {{ .Values.ports.metrics.port }}
name: metrics
targetPort: metrics
protocol: TCP
{{- if .Values.ports.metrics.nodePort }}
nodePort: {{ .Values.ports.metrics.nodePort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,86 @@
{{- $services := .Values.service.additionalServices -}}
{{- $services = set $services "default" (omit .Values.service "additionalServices") }}
{{- range $name, $service := $services -}}
{{- if ne $service.enabled false -}}
{{- $fullname := include "traefik.service-name" (dict "root" $ "name" $name) }}
{{- $tcpPorts := dict -}}
{{- $udpPorts := dict -}}
{{- $exposedPorts := false -}}
{{- range $portName, $config := $.Values.ports -}}
{{- if $config -}}
{{- if ($config.http3).enabled -}}
{{- if (not ($config.http).tls.enabled) -}}
{{- fail "ERROR: You cannot enable http3 without enabling tls" -}}
{{- end -}}
{{ $udpConfig := deepCopy $config -}}
{{ $_ := set $udpConfig "protocol" "UDP" -}}
{{ $_ := set $udpConfig "exposedPort" (default $config.exposedPort $config.http3.advertisedPort) -}}
{{- if (not $service.single) }}
{{ $_ := set $udpPorts (printf "%s-http3" $portName) $udpConfig -}}
{{- else }}
{{ $_ := set $tcpPorts (printf "%s-http3" $portName) $udpConfig -}}
{{- end }}
{{- end -}}
{{- if eq (toString $config.protocol) "UDP" -}}
{{ $_ := set $udpPorts $portName $config -}}
{{- end -}}
{{- if eq (toString (default "TCP" $config.protocol)) "TCP" -}}
{{ $_ := set $tcpPorts $portName $config -}}
{{- end -}}
{{- if (index (default dict $config.expose) $name) -}}
{{- $exposedPorts = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if (eq $exposedPorts false) -}}
{{- fail (printf "ERROR: Cannot create Service %s without ports" $fullname) -}}
{{- end -}}
{{- if and $exposedPorts (or $tcpPorts $service.single) }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $fullname }}
namespace: {{ template "traefik.namespace" $ }}
{{- template "traefik.service-metadata" (dict "root" $ "service" $service) }}
annotations:
{{- with (merge dict (default dict $service.annotationsTCP) (default dict $service.annotations)) }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- template "traefik.service-spec" (dict "root" $ "service" $service) }}
ports:
{{- template "traefik.service-ports" (dict "ports" $tcpPorts "serviceName" $name) }}
{{- if $service.single }}
{{- template "traefik.service-ports" (dict "ports" $udpPorts "serviceName" $name) }}
{{- end }}
{{- end }}
{{- if and $exposedPorts (and $udpPorts (not $service.single)) }}
{{- $ports := include "traefik.service-ports" (dict "ports" $udpPorts "serviceName" $name) }}
{{- if not (empty $ports) }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $fullname }}-udp
namespace: {{ template "traefik.namespace" $ }}
{{- template "traefik.service-metadata" (dict "root" $ "service" $service) }}
annotations:
{{- with (merge dict (default dict $service.annotationsUDP) (default dict $service.annotations)) }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- template "traefik.service-spec" (dict "root" $ "service" $service) }}
ports:
{{- $ports }}
{{- end }}
{{- end }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,69 @@
{{- if .Values.metrics.prometheus }}
{{- if (.Values.metrics.prometheus.serviceMonitor).enabled }}
{{- if (not (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1")) }}
{{- if (not (.Values.metrics.prometheus.disableAPICheck)) }}
{{- fail "ERROR: You have to deploy monitoring.coreos.com/v1 first" }}
{{- end }}
{{- end }}
apiVersion: {{ .Values.metrics.prometheus.serviceMonitor.apiVersion | default "monitoring.coreos.com/v1" }}
kind: ServiceMonitor
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ .Values.metrics.prometheus.serviceMonitor.namespace | default (include "traefik.namespace" .) }}
labels:
{{- if (.Values.metrics.prometheus.service).enabled }}
{{- include "traefik.metricsservicelabels" . | nindent 4 }}
{{- else }}
{{- include "traefik.labels" . | nindent 4 }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
jobLabel: {{ .Values.metrics.prometheus.serviceMonitor.jobLabel | default .Release.Name }}
endpoints:
- targetPort: metrics
path: /{{ .Values.metrics.prometheus.entryPoint }}
{{- with .Values.metrics.prometheus.serviceMonitor.honorLabels }}
honorLabels: {{ . }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.honorTimestamps }}
honorTimestamps: {{ . }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.enableHttp2 }}
enableHttp2: {{ . }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.followRedirects }}
followRedirects: {{ . }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.interval }}
interval: {{ . }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.scrapeTimeout }}
scrapeTimeout: {{ . }}
{{- end }}
{{- if .Values.metrics.prometheus.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{ tpl (toYaml .Values.metrics.prometheus.serviceMonitor.metricRelabelings | indent 6) . }}
{{- end }}
{{- if .Values.metrics.prometheus.serviceMonitor.relabelings }}
relabelings:
{{ toYaml .Values.metrics.prometheus.serviceMonitor.relabelings | indent 6 }}
{{- end }}
{{- if .Values.metrics.prometheus.serviceMonitor.namespaceSelector }}
namespaceSelector:
{{ toYaml .Values.metrics.prometheus.serviceMonitor.namespaceSelector | indent 4 -}}
{{ else }}
namespaceSelector:
matchNames:
- {{ template "traefik.namespace" . }}
{{- end }}
selector:
matchLabels:
{{- if (.Values.metrics.prometheus.service).enabled }}
{{- include "traefik.metricslabelselector" . | nindent 6 }}
{{- else }}
{{- include "traefik.labelselector" . | nindent 6 }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,46 @@
{{- range $name, $config := .Values.tlsOptions }}
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: {{ $name }}
namespace: {{ template "traefik.namespace" $ }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
{{- with $config.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with $config.alpnProtocols }}
alpnProtocols:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $config.cipherSuites }}
cipherSuites:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $config.clientAuth }}
clientAuth:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $config.curvePreferences }}
curvePreferences:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $config.disableSessionTickets }}
{{- $version := include "traefik.proxyVersion" $ }}
{{- if semverCompare "<v3.4.0-0" $version }}
{{- fail "ERROR: disableSessionTickets is a feature only available for traefik >= v3.4.0." }}
{{- end }}
disableSessionTickets: {{ . }}
{{- end }}
{{- with $config.maxVersion }}
maxVersion: {{ . }}
{{- end }}
{{- with $config.minVersion }}
minVersion: {{ . }}
{{- end }}
{{- with $config.sniStrict }}
sniStrict: {{ . }}
{{- end }}
---
{{- end -}}
@@ -0,0 +1,12 @@
{{- range $name, $config := .Values.tlsStore }}
apiVersion: traefik.io/v1alpha1
kind: TLSStore
metadata:
name: {{ $name }}
namespace: {{ template "traefik.namespace" $ }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
spec:
{{- toYaml $config | nindent 2 }}
---
{{- end -}}