From 0027501e0977c1b69d48fda6b253b8d5afc5d5fd Mon Sep 17 00:00:00 2001 From: Melvin GABALI Date: Wed, 21 Jan 2026 22:33:19 +0100 Subject: [PATCH] clear --- apps/applicationset-cert-manager.yaml | 56 ---- apps/applicationset-tls-sync.yaml | 44 --- apps/appproject-dev.yaml | 1 - docs/PKI-INTERNE.md | 285 ------------------ docs/TLS-SECRETS-SYNC.md | 62 ---- helm/tls-sync/ops/Chart.yaml | 7 - .../ops/templates/configmap-script.yaml | 176 ----------- helm/tls-sync/ops/templates/cronjob.yaml | 62 ---- helm/tls-sync/ops/templates/rbac.yaml | 33 -- .../templates/secret-kubeconfig-template.yaml | 24 -- helm/tls-sync/ops/values.yaml | 36 --- scripts/extract-ca-root-cert.sh | 119 -------- scripts/init-pki.sh | 182 ----------- 13 files changed, 1087 deletions(-) delete mode 100644 apps/applicationset-cert-manager.yaml delete mode 100644 apps/applicationset-tls-sync.yaml delete mode 100644 apps/appproject-dev.yaml delete mode 100644 docs/PKI-INTERNE.md delete mode 100644 docs/TLS-SECRETS-SYNC.md delete mode 100644 helm/tls-sync/ops/Chart.yaml delete mode 100644 helm/tls-sync/ops/templates/configmap-script.yaml delete mode 100644 helm/tls-sync/ops/templates/cronjob.yaml delete mode 100644 helm/tls-sync/ops/templates/rbac.yaml delete mode 100644 helm/tls-sync/ops/templates/secret-kubeconfig-template.yaml delete mode 100644 helm/tls-sync/ops/values.yaml delete mode 100644 scripts/extract-ca-root-cert.sh delete mode 100644 scripts/init-pki.sh diff --git a/apps/applicationset-cert-manager.yaml b/apps/applicationset-cert-manager.yaml deleted file mode 100644 index 155cace..0000000 --- a/apps/applicationset-cert-manager.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: ApplicationSet -metadata: - name: cert-manager-apps - namespace: argocd-ops -spec: - generators: - # Utilise un générateur merge pour combiner : - # 1. Les répertoires Helm existants (détermine quels environnements sont disponibles pour cert-manager) - # 2. Les fichiers de config partagés (pour obtenir name et server) - - merge: - generators: - # Premier générateur : scanne uniquement les répertoires Helm qui existent pour cert-manager - - git: - repoURL: https://git.gkdomaine.fr/kubernetes/argocd.git - revision: main - directories: - - path: "helm/cert-manager/*" - # Deuxième générateur : lit les fichiers de config partagés - # ApplicationSet utilisera seulement les fichiers config.json dont le basename - # correspond à un répertoire Helm trouvé - - git: - repoURL: https://git.gkdomaine.fr/kubernetes/argocd.git - revision: main - files: - - path: "configs/*/config.json" - mergeKeys: - - path.basename - template: - metadata: - # Utilise path.basename qui vient du générateur git (plus fiable que environment du JSON) - name: 'cert-manager-{{path.basename}}' - spec: - # Utilise path.basename pour le projet (ou {{environment}} si disponible dans le JSON) - project: '{{path.basename}}' - source: - repoURL: '{{repository}}' - targetRevision: '{{targetRevision}}' - # Construit explicitement le chemin Helm à partir du basename - path: '{{helmPath}}/cert-manager/{{path.basename}}' - helm: - valueFiles: - - values.yaml - destination: - # Les variables {{name}} et {{server}} viennent du fichier config.json - # (deuxième générateur du merge) - name: '{{name}}' - # server: '{{server}}' - namespace: 'cert-manager' - syncPolicy: - automated: - prune: true - selfHeal: true - syncOptions: - - CreateNamespace=true - diff --git a/apps/applicationset-tls-sync.yaml b/apps/applicationset-tls-sync.yaml deleted file mode 100644 index 561f784..0000000 --- a/apps/applicationset-tls-sync.yaml +++ /dev/null @@ -1,44 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: ApplicationSet -metadata: - name: tls-sync - namespace: argocd-ops -spec: - generators: - # Le CronJob de synchronisation TLS est déployé UNIQUEMENT sur le cluster OPS - - merge: - generators: - # Premier générateur : scanne les répertoires Helm pour tls-sync - - git: - repoURL: https://git.gkdomaine.fr/kubernetes/argocd.git - revision: main - directories: - - path: "helm/tls-sync/*" - # 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: 'tls-sync-{{path.basename}}' - spec: - project: default - source: - repoURL: '{{repository}}' - targetRevision: '{{targetRevision}}' - path: '{{helmPath}}/tls-sync/{{path.basename}}' - destination: - # Déploie uniquement sur le cluster OPS - name: '{{name}}' - namespace: certificates-{{path.basename}} - syncPolicy: - automated: - prune: true - selfHeal: true - syncOptions: - - CreateNamespace=true - diff --git a/apps/appproject-dev.yaml b/apps/appproject-dev.yaml deleted file mode 100644 index 8b13789..0000000 --- a/apps/appproject-dev.yaml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/PKI-INTERNE.md b/docs/PKI-INTERNE.md deleted file mode 100644 index 02a5d86..0000000 --- a/docs/PKI-INTERNE.md +++ /dev/null @@ -1,285 +0,0 @@ -# PKI Interne pour les Sites Internes - -## Vue d'ensemble - -Cette architecture implémente une **PKI (Public Key Infrastructure) privée** pour gérer les certificats TLS des sites internes (domaines `.local`), tout en conservant Let's Encrypt pour les sites publics (domaines `.fr`). - -## Architecture - -### Stratégie hybride - -- **Sites publics** (`.fr`) → **Let's Encrypt** (`letsencrypt-prod`) - - Nécessite un accès Internet - - Validation via HTTP-01 challenge - - Certificats reconnus par tous les navigateurs - -- **Sites internes** (`.local`) → **PKI Interne** (`ca-issuer`) - - Pas besoin d'accès Internet - - Contrôle total sur les certificats - - Certificats signés par votre propre CA root - -## Composants - -### 1. CA Root (`ca-root-issuer`) - -Génère la **Certificate Authority root** de votre PKI interne. - -```yaml -ClusterIssuer: ca-root-issuer -Certificate: ca-root-certificate -Secret: ca-root-secret -``` - -**Durée de vie** : 10 ans (configurable) - -### 2. CA Issuer (`ca-issuer`) - -Utilise la CA root pour signer les certificats des applications internes. - -```yaml -ClusterIssuer: ca-issuer -``` - -### 3. Distribution du certificat CA root - -Le certificat CA root doit être distribué aux clients (navigateurs, applications) pour qu'ils fassent confiance aux certificats signés. - -**ConfigMap** : `ca-root-certificate` dans le namespace `certificates-ops` - -## Avantages de la PKI Interne - -✅ **Pas d'accès Internet requis** - Les clusters DEV/RCT/PRD peuvent générer des certificats sans Internet -✅ **Contrôle total** - Vous gérez la durée de vie, les politiques, etc. -✅ **Pas de limites de taux** - Pas de restrictions comme Let's Encrypt (50 certificats/semaine) -✅ **Domaines internes** - Support natif pour `.local`, `.internal`, etc. -✅ **Sécurité renforcée** - Certificats uniquement pour votre infrastructure interne -✅ **Renouvellement automatique** - cert-manager gère le renouvellement automatiquement - -## Utilisation - -### Pour un site interne (`.local`) - -Créez un Certificate qui utilise `ca-issuer` : - -```yaml -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: harbor-tls - namespace: certificates-ops - annotations: - # IMPORTANT: Ce certificat doit être créé après que ca-issuer soit prêt - # ca-issuer a sync-wave "1", donc ce certificat doit avoir sync-wave "2" ou plus - argocd.argoproj.io/sync-wave: "2" -spec: - secretName: harbor-tls - issuerRef: - name: ca-issuer - kind: ClusterIssuer - dnsNames: - - harbor.gkdomaine.local - - harbor.dev.gkdomaine.local -``` - -**⚠️ Important** : N'oubliez pas l'annotation `argocd.argoproj.io/sync-wave: "2"` pour que le certificat soit créé après l'initialisation de la PKI. - -### Pour un site public (`.fr`) - -Utilisez `letsencrypt-prod` comme avant : - -```yaml -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: homarr-dev-tls - namespace: certificates-ops -spec: - secretName: homarr-dev-tls - issuerRef: - name: letsencrypt-prod - kind: ClusterIssuer - dnsNames: - - homarr.dev.gkdomaine.fr -``` - -## Installation - -### Étape 1 : Déployer la CA root - -Les ressources sont déployées automatiquement via ArgoCD : - -```bash -# Vérifier que la CA root est créée -kubectl get certificate ca-root-certificate -n certificates-ops --context=cluster-ops - -# Vérifier le ClusterIssuer CA -kubectl get clusterissuer ca-issuer --context=cluster-ops -``` - -### Étape 2 : Extraire le certificat CA root - -```bash -# Extraire le certificat CA root -kubectl get secret ca-root-secret -n certificates-ops \ - --context=cluster-ops \ - -o jsonpath='{.data.tls\.crt}' | base64 -d > ca-root.crt - -# Vérifier le certificat -openssl x509 -in ca-root.crt -text -noout -``` - -### Étape 3 : Distribuer le certificat CA root - -#### Option A : Ajouter au ConfigMap (pour distribution dans Kubernetes) - -```bash -# Mettre à jour le ConfigMap avec le certificat CA -kubectl create configmap ca-root-certificate \ - --from-file=ca.crt=ca-root.crt \ - -n certificates-ops \ - --context=cluster-ops \ - --dry-run=client -o yaml | kubectl apply -f - -``` - -#### Option B : Installer sur les machines clientes - -**Windows** : -```powershell -# Importer dans le magasin de certificats Windows -Import-Certificate -FilePath ca-root.crt -CertStoreLocation Cert:\LocalMachine\Root -``` - -**Linux** : -```bash -# Copier dans le magasin de certificats système -sudo cp ca-root.crt /usr/local/share/ca-certificates/gkdomaine-ca-root.crt -sudo update-ca-certificates -``` - -**macOS** : -```bash -# Importer dans le trousseau système -sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ca-root.crt -``` - -#### Option C : Configurer dans les navigateurs - -- **Chrome/Edge** : Paramètres → Confidentialité et sécurité → Gérer les certificats → Autorités de certification → Importer -- **Firefox** : Paramètres → Confidentialité et sécurité → Certificats → Afficher les certificats → Autorités → Importer - -### Étape 4 : Synchroniser le ConfigMap vers les autres clusters - -Le ConfigMap `ca-root-certificate` peut être synchronisé vers les clusters DEV/RCT/PRD pour que les pods puissent faire confiance aux certificats : - -```bash -# Synchroniser vers cluster-dev -kubectl get configmap ca-root-certificate -n certificates-ops \ - --context=cluster-ops -o yaml | \ - kubectl apply --context=cluster-dev -f - -``` - -## Vérification - -### Vérifier la CA root - -```bash -# Vérifier le certificat CA root -kubectl get certificate ca-root-certificate -n certificates-ops --context=cluster-ops - -# Vérifier le secret CA root -kubectl get secret ca-root-secret -n certificates-ops --context=cluster-ops - -# Voir les détails du certificat -kubectl get secret ca-root-secret -n certificates-ops \ - --context=cluster-ops \ - -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout -``` - -### Vérifier un certificat signé par la CA - -```bash -# Vérifier un certificat d'application -kubectl get certificate harbor-tls -n certificates-ops --context=cluster-ops - -# Vérifier la chaîne de certificats -kubectl get secret harbor-tls -n certificates-ops \ - --context=cluster-ops \ - -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout - -# Vérifier que le certificat est signé par la CA root -kubectl get secret harbor-tls -n certificates-ops \ - --context=cluster-ops \ - -o jsonpath='{.data.tls\.crt}' | base64 -d | \ - openssl verify -CAfile <(kubectl get secret ca-root-secret -n certificates-ops \ - --context=cluster-ops -o jsonpath='{.data.tls\.crt}' | base64 -d) -``` - -## Migration des certificats existants - -Pour migrer un certificat de Let's Encrypt vers la PKI interne : - -1. **Modifier le Certificate** pour utiliser `ca-issuer` au lieu de `letsencrypt-prod` -2. **Supprimer l'ancien secret** pour forcer la régénération -3. **Vérifier** que le nouveau certificat est généré et signé par la CA root - -Exemple pour Harbor : - -```bash -# 1. Modifier le Certificate (dans Git) -# issuerRef.name: ca-issuer - -# 2. Supprimer l'ancien secret -kubectl delete secret harbor-tls -n certificates-ops --context=cluster-ops - -# 3. Vérifier la régénération -kubectl get certificate harbor-tls -n certificates-ops --context=cluster-ops -w -``` - -## Sécurité - -### Bonnes pratiques - -- 🔒 **Protéger la clé privée CA root** - Stockée dans `ca-root-secret`, ne jamais exposer -- 🔄 **Rotation périodique** - Planifier la rotation de la CA root avant expiration (tous les 10 ans) -- 📋 **Audit régulier** - Vérifier régulièrement les certificats émis -- 🚫 **Isolation** - Ne jamais utiliser la CA interne pour des sites publics -- 🔐 **Backup** - Sauvegarder régulièrement le secret `ca-root-secret` - -### Rotation de la CA root - -Quand la CA root approche de son expiration : - -1. Créer une nouvelle CA root (`ca-root-certificate-v2`) -2. Créer un nouveau ClusterIssuer (`ca-issuer-v2`) -3. Migrer progressivement les certificats vers la nouvelle CA -4. Mettre à jour les clients avec le nouveau certificat CA root - -## Troubleshooting - -### Le certificat n'est pas généré - -```bash -# Vérifier les logs de cert-manager -kubectl logs -n cert-manager-ops -l app.kubernetes.io/name=cert-manager --context=cluster-ops --tail=100 - -# Vérifier le Certificate -kubectl describe certificate -n certificates-ops --context=cluster-ops -``` - -### Le navigateur affiche "Certificat non fiable" - -- Vérifier que le certificat CA root est installé sur la machine cliente -- Vérifier que le certificat est bien signé par la CA root -- Vérifier la date de validité du certificat - -### Erreur "certificate signed by unknown authority" - -- Le certificat CA root n'est pas installé sur le client -- Vérifier que le ConfigMap `ca-root-certificate` est synchronisé vers le cluster cible - -## Références - -- [cert-manager CA Issuer Documentation](https://cert-manager.io/docs/configuration/ca/) -- [PKI Best Practices](https://www.ssl.com/article/pki-best-practices/) -- [Kubernetes Certificate Management](https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/) - diff --git a/docs/TLS-SECRETS-SYNC.md b/docs/TLS-SECRETS-SYNC.md deleted file mode 100644 index ae40a6e..0000000 --- a/docs/TLS-SECRETS-SYNC.md +++ /dev/null @@ -1,62 +0,0 @@ -# Synchronisation des Secrets TLS Multi-Cluster - -## Architecture - -Les certificats Let's Encrypt sont générés dans le cluster OPS (qui a cert-manager et accès Internet). Les secrets TLS doivent ensuite être synchronisés vers les clusters DEV, RCT et PRD où les applications sont déployées. - -## Solution actuelle - -La solution actuelle utilise des Jobs Kubernetes pour copier les secrets, mais nécessite une configuration manuelle des contextes kubectl. - -## Solution recommandée : Utiliser ArgoCD avec des Applications - -### Option 1 : Synchronisation manuelle via script - -Créez un script qui copie les secrets depuis OPS vers les autres clusters : - -```bash -#!/bin/bash -# sync-tls-secrets.sh - -SECRET_NAME="homarr-dev-tls" -SOURCE_CLUSTER="cluster-ops" -SOURCE_NS="certificates-ops" -TARGET_CLUSTER="cluster-dev" -TARGET_NS="homarr-dev" - -# Récupérer le secret depuis OPS -kubectl get secret $SECRET_NAME -n $SOURCE_NS --context=$SOURCE_CLUSTER -o yaml > /tmp/secret.yaml - -# Modifier les métadonnées -sed -i '/^ uid:/d' /tmp/secret.yaml -sed -i '/^ resourceVersion:/d' /tmp/secret.yaml -sed -i '/^ selfLink:/d' /tmp/secret.yaml -sed -i '/^ creationTimestamp:/d' /tmp/secret.yaml -sed -i "s/namespace: $SOURCE_NS/namespace: $TARGET_NS/" /tmp/secret.yaml - -# Appliquer sur le cluster cible -kubectl apply -f /tmp/secret.yaml --context=$TARGET_CLUSTER - -echo "Secret $SECRET_NAME synchronisé de $SOURCE_CLUSTER vers $TARGET_CLUSTER" -``` - -### Option 2 : Utiliser External Secrets Operator (Recommandé) - -External Secrets Operator peut synchroniser les secrets depuis un backend (comme Kubernetes secrets dans OPS) vers les autres clusters. - -### Option 3 : Utiliser un CronJob pour synchronisation automatique - -Créez un CronJob qui synchronise automatiquement les secrets toutes les heures ou à chaque changement. - -## Configuration actuelle - -- **Source** : Namespace `certificates-ops` sur cluster OPS -- **Destination** : Namespaces des applications sur clusters DEV/RCT/PRD -- **Mécanisme** : Jobs Kubernetes (nécessite configuration manuelle) - -## Prochaines étapes - -1. Configurer les contextes kubectl pour accéder aux différents clusters -2. Tester la synchronisation manuelle -3. Automatiser via CronJob ou External Secrets Operator - diff --git a/helm/tls-sync/ops/Chart.yaml b/helm/tls-sync/ops/Chart.yaml deleted file mode 100644 index 9640f44..0000000 --- a/helm/tls-sync/ops/Chart.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v2 -name: tls-sync -description: Chart pour synchroniser automatiquement les secrets TLS depuis OPS vers les autres clusters -type: application -version: 1.0.0 -appVersion: "1.0.0" - diff --git a/helm/tls-sync/ops/templates/configmap-script.yaml b/helm/tls-sync/ops/templates/configmap-script.yaml deleted file mode 100644 index b16a283..0000000 --- a/helm/tls-sync/ops/templates/configmap-script.yaml +++ /dev/null @@ -1,176 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: tls-sync-script - namespace: {{ .Release.Namespace }} -data: - sync-all-certificates.sh: | - #!/bin/bash - # Script pour synchroniser automatiquement tous les secrets TLS depuis les certificats dans OPS - # Ce script est exécuté dans un CronJob Kubernetes - - set -e - - SOURCE_NS="${SOURCE_NS:-{{ .Values.tlsSync.sourceNamespace }}}" - - echo "=== Synchronisation automatique des secrets TLS ===" - echo "Source: namespace $SOURCE_NS (cluster OPS)" - echo "Date: $(date)" - echo "" - - # Fonction pour déterminer le cluster et namespace cible à partir du nom du certificat - determine_target() { - local cert_name=$1 - - if [[ $cert_name =~ -dev-tls$ ]]; then - TARGET_CLUSTER="cluster-dev" - TARGET_NS="${cert_name%-tls}" - elif [[ $cert_name =~ -rct-tls$ ]]; then - TARGET_CLUSTER="cluster-rct" - TARGET_NS="${cert_name%-tls}" - elif [[ $cert_name =~ -prd-tls$ ]]; then - TARGET_CLUSTER="cluster-prd" - TARGET_NS="${cert_name%-tls}" - else - if [[ $cert_name == *"dev"* ]]; then - TARGET_CLUSTER="cluster-dev" - TARGET_NS="${cert_name%-tls}" - else - echo "⚠️ Impossible de déterminer le cluster cible pour $cert_name" - return 1 - fi - fi - - return 0 - } - - # Vérifier l'accès au cluster OPS (in-cluster) - echo "1. Vérification de l'accès au cluster OPS..." - if ! kubectl get nodes &>/dev/null; then - echo "❌ Erreur: Impossible d'accéder au cluster OPS" - exit 1 - fi - echo " ✅ Accès au cluster OPS confirmé" - - # Récupérer tous les certificats - echo "2. Récupération des certificats depuis $SOURCE_NS..." - CERTIFICATES=$(kubectl get certificates -n "$SOURCE_NS" -o json 2>&1) - KUBECTL_EXIT_CODE=$? - - if [ $KUBECTL_EXIT_CODE -ne 0 ]; then - echo "❌ Erreur lors de la récupération des certificats:" - echo "$CERTIFICATES" | head -5 - exit 1 - fi - - # Vérifier que jq est disponible - if ! command -v jq &> /dev/null; then - echo "❌ Erreur: jq n'est pas disponible dans le conteneur" - exit 1 - fi - - CERT_COUNT=$(echo "$CERTIFICATES" | jq -r '.items | length' 2>/dev/null) - if [ -z "$CERT_COUNT" ] || [ "$CERT_COUNT" == "null" ] || [ "$CERT_COUNT" == "0" ]; then - echo "⚠️ Aucun certificat trouvé dans $SOURCE_NS" - exit 0 - fi - - echo " Trouvé $CERT_COUNT certificat(s)" - echo "" - - # Traiter chaque certificat - SUCCESS_COUNT=0 - SKIP_COUNT=0 - ERROR_COUNT=0 - - for i in $(seq 0 $((CERT_COUNT - 1))); do - CERT_NAME=$(echo "$CERTIFICATES" | jq -r ".items[$i].metadata.name") - SECRET_NAME=$(echo "$CERTIFICATES" | jq -r ".items[$i].spec.secretName") - CERT_NAMESPACE=$(echo "$CERTIFICATES" | jq -r ".items[$i].metadata.namespace") - - if [ "$SECRET_NAME" == "null" ] || [ -z "$SECRET_NAME" ]; then - SECRET_NAME="$CERT_NAME" - fi - - echo "📋 Traitement du certificat: $CERT_NAME" - echo " Secret: $SECRET_NAME" - - # Déterminer le cluster et namespace cible - if ! determine_target "$CERT_NAME"; then - echo " ⚠️ Ignoré (impossible de déterminer la destination)" - SKIP_COUNT=$((SKIP_COUNT + 1)) - echo "" - continue - fi - - echo " Destination: $TARGET_CLUSTER (namespace: $TARGET_NS)" - - # Vérifier que le secret existe dans la source - if ! kubectl get secret "$SECRET_NAME" -n "$SOURCE_NS" &>/dev/null; then - echo " ⚠️ Le secret $SECRET_NAME n'existe pas encore (certificat peut-être en cours de génération)" - SKIP_COUNT=$((SKIP_COUNT + 1)) - echo "" - continue - fi - - # Synchroniser le secret - echo " Synchronisation en cours..." - - # Récupérer le secret - TEMP_FILE=$(mktemp) - if ! kubectl get secret "$SECRET_NAME" -n "$SOURCE_NS" -o yaml > "$TEMP_FILE" 2>/dev/null; then - echo " ❌ Erreur: Impossible de récupérer le secret" - rm -f "$TEMP_FILE" - ERROR_COUNT=$((ERROR_COUNT + 1)) - echo "" - continue - fi - - # Modifier les métadonnées - sed -i '/^ uid:/d' "$TEMP_FILE" 2>/dev/null || true - sed -i '/^ resourceVersion:/d' "$TEMP_FILE" 2>/dev/null || true - sed -i '/^ selfLink:/d' "$TEMP_FILE" 2>/dev/null || true - sed -i '/^ creationTimestamp:/d' "$TEMP_FILE" 2>/dev/null || true - sed -i "s/namespace: $SOURCE_NS/namespace: $TARGET_NS/" "$TEMP_FILE" 2>/dev/null || true - - # Créer le namespace s'il n'existe pas - kubectl create namespace "$TARGET_NS" --context="$TARGET_CLUSTER" --dry-run=client -o yaml | kubectl apply --context="$TARGET_CLUSTER" -f - >/dev/null 2>&1 || true - - # Appliquer le secret - if kubectl apply -f "$TEMP_FILE" --context="$TARGET_CLUSTER" >/dev/null 2>&1; then - if kubectl get secret "$SECRET_NAME" -n "$TARGET_NS" --context="$TARGET_CLUSTER" >/dev/null 2>&1; then - echo " ✅ Synchronisé avec succès" - SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) - else - echo " ❌ Erreur: Le secret n'a pas été créé" - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - else - echo " ❌ Erreur lors de l'application du secret" - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - - # Nettoyage - rm -f "$TEMP_FILE" 2>/dev/null || true - - echo "" - done - - # Résumé - echo "=== Résumé ===" - echo "✅ Synchronisés avec succès: $SUCCESS_COUNT" - echo "⚠️ Ignorés: $SKIP_COUNT" - echo "❌ Erreurs: $ERROR_COUNT" - echo "" - - if [ $ERROR_COUNT -eq 0 ] && [ $SUCCESS_COUNT -gt 0 ]; then - echo "🎉 Toutes les synchronisations réussies !" - exit 0 - elif [ $ERROR_COUNT -gt 0 ]; then - echo "⚠️ Certaines synchronisations ont échoué" - exit 1 - else - echo "ℹ️ Aucune synchronisation effectuée" - exit 0 - fi - diff --git a/helm/tls-sync/ops/templates/cronjob.yaml b/helm/tls-sync/ops/templates/cronjob.yaml deleted file mode 100644 index 070c6b9..0000000 --- a/helm/tls-sync/ops/templates/cronjob.yaml +++ /dev/null @@ -1,62 +0,0 @@ -apiVersion: batch/v1 -kind: CronJob -metadata: - name: tls-sync - namespace: {{ .Release.Namespace }} -spec: - schedule: {{ .Values.tlsSync.schedule | quote }} - concurrencyPolicy: {{ .Values.tlsSync.concurrencyPolicy }} - successfulJobsHistoryLimit: {{ .Values.tlsSync.successfulJobsHistoryLimit }} - failedJobsHistoryLimit: {{ .Values.tlsSync.failedJobsHistoryLimit }} - jobTemplate: - spec: - activeDeadlineSeconds: {{ .Values.tlsSync.jobTimeout }} - backoffLimit: 2 - template: - metadata: - labels: - app: tls-sync - spec: - serviceAccountName: tls-sync - restartPolicy: OnFailure - containers: - - name: sync - image: {{ .Values.tlsSync.image.repository }}:{{ .Values.tlsSync.image.tag }} - imagePullPolicy: {{ .Values.tlsSync.image.pullPolicy }} - command: - - /bin/bash - - -c - - | - # Installer jq si nécessaire (l'image bitnami/kubectl ne contient pas jq) - if ! command -v jq &> /dev/null; then - echo "Installation de jq..." - apk add --no-cache jq 2>/dev/null || \ - (apt-get update && apt-get install -y jq 2>/dev/null) || \ - (yum install -y jq 2>/dev/null) || \ - (echo "⚠️ Impossible d'installer jq" && exit 1) - fi - - # Exécuter le script de synchronisation - /scripts/sync-all-certificates.sh - env: - - name: SOURCE_NS - value: {{ .Values.tlsSync.sourceNamespace | quote }} - volumeMounts: - - name: sync-script - mountPath: /scripts - readOnly: true - - name: kubeconfig - mountPath: /root/.kube - readOnly: true - resources: - {{- toYaml .Values.tlsSync.resources | nindent 14 }} - volumes: - - name: sync-script - configMap: - name: tls-sync-script - defaultMode: 0755 - - name: kubeconfig - secret: - secretName: tls-sync-kubeconfig - optional: true - diff --git a/helm/tls-sync/ops/templates/rbac.yaml b/helm/tls-sync/ops/templates/rbac.yaml deleted file mode 100644 index 6a78c44..0000000 --- a/helm/tls-sync/ops/templates/rbac.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: tls-sync - namespace: {{ .Release.Namespace }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: tls-sync-role - namespace: {{ .Release.Namespace }} -rules: -- apiGroups: ["cert-manager.io"] - resources: ["certificates"] - verbs: ["get", "list"] -- apiGroups: [""] - resources: ["secrets"] - verbs: ["get", "list"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: tls-sync-rolebinding - namespace: {{ .Release.Namespace }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: tls-sync-role -subjects: -- kind: ServiceAccount - name: tls-sync - namespace: {{ .Release.Namespace }} - diff --git a/helm/tls-sync/ops/templates/secret-kubeconfig-template.yaml b/helm/tls-sync/ops/templates/secret-kubeconfig-template.yaml deleted file mode 100644 index 8e369c3..0000000 --- a/helm/tls-sync/ops/templates/secret-kubeconfig-template.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# Template pour créer le Secret contenant les kubeconfigs -# Ce fichier est un template - vous devez créer le Secret manuellement -# avec vos kubeconfigs pour chaque cluster -# -# Exemple de commande pour créer le Secret : -# -# kubectl create secret generic tls-sync-kubeconfig \ -# --from-file=config=/root/.kube/config \ -# -n certificates-ops \ -# --dry-run=client -o yaml | kubectl apply -f - -# -# OU si vous avez plusieurs fichiers kubeconfig : -# -# kubectl create secret generic tls-sync-kubeconfig \ -# --from-file=cluster-dev=/path/to/dev-kubeconfig \ -# --from-file=cluster-rct=/path/to/rct-kubeconfig \ -# --from-file=cluster-prd=/path/to/prd-kubeconfig \ -# -n certificates-ops \ -# --dry-run=client -o yaml | kubectl apply -f - -# -# Note: Le CronJob monte ce Secret dans /root/.kube -# Assurez-vous que le fichier principal s'appelle 'config' ou -# configurez votre script pour utiliser les fichiers appropriés - diff --git a/helm/tls-sync/ops/values.yaml b/helm/tls-sync/ops/values.yaml deleted file mode 100644 index dcbb531..0000000 --- a/helm/tls-sync/ops/values.yaml +++ /dev/null @@ -1,36 +0,0 @@ -# Configuration pour la synchronisation automatique des secrets TLS -tlsSync: - # Intervalle de synchronisation (format cron) - # Par défaut: toutes les heures - schedule: "0 * * * *" # Toutes les heures à minute 0 - - # Namespace source où se trouvent les certificats - sourceNamespace: "certificates-ops" - - # Image à utiliser (doit contenir kubectl et bash) - image: - repository: bitnami/kubectl - tag: "1.31" - pullPolicy: IfNotPresent - - # Ressources pour le Job - resources: - requests: - memory: "64Mi" - cpu: "50m" - limits: - memory: "128Mi" - cpu: "200m" - - # Nombre de jobs réussis à conserver - successfulJobsHistoryLimit: 3 - - # Nombre de jobs échoués à conserver - failedJobsHistoryLimit: 3 - - # Timeout pour le job (en secondes) - jobTimeout: 300 # 5 minutes - - # Concurrency policy: Allow, Forbid, Replace - concurrencyPolicy: Forbid - diff --git a/scripts/extract-ca-root-cert.sh b/scripts/extract-ca-root-cert.sh deleted file mode 100644 index 2e02d1d..0000000 --- a/scripts/extract-ca-root-cert.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/bash - -# Script pour extraire le certificat CA root et le mettre à jour dans le ConfigMap -# Usage: ./extract-ca-root-cert.sh [--context CLUSTER_CONTEXT] [--output FILE] - -set -e - -CONTEXT="${KUBECTL_CONTEXT:-cluster-ops}" -NAMESPACE="certificates-ops" -SECRET_NAME="ca-root-secret" -CONFIGMAP_NAME="ca-root-certificate" -OUTPUT_FILE="" - -# Parse arguments -while [[ $# -gt 0 ]]; do - case $1 in - --context) - CONTEXT="$2" - shift 2 - ;; - --output) - OUTPUT_FILE="$2" - shift 2 - ;; - *) - echo "Usage: $0 [--context CLUSTER_CONTEXT] [--output FILE]" - echo " --context: Contexte kubectl (défaut: cluster-ops)" - echo " --output: Fichier de sortie pour le certificat (optionnel)" - exit 1 - ;; - esac -done - -echo "=== Extraction du certificat CA root ===" -echo "Cluster: $CONTEXT" -echo "Namespace: $NAMESPACE" -echo "" - -# Vérifier que kubectl est disponible -if ! command -v kubectl &> /dev/null; then - echo "❌ kubectl n'est pas installé" - exit 1 -fi - -# Vérifier l'accès au cluster -if ! kubectl --context="$CONTEXT" cluster-info &> /dev/null; then - echo "❌ Impossible d'accéder au cluster $CONTEXT" - exit 1 -fi - -# Vérifier que le secret existe -if ! kubectl --context="$CONTEXT" get secret "$SECRET_NAME" -n "$NAMESPACE" &> /dev/null; then - echo "❌ Le secret $SECRET_NAME n'existe pas dans le namespace $NAMESPACE" - echo " Assurez-vous que la CA root a été générée :" - echo " kubectl get certificate ca-root-certificate -n $NAMESPACE --context=$CONTEXT" - exit 1 -fi - -# Extraire le certificat -echo "📋 Extraction du certificat depuis le secret..." -CA_CERT=$(kubectl --context="$CONTEXT" get secret "$SECRET_NAME" -n "$NAMESPACE" \ - -o jsonpath='{.data.tls\.crt}' | base64 -d) - -if [ -z "$CA_CERT" ]; then - echo "❌ Impossible d'extraire le certificat du secret" - exit 1 -fi - -# Sauvegarder dans un fichier si demandé -if [ -n "$OUTPUT_FILE" ]; then - echo "$CA_CERT" > "$OUTPUT_FILE" - echo "✅ Certificat sauvegardé dans: $OUTPUT_FILE" -else - TEMP_FILE=$(mktemp) - echo "$CA_CERT" > "$TEMP_FILE" - OUTPUT_FILE="$TEMP_FILE" - echo "✅ Certificat extrait dans un fichier temporaire" -fi - -# Afficher les informations du certificat -echo "" -echo "📜 Informations du certificat CA root:" -echo "$CA_CERT" | openssl x509 -text -noout | grep -E "Subject:|Issuer:|Not Before|Not After|X509v3 Subject Alternative Name" || true - -# Mettre à jour le ConfigMap -echo "" -echo "🔄 Mise à jour du ConfigMap $CONFIGMAP_NAME..." - -# Créer ou mettre à jour le ConfigMap -kubectl --context="$CONTEXT" create configmap "$CONFIGMAP_NAME" \ - --from-file=ca.crt="$OUTPUT_FILE" \ - -n "$NAMESPACE" \ - --dry-run=client -o yaml | \ - kubectl --context="$CONTEXT" apply -f - - -if [ $? -eq 0 ]; then - echo "✅ ConfigMap mis à jour avec succès" -else - echo "❌ Erreur lors de la mise à jour du ConfigMap" - exit 1 -fi - -# Nettoyer le fichier temporaire si créé -if [ -n "$TEMP_FILE" ] && [ -f "$TEMP_FILE" ]; then - rm "$TEMP_FILE" -fi - -echo "" -echo "=== Résumé ===" -echo "✅ Certificat CA root extrait" -echo "✅ ConfigMap $CONFIGMAP_NAME mis à jour dans le namespace $NAMESPACE" -echo "" -echo "📋 Prochaines étapes:" -echo "1. Distribuer le certificat CA root aux clients (navigateurs, machines)" -echo "2. Voir docs/PKI-INTERNE.md pour les instructions détaillées" -echo "" -echo "Pour extraire le certificat dans un fichier:" -echo " $0 --output ca-root.crt" - diff --git a/scripts/init-pki.sh b/scripts/init-pki.sh deleted file mode 100644 index 24ad717..0000000 --- a/scripts/init-pki.sh +++ /dev/null @@ -1,182 +0,0 @@ -#!/bin/bash - -# Script d'initialisation de la PKI interne -# Ce script vérifie et crée le certificat CA root si nécessaire -# Usage: ./init-pki.sh [--context CLUSTER_CONTEXT] - -set -e - -CONTEXT="${KUBECTL_CONTEXT:-cluster-ops}" -NAMESPACE="certificates-ops" -CERT_NAME="ca-root-certificate" -SECRET_NAME="ca-root-secret" -ISSUER_NAME="ca-root-issuer" - -# Parse arguments -while [[ $# -gt 0 ]]; do - case $1 in - --context) - CONTEXT="$2" - shift 2 - ;; - *) - echo "Usage: $0 [--context CLUSTER_CONTEXT]" - echo " --context: Contexte kubectl (défaut: cluster-ops)" - exit 1 - ;; - esac -done - -echo "=== Initialisation de la PKI interne ===" -echo "Cluster: $CONTEXT" -echo "Namespace: $NAMESPACE" -echo "" - -# Vérifier que kubectl est disponible -if ! command -v kubectl &> /dev/null; then - echo "❌ kubectl n'est pas installé" - exit 1 -fi - -# Vérifier l'accès au cluster -if ! kubectl --context="$CONTEXT" cluster-info &> /dev/null; then - echo "❌ Impossible d'accéder au cluster $CONTEXT" - exit 1 -fi - -# Vérifier que cert-manager est installé -if ! kubectl --context="$CONTEXT" get crd certificates.cert-manager.io &> /dev/null; then - echo "❌ cert-manager n'est pas installé sur le cluster $CONTEXT" - exit 1 -fi - -# Vérifier que le namespace existe -if ! kubectl --context="$CONTEXT" get namespace "$NAMESPACE" &> /dev/null; then - echo "📦 Création du namespace $NAMESPACE..." - kubectl --context="$CONTEXT" create namespace "$NAMESPACE" -fi - -# Vérifier que le ClusterIssuer ca-root-issuer existe -if ! kubectl --context="$CONTEXT" get clusterissuer "$ISSUER_NAME" &> /dev/null; then - echo "❌ Le ClusterIssuer $ISSUER_NAME n'existe pas" - echo " Assurez-vous qu'il est déployé via ArgoCD" - exit 1 -fi - -# Vérifier si le secret existe déjà -if kubectl --context="$CONTEXT" get secret "$SECRET_NAME" -n "$NAMESPACE" &> /dev/null; then - echo "✅ Le secret $SECRET_NAME existe déjà" - echo " La PKI est déjà initialisée" - - # Vérifier l'état du certificat - if kubectl --context="$CONTEXT" get certificate "$CERT_NAME" -n "$NAMESPACE" &> /dev/null; then - CERT_STATUS=$(kubectl --context="$CONTEXT" get certificate "$CERT_NAME" -n "$NAMESPACE" \ - -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null || echo "Unknown") - - if [ "$CERT_STATUS" == "True" ]; then - echo "✅ Le certificat CA root est prêt" - echo "" - echo "📋 Informations du certificat:" - kubectl --context="$CONTEXT" get certificate "$CERT_NAME" -n "$NAMESPACE" -o wide - echo "" - echo "✅ La PKI est opérationnelle" - exit 0 - else - echo "⚠️ Le certificat existe mais n'est pas encore prêt (status: $CERT_STATUS)" - echo " Attente de la génération..." - fi - else - echo "⚠️ Le secret existe mais le Certificate n'existe pas" - echo " Cela peut indiquer un problème de configuration" - fi -else - echo "📋 Le secret $SECRET_NAME n'existe pas encore" - echo " Vérification du Certificate..." -fi - -# Vérifier si le Certificate existe -if ! kubectl --context="$CONTEXT" get certificate "$CERT_NAME" -n "$NAMESPACE" &> /dev/null; then - echo "❌ Le Certificate $CERT_NAME n'existe pas dans le namespace $NAMESPACE" - echo " Assurez-vous qu'il est déployé via ArgoCD" - echo "" - echo " Le Certificate doit être créé dans:" - echo " helm/certificates/ops/templates/certificate-ca-root.yaml" - exit 1 -fi - -# Attendre que le certificat soit généré -echo "⏳ Attente de la génération du certificat CA root..." -echo " (Cela peut prendre quelques secondes)" - -MAX_WAIT=120 # 2 minutes -ELAPSED=0 -INTERVAL=5 - -while [ $ELAPSED -lt $MAX_WAIT ]; do - if kubectl --context="$CONTEXT" get secret "$SECRET_NAME" -n "$NAMESPACE" &> /dev/null; then - CERT_STATUS=$(kubectl --context="$CONTEXT" get certificate "$CERT_NAME" -n "$NAMESPACE" \ - -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null || echo "False") - - if [ "$CERT_STATUS" == "True" ]; then - echo "" - echo "✅ Certificat CA root généré avec succès !" - break - fi - fi - - echo -n "." - sleep $INTERVAL - ELAPSED=$((ELAPSED + INTERVAL)) -done - -echo "" - -# Vérifier le résultat final -if ! kubectl --context="$CONTEXT" get secret "$SECRET_NAME" -n "$NAMESPACE" &> /dev/null; then - echo "" - echo "❌ Le secret n'a pas été généré après $MAX_WAIT secondes" - echo "" - echo "🔍 Diagnostic:" - echo "" - echo "1. Vérifier le Certificate:" - kubectl --context="$CONTEXT" get certificate "$CERT_NAME" -n "$NAMESPACE" -o yaml - echo "" - echo "2. Vérifier les événements:" - kubectl --context="$CONTEXT" get events -n "$NAMESPACE" --sort-by='.lastTimestamp' | tail -10 - echo "" - echo "3. Vérifier les logs de cert-manager:" - echo " kubectl --context=$CONTEXT logs -n cert-manager-ops -l app.kubernetes.io/name=cert-manager --tail=50" - exit 1 -fi - -# Vérifier que le ClusterIssuer ca-issuer fonctionne maintenant -echo "🔍 Vérification du ClusterIssuer ca-issuer..." -sleep 2 - -if kubectl --context="$CONTEXT" get clusterissuer ca-issuer &> /dev/null; then - ISSUER_STATUS=$(kubectl --context="$CONTEXT" get clusterissuer ca-issuer \ - -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null || echo "False") - - if [ "$ISSUER_STATUS" == "True" ]; then - echo "✅ Le ClusterIssuer ca-issuer est prêt" - else - echo "⚠️ Le ClusterIssuer ca-issuer n'est pas encore prêt (status: $ISSUER_STATUS)" - echo " Il devrait se mettre à jour automatiquement" - fi -fi - -echo "" -echo "=== Résumé ===" -echo "✅ Certificat CA root: $(kubectl --context="$CONTEXT" get certificate "$CERT_NAME" -n "$NAMESPACE" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null || echo "Unknown")" -echo "✅ Secret CA root: $(kubectl --context="$CONTEXT" get secret "$SECRET_NAME" -n "$NAMESPACE" &> /dev/null && echo "Existe" || echo "Manquant")" -echo "" -echo "📋 Prochaines étapes:" -echo "1. Extraire le certificat CA root:" -echo " ./scripts/extract-ca-root-cert.sh --context=$CONTEXT" -echo "" -echo "2. Distribuer le certificat aux clients (voir docs/PKI-INTERNE.md)" -echo "" -echo "3. Créer des certificats pour vos applications internes en utilisant 'ca-issuer'" -echo "" -echo "🎉 Initialisation terminée !" -