disable
This commit is contained in:
@@ -1,289 +0,0 @@
|
||||
# cert-manager-webhook-ovh
|
||||
|
||||
Ce chart déploie le webhook OVH pour cert-manager, permettant l'utilisation du challenge DNS-01 avec OVH pour obtenir des certificats wildcard Let's Encrypt.
|
||||
|
||||
## Configuration des credentials OVH
|
||||
|
||||
Les credentials OVH peuvent être gérés de deux façons :
|
||||
|
||||
### Option 1 : Secret Kubernetes classique (par défaut)
|
||||
|
||||
**Méthode A : Via values.yaml (recommandé si vous n'utilisez pas External Secrets)**
|
||||
|
||||
Configurez les credentials dans `values.yaml` :
|
||||
|
||||
```yaml
|
||||
externalSecret:
|
||||
enabled: false # External Secrets désactivé
|
||||
|
||||
ovhCredentials:
|
||||
applicationKey: "VOTRE_APPLICATION_KEY"
|
||||
applicationSecret: "VOTRE_APPLICATION_SECRET"
|
||||
consumerKey: "VOTRE_CONSUMER_KEY"
|
||||
```
|
||||
|
||||
Le chart créera automatiquement le secret `cert-manager-webhook-ovh` dans les deux namespaces (`cert-manager-webhook-ovh-ops` et `cert-manager-ops`).
|
||||
|
||||
**Méthode B : Création manuelle via kubectl**
|
||||
|
||||
Créez manuellement le Secret `cert-manager-webhook-ovh` dans les deux namespaces :
|
||||
|
||||
```bash
|
||||
# Dans cert-manager-webhook-ovh-ops
|
||||
kubectl create secret generic cert-manager-webhook-ovh \
|
||||
--from-literal=application-key="VOTRE_APPLICATION_KEY" \
|
||||
--from-literal=application-secret="VOTRE_APPLICATION_SECRET" \
|
||||
--from-literal=consumer-key="VOTRE_CONSUMER_KEY" \
|
||||
-n cert-manager-webhook-ovh-ops \
|
||||
--context=cluster-ops
|
||||
|
||||
# Dans cert-manager-ops
|
||||
kubectl create secret generic cert-manager-webhook-ovh \
|
||||
--from-literal=application-key="VOTRE_APPLICATION_KEY" \
|
||||
--from-literal=application-secret="VOTRE_APPLICATION_SECRET" \
|
||||
--from-literal=consumer-key="VOTRE_CONSUMER_KEY" \
|
||||
-n cert-manager-ops \
|
||||
--context=cluster-ops
|
||||
```
|
||||
|
||||
### Option 2 : External Secrets Operator - Stratégie Multi-Namespace (recommandé)
|
||||
|
||||
Utilisez External Secrets Operator pour synchroniser automatiquement les credentials depuis HashiCorp Vault dans **plusieurs namespaces** en utilisant un **ClusterSecretStore** partagé.
|
||||
|
||||
#### Avantages de la stratégie Multi-Namespace
|
||||
|
||||
- ✅ **Un seul ClusterSecretStore** : Configuration centralisée pour tous les namespaces
|
||||
- ✅ **Synchronisation automatique** : Les secrets sont créés automatiquement dans chaque namespace
|
||||
- ✅ **Rotation automatique** : Les secrets sont rafraîchis automatiquement selon `refreshInterval`
|
||||
- ✅ **Sécurité** : Les credentials ne sont jamais stockés en clair dans Git
|
||||
- ✅ **Partage facile** : Le même secret est disponible dans `cert-manager-ops` et `cert-manager-webhook-ovh-ops`
|
||||
|
||||
#### Prérequis
|
||||
|
||||
1. **External Secrets Operator installé** dans le cluster
|
||||
2. **HashiCorp Vault configuré** avec un rôle Kubernetes auth
|
||||
3. **ServiceAccount configuré** : Le ServiceAccount `cert-manager-webhook-ovh-sa` doit être autorisé dans Vault pour les namespaces `cert-manager-ops` et `cert-manager-webhook-ovh-ops`
|
||||
|
||||
#### Configuration dans Vault
|
||||
|
||||
Créez un rôle Vault pour l'authentification Kubernetes :
|
||||
|
||||
```bash
|
||||
# Configuration du rôle Vault
|
||||
vault write auth/kubernetes/role/cert-manager-webhook-ovh-role \
|
||||
bound_service_account_names=cert-manager-webhook-ovh-sa \
|
||||
bound_service_account_namespaces=cert-manager-webhook-ovh-ops,cert-manager-ops \
|
||||
policies=cert-manager-webhook-ovh-policy \
|
||||
ttl=1h
|
||||
|
||||
# IMPORTANT : Ne configurez PAS bound_service_account_namespace_selector
|
||||
# Utilisez bound_service_account_namespaces avec une liste de namespaces
|
||||
```
|
||||
|
||||
Créez une policy Vault pour accéder aux secrets OVH :
|
||||
|
||||
```bash
|
||||
vault policy write cert-manager-webhook-ovh-policy - <<EOF
|
||||
path "secret/data/cert-manager-webhook-ovh" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
Stockez les credentials OVH dans Vault :
|
||||
|
||||
```bash
|
||||
# Pour Vault KV v2, utilisez cette commande :
|
||||
vault kv put secret/cert-manager-webhook-ovh \
|
||||
application-key="VOTRE_APPLICATION_KEY" \
|
||||
application-secret="VOTRE_APPLICATION_SECRET" \
|
||||
consumer-key="VOTRE_CONSUMER_KEY"
|
||||
|
||||
# Vérifiez que le secret est bien stocké :
|
||||
vault kv get secret/cert-manager-webhook-ovh
|
||||
```
|
||||
|
||||
**Important** :
|
||||
- Pour Vault KV v2 avec External Secrets, utilisez le format avec `key` et `property` séparés :
|
||||
- `key`: Le chemin du secret dans Vault (ex: `cert-manager-webhook-ovh`)
|
||||
- `property`: La clé dans le JSON du secret (ex: `application-key`)
|
||||
- Le mount path `secret` est déjà défini dans le ClusterSecretStore, donc ne l'incluez pas dans `key`.
|
||||
|
||||
#### Configuration dans values.yaml
|
||||
|
||||
Activez External Secrets dans `values.yaml` :
|
||||
|
||||
```yaml
|
||||
externalSecret:
|
||||
enabled: true
|
||||
refreshInterval: "1h"
|
||||
secretName: "cert-manager-webhook-ovh"
|
||||
secretPath: "cert-manager-webhook-ovh" # Chemin du secret dans Vault
|
||||
remoteRef:
|
||||
applicationKey: "application-key" # Clé dans le JSON
|
||||
applicationSecret: "application-secret" # Clé dans le JSON
|
||||
consumerKey: "consumer-key" # Clé dans le JSON
|
||||
vault:
|
||||
secretStoreName: "vault-backend"
|
||||
server: "https://vault.example.com:8200"
|
||||
path: "secret"
|
||||
version: "v2"
|
||||
auth:
|
||||
kubernetes:
|
||||
mountPath: "kubernetes"
|
||||
role: "cert-manager-webhook-ovh-role" # Nom du rôle Vault
|
||||
serviceAccountRef:
|
||||
name: "cert-manager-webhook-ovh-sa"
|
||||
namespace: "cert-manager-webhook-ovh-ops"
|
||||
```
|
||||
|
||||
#### Fonctionnement
|
||||
|
||||
1. **ClusterSecretStore** : Un seul `ClusterSecretStore` est créé pour Vault (accessible depuis tous les namespaces)
|
||||
2. **ExternalSecrets multiples** : Deux `ExternalSecret` sont créés :
|
||||
- Un dans `cert-manager-webhook-ovh-ops` (namespace du chart)
|
||||
- Un dans `cert-manager-ops` (namespace de cert-manager)
|
||||
3. **Secrets synchronisés** : Chaque `ExternalSecret` crée le Secret `cert-manager-webhook-ovh` dans son namespace respectif
|
||||
4. **Synchronisation automatique** : Les secrets sont rafraîchis automatiquement selon `refreshInterval`
|
||||
|
||||
#### Vérification
|
||||
|
||||
```bash
|
||||
# Vérifier le ClusterSecretStore
|
||||
kubectl get clustersecretstore vault-backend --context=cluster-ops
|
||||
|
||||
# Vérifier les ExternalSecrets
|
||||
kubectl get externalsecret -n cert-manager-webhook-ovh-ops --context=cluster-ops
|
||||
kubectl get externalsecret -n cert-manager-ops --context=cluster-ops
|
||||
|
||||
# Vérifier les Secrets créés
|
||||
kubectl get secret cert-manager-webhook-ovh -n cert-manager-webhook-ovh-ops --context=cluster-ops
|
||||
kubectl get secret cert-manager-webhook-ovh -n cert-manager-ops --context=cluster-ops
|
||||
|
||||
# Vérifier le statut de synchronisation
|
||||
kubectl describe externalsecret cert-manager-webhook-ovh -n cert-manager-webhook-ovh-ops --context=cluster-ops
|
||||
kubectl describe externalsecret cert-manager-webhook-ovh -n cert-manager-ops --context=cluster-ops
|
||||
```
|
||||
|
||||
## Dépannage
|
||||
|
||||
### Erreur "could not get secret data from provider" ou "permission denied"
|
||||
|
||||
Cette erreur indique que External Secrets Operator ne peut pas lire les secrets depuis Vault. Vérifiez les points suivants :
|
||||
|
||||
#### 1. Vérifier que le secret existe dans Vault
|
||||
|
||||
```bash
|
||||
# Vérifier que le secret existe
|
||||
vault kv get secret/cert-manager-webhook-ovh
|
||||
|
||||
# Si le secret n'existe pas, créez-le :
|
||||
vault kv put secret/cert-manager-webhook-ovh \
|
||||
application-key="VOTRE_APPLICATION_KEY" \
|
||||
application-secret="VOTRE_APPLICATION_SECRET" \
|
||||
consumer-key="VOTRE_CONSUMER_KEY"
|
||||
```
|
||||
|
||||
#### 2. Vérifier la policy Vault
|
||||
|
||||
```bash
|
||||
# Vérifier que la policy existe
|
||||
vault policy read cert-manager-webhook-ovh-policy
|
||||
|
||||
# Si la policy n'existe pas, créez-la :
|
||||
vault policy write cert-manager-webhook-ovh-policy - <<EOF
|
||||
path "secret/data/cert-manager-webhook-ovh" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
#### 3. Vérifier le rôle Vault et les permissions
|
||||
|
||||
```bash
|
||||
# Vérifier la configuration du rôle
|
||||
vault read auth/kubernetes/role/cert-manager-webhook-ovh-role
|
||||
|
||||
# Vérifier que le rôle utilise la bonne policy
|
||||
# Le rôle doit avoir : policies = cert-manager-webhook-ovh-policy
|
||||
```
|
||||
|
||||
#### 4. Vérifier que le ServiceAccount peut s'authentifier
|
||||
|
||||
```bash
|
||||
# Vérifier que le ServiceAccount existe
|
||||
kubectl get serviceaccount cert-manager-webhook-ovh-sa -n cert-manager-webhook-ovh-ops
|
||||
|
||||
# Vérifier les permissions RBAC
|
||||
kubectl auth can-i use secret --namespace=cert-manager-webhook-ovh-ops \
|
||||
--as=system:serviceaccount:cert-manager-webhook-ovh-ops:cert-manager-webhook-ovh-sa
|
||||
```
|
||||
|
||||
#### 5. Vérifier la connexion à Vault
|
||||
|
||||
```bash
|
||||
# Vérifier que le ClusterSecretStore peut se connecter à Vault
|
||||
kubectl describe clustersecretstore vault-backend
|
||||
|
||||
# Vérifier les logs d'External Secrets Operator
|
||||
kubectl logs -n external-secrets-system \
|
||||
-l app.kubernetes.io/name=external-secrets \
|
||||
--tail=50 | grep -i "vault\|error\|failed"
|
||||
```
|
||||
|
||||
#### 6. Vérifier le format des chemins
|
||||
|
||||
Le format correct pour Vault KV v2 avec External Secrets utilise `key` et `property` séparés :
|
||||
|
||||
Vérifiez dans `values.yaml` :
|
||||
```yaml
|
||||
secretPath: "cert-manager-webhook-ovh" # ✅ Correct - chemin du secret
|
||||
remoteRef:
|
||||
applicationKey: "application-key" # ✅ Correct - clé dans le JSON
|
||||
# ❌ Incorrect: "cert-manager-webhook-ovh#application-key"
|
||||
# ❌ Incorrect: "secret/data/cert-manager-webhook-ovh#application-key"
|
||||
```
|
||||
|
||||
**Important** :
|
||||
- `secretPath` : Le chemin du secret dans Vault (sans le préfixe `secret/data/`)
|
||||
- `remoteRef.*` : Les clés dans le JSON du secret
|
||||
- Le mount path `secret` est géré par le ClusterSecretStore
|
||||
|
||||
#### 7. Forcer une nouvelle synchronisation
|
||||
|
||||
```bash
|
||||
# Forcer une synchronisation immédiate
|
||||
kubectl annotate externalsecret cert-manager-webhook-ovh \
|
||||
-n cert-manager-ops \
|
||||
force-sync=$(date +%s) \
|
||||
--overwrite
|
||||
```
|
||||
|
||||
### Erreur "invalid bound_service_account_namespace_selector configured"
|
||||
|
||||
Cette erreur se produit lors de la création d'un rôle Vault. **Ne configurez PAS** `bound_service_account_namespace_selector`. Utilisez plutôt `bound_service_account_namespaces` :
|
||||
|
||||
```bash
|
||||
# ✅ Configuration CORRECTE
|
||||
vault write auth/kubernetes/role/cert-manager-webhook-ovh-role \
|
||||
bound_service_account_names=cert-manager-webhook-ovh-sa \
|
||||
bound_service_account_namespaces=cert-manager-webhook-ovh-ops,cert-manager-ops \
|
||||
policies=cert-manager-webhook-ovh-policy \
|
||||
ttl=1h
|
||||
```
|
||||
|
||||
### Le secret n'est pas créé dans un namespace
|
||||
|
||||
Vérifiez que :
|
||||
1. Le `ClusterSecretStore` existe et est valide
|
||||
2. L'`ExternalSecret` existe dans le namespace concerné
|
||||
3. Le ServiceAccount a les permissions nécessaires dans Vault
|
||||
4. Les credentials sont correctement stockés dans Vault
|
||||
|
||||
```bash
|
||||
# Vérifier les logs d'External Secrets Operator
|
||||
kubectl logs -n external-secrets-system -l app.kubernetes.io/name=external-secrets --context=cluster-ops --tail=50
|
||||
|
||||
# Vérifier les événements de l'ExternalSecret
|
||||
kubectl describe externalsecret cert-manager-webhook-ovh -n cert-manager-ops --context=cluster-ops
|
||||
```
|
||||
@@ -1,160 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Script de vérification des ExternalSecrets pour cert-manager-webhook-ovh
|
||||
|
||||
set -e
|
||||
|
||||
# Détection automatique du contexte si non fourni
|
||||
if [ -z "$1" ]; then
|
||||
# Essayer de détecter le contexte actuel
|
||||
CURRENT_CONTEXT=$(kubectl config current-context 2>/dev/null || echo "")
|
||||
if [ -n "$CURRENT_CONTEXT" ]; then
|
||||
CONTEXT="$CURRENT_CONTEXT"
|
||||
echo "⚠️ Aucun contexte spécifié, utilisation du contexte actuel: $CONTEXT"
|
||||
else
|
||||
CONTEXT=""
|
||||
echo "⚠️ Aucun contexte kubectl trouvé. Les commandes seront exécutées sans --context"
|
||||
fi
|
||||
else
|
||||
CONTEXT="$1"
|
||||
fi
|
||||
|
||||
# Fonction pour exécuter kubectl avec ou sans contexte
|
||||
kubectl_cmd() {
|
||||
if [ -n "$CONTEXT" ]; then
|
||||
kubectl "$@" --context="$CONTEXT"
|
||||
else
|
||||
kubectl "$@"
|
||||
fi
|
||||
}
|
||||
SECRET_NAME="${2:-cert-manager-webhook-ovh}"
|
||||
NAMESPACE_WEBHOOK="${3:-cert-manager-webhook-ovh-ops}"
|
||||
NAMESPACE_CERTMANAGER="${4:-cert-manager-ops}"
|
||||
SECRET_STORE_NAME="${5:-vault-backend}"
|
||||
|
||||
echo "=== Vérification des ExternalSecrets pour cert-manager-webhook-ovh ==="
|
||||
echo "Contexte: $CONTEXT"
|
||||
echo ""
|
||||
|
||||
# 1. Vérifier le ClusterSecretStore
|
||||
echo "1. Vérification du ClusterSecretStore '$SECRET_STORE_NAME'..."
|
||||
if kubectl_cmd get clustersecretstore "$SECRET_STORE_NAME" &>/dev/null; then
|
||||
echo " ✅ ClusterSecretStore trouvé"
|
||||
kubectl_cmd get clustersecretstore "$SECRET_STORE_NAME" -o wide
|
||||
echo ""
|
||||
|
||||
# Afficher les détails
|
||||
echo " Détails du ClusterSecretStore:"
|
||||
kubectl_cmd describe clustersecretstore "$SECRET_STORE_NAME" | grep -A 20 "Spec:" || true
|
||||
echo ""
|
||||
else
|
||||
echo " ❌ ClusterSecretStore '$SECRET_STORE_NAME' non trouvé"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 2. Vérifier les ExternalSecrets
|
||||
echo "2. Vérification des ExternalSecrets..."
|
||||
|
||||
# Dans cert-manager-webhook-ovh-ops
|
||||
echo " a) Dans le namespace '$NAMESPACE_WEBHOOK':"
|
||||
if kubectl_cmd get externalsecret "$SECRET_NAME" -n "$NAMESPACE_WEBHOOK" &>/dev/null; then
|
||||
echo " ✅ ExternalSecret trouvé"
|
||||
kubectl_cmd get externalsecret "$SECRET_NAME" -n "$NAMESPACE_WEBHOOK" -o wide
|
||||
echo ""
|
||||
|
||||
# Afficher le statut
|
||||
echo " Statut:"
|
||||
kubectl_cmd get externalsecret "$SECRET_NAME" -n "$NAMESPACE_WEBHOOK" -o jsonpath='{.status}' | jq '.' 2>/dev/null || \
|
||||
kubectl_cmd describe externalsecret "$SECRET_NAME" -n "$NAMESPACE_WEBHOOK" | grep -A 10 "Status:" || true
|
||||
echo ""
|
||||
else
|
||||
echo " ❌ ExternalSecret '$SECRET_NAME' non trouvé dans '$NAMESPACE_WEBHOOK'"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Dans cert-manager-ops
|
||||
echo " b) Dans le namespace '$NAMESPACE_CERTMANAGER':"
|
||||
if kubectl_cmd get externalsecret "$SECRET_NAME" -n "$NAMESPACE_CERTMANAGER" &>/dev/null; then
|
||||
echo " ✅ ExternalSecret trouvé"
|
||||
kubectl_cmd get externalsecret "$SECRET_NAME" -n "$NAMESPACE_CERTMANAGER" -o wide
|
||||
echo ""
|
||||
|
||||
# Afficher le statut
|
||||
echo " Statut:"
|
||||
kubectl_cmd get externalsecret "$SECRET_NAME" -n "$NAMESPACE_CERTMANAGER" -o jsonpath='{.status}' | jq '.' 2>/dev/null || \
|
||||
kubectl_cmd describe externalsecret "$SECRET_NAME" -n "$NAMESPACE_CERTMANAGER" | grep -A 10 "Status:" || true
|
||||
echo ""
|
||||
else
|
||||
echo " ❌ ExternalSecret '$SECRET_NAME' non trouvé dans '$NAMESPACE_CERTMANAGER'"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 3. Vérifier les Secrets créés
|
||||
echo "3. Vérification des Secrets créés par External Secrets..."
|
||||
|
||||
# Dans cert-manager-webhook-ovh-ops
|
||||
echo " a) Secret dans '$NAMESPACE_WEBHOOK':"
|
||||
if kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE_WEBHOOK" &>/dev/null; then
|
||||
echo " ✅ Secret trouvé"
|
||||
kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE_WEBHOOK" -o wide
|
||||
echo ""
|
||||
|
||||
# Vérifier les clés présentes
|
||||
echo " Clés présentes dans le secret:"
|
||||
kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE_WEBHOOK" -o jsonpath='{.data}' | jq 'keys' 2>/dev/null || \
|
||||
kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE_WEBHOOK" -o jsonpath='{.data}' | grep -o '"[^"]*":' | sed 's/"//g' | sed 's/://g' || true
|
||||
echo ""
|
||||
else
|
||||
echo " ❌ Secret '$SECRET_NAME' non trouvé dans '$NAMESPACE_WEBHOOK'"
|
||||
echo " ⚠️ Le secret sera créé automatiquement par External Secrets une fois la synchronisation réussie"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Dans cert-manager-ops
|
||||
echo " b) Secret dans '$NAMESPACE_CERTMANAGER':"
|
||||
if kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE_CERTMANAGER" &>/dev/null; then
|
||||
echo " ✅ Secret trouvé"
|
||||
kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE_CERTMANAGER" -o wide
|
||||
echo ""
|
||||
|
||||
# Vérifier les clés présentes
|
||||
echo " Clés présentes dans le secret:"
|
||||
kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE_CERTMANAGER" -o jsonpath='{.data}' | jq 'keys' 2>/dev/null || \
|
||||
kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE_CERTMANAGER" -o jsonpath='{.data}' | grep -o '"[^"]*":' | sed 's/"//g' | sed 's/://g' || true
|
||||
echo ""
|
||||
else
|
||||
echo " ❌ Secret '$SECRET_NAME' non trouvé dans '$NAMESPACE_CERTMANAGER'"
|
||||
echo " ⚠️ Le secret sera créé automatiquement par External Secrets une fois la synchronisation réussie"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 4. Vérifier les événements et logs d'External Secrets Operator
|
||||
echo "4. Vérification des événements récents..."
|
||||
echo " Événements pour ExternalSecret dans '$NAMESPACE_CERTMANAGER':"
|
||||
kubectl_cmd get events -n "$NAMESPACE_CERTMANAGER" \
|
||||
--field-selector involvedObject.name="$SECRET_NAME" \
|
||||
--sort-by='.lastTimestamp' | tail -5 || echo " Aucun événement récent"
|
||||
echo ""
|
||||
|
||||
# 5. Résumé
|
||||
echo "=== Résumé ==="
|
||||
echo ""
|
||||
echo "Pour voir les détails complets d'un ExternalSecret:"
|
||||
if [ -n "$CONTEXT" ]; then
|
||||
echo " kubectl describe externalsecret $SECRET_NAME -n $NAMESPACE_CERTMANAGER --context=$CONTEXT"
|
||||
echo ""
|
||||
echo "Pour voir les logs d'External Secrets Operator:"
|
||||
echo " kubectl logs -n external-secrets-system -l app.kubernetes.io/name=external-secrets --context=$CONTEXT --tail=50"
|
||||
echo ""
|
||||
echo "Pour forcer une synchronisation immédiate:"
|
||||
echo " kubectl annotate externalsecret $SECRET_NAME -n $NAMESPACE_CERTMANAGER --context=$CONTEXT force-sync=\$(date +%s) --overwrite"
|
||||
else
|
||||
echo " kubectl describe externalsecret $SECRET_NAME -n $NAMESPACE_CERTMANAGER"
|
||||
echo ""
|
||||
echo "Pour voir les logs d'External Secrets Operator:"
|
||||
echo " kubectl logs -n external-secrets-system -l app.kubernetes.io/name=external-secrets --tail=50"
|
||||
echo ""
|
||||
echo "Pour forcer une synchronisation immédiate:"
|
||||
echo " kubectl annotate externalsecret $SECRET_NAME -n $NAMESPACE_CERTMANAGER force-sync=\$(date +%s) --overwrite"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Script de vérification rapide du TLS Sync Wildcard
|
||||
# Usage: ./verify-tls-sync.sh [--context cluster-ops]
|
||||
|
||||
set -e
|
||||
|
||||
CONTEXT="${1:-cluster-ops}"
|
||||
NAMESPACE="certificates-ops"
|
||||
|
||||
echo "=== Vérification du TLS Sync Wildcard ==="
|
||||
echo "Contexte: $CONTEXT"
|
||||
echo "Namespace: $NAMESPACE"
|
||||
echo ""
|
||||
|
||||
# Couleurs pour l'affichage
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Fonction pour afficher un résultat
|
||||
check_result() {
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# 1. Vérifier le CronJob
|
||||
echo "1. Vérification du CronJob..."
|
||||
if kubectl get cronjob -n "$NAMESPACE" tls-sync-wildcard --context="$CONTEXT" &>/dev/null; then
|
||||
echo -e "${GREEN}✅ CronJob existe${NC}"
|
||||
SCHEDULE=$(kubectl get cronjob -n "$NAMESPACE" tls-sync-wildcard --context="$CONTEXT" -o jsonpath='{.spec.schedule}' 2>/dev/null)
|
||||
echo " Schedule: $SCHEDULE"
|
||||
else
|
||||
echo -e "${RED}❌ CronJob manquant${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 2. Vérifier les Jobs
|
||||
echo "2. Vérification des Jobs..."
|
||||
JOBS=$(kubectl get jobs -n "$NAMESPACE" -l app=tls-sync-wildcard --context="$CONTEXT" --no-headers 2>/dev/null | wc -l)
|
||||
if [ "$JOBS" -gt 0 ]; then
|
||||
echo -e "${GREEN}✅ $JOBS Job(s) trouvé(s)${NC}"
|
||||
echo ""
|
||||
echo " Derniers Jobs:"
|
||||
kubectl get jobs -n "$NAMESPACE" -l app=tls-sync-wildcard --context="$CONTEXT" --sort-by=.metadata.creationTimestamp -o custom-columns=NAME:.metadata.name,STATUS:.status.conditions[0].type,AGE:.metadata.creationTimestamp | tail -5
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Aucun Job trouvé (le CronJob n'a peut-être pas encore été exécuté)${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 3. Vérifier les logs du dernier Job
|
||||
echo "3. Logs du dernier Job..."
|
||||
LAST_JOB=$(kubectl get jobs -n "$NAMESPACE" -l app=tls-sync-wildcard --context="$CONTEXT" --sort-by=.metadata.creationTimestamp -o jsonpath='{.items[-1].metadata.name}' 2>/dev/null)
|
||||
if [ -n "$LAST_JOB" ]; then
|
||||
echo " Job: $LAST_JOB"
|
||||
echo ""
|
||||
LOGS=$(kubectl logs -n "$NAMESPACE" job/"$LAST_JOB" --context="$CONTEXT" --tail=20 2>/dev/null)
|
||||
if [ -n "$LOGS" ]; then
|
||||
echo "$LOGS" | sed 's/^/ /'
|
||||
|
||||
# Vérifier les erreurs dans les logs
|
||||
if echo "$LOGS" | grep -qi "error\|❌\|failed"; then
|
||||
echo ""
|
||||
echo -e "${RED}⚠️ Des erreurs ont été détectées dans les logs${NC}"
|
||||
elif echo "$LOGS" | grep -qi "✅\|succès"; then
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ Synchronisation réussie${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Aucun log disponible${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Aucun Job trouvé pour voir les logs${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 4. Vérifier les secrets dans les clusters cibles
|
||||
echo "4. Vérification des secrets synchronisés..."
|
||||
|
||||
# Cluster DEV
|
||||
echo " Cluster DEV:"
|
||||
for ns in headlamp-dev homarr-dev longhorn-dev; do
|
||||
if kubectl get secret wildcard-dev-tls -n "$ns" --context=cluster-dev &>/dev/null; then
|
||||
AGE=$(kubectl get secret wildcard-dev-tls -n "$ns" --context=cluster-dev -o jsonpath='{.metadata.creationTimestamp}' 2>/dev/null)
|
||||
echo -e " ${GREEN}✅ $ns${NC} (créé: $AGE)"
|
||||
else
|
||||
echo -e " ${RED}❌ $ns: secret manquant${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Cluster RCT (si applicable)
|
||||
if kubectl get secret wildcard-rct-tls -n certificates-ops --context="$CONTEXT" &>/dev/null; then
|
||||
echo " Cluster RCT:"
|
||||
for ns in headlamp-rct homarr-rct longhorn-rct; do
|
||||
if kubectl get secret wildcard-rct-tls -n "$ns" --context=cluster-rct &>/dev/null; then
|
||||
AGE=$(kubectl get secret wildcard-rct-tls -n "$ns" --context=cluster-rct -o jsonpath='{.metadata.creationTimestamp}' 2>/dev/null)
|
||||
echo -e " ${GREEN}✅ $ns${NC} (créé: $AGE)"
|
||||
else
|
||||
echo -e " ${RED}❌ $ns: secret manquant${NC}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Cluster PRD (si applicable)
|
||||
if kubectl get secret wildcard-prd-tls -n certificates-ops --context="$CONTEXT" &>/dev/null; then
|
||||
echo " Cluster PRD:"
|
||||
for ns in headlamp-prd homarr-prd longhorn-prd; do
|
||||
if kubectl get secret wildcard-prd-tls -n "$ns" --context=cluster-prd &>/dev/null; then
|
||||
AGE=$(kubectl get secret wildcard-prd-tls -n "$ns" --context=cluster-prd -o jsonpath='{.metadata.creationTimestamp}' 2>/dev/null)
|
||||
echo -e " ${GREEN}✅ $ns${NC} (créé: $AGE)"
|
||||
else
|
||||
echo -e " ${RED}❌ $ns: secret manquant${NC}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 5. Vérifier les ressources nécessaires
|
||||
echo "5. Vérification des ressources..."
|
||||
|
||||
# ServiceAccount
|
||||
if kubectl get serviceaccount tls-sync-wildcard -n "$NAMESPACE" --context="$CONTEXT" &>/dev/null; then
|
||||
echo -e "${GREEN}✅ ServiceAccount existe${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ ServiceAccount manquant${NC}"
|
||||
fi
|
||||
|
||||
# ClusterRole
|
||||
if kubectl get clusterrole tls-sync-wildcard --context="$CONTEXT" &>/dev/null; then
|
||||
echo -e "${GREEN}✅ ClusterRole existe${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ ClusterRole manquant${NC}"
|
||||
fi
|
||||
|
||||
# ClusterRoleBinding
|
||||
if kubectl get clusterrolebinding tls-sync-wildcard --context="$CONTEXT" &>/dev/null; then
|
||||
echo -e "${GREEN}✅ ClusterRoleBinding existe${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ ClusterRoleBinding manquant${NC}"
|
||||
fi
|
||||
|
||||
# ConfigMap
|
||||
if kubectl get configmap tls-sync-wildcard-script -n "$NAMESPACE" --context="$CONTEXT" &>/dev/null; then
|
||||
echo -e "${GREEN}✅ ConfigMap existe${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ ConfigMap manquant${NC}"
|
||||
fi
|
||||
|
||||
# Secret kubeconfig
|
||||
if kubectl get secret tls-sync-kubeconfig -n "$NAMESPACE" --context="$CONTEXT" &>/dev/null; then
|
||||
echo -e "${GREEN}✅ Secret kubeconfig existe${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Secret kubeconfig manquant${NC}"
|
||||
echo " Créez-le avec: kubectl create secret generic tls-sync-kubeconfig --from-file=config=\$HOME/.kube/config -n $NAMESPACE"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# 6. Résumé
|
||||
echo "=== Résumé ==="
|
||||
echo ""
|
||||
echo "Pour déclencher une synchronisation manuelle:"
|
||||
echo " kubectl create job --from=cronjob/tls-sync-wildcard tls-sync-wildcard-manual-\$(date +%s) -n $NAMESPACE --context=$CONTEXT"
|
||||
echo ""
|
||||
echo "Pour voir les logs en temps réel:"
|
||||
echo " kubectl logs -n $NAMESPACE -l app=tls-sync-wildcard --context=$CONTEXT -f"
|
||||
echo ""
|
||||
echo "Pour plus de détails, consultez: helm/tls-sync-wildcard/ops/VÉRIFICATION.md"
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Script de vérification des permissions Vault pour External Secrets
|
||||
|
||||
set -e
|
||||
|
||||
VAULT_ROLE="${1:-cert-manager-webhook-ovh-role}"
|
||||
VAULT_POLICY="${2:-cert-manager-webhook-ovh-policy}"
|
||||
SERVICE_ACCOUNT="${3:-cert-manager-webhook-ovh-sa}"
|
||||
NAMESPACE="${4:-cert-manager-webhook-ovh-ops}"
|
||||
VAULT_SECRET_PATH="${5:-secret/cert-manager-webhook-ovh}"
|
||||
|
||||
echo "=== Vérification des permissions Vault ==="
|
||||
echo "Rôle Vault: $VAULT_ROLE"
|
||||
echo "Policy Vault: $VAULT_POLICY"
|
||||
echo "ServiceAccount: $SERVICE_ACCOUNT"
|
||||
echo "Namespace: $NAMESPACE"
|
||||
echo "Chemin secret: $VAULT_SECRET_PATH"
|
||||
echo ""
|
||||
|
||||
# 1. Vérifier que le secret existe dans Vault
|
||||
echo "1. Vérification du secret dans Vault..."
|
||||
if vault kv get "$VAULT_SECRET_PATH" &>/dev/null; then
|
||||
echo " ✅ Secret trouvé dans Vault"
|
||||
echo ""
|
||||
echo " Contenu du secret:"
|
||||
vault kv get "$VAULT_SECRET_PATH" | grep -E "application-key|application-secret|consumer-key" || true
|
||||
echo ""
|
||||
else
|
||||
echo " ❌ Secret '$VAULT_SECRET_PATH' non trouvé dans Vault"
|
||||
echo ""
|
||||
echo " Créez le secret avec:"
|
||||
echo " vault kv put $VAULT_SECRET_PATH \\"
|
||||
echo " application-key=\"VOTRE_APPLICATION_KEY\" \\"
|
||||
echo " application-secret=\"VOTRE_APPLICATION_SECRET\" \\"
|
||||
echo " consumer-key=\"VOTRE_CONSUMER_KEY\""
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 2. Vérifier la policy Vault
|
||||
echo "2. Vérification de la policy Vault '$VAULT_POLICY'..."
|
||||
if vault policy read "$VAULT_POLICY" &>/dev/null; then
|
||||
echo " ✅ Policy existe"
|
||||
echo ""
|
||||
echo " Contenu de la policy:"
|
||||
vault policy read "$VAULT_POLICY"
|
||||
echo ""
|
||||
|
||||
# Vérifier que la policy autorise la lecture du secret
|
||||
SECRET_NAME=$(basename "$VAULT_SECRET_PATH")
|
||||
if vault policy read "$VAULT_POLICY" | grep -q "secret/data/$SECRET_NAME"; then
|
||||
echo " ✅ Policy autorise l'accès à secret/data/$SECRET_NAME"
|
||||
else
|
||||
echo " ⚠️ Policy ne semble pas autoriser l'accès à secret/data/$SECRET_NAME"
|
||||
echo " Créez la policy avec:"
|
||||
echo " vault policy write $VAULT_POLICY - <<EOF"
|
||||
echo " path \"secret/data/$SECRET_NAME\" {"
|
||||
echo " capabilities = [\"read\"]"
|
||||
echo " }"
|
||||
echo " EOF"
|
||||
fi
|
||||
echo ""
|
||||
else
|
||||
echo " ❌ Policy '$VAULT_POLICY' n'existe pas"
|
||||
echo ""
|
||||
echo " Créez la policy avec:"
|
||||
echo " vault policy write $VAULT_POLICY - <<EOF"
|
||||
echo " path \"secret/data/ovh\" {"
|
||||
echo " capabilities = [\"read\"]"
|
||||
echo " }"
|
||||
echo " EOF"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 3. Vérifier le rôle Vault
|
||||
echo "3. Vérification du rôle Vault '$VAULT_ROLE'..."
|
||||
if vault read "auth/kubernetes/role/$VAULT_ROLE" &>/dev/null; then
|
||||
echo " ✅ Rôle existe"
|
||||
echo ""
|
||||
echo " Configuration du rôle:"
|
||||
vault read "auth/kubernetes/role/$VAULT_ROLE" | grep -E "bound_service_account|policies|ttl" || true
|
||||
echo ""
|
||||
|
||||
# Vérifier que le rôle utilise la bonne policy
|
||||
if vault read "auth/kubernetes/role/$VAULT_ROLE" | grep -q "$VAULT_POLICY"; then
|
||||
echo " ✅ Rôle utilise la policy '$VAULT_POLICY'"
|
||||
else
|
||||
echo " ⚠️ Rôle ne semble pas utiliser la policy '$VAULT_POLICY'"
|
||||
echo " Vérifiez avec: vault read auth/kubernetes/role/$VAULT_ROLE"
|
||||
fi
|
||||
|
||||
# Vérifier les ServiceAccounts autorisés
|
||||
BOUND_SA=$(vault read "auth/kubernetes/role/$VAULT_ROLE" -format=json 2>/dev/null | jq -r '.data.bound_service_account_names[]' 2>/dev/null || echo "")
|
||||
if echo "$BOUND_SA" | grep -q "$SERVICE_ACCOUNT"; then
|
||||
echo " ✅ ServiceAccount '$SERVICE_ACCOUNT' est autorisé"
|
||||
else
|
||||
echo " ⚠️ ServiceAccount '$SERVICE_ACCOUNT' n'est pas dans bound_service_account_names"
|
||||
echo " Rôle autorise: $BOUND_SA"
|
||||
fi
|
||||
|
||||
# Vérifier les namespaces autorisés
|
||||
BOUND_NS=$(vault read "auth/kubernetes/role/$VAULT_ROLE" -format=json 2>/dev/null | jq -r '.data.bound_service_account_namespaces[]' 2>/dev/null || echo "")
|
||||
if echo "$BOUND_NS" | grep -q "$NAMESPACE"; then
|
||||
echo " ✅ Namespace '$NAMESPACE' est autorisé"
|
||||
else
|
||||
echo " ⚠️ Namespace '$NAMESPACE' n'est pas dans bound_service_account_namespaces"
|
||||
echo " Rôle autorise: $BOUND_NS"
|
||||
fi
|
||||
echo ""
|
||||
else
|
||||
echo " ❌ Rôle '$VAULT_ROLE' n'existe pas"
|
||||
echo ""
|
||||
echo " Créez le rôle avec:"
|
||||
echo " vault write auth/kubernetes/role/$VAULT_ROLE \\"
|
||||
echo " bound_service_account_names=$SERVICE_ACCOUNT \\"
|
||||
echo " bound_service_account_namespaces=$NAMESPACE,cert-manager-ops \\"
|
||||
echo " policies=$VAULT_POLICY \\"
|
||||
echo " ttl=1h"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 4. Vérifier le ServiceAccount Kubernetes
|
||||
echo "4. Vérification du ServiceAccount Kubernetes..."
|
||||
if kubectl get serviceaccount "$SERVICE_ACCOUNT" -n "$NAMESPACE" &>/dev/null; then
|
||||
echo " ✅ ServiceAccount existe"
|
||||
kubectl get serviceaccount "$SERVICE_ACCOUNT" -n "$NAMESPACE" -o wide
|
||||
echo ""
|
||||
else
|
||||
echo " ❌ ServiceAccount '$SERVICE_ACCOUNT' n'existe pas dans '$NAMESPACE'"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 5. Résumé et actions recommandées
|
||||
echo "=== Résumé ==="
|
||||
echo ""
|
||||
echo "Si toutes les vérifications passent mais que l'erreur 403 persiste:"
|
||||
echo ""
|
||||
echo "1. Vérifiez que le mount Kubernetes dans Vault est correctement configuré:"
|
||||
echo " vault read auth/kubernetes/config"
|
||||
echo ""
|
||||
echo "2. Testez l'authentification manuellement:"
|
||||
echo " # Récupérer le token du ServiceAccount"
|
||||
echo " TOKEN=\$(kubectl get secret -n $NAMESPACE -o jsonpath='{.items[?(@.metadata.annotations.kubernetes\\.io/service-account\\.name==\"$SERVICE_ACCOUNT\")].data.token}' | head -1 | base64 -d)"
|
||||
echo " # Tester l'authentification"
|
||||
echo " vault write auth/kubernetes/login role=$VAULT_ROLE jwt=\"\$TOKEN\""
|
||||
echo ""
|
||||
echo "3. Vérifiez les logs d'External Secrets Operator:"
|
||||
echo " kubectl logs -n external-secrets-system -l app.kubernetes.io/name=external-secrets --tail=50 | grep -i vault"
|
||||
echo ""
|
||||
|
||||
Reference in New Issue
Block a user