# Cheatsheet Jenkins X - Guide Ultra-Détaillé pour Grands Débutants


[OK] CONCEPTS FONDAMENTAUX (EXPLICATIONS TRÈS DÉTAILLÉES)

# === QU'EST-CE QUE JENKINS X ? ===

# Imagine que tu développes une application Python/Node.js/Java
# Tu veux que chaque fois que tu modifies le code:
# 1. Tes tests s'exécutent automatiquement
# 2. L'application se build (compile/package)
# 3. L'application se déploie automatiquement sur le cloud
# 4. Les utilisateurs voient immédiatement les changements

# Solution classique (compliquée):
# 1. Installer Jenkins sur un serveur
# 2. Configurer Kubernetes manuellement
# 3. Écrire des scripts de déploiement complexes
# 4. Gérer les secrets, les certificats SSL, les domaines...
# 5. Maintenir tout ce système (mises à jour, sécurité...)
# = ÉNORMÉMENT DE TRAVAIL! Des semaines de configuration!

# JENKINS X = Plateforme CI/CD automatisée pour Kubernetes!
# Tu ne fais que:
# 1. Installer Jenkins X avec une commande
# 2. Créer ton projet ou importer ton code
# 3. git push
# 4. BOOM! Ton app est testée, buildée, et déployée automatiquement!

# Jenkins X s'appelle une solution "CI/CD native Kubernetes"
# = Continuous Integration / Continuous Deployment pour Kubernetes
# = Automatise tout le processus de développement -> production


# === VOCABULAIRE JENKINS X (TRÈS IMPORTANT!) ===

# CI/CD (Continuous Integration / Continuous Deployment)
# CI = Intégration Continue:
#   - À chaque commit git, le code est testé automatiquement
#   - Les bugs sont détectés immédiatement
#   - Exemple: Tu push du code -> tests s'exécutent -> tu reçois un rapport
# CD = Déploiement Continu:
#   - Si les tests passent, l'app est déployée automatiquement
#   - Pas besoin de déployer manuellement!
#   - Exemple: Tests OK -> build Docker -> déploie sur Kubernetes -> utilisateurs voient la nouvelle version

# KUBERNETES (K8s)
# = Plateforme pour orchestrer des conteneurs Docker
# = Gère automatiquement: scaling, résilience, load balancing
# Analogie: Si Docker est une boîte (conteneur), Kubernetes est l'entrepôt qui gère des milliers de boîtes
# Jenkins X utilise Kubernetes pour déployer tes apps
# Tu n'as PAS besoin de connaître Kubernetes en détail pour utiliser Jenkins X!

# PIPELINE
# = Séquence d'étapes automatiques pour CI/CD
# Exemple de pipeline typique:
#   1. Checkout code (récupérer le code depuis git)
#   2. Install dependencies (installer les packages)
#   3. Run tests (exécuter les tests)
#   4. Build Docker image (créer l'image Docker)
#   5. Push to registry (pousser l'image vers un registre)
#   6. Deploy to Staging (déployer en environnement de test)
#   7. Deploy to Production (déployer en production)
# Jenkins X crée ce pipeline AUTOMATIQUEMENT pour toi!

# ENVIRONMENT (Environnement)
# = Un espace isolé où ton app tourne
# Types d'environnements:
#   - Development: Pour développer et tester
#   - Staging: Environnement de pré-production (copie exacte de la prod)
#   - Production: Environnement réel où les utilisateurs accèdent
# Jenkins X gère ces environnements via GitOps

# GITOPS
# = Méthode où TOUT est géré via Git
# - Ton code d'application -> dans Git
# - Ta configuration Kubernetes -> dans Git
# - Tes secrets (chiffrés) -> dans Git
# Pour changer quelque chose: tu fais un commit et Jenkins X applique automatiquement
# Avantages:
#   - Historique complet des changements
#   - Rollback facile (revenir à une version précédente)
#   - Transparence: tout est visible dans Git

# PREVIEW ENVIRONMENT
# = Environnement temporaire créé automatiquement pour chaque Pull Request
# Exemple:
#   1. Tu crées une branche Git: feature/nouvelle-fonctionnalité
#   2. Tu push et crées une Pull Request sur GitHub
#   3. Jenkins X détecte la PR et crée un Preview Environment
#   4. Tu obtiens une URL unique: https://pr-42-myapp.jx.example.com
#   5. Tu peux tester la nouvelle fonctionnalité AVANT de merger
#   6. Quand tu merges la PR, le Preview Environment est supprimé automatiquement
# C'EST MAGIQUE! Parfait pour les revues de code

# HELM CHART
# = Package de configuration Kubernetes
# Analogie: Comme un requirements.txt pour Python, mais pour Kubernetes
# Un Helm Chart décrit:
#   - Quel conteneur Docker utiliser
#   - Combien de réplicas (instances) lancer
#   - Quels ports exposer
#   - Quelles variables d'environnement définir
# Jenkins X génère un Helm Chart AUTOMATIQUEMENT pour ton projet

# TEKTON
# = Moteur de pipeline moderne pour Kubernetes
# Jenkins X 3.x utilise Tekton (au lieu de Jenkins classique)
# Avantages:
#   - Pipelines définis en YAML (lisible, versionnable)
#   - Cloud-native (conçu pour Kubernetes)
#   - Scalable (parallélise les tâches)
# Tu n'as pas besoin de connaître Tekton en détail, Jenkins X l'utilise en coulisses

# NAMESPACE
# = Espace de noms Kubernetes isolé
# Analogie: Comme un dossier dans un ordinateur
# Jenkins X crée automatiquement des namespaces:
#   - jx: Pour les composants Jenkins X
#   - jx-staging: Pour l'environnement Staging
#   - jx-production: Pour l'environnement Production
#   - jx-preview-pr-42: Pour chaque Preview Environment


# === COMMENT ÇA MARCHE? (FLUX COMPLET) ===

# 1. Tu as un projet Python/Node/Java sur ton ordinateur
#    myapp/
#    ├── app.py (ton application)
#    ├── requirements.txt (dépendances)
#    └── tests/ (tests unitaires)

# 2. Tu initialises Jenkins X dans ce projet:
#    jx project import
#    Jenkins X détecte automatiquement le langage (Python)

# 3. Jenkins X génère AUTOMATIQUEMENT:
#    - Dockerfile (pour containeriser l'app)
#    - Jenkinsfile (pipeline CI/CD)
#    - Helm Chart (configuration Kubernetes)
#    - Fichiers GitOps (pour gérer les environnements)

# 4. Tu fais un commit et push:
#    git add .
#    git commit -m "Initial commit"
#    git push origin main

# 5. Jenkins X détecte le push et déclenche automatiquement:
#    a. Checkout du code depuis Git
#    b. Installation des dépendances (pip install -r requirements.txt)
#    c. Exécution des tests (pytest)
#    d. Build de l'image Docker
#    e. Push de l'image vers un registre (Docker Hub, GCR, ECR...)
#    f. Déploiement automatique en Staging
#    g. (Optionnel) Promotion manuelle vers Production

# 6. Ton app est LIVE en Staging!
#    URL: https://myapp-staging.jx.example.com

# 7. Tu vérifies que tout fonctionne en Staging
#    Si OK, tu promeus vers Production:
#    jx promote myapp --version 1.0.0 --env production

# 8. Ton app est maintenant en Production!
#    URL: https://myapp.jx.example.com
#    Les utilisateurs peuvent y accéder!


# === DIFFÉRENCES JENKINS CLASSIQUE vs JENKINS X ===

# JENKINS CLASSIQUE:
# - Installation manuelle complexe
# - Configuration UI (cliquodrôme)
# - Scripts Groovy compliqués
# - Pas natif Kubernetes
# - Déploiement manuel ou semi-automatique

# JENKINS X:
# - Installation automatique avec jx CLI
# - Configuration via GitOps (tout en YAML)
# - Pipelines générés automatiquement
# - 100% natif Kubernetes
# - Déploiement automatique avec Preview Environments

# Analogie:
# Jenkins classique = Voiture manuelle (tu contrôles tout)
# Jenkins X = Voiture autonome (elle conduit toute seule)


[OK] INSTALLATION SUPER DÉTAILLÉE

# === PRÉREQUIS (À INSTALLER D'ABORD) ===

# Jenkins X a besoin de ces outils installés sur ton ordinateur:

# 1. KUBECTL (CLI Kubernetes)
# = Outil pour interagir avec un cluster Kubernetes
# = Jenkins X l'utilise pour déployer

# 2. HELM (Package Manager Kubernetes)
# = Gestionnaire de packages pour Kubernetes
# = Jenkins X l'utilise pour installer des composants

# 3. GIT (Versioning)
# = Tu DOIS avoir Git installé et configuré

# 4. DOCKER (Optionnel mais recommandé)
# = Pour builder les images localement


# === INSTALLATION KUBECTL ===

# === macOS (avec Homebrew) ===
brew install kubectl

# Vérifier:
kubectl version --client
# Affiche: Client Version: v1.28.0

# === Linux (Ubuntu/Debian) ===
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

# Vérifier:
kubectl version --client

# === Windows (avec Chocolatey) ===
choco install kubernetes-cli

# Ou télécharger manuellement:
# https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/

# Vérifier:
kubectl version --client


# === INSTALLATION HELM ===

# === macOS ===
brew install helm

# === Linux ===
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# === Windows ===
choco install kubernetes-helm

# Vérifier:
helm version
# Affiche: version.BuildInfo{Version:"v3.12.0"}


# === INSTALLATION JENKINS X CLI ===

# La CLI Jenkins X (jx) est l'outil principal!

# === macOS ===
brew tap jenkins-x/jx
brew install jx

# === Linux ===
curl -L https://github.com/jenkins-x/jx/releases/download/v3.10.0/jx-linux-amd64.tar.gz | tar xzv
sudo mv jx /usr/local/bin

# === Windows (PowerShell en tant qu'admin) ===
# Télécharger depuis:
# https://github.com/jenkins-x/jx/releases

# Puis ajouter au PATH

# Vérifier l'installation:
jx version
# Affiche: 3.10.0


# === CHOISIR UN FOURNISSEUR CLOUD ===

# Jenkins X a besoin d'un cluster Kubernetes pour fonctionner
# Tu as plusieurs options:

# OPTION 1: Google Kubernetes Engine (GKE) - RECOMMANDÉ
# Pourquoi? Jenkins X est optimisé pour GCP
# Coût: ~$70-100/mois (petit cluster)
# Prérequis: Compte Google Cloud avec facturation activée

# OPTION 2: Amazon Elastic Kubernetes Service (EKS)
# Coût: ~$70-120/mois
# Prérequis: Compte AWS

# OPTION 3: Azure Kubernetes Service (AKS)
# Coût: ~$70-100/mois
# Prérequis: Compte Azure

# OPTION 4: Kubernetes local (minikube, k3s, kind)
# Coût: GRATUIT (tourne sur ton ordinateur)
# Limites: Pas adapté pour la production, ressources limitées
# Parfait pour: Apprendre et tester Jenkins X

# OPTION 5: Managed Jenkins X (CloudBees, etc)
# Coût: Variable (souvent cher)
# Avantage: Tout est géré pour toi


# === CRÉER UN COMPTE GOOGLE CLOUD (SI GKE) ===

# 1. Va sur: https://cloud.google.com/
# 2. Clique "Get started for free"
# 3. Connecte-toi avec ton compte Google
# 4. Remplis les informations de facturation
#    (Google offre $300 de crédit gratuit pour 90 jours!)
# 5. Accepte les conditions

# 6. Installer gcloud CLI:

# macOS:
brew install --cask google-cloud-sdk

# Linux:
curl https://sdk.cloud.google.com | bash
exec -l $SHELL

# Windows:
# Télécharger depuis: https://cloud.google.com/sdk/docs/install

# 7. Initialiser gcloud:
gcloud init

# Suis les instructions:
# - Sélectionne ton compte Google
# - Crée ou sélectionne un projet
# - Choisis une région (europe-west1 pour Europe)

# 8. Activer les APIs nécessaires:
gcloud services enable container.googleapis.com
gcloud services enable compute.googleapis.com

# 9. Configurer les credentials:
gcloud auth application-default login


# === INSTALLATION AVEC GKE (MÉTHODE RECOMMANDÉE) ===

# === ÉTAPE 1: Créer un cluster GKE ===

# Jenkins X peut créer le cluster automatiquement!

# Commande:
jx create cluster gke \
  --cluster-name=jx-cluster \
  --project-id=my-gcp-project \
  --region=europe-west1 \
  --machine-type=n1-standard-2 \
  --min-num-nodes=3 \
  --max-num-nodes=5 \
  --disk-size=50

# Explications:
# --cluster-name: Nom de ton cluster
# --project-id: ID de ton projet GCP (trouve-le dans la console GCP)
# --region: Région géographique (europe-west1 = Belgique)
# --machine-type: Type de machine (n1-standard-2 = 2 vCPUs, 7.5 GB RAM)
# --min-num-nodes: Nombre minimum de nœuds (machines)
# --max-num-nodes: Nombre maximum (auto-scaling)
# --disk-size: Taille du disque en GB

# Ce que fait cette commande:
# 1. Crée un cluster Kubernetes sur GKE
# 2. Installe Jenkins X sur le cluster
# 3. Configure GitOps
# 4. Crée les environnements Staging et Production
# 5. Installe les add-ons (Tekton, Lighthouse, etc)

# Durée: 10-15 minutes

# Affiche plein de logs:
# Creating GKE cluster...
# Waiting for cluster to be ready...
# Installing Jenkins X...
# Creating environments...
# Installation complete!

# À la fin, tu vois:
# Jenkins X installation completed successfully!
# Your cluster is ready at: https://jx.1.2.3.4.nip.io


# === ÉTAPE 2: Vérifier l'installation ===

# Vérifier que kubectl est configuré:
kubectl get nodes
# Affiche les nœuds du cluster

# Vérifier les namespaces Jenkins X:
kubectl get namespaces
# Affiche:
# jx
# jx-staging
# jx-production

# Vérifier les pods Jenkins X:
kubectl get pods -n jx
# Affiche les composants Jenkins X en cours d'exécution

# Vérifier la version Jenkins X:
jx version
# Affiche la version installée


# === INSTALLATION LOCALE AVEC MINIKUBE (GRATUIT) ===

# Si tu veux tester Jenkins X sans payer, utilise minikube!

# === ÉTAPE 1: Installer minikube ===

# macOS:
brew install minikube

# Linux:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Windows:
choco install minikube

# Vérifier:
minikube version


# === ÉTAPE 2: Démarrer minikube ===

# Lancer un cluster local:
minikube start --cpus=4 --memory=8192 --disk-size=50g

# Explications:
# --cpus=4: 4 cœurs CPU (Jenkins X a besoin de ressources!)
# --memory=8192: 8 GB RAM (minimum recommandé)
# --disk-size=50g: 50 GB de disque

# Durée: 3-5 minutes

# Affiche:
# [SMILING_FACE_WITH_OPEN_MOUTH_AND_SMILING_EYES]  minikube v1.31.0 on Darwin 13.0
# *  Using the docker driver
# [BIEN]  Starting control plane node minikube
# [BRAVO]  Done! kubectl is now configured to use "minikube"


# === ÉTAPE 3: Installer Jenkins X sur minikube ===

jx admin boot

# Ou avec GitOps:
jx boot --repository https://github.com/jenkins-x/jenkins-x-boot-config.git

# Suis les instructions interactives:
# - Choisis le type d'installation (local)
# - Choisis le repository Git (GitHub, GitLab, Bitbucket)
# - Connecte ton compte Git
# - Configure les domaines

# Durée: 10-20 minutes

# À la fin:
# Jenkins X installation completed!


# === ÉTAPE 4: Configurer l'accès ===

# Jenkins X utilise ingress pour l'accès externe
# Sur minikube, active l'ingress:
minikube addons enable ingress

# Obtenir l'IP de minikube:
minikube ip
# Affiche: 192.168.49.2 (exemple)

# Ajouter à /etc/hosts (Linux/macOS):
echo "192.168.49.2 jx.local" | sudo tee -a /etc/hosts

# Ou sur Windows (C:\Windows\System32\drivers\etc\hosts):
# 192.168.49.2 jx.local

# Accéder à Jenkins X:
# http://jx.local


[OK] CONFIGURATION INITIALE

# === SE CONNECTER À GITHUB/GITLAB/BITBUCKET ===

# Jenkins X a besoin d'accéder à ton repository Git

# === Créer un token GitHub ===

# 1. Va sur: https://github.com/settings/tokens
# 2. Clique "Generate new token (classic)"
# 3. Donne un nom: "Jenkins X Token"
# 4. Sélectionne les permissions:
#    - repo (tous)
#    - admin:repo_hook (tous)
#    - admin:org_hook
#    - user (email)
# 5. Clique "Generate token"
# 6. COPIE LE TOKEN (tu ne le verras qu'une fois!)

# === Configurer Jenkins X avec GitHub ===

jx create git server github --name github
jx create git token --server https://github.com --name jenkins-x --token YOUR_TOKEN_HERE

# Explications:
# create git server: Ajoute GitHub comme serveur Git
# create git token: Configure le token pour l'authentification

# Vérifier:
jx get git
# Affiche la configuration Git


# === CRÉER UN REPOSITORY POUR LES ENVIRONNEMENTS ===

# Jenkins X stocke la configuration des environnements dans Git (GitOps)

# Créer un repo sur GitHub:
# 1. Va sur: https://github.com/new
# 2. Nom: "jx-environments"
# 3. Visibilité: Private (recommandé)
# 4. Clique "Create repository"

# Dire à Jenkins X d'utiliser ce repo:
jx create env staging --git-url https://github.com/your-username/jx-environments.git

# Jenkins X va:
# 1. Cloner le repo
# 2. Créer la structure GitOps
# 3. Commiter et pusher


# === CONFIGURER LES DOMAINES ===

# Par défaut, Jenkins X utilise des domaines automatiques (nip.io)
# Exemple: myapp-staging.1.2.3.4.nip.io

# Pour utiliser ton propre domaine:

# 1. Acheter un domaine (GoDaddy, Namecheap, etc)
# 2. Pointer le domaine vers l'IP du cluster

# Obtenir l'IP du load balancer:
kubectl get svc -n jx

# Affiche:
# jx-ingress-controller   LoadBalancer   10.0.0.1   1.2.3.4   80:30080/TCP,443:30443/TCP

# L'IP externe: 1.2.3.4

# 3. Configurer le DNS:
# Ajouter un enregistrement A:
# *.jx.example.com -> 1.2.3.4

# 4. Configurer Jenkins X:
jx upgrade ingress --domain jx.example.com

# Maintenant tes apps auront des URLs:
# https://myapp-staging.jx.example.com
# https://myapp-production.jx.example.com


# === CONFIGURER LES SECRETS ===

# Jenkins X stocke les secrets dans Kubernetes Secrets

# Ajouter un secret:
kubectl create secret generic my-secret \
  --from-literal=api-key=my-secret-key \
  -n jx-staging

# Pour que ton app utilise ce secret:
# Dans ton code Python:
import os
api_key = os.environ.get("API_KEY")

# Dans ton Helm Chart (values.yaml):
# env:
#   API_KEY:
#     valueFrom:
#       secretKeyRef:
#         name: my-secret
#         key: api-key


[OK] CRÉER TON PREMIER PROJET

# === OPTION 1: CRÉER UN NOUVEAU PROJET ===

# Jenkins X peut générer un projet complet pour toi!

# Créer un projet Python Flask:
jx create quickstart \
  --language python \
  --framework flask \
  --name myflaskapp \
  --org your-github-username

# Explications:
# --language python: Langage du projet
# --framework flask: Framework (flask, django, fastapi)
# --name myflaskapp: Nom du projet
# --org your-github-username: Organisation GitHub

# Ce que fait cette commande:
# 1. Génère un projet Python Flask avec structure standard
# 2. Crée un repository GitHub: your-username/myflaskapp
# 3. Génère Dockerfile, Jenkinsfile, Helm Chart
# 4. Fait le premier commit
# 5. Push vers GitHub
# 6. Déclenche le premier build/deploy automatiquement!

# Durée: 2-3 minutes

# Affiche:
# Creating project myflaskapp
# Creating GitHub repository...
# Generating project files...
# Committing and pushing...
# Triggering pipeline...
# Done!

# Structure générée:
# myflaskapp/
# ├── app.py                 # Application Flask
# ├── requirements.txt       # Dépendances Python
# ├── Dockerfile             # Pour containeriser
# ├── Jenkinsfile            # Pipeline CI/CD
# ├── charts/                # Helm Charts
# │   └── myflaskapp/
# │       ├── Chart.yaml
# │       ├── values.yaml
# │       └── templates/
# └── tests/                 # Tests unitaires
#     └── test_app.py


# === OPTION 2: IMPORTER UN PROJET EXISTANT ===

# Tu as déjà un projet? Importe-le dans Jenkins X!

# === Exemple: Projet Flask existant ===

# Structure de ton projet actuel:
# myapp/
# ├── app.py
# ├── requirements.txt
# └── tests/
#     └── test_app.py

# === ÉTAPE 1: Initialiser Git (si pas déjà fait) ===

cd myapp
git init
git add .
git commit -m "Initial commit"

# === ÉTAPE 2: Créer un repo GitHub ===

# Via CLI GitHub:
gh repo create myapp --public --source=. --remote=origin --push

# Ou manuellement:
# 1. Va sur https://github.com/new
# 2. Crée le repo "myapp"
# 3. Push:
git remote add origin https://github.com/your-username/myapp.git
git push -u origin main


# === ÉTAPE 3: Importer dans Jenkins X ===

cd myapp
jx project import

# Jenkins X va:
# 1. Détecter automatiquement que c'est un projet Python
# 2. Te demander des confirmations (appuie sur Entrée pour accepter les valeurs par défaut)
# 3. Générer Dockerfile, Jenkinsfile, Helm Chart
# 4. Commiter et pusher
# 5. Configurer les webhooks GitHub
# 6. Déclencher le premier pipeline!

# Questions interactives:

# ? Do you want to create a Dockerfile?
# [Oui/Non] -> Oui (Jenkins X génère un Dockerfile optimal)

# ? Docker registry organization?
# [your-dockerhub-username] -> Entre ton username Docker Hub (ou laisse vide pour GCR)

# ? Do you want to create a Helm chart?
# [Oui/Non] -> Oui (Jenkins X génère le Helm Chart)

# ? Do you want to use GitOps?
# [Oui/Non] -> Oui (Recommandé!)

# Durée: 2-3 minutes

# Affiche:
# Detecting project type...
# Detected Python project
# Generating Dockerfile...
# Generating Jenkinsfile...
# Generating Helm Chart...
# Committing changes...
# Pushing to GitHub...
# Configuring webhooks...
# Triggering initial build...
# Done!


# === ÉTAPE 4: Vérifier le pipeline ===

# Voir l'activité du pipeline:
jx get activities
# ou
jx get activity -w

# Affiche:
# STEP                     STATUS
# Checkout Source          Succeeded
# Install Dependencies     Succeeded
# Run Tests                Succeeded
# Build Docker Image       Succeeded
# Push Docker Image        Succeeded
# Deploy to Staging        Succeeded

# Voir les logs en temps réel:
jx get build logs
# ou pour un build spécifique:
jx get build logs your-username/myapp/main


# === ÉTAPE 5: Accéder à ton app ===

# Obtenir l'URL de Staging:
jx get applications
# ou
jx get apps

# Affiche:
# APPLICATION  STAGING                                    PRODUCTION
# myapp        https://myapp-staging.jx.example.com       https://myapp-production.jx.example.com

# Ouvrir dans le navigateur:
jx ui
# Ouvre l'interface web Jenkins X

# Ou manuellement:
# https://myapp-staging.jx.example.com


[OK] STRUCTURE D'UN PROJET JENKINS X

# === FICHIERS GÉNÉRÉS PAR JENKINS X ===

# Quand tu importes ou crées un projet, Jenkins X génère:

# === FILE #1: Dockerfile ===

# Qu'est-ce que c'est?
# = Instructions pour créer une image Docker de ton app

# Exemple généré pour Python Flask:

FROM python:3.11-slim

WORKDIR /app

# Copier les dépendances
COPY requirements.txt .

# Installer les dépendances
RUN pip install --no-cache-dir -r requirements.txt

# Copier le code de l'app
COPY . .

# Exposer le port
EXPOSE 8080

# Commande de démarrage
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]

# Explications:
# FROM python:3.11-slim: Utilise l'image Python officielle
# WORKDIR /app: Tous les fichiers vont dans /app
# COPY requirements.txt: Copie les dépendances
# RUN pip install: Installe les packages Python
# COPY . .: Copie tout le code de l'app
# EXPOSE 8080: L'app écoute sur le port 8080
# CMD: Commande pour démarrer l'app (gunicorn pour production)


# === FILE #2: .lighthouse/jenkins-x/triggers.yaml ===

# Qu'est-ce que c'est?
# = Configuration des triggers (quand déclencher les pipelines)

# Contenu:

apiVersion: config.lighthouse.jenkins-x.io/v1alpha1
kind: TriggerConfig
spec:
  presubmits:
    - name: pr
      context: "pr"
      always_run: true
      optional: false
      source: "pullrequest.yaml"
  postsubmits:
    - name: release
      branches:
        - ^main$
        - ^master$
      source: "release.yaml"

# Explications:
# presubmits: Pipelines qui s'exécutent sur les Pull Requests
#   - always_run: true -> S'exécute à chaque commit dans la PR
#   - source: "pullrequest.yaml" -> Fichier du pipeline à exécuter
# postsubmits: Pipelines qui s'exécutent après merge
#   - branches: ^main$ -> Seulement sur la branche main
#   - source: "release.yaml" -> Pipeline de release


# === FILE #3: .lighthouse/jenkins-x/pullrequest.yaml ===

# Qu'est-ce que c'est?
# = Pipeline qui s'exécute sur chaque Pull Request

# Contenu:

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: pullrequest
spec:
  pipelineSpec:
    tasks:
      - name: checkout
        taskSpec:
          steps:
            - name: git-clone
              image: gcr.io/jenkinsxio/builder-jx:latest
              script: |
                #!/bin/sh
                git clone $(params.SOURCE_URL) /workspace/source
                cd /workspace/source
                git checkout $(params.PULL_PULL_SHA)

      - name: build
        taskSpec:
          steps:
            - name: install-deps
              image: python:3.11
              script: |
                #!/bin/sh
                cd /workspace/source
                pip install -r requirements.txt

            - name: run-tests
              image: python:3.11
              script: |
                #!/bin sh
                cd /workspace/source
                pytest tests/

            - name: build-docker
              image: gcr.io/kaniko-project/executor:latest
              script: |
                #!/bin/sh
                cd /workspace/source/kaniko/executor --context=. --destination=myapp:pr-$(params.PULL_NUMBER)

# Explications:
# checkout task: Clone le code de la PR
# build task:
#   - install-deps: Installe les dépendances Python
#   - run-tests: Exécute les tests avec pytest
#   - build-docker: Build l'image Docker avec Kaniko


# === FILE #4: .lighthouse/jenkins-x/release.yaml ===

# Qu'est-ce que c'est?
# = Pipeline qui s'exécute après merge (déploiement)

# Contenu:

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: release
spec:
  pipelineSpec:
    tasks:
      - name: checkout
        # ... (identique à pullrequest.yaml)

      - name: build-and-push
        taskSpec:
          steps:
            - name: semantic-release
              image: gcr.io/jenkinsxio/builder-jx:latest
              script: |
                #!/bin/sh
                jx step next-version --use-git-tag-only

            - name: build-docker
              image: gcr.io/kaniko-project/executor:latest
              script: |
                #!/bin/sh
                VERSION=$(cat VERSION)
                /kaniko/executor --context=. --destination=myapp:$VERSION

            - name: helm-package
              image: gcr.io/jenkinsxio/builder-jx:latest
              script: |
                #!/bin/sh
                VERSION=$(cat VERSION)
                cd charts/myapp
                helm package . --version $VERSION

      - name: deploy-staging
        taskSpec:
          steps:
            - name: jx-promote
              image: gcr.io/jenkinsxio/builder-jx:latest
              script: |
                #!/bin/sh
                VERSION=$(cat VERSION)
                jx promote myapp --version $VERSION --env staging --no-wait

# Explications:
# semantic-release: Génère automatiquement une version (1.0.0, 1.0.1, etc)
# build-docker: Build et push l'image Docker avec la version
# helm-package: Package le Helm Chart
# deploy-staging: Déploie automatiquement en Staging


# === FILE #5: charts/myapp/Chart.yaml ===

# Qu'est-ce que c'est?
# = Métadonnées du Helm Chart

# Contenu:

apiVersion: v2
name: myapp
description: My Flask Application
version: 1.0.0
appVersion: 1.0.0
icon: https://example.com/icon.png

# Explications:
# name: Nom du chart
# version: Version du chart (incrémenté à chaque changement)
# appVersion: Version de l'app


# === FILE #6: charts/myapp/values.yaml ===

# Qu'est-ce que c'est?
# = Configuration par défaut du déploiement Kubernetes

# Contenu:

replicaCount: 2

image:
  repository: myapp
  tag: latest
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 8080

ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
  hosts:
    - host: myapp.example.com
      paths:
        - path: /
          pathType: Prefix

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi

env:
  DEBUG: "False"
  LOG_LEVEL: "INFO"

# Explications:
# replicaCount: 2 -> 2 instances de l'app (haute disponibilité)
# image: Configuration de l'image Docker
# service: Expose l'app sur le port 8080
# ingress: Configuration de l'accès externe (URL)
# resources: Limites CPU/RAM pour chaque pod
# env: Variables d'environnement


# === FILE #7: charts/myapp/templates/deployment.yaml ===

# Qu'est-ce que c'est?
# = Template Kubernetes Deployment (gère les pods)

# Contenu (simplifié):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Chart.Name }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Chart.Name }}
  template:
    metadata:
      labels:
        app: {{ .Chart.Name }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: {{ .Values.service.port }}
          env:
            {{- range $key, $value := .Values.env }}
            - name: {{ $key }}
              value: {{ $value | quote }}
            {{- end }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

# Explications:
# {{ .Chart.Name }}: Nom du chart (myapp)
# {{ .Values.replicaCount }}: Nombre de réplicas (2)
# Les valeurs entre {{ }} sont remplacées par celles de values.yaml


[OK] WORKFLOW DE DÉVELOPPEMENT

# === FLUX COMPLET: DÉVELOPPEMENT -> PRODUCTION ===

# === JOUR 1: Développement local ===

# 1. Clone ton projet:
git clone https://github.com/your-username/myapp.git
cd myapp

# 2. Crée une branche pour ta nouvelle fonctionnalité:
git checkout -b feature/add-login

# 3. Développe localement:
# Édite app.py, ajoute tests, etc

# 4. Teste localement:
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python app.py

# Ouvre: http://localhost:5000
# Vérifie que tout fonctionne!

# 5. Lance les tests:
pytest tests/
# Tous les tests doivent passer!


# === JOUR 2: Créer une Pull Request ===

# 1. Commit tes changements:
git add .
git commit -m "Add login functionality"

# 2. Push la branche:
git push origin feature/add-login

# 3. Créer une Pull Request sur GitHub:
# Va sur: https://github.com/your-username/myapp
# Clique "Compare & pull request"
# Titre: "Add login functionality"
# Description: Décris ce que tu as fait
# Clique "Create pull request"

# 4. Jenkins X détecte AUTOMATIQUEMENT la PR!
#    Il va:
#    a. Checkout du code de la branche
#    b. Installer les dépendances
#    c. Exécuter les tests
#    d. Build l'image Docker
#    e. Créer un Preview Environment!
#    f. Commenter sur la PR avec l'URL du Preview

# 5. Tu reçois un commentaire de Jenkins X sur la PR:
#    "Preview environment is ready: https://pr-42-myapp.jx.example.com"

# 6. Teste le Preview Environment:
#    Ouvre l'URL et vérifie que la nouvelle fonctionnalité marche

# 7. Si des tests échouent:
#    Jenkins X commente: "Build failed! See logs: [lien]"
#    Corrige le code, commit, push
#    Jenkins X re-teste automatiquement!


# === JOUR 3: Merge et Déploiement ===

# 1. Quand tout est OK, merge la PR:
#    Clique "Merge pull request" sur GitHub

# 2. Jenkins X détecte le merge et déclenche AUTOMATIQUEMENT:
#    a. Build de l'image Docker avec un nouveau tag (1.0.1)
#    b. Push de l'image vers le registre
#    c. Déploiement automatique en STAGING!

# 3. Vérifie Staging:
jx get applications

# Affiche:
# APPLICATION  STAGING                                    PRODUCTION
# myapp        https://myapp-staging.jx.example.com       https://myapp.jx.example.com
#              (v1.0.1)                                   (v1.0.0)

# Ouvre: https://myapp-staging.jx.example.com
# La nouvelle version est LIVE en Staging!

# 4. Teste en Staging:
#    Fais des tests manuels, vérifie les logs, etc

# 5. Si tout est OK, PROMOUVOIR vers Production:
jx promote myapp --version 1.0.1 --env production

# Ou via l'interface web:
jx console

# Jenkins X va:
#    a. Mettre à jour le Git repository des environnements
#    b. Appliquer les changements Kubernetes
#    c. Déployer en Production!

# 6. Vérifie Production:
jx get applications

# Affiche:
# APPLICATION  STAGING                                    PRODUCTION
# myapp        https://myapp-staging.jx.example.com       https://myapp.jx.example.com
#              (v1.0.1)                                   (v1.0.1)

# Ouvre: https://myapp.jx.example.com
# La nouvelle version est LIVE en Production!


# === ROLLBACK (Si quelque chose va mal) ===

# Si la version 1.0.1 a un bug critique en Production:

# 1. Trouver la version précédente qui marchait:
jx get applications --env production

# Affiche l'historique:
# VERSION  DATE                 STATUS
# 1.0.1    2024-01-15 14:30     Deployed
# 1.0.0    2024-01-14 10:00     Superseded

# 2. Rollback vers 1.0.0:
jx promote myapp --version 1.0.0 --env production

# Jenkins X va:
#    Redéployer instantanément la version 1.0.0
#    Tes utilisateurs voient à nouveau la version stable!

# Durée: ~30 secondes


[OK] PREVIEW ENVIRONMENTS (SUPER PUISSANT!)

# === C'EST QUOI UN PREVIEW ENVIRONMENT? ===

# = Environnement temporaire créé AUTOMATIQUEMENT pour chaque PR
# = Permet de tester la PR AVANT de merger
# = URL unique: https://pr-42-myapp.jx.example.com

# Avantages:
# - Testable par les reviewers
# - QA peut tester sans bloquer les devs
# - Product managers peuvent voir les features
# - Zero configuration!


# === COMMENT ÇA MARCHE? ===

# 1. Tu crées une PR:
git checkout -b feature/new-button
# ... modifie le code ...
git push origin feature/new-button
# Crée la PR sur GitHub

# 2. Jenkins X détecte la PR et:
#    a. Exécute les tests
#    b. Build l'image Docker: myapp:pr-42
#    c. Crée un namespace Kubernetes: jx-preview-pr-42-myapp
#    d. Déploie l'app dans ce namespace
#    e. Crée une URL unique: https://pr-42-myapp.jx.example.com
#    f. Commente sur la PR avec l'URL

# 3. Tu peux:
#    - Tester l'URL toi-même
#    - Partager l'URL aux reviewers
#    - Faire des tests end-to-end

# 4. À chaque nouveau commit dans la PR:
#    Jenkins X MET À JOUR le Preview Environment automatiquement!

# 5. Quand la PR est merged ou fermée:
#    Jenkins X SUPPRIME le Preview Environment automatiquement
#    (économise les ressources!)


# === VOIR LES PREVIEW ENVIRONMENTS ===

# Lister tous les Preview Environments actifs:
jx get preview

# Affiche:
# PULL REQUEST                         NAMESPACE              APPLICATION
# PR-42 (feature/new-button)          jx-preview-pr-42       https://pr-42-myapp.jx.example.com
# PR-38 (feature/refactor)            jx-preview-pr-38       https://pr-38-myapp.jx.example.com

# Voir les logs d'un Preview:
jx get build logs --filter pr-42

# Supprimer manuellement un Preview (rare):
jx delete preview --pr 42


# === PERSONNALISER LES PREVIEW ENVIRONMENTS ===

# Par défaut, Jenkins X utilise la même config que Staging
# Tu peux la personnaliser!

# Édite: charts/preview/values.yaml

# Exemple: Activer le debug mode pour les Previews:

replicaCount: 1  # Un seul pod suffit pour un Preview

image:
  repository: myapp
  tag: pr-42
  pullPolicy: Always

env:
  DEBUG: "True"  # Debug activé!
  LOG_LEVEL: "DEBUG"

resources:
  limits:
    cpu: 200m      # Moins de ressources (c'est un Preview)
    memory: 256Mi

# Commit et push:
git add charts/preview/values.yaml
git commit -m "Customize preview environments"
git push


[OK] ENVIRONNEMENTS (STAGING & PRODUCTION)

# === COMPRENDRE LES ENVIRONNEMENTS ===

# Jenkins X crée automatiquement deux environnements:

# STAGING
# = Environnement de pré-production
# = Réplique exacte de la production
# = Déploiement AUTOMATIQUE après chaque merge
# = Pour tester avant de promouvoir en prod

# PRODUCTION
# = Environnement réel où les utilisateurs accèdent
# = Déploiement MANUEL (tu décides quand promouvoir)
# = Stable et sécurisé


# === STRUCTURE GITOPS DES ENVIRONNEMENTS ===

# Jenkins X stocke chaque environnement dans un repo Git

# Exemple:
# https://github.com/your-username/jx-staging
# https://github.com/your-username/jx-production

# Structure d'un repo d'environnement:

# jx-staging/
# ├── README.md
# ├── env/
# │   ├── requirements.yaml       # Liste des apps à déployer
# │   └── values.yaml             # Configuration de l'environnement
# └── Chart.yaml

# Le fichier requirements.yaml liste toutes les apps:

dependencies:
  - name: myapp
    repository: https://charts.example.com
    version: 1.0.1
  - name: another-app
    repository: https://charts.example.com
    version: 2.3.0

# Quand tu promeus une version, Jenkins X:
# 1. Met à jour requirements.yaml avec la nouvelle version
# 2. Commit et push vers le repo Git
# 3. Kubernetes détecte le changement et applique automatiquement!


# === VOIR LES ENVIRONNEMENTS ===

jx get environments

# Affiche:
# NAME        LABEL       KIND        PROMOTE  NAMESPACE     ORDER  CLUSTER  SOURCE
# dev         Development Development Never    jx            0               
# staging     Staging     Permanent   Auto     jx-staging    100             https://github.com/your-username/jx-staging
# production  Production  Permanent   Manual   jx-production 200             https://github.com/your-username/jx-production

# Explications:
# dev: Environnement local (ton ordinateur)
# staging: Auto-promote (déploiement automatique)
# production: Manual promote (tu décides quand déployer)


# === VOIR LES VERSIONS DÉPLOYÉES ===

jx get version

# Affiche:
# APPLICATION  STAGING  PRODUCTION
# myapp        1.0.5    1.0.3
# api-service  2.1.0    2.0.8

# Version différente = Staging est en avance!


# === PROMOUVOIR VERS PRODUCTION ===

# Méthode 1: CLI
jx promote myapp --version 1.0.5 --env production

# Méthode 2: Interface web
jx console
# Navigue vers "Applications" -> "myapp" -> "Promote"

# Méthode 3: Manuellement via Git (GitOps)
# 1. Clone le repo de production:
git clone https://github.com/your-username/jx-production
cd jx-production

# 2. Édite env/requirements.yaml:
# Change:
# - name: myapp
#   version: 1.0.3
# En:
# - name: myapp
#   version: 1.0.5

# 3. Commit et push:
git add env/requirements.yaml
git commit -m "Promote myapp to 1.0.5"
git push

# Jenkins X détecte le changement et déploie automatiquement!


# === CRÉER UN NOUVEL ENVIRONNEMENT (ex: QA) ===

# Par défaut: dev, staging, production
# Tu peux ajouter d'autres environnements!

jx create env \
  --name qa \
  --label QA \
  --namespace jx-qa \
  --promotion Manual \
  --order 150

# Explications:
# --name qa: Nom de l'environnement
# --namespace jx-qa: Namespace Kubernetes
# --promotion Manual: Promotion manuelle (comme Production)
# --order 150: Entre Staging (100) et Production (200)

# Jenkins X va:
# 1. Créer le namespace jx-qa
# 2. Créer un repo Git: jx-qa
# 3. Configurer les pipelines

# Maintenant tu as:
# dev -> staging -> QA -> production


# === SUPPRIMER UN ENVIRONNEMENT ===

jx delete env qa

# ATTENTION: Cela supprime l'environnement ET tous les déploiements!


[OK] PIPELINES & TEKTON

# === COMPRENDRE LES PIPELINES ===

# Pipeline = Séquence d'étapes automatisées
# Jenkins X 3.x utilise Tekton (plus moderne que Jenkins classique)

# Exemple de pipeline:
# 1. Checkout: Récupérer le code depuis Git
# 2. Install: Installer les dépendances
# 3. Test: Exécuter les tests
# 4. Build: Créer l'image Docker
# 5. Push: Pousser l'image vers le registre
# 6. Deploy: Déployer en Staging


# === VOIR LES PIPELINES ===

# Voir tous les pipelines récents:
jx get pipelines
# ou
jx get activities

# Affiche:
# STEP                          STATUS     AGE
# your-username/myapp/main #42
#   Checkout Source             Succeeded  2m
#   Install Dependencies        Succeeded  1m
#   Run Tests                   Succeeded  1m
#   Build Docker Image          Succeeded  30s
#   Push Image                  Succeeded  20s
#   Deploy to Staging           Succeeded  10s

# Voir un pipeline spécifique en temps réel:
jx get activity -w
# -w: watch mode (rafraîchit automatiquement)


# === VOIR LES LOGS D'UN PIPELINE ===

# Logs du dernier build:
jx get build logs

# Logs d'un build spécifique:
jx get build logs your-username/myapp/main

# Logs d'un step spécifique:
jx get build logs your-username/myapp/main --step "Run Tests"

# Suivre les logs en temps réel:
jx get build logs -f
# -f: follow (comme tail -f)


# === RELANCER UN PIPELINE ===

# Si un pipeline échoue, tu peux le relancer:

jx start pipeline your-username/myapp/main


# === PERSONNALISER UN PIPELINE ===

# Les pipelines sont définis dans:
# .lighthouse/jenkins-x/release.yaml (pour les releases)
# .lighthouse/jenkins-x/pullrequest.yaml (pour les PRs)

# Exemple: Ajouter une étape "Lint"

# Édite: .lighthouse/jenkins-x/pullrequest.yaml

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: pullrequest
spec:
  pipelineSpec:
    tasks:
      - name: checkout
        # ... (existant)

      - name: lint
        taskSpec:
          steps:
            - name: pylint
              image: python:3.11
              script: |
                #!/bin/sh
                cd /workspace/source
                pip install pylint
                pylint app.py

      - name: build
        # ... (existant)

# Commit et push:
git add .lighthouse/jenkins-x/pullrequest.yaml
git commit -m "Add linting step to pipeline"
git push

# Maintenant chaque PR exécutera pylint!


# === PIPELINE AVEC ÉTAPES PARALLÈLES ===

# Pour gagner du temps, tu peux paralléliser certaines étapes

# Exemple: Lancer les tests ET le linting en parallèle

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
spec:
  pipelineSpec:
    tasks:
      - name: checkout
        # ...

      - name: parallel-checks
        taskSpec:
          steps:
            - name: tests
              image: python:3.11
              script: |
                #!/bin/sh
                pytest tests/
            - name: lint
              image: python:3.11
              script: |
                #!/bin/sh
                pylint app.py
        runAfter:
          - checkout

      - name: build
        runAfter:
          - parallel-checks

# Les steps "tests" et "lint" s'exécutent EN MÊME TEMPS!
# Le build attend que les deux soient terminés


# === PIPELINE AVEC CONDITIONS ===

# Exemple: Déployer en Production SEULEMENT si c'est un tag

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
spec:
  pipelineSpec:
    tasks:
      - name: deploy-production
        when:
          - input: "$(params.BRANCH_NAME)"
            operator: in
            values:
              - "refs/tags/v*"
        taskSpec:
          steps:
            - name: promote
              script: |
                #!/bin/sh
                jx promote myapp --version $(params.VERSION) --env production

# Maintenant, Production est déployé SEULEMENT quand tu crées un tag:
git tag v1.0.5
git push origin v1.0.5


[OK] SECRETS & CONFIGURATION

# === GÉRER LES SECRETS ===

# Jenkins X stocke les secrets dans Kubernetes Secrets
# JAMAIS dans Git (sécurité!)

# === AJOUTER UN SECRET ===

# Méthode 1: kubectl
kubectl create secret generic my-api-secret \
  --from-literal=api-key=my-secret-key-12345 \
  --namespace jx-staging

# Méthode 2: Via Jenkins X
jx create secret \
  --name my-api-secret \
  --namespace jx-staging \
  --key api-key \
  --value my-secret-key-12345

# Vérifier:
kubectl get secrets -n jx-staging

# Affiche:
# NAME             TYPE     DATA   AGE
# my-api-secret    Opaque   1      10s


# === UTILISER UN SECRET DANS TON APP ===

# Étape 1: Injecter le secret comme variable d'environnement

# Édite: charts/myapp/values.yaml

env:
  API_KEY:
    valueFrom:
      secretKeyRef:
        name: my-api-secret
        key: api-key

# Étape 2: Lire la variable dans ton code Python

import os

api_key = os.environ.get("API_KEY")
print(f"API Key: {api_key}")

# Quand l'app tourne, elle reçoit automatiquement le secret!


# === SECRETS CHIFFRÉS DANS GIT (SEALED SECRETS) ===

# Problème: Tu veux versionner tes secrets dans Git (GitOps)
# Mais tu ne peux PAS mettre des secrets en clair!

# Solution: Sealed Secrets
# = Secrets chiffrés que SEUL ton cluster peut déchiffrer

# Installer Sealed Secrets:
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.18.0/controller.yaml

# Installer le CLI:
# macOS:
brew install kubeseal

# Linux:
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.18.0/kubeseal-linux-amd64 -O kubeseal
chmod +x kubeseal
sudo mv kubeseal /usr/local/bin/

# Créer un Sealed Secret:

# 1. Créer un secret normal (temporaire):
kubectl create secret generic my-secret \
  --from-literal=password=super-secret \
  --dry-run=client -o yaml > my-secret.yaml

# 2. Chiffrer avec kubeseal:
kubeseal < my-secret.yaml > my-sealed-secret.yaml

# 3. Supprimer le secret temporaire:
rm my-secret.yaml

# 4. Le fichier my-sealed-secret.yaml contient:
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: my-secret
spec:
  encryptedData:
    password: AgBX7Vn... (long hash chiffré)

# 5. Commit dans Git:
git add my-sealed-secret.yaml
git commit -m "Add sealed secret"
git push

# 6. Appliquer dans le cluster:
kubectl apply -f my-sealed-secret.yaml -n jx-staging

# Le contrôleur Sealed Secrets déchiffre automatiquement et crée le secret!


# === VARIABLES D'ENVIRONNEMENT PAR ENVIRONMENT ===

# Tu veux des valeurs différentes selon l'environnement?

# Staging: DEBUG=True
# Production: DEBUG=False

# Solution: Utiliser values.yaml par environnement

# Crée: charts/myapp/values-staging.yaml

replicaCount: 1
env:
  DEBUG: "True"
  LOG_LEVEL: "DEBUG"

# Crée: charts/myapp/values-production.yaml

replicaCount: 3
env:
  DEBUG: "False"
  LOG_LEVEL: "INFO"

# Jenkins X utilisera automatiquement le bon fichier!


[OK] MONITORING & LOGS

# === VOIR LES LOGS D'UNE APP ===

# Logs en temps réel:
jx logs -n jx-staging -f

# Logs d'un pod spécifique:
kubectl logs -n jx-staging myapp-7d8f5b9c-abc12 -f

# Logs de tous les pods d'une app:
jx logs -n jx-staging --app myapp -f


# === INSTALLER PROMETHEUS & GRAFANA ===

# Prometheus = Collecte des métriques
# Grafana = Visualisation (dashboards)

# Installer via jx:
jx upgrade addons prometheus --namespace jx

# Installer Grafana:
jx upgrade addons grafana --namespace jx

# Obtenir l'URL de Grafana:
jx get urls -n jx

# Affiche:
# grafana: https://grafana.jx.example.com

# Ouvrir Grafana:
# Username: admin
# Password: (obtenir avec):
kubectl get secret grafana -n jx -o jsonpath="{.data.admin-password}" | base64 --decode

# Dashboards pré-configurés:
# - Kubernetes Cluster Monitoring
# - Application Metrics
# - Pipeline Metrics


# === ALERTES ===

# Configurer des alertes Slack:

# 1. Créer un webhook Slack:
# https://api.slack.com/messaging/webhooks

# 2. Ajouter le webhook comme secret:
kubectl create secret generic slack-webhook \
  --from-literal=url=https://hooks.slack.com/services/XXX/YYY/ZZZ \
  -n jx

# 3. Configurer Prometheus Alertmanager:

# Édite la ConfigMap:
kubectl edit configmap alertmanager -n jx

# Ajoute:
receivers:
  - name: 'slack'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
        channel: '#devops'
        title: 'Jenkins X Alert'

# Maintenant tu reçois des alertes sur Slack!


[OK] SCALING & PERFORMANCE

# === SCALING HORIZONTAL (Plus de pods) ===

# Augmenter le nombre de réplicas:

# Méthode 1: Via Helm values

# Édite: charts/myapp/values.yaml

replicaCount: 5  # Au lieu de 2

# Commit et déploie:
git add charts/myapp/values.yaml
git commit -m "Scale to 5 replicas"
git push

# Méthode 2: Via kubectl
kubectl scale deployment myapp --replicas=5 -n jx-staging


# === AUTO-SCALING (HPA) ===

# HPA = Horizontal Pod Autoscaler
# = Scale automatiquement selon la charge CPU/RAM

# Activer HPA dans values.yaml:

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70
  targetMemoryUtilizationPercentage: 80

# Explications:
# minReplicas: Minimum 2 pods
# maxReplicas: Maximum 10 pods
# targetCPU: Scale si CPU > 70%
# targetMemory: Scale si RAM > 80%

# Commit et déploie:
git add charts/myapp/values.yaml
git commit -m "Enable auto-scaling"
git push

# Vérifier l'HPA:
kubectl get hpa -n jx-staging

# Affiche:
# NAME    REFERENCE          TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
# myapp   Deployment/myapp   30%/70%    2         10        2          5m


# === SCALING VERTICAL (Plus de ressources) ===

# Augmenter CPU/RAM par pod:

# Édite: charts/myapp/values.yaml

resources:
  limits:
    cpu: 1000m      # 1 CPU
    memory: 1024Mi  # 1 GB
  requests:
    cpu: 500m       # 0.5 CPU
    memory: 512Mi   # 512 MB

# Commit et déploie


# === OPTIMISER LES IMAGES DOCKER ===

# Image plus petite = Déploiement plus rapide!

# Dockerfile optimisé:

# Multi-stage build
FROM python:3.11-slim as builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

# Image finale
FROM python:3.11-slim

WORKDIR /app

# Copier seulement les packages installés
COPY --from=builder /root/.local /root/.local
ENV PATH=/root/.local/bin:$PATH

COPY . .

CMD ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]

# Taille réduite de 500MB à 150MB!


[OK] SÉCURITÉ 

# === SCANNER LES VULNÉRABILITÉS ===

# Jenkins X peut scanner automatiquement tes images Docker pour détecter les failles de sécurité

# === Installer Trivy (Scanner de vulnérabilités) ===

# Trivy = Outil open-source pour scanner les CVEs (Common Vulnerabilities and Exposures)
# Il détecte les packages vulnérables dans tes images Docker

# Installer Trivy dans le cluster:
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/trivy-operator/main/deploy/static/trivy-operator.yaml

# Ou via Helm:
helm repo add aqua https://aquasecurity.github.io/helm-charts/
helm install trivy-operator aqua/trivy-operator --namespace trivy-system --create-namespace


# === Intégrer Trivy dans le Pipeline ===

# Édite: .lighthouse/jenkins-x/release.yaml

# Ajoute une étape de scan avant le push de l'image:

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
spec:
  pipelineSpec:
    tasks:
      - name: build-image
        taskSpec:
          steps:
            - name: build-docker
              image: gcr.io/kaniko-project/executor:latest
              script: |
                #!/bin/sh
                /kaniko/executor --context=. --destination=myapp:$(params.VERSION) --no-push

      - name: security-scan
        taskSpec:
          steps:
            - name: trivy-scan
              image: aquasec/trivy:latest
              script: |
                #!/bin/sh
                trivy image myapp:$(params.VERSION) --severity HIGH,CRITICAL --exit-code 1
        runAfter:
          - build-image

      - name: push-image
        taskSpec:
          steps:
            - name: push
              image: gcr.io/kaniko-project/executor:latest
              script: |
                #!/bin/sh
                /kaniko/executor --context=. --destination=myapp:$(params.VERSION)
        runAfter:
          - security-scan

# Explications:
# --severity HIGH,CRITICAL: Scanner uniquement les vulnérabilités graves
# --exit-code 1: Échouer le pipeline si des vulnérabilités sont trouvées
# runAfter: L'image est poussée SEULEMENT si le scan réussit

# Commit et push:
git add .lighthouse/jenkins-x/release.yaml
git commit -m "Add security scanning with Trivy"
git push

# Maintenant, chaque build scanne automatiquement les vulnérabilités!
# Si Trivy détecte une faille critique, le pipeline échoue et l'image n'est PAS déployée


# === Voir les Résultats du Scan ===

# Vérifier les vulnérabilités détectées:
jx get build logs --step security-scan

# Affiche un rapport:
# Total: 5 (HIGH: 3, CRITICAL: 2)
# +--------------+------------------+----------+-------------------+
# | LIBRARY      | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |
# +--------------+------------------+----------+-------------------+
# | openssl      | CVE-2023-12345   | CRITICAL | 1.1.1             |
# | curl         | CVE-2023-67890   | HIGH     | 7.68.0            |
# +--------------+------------------+----------+-------------------+

# Pour corriger:
# 1. Mettre à jour les packages dans le Dockerfile
# 2. Rebuilder l'image
# 3. Re-scanner


# === RBAC (Role-Based Access Control) ===

# RBAC = Contrôle d'accès basé sur les rôles
# = Définir QUI peut faire QUOI dans Jenkins X

# === Concepts RBAC ===

# User (Utilisateur): Une personne ou un service
# Role (Rôle): Ensemble de permissions (ex: "developer", "admin")
# RoleBinding: Lie un User à un Role

# Exemple de rôles:
# - Viewer: Peut seulement VOIR les pipelines et apps
# - Developer: Peut déclencher des builds et voir les logs
# - Admin: Peut tout faire (créer/supprimer des environnements, etc)


# === Créer un Rôle "Developer" ===

# Créer un fichier: rbac-developer.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer
  namespace: jx
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["tekton.dev"]
    resources: ["pipelineruns", "taskruns"]
    verbs: ["get", "list", "watch", "create"]
  - apiGroups: ["jenkins.io"]
    resources: ["pipelineactivities"]
    verbs: ["get", "list", "watch"]

# Explications:
# rules: Liste des permissions
# resources: Types de ressources Kubernetes
# verbs: Actions autorisées
#   - get: Récupérer une ressource
#   - list: Lister les ressources
#   - watch: Surveiller les changements
#   - create: Créer une ressource

# Appliquer:
kubectl apply -f rbac-developer.yaml


# === Assigner le Rôle à un Utilisateur ===

# Créer un fichier: rbac-binding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: alice-developer
  namespace: jx
subjects:
  - kind: User
    name: alice@example.com
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer
  apiGroup: rbac.authorization.k8s.io

# Explications:
# subjects: Liste des utilisateurs/groupes
# roleRef: Le rôle à assigner

# Appliquer:
kubectl apply -f rbac-binding.yaml

# Maintenant alice@example.com a les permissions "developer"!


# === Créer un Rôle "Viewer" (Lecture seule) ===

# Créer un fichier: rbac-viewer.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: viewer
  namespace: jx
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "configmaps"]
    verbs: ["get", "list"]
  - apiGroups: ["tekton.dev"]
    resources: ["pipelineruns", "taskruns"]
    verbs: ["get", "list"]
  - apiGroups: ["jenkins.io"]
    resources: ["pipelineactivities"]
    verbs: ["get", "list"]

# Pas de "create", "update", "delete" -> Lecture seule!

# Assigner à un utilisateur:
kubectl create rolebinding bob-viewer \
  --role=viewer \
  --user=bob@example.com \
  --namespace=jx


# === AUDIT LOGS ===

# Kubernetes enregistre TOUTES les actions dans des audit logs
# Utile pour tracer qui a fait quoi

# Activer les audit logs sur GKE:
gcloud container clusters update jx-cluster \
  --enable-cloud-logging \
  --logging=SYSTEM,WORKLOAD,API

# Voir les logs d'audit:
gcloud logging read "resource.type=k8s_cluster" --limit 50

# Affiche:
# 2024-01-15 14:30:00 | User alice@example.com created pipelinerun "myapp-main-42" in namespace jx
# 2024-01-15 14:31:00 | User bob@example.com viewed pods in namespace jx-staging


# === SECRETS ENCRYPTION AT REST ===

# Par défaut, les secrets Kubernetes sont stockés en base64 (facilement décodable!)
# Pour plus de sécurité, chiffre-les au repos

# Sur GKE:
gcloud container clusters update jx-cluster \
  --database-encryption-key projects/my-project/locations/global/keyRings/my-keyring/cryptoKeys/my-key

# Sur EKS:
# AWS gère le chiffrement automatiquement avec KMS

# Sur AKS:
az aks update \
  --name jx-cluster \
  --resource-group my-rg \
  --enable-azure-keyvault-kms

# Maintenant, les secrets sont chiffrés avec une clé managée par le cloud provider!


# === NETWORK POLICIES ===

# Network Policies = Pare-feu pour les pods
# = Contrôler quel pod peut communiquer avec quel autre pod

# Exemple: Bloquer tout trafic vers la base de données SAUF depuis l'app

# Créer un fichier: network-policy-db.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-app-to-db
  namespace: jx-staging
spec:
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: myapp
      ports:
        - protocol: TCP
          port: 5432

# Explications:
# podSelector: Cible les pods postgres
# ingress: Autoriser le trafic ENTRANT
# from: Seulement depuis les pods myapp
# ports: Seulement sur le port 5432

# Appliquer:
kubectl apply -f network-policy-db.yaml

# Maintenant, SEULE l'app peut accéder à la DB!
# Tous les autres pods sont bloqués


# === POD SECURITY POLICIES ===

# PSP = Règles de sécurité pour les pods
# Exemple: Interdire les conteneurs qui tournent en root

# Créer un fichier: psp-restricted.yaml

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  privileged: false
  allowPrivilegeEscalation: false
  runAsUser:
    rule: MustRunAsNonRoot
  seLinux:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  volumes:
    - 'configMap'
    - 'emptyDir'
    - 'projected'
    - 'secret'

# Explications:
# privileged: false -> Pas de conteneurs privilégiés
# allowPrivilegeEscalation: false -> Impossible d'augmenter les privilèges
# runAsUser: MustRunAsNonRoot -> DOIT tourner en tant que non-root

# Appliquer:
kubectl apply -f psp-restricted.yaml

# Lier la PSP au namespace jx-staging:
kubectl create rolebinding psp-restricted \
  --role=psp:restricted \
  --serviceaccount=jx-staging:default \
  --namespace=jx-staging


[OK] MULTI-CLUSTER & MULTI-RÉGION

# === DÉPLOYER SUR PLUSIEURS CLUSTERS ===

# Cas d'usage:
# - Déployer en Europe ET en Amérique (latence)
# - Déployer sur plusieurs clouds (redondance)
# - Déployer sur différents environnements (dev, staging, prod)

# === Architecture Multi-Cluster ===

# Cluster 1 (Europe): jx-cluster-eu
# Cluster 2 (US): jx-cluster-us
# Cluster 3 (Asie): jx-cluster-asia

# Jenkins X peut déployer automatiquement sur tous!


# === ÉTAPE 1: Créer les Clusters ===

# Cluster Europe (GKE):
gcloud container clusters create jx-cluster-eu \
  --region=europe-west1 \
  --num-nodes=3 \
  --machine-type=n1-standard-2

# Cluster US (GKE):
gcloud container clusters create jx-cluster-us \
  --region=us-central1 \
  --num-nodes=3 \
  --machine-type=n1-standard-2

# Obtenir les credentials:
gcloud container clusters get-credentials jx-cluster-eu --region=europe-west1
gcloud container clusters get-credentials jx-cluster-us --region=us-central1


# === ÉTAPE 2: Configurer les Contexts Kubernetes ===

# Lister les contexts:
kubectl config get-contexts

# Affiche:
# CURRENT   NAME                    CLUSTER                 AUTHINFO
# *         gke_jx-cluster-eu       gke_jx-cluster-eu       gke_jx-cluster-eu
#           gke_jx-cluster-us       gke_jx-cluster-us       gke_jx-cluster-us

# Renommer pour simplifier:
kubectl config rename-context gke_jx-cluster-eu eu
kubectl config rename-context gke_jx-cluster-us us

# Changer de context:
kubectl config use-context eu


# === ÉTAPE 3: Installer Jenkins X sur Chaque Cluster ===

# Cluster Europe:
kubectl config use-context eu
jx boot

# Cluster US:
kubectl config use-context us
jx boot


# === ÉTAPE 4: Créer un Environnement Multi-Cluster ===

# Créer un environnement "production-eu":
kubectl config use-context eu
jx create env \
  --name production-eu \
  --label "Production Europe" \
  --namespace jx-production \
  --promotion Manual

# Créer un environnement "production-us":
kubectl config use-context us
jx create env \
  --name production-us \
  --label "Production US" \
  --namespace jx-production \
  --promotion Manual


# === ÉTAPE 5: Déployer sur Plusieurs Clusters ===

# Méthode 1: Promotion manuelle

# Promouvoir vers Europe:
kubectl config use-context eu
jx promote myapp --version 1.0.5 --env production-eu

# Promouvoir vers US:
kubectl config use-context us
jx promote myapp --version 1.0.5 --env production-us


# Méthode 2: Script automatisé

# Créer un fichier: deploy-multi-cluster.sh

#!/bin/bash

VERSION=$1

# Liste des clusters
CLUSTERS=("eu" "us" "asia")

for CLUSTER in "${CLUSTERS[@]}"; do
  echo "Deploying to $CLUSTER..."
  kubectl config use-context $CLUSTER
  jx promote myapp --version $VERSION --env production-$CLUSTER --no-wait
done

echo "Deployment to all clusters initiated!"

# Rendre exécutable:
chmod +x deploy-multi-cluster.sh

# Utiliser:
./deploy-multi-cluster.sh 1.0.5


# === LOAD BALANCING GLOBAL ===

# Pour diriger les utilisateurs vers le cluster le plus proche:

# Sur GCP, utilise Global Load Balancer:

# 1. Créer des IP statiques:
gcloud compute addresses create lb-ip-eu --global
gcloud compute addresses create lb-ip-us --global

# 2. Configurer le Load Balancer avec Google Cloud Console
# Ou utiliser un service comme Cloudflare pour le geo-routing


# === SYNCHRONISER LES CONFIGS ENTRE CLUSTERS ===

# Utiliser un repository Git central pour les configs:

# Structure:
# jx-multi-cluster/
# ├── clusters/
# │   ├── eu/
# │   │   └── values.yaml
# │   └── us/
# │       └── values.yaml
# └── base/
#     └── values.yaml

# base/values.yaml (config commune):
replicaCount: 3
image:
  repository: myapp
  tag: 1.0.5

# clusters/eu/values.yaml (spécifique Europe):
ingress:
  hosts:
    - myapp-eu.example.com
env:
  REGION: "europe"

# clusters/us/values.yaml (spécifique US):
ingress:
  hosts:
    - myapp-us.example.com
env:
  REGION: "us"

# Script de déploiement:

#!/bin/bash

VERSION=$1
CLUSTERS=("eu" "us")

for CLUSTER in "${CLUSTERS[@]}"; do
  kubectl config use-context $CLUSTER
  helm upgrade --install myapp ./charts/myapp \
    -f ./base/values.yaml \
    -f ./clusters/$CLUSTER/values.yaml \
    --set image.tag=$VERSION \
    --namespace jx-production
done


[OK] DISASTER RECOVERY & BACKUP

# === BACKUP DU CLUSTER ===

# Sauvegarder TOUTES les ressources Kubernetes

# === Installer Velero (Outil de backup) ===

# Velero = Outil open-source pour backup/restore de Kubernetes

# Sur GCP:

# 1. Créer un bucket pour les backups:
gsutil mb gs://jx-backups-bucket/

# 2. Créer un service account:
gcloud iam service-accounts create velero \
  --display-name "Velero service account"

# 3. Donner les permissions:
gcloud projects add-iam-policy-binding my-project \
  --member serviceAccount:velero@my-project.iam.gserviceaccount.com \
  --role roles/compute.storageAdmin

# 4. Créer une clé:
gcloud iam service-accounts keys create credentials-velero \
  --iam-account velero@my-project.iam.gserviceaccount.com

# 5. Installer Velero:
velero install \
  --provider gcp \
  --plugins velero/velero-plugin-for-gcp:v1.7.0 \
  --bucket jx-backups-bucket \
  --secret-file ./credentials-velero


# === Créer un Backup ===

# Backup de tout le namespace jx:
velero backup create jx-backup-$(date +%Y%m%d) \
  --include-namespaces jx,jx-staging,jx-production

# Affiche:
# Backup request "jx-backup-20240115" submitted successfully.

# Vérifier le backup:
velero backup get

# Affiche:
# NAME                STATUS      CREATED                         EXPIRES
# jx-backup-20240115  Completed   2024-01-15 14:30:00 +0000 UTC   29d


# === Restaurer un Backup ===

# En cas de disaster (cluster détruit), restaure tout:

# 1. Créer un nouveau cluster:
gcloud container clusters create jx-cluster-new \
  --region=europe-west1 \
  --num-nodes=3

# 2. Installer Velero sur le nouveau cluster (mêmes paramètres)

# 3. Restaurer le backup:
velero restore create --from-backup jx-backup-20240115

# Durée: 5-10 minutes

# Affiche:
# Restore request "jx-backup-20240115-20240116143000" submitted successfully.

# Vérifier:
velero restore get

# Toutes les ressources sont restaurées!
# Pods, services, configmaps, secrets, tout!


# === Backup Automatique Quotidien ===

# Créer un schedule de backup:
velero schedule create daily-jx-backup \
  --schedule="0 2 * * *" \
  --include-namespaces jx,jx-staging,jx-production \
  --ttl 720h0m0s

# Explications:
# --schedule="0 2 * * *": Tous les jours à 2h du matin (cron syntax)
# --ttl 720h0m0s: Garder les backups pendant 30 jours

# Vérifier les schedules:
velero schedule get

# Affiche:
# NAME                STATUS    SCHEDULE      LAST BACKUP
# daily-jx-backup     Enabled   0 2 * * *     2024-01-15 02:00:00


# === BACKUP DES SECRETS ===

# Les secrets sont inclus dans les backups Velero
# MAIS ils sont stockés EN CLAIR dans le bucket!

# Solution: Chiffrer le bucket

# Sur GCP:
gsutil encryption set -k projects/my-project/locations/global/keyRings/my-keyring/cryptoKeys/backup-key \
  gs://jx-backups-bucket/

# Maintenant les backups sont chiffrés au repos!


# === ETCD BACKUP (Niveau Cluster) ===

# ETCD = Base de données de Kubernetes (stocke TOUT l'état du cluster)

# Sur GKE, les backups ETCD sont automatiques (géré par Google)

# Sur un cluster self-managed:

# Backup manuel:
ETCDCTL_API=3 etcdctl snapshot save /backups/etcd-snapshot.db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

# Restore:
ETCDCTL_API=3 etcdctl snapshot restore /backups/etcd-snapshot.db \
  --data-dir=/var/lib/etcd


# === GIT BACKUP ===

# GitOps = Tout est dans Git
# Donc: Backup Git = Backup de ta config Jenkins X!

# Méthode 1: GitHub a des backups automatiques (pas besoin de faire quoi que ce soit)

# Méthode 2: Clone régulier vers un autre provider

# Script: backup-git.sh

#!/bin/bash

# Liste des repos Jenkins X
REPOS=(
  "jx-environments"
  "jx-staging"
  "jx-production"
  "myapp"
)

# Destination: GitLab (ou autre)
BACKUP_ORG="my-gitlab-org"

for REPO in "${REPOS[@]}"; do
  echo "Backing up $REPO..."
  
  # Clone depuis GitHub
  git clone https://github.com/my-github-org/$REPO.git /tmp/$REPO
  
  # Push vers GitLab
  cd /tmp/$REPO
  git remote add backup https://gitlab.com/$BACKUP_ORG/$REPO.git
  git push backup --all
  git push backup --tags
  
  # Nettoyer
  cd ..
  rm -rf /tmp/$REPO
  
  echo "$REPO backed up!"
done

# Automatiser avec cron:
# 0 3 * * * /path/to/backup-git.sh


[OK] MIGRATION & UPGRADE

# === MIGRER UN PROJET VERS JENKINS X ===

# Tu as un projet existant avec Jenkins classique ou GitLab CI?
# Migre vers Jenkins X!

# === Cas 1: Migration depuis Jenkins Classique ===

# Projet actuel:
# - Jenkins avec Jenkinsfile
# - Build Docker manuellement
# - Déploiement scriptés

# Étapes de migration:

# 1. Sauvegarder le Jenkinsfile actuel:
cp Jenkinsfile Jenkinsfile.old

# 2. Initialiser Jenkins X:
jx project import

# Jenkins X va:
# - Détecter le langage
# - Générer un nouveau pipeline Tekton
# - Créer le Helm Chart

# 3. Comparer les pipelines:
# Ouvre: .lighthouse/jenkins-x/release.yaml
# Compare avec Jenkinsfile.old

# 4. Migrer les étapes custom:
# Si tu avais des étapes spéciales dans Jenkinsfile, ajoute-les dans release.yaml

# Exemple Jenkinsfile ancien:
# stage('Custom Test') {
#   steps {
#     sh 'npm run custom-test'
#   }
# }

# Équivalent Tekton (dans release.yaml):
# - name: custom-test
#   taskSpec:
#     steps:
#       - name: run-custom-test
#         image: node:18
#         script: |
#           #!/bin/sh
#           npm run custom-test

# 5. Tester:
git add .
git commit -m "Migrate to Jenkins X"
git push

# Surveiller le premier build:
jx get activity -w

# 6. Si succès, supprimer l'ancien Jenkins:
# Désactiver les jobs Jenkins classiques


# === Cas 2: Migration depuis GitLab CI ===

# Projet actuel:
# - .gitlab-ci.yml
# - GitLab Runner
# - Registre GitLab

# Étapes:

# 1. Exporter le projet depuis GitLab:
git clone https://gitlab.com/my-org/myapp.git
cd myapp

# 2. Créer un repo GitHub:
gh repo create myapp --public --source=. --remote=origin --push

# 3. Importer dans Jenkins X:
jx project import

# 4. Migrer les jobs GitLab -> Tekton:

# Exemple .gitlab-ci.yml:
# stages:
#   - test
#   - build
#   - deploy
# 
# test:
#   stage: test
#   script:
#     - npm test
# 
# build:
#   stage: build
#   script:
#     - docker build -t myapp .

# Équivalent Tekton:
# tasks:
#   - name: test
#     taskSpec:
#       steps:
#         - name: run-tests
#           image: node:18
#           script: |
#             #!/bin/sh
#             npm test
#   
#   - name: build
#     taskSpec:
#       steps:
#         - name: build-image
#           image: gcr.io/kaniko-project/executor:latest
#           script: |
#             #!/bin/sh
#             /kaniko/executor --context=. --destination=myapp:latest

# 5. Migrer les secrets:
# GitLab CI Variables -> Kubernetes Secrets

# 6. Migrer les environnements:
# GitLab Environments -> Jenkins X Environments


# === UPGRADE JENKINS X ===

# Nouvelle version de Jenkins X disponible?

# === Vérifier la Version Actuelle ===

jx version

# Affiche:
# VERSION
# 3.2.123

# Vérifier les mises à jour:
jx upgrade cli

# Affiche:
# New version available: 3.10.456


# === Upgrade de la CLI ===

# macOS:
brew upgrade jx

# Linux:
curl -L https://github.com/jenkins-x/jx/releases/download/v3.10.456/jx-linux-amd64.tar.gz | tar xzv
sudo mv jx /usr/local/bin

# Vérifier:
jx version
# VERSION
# 3.10.456


# === Upgrade des Composants du Cluster ===

# Jenkins X dans le cluster a aussi besoin d'upgrade

# Méthode 1: Upgrade automatique
jx upgrade platform

# Jenkins X va:
# 1. Vérifier les versions des composants
# 2. Mettre à jour Tekton, Lighthouse, etc
# 3. Redémarrer les pods si nécessaire

# Durée: 5-10 minutes

# Méthode 2: Upgrade via GitOps

# 1. Clone le repo de config:
git clone https://github.com/your-org/jx-requirements.git
cd jx-requirements

# 2. Édite: jx-requirements.yml

# Change:
# version: 3.2.123
# En:
# version: 3.10.456

# 3. Commit et push:
git add jx-requirements.yml
git commit -m "Upgrade Jenkins X to 3.10.456"
git push

# Jenkins X détecte le changement et s'upgrade automatiquement!


# === Upgrade des Applications ===

# Tes apps utilisent peut-être de vieilles dépendances

# Upgrade Python:

# Édite: Dockerfile

# Change:
# FROM python:3.9
# En:
# FROM python:3.11

# Édite: .python-version (si tu utilises pyenv)
echo "3.11" > .python-version

# Commit et push:
git add Dockerfile .python-version
git commit -m "Upgrade to Python 3.11"
git push

# Jenkins X rebuild et redéploie automatiquement!


# === ROLLBACK D'UN UPGRADE ===

# Si l'upgrade casse quelque chose:

# 1. Identifier la version précédente:
jx get applications --env production

# 2. Rollback:
jx promote myapp --version 1.0.4 --env production

# Ou via GitOps:
cd jx-production
git revert HEAD
git push


[OK] CUSTOM BUILDERS & BUILD PACKS

# === CRÉER UN CUSTOM BUILDER ===

# Jenkins X utilise des "builders" (images Docker) pour exécuter les pipelines
# Par défaut: python, node, java, go...

# Besoin d'un builder custom? (ex: Python + Terraform)

# === ÉTAPE 1: Créer l'Image du Builder ===

# Créer un fichier: Dockerfile.builder

FROM python:3.11-slim

# Installer les outils nécessaires
RUN apt-get update && apt-get install -y \
    git \
    curl \
    wget \
    unzip \
    && rm -rf /var/lib/apt/lists/*

# Installer Terraform
RUN wget https://releases.hashicorp.com/terraform/1.5.0/terraform_1.5.0_linux_amd64.zip \
    && unzip terraform_1.5.0_linux_amd64.zip \
    && mv terraform /usr/local/bin/ \
    && rm terraform_1.5.0_linux_amd64.zip

# Installer AWS CLI
RUN pip install awscli

# Installer kubectl
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" \
    && chmod +x kubectl \
    && mv kubectl /usr/local/bin/

# Installer Helm
RUN curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# Installer Python packages communs
RUN pip install pytest black flake8 mypy

WORKDIR /workspace

# Builder le custom builder:
docker build -f Dockerfile.builder -t my-custom-builder:1.0.0 .

# Pousser vers un registre:
docker tag my-custom-builder:1.0.0 gcr.io/my-project/my-custom-builder:1.0.0
docker push gcr.io/my-project/my-custom-builder:1.0.0


# === ÉTAPE 2: Utiliser le Custom Builder ===

# Édite: .lighthouse/jenkins-x/release.yaml

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
spec:
  pipelineSpec:
    tasks:
      - name: build-and-deploy
        taskSpec:
          steps:
            - name: run-tests
              image: gcr.io/my-project/my-custom-builder:1.0.0
              script: |
                #!/bin/sh
                pytest tests/
            
            - name: deploy-infrastructure
              image: gcr.io/my-project/my-custom-builder:1.0.0
              script: |
                #!/bin/sh
                cd terraform/
                terraform init
                terraform apply -auto-approve
            
            - name: deploy-app
              image: gcr.io/my-project/my-custom-builder:1.0.0
              script: |
                #!/bin/sh
                kubectl apply -f k8s/

# Commit et push:
git add .lighthouse/jenkins-x/release.yaml
git commit -m "Use custom builder"
git push


# === CRÉER UN BUILD PACK CUSTOM ===

# Build Pack = Template de projet Jenkins X
# Par défaut: python, node, java...

# Créer un Build Pack pour FastAPI:

# === ÉTAPE 1: Créer la Structure ===

# Créer un repo: jx-buildpack-fastapi

mkdir jx-buildpack-fastapi
cd jx-buildpack-fastapi

# Structure:
# jx-buildpack-fastapi/
# ├── Dockerfile
# ├── Jenkinsfile
# ├── charts/
# │   └── preview/
# │       └── values.yaml
# ├── pipeline.yaml
# └── buildpack.yaml


# === ÉTAPE 2: Créer le Dockerfile ===

# Dockerfile

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]


# === ÉTAPE 3: Créer le Pipeline ===

# pipeline.yaml

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: fastapi-pipeline
spec:
  pipelineSpec:
    tasks:
      - name: test
        taskSpec:
          steps:
            - name: pytest
              image: python:3.11
              script: |
                #!/bin/sh
                pip install -r requirements.txt
                pytest tests/
      
      - name: build
        taskSpec:
          steps:
            - name: build-image
              image: gcr.io/kaniko-project/executor:latest
              script: |
                #!/bin/sh
                /kaniko/executor --context=. --destination={{.image.repository}}:{{.image.tag}}
      
      - name: deploy
        taskSpec:
          steps:
            - name: helm-deploy
              image: gcr.io/jenkinsxio/builder-jx:latest
              script: |
                #!/bin/sh
                jx promote --version {{.image.tag}} --env staging


# === ÉTAPE 4: Créer buildpack.yaml ===

# buildpack.yaml

name: fastapi
version: 1.0.0
description: Build pack for FastAPI applications
language: python
framework: fastapi

files:
  - Dockerfile
  - pipeline.yaml
  - charts/


# === ÉTAPE 5: Publier le Build Pack ===

# 1. Créer un repo GitHub:
gh repo create jx-buildpack-fastapi --public

# 2. Pusher:
git add .
git commit -m "Initial FastAPI build pack"
git push -u origin main


# === ÉTAPE 6: Utiliser le Build Pack ===

# Lors de la création d'un nouveau projet:
jx create quickstart \
  --build-pack https://github.com/your-org/jx-buildpack-fastapi.git \
  --name myapi

# Ou pour un projet existant:
jx project import \
  --build-pack https://github.com/your-org/jx-buildpack-fastapi.git


[OK] INTÉGRATIONS EXTERNES

# === INTÉGRATION AVEC SLACK ===

# Recevoir des notifications Slack pour les builds

# === ÉTAPE 1: Créer un Webhook Slack ===

# 1. Va sur: https://api.slack.com/apps
# 2. Clique "Create New App"
# 3. Choisis "From scratch"
# 4. Nom: "Jenkins X Bot"
# 5. Workspace: Ton workspace Slack
# 6. Active "Incoming Webhooks"
# 7. Clique "Add New Webhook to Workspace"
# 8. Choisis le canal: #devops
# 9. Copie le Webhook URL: https://hooks.slack.com/services/XXX/YYY/ZZZ


# === ÉTAPE 2: Configurer Jenkins X ===

# Ajouter le webhook comme secret:
kubectl create secret generic slack-webhook \
  --from-literal=url=https://hooks.slack.com/services/XXX/YYY/ZZZ \
  -n jx

# Installer le plugin Slack:
helm repo add jenkins-x https://storage.googleapis.com/chartmuseum.jenkins-x.io
helm install jx-slack jenkins-x/jx-slack \
  --namespace jx \
  --set webhook.url=$(kubectl get secret slack-webhook -n jx -o jsonpath='{.data.url}' | base64 -d)


# === ÉTAPE 3: Configurer les Notifications ===

# Édite: .lighthouse/jenkins-x/triggers.yaml

# Ajoute:
spec:
  postsubmits:
    - name: release
      branches:
        - ^main$
      source: "release.yaml"
      notifications:
        - slack:
            channel: "#devops"
            message: "Build {{.status}} for {{.repo}}/{{.branch}} #{{.build}}"

# Commit et push:
git add .lighthouse/jenkins-x/triggers.yaml
git commit -m "Add Slack notifications"
git push

# Maintenant tu reçois des notifications Slack:
# [OK] Build Succeeded for myapp/main #42
# [X] Build Failed for myapp/feature-x #43


# === INTÉGRATION AVEC JIRA ===

# Lier les commits/PRs aux tickets JIRA

# === ÉTAPE 1: Créer un Token JIRA ===

# 1. Va sur: https://id.atlassian.com/manage-profile/security/api-tokens
# 2. Clique "Create API token"
# 3. Nom: "Jenkins X"
# 4. Copie le token


# === ÉTAPE 2: Configurer Jenkins X ===

# Ajouter les credentials JIRA:
kubectl create secret generic jira-credentials \
  --from-literal=username=your-email@example.com \
  --from-literal=token=YOUR_JIRA_TOKEN \
  --from-literal=url=https://your-company.atlassian.net \
  -n jx

# Installer le plugin JIRA:
helm install jx-jira jenkins-x/jx-jira \
  --namespace jx \
  --set jira.username=$(kubectl get secret jira-credentials -n jx -o jsonpath='{.data.username}' | base64 -d) \
  --set jira.token=$(kubectl get secret jira-credentials -n jx -o jsonpath='{.data.token}' | base64 -d) \
  --set jira.url=$(kubectl get secret jira-credentials -n jx -o jsonpath='{.data.url}' | base64 -d)


# === ÉTAPE 3: Utiliser dans les Commits ===

# Dans tes commits, référence les tickets JIRA:

git commit -m "PROJ-123: Add login feature"

# Jenkins X va:
# 1. Détecter "PROJ-123"
# 2. Ajouter un commentaire sur le ticket JIRA:
#    "Commit abc123 pushed by alice@example.com
#     Build: https://jx.example.com/builds/42"

# Quand le build est déployé:
# JIRA reçoit un autre commentaire:
# "Build #42 deployed to Staging
#  URL: https://myapp-staging.jx.example.com"


# === INTÉGRATION AVEC SONARQUBE ===

# SonarQube = Analyse de qualité du code

# === ÉTAPE 1: Installer SonarQube ===

# Dans le cluster Kubernetes:
helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube
helm install sonarqube sonarqube/sonarqube --namespace sonarqube --create-namespace

# Obtenir l'URL:
kubectl get svc -n sonarqube

# Affiche:
# sonarqube   LoadBalancer   10.0.0.1   34.56.78.90   9000:30000/TCP

# Ouvrir: http://34.56.78.90:9000
# Login: admin / admin
# Change le mot de passe!


# === ÉTAPE 2: Créer un Token SonarQube ===

# 1. Va sur: My Account -> Security
# 2. Generate Token: "Jenkins X"
# 3. Copie le token: squ_abc123...


# === ÉTAPE 3: Configurer Jenkins X ===

# Ajouter le token:
kubectl create secret generic sonarqube-token \
  --from-literal=token=squ_abc123... \
  -n jx


# === ÉTAPE 4: Intégrer dans le Pipeline ===

# Édite: .lighthouse/jenkins-x/pullrequest.yaml

# Ajoute une étape SonarQube:

- name: sonarqube-scan
  taskSpec:
    steps:
      - name: scan
        image: sonarsource/sonar-scanner-cli:latest
        env:
          - name: SONAR_TOKEN
            valueFrom:
              secretKeyRef:
                name: sonarqube-token
                key: token
        script: |
          #!/bin/sh
          sonar-scanner \
            -Dsonar.host.url=http://sonarqube.sonarqube:9000 \
            -Dsonar.login=$SONAR_TOKEN \
            -Dsonar.projectKey=myapp \
            -Dsonar.sources=. \
            -Dsonar.python.coverage.reportPaths=coverage.xml

# Commit et push:
git add .lighthouse/jenkins-x/pullrequest.yaml
git commit -m "Add SonarQube scanning"
git push

# Maintenant chaque PR est analysée par SonarQube!
# Tu reçois un rapport avec:
# - Bugs détectés
# - Code smells
# - Couverture de tests
# - Duplications de code


# === INTÉGRATION AVEC DATADOG ===

# Datadog = Monitoring et observabilité

# === ÉTAPE 1: Obtenir la Clé API Datadog ===

# 1. Va sur: https://app.datadoghq.com/account/settings#api
# 2. Copie la clé API


# === ÉTAPE 2: Installer l'Agent Datadog ===

# Ajouter la clé comme secret:
kubectl create secret generic datadog-api-key \
  --from-literal=api-key=YOUR_DATADOG_API_KEY \
  -n jx

# Installer l'agent Datadog:
helm repo add datadog https://helm.datadoghq.com
helm install datadog datadog/datadog \
  --namespace jx \
  --set datadog.apiKey=$(kubectl get secret datadog-api-key -n jx -o jsonpath='{.data.api-key}' | base64 -d) \
  --set datadog.logs.enabled=true \
  --set datadog.apm.enabled=true

# Durée: 2-3 minutes

# Vérifier:
kubectl get pods -n jx | grep datadog

# Affiche:
# datadog-agent-abc123   1/1     Running   0          1m


# === ÉTAPE 3: Instrumenter ton App ===

# Python avec Datadog APM:

# Ajouter dans requirements.txt:
echo "ddtrace" >> requirements.txt

# Édite: Dockerfile

# Change:
# CMD ["gunicorn", "app:app"]
# En:
CMD ["ddtrace-run", "gunicorn", "app:app"]

# Édite: charts/myapp/values.yaml

# Ajoute les variables d'environnement:
env:
  DD_AGENT_HOST:
    valueFrom:
      fieldRef:
        fieldPath: status.hostIP
  DD_ENV: "staging"
  DD_SERVICE: "myapp"
  DD_VERSION: "1.0.0"
  DD_LOGS_INJECTION: "true"

# Commit et déploie:
git add .
git commit -m "Add Datadog instrumentation"
git push

# Maintenant Datadog collecte:
# - Métriques (CPU, RAM, requêtes/s)
# - Logs
# - Traces APM (temps de réponse, erreurs)
# - Events (déploiements)


# === INTÉGRATION AVEC ARGOCD ===

# ArgoCD = GitOps Continuous Delivery (alternative à Jenkins X pour le CD)

# Tu peux utiliser Jenkins X pour CI (build/test) et ArgoCD pour CD (deploy)

# === ÉTAPE 1: Installer ArgoCD ===

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Obtenir le mot de passe admin:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# Accéder à l'UI:
kubectl port-forward svc/argocd-server -n argocd 8080:443

# Ouvre: https://localhost:8080
# Login: admin / (mot de passe obtenu ci-dessus)


# === ÉTAPE 2: Créer une Application ArgoCD ===

# Créer un fichier: argocd-app.yaml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-staging
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/jx-staging.git
    targetRevision: main
    path: env
  destination:
    server: https://kubernetes.default.svc
    namespace: jx-staging
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

# Appliquer:
kubectl apply -f argocd-app.yaml

# ArgoCD surveille maintenant le repo jx-staging
# Dès qu'un changement est pushé, ArgoCD déploie automatiquement!


# === ÉTAPE 3: Workflow Jenkins X + ArgoCD ===

# 1. Développeur push du code
# 2. Jenkins X:
#    a. Exécute les tests
#    b. Build l'image Docker
#    c. Met à jour le repo jx-staging (nouvelle version)
# 3. ArgoCD:
#    a. Détecte le changement dans jx-staging
#    b. Déploie la nouvelle version automatiquement

# Avantages:
# - Jenkins X = CI (ce qu'il fait de mieux)
# - ArgoCD = CD (UI visuelle, drift detection)


[OK] TROUBLESHOOTING & DEBUGGING

# === PROBLÈMES COURANTS ===

# === Problème 1: Pipeline Bloqué ===

# Symptôme:
# jx get activity
# STEP                STATUS     AGE
# Build Docker Image  Running    15m

# Le step tourne depuis 15 minutes sans finir!

# Diagnostic:

# 1. Voir les logs du step:
jx get build logs --step "Build Docker Image"

# Si rien ne s'affiche, le pod est peut-être bloqué

# 2. Lister les pods Tekton:
kubectl get pods -n jx

# Cherche le pod qui correspond:
# myapp-main-42-build-docker-image-abc123

# 3. Décrire le pod:
kubectl describe pod myapp-main-42-build-docker-image-abc123 -n jx

# Regarde la section Events:
# Warning  FailedScheduling  5m   No nodes available

# Ah! Pas assez de ressources!

# Solutions:
# a. Augmenter la taille du cluster
# b. Réduire les resources requests dans values.yaml


# === Problème 2: Image Docker Non Trouvée ===

# Symptôme:
# kubectl get pods -n jx-staging
# NAME                    READY   STATUS             RESTARTS   AGE
# myapp-7d8f5b9c-abc12    0/1     ImagePullBackOff   0          5m

# Diagnostic:

# 1. Décrire le pod:
kubectl describe pod myapp-7d8f5b9c-abc12 -n jx-staging

# Erreur:
# Failed to pull image "myapp:1.0.5": rpc error: code = Unknown desc = Error response from daemon: pull access denied

# L'image n'existe pas ou n'est pas accessible!

# Solutions:

# a. Vérifier que l'image existe:
docker pull myapp:1.0.5

# b. Vérifier les credentials du registre:
kubectl get secret regcred -n jx-staging

# Si absent, créer:
kubectl create secret docker-registry regcred \
  --docker-server=gcr.io \
  --docker-username=_json_key \
  --docker-password="$(cat key.json)" \
  --namespace=jx-staging

# c. Mettre à jour le deployment pour utiliser le secret:
# Dans charts/myapp/templates/deployment.yaml
spec:
  imagePullSecrets:
    - name: regcred


# === Problème 3: Preview Environment Ne Se Crée Pas ===

# Symptôme:
# Tu crées une PR mais pas de Preview Environment

# Diagnostic:

# 1. Vérifier les triggers:
kubectl get triggerconfig -n jx

# Si vide, le trigger n'est pas configuré!

# 2. Vérifier les webhooks GitHub:
# Va sur: https://github.com/your-org/myapp/settings/hooks
# Vérifie qu'il y a un webhook pointant vers Jenkins X

# Si absent:
jx project import --no-import

# Jenkins X reconfigure les webhooks

# 3. Vérifier Lighthouse (gère les PRs):
kubectl get pods -n jx | grep lighthouse

# Si pas de pods lighthouse:
jx upgrade platform


# === Problème 4: Secrets Non Injectés ===

# Symptôme:
# Ton app crash avec:
# KeyError: 'API_KEY'

# L'app ne reçoit pas la variable d'environnement!

# Diagnostic:

# 1. Vérifier que le secret existe:
kubectl get secret my-api-secret -n jx-staging

# Si absent, créer:
kubectl create secret generic my-api-secret \
  --from-literal=api-key=abc123 \
  -n jx-staging

# 2. Vérifier que le secret est référencé dans values.yaml:
cat charts/myapp/values.yaml

# Doit contenir:
# env:
#   API_KEY:
#     valueFrom:
#       secretKeyRef:
#         name: my-api-secret
#         key: api-key

# Si absent, ajouter et redéployer

# 3. Vérifier que la variable est injectée:
kubectl exec -it myapp-7d8f5b9c-abc12 -n jx-staging -- env | grep API_KEY

# Doit afficher:
# API_KEY=abc123


# === Problème 5: Déploiement Lent ===

# Symptôme:
# Le déploiement prend 10 minutes au lieu de 2 minutes

# Diagnostic:

# 1. Identifier l'étape lente:
jx get activity -w

# Observe quelle étape prend du temps

# 2. Si "Build Docker Image" est lent:

# Optimiser le Dockerfile:
# a. Utiliser un cache de build:

# Dans pipeline.yaml:
steps:
  - name: build-with-cache
    image: gcr.io/kaniko-project/executor:latest
    script: |
      #!/bin/sh
      /kaniko/executor \
        --context=. \
        --destination=myapp:$(params.VERSION) \
        --cache=true \
        --cache-ttl=24h

# b. Utiliser multi-stage builds (voir section Optimization)

# 3. Si "Run Tests" est lent:

# Paralléliser les tests:

# Dans pullrequest.yaml:
steps:
  - name: test-unit
    image: python:3.11
    script: |
      #!/bin/sh
      pytest tests/unit/ -n auto
  - name: test-integration
    image: python:3.11
    script: |
      #!/bin/sh
      pytest tests/integration/ -n auto

# -n auto: Pytest parallélise automatiquement


# === Problème 6: Out of Memory ===

# Symptôme:
# kubectl get pods -n jx-staging
# NAME                    READY   STATUS      RESTARTS   AGE
# myapp-7d8f5b9c-abc12    0/1     OOMKilled   3          5m

# Le pod est tué car il dépasse la limite mémoire!

# Diagnostic:

# 1. Voir la consommation mémoire:
kubectl top pod myapp-7d8f5b9c-abc12 -n jx-staging

# Affiche:
# NAME                    CPU    MEMORY
# myapp-7d8f5b9c-abc12    100m   600Mi

# Il utilise 600 MB mais la limite est 512 MB!

# Solutions:

# a. Augmenter la limite:
# Dans charts/myapp/values.yaml
resources:
  limits:
    memory: 1024Mi  # Au lieu de 512Mi

# b. Optimiser l'app:
# - Réduire les dépendances
# - Utiliser un profiler (memory_profiler en Python)
# - Libérer la mémoire après usage


# === Problème 7: Certificat SSL Invalide ===

# Symptôme:
# curl https://myapp-staging.jx.example.com
# curl: (60) SSL certificate problem: unable to get local issuer certificate

# Diagnostic:

# 1. Vérifier le certificat:
kubectl get certificate -n jx-staging

# Affiche:
# NAME             READY   SECRET           AGE
# myapp-tls-cert   False   myapp-tls-cert   5m

# READY=False -> Le certificat n'est pas généré!

# 2. Voir les événements:
kubectl describe certificate myapp-tls-cert -n jx-staging

# Erreur:
# Error: Failed to verify domain ownership

# Solutions:

# a. Vérifier que le DNS pointe vers le bon IP:
nslookup myapp-staging.jx.example.com

# Doit afficher l'IP du load balancer

# b. Vérifier cert-manager (gère les certificats):
kubectl get pods -n cert-manager

# Si pas de pods, installer cert-manager:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml


# === Problème 8: GitOps Ne Se Synchronise Pas ===

# Symptôme:
# Tu fais un:
# jx promote myapp --version 1.0.5 --env production

# Mais la version en Production reste 1.0.4

# Diagnostic:

# 1. Vérifier que le commit a été fait:
cd ~/jx-production
git log

# Si pas de nouveau commit:
# Le problème est dans la promotion

# 2. Vérifier les logs de promotion:
jx get activity | grep promote

# Erreur possible:
# Failed to push to https://github.com/your-org/jx-production.git: authentication failed

# Solutions:

# a. Vérifier le token GitHub:
kubectl get secret jx-git-token -n jx -o yaml

# Si expiré, régénérer:
jx create git token --server https://github.com --name jenkins-x --token NEW_TOKEN

# b. Vérifier les permissions du token:
# Le token doit avoir "repo" et "admin:repo_hook"


# === DEBUGGING AVANCÉ ===

# === Activer le Mode Debug ===

# Dans charts/myapp/values.yaml:

env:
  DEBUG: "True"
  LOG_LEVEL: "DEBUG"

# Redéployer:
jx promote myapp --version 1.0.5 --env staging

# Maintenant l'app log TOUT (requêtes, erreurs, variables, etc)


# === Exécuter des Commandes dans un Pod ===

# Ouvrir un shell dans le pod:
kubectl exec -it myapp-7d8f5b9c-abc12 -n jx-staging -- /bin/bash

# Commandes utiles:
# - Voir les variables d'environnement:
env

# - Tester la connectivité:
curl https://api.example.com

# - Voir les fichiers:
ls -la /app

# - Lire les logs:
cat /var/log/app.log

# Quitter:
exit


# === Port-Forward pour Tester Localement ===

# Accéder à l'app directement sans passer par l'ingress:

kubectl port-forward svc/myapp 8080:8080 -n jx-staging

# Ouvre: http://localhost:8080

# Utile pour:
# - Tester l'app sans DNS
# - Debugger les problèmes d'ingress


# === Copier des Fichiers depuis/vers un Pod ===

# Copier un fichier vers le pod:
kubectl cp local-file.txt myapp-7d8f5b9c-abc12:/app/remote-file.txt -n jx-staging

# Copier un fichier depuis le pod:
kubectl cp myapp-7d8f5b9c-abc12:/app/debug.log ./debug.log -n jx-staging


# === Voir les Événements Kubernetes ===

# Tous les événements du namespace:
kubectl get events -n jx-staging --sort-by='.lastTimestamp'

# Affiche:
# LAST SEEN   TYPE      REASON              OBJECT                       MESSAGE
# 2m          Warning   FailedScheduling    pod/myapp-abc123             0/3 nodes available
# 1m          Normal    Scheduled           pod/myapp-abc123             Successfully assigned
# 30s         Normal    Pulling             pod/myapp-abc123             Pulling image
# 10s         Normal    Pulled              pod/myapp-abc123             Successfully pulled
# 5s          Normal    Started             pod/myapp-abc123             Started container


SCANNER LES VULNÉRABILITÉS ===

# Jenkins X peut scanner tes images Docker

# Installer Anchore (scanner de vulnérabilités):
jx upgrade addons anchore --namespace jx

# Configurer le pipeline pour scanner:

# Édite: .lighthouse/jenkins-x/release.yaml

- name: security-scan
  taskSpec:
    steps:
      - name: anchore-scan
        image: anchore/engine-cli:latest
        script: |
          #!/bin/sh
          anchore-cli image add myapp:$(params.VERSION)
          anchore-cli image wait myapp:$(params.VERSION)
          anchore-cli image vuln myapp:$(params.VERSION) all

# Si des vulnérabilités critiques: le pipeline échoue!


# === NETWORK POLICIES ===

# Restreindre les connexions réseau entre pods

# Créer: charts/myapp/templates/networkpolicy.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: {{ .Chart.Name }}-netpol
spec:
  podSelector:
    matchLabels:
      app: {{ .Chart.Name }}
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: jx-staging
      ports:
        - protocol: TCP
          port: 8080
  egress:
    - to:
        - namespaceSelector: {}
      ports:
        - protocol: TCP
          port: 443  # HTTPS seulement

# Explications:
# Ingress: Accepte seulement des connexions depuis jx-staging
# Egress: Peut seulement faire des requêtes HTTPS (443)


# === RBAC (Role-Based Access Control) ===

# Limiter les permissions des pods

# Créer: charts/myapp/templates/serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ .Chart.Name }}-sa

---
apiVersion: rbac.authorization.k8s.io/v1
kind:Role
metadata:
  name: {{ .Chart.Name }}-role
rules:
  - apiGroups: [""]
    resources: ["configmaps", "secrets"]
    verbs: ["get", "list"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: {{ .Chart.Name }}-binding
subjects:
  - kind: ServiceAccount
    name: {{ .Chart.Name }}-sa
roleRef:
  kind: Role
  name: {{ .Chart.Name }}-role
  apiGroup: rbac.authorization.k8s.io

# Dans deployment.yaml:
spec:
  template:
    spec:
      serviceAccountName: {{ .Chart.Name }}-sa


[OK] EXEMPLE COMPLET: APPLICATION FLASK

# === PROJET: API REST Flask avec Base de Données ===

# Tu vas créer une API REST complète et la déployer avec Jenkins X

# === ÉTAPE 1: Créer le projet avec Jenkins X ===

jx create quickstart \
  --language python \
  --framework flask \
  --name flask-api \
  --org your-github-username

# Jenkins X génère la structure


# === ÉTAPE 2: Développer l'API ===

# Édite: app.py

from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
import os

app = Flask(__name__)

# Configuration base de données
database_url = os.environ.get('DATABASE_URL', 'sqlite:///app.db')
# Fix pour PostgreSQL (Heroku/Kubernetes utilisent postgresql://)
if database_url.startswith('postgres://'):
    database_url = database_url.replace('postgres://', 'postgresql://', 1)

app.config['SQLALCHEMY_DATABASE_URI'] = database_url
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

# Modèle
class Task(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    completed = db.Column(db.Boolean, default=False)

    def to_dict(self):
        return {
            'id': self.id,
            'title': self.title,
            'completed': self.completed
        }

# Créer les tables
with app.app_context():
    db.create_all()

# Routes
@app.route('/health')
def health():
    return jsonify({'status': 'healthy'})

@app.route('/tasks', methods=['GET'])
def get_tasks():
    tasks = Task.query.all()
    return jsonify([task.to_dict() for task in tasks])

@app.route('/tasks', methods=['POST'])
def create_task():
    data = request.get_json()
    task = Task(title=data['title'])
    db.session.add(task)
    db.session.commit()
    return jsonify(task.to_dict()), 201

@app.route('/tasks/<int:id>', methods=['GET'])
def get_task(id):
    task = Task.query.get_or_404(id)
    return jsonify(task.to_dict())

@app.route('/tasks/<int:id>', methods=['PUT'])
def update_task(id):
    task = Task.query.get_or_404(id)
    data = request.get_json()
    task.title = data.get('title', task.title)
    task.completed = data.get('completed', task.completed)
    db.session.commit()
    return jsonify(task.to_dict())

@app.route('/tasks/<int:id>', methods=['DELETE'])
def delete_task(id):
    task = Task.query.get_or_404(id)
    db.session.delete(task)
    db.session.commit()
    return '', 204

if __name__ == '__main__':
    port = int(os.environ.get('PORT', 8080))
    app.run(host='0.0.0.0', port=port, debug=False)


# === ÉTAPE 3: Créer les tests ===

# Crée: tests/test_app.py

import pytest
from app import app, db, Task

@pytest.fixture
def client():
    app.config['TESTING'] = True
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
    
    with app.test_client() as client:
        with app.app_context():
            db.create_all()
        yield client
        with app.app_context():
            db.drop_all()

def test_health(client):
    response = client.get('/health')
    assert response.status_code == 200
    assert response.json['status'] == 'healthy'

def test_create_task(client):
    response = client.post('/tasks', json={'title': 'Test task'})
    assert response.status_code == 201
    assert response.json['title'] == 'Test task'
    assert response.json['completed'] == False

def test_get_tasks(client):
    client.post('/tasks', json={'title': 'Task 1'})
    client.post('/tasks', json={'title': 'Task 2'})
    
    response = client.get('/tasks')
    assert response.status_code == 200
    assert len(response.json) == 2

def test_update_task(client):
    # Créer
    response = client.post('/tasks', json={'title': 'Old title'})
    task_id = response.json['id']
    
    # Mettre à jour
    response = client.put(f'/tasks/{task_id}', 
                         json={'title': 'New title', 'completed': True})
    assert response.status_code == 200
    assert response.json['title'] == 'New title'
    assert response.json['completed'] == True

def test_delete_task(client):
    # Créer
    response = client.post('/tasks', json={'title': 'To delete'})
    task_id = response.json['id']
    
    # Supprimer
    response = client.delete(f'/tasks/{task_id}')
    assert response.status_code == 204
    
    # Vérifier suppression
    response = client.get(f'/tasks/{task_id}')
    assert response.status_code == 404


# === ÉTAPE 4: Mettre à jour requirements.txt ===

# Édite: requirements.txt

Flask==2.3.0
Flask-SQLAlchemy==3.0.0
gunicorn==20.1.0
pytest==7.4.0
psycopg2-binary==2.9.6


# === ÉTAPE 5: Ajouter PostgreSQL ===

# Jenkins X peut ajouter PostgreSQL automatiquement

# Méthode 1: Ajouter via Helm dependency

# Édite: charts/flask-api/requirements.yaml

dependencies:
  - name: postgresql
    version: 12.1.0
    repository: https://charts.bitnami.com/bitnami
    condition: postgresql.enabled

# Édite: charts/flask-api/values.yaml

postgresql:
  enabled: true
  auth:
    database: flask_api
    username: flask_user
    password: change-this-password
  persistence:
    size: 8Gi

env:
  DATABASE_URL:
    value: "postgresql://flask_user:change-this-password@flask-api-postgresql:5432/flask_api"


# === ÉTAPE 6: Commit et Push ===

git add .
git commit -m "Complete Flask API with PostgreSQL"
git push origin main

# Jenkins X va automatiquement:
# 1. Exécuter les tests
# 2. Build l'image Docker
# 3. Déployer PostgreSQL
# 4. Déployer l'API
# 5. Créer l'URL: https://flask-api-staging.jx.example.com


# === ÉTAPE 7: Tester l'API ===

# Obtenir l'URL:
jx get applications

# Tester avec curl:
URL="https://flask-api-staging.jx.example.com"

# Health check:
curl $URL/health

# Créer une tâche:
curl -X POST $URL/tasks \
  -H "Content-Type: application/json" \
  -d '{"title":"Learn Jenkins X"}'

# Lister les tâches:
curl $URL/tasks

# Mettre à jour:
curl -X PUT $URL/tasks/1 \
  -H "Content-Type: application/json" \
  -d '{"completed":true}'

# Supprimer:
curl -X DELETE $URL/tasks/1


# === ÉTAPE 8: Créer une PR pour tester Preview Environment ===

# Créer une branche:
git checkout -b feature/add-sorting

# Modifier app.py (ajouter tri):
@app.route('/tasks', methods=['GET'])
def get_tasks():
    sort_by = request.args.get('sort', 'id')
    if sort_by == 'title':
        tasks = Task.query.order_by(Task.title).all()
    else:
        tasks = Task.query.order_by(Task.id).all()
    return jsonify([task.to_dict() for task in tasks])

# Commit et push:
git add app.py
git commit -m "Add sorting to tasks endpoint"
git push origin feature/add-sorting

# Créer la PR sur GitHub

# Jenkins X crée un Preview Environment!
# Teste: https://pr-5-flask-api.jx.example.com/tasks?sort=title


# === ÉTAPE 9: Merge et Promouvoir ===

# Merge la PR sur GitHub

# Jenkins X déploie automatiquement en Staging

# Tester en Staging:
curl https://flask-api-staging.jx.example.com/tasks?sort=title

# Si OK, promouvoir en Production:
jx promote flask-api --version 1.0.1 --env production

# Vérifier:
curl https://flask-api.jx.example.com/health


[OK] TROUBLESHOOTING (RÉSOLUTION DE PROBLÈMES)

# === PROBLÈME: Pipeline échoue ===

# Voir les logs:
jx get build logs -f

# Erreur commune: "npm install failed"
# Solution: Vérifier requirements.txt / package.json

# Erreur commune: "Tests failed"
# Solution: Lancer les tests localement d'abord
pytest tests/


# === PROBLÈME: App ne démarre pas ===

# Voir les logs du pod:
kubectl logs -n jx-staging -l app=myapp -f

# Erreur commune: "Port 8080 already in use"
# Solution: Vérifier le Dockerfile:
# CMD devrait utiliser le port 8080 (standard Jenkins X)


# === PROBLÈME: Preview Environment ne se crée pas ===

# Vérifier les webhooks GitHub:
# GitHub -> Settings -> Webhooks
# Doit avoir un webhook vers: https://hook.jx.example.com

# Recréer le webhook:
jx create webhook --url https://github.com/your-username/myapp


# === PROBLÈME: DNS ne résout pas ===

# Vérifier l'ingress:
kubectl get ingress -n jx-staging

# Vérifier les services:
kubectl get svc -n jx-staging

# Recréer l'ingress:
kubectl delete ingress myapp -n jx-staging
# Jenkins X le recrée automatiquement


# === PROBLÈME: Base de données ne se connecte pas ===

# Vérifier le secret:
kubectl get secret myapp-postgresql -n jx-staging -o yaml

# Vérifier la variable d'environnement:
kubectl exec -it myapp-xxx -n jx-staging -- env | grep DATABASE_URL


# === PROBLÈME: Out of Memory ===

# Augmenter les limites:
# Édite: charts/myapp/values.yaml

resources:
  limits:
    memory: 1024Mi  # Au lieu de 512Mi

# Commit et redéploie


# === PROBLÈME: Cluster plein ===

# Voir l'utilisation des ressources:
kubectl top nodes

# Affiche:
# NAME      CPU   MEMORY
# node-1    80%   70%
# node-2    90%   85%  <- Plein!

# Solutions:
# 1. Ajouter des nœuds (GKE):
gcloud container clusters resize jx-cluster --num-nodes=5

# 2. Supprimer les vieux Preview Environments:
jx gc previews

# 3. Réduire les réplicas:
kubectl scale deployment myapp --replicas=1 -n jx-staging


[OK] COMMANDES UTILES (CHEAT SHEET)

# === JENKINS X CLI ===

jx version                        # Version de Jenkins X
jx get applications               # Liste des apps et URLs
jx get activity -w                # Voir les pipelines en temps réel
jx get build logs -f              # Logs du build en cours
jx get preview                    # Liste des Preview Environments
jx get environments               # Liste des environnements
jx promote myapp --env production # Promouvoir vers Production
jx delete application myapp       # Supprimer une app
jx gc previews                    # Nettoyer les vieux Previews
jx ui                             # Ouvrir l'interface web
jx console                        # Ouvrir la console Jenkins X
jx get urls                       # Voir toutes les URLs

# === KUBERNETES ===

kubectl get pods -n jx-staging              # Pods en Staging
kubectl get pods -n jx-staging -w           # Watch mode
kubectl logs POD_NAME -n jx-staging -f      # Logs d'un pod
kubectl describe pod POD_NAME -n jx-staging # Détails d'un pod
kubectl exec -it POD_NAME -n jx-staging -- /bin/sh  # Shell dans un pod
kubectl get ingress -n jx-staging           # Voir les ingress
kubectl get svc -n jx-staging               # Voir les services
kubectl top pods -n jx-staging              # Utilisation CPU/RAM

# === GIT ===

git checkout -b feature/new-feature  # Créer une branche
git add .                            # Ajouter tous les fichiers
git commit -m "Message"              # Commit
git push origin feature/new-feature  # Push la branche
git push origin main                 # Push vers main (déclenche deploy)

# === HELM ===

helm list -n jx-staging              # Liste des releases Helm
helm get values myapp -n jx-staging  # Voir les valeurs
helm upgrade myapp charts/myapp -n jx-staging  # Upgrade manuel


[OK] RESSOURCES & LIENS

# Documentation officielle Jenkins X:
# https://jenkins-x.io/docs/

# Guides spécifiques:
# Getting Started: https://jenkins-x.io/docs/getting-started/
# Pipelines: https://jenkins-x.io/docs/pipelines/
# Preview Environments: https://jenkins-x.io/docs/preview-environments/

# GitHub Jenkins X:
# https://github.com/jenkins-x/jx

# Tekton Documentation:
# https://tekton.dev/docs/

# Helm Charts:
# https://helm.sh/docs/

# Kubernetes:
# https://kubernetes.io/docs/

# Community Slack:
# https://jenkins-x.io/community/

# Blog et actualités:
# https://jenkins-x.io/blog/


[OK] CONCLUSION

# Jenkins X = Automatisation COMPLÈTE du CI/CD sur Kubernetes
# Tu pousses du code -> tout se déploie automatiquement!

# Avantages:
# [OK] Zero configuration (génère tout automatiquement)
# [OK] Preview Environments (teste avant de merger)
# [OK] GitOps (tout versionné dans Git)
# [OK] Scalabilité (Kubernetes natif)
# [OK] Production-ready (utilisé par des milliers d'entreprises)

# Tu es maintenant prêt à déployer des apps en production avec Jenkins X!
```



[OK] PERFORMANCE OPTIMIZATION

# === OPTIMISER LES BUILDS ===

# === Utiliser Build Cache ===

# Kaniko supporte le cache de layers Docker

# Dans .lighthouse/jenkins-x/release.yaml:

steps:
  - name: build-cached
    image: gcr.io/kaniko-project/executor:latest
    script: |
      #!/bin/sh
      /kaniko/executor \
        --context=. \
        --destination=gcr.io/my-project/myapp:$(params.VERSION) \
        --cache=true \
        --cache-repo=gcr.io/my-project/cache

# --cache=true: Active le cache
# --cache-repo: Où stocker le cache

# Gain de temps: 50-70% pour les rebuilds!


# === Paralléliser les Steps ===

# Au lieu d'exécuter les steps séquentiellement:
# test -> lint -> build

# Exécute test ET lint EN PARALLÈLE:

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
spec:
  pipelineSpec:
    tasks:
      - name: parallel-validation
        taskSpec:
          steps:
            - name: test
              image: python:3.11
              script: |
                #!/bin/sh
                pytest tests/
            - name: lint
              image: python:3.11
              script: |
                #!/bin/sh
                pylint app.py
        # Les deux steps s'exécutent EN MÊME TEMPS!

      - name: build
        runAfter:
          - parallel-validation
        # Build APRÈS que test ET lint soient terminés


# === Réduire la Taille des Images ===

# Image Python de base: 900 MB
# Image optimisée: 150 MB

# Dockerfile optimisé:

# === STAGE 1: Builder ===
FROM python:3.11 as builder

WORKDIR /app

# Installer les dépendances
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# === STAGE 2: Runtime ===
FROM python:3.11-slim

WORKDIR /app

# Copier seulement les packages installés (pas pip, setuptools, etc)
COPY --from=builder /root/.local /root/.local
ENV PATH=/root/.local/bin:$PATH

# Copier le code de l'app
COPY . .

# Supprimer les fichiers inutiles
RUN rm -rf tests/ .git/ .github/ __pycache__/ *.pyc

CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8080"]

# Gains:
# - Taille réduite de 900 MB -> 150 MB
# - Pull plus rapide
# - Moins de vulnérabilités (moins de packages)


# === OPTIMISER LES DÉPLOIEMENTS ===

# === Rolling Update Strategy ===

# Par défaut, Kubernetes remplace les pods un par un
# Optimise la stratégie pour un déploiement plus rapide

# Dans charts/myapp/templates/deployment.yaml:

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2          # Crée 2 nouveaux pods avant de supprimer les anciens
      maxUnavailable: 0    # Garde tous les anciens pods jusqu'à ce que les nouveaux soient prêts

# Avec maxSurge=2:
# - Déploiement 2x plus rapide
# - Zero downtime garanti


# === Readiness Probe ===

# Empêche Kubernetes d'envoyer du trafic vers un pod pas encore prêt

# Dans charts/myapp/templates/deployment.yaml:

spec:
  containers:
    - name: myapp
      readinessProbe:
        httpGet:
          path: /health
          port: 8080
        initialDelaySeconds: 5
        periodSeconds: 5
        successThreshold: 1

# Kubernetes attend que /health retourne 200 avant d'envoyer du trafic


# === Liveness Probe ===

# Redémarre automatiquement les pods qui crashent

spec:
  containers:
    - name: myapp
      livenessProbe:
        httpGet:
          path: /health
          port: 8080
        initialDelaySeconds: 30
        periodSeconds: 10
        failureThreshold: 3

# Si /health échoue 3 fois de suite, le pod est redémarré


# === OPTIMISER LES RESSOURCES ===

# === CPU Request vs Limit ===

# Request: CPU garanti (réservé)
#