# ArgoCD — GitOps cluster Funk

ArgoCD est l'opérateur GitOps du cluster. Il surveille le repo `Funk-lab` et
applique automatiquement tout ce qui se trouve dans `k8s/` vers le cluster Kubernetes.

---

## Accès

| Interface | URL | Login | Mot de passe |
|---|---|---|---|
| UI web | http://argocd.lab.local | `admin` | voir ci-dessous |
| CLI | `argocd` | — | — |

**Mot de passe initial :**
```bash
kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d && echo
```

> Supprimer ce secret après avoir changé le mot de passe :
> `kubectl -n argocd delete secret argocd-initial-admin-secret`

---

## Principe GitOps

```
Modifier un fichier dans k8s/  →  git commit + git push  →  ArgoCD détecte (~3 min)  →  kubectl apply automatique
```

**Tu ne fais plus jamais `helm install` ou `kubectl apply` manuellement pour les workloads.**
Tout passe par Git. Le repo est la source de vérité.

---

## Installation (bootstrap — fait une seule fois)

ArgoCD est bootstrappé manuellement via Helm, puis se gère ensuite lui-même via GitOps.

```bash
# Ajouter le repo Helm ArgoCD
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

# Installer ArgoCD
kubectl create namespace argocd
helm install argocd argo/argo-cd \
  --namespace argocd \
  --version 9.5.14 \
  -f k8s/argocd-bootstrap/values.yaml \
  --wait --timeout 5m

# Donner accès au repo Git (SSH)
kubectl create secret generic argocd-repo-funk-lab \
  --namespace argocd \
  --from-literal=type=git \
  --from-literal=url=git@github.com:Alkatrazz24/Funk-lab.git \
  --from-file=sshPrivateKey=~/.ssh/id_ed25519
kubectl label secret argocd-repo-funk-lab \
  -n argocd "argocd.argoproj.io/secret-type=repository"

# Appliquer l'App of Apps racine
kubectl apply -f k8s/apps-of-apps/root.yaml
```

---

## Structure GitOps

```
k8s/
├── argocd-bootstrap/        ← values.yaml Helm (bootstrap manuel uniquement)
├── apps-of-apps/
│   ├── root.yaml            ← Application racine (appliquée une seule fois)
│   └── apps/
│       └── monitoring.yaml  ← Application monitoring (créée par root)
└── infra/
    └── monitoring/          ← Manifests déployés par l'app monitoring
        ├── namespace.yaml
        ├── helmrelease.yaml  ← Application kube-prometheus-stack
        └── values.yaml
```

**Pattern App of Apps :**
- `root` surveille `k8s/apps-of-apps/apps/` → crée les Applications enfants
- Chaque Application enfant surveille son propre répertoire dans `k8s/infra/` ou `k8s/apps/`

---

## Déployer une nouvelle application

### 1. Créer les manifests

```bash
mkdir -p k8s/apps/<nom-app>
vim k8s/apps/<nom-app>/deployment.yaml
# ...
```

### 2. Créer l'Application ArgoCD

```bash
cat > k8s/apps-of-apps/apps/<nom-app>.yaml << 'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: <nom-app>
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: git@github.com:Alkatrazz24/Funk-lab.git
    targetRevision: main
    path: k8s/apps/<nom-app>
  destination:
    server: https://kubernetes.default.svc
    namespace: <namespace>
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
EOF
```

### 3. Pousser et attendre

```bash
git add k8s/
git commit -m "feat: <nom-app>"
git push
# ArgoCD déploie automatiquement en ~3 min
```

---

## Déployer un chart Helm via ArgoCD (multi-source)

Pattern pour un chart Helm avec values dans le repo :

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: mon-chart
  namespace: argocd
spec:
  project: default
  sources:
    - repoURL: https://charts.exemple.com
      chart: mon-chart
      targetRevision: 1.2.3
      helm:
        valueFiles:
          - $values/k8s/infra/mon-chart/values.yaml
    - repoURL: git@github.com:Alkatrazz24/Funk-lab.git
      targetRevision: main
      ref: values
  destination:
    server: https://kubernetes.default.svc
    namespace: mon-namespace
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true
```

> **Important :** utiliser `sources` (pluriel) — pas `source` + `sources` en même temps.
> Le champ est `valueFiles` (pas `valuesFiles`).

---

## Commandes utiles

```bash
# État de toutes les applications
kubectl get applications -n argocd

# Forcer un refresh (re-lire le repo Git)
kubectl -n argocd annotate application <nom> argocd.argoproj.io/refresh=hard --overwrite

# Logs ArgoCD
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-server --tail=50
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-application-controller --tail=50

# Redémarrer ArgoCD
kubectl rollout restart deployment -n argocd

# Mettre à jour ArgoCD
helm upgrade argocd argo/argo-cd \
  --namespace argocd \
  --version <nouvelle-version> \
  -f k8s/argocd-bootstrap/values.yaml
```

---

## Dépannage

### Application bloquée en OutOfSync

```bash
kubectl describe application <nom> -n argocd | grep -A5 "Message"
# Forcer un hard refresh
kubectl -n argocd annotate application <nom> argocd.argoproj.io/refresh=hard --overwrite
```

### Erreur "Repository not found"

La clé SSH n'est pas configurée ou le secret a été supprimé :
```bash
kubectl get secret -n argocd -l argocd.argoproj.io/secret-type=repository
# Recréer si absent (voir section Installation)
```

### Erreur "field not declared in schema" sur une Application

Symptôme : ArgoCD essaie de patcher une ressource Application avec un champ invalide.
Fix : supprimer la ressource ArgoCD et laisser root la recréer depuis le Git corrigé.
```bash
kubectl delete application <nom> -n argocd
kubectl -n argocd annotate application root argocd.argoproj.io/refresh=hard --overwrite
```

### StatefulSet bloqué par PVC après changement de storageSpec

Les StatefulSets n'autorisent pas la modification de `volumeClaimTemplates`.
```bash
# Patcher le CRD pour supprimer le storage
kubectl patch <crd> <nom> -n <ns> --type=merge -p '{"spec":{"storage":null}}'
# Supprimer StatefulSet + PVC
kubectl delete statefulset <nom> -n <ns>
kubectl delete pvc -n <ns> --all
```

---

## Configuration Helm (k8s/argocd-bootstrap/values.yaml)

- Ingress Traefik sur `argocd.lab.local`
- `server.insecure: true` — TLS terminé par Traefik
- `dex.enabled: false` — pas de SSO pour l'instant
- Resources limitées (128-256 Mi RAM par composant)
