From 7d9336834e74f2af091257c427e05ef52b554877 Mon Sep 17 00:00:00 2001 From: Melvin GABALI Date: Wed, 21 Jan 2026 01:13:11 +0100 Subject: [PATCH] add ovh --- ...plicationset-cert-manager-webhook-ovh.yaml | 47 ++++++ docs/INSTALLATION-WEBHOOK-OVH.md | 135 ++++++++++++++++++ helm/cert-manager-webhook-ovh/ops/Chart.yaml | 7 + helm/cert-manager-webhook-ovh/ops/README.md | 67 +++++++++ .../ops/templates/deployment.yaml | 63 ++++++++ .../ops/templates/mutating-webhook.yaml | 31 ++++ .../ops/templates/rbac.yaml | 31 ++++ .../ops/templates/service.yaml | 19 +++ .../ops/templates/serviceaccount.yaml | 9 ++ .../ops/templates/validating-webhook.yaml | 31 ++++ helm/cert-manager-webhook-ovh/ops/values.yaml | 32 +++++ .../cluster-issuer-letsencrypt-dns01.yaml | 26 ++-- .../ops/templates/secret-ovh-credentials.yaml | 8 +- 13 files changed, 496 insertions(+), 10 deletions(-) create mode 100644 apps/applicationset-cert-manager-webhook-ovh.yaml create mode 100644 docs/INSTALLATION-WEBHOOK-OVH.md create mode 100644 helm/cert-manager-webhook-ovh/ops/Chart.yaml create mode 100644 helm/cert-manager-webhook-ovh/ops/README.md create mode 100644 helm/cert-manager-webhook-ovh/ops/templates/deployment.yaml create mode 100644 helm/cert-manager-webhook-ovh/ops/templates/mutating-webhook.yaml create mode 100644 helm/cert-manager-webhook-ovh/ops/templates/rbac.yaml create mode 100644 helm/cert-manager-webhook-ovh/ops/templates/service.yaml create mode 100644 helm/cert-manager-webhook-ovh/ops/templates/serviceaccount.yaml create mode 100644 helm/cert-manager-webhook-ovh/ops/templates/validating-webhook.yaml create mode 100644 helm/cert-manager-webhook-ovh/ops/values.yaml diff --git a/apps/applicationset-cert-manager-webhook-ovh.yaml b/apps/applicationset-cert-manager-webhook-ovh.yaml new file mode 100644 index 0000000..2bed1ab --- /dev/null +++ b/apps/applicationset-cert-manager-webhook-ovh.yaml @@ -0,0 +1,47 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: cert-manager-webhook-ovh + namespace: argocd-ops +spec: + generators: + # Le webhook OVH est déployé UNIQUEMENT sur le cluster OPS + - merge: + generators: + # Premier générateur : scanne les répertoires Helm pour cert-manager-webhook-ovh + - git: + repoURL: https://git.gkdomaine.fr/kubernetes/argocd.git + revision: main + directories: + - path: "helm/cert-manager-webhook-ovh/*" + # Deuxième générateur : lit la config OPS uniquement + - git: + repoURL: https://git.gkdomaine.fr/kubernetes/argocd.git + revision: main + files: + - path: "configs/ops/config.json" + mergeKeys: + - path.basename + template: + metadata: + name: 'cert-manager-webhook-ovh-{{path.basename}}' + spec: + project: default + source: + repoURL: '{{repository}}' + targetRevision: '{{targetRevision}}' + path: '{{helmPath}}/cert-manager-webhook-ovh/{{path.basename}}' + helm: + valueFiles: + - values.yaml + destination: + # Déploie uniquement sur le cluster OPS + name: '{{name}}' + namespace: cert-manager-ops + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + diff --git a/docs/INSTALLATION-WEBHOOK-OVH.md b/docs/INSTALLATION-WEBHOOK-OVH.md new file mode 100644 index 0000000..47fc71a --- /dev/null +++ b/docs/INSTALLATION-WEBHOOK-OVH.md @@ -0,0 +1,135 @@ +# Installation du Webhook OVH pour cert-manager + +## Problème + +Cert-manager v1.19.2 ne supporte **pas nativement** le provider OVH. L'erreur `no DNS01 provider configured` apparaît car cert-manager ne reconnaît pas la syntaxe `ovh:` directement. + +## Solution + +Installer le webhook `cert-manager-webhook-ovh` qui ajoute le support OVH à cert-manager. + +## Étape 1 : Ajouter le dépôt Helm + +```bash +helm repo add cert-manager-webhook-ovh https://cert-manager.github.io/webhook-ovh +helm repo update +``` + +## Étape 2 : Installer le Webhook OVH + +```bash +helm install cert-manager-webhook-ovh cert-manager-webhook-ovh/cert-manager-webhook-ovh \ + -n cert-manager-ops \ + --create-namespace \ + --set groupName=acme.gkdomaine.fr +``` + +**Important** : Le `groupName` doit correspondre à celui configuré dans le ClusterIssuer (`acme.gkdomaine.fr`). + +## Étape 3 : Vérifier l'Installation + +```bash +# Vérifier que le webhook est installé +kubectl get pods -n cert-manager-ops | grep webhook-ovh + +# Vérifier les logs +kubectl logs -n cert-manager-ops -l app.kubernetes.io/name=cert-manager-webhook-ovh +``` + +## Étape 4 : Mettre à jour le Secret OVH + +Le Secret doit maintenant contenir les 3 clés (application-key, application-secret, consumer-key) : + +```bash +kubectl create secret generic ovh-credentials \ + --from-literal=application-key=e598bb73ded17ee6 \ + --from-literal=application-secret=VOTRE_APPLICATION_SECRET \ + --from-literal=consumer-key=372e273858204d972dbf7c50506d12a1 \ + -n certificates-ops \ + --context=cluster-ops +``` + +Ou mettez à jour le Secret existant : + +```bash +kubectl patch secret ovh-credentials -n certificates-ops \ + --type='json' \ + -p='[ + {"op": "add", "path": "/data/application-key", "value": "'$(echo -n 'e598bb73ded17ee6' | base64)'"}, + {"op": "add", "path": "/data/consumer-key", "value": "'$(echo -n '372e273858204d972dbf7c50506d12a1' | base64)'"} + ]' \ + --context=cluster-ops +``` + +## Étape 5 : Vérifier le ClusterIssuer + +Après installation du webhook, le ClusterIssuer devrait être accepté : + +```bash +# Vérifier le ClusterIssuer +kubectl get clusterissuer letsencrypt-dns01-prod --context=cluster-ops + +# Voir les détails +kubectl describe clusterissuer letsencrypt-dns01-prod --context=cluster-ops +``` + +## Alternative : Utiliser Cloudflare (si disponible) + +Si vous avez accès à Cloudflare pour gérer votre DNS, vous pouvez utiliser Cloudflare qui est supporté nativement par cert-manager : + +```yaml +solvers: +- selector: + dnsZones: + - "dev.gkdomaine.fr" + dns01: + cloudflare: + email: gkpoubelle78@gmail.com + apiKeySecretRef: + name: cloudflare-api-key + key: api-key +``` + +## Troubleshooting + +### Le webhook ne démarre pas + +1. Vérifiez les logs : +```bash +kubectl logs -n cert-manager-ops -l app.kubernetes.io/name=cert-manager-webhook-ovh +``` + +2. Vérifiez les événements : +```bash +kubectl get events -n cert-manager-ops --sort-by='.lastTimestamp' | grep webhook-ovh +``` + +### Le ClusterIssuer est toujours rejeté + +1. Vérifiez que le `groupName` correspond : + - Dans le ClusterIssuer : `groupName: acme.gkdomaine.fr` + - Dans l'installation du webhook : `--set groupName=acme.gkdomaine.fr` + +2. Vérifiez les logs du webhook cert-manager : +```bash +kubectl logs -n cert-manager-ops -l app.kubernetes.io/component=webhook +``` + +### Le certificat ne se génère pas + +1. Vérifiez que le Secret contient les 3 clés : +```bash +kubectl get secret ovh-credentials -n certificates-ops -o yaml +``` + +2. Vérifiez les challenges DNS : +```bash +kubectl get challenges -n certificates-ops +kubectl describe challenge -n certificates-ops +``` + +## Documentation + +- [cert-manager-webhook-ovh GitHub](https://github.com/cert-manager/webhook-ovh) +- [Documentation cert-manager DNS-01](https://cert-manager.io/docs/configuration/acme/dns01/) + diff --git a/helm/cert-manager-webhook-ovh/ops/Chart.yaml b/helm/cert-manager-webhook-ovh/ops/Chart.yaml new file mode 100644 index 0000000..3e4d3ff --- /dev/null +++ b/helm/cert-manager-webhook-ovh/ops/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: cert-manager-webhook-ovh +description: Webhook OVH pour cert-manager - Ajoute le support DNS-01 pour OVH +type: application +version: 1.0.0 +appVersion: "1.0.0" + diff --git a/helm/cert-manager-webhook-ovh/ops/README.md b/helm/cert-manager-webhook-ovh/ops/README.md new file mode 100644 index 0000000..53d1209 --- /dev/null +++ b/helm/cert-manager-webhook-ovh/ops/README.md @@ -0,0 +1,67 @@ +# Cert-manager Webhook OVH + +Ce chart Helm déploie le webhook OVH pour cert-manager, permettant d'utiliser le DNS-01 challenge avec OVH comme fournisseur DNS. + +## Installation via ArgoCD + +Ce chart est déployé automatiquement via l'ApplicationSet `cert-manager-webhook-ovh` dans ArgoCD. + +## Image Docker + +**Important** : L'image Docker officielle pour cert-manager-webhook-ovh peut ne pas exister. Vous avez deux options : + +### Option 1 : Utiliser une image existante + +Si une image existe sur un registry (Docker Hub, Quay.io, etc.), mettez à jour `values.yaml` : + +```yaml +image: + repository: votre-registry/cert-manager-webhook-ovh + tag: "v1.0.0" +``` + +### Option 2 : Construire l'image vous-même + +1. Clonez le repository du webhook OVH : +```bash +git clone https://github.com/cert-manager/webhook-ovh.git +cd webhook-ovh +``` + +2. Construisez l'image : +```bash +docker build -t votre-registry/cert-manager-webhook-ovh:v1.0.0 . +docker push votre-registry/cert-manager-webhook-ovh:v1.0.0 +``` + +3. Mettez à jour `values.yaml` avec votre image. + +## Configuration + +Le `groupName` dans `values.yaml` doit correspondre exactement à celui configuré dans le ClusterIssuer : + +```yaml +groupName: acme.gkdomaine.fr +``` + +## Vérification + +Après déploiement : + +```bash +# Vérifier les pods +kubectl get pods -n cert-manager-ops | grep webhook-ovh + +# Vérifier les logs +kubectl logs -n cert-manager-ops -l app=cert-manager-webhook-ovh + +# Vérifier les webhooks +kubectl get mutatingwebhookconfiguration cert-manager-webhook-ovh +kubectl get validatingwebhookconfiguration cert-manager-webhook-ovh +``` + +## Documentation + +- [cert-manager Webhooks](https://cert-manager.io/docs/concepts/webhook/) +- [DNS-01 Challenge](https://cert-manager.io/docs/configuration/acme/dns01/) + diff --git a/helm/cert-manager-webhook-ovh/ops/templates/deployment.yaml b/helm/cert-manager-webhook-ovh/ops/templates/deployment.yaml new file mode 100644 index 0000000..f02fba6 --- /dev/null +++ b/helm/cert-manager-webhook-ovh/ops/templates/deployment.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cert-manager-webhook-ovh + namespace: {{ .Values.namespace }} + labels: + app: cert-manager-webhook-ovh + app.kubernetes.io/name: cert-manager-webhook-ovh + app.kubernetes.io/component: webhook +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: cert-manager-webhook-ovh + template: + metadata: + labels: + app: cert-manager-webhook-ovh + app.kubernetes.io/name: cert-manager-webhook-ovh + app.kubernetes.io/component: webhook + spec: + serviceAccountName: cert-manager-webhook-ovh + containers: + - name: webhook + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - --v=2 + - --group-name={{ .Values.groupName }} + - --secure-port=10250 + ports: + - name: https + containerPort: 10250 + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: 6080 + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /healthz + port: 6080 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + resources: + {{- toYaml .Values.resources | nindent 10 }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + diff --git a/helm/cert-manager-webhook-ovh/ops/templates/mutating-webhook.yaml b/helm/cert-manager-webhook-ovh/ops/templates/mutating-webhook.yaml new file mode 100644 index 0000000..7a8f643 --- /dev/null +++ b/helm/cert-manager-webhook-ovh/ops/templates/mutating-webhook.yaml @@ -0,0 +1,31 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: cert-manager-webhook-ovh + labels: + app: cert-manager-webhook-ovh + app.kubernetes.io/name: cert-manager-webhook-ovh +webhooks: +- name: webhook.cert-manager.io + admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: cert-manager-webhook-ovh + namespace: {{ .Values.namespace }} + path: "/mutate" + failurePolicy: Fail + sideEffects: None + rules: + - apiGroups: + - cert-manager.io + - acme.cert-manager.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - "*/*" + diff --git a/helm/cert-manager-webhook-ovh/ops/templates/rbac.yaml b/helm/cert-manager-webhook-ovh/ops/templates/rbac.yaml new file mode 100644 index 0000000..2c55a8e --- /dev/null +++ b/helm/cert-manager-webhook-ovh/ops/templates/rbac.yaml @@ -0,0 +1,31 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cert-manager-webhook-ovh:webhook-requester + labels: + app: cert-manager-webhook-ovh +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cert-manager-webhook-ovh:webhook-requester + labels: + app: cert-manager-webhook-ovh +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cert-manager-webhook-ovh:webhook-requester +subjects: +- apiGroup: "" + kind: ServiceAccount + name: cert-manager-webhook-ovh + namespace: {{ .Values.namespace }} + diff --git a/helm/cert-manager-webhook-ovh/ops/templates/service.yaml b/helm/cert-manager-webhook-ovh/ops/templates/service.yaml new file mode 100644 index 0000000..e993b32 --- /dev/null +++ b/helm/cert-manager-webhook-ovh/ops/templates/service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: cert-manager-webhook-ovh + namespace: {{ .Values.namespace }} + labels: + app: cert-manager-webhook-ovh + app.kubernetes.io/name: cert-manager-webhook-ovh + app.kubernetes.io/component: webhook +spec: + type: ClusterIP + ports: + - name: https + port: 443 + targetPort: 10250 + protocol: TCP + selector: + app: cert-manager-webhook-ovh + diff --git a/helm/cert-manager-webhook-ovh/ops/templates/serviceaccount.yaml b/helm/cert-manager-webhook-ovh/ops/templates/serviceaccount.yaml new file mode 100644 index 0000000..01e1d8f --- /dev/null +++ b/helm/cert-manager-webhook-ovh/ops/templates/serviceaccount.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: cert-manager-webhook-ovh + namespace: {{ .Values.namespace }} + labels: + app: cert-manager-webhook-ovh + app.kubernetes.io/name: cert-manager-webhook-ovh + diff --git a/helm/cert-manager-webhook-ovh/ops/templates/validating-webhook.yaml b/helm/cert-manager-webhook-ovh/ops/templates/validating-webhook.yaml new file mode 100644 index 0000000..efeb213 --- /dev/null +++ b/helm/cert-manager-webhook-ovh/ops/templates/validating-webhook.yaml @@ -0,0 +1,31 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: cert-manager-webhook-ovh + labels: + app: cert-manager-webhook-ovh + app.kubernetes.io/name: cert-manager-webhook-ovh +webhooks: +- name: webhook.cert-manager.io + admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: cert-manager-webhook-ovh + namespace: {{ .Values.namespace }} + path: "/validate" + failurePolicy: Fail + sideEffects: None + rules: + - apiGroups: + - cert-manager.io + - acme.cert-manager.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - "*/*" + diff --git a/helm/cert-manager-webhook-ovh/ops/values.yaml b/helm/cert-manager-webhook-ovh/ops/values.yaml new file mode 100644 index 0000000..29b13d4 --- /dev/null +++ b/helm/cert-manager-webhook-ovh/ops/values.yaml @@ -0,0 +1,32 @@ +# Configuration pour cert-manager-webhook-ovh +# GroupName pour le webhook (doit correspondre à celui du ClusterIssuer) +groupName: acme.gkdomaine.fr + +# Namespace où installer le webhook +namespace: cert-manager-ops + +# Image du webhook +# Note: Utilisez l'image officielle cert-manager-webhook-ovh si disponible +# Sinon, vous devrez peut-être construire l'image vous-même +image: + repository: quay.io/cert-manager-webhook-ovh/cert-manager-webhook-ovh + tag: "v1.0.0" + pullPolicy: IfNotPresent + +# Ressources +resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "128Mi" + cpu: "200m" + +# Réplicas +replicaCount: 1 + +# Node selector, tolerations, etc. +nodeSelector: {} +tolerations: [] +affinity: {} + diff --git a/helm/certificates/ops/templates/cluster-issuer-letsencrypt-dns01.yaml b/helm/certificates/ops/templates/cluster-issuer-letsencrypt-dns01.yaml index 0a6ea26..25306e5 100644 --- a/helm/certificates/ops/templates/cluster-issuer-letsencrypt-dns01.yaml +++ b/helm/certificates/ops/templates/cluster-issuer-letsencrypt-dns01.yaml @@ -9,18 +9,28 @@ spec: privateKeySecretRef: name: letsencrypt-dns01-prod-key solvers: - # Configuration DNS-01 pour OVH + # Configuration DNS-01 pour OVH via webhook + # IMPORTANT: Vous devez installer cert-manager-webhook-ovh avant d'utiliser cette configuration + # Installation: helm repo add cert-manager-webhook-ovh https://cert-manager.github.io/webhook-ovh + # helm install cert-manager-webhook-ovh cert-manager-webhook-ovh/cert-manager-webhook-ovh -n cert-manager-ops - selector: dnsZones: - "dev.gkdomaine.fr" dns01: - ovh: - endpoint: ovh-eu # ovh-eu pour l'Europe, ovh-us pour les USA, ovh-ca pour le Canada - applicationKey: "e598bb73ded17ee6" - applicationSecretRef: - name: ovh-credentials - key: application-secret - consumerKey: "372e273858204d972dbf7c50506d12a1" + webhook: + groupName: acme.gkdomaine.fr + solverName: ovh + config: + endpoint: ovh-eu + applicationKeyRef: + name: ovh-credentials + key: application-key + applicationSecretRef: + name: ovh-credentials + key: application-secret + consumerKeyRef: + name: ovh-credentials + key: consumer-key # Option 4 : Generic (webhook personnalisé) # - dns01: diff --git a/helm/certificates/ops/templates/secret-ovh-credentials.yaml b/helm/certificates/ops/templates/secret-ovh-credentials.yaml index 4b4d1a0..0826d0d 100644 --- a/helm/certificates/ops/templates/secret-ovh-credentials.yaml +++ b/helm/certificates/ops/templates/secret-ovh-credentials.yaml @@ -18,7 +18,11 @@ metadata: namespace: certificates-ops type: Opaque data: - # Remplacez cette valeur par votre Application Secret encodé en base64 - # Pour encoder : echo -n 'VOTRE_APPLICATION_SECRET' | base64 + # Encodez vos credentials en base64 : + # echo -n 'VOTRE_APPLICATION_KEY' | base64 + # echo -n 'VOTRE_APPLICATION_SECRET' | base64 + # echo -n 'VOTRE_CONSUMER_KEY' | base64 + application-key: ZTVhOGJiNzNkZWQxN2VlNg== # e598bb73ded17ee6 en base64 application-secret: NDYyMGM0ODI0OTlmOTcxZjRkMTgxNGY4MTU3ZjgyY2M= # VOTRE_APPLICATION_SECRET en base64 + consumer-key: MzcyZTI3Mzg1ODIwNGQ5NzJkYmY3YzUwNTA2ZDEyYTE= # 372e273858204d972dbf7c50506d12a1 en base64