academia/deploy/k3s/deploy.sh

182 lines
4.8 KiB
Bash
Executable File

#!/bin/bash
# K3s Deployment Script con Tests y Smoke Tests
# Uso: ./deploy.sh [all|test|build|deploy|smoke|status|clean|rollback]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Colores
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuración
NAMESPACE="academia"
DOMAIN="academia.ingeniumcodex.com"
API_IMAGE="student-api:latest"
FRONTEND_IMAGE="student-frontend:latest"
log() { echo -e "${GREEN}[$(date +%T)]${NC} $1"; }
warn() { echo -e "${YELLOW}[$(date +%T)]${NC} $1"; }
err() { echo -e "${RED}[$(date +%T)]${NC} $1" >&2; exit 1; }
pull_code() {
log "=== Actualizando código ==="
cd "$PROJECT_ROOT"
git fetch origin main
git reset --hard origin/main
log "✓ Código actualizado"
}
run_tests() {
log "=== Ejecutando tests ==="
cd "$PROJECT_ROOT"
if command -v dotnet &> /dev/null; then
dotnet test tests/Domain.Tests --verbosity minimal || err "Domain tests fallaron"
dotnet test tests/Application.Tests --verbosity minimal || err "Application tests fallaron"
log "✓ Todos los tests pasaron"
else
warn "dotnet no instalado - omitiendo tests (ejecutar localmente antes del push)"
fi
}
build_images() {
log "=== Construyendo imágenes Docker (paralelo) ==="
cd "$PROJECT_ROOT"
sudo docker build -t "$API_IMAGE" -f deploy/docker/Dockerfile.api . &
PID_API=$!
sudo docker build -t "$FRONTEND_IMAGE" -f deploy/docker/Dockerfile.frontend . &
PID_FE=$!
wait $PID_API && log "✓ API imagen construida" || err "Error construyendo API"
wait $PID_FE && log "✓ Frontend imagen construida" || err "Error construyendo Frontend"
}
import_images() {
log "=== Importando imágenes a K3s ==="
sudo sh -c "docker save $API_IMAGE | k3s ctr images import -"
sudo sh -c "docker save $FRONTEND_IMAGE | k3s ctr images import -"
log "✓ Imágenes importadas"
}
deploy_k8s() {
log "=== Desplegando en K3s ==="
cd "$SCRIPT_DIR"
sudo kubectl apply -k .
sudo kubectl rollout restart deployment/student-api deployment/student-frontend -n $NAMESPACE
log "=== Esperando rollout ==="
sudo kubectl rollout status deployment/student-api -n $NAMESPACE --timeout=180s
sudo kubectl rollout status deployment/student-frontend -n $NAMESPACE --timeout=60s
log "✓ Deploy completado"
}
smoke_tests() {
log "=== Ejecutando smoke tests ==="
sleep 10
# Health check
if curl -sf https://$DOMAIN/health | grep -q '"status":"Healthy"'; then
log "✓ Health check API"
else
err "Health check falló"
fi
# Frontend
if curl -sf https://$DOMAIN/ | grep -q 'Sistema de Estudiantes'; then
log "✓ Frontend check"
else
err "Frontend check falló"
fi
# GraphQL
if curl -sf -X POST https://$DOMAIN/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{ subjects { id name } }"}' | grep -q '"subjects"'; then
log "✓ GraphQL check"
else
err "GraphQL check falló"
fi
# Database
if curl -sf https://$DOMAIN/health | grep -q '"name":"database","status":"Healthy"'; then
log "✓ Database check"
else
err "Database check falló"
fi
log "✓ Todos los smoke tests pasaron"
}
show_status() {
log "=== Estado del cluster ==="
sudo kubectl get pods -n $NAMESPACE -o wide
echo ""
sudo kubectl get svc -n $NAMESPACE
}
rollback() {
warn "=== Rollback ==="
sudo kubectl rollout undo deployment/student-api deployment/student-frontend -n $NAMESPACE
log "✓ Rollback completado"
}
clean() {
warn "=== Limpiando namespace $NAMESPACE ==="
sudo kubectl delete namespace $NAMESPACE --ignore-not-found
log "✓ Namespace eliminado"
}
# Main
case "${1:-help}" in
all)
pull_code
run_tests
build_images
import_images
deploy_k8s
smoke_tests
show_status
;;
test)
run_tests
;;
build)
build_images
import_images
;;
deploy)
deploy_k8s
;;
smoke)
smoke_tests
;;
status)
show_status
;;
rollback)
rollback
;;
clean)
clean
;;
*)
echo "Uso: $0 [all|test|build|deploy|smoke|status|rollback|clean]"
echo ""
echo " all - Pull, test, build, deploy y smoke tests"
echo " test - Solo ejecutar tests"
echo " build - Construir e importar imágenes"
echo " deploy - Solo desplegar a K8s"
echo " smoke - Solo ejecutar smoke tests"
echo " status - Ver estado del cluster"
echo " rollback - Revertir último deploy"
echo " clean - Eliminar namespace"
exit 0
;;
esac
log "=== Completado ==="