Migration complète vers PrimeFaces Freya - Corrections des incompatibilités et intégration de primefaces-freya-extension

This commit is contained in:
lionsdev
2025-12-27 00:18:31 +00:00
parent 5e272a8256
commit 5c996931a6
206 changed files with 36646 additions and 1593 deletions

View File

@@ -0,0 +1,243 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Script pour créer les secrets Kubernetes en production
.DESCRIPTION
Ce script crée les secrets Kubernetes nécessaires pour Lions User Manager :
- Secret frontend (Keycloak client secret, OIDC encryption secret)
- Secret backend (Keycloak service account secret, DB password, etc.)
.PARAMETER VpsHost
Host SSH du VPS (ex: lions@176.57.150.2)
.PARAMETER Namespace
Namespace Kubernetes (défaut: lions-user-manager)
.PARAMETER FrontendClientSecret
Secret du client frontend Keycloak
.PARAMETER BackendClientSecret
Secret du service account backend Keycloak
.PARAMETER OidcEncryptionSecret
Secret de chiffrement OIDC (32+ caractères)
.PARAMETER KeycloakAdminPassword
Mot de passe admin Keycloak
.PARAMETER DatabasePassword
Mot de passe base de données
.PARAMETER BackendUrl
URL du backend (défaut: https://api.lions.dev/lions-user-manager)
.EXAMPLE
.\create-kubernetes-secrets-production.ps1 `
-VpsHost "lions@176.57.150.2" `
-FrontendClientSecret "frontend-secret" `
-BackendClientSecret "backend-secret" `
-OidcEncryptionSecret "32-char-encryption-secret-here" `
-KeycloakAdminPassword "admin-password" `
-DatabasePassword "db-password"
#>
param(
[Parameter(Mandatory=$true)]
[string]$VpsHost,
[Parameter(Mandatory=$false)]
[string]$Namespace = "lions-user-manager",
[Parameter(Mandatory=$true)]
[string]$FrontendClientSecret,
[Parameter(Mandatory=$true)]
[string]$BackendClientSecret,
[Parameter(Mandatory=$true)]
[string]$OidcEncryptionSecret,
[Parameter(Mandatory=$true)]
[string]$KeycloakAdminPassword,
[Parameter(Mandatory=$true)]
[string]$DatabasePassword,
[Parameter(Mandatory=$false)]
[string]$BackendUrl = "https://api.lions.dev/lions-user-manager"
)
$ErrorActionPreference = "Stop"
# Couleurs
function Write-Success { Write-Host "$args" -ForegroundColor Green }
function Write-Info { Write-Host " $args" -ForegroundColor Cyan }
function Write-Warning { Write-Host "⚠️ $args" -ForegroundColor Yellow }
function Write-Error { Write-Host "$args" -ForegroundColor Red }
function Write-Step { Write-Host "`n🚀 $args" -ForegroundColor Magenta }
Write-Host @"
🔐 CRÉATION SECRETS KUBERNETES PRODUCTION 🔐
"@ -ForegroundColor Cyan
Write-Info "VPS Host: $VpsHost"
Write-Info "Namespace: $Namespace"
Write-Info ""
# Vérifier que le namespace existe
Write-Step "1. Vérification du namespace..."
$checkNsCmd = "kubectl get namespace $Namespace"
try {
ssh.exe $VpsHost $checkNsCmd | Out-Null
Write-Success "Namespace $Namespace existe"
} catch {
Write-Info "Création du namespace $Namespace..."
$createNsCmd = "kubectl create namespace $Namespace"
ssh.exe $VpsHost $createNsCmd
Write-Success "Namespace $Namespace créé"
}
# 2. Créer le secret frontend
Write-Step "2. Création du secret frontend..."
$frontendSecretYaml = @"
apiVersion: v1
kind: Secret
metadata:
name: lions-user-manager-client-secrets
namespace: $Namespace
type: Opaque
stringData:
KEYCLOAK_CLIENT_SECRET: $FrontendClientSecret
OIDC_ENCRYPTION_SECRET: $OidcEncryptionSecret
LIONS_USER_MANAGER_BACKEND_URL: $BackendUrl
"@
$frontendSecretFile = [System.IO.Path]::GetTempFileName()
$frontendSecretYaml | Out-File -FilePath $frontendSecretFile -Encoding UTF8
try {
# Supprimer le secret s'il existe déjà
$deleteCmd = "kubectl delete secret lions-user-manager-client-secrets -n $Namespace --ignore-not-found=true"
ssh.exe $VpsHost $deleteCmd | Out-Null
# Copier le fichier sur le VPS et créer le secret
$remoteFile = "/tmp/frontend-secret.yaml"
scp.exe $frontendSecretFile "$VpsHost`:$remoteFile"
$createSecretCmd = "kubectl apply -f $remoteFile"
ssh.exe $VpsHost $createSecretCmd
Write-Success "Secret frontend créé"
} catch {
Write-Error "Erreur création secret frontend: $($_.Exception.Message)"
exit 1
} finally {
Remove-Item $frontendSecretFile -Force
}
# 3. Créer le secret backend
Write-Step "3. Création du secret backend..."
$backendSecretYaml = @"
apiVersion: v1
kind: Secret
metadata:
name: lions-user-manager-server-secrets
namespace: $Namespace
type: Opaque
stringData:
KEYCLOAK_CLIENT_SECRET: $BackendClientSecret
KEYCLOAK_ADMIN_USERNAME: admin
KEYCLOAK_ADMIN_PASSWORD: $KeycloakAdminPassword
DB_PASSWORD: $DatabasePassword
"@
$backendSecretFile = [System.IO.Path]::GetTempFileName()
$backendSecretYaml | Out-File -FilePath $backendSecretFile -Encoding UTF8
try {
# Supprimer le secret s'il existe déjà
$deleteCmd = "kubectl delete secret lions-user-manager-server-secrets -n $Namespace --ignore-not-found=true"
ssh.exe $VpsHost $deleteCmd | Out-Null
# Copier le fichier sur le VPS et créer le secret
$remoteFile = "/tmp/backend-secret.yaml"
scp.exe $backendSecretFile "$VpsHost`:$remoteFile"
$createSecretCmd = "kubectl apply -f $remoteFile"
ssh.exe $VpsHost $createSecretCmd
Write-Success "Secret backend créé"
} catch {
Write-Error "Erreur création secret backend: $($_.Exception.Message)"
exit 1
} finally {
Remove-Item $backendSecretFile -Force
}
# 4. Vérifier les secrets
Write-Step "4. Vérification des secrets créés..."
$listSecretsCmd = "kubectl get secrets -n $Namespace | grep lions-user-manager"
try {
$secrets = ssh.exe $VpsHost $listSecretsCmd
Write-Success "Secrets listés:"
Write-Host $secrets
} catch {
Write-Warning "Erreur lors de la vérification: $($_.Exception.Message)"
}
# 5. Décrire les secrets (sans afficher les valeurs)
Write-Step "5. Description des secrets (sans valeurs)..."
try {
Write-Info "Secret frontend:"
$describeFrontendCmd = "kubectl describe secret lions-user-manager-client-secrets -n $Namespace"
ssh.exe $VpsHost $describeFrontendCmd
Write-Info "Secret backend:"
$describeBackendCmd = "kubectl describe secret lions-user-manager-server-secrets -n $Namespace"
ssh.exe $VpsHost $describeBackendCmd
} catch {
Write-Warning "Erreur lors de la description: $($_.Exception.Message)"
}
# 6. Résumé
Write-Step "6. Résumé de la configuration..."
Write-Host @"
SECRETS KUBERNETES CRÉÉS
"@ -ForegroundColor Green
Write-Host "📋 SECRETS CRÉÉS:" -ForegroundColor Yellow
Write-Host ""
Write-Host "🔐 FRONTEND (lions-user-manager-client-secrets):" -ForegroundColor Cyan
Write-Host " - KEYCLOAK_CLIENT_SECRET"
Write-Host " - OIDC_ENCRYPTION_SECRET"
Write-Host " - LIONS_USER_MANAGER_BACKEND_URL"
Write-Host ""
Write-Host "🔐 BACKEND (lions-user-manager-server-secrets):" -ForegroundColor Cyan
Write-Host " - KEYCLOAK_CLIENT_SECRET"
Write-Host " - KEYCLOAK_ADMIN_USERNAME"
Write-Host " - KEYCLOAK_ADMIN_PASSWORD"
Write-Host " - DB_PASSWORD"
Write-Host ""
Write-Host "⚠️ PROCHAINES ÉTAPES:" -ForegroundColor Yellow
Write-Host " 1. Vérifiez que les secrets sont correctement créés"
Write-Host " 2. Configurez les Deployments pour utiliser ces secrets"
Write-Host " 3. Procédez au déploiement avec lionsctl"
Write-Host ""

View File

@@ -0,0 +1,155 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Script pour tuer les processus Java liés au projet Lions User Manager
.DESCRIPTION
Ce script identifie et tue tous les processus Java qui pourraient verrouiller
les fichiers du projet, permettant ainsi d'exécuter mvn clean sans erreur.
.PARAMETER Force
Force l'arrêt des processus sans confirmation
.EXAMPLE
.\kill-java-processes.ps1
.EXAMPLE
.\kill-java-processes.ps1 -Force
#>
param(
[Parameter(Mandatory=$false)]
[switch]$Force
)
$ErrorActionPreference = "Stop"
# Couleurs
function Write-Success { Write-Host "$args" -ForegroundColor Green }
function Write-Info { Write-Host " $args" -ForegroundColor Cyan }
function Write-Warning { Write-Host "⚠️ $args" -ForegroundColor Yellow }
function Write-Error { Write-Host "$args" -ForegroundColor Red }
function Write-Step { Write-Host "`n🚀 $args" -ForegroundColor Magenta }
Write-Host @"
🔪 ARRÊT DES PROCESSUS JAVA - LIONS USER MANAGER 🔪
"@ -ForegroundColor Cyan
# 1. Lister tous les processus Java
Write-Step "1. Recherche des processus Java..."
$javaProcesses = Get-Process | Where-Object {
$_.ProcessName -like "*java*" -or $_.ProcessName -like "*javaw*"
} | Where-Object {
# Exclure les processus Cursor/IDE
$_.Path -notlike "*\.cursor\*" -and
$_.Path -notlike "*\.vscode\*" -and
$_.Path -notlike "*IntelliJ*" -and
$_.Path -notlike "*eclipse*"
}
if ($javaProcesses.Count -eq 0) {
Write-Success "Aucun processus Java trouvé à arrêter"
exit 0
}
Write-Info "Processus Java trouvés: $($javaProcesses.Count)"
$javaProcesses | ForEach-Object {
Write-Host " - PID: $($_.Id) | Process: $($_.ProcessName) | Path: $($_.Path)" -ForegroundColor Gray
}
# 2. Vérifier les ports utilisés
Write-Step "2. Vérification des ports utilisés..."
$ports = @(8080, 8081, 8180)
foreach ($port in $ports) {
$connections = netstat -ano | Select-String ":$port\s" | ForEach-Object {
if ($_ -match '\s+(\d+)$') {
$matches[1]
}
}
if ($connections) {
Write-Info "Port $port utilisé par les PIDs: $($connections -join ', ')"
}
}
# 3. Demander confirmation (sauf si -Force)
if (-not $Force) {
Write-Warning "`n⚠️ Ces processus seront arrêtés de force."
$confirm = Read-Host "Continuer ? (O/N)"
if ($confirm -ne "O" -and $confirm -ne "o" -and $confirm -ne "Y" -and $confirm -ne "y") {
Write-Info "Opération annulée"
exit 0
}
}
# 4. Arrêter les processus
Write-Step "3. Arrêt des processus Java..."
$killed = 0
$errors = 0
foreach ($process in $javaProcesses) {
try {
Write-Info "Arrêt du processus $($process.Id) ($($process.ProcessName))..."
Stop-Process -Id $process.Id -Force -ErrorAction Stop
$killed++
Write-Success "Processus $($process.Id) arrêté"
} catch {
$errors++
Write-Error "Erreur lors de l'arrêt du processus $($process.Id): $_"
}
}
# 5. Attendre un peu pour que les fichiers soient libérés
if ($killed -gt 0) {
Write-Info "Attente de 2 secondes pour libérer les fichiers..."
Start-Sleep -Seconds 2
}
# 6. Vérifier qu'il ne reste plus de processus (sauf Cursor/IDE)
Write-Step "4. Vérification finale..."
$remaining = Get-Process | Where-Object {
($_.ProcessName -like "*java*" -or $_.ProcessName -like "*javaw*") -and
$_.Path -notlike "*\.cursor\*" -and
$_.Path -notlike "*\.vscode\*" -and
$_.Path -notlike "*IntelliJ*" -and
$_.Path -notlike "*eclipse*"
}
if ($remaining.Count -eq 0) {
Write-Success "Tous les processus Java du projet ont été arrêtés"
} else {
Write-Warning "Il reste $($remaining.Count) processus Java:"
$remaining | ForEach-Object {
Write-Host " - PID: $($_.Id) | Process: $($_.ProcessName)" -ForegroundColor Yellow
}
}
# 7. Résumé
Write-Host @"
PROCESSUS JAVA ARRÊTÉS
"@ -ForegroundColor Green
Write-Host "📊 RÉSUMÉ:" -ForegroundColor Yellow
Write-Host " Processus arrêtés: $killed" -ForegroundColor White
if ($errors -gt 0) {
Write-Host " Erreurs: $errors" -ForegroundColor Red
}
Write-Host ""
Write-Host "💡 Vous pouvez maintenant exécuter 'mvn clean' sans erreur" -ForegroundColor Cyan
Write-Host ""

View File

@@ -0,0 +1,288 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Script pour pousser Lions User Manager sur git.lions.dev
.DESCRIPTION
Ce script crée les repositories et pousse les modules de lions-user-manager
sur git.lions.dev pour permettre le déploiement avec lionsctl pipeline.
.PARAMETER Component
Composant à pousser: 'api', 'server', 'client', ou 'all' (défaut: 'all')
.EXAMPLE
.\push-to-git-lions.ps1 -Component all
.EXAMPLE
.\push-to-git-lions.ps1 -Component client
#>
param(
[Parameter(Mandatory=$false)]
[ValidateSet('api', 'server', 'client', 'all')]
[string]$Component = 'all'
)
# Configuration
$ErrorActionPreference = "Stop"
$GitServer = "https://git.lions.dev"
$GitOrg = "lionsdev"
$ApiRepo = "lions-user-manager-server-api"
$ServerRepo = "lions-user-manager-server-impl-quarkus"
$ClientRepo = "lions-user-manager-client-quarkus-primefaces-freya"
# Identifiants Git
$GitUsername = "lionsdev"
$GitPassword = "lions@2025"
# Chemins
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$ProjectRoot = Split-Path -Parent $ScriptDir
$ApiPath = Join-Path $ProjectRoot "lions-user-manager-server-api"
$ServerPath = Join-Path $ProjectRoot "lions-user-manager-server-impl-quarkus"
$ClientPath = Join-Path $ProjectRoot "lions-user-manager-client-quarkus-primefaces-freya"
# Couleurs
function Write-Success { Write-Host "$args" -ForegroundColor Green }
function Write-Info { Write-Host " $args" -ForegroundColor Cyan }
function Write-Warning { Write-Host "⚠️ $args" -ForegroundColor Yellow }
function Write-Error { Write-Host "$args" -ForegroundColor Red }
function Write-Step { Write-Host "`n🚀 $args" -ForegroundColor Magenta }
# Vérifier Git
function Test-Git {
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
Write-Error "Git n'est pas installé ou n'est pas dans le PATH"
exit 1
}
Write-Success "Git trouvé: $(git --version)"
}
# Vérifier si un dépôt existe (via API Gitea)
function Test-GitRepository {
param(
[string]$RepoName
)
$repoUrl = "$GitServer/api/v1/repos/$GitOrg/$RepoName"
$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${GitUsername}:${GitPassword}"))
$headers = @{
"Authorization" = "Basic $auth"
}
try {
$response = Invoke-RestMethod -Uri $repoUrl -Method Get -Headers $headers -ErrorAction SilentlyContinue
Write-Success "Dépôt $RepoName existe déjà"
return $true
} catch {
Write-Warning "Dépôt $RepoName n'existe pas. Veuillez le créer manuellement sur git.lions.dev"
Write-Info "URL: $GitServer/$GitOrg/$RepoName"
return $false
}
}
# Pousser un module
function Push-Module {
param(
[string]$ModulePath,
[string]$RepoName,
[string]$Description,
[string]$ComponentName
)
Write-Step "Push du $ComponentName vers git.lions.dev..."
if (-not (Test-Path $ModulePath)) {
Write-Error "Répertoire $ComponentName introuvable: $ModulePath"
return $false
}
# Vérifier si le dépôt existe (optionnel, on essaie quand même de pousser)
Write-Info "Vérification de l'existence du dépôt $RepoName..."
$repoExists = Test-GitRepository -RepoName $RepoName
if (-not $repoExists) {
Write-Warning "Le dépôt $RepoName n'a pas été trouvé via l'API, mais on essaie quand même de pousser..."
Write-Info "Si le push échoue, assurez-vous que le dépôt existe sur $GitServer/$GitOrg/$RepoName"
}
Push-Location $ModulePath
try {
# Vérifier si c'est un repo Git
if (-not (Test-Path ".git")) {
Write-Info "Initialisation du repository Git..."
git init
git add .
git commit -m "Initial commit - $Description"
} else {
# Ajouter tous les fichiers modifiés
git add .
$hasChanges = git diff --cached --quiet
if (-not $hasChanges) {
git commit -m "Update - $Description" 2>$null
}
}
# Vérifier la branche
$currentBranch = git branch --show-current
if ([string]::IsNullOrEmpty($currentBranch)) {
Write-Info "Création de la branche main..."
git checkout -b main 2>$null
} elseif ($currentBranch -ne "main") {
Write-Info "Renommage de la branche $currentBranch en main..."
git branch -M main 2>$null
}
# Ajouter le remote git.lions.dev
$remoteUrl = "$GitServer/$GitOrg/$RepoName.git"
Write-Info "Ajout du remote: $remoteUrl"
git remote remove lions 2>$null
git remote add lions $remoteUrl
# Encoder le mot de passe pour l'URL (le @ doit être %40)
$encodedPassword = [System.Web.HttpUtility]::UrlEncode($GitPassword)
$remoteUrlWithAuth = "$($GitServer.Replace('https://',"https://${GitUsername}:${encodedPassword}@"))/$GitOrg/$RepoName.git"
git remote set-url lions $remoteUrlWithAuth
# Pousser vers git.lions.dev
Write-Info "Push vers git.lions.dev..."
Write-Info "URL: $remoteUrl"
$env:GIT_TERMINAL_PROMPT = "0"
$env:GIT_ASKPASS = "echo"
git push lions main --force 2>&1 | Out-String | Write-Host
if ($LASTEXITCODE -eq 0) {
Write-Success "$ComponentName poussé avec succès vers git.lions.dev"
Write-Info "URL: $remoteUrl"
return $true
} else {
Write-Error "Échec du push du $ComponentName"
return $false
}
} finally {
Pop-Location
}
}
# Afficher les commandes de déploiement
function Show-DeploymentCommands {
Write-Step "Commandes de déploiement avec lionsctl:"
Write-Host @"
📋 COMMANDES DE DÉPLOIEMENT
"@ -ForegroundColor Cyan
if ($Component -eq 'server' -or $Component -eq 'all') {
Write-Host "🔨 SERVER (Backend Quarkus):" -ForegroundColor Yellow
Write-Host ""
Write-Host "# Développement (cluster k1)" -ForegroundColor Gray
Write-Host "cd ../lions-infrastructure-2025/lionsctl" -ForegroundColor White
Write-Host "./lionsctl.exe pipeline -u https://git.lions.dev/lionsdev/$ServerRepo -b main -j 17 -e dev -c k1 -m gbanedahoud@gmail.com" -ForegroundColor Green
Write-Host ""
Write-Host "# Production (cluster k2)" -ForegroundColor Gray
Write-Host "cd ../lions-infrastructure-2025/lionsctl" -ForegroundColor White
Write-Host "./lionsctl.exe pipeline -u https://git.lions.dev/lionsdev/$ServerRepo -b main -j 17 -e production -c k2 -m gbanedahoud@gmail.com" -ForegroundColor Green
Write-Host ""
}
if ($Component -eq 'client' -or $Component -eq 'all') {
Write-Host "🎨 CLIENT (Frontend Quarkus PrimeFaces):" -ForegroundColor Yellow
Write-Host ""
Write-Host "# Développement (cluster k1)" -ForegroundColor Gray
Write-Host "cd ../lions-infrastructure-2025/lionsctl" -ForegroundColor White
Write-Host "./lionsctl.exe pipeline -u https://git.lions.dev/lionsdev/$ClientRepo -b main -j 17 -e dev -c k1 -m gbanedahoud@gmail.com" -ForegroundColor Green
Write-Host ""
Write-Host "# Production (cluster k2)" -ForegroundColor Gray
Write-Host "cd ../lions-infrastructure-2025/lionsctl" -ForegroundColor White
Write-Host "./lionsctl.exe pipeline -u https://git.lions.dev/lionsdev/$ClientRepo -b main -j 17 -e production -c k2 -m gbanedahoud@gmail.com" -ForegroundColor Green
Write-Host ""
}
Write-Host @"
💡 ASTUCE: Copiez-collez ces commandes pour déployer avec lionsctl !
"@ -ForegroundColor Cyan
}
# Main
function Main {
Write-Host @"
🚀 PUSH LIONS USER MANAGER VERS GIT.LIONS.DEV 🚀
"@ -ForegroundColor Cyan
Write-Info "Composant: $Component"
Write-Info "Serveur Git: $GitServer"
Write-Info "Organisation: $GitOrg"
Write-Info ""
# Vérifier Git
Test-Git
# Push
$success = $true
if ($Component -eq 'api' -or $Component -eq 'all') {
$result = Push-Module -ModulePath $ApiPath -RepoName $ApiRepo `
-Description "Lions User Manager - Server API (DTOs, Interfaces)" `
-ComponentName "API"
$success = $success -and $result
}
if ($Component -eq 'server' -or $Component -eq 'all') {
$result = Push-Module -ModulePath $ServerPath -RepoName $ServerRepo `
-Description "Lions User Manager - Server Implementation (Quarkus)" `
-ComponentName "Server"
$success = $success -and $result
}
if ($Component -eq 'client' -or $Component -eq 'all') {
$result = Push-Module -ModulePath $ClientPath -RepoName $ClientRepo `
-Description "Lions User Manager - Client (Quarkus PrimeFaces Freya)" `
-ComponentName "Client"
$success = $success -and $result
}
if ($success) {
# Afficher les commandes de déploiement
Show-DeploymentCommands
Write-Host @"
PUSH TERMINÉ AVEC SUCCÈS !
Vous pouvez maintenant déployer avec lionsctl pipeline (voir ci-dessus)
"@ -ForegroundColor Green
} else {
Write-Error "Certains push ont échoué. Vérifiez les erreurs ci-dessus."
exit 1
}
}
# Exécuter
Main

View File

@@ -0,0 +1,214 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Script pour configurer la base de données PostgreSQL en production
.DESCRIPTION
Ce script configure PostgreSQL pour Lions User Manager :
- Création de la base de données lions_audit
- Création de l'utilisateur lions_audit_user
- Octroi des privilèges
.PARAMETER VpsHost
Host SSH du VPS (ex: lions@176.57.150.2)
.PARAMETER Namespace
Namespace Kubernetes pour PostgreSQL (défaut: postgresql)
.PARAMETER PostgresUser
Utilisateur PostgreSQL (défaut: lionsuser)
.PARAMETER DatabaseName
Nom de la base de données (défaut: lions_audit)
.PARAMETER DatabaseUser
Nom de l'utilisateur de la base (défaut: lions_audit_user)
.PARAMETER DatabasePassword
Mot de passe pour l'utilisateur de la base
.EXAMPLE
.\setup-database-production.ps1 -VpsHost "lions@176.57.150.2" -DatabasePassword "strong-password-123"
#>
param(
[Parameter(Mandatory=$true)]
[string]$VpsHost,
[Parameter(Mandatory=$false)]
[string]$Namespace = "postgresql",
[Parameter(Mandatory=$false)]
[string]$PostgresUser = "lionsuser",
[Parameter(Mandatory=$false)]
[string]$DatabaseName = "lions_audit",
[Parameter(Mandatory=$false)]
[string]$DatabaseUser = "lions_audit_user",
[Parameter(Mandatory=$true)]
[string]$DatabasePassword
)
$ErrorActionPreference = "Stop"
# Couleurs
function Write-Success { Write-Host "$args" -ForegroundColor Green }
function Write-Info { Write-Host " $args" -ForegroundColor Cyan }
function Write-Warning { Write-Host "⚠️ $args" -ForegroundColor Yellow }
function Write-Error { Write-Host "$args" -ForegroundColor Red }
function Write-Step { Write-Host "`n🚀 $args" -ForegroundColor Magenta }
Write-Host @"
🗄 CONFIGURATION BASE DE DONNÉES PRODUCTION 🗄
"@ -ForegroundColor Cyan
Write-Info "VPS Host: $VpsHost"
Write-Info "Namespace: $Namespace"
Write-Info "Database: $DatabaseName"
Write-Info "Database User: $DatabaseUser"
Write-Info ""
# 1. Trouver le pod PostgreSQL
Write-Step "1. Recherche du pod PostgreSQL..."
$getPodCmd = "kubectl get pods -n $Namespace -o jsonpath='{.items[0].metadata.name}'"
try {
$POSTGRES_POD = ssh.exe $VpsHost $getPodCmd
if ([string]::IsNullOrEmpty($POSTGRES_POD)) {
Write-Error "Aucun pod PostgreSQL trouvé dans le namespace $Namespace"
exit 1
}
Write-Success "Pod PostgreSQL trouvé: $POSTGRES_POD"
} catch {
Write-Error "Erreur lors de la recherche du pod: $($_.Exception.Message)"
exit 1
}
# 2. Lister les bases de données existantes
Write-Step "2. Liste des bases de données existantes..."
$listDbCmd = "kubectl exec -n $Namespace $POSTGRES_POD -- psql -U $PostgresUser -d postgres -c '\l'"
try {
ssh.exe $VpsHost $listDbCmd
} catch {
Write-Warning "Erreur lors de la liste des bases: $($_.Exception.Message)"
}
# 3. Vérifier si la base existe déjà
Write-Step "3. Vérification de l'existence de la base de données..."
$checkDbCmd = "kubectl exec -n $Namespace $POSTGRES_POD -- psql -U $PostgresUser -d postgres -tAc \"SELECT 1 FROM pg_database WHERE datname='$DatabaseName'\""
try {
$dbExists = ssh.exe $VpsHost $checkDbCmd
if ($dbExists -eq "1") {
Write-Warning "La base de données $DatabaseName existe déjà"
$createDb = Read-Host "Voulez-vous la recréer ? (oui/non)"
if ($createDb -eq "oui") {
$dropDbCmd = "kubectl exec -n $Namespace $POSTGRES_POD -- psql -U $PostgresUser -d postgres -c 'DROP DATABASE IF EXISTS $DatabaseName;'"
ssh.exe $VpsHost $dropDbCmd
Write-Success "Base de données supprimée"
} else {
Write-Info "Base de données conservée"
}
}
} catch {
Write-Warning "Erreur lors de la vérification: $($_.Exception.Message)"
}
# 4. Créer la base de données
Write-Step "4. Création de la base de données $DatabaseName..."
$createDbCmd = "kubectl exec -n $Namespace $POSTGRES_POD -- psql -U $PostgresUser -d postgres -c 'CREATE DATABASE $DatabaseName OWNER $PostgresUser;'"
try {
ssh.exe $VpsHost $createDbCmd
Write-Success "Base de données $DatabaseName créée"
} catch {
Write-Warning "Erreur lors de la création (peut-être qu'elle existe déjà): $($_.Exception.Message)"
}
# 5. Créer l'utilisateur
Write-Step "5. Création de l'utilisateur $DatabaseUser..."
$createUserCmd = "kubectl exec -n $Namespace $POSTGRES_POD -- psql -U $PostgresUser -d postgres -c \"CREATE USER $DatabaseUser WITH PASSWORD '$DatabasePassword';\""
try {
ssh.exe $VpsHost $createUserCmd
Write-Success "Utilisateur $DatabaseUser créé"
} catch {
Write-Warning "Erreur lors de la création de l'utilisateur (peut-être qu'il existe déjà): $($_.Exception.Message)"
}
# 6. Octroyer les privilèges
Write-Step "6. Octroi des privilèges..."
$grantDbCmd = "kubectl exec -n $Namespace $POSTGRES_POD -- psql -U $PostgresUser -d postgres -c 'GRANT ALL PRIVILEGES ON DATABASE $DatabaseName TO $DatabaseUser;'"
try {
ssh.exe $VpsHost $grantDbCmd
Write-Success "Privilèges accordés sur la base de données"
} catch {
Write-Warning "Erreur lors de l'octroi des privilèges: $($_.Exception.Message)"
}
# 7. Octroyer les privilèges sur le schéma public
Write-Step "7. Octroi des privilèges sur le schéma public..."
$grantSchemaCmd = "kubectl exec -n $Namespace $POSTGRES_POD -- psql -U $PostgresUser -d $DatabaseName -c 'GRANT ALL ON SCHEMA public TO $DatabaseUser;'"
try {
ssh.exe $VpsHost $grantSchemaCmd
Write-Success "Privilèges accordés sur le schéma public"
} catch {
Write-Warning "Erreur lors de l'octroi des privilèges sur le schéma: $($_.Exception.Message)"
}
# 8. Test de connexion
Write-Step "8. Test de connexion à la base de données..."
$testConnCmd = "kubectl exec -n $Namespace $POSTGRES_POD -- psql -U $DatabaseUser -d $DatabaseName -c 'SELECT version();'"
try {
$version = ssh.exe $VpsHost $testConnCmd
Write-Success "Connexion réussie !"
Write-Info "Version PostgreSQL: $version"
} catch {
Write-Error "Échec de la connexion: $($_.Exception.Message)"
exit 1
}
# 9. Résumé
Write-Step "9. Résumé de la configuration..."
Write-Host @"
CONFIGURATION BASE DE DONNÉES TERMINÉE
"@ -ForegroundColor Green
Write-Host "📋 INFORMATIONS IMPORTANTES:" -ForegroundColor Yellow
Write-Host ""
Write-Host "🗄️ BASE DE DONNÉES:" -ForegroundColor Cyan
Write-Host " Nom: $DatabaseName"
Write-Host " Utilisateur: $DatabaseUser"
Write-Host " Mot de passe: $DatabasePassword"
Write-Host ""
Write-Host "🔗 CONNEXION:" -ForegroundColor Cyan
Write-Host " Host: lions-db.lions.svc.cluster.local (Service Kubernetes)"
Write-Host " Port: 5432"
Write-Host " Database: $DatabaseName"
Write-Host ""
Write-Host "⚠️ ACTIONS REQUISES:" -ForegroundColor Yellow
Write-Host " 1. Sauvegardez le mot de passe de la base de données"
Write-Host " 2. Créez le secret Kubernetes avec ces informations"
Write-Host " 3. Vérifiez que Flyway peut exécuter les migrations"
Write-Host ""

View File

@@ -0,0 +1,318 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Script pour configurer Keycloak en production pour Lions User Manager
.DESCRIPTION
Ce script configure Keycloak production avec :
- Création des clients OIDC (frontend + backend)
- Création des rôles realm
- Configuration des protocol mappers
- Assignation des rôles au service account
.PARAMETER KeycloakUrl
URL de Keycloak (défaut: https://security.lions.dev)
.PARAMETER Realm
Realm Keycloak (défaut: master)
.PARAMETER AdminUsername
Nom d'utilisateur admin Keycloak
.PARAMETER AdminPassword
Mot de passe admin Keycloak
.EXAMPLE
.\setup-keycloak-production.ps1 -AdminUsername admin -AdminPassword "your-password"
#>
param(
[Parameter(Mandatory=$false)]
[string]$KeycloakUrl = "https://security.lions.dev",
[Parameter(Mandatory=$false)]
[string]$Realm = "master",
[Parameter(Mandatory=$true)]
[string]$AdminUsername,
[Parameter(Mandatory=$true)]
[string]$AdminPassword
)
$ErrorActionPreference = "Stop"
# Couleurs
function Write-Success { Write-Host "$args" -ForegroundColor Green }
function Write-Info { Write-Host " $args" -ForegroundColor Cyan }
function Write-Warning { Write-Host "⚠️ $args" -ForegroundColor Yellow }
function Write-Error { Write-Host "$args" -ForegroundColor Red }
function Write-Step { Write-Host "`n🚀 $args" -ForegroundColor Magenta }
Write-Host @"
🔐 CONFIGURATION KEYCLOAK PRODUCTION - LIONS USER MANAGER 🔐
"@ -ForegroundColor Cyan
Write-Info "Keycloak URL: $KeycloakUrl"
Write-Info "Realm: $Realm"
Write-Info "Admin Username: $AdminUsername"
Write-Info ""
# 1. Obtenir le token admin
Write-Step "1. Obtention du token admin Keycloak..."
$tokenUrl = "$KeycloakUrl/realms/$Realm/protocol/openid-connect/token"
$tokenBody = @{
username = $AdminUsername
password = $AdminPassword
grant_type = "password"
client_id = "admin-cli"
} | ConvertTo-Json
try {
$tokenResponse = Invoke-RestMethod -Uri $tokenUrl -Method Post -Body $tokenBody -ContentType "application/json"
$accessToken = $tokenResponse.access_token
if ([string]::IsNullOrEmpty($accessToken)) {
Write-Error "Impossible d'obtenir le token admin"
exit 1
}
Write-Success "Token admin obtenu"
} catch {
Write-Error "Erreur lors de l'obtention du token: $($_.Exception.Message)"
exit 1
}
$headers = @{
"Authorization" = "Bearer $accessToken"
"Content-Type" = "application/json"
}
# 2. Créer les rôles realm
Write-Step "2. Création des rôles realm..."
$roles = @(
@{name="admin"; description="System administrator with full access"},
@{name="user_manager"; description="User manager - Can create, update, delete users"},
@{name="user_viewer"; description="User viewer - Read-only access to users"},
@{name="auditor"; description="Auditor - Can view audit logs"},
@{name="sync_manager"; description="Sync manager - Can manage synchronization"},
@{name="role_manager"; description="Role manager - Can create, update, delete roles"},
@{name="role_viewer"; description="Role viewer - Read-only access to roles"}
)
foreach ($role in $roles) {
$roleUrl = "$KeycloakUrl/admin/realms/$Realm/roles"
$roleBody = @{
name = $role.name
description = $role.description
composite = $false
clientRole = $false
} | ConvertTo-Json -Compress
try {
$existingRole = Invoke-RestMethod -Uri "$roleUrl/$($role.name)" -Method Get -Headers $headers -ErrorAction SilentlyContinue
Write-Warning "Rôle $($role.name) existe déjà, ignoré"
} catch {
try {
Invoke-RestMethod -Uri $roleUrl -Method Post -Headers $headers -Body $roleBody | Out-Null
Write-Success "Rôle $($role.name) créé"
} catch {
Write-Warning "Erreur création rôle $($role.name): $($_.Exception.Message)"
}
}
}
# 3. Créer le client frontend
Write-Step "3. Création du client frontend (lions-user-manager-client)..."
$frontendClientUrl = "$KeycloakUrl/admin/realms/$Realm/clients"
$frontendClientBody = @{
clientId = "lions-user-manager-client"
name = "Lions User Manager Client (Frontend)"
description = "Frontend application for Lions User Manager"
enabled = $true
publicClient = $true
standardFlowEnabled = $true
directAccessGrantsEnabled = $false
serviceAccountsEnabled = $false
redirectUris = @(
"https://user-manager.lions.dev/*",
"https://admin.lions.dev/*",
"https://user-manager.lions.dev/auth/callback"
)
webOrigins = @(
"https://user-manager.lions.dev",
"https://admin.lions.dev"
)
protocol = "openid-connect"
attributes = @{
"pkce.code.challenge.method" = "S256"
"use.refresh.tokens" = "true"
"frontchannel.logout.session.required" = "true"
}
} | ConvertTo-Json -Depth 10 -Compress
try {
# Vérifier si le client existe
$clients = Invoke-RestMethod -Uri $frontendClientUrl -Method Get -Headers $headers
$existingClient = $clients | Where-Object { $_.clientId -eq "lions-user-manager-client" }
if ($existingClient) {
Write-Warning "Client frontend existe déjà (ID: $($existingClient.id))"
$frontendClientId = $existingClient.id
} else {
$response = Invoke-RestMethod -Uri $frontendClientUrl -Method Post -Headers $headers -Body $frontendClientBody
Write-Success "Client frontend créé"
# Récupérer l'ID du client créé
$clients = Invoke-RestMethod -Uri $frontendClientUrl -Method Get -Headers $headers
$frontendClient = $clients | Where-Object { $_.clientId -eq "lions-user-manager-client" }
$frontendClientId = $frontendClient.id
}
} catch {
Write-Error "Erreur création client frontend: $($_.Exception.Message)"
exit 1
}
# 4. Créer le client backend (service account)
Write-Step "4. Création du client backend (lions-user-manager) avec service account..."
$backendClientUrl = "$KeycloakUrl/admin/realms/$Realm/clients"
$backendClientBody = @{
clientId = "lions-user-manager"
name = "Lions User Manager Server (Backend)"
description = "Backend API for Lions User Manager with service account"
enabled = $true
publicClient = $false
standardFlowEnabled = $false
directAccessGrantsEnabled = $true
serviceAccountsEnabled = $true
authorizationServicesEnabled = $true
protocol = "openid-connect"
attributes = @{
"access.token.lifespan" = "300"
"client.session.idle.timeout" = "1800"
"client.session.max.lifespan" = "36000"
}
} | ConvertTo-Json -Depth 10 -Compress
try {
# Vérifier si le client existe
$clients = Invoke-RestMethod -Uri $backendClientUrl -Method Get -Headers $headers
$existingClient = $clients | Where-Object { $_.clientId -eq "lions-user-manager" }
if ($existingClient) {
Write-Warning "Client backend existe déjà (ID: $($existingClient.id))"
$backendClientId = $existingClient.id
} else {
$response = Invoke-RestMethod -Uri $backendClientUrl -Method Post -Headers $headers -Body $backendClientBody
Write-Success "Client backend créé"
# Récupérer l'ID du client créé
$clients = Invoke-RestMethod -Uri $backendClientUrl -Method Get -Headers $headers
$backendClient = $clients | Where-Object { $_.clientId -eq "lions-user-manager" }
$backendClientId = $backendClient.id
}
# Récupérer le secret du client backend
$secretUrl = "$KeycloakUrl/admin/realms/$Realm/clients/$backendClientId/client-secret"
$secretResponse = Invoke-RestMethod -Uri $secretUrl -Method Get -Headers $headers
$backendSecret = $secretResponse.value
Write-Success "Secret backend récupéré: $backendSecret"
Write-Info "⚠️ IMPORTANT: Sauvegardez ce secret pour la configuration Kubernetes !"
} catch {
Write-Error "Erreur création client backend: $($_.Exception.Message)"
exit 1
}
# 5. Assigner les rôles au service account
Write-Step "5. Assignation des rôles au service account backend..."
try {
# Récupérer l'ID du service account
$serviceAccountUrl = "$KeycloakUrl/admin/realms/$Realm/clients/$backendClientId/service-account-user"
$serviceAccount = Invoke-RestMethod -Uri $serviceAccountUrl -Method Get -Headers $headers
$serviceAccountId = $serviceAccount.id
# Récupérer les rôles à assigner
$rolesToAssign = @("admin", "user_manager", "auditor", "sync_manager", "role_manager")
$realmRoles = Invoke-RestMethod -Uri "$KeycloakUrl/admin/realms/$Realm/roles" -Method Get -Headers $headers
$rolesToAssignObjects = $realmRoles | Where-Object { $rolesToAssign -contains $_.name }
# Assigner les rôles
$assignRolesUrl = "$KeycloakUrl/admin/realms/$Realm/users/$serviceAccountId/role-mappings/realm"
$rolesBody = $rolesToAssignObjects | ConvertTo-Json -Depth 10
Invoke-RestMethod -Uri $assignRolesUrl -Method Post -Headers $headers -Body $rolesBody | Out-Null
Write-Success "Rôles assignés au service account: $($rolesToAssign -join ', ')"
} catch {
Write-Warning "Erreur assignation rôles au service account: $($_.Exception.Message)"
Write-Info "Vous devrez assigner les rôles manuellement dans Keycloak Admin Console"
}
# 6. Vérifier le protocol mapper roles
Write-Step "6. Vérification du protocol mapper 'roles'..."
try {
$clientScopesUrl = "$KeycloakUrl/admin/realms/$Realm/client-scopes"
$clientScopes = Invoke-RestMethod -Uri $clientScopesUrl -Method Get -Headers $headers
$rolesScope = $clientScopes | Where-Object { $_.name -eq "roles" }
if ($rolesScope) {
$mappersUrl = "$KeycloakUrl/admin/realms/$Realm/client-scopes/$($rolesScope.id)/protocol-mappers/models"
$mappers = Invoke-RestMethod -Uri $mappersUrl -Method Get -Headers $headers
$realmRolesMapper = $mappers | Where-Object { $_.name -eq "realm roles" }
if ($realmRolesMapper) {
Write-Success "Protocol mapper 'realm roles' trouvé"
Write-Info "Vérifiez qu'il est configuré pour l'access token (claim: realm_access.roles)"
} else {
Write-Warning "Protocol mapper 'realm roles' non trouvé - à créer manuellement"
}
} else {
Write-Warning "Client scope 'roles' non trouvé - à créer manuellement"
}
} catch {
Write-Warning "Erreur vérification protocol mapper: $($_.Exception.Message)"
}
# 7. Résumé
Write-Step "7. Résumé de la configuration..."
Write-Host @"
CONFIGURATION KEYCLOAK TERMINÉE
"@ -ForegroundColor Green
Write-Host "📋 INFORMATIONS IMPORTANTES:" -ForegroundColor Yellow
Write-Host ""
Write-Host "🔑 SECRET BACKEND (Service Account):" -ForegroundColor Cyan
Write-Host " $backendSecret" -ForegroundColor White
Write-Host ""
Write-Host "⚠️ ACTIONS REQUISES:" -ForegroundColor Yellow
Write-Host " 1. Sauvegardez le secret backend ci-dessus"
Write-Host " 2. Vérifiez le protocol mapper 'roles' dans Keycloak Admin Console"
Write-Host " 3. Vérifiez que les rôles sont assignés au service account"
Write-Host " 4. Créez les secrets Kubernetes avec ces informations"
Write-Host ""
Write-Host "🔗 URLS:" -ForegroundColor Cyan
Write-Host " Keycloak Admin: $KeycloakUrl/admin"
Write-Host " Realm: $Realm"
Write-Host ""

View File

@@ -0,0 +1,159 @@
# Script de vérification de la configuration Keycloak
# Pour Lions User Manager
Write-Host "============================================" -ForegroundColor Cyan
Write-Host " Vérification Configuration Keycloak" -ForegroundColor Cyan
Write-Host "============================================" -ForegroundColor Cyan
Write-Host ""
$KEYCLOAK_URL = "http://localhost:8180"
$ADMIN_USER = "admin"
$ADMIN_PASS = "admin"
Write-Host "1. Connexion à Keycloak Master..." -ForegroundColor Yellow
# Obtenir le token admin
try {
$tokenResponse = Invoke-RestMethod -Uri "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" `
-Method Post `
-ContentType "application/x-www-form-urlencoded" `
-Body @{
grant_type = "password"
client_id = "admin-cli"
username = $ADMIN_USER
password = $ADMIN_PASS
}
$ACCESS_TOKEN = $tokenResponse.access_token
Write-Host " ✅ Connexion réussie au realm master" -ForegroundColor Green
} catch {
Write-Host " ❌ Échec de connexion au realm master!" -ForegroundColor Red
Write-Host " Erreur: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}
Write-Host ""
Write-Host "2. Vérification du realm 'lions-user-manager'..." -ForegroundColor Yellow
# Vérifier si le realm existe
try {
$realm = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/lions-user-manager" `
-Method Get `
-Headers @{
Authorization = "Bearer $ACCESS_TOKEN"
}
Write-Host " ✅ Realm 'lions-user-manager' existe" -ForegroundColor Green
Write-Host " Enabled: $($realm.enabled)" -ForegroundColor Gray
} catch {
Write-Host " ❌ Realm 'lions-user-manager' n'existe PAS!" -ForegroundColor Red
Write-Host " Vous devez créer ce realm dans Keycloak" -ForegroundColor Red
exit 1
}
Write-Host ""
Write-Host "3. Vérification du client 'lions-user-manager-client'..." -ForegroundColor Yellow
# Récupérer les clients du realm
try {
$clients = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/lions-user-manager/clients" `
-Method Get `
-Headers @{
Authorization = "Bearer $ACCESS_TOKEN"
}
$client = $clients | Where-Object { $_.clientId -eq "lions-user-manager-client" }
if ($client) {
Write-Host " ✅ Client 'lions-user-manager-client' existe" -ForegroundColor Green
Write-Host " Client ID: $($client.clientId)" -ForegroundColor Gray
Write-Host " Enabled: $($client.enabled)" -ForegroundColor Gray
Write-Host " Public Client: $($client.publicClient)" -ForegroundColor Gray
Write-Host " Standard Flow Enabled: $($client.standardFlowEnabled)" -ForegroundColor Gray
Write-Host " Redirect URIs: $($client.redirectUris -join ', ')" -ForegroundColor Gray
if (-not $client.enabled) {
Write-Host " ⚠️ ATTENTION: Le client est désactivé!" -ForegroundColor Red
}
if ($client.publicClient) {
Write-Host " ⚠️ ATTENTION: Le client est PUBLIC (devrait être CONFIDENTIAL)" -ForegroundColor Yellow
}
} else {
Write-Host " ❌ Client 'lions-user-manager-client' N'EXISTE PAS!" -ForegroundColor Red
Write-Host " VOUS DEVEZ LE CRÉER DANS KEYCLOAK!" -ForegroundColor Red
Write-Host ""
Write-Host " Configuration requise:" -ForegroundColor Yellow
Write-Host " - Client ID: lions-user-manager-client" -ForegroundColor Gray
Write-Host " - Client Protocol: openid-connect" -ForegroundColor Gray
Write-Host " - Access Type: confidential" -ForegroundColor Gray
Write-Host " - Standard Flow: ON" -ForegroundColor Gray
Write-Host " - Valid Redirect URIs: http://localhost:8080/*" -ForegroundColor Gray
Write-Host " - Web Origins: http://localhost:8080" -ForegroundColor Gray
exit 1
}
} catch {
Write-Host " ❌ Erreur lors de la récupération des clients" -ForegroundColor Red
Write-Host " Erreur: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}
Write-Host ""
Write-Host "4. Vérification des rôles du realm..." -ForegroundColor Yellow
try {
$roles = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/lions-user-manager/roles" `
-Method Get `
-Headers @{
Authorization = "Bearer $ACCESS_TOKEN"
}
Write-Host "$($roles.Count) rôles trouvés" -ForegroundColor Green
$roles | ForEach-Object {
Write-Host " - $($_.name)" -ForegroundColor Gray
}
} catch {
Write-Host " ⚠️ Impossible de récupérer les rôles" -ForegroundColor Yellow
}
Write-Host ""
Write-Host "5. Vérification des utilisateurs..." -ForegroundColor Yellow
try {
$users = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/lions-user-manager/users?max=5" `
-Method Get `
-Headers @{
Authorization = "Bearer $ACCESS_TOKEN"
}
Write-Host "$($users.Count) utilisateur(s) trouvé(s) (max 5 affichés)" -ForegroundColor Green
$users | ForEach-Object {
Write-Host " - $($_.username) ($($_.email))" -ForegroundColor Gray
}
if ($users.Count -eq 0) {
Write-Host " ⚠️ Aucun utilisateur dans le realm" -ForegroundColor Yellow
Write-Host " Créez des utilisateurs pour tester l'application" -ForegroundColor Yellow
}
} catch {
Write-Host " ⚠️ Impossible de récupérer les utilisateurs" -ForegroundColor Yellow
}
Write-Host ""
Write-Host "============================================" -ForegroundColor Cyan
Write-Host " Résumé de la Configuration" -ForegroundColor Cyan
Write-Host "============================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "CLIENT (Pour l'authentification des utilisateurs):" -ForegroundColor Yellow
Write-Host " Realm: lions-user-manager" -ForegroundColor Gray
Write-Host " Client ID: lions-user-manager-client" -ForegroundColor Gray
Write-Host " URL: $KEYCLOAK_URL/realms/lions-user-manager" -ForegroundColor Gray
Write-Host ""
Write-Host "SERVER ADMIN (Pour administrer tous les realms):" -ForegroundColor Yellow
Write-Host " Realm: master" -ForegroundColor Gray
Write-Host " Client ID: admin-cli" -ForegroundColor Gray
Write-Host " Username: admin" -ForegroundColor Gray
Write-Host " URL: $KEYCLOAK_URL/realms/master" -ForegroundColor Gray
Write-Host ""
Write-Host "✅ Vérification terminée!" -ForegroundColor Green