diff --git a/EXAMPLES.md b/EXAMPLES.md index 9fb939d96..12e544a75 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -331,14 +331,15 @@ Here is a more complete example, using also native Let's encrypt feature of Trae persistence: enabled: true size: 128Mi -certResolvers: +certificatesResolvers: letsencrypt: - email: "{{ letsencrypt_email }}" - #caServer: https://acme-v02.api.letsencrypt.org/directory # Production server - caServer: https://acme-staging-v02.api.letsencrypt.org/directory # Staging server - dnsChallenge: - provider: azuredns - storage: /data/acme.json + acme: + email: "{{ letsencrypt_email }}" + #caServer: https://acme-v02.api.letsencrypt.org/directory # Production server + caServer: https://acme-staging-v02.api.letsencrypt.org/directory # Staging server + dnsChallenge: + provider: azuredns + storage: /data/acme.json env: - name: AZURE_CLIENT_ID value: "{{ azure_dns_challenge_application_id }}" @@ -529,11 +530,12 @@ stringData: persistence: enabled: true storageClass: xxx -certResolvers: +certificatesResolvers: letsencrypt: - dnsChallenge: - provider: cloudflare - storage: /data/acme.json + acme: + dnsChallenge: + provider: cloudflare + storage: /data/acme.json env: - name: CF_DNS_API_TOKEN valueFrom: @@ -553,6 +555,9 @@ podSecurityContext: fsGroupChangePolicy: "OnRootMismatch" ``` +>[!NOTE] +> With [Traefik Hub](https://traefik.io/traefik-hub/), certificates can be stored as a `Secret` on Kubernetes with `distributedAcme` resolver. + # Provide default certificate with cert-manager and CloudFlare DNS Setup: diff --git a/traefik/VALUES.md b/traefik/VALUES.md index 082fda0cc..a3707d4b3 100644 --- a/traefik/VALUES.md +++ b/traefik/VALUES.md @@ -32,7 +32,7 @@ Kubernetes: `>=1.22.0-0` | additionalVolumeMounts | list | `[]` | Additional volumeMounts to add to the Traefik container | | affinity | object | `{}` | on nodes where no other traefik pods are scheduled. It should be used when hostNetwork: true to prevent port conflicts | | autoscaling.enabled | bool | `false` | Create HorizontalPodAutoscaler object. See EXAMPLES.md for more details. | -| certResolvers | object | `{}` | Certificates resolvers configuration. Ref: https://doc.traefik.io/traefik/https/acme/#certificate-resolvers See EXAMPLES.md for more details. | +| certificatesResolvers | object | `{}` | Certificates resolvers configuration. Ref: https://doc.traefik.io/traefik/https/acme/#certificate-resolvers See EXAMPLES.md for more details. | | commonLabels | object | `{}` | Add additional label to all resources | | core.defaultRuleSyntax | string | `""` | Can be used to use globally v2 router syntax See https://doc.traefik.io/traefik/v3.0/migration/v2-to-v3/#new-v3-syntax-notable-changes | | deployment.additionalContainers | list | `[]` | Additional containers (e.g. for metric offloading sidecars) | @@ -191,7 +191,7 @@ Kubernetes: `>=1.22.0-0` | nodeSelector | object | `{}` | nodeSelector is the simplest recommended form of node selection constraint. | | persistence.accessMode | string | `"ReadWriteOnce"` | | | persistence.annotations | object | `{}` | | -| persistence.enabled | bool | `false` | Enable persistence using Persistent Volume Claims ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ It can be used to store TLS certificates, see `storage` in certResolvers | +| persistence.enabled | bool | `false` | Enable persistence using Persistent Volume Claims ref: http://kubernetes.io/docs/user-guide/persistent-volumes/. It can be used to store TLS certificates along with `certificatesResolvers..acme.storage` option | | persistence.existingClaim | string | `""` | | | persistence.name | string | `"data"` | | | persistence.path | string | `"/data"` | | diff --git a/traefik/templates/_helpers.tpl b/traefik/templates/_helpers.tpl index 2183f84ab..284e9126a 100644 --- a/traefik/templates/_helpers.tpl +++ b/traefik/templates/_helpers.tpl @@ -159,3 +159,20 @@ Cert: {{ $cert.Cert | b64enc }} Key: {{ $cert.Key | b64enc }} {{- 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 }} +--{{ join "." (list $path $key)}}={{ join "," $value }} + {{- 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 -}} diff --git a/traefik/templates/_podtemplate.tpl b/traefik/templates/_podtemplate.tpl index c7eb8d029..b08f83273 100644 --- a/traefik/templates/_podtemplate.tpl +++ b/traefik/templates/_podtemplate.tpl @@ -685,17 +685,7 @@ {{- end }} {{- end }} {{- end }} - {{- range $resolver, $config := $.Values.certResolvers }} - {{- range $option, $setting := $config }} - {{- if kindIs "map" $setting }} - {{- range $field, $value := $setting }} - - "--certificatesresolvers.{{ $resolver }}.acme.{{ $option }}.{{ $field }}={{ if kindIs "slice" $value }}{{ join "," $value }}{{ else }}{{ $value }}{{ end }}" - {{- end }} - {{- else }} - - "--certificatesresolvers.{{ $resolver }}.acme.{{ $option }}={{ $setting }}" - {{- end }} - {{- end }} - {{- end }} + {{- include "traefik.yaml2CommandLineArgs" (dict "path" "certificatesresolvers" "content" $.Values.certificatesResolvers) | nindent 10 }} {{- with .Values.additionalArguments }} {{- range . }} - {{ . | quote }} diff --git a/traefik/templates/requirements.yaml b/traefik/templates/requirements.yaml index 795e45937..611a187ef 100644 --- a/traefik/templates/requirements.yaml +++ b/traefik/templates/requirements.yaml @@ -5,6 +5,10 @@ {{- end }} {{- end }} +{{- if .Values.certResolvers }} + {{- fail "ERROR: certResolvers setting has been removed. See v33.0.0 Changelog." }} +{{- 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 }} diff --git a/traefik/tests/pod-config_test.yaml b/traefik/tests/pod-config_test.yaml index 4f6053b09..9fed690b5 100644 --- a/traefik/tests/pod-config_test.yaml +++ b/traefik/tests/pod-config_test.yaml @@ -330,15 +330,16 @@ tests: content: "--experimental.kubernetesgateway" - it: should have the certificate resolver options applied set: - certResolvers: + certificatesResolvers: myAcmeResolver: - email: email@example.com - dnsChallenge: - provider: myProvider - resolvers: - - 1.1.1.1 - - 8.8.8.8 - tlsChallenge: true + acme: + email: email@example.com + dnsChallenge: + provider: myProvider + resolvers: + - 1.1.1.1 + - 8.8.8.8 + tlsChallenge: true asserts: - contains: path: spec.template.spec.containers[0].args @@ -352,6 +353,38 @@ tests: - contains: path: spec.template.spec.containers[0].args content: "--certificatesresolvers.myAcmeResolver.acme.tlsChallenge=true" + + - it: should have the distributed acme resolver options applied + set: + certificatesResolvers: + my-resolver: + distributedAcme: + email: email@example.com + storage: + kubernetes: true + httpChallenge: + entrypoint: "web" + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: "--certificatesresolvers.my-resolver.distributedAcme.email=email@example.com" + - contains: + path: spec.template.spec.containers[0].args + content: "--certificatesresolvers.my-resolver.distributedAcme.storage.kubernetes=true" + - contains: + path: spec.template.spec.containers[0].args + content: "--certificatesresolvers.my-resolver.distributedAcme.httpChallenge.entrypoint=web" + + - it: should have the tailscale resolver options applied + set: + certificatesResolvers: + my-resolver: + tailscale: true + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: "--certificatesresolvers.my-resolver.tailscale=true" + - it: should have prometheus annotations with specified values set: ports: diff --git a/traefik/tests/requirements-config_test.yaml b/traefik/tests/requirements-config_test.yaml index 5648615da..829035bce 100644 --- a/traefik/tests/requirements-config_test.yaml +++ b/traefik/tests/requirements-config_test.yaml @@ -87,3 +87,18 @@ tests: asserts: - failedTemplate: errorMessage: "ERROR: Kubernetes Gateway provider requires ClusterRole. RBAC cannot be namespaced." + - it: should fail when trying to use certResolvers + set: + certResolvers: + myAcmeResolver: + email: email@example.com + dnsChallenge: + provider: myProvider + resolvers: + - 1.1.1.1 + - 8.8.8.8 + tlsChallenge: true + asserts: + - failedTemplate: + errorMessage: "ERROR: certResolvers setting has been removed. See v33.0.0 Changelog." + diff --git a/traefik/values.schema.json b/traefik/values.schema.json index 9ead304c7..d9ee485c7 100644 --- a/traefik/values.schema.json +++ b/traefik/values.schema.json @@ -22,7 +22,7 @@ }, "type": "object" }, - "certResolvers": { + "certificatesResolvers": { "properties": {}, "type": "object" }, diff --git a/traefik/values.yaml b/traefik/values.yaml index 9eb011811..664426163 100644 --- a/traefik/values.yaml +++ b/traefik/values.yaml @@ -774,8 +774,8 @@ autoscaling: persistence: # -- Enable persistence using Persistent Volume Claims - # ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - # It can be used to store TLS certificates, see `storage` in certResolvers + # ref: http://kubernetes.io/docs/user-guide/persistent-volumes/. + # It can be used to store TLS certificates along with `certificatesResolvers..acme.storage` option enabled: false name: data existingClaim: "" @@ -791,7 +791,7 @@ persistence: # -- Certificates resolvers configuration. # Ref: https://doc.traefik.io/traefik/https/acme/#certificate-resolvers # See EXAMPLES.md for more details. -certResolvers: {} +certificatesResolvers: {} # -- If hostNetwork is true, runs traefik in the host network namespace # To prevent unschedulabel pods due to port collisions, if hostNetwork=true