Proyecto Final: Sistema Empresarial de Usuarios
En este módulo final del curso, desarrollaremos un sistema completo y profesional para la gestión masiva de usuarios en entornos empresariales. Este proyecto integra todos los conocimientos adquiridos: seguridad, automatización, manejo de errores, logging, y mejores prácticas de administración de sistemas.
El sistema que construiremos será capaz de procesar archivos CSV con información de empleados, crear usuarios con configuraciones específicas por departamento, establecer estructuras de directorios corporativas, configurar permisos granulares, y generar reportes detallados de la operación.
Objetivos del Proyecto Final
- Automatización completa: Creación masiva de usuarios desde CSV
- Seguridad robusta: Implementación de políticas de contraseñas seguras
- Configuración por roles: Diferentes configuraciones según departamento
- Auditoría completa: Logging detallado y reportes de cumplimiento
- Escalabilidad: Capaz de manejar cientos o miles de usuarios
Casos de Uso Empresariales
- Onboarding masivo de empleados nuevos
- Migración de sistemas de autenticación
- Reestructuración organizacional
- Implementación de políticas de seguridad unificadas
- Automatización de procesos de RRHH
Sistema de Gestión Masiva de Usuarios
Script Principal: Enterprise User Manager
Sistema completo y robusto para la creación y gestión masiva de usuarios empresariales.
#!/bin/bash
# Enterprise User Management System
# Sistema profesional para gestión masiva de usuarios en entornos empresariales
# Proyecto Final - Curso Bash Scripting Avanzado
# ========================================
# CONFIGURACIÓN GLOBAL DEL SISTEMA
# ========================================
set -euo pipefail
IFS=$'\n\t'
# Variables del sistema
readonly SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_VERSION="2.0.0"
readonly SCRIPT_AUTHOR="Enterprise IT Team"
# Directorios de trabajo
readonly CONFIG_DIR="/etc/enterprise-user-manager"
readonly LOG_DIR="/var/log/enterprise-user-manager"
readonly BACKUP_DIR="/var/backups/enterprise-user-manager"
readonly TEMPLATE_DIR="$CONFIG_DIR/templates"
readonly REPORTS_DIR="/var/reports/enterprise-user-manager"
# Archivos de configuración
readonly MAIN_CONFIG="$CONFIG_DIR/config.conf"
readonly DEPARTMENTS_CONFIG="$CONFIG_DIR/departments.yaml"
readonly PASSWORD_POLICY="$CONFIG_DIR/password_policy.conf"
# Archivos de log
readonly MAIN_LOG="$LOG_DIR/main.log"
readonly AUDIT_LOG="$LOG_DIR/audit.log"
readonly ERROR_LOG="$LOG_DIR/errors.log"
readonly SECURITY_LOG="$LOG_DIR/security.log"
# Archivos temporales
readonly TEMP_DIR="/tmp/eum_$$"
readonly LOCK_FILE="/var/run/enterprise-user-manager.lock"
# Configuración de colores
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly MAGENTA='\033[0;35m'
readonly CYAN='\033[0;36m'
readonly NC='\033[0m'
# ========================================
# CONFIGURACIÓN POR DEFECTO DEL SISTEMA
# ========================================
# Configuración por defecto
readonly DEFAULT_CONFIG='
# Configuración Enterprise User Manager
COMPANY_NAME="Mi Empresa Corp"
DEFAULT_SHELL="/bin/bash"
HOME_BASE_DIR="/home"
CORPORATE_GROUPS=(employees contractors)
SUDO_GROUPS=(sysadmin devops)
PASSWORD_EXPIRY_DAYS=90
MIN_UID=2000
MAX_UID=60000
BACKUP_RETENTION_DAYS=30
EMAIL_DOMAIN="miempresa.com"
ENABLE_LDAP_SYNC=false
ENABLE_EMAIL_NOTIFICATIONS=true
ENABLE_SLACK_NOTIFICATIONS=false
'
# Configuración de departamentos (YAML simplificado)
readonly DEFAULT_DEPARTMENTS='
# Configuración por Departamentos
departments:
IT:
groups: [employees, it, sudo]
shell: /bin/bash
home_quota: "10G"
description: "Departamento de Tecnología"
HR:
groups: [employees, hr]
shell: /bin/bash
home_quota: "5G"
description: "Recursos Humanos"
FINANCE:
groups: [employees, finance]
shell: /bin/bash
home_quota: "8G"
description: "Departamento Financiero"
SALES:
groups: [employees, sales]
shell: /bin/bash
home_quota: "6G"
description: "Ventas y Marketing"
EXEC:
groups: [employees, executives, sudo]
shell: /bin/bash
home_quota: "15G"
description: "Nivel Ejecutivo"
'
# ========================================
# FUNCIONES DE UTILIDAD BÁSICAS
# ========================================
# Función de logging centralizada
log_message() {
local level="$1"
local message="$2"
local component="${3:-MAIN}"
local timestamp="$(date '+%Y-%m-%d %H:%M:%S %Z')"
local user="$(whoami)"
local real_user="${SUDO_USER:-$user}"
local pid="$$"
# Formato: TIMESTAMP [LEVEL] (COMPONENT) USER(REAL_USER)[PID]: MESSAGE
local log_entry="$timestamp [$level] ($component) $user($real_user)[$pid]: $message"
# Escribir a log principal
echo "$log_entry" | tee -a "$MAIN_LOG" >/dev/null
# Log específico según level
case "$level" in
ERROR|CRITICAL)
echo "$log_entry" >> "$ERROR_LOG"
;;
SECURITY|AUTH)
echo "$log_entry" >> "$SECURITY_LOG"
;;
AUDIT)
echo "$log_entry" >> "$AUDIT_LOG"
;;
esac
# Output con colores
case "$level" in
ERROR) echo -e "${RED}[ERROR]${NC} $message" >&2 ;;
CRITICAL) echo -e "${RED}[CRITICAL]${NC} $message" >&2 ;;
WARNING) echo -e "${YELLOW}[WARNING]${NC} $message" >&2 ;;
INFO) echo -e "${BLUE}[INFO]${NC} $message" ;;
SUCCESS) echo -e "${GREEN}[SUCCESS]${NC} $message" ;;
DEBUG) [[ "${VERBOSE:-false}" == "true" ]] && echo -e "${MAGENTA}[DEBUG]${NC} $message" ;;
AUDIT) echo -e "${CYAN}[AUDIT]${NC} $message" ;;
SECURITY) echo -e "${RED}[SECURITY]${NC} $message" ;;
esac
# Enviar a syslog también
logger -t "$SCRIPT_NAME[$pid]" -p "user.$level" "$message"
}
# Función de cleanup y salida
cleanup() {
local exit_code=${1:-0}
log_message "INFO" "Iniciando proceso de cleanup..."
# Remover archivos temporales
[[ -d "$TEMP_DIR" ]] && rm -rf "$TEMP_DIR"
# Remover lock file
[[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
# Cleanup de procesos hijo si existen
local child_pids=$(jobs -p)
if [[ -n "$child_pids" ]]; then
log_message "INFO" "Terminando procesos hijo: $child_pids"
kill $child_pids 2>/dev/null || true
fi
log_message "INFO" "Sistema finalizado con código: $exit_code"
exit "$exit_code"
}
# Configurar traps para manejo de señales
trap 'cleanup 130' INT TERM
trap 'cleanup 1' ERR
trap cleanup EXIT
# ========================================
# FUNCIONES DE INICIALIZACIÓN
# ========================================
# Verificar prerrequisitos del sistema
check_prerequisites() {
log_message "INFO" "Verificando prerrequisitos del sistema..."
# Verificar ejecución como root
if [[ $EUID -ne 0 ]]; then
log_message "CRITICAL" "Este script debe ejecutarse como root"
cleanup 1
fi
# Verificar comandos requeridos
local required_commands=(
"useradd" "usermod" "userdel" "groupadd" "passwd"
"chage" "quota" "setquota" "getent" "id"
"openssl" "pwgen" "csvtool" "jq" "sendmail"
)
for cmd in "${required_commands[@]}"; do
if ! command -v "$cmd" &>/dev/null; then
log_message "WARNING" "Comando recomendado no encontrado: $cmd"
fi
done
# Verificar sistema de archivos con soporte para quotas
if ! grep -q "usrquota" /proc/mounts; then
log_message "WARNING" "Sistema de quotas no habilitado - funcionalidad limitada"
fi
log_message "SUCCESS" "Verificación de prerrequisitos completada"
}
# Inicializar estructura de directorios
init_directory_structure() {
log_message "INFO" "Inicializando estructura de directorios..."
local directories=(
"$CONFIG_DIR" "$LOG_DIR" "$BACKUP_DIR"
"$TEMPLATE_DIR" "$REPORTS_DIR" "$TEMP_DIR"
)
for dir in "${directories[@]}"; do
if [[ ! -d "$dir" ]]; then
mkdir -p "$dir"
chmod 755 "$dir"
log_message "DEBUG" "Directorio creado: $dir"
fi
done
# Configurar permisos específicos
chmod 700 "$LOG_DIR" "$BACKUP_DIR"
chown root:root "$CONFIG_DIR" "$LOG_DIR" "$BACKUP_DIR"
log_message "SUCCESS" "Estructura de directorios inicializada"
}
# Cargar configuración del sistema
load_configuration() {
log_message "INFO" "Cargando configuración del sistema..."
# Crear configuración por defecto si no existe
if [[ ! -f "$MAIN_CONFIG" ]]; then
echo "$DEFAULT_CONFIG" > "$MAIN_CONFIG"
chmod 600 "$MAIN_CONFIG"
log_message "INFO" "Configuración por defecto creada: $MAIN_CONFIG"
fi
# Cargar configuración
source "$MAIN_CONFIG"
# Crear configuración de departamentos si no existe
if [[ ! -f "$DEPARTMENTS_CONFIG" ]]; then
echo "$DEFAULT_DEPARTMENTS" > "$DEPARTMENTS_CONFIG"
chmod 600 "$DEPARTMENTS_CONFIG"
log_message "INFO" "Configuración de departamentos creada: $DEPARTMENTS_CONFIG"
fi
log_message "SUCCESS" "Configuración cargada exitosamente"
}
# Verificar y crear lock file
acquire_lock() {
if [[ -f "$LOCK_FILE" ]]; then
local lock_pid="$(cat "$LOCK_FILE" 2>/dev/null)"
if [[ -n "$lock_pid" ]] && kill -0 "$lock_pid" 2>/dev/null; then
log_message "CRITICAL" "Otra instancia del script está ejecutándose (PID: $lock_pid)"
cleanup 1
else
log_message "WARNING" "Lock file obsoleto encontrado, removiendo"
rm -f "$LOCK_FILE"
fi
fi
echo "$$" > "$LOCK_FILE"
log_message "DEBUG" "Lock adquirido: PID $$"
}
# ========================================
# FUNCIONES DE VALIDACIÓN
# ========================================
# Validar formato CSV
validate_csv_file() {
local csv_file="$1"
log_message "INFO" "Validando archivo CSV: $csv_file"
# Verificar que el archivo existe y es legible
if [[ ! -f "$csv_file" ]] || [[ ! -r "$csv_file" ]]; then
log_message "ERROR" "Archivo CSV no encontrado o no legible: $csv_file"
return 1
fi
# Verificar que no está vacío
if [[ ! -s "$csv_file" ]]; then
log_message "ERROR" "Archivo CSV está vacío: $csv_file"
return 1
fi
# Verificar formato de header esperado
local expected_header="username,first_name,last_name,email,department,position,phone,start_date"
local actual_header=$(head -1 "$csv_file")
if [[ "$actual_header" != "$expected_header" ]]; then
log_message "ERROR" "Header CSV inválido. Esperado: $expected_header"
log_message "ERROR" "Encontrado: $actual_header"
return 1
fi
# Contar líneas válidas (sin header)
local user_count=$(($(wc -l < "$csv_file") - 1))
if [[ $user_count -le 0 ]]; then
log_message "ERROR" "No hay usuarios válidos en el CSV"
return 1
fi
log_message "SUCCESS" "CSV válido: $user_count usuarios encontrados"
return 0
}
# Validar datos de usuario individual
validate_user_data() {
local username="$1"
local first_name="$2"
local last_name="$3"
local email="$4"
local department="$5"
local position="$6"
local phone="$7"
local start_date="$8"
# Validar username
if [[ ! "$username" =~ ^[a-z][a-z0-9_-]{2,31}$ ]]; then
log_message "ERROR" "Username inválido: $username"
return 1
fi
# Verificar si el usuario ya existe
if id "$username" &>/dev/null; then
log_message "WARNING" "Usuario ya existe: $username"
return 2 # Código especial para usuario existente
fi
# Validar email
if [[ ! "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
log_message "ERROR" "Email inválido: $email"
return 1
fi
# Validar departamento
if ! grep -q "^ $department:" "$DEPARTMENTS_CONFIG"; then
log_message "ERROR" "Departamento no configurado: $department"
return 1
fi
# Validar nombres
if [[ -z "$first_name" ]] || [[ -z "$last_name" ]]; then
log_message "ERROR" "Nombres no pueden estar vacíos"
return 1
fi
return 0
}
# ========================================
# FUNCIONES DE GESTIÓN DE USUARIOS
# ========================================
# Generar contraseña segura
generate_secure_password() {
local length="${1:-16}"
local password=""
# Verificar si pwgen está disponible
if command -v pwgen &>/dev/null; then
password=$(pwgen -s -B -n "$length" 1)
else
# Fallback usando openssl
password=$(openssl rand -base64 "$length" | tr -d "=+/" | cut -c1-"$length")
fi
# Asegurar complejidad mínima
if [[ ! "$password" =~ [A-Z] ]] || [[ ! "$password" =~ [a-z] ]] || [[ ! "$password" =~ [0-9] ]]; then
# Agregar caracteres necesarios
password="${password}Aa1"
fi
echo "$password"
}
# Obtener configuración de departamento
get_department_config() {
local department="$1"
local config_key="$2"
# Parsear YAML simplificado (limitado pero funcional)
awk -v dept="$department" -v key="$config_key" '
/^ [A-Z]+:/ { current_dept = substr($1, 3, length($1)-3) }
current_dept == dept && $1 == key":" {
gsub(/^ +/, "", $2);
gsub(/[\[\]]/, "", $2);
print $2
}
' "$DEPARTMENTS_CONFIG"
}
# Crear usuario individual
create_single_user() {
local username="$1"
local first_name="$2"
local last_name="$3"
local email="$4"
local department="$5"
local position="$6"
local phone="$7"
local start_date="$8"
log_message "INFO" "Creando usuario: $username ($first_name $last_name)"
log_message "AUDIT" "USER_CREATE_START: $username, $department, $email"
# Obtener configuración del departamento
local dept_groups=$(get_department_config "$department" "groups")
local dept_shell=$(get_department_config "$department" "shell")
local dept_quota=$(get_department_config "$department" "home_quota")
# Configurar valores por defecto si no se encuentran
dept_shell="${dept_shell:-$DEFAULT_SHELL}"
# Generar contraseña segura
local password=$(generate_secure_password)
local password_file="$TEMP_DIR/${username}_password.txt"
echo "$password" > "$password_file"
chmod 600 "$password_file"
# Crear usuario
local useradd_cmd="useradd -m -s $dept_shell -c \"$first_name $last_name ($department)\""
# Asignar UID automáticamente dentro del rango
local next_uid=$(awk -F: -v min="$MIN_UID" -v max="$MAX_UID" '$3 >= min && $3 <= max {uid[$3]=1} END {for(i=min;i<=max;i++) if(!uid[i]) {print i; exit}}' /etc/passwd)
if [[ -n "$next_uid" ]]; then
useradd_cmd="$useradd_cmd -u $next_uid"
fi
if eval "$useradd_cmd $username"; then
log_message "SUCCESS" "Usuario creado exitosamente: $username"
else
log_message "ERROR" "Falló la creación del usuario: $username"
return 1
fi
# Establecer contraseña
if echo "$username:$password" | chpasswd; then
log_message "DEBUG" "Contraseña establecida para: $username"
else
log_message "ERROR" "Falló establecer contraseña para: $username"
return 1
fi
# Forzar cambio de contraseña en primer login
if chage -d 0 "$username"; then
log_message "DEBUG" "Cambio de contraseña forzado para: $username"
fi
# Agregar a grupos
if [[ -n "$dept_groups" ]]; then
# Limpiar formato de grupos
dept_groups=$(echo "$dept_groups" | tr -d '[]' | tr ',' ' ')
for group in $dept_groups; do
group=$(echo "$group" | xargs) # Trim whitespace
# Crear grupo si no existe
if ! getent group "$group" >/dev/null; then
if groupadd "$group"; then
log_message "INFO" "Grupo creado: $group"
fi
fi
# Agregar usuario al grupo
if usermod -a -G "$group" "$username"; then
log_message "DEBUG" "Usuario $username agregado al grupo: $group"
fi
done
fi
# Configurar quota si está especificada
if [[ -n "$dept_quota" ]] && command -v setquota &>/dev/null; then
local quota_kb=$(echo "$dept_quota" | sed 's/G/*1024*1024/;s/M/*1024/' | bc 2>/dev/null || echo "5242880")
if setquota -u "$username" "$quota_kb" "$quota_kb" 0 0 /home 2>/dev/null; then
log_message "DEBUG" "Quota configurada para $username: $dept_quota"
fi
fi
# Crear estructura de directorios personalizada
create_user_directory_structure "$username" "$department"
# Configurar archivos de perfil
setup_user_profile "$username" "$department"
# Generar credenciales para entrega
generate_user_credentials "$username" "$first_name" "$last_name" "$email" "$password"
log_message "AUDIT" "USER_CREATE_SUCCESS: $username, UID: $(id -u "$username"), Groups: $(groups "$username")"
log_message "SUCCESS" "Usuario $username configurado completamente"
return 0
}
# Crear estructura de directorios personalizada
create_user_directory_structure() {
local username="$1"
local department="$2"
local home_dir="/home/$username"
log_message "DEBUG" "Configurando estructura de directorios para: $username"
# Directorios estándar
local standard_dirs=(
"Documents" "Downloads" "Desktop" "Projects"
"Scripts" "Backups" ".ssh" ".config"
)
for dir in "${standard_dirs[@]}"; do
local full_path="$home_dir/$dir"
if [[ ! -d "$full_path" ]]; then
mkdir -p "$full_path"
chown "$username:$username" "$full_path"
chmod 755 "$full_path"
fi
done
# Configurar permisos especiales para .ssh
chmod 700 "$home_dir/.ssh"
# Crear directorio específico por departamento
local dept_dir="$home_dir/Department_${department}"
mkdir -p "$dept_dir"
chown "$username:$username" "$dept_dir"
chmod 755 "$dept_dir"
# Crear README personalizado
cat > "$home_dir/README.txt" << EOF
Bienvenido al sistema $COMPANY_NAME
===================================
Usuario: $username
Departamento: $department
Fecha de creación: $(date)
Estructura de directorios:
- Documents/: Documentos personales
- Projects/: Proyectos de trabajo
- Scripts/: Scripts personalizados
- Department_${department}/: Recursos del departamento
- .ssh/: Configuración SSH (mantener privado)
Para soporte técnico, contacta al departamento de IT.
EOF
chown "$username:$username" "$home_dir/README.txt"
chmod 644 "$home_dir/README.txt"
log_message "DEBUG" "Estructura de directorios creada para: $username"
}
# Configurar perfil de usuario
setup_user_profile() {
local username="$1"
local department="$2"
local home_dir="/home/$username"
# Configurar .bashrc personalizado
cat >> "$home_dir/.bashrc" << EOF
# Configuración personalizada $COMPANY_NAME
export COMPANY="$COMPANY_NAME"
export DEPARTMENT="$department"
export USER_CREATED="$(date)"
# Aliases útiles
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias grep='grep --color=auto'
alias ..='cd ..'
alias ...='cd ../..'
# Configuración del prompt
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
# Mensaje de bienvenida
echo "Bienvenido a $COMPANY_NAME, $username"
echo "Departamento: $department"
echo "Último login: \$(date)"
EOF
# Configurar .profile
cat >> "$home_dir/.profile" << EOF
# Configuración de entorno $COMPANY_NAME
export PATH="\$HOME/Scripts:\$PATH"
export EDITOR=nano
export PAGER=less
EOF
# Ajustar propietario
chown "$username:$username" "$home_dir/.bashrc" "$home_dir/.profile"
log_message "DEBUG" "Perfil configurado para: $username"
}
# Generar archivo de credenciales
generate_user_credentials() {
local username="$1"
local first_name="$2"
local last_name="$3"
local email="$4"
local password="$5"
local credentials_file="$REPORTS_DIR/credentials_${username}_$(date +%Y%m%d_%H%M%S).txt"
cat > "$credentials_file" << EOF
CREDENCIALES DE ACCESO - $COMPANY_NAME
======================================
Información del Usuario:
- Nombre Completo: $first_name $last_name
- Usuario: $username
- Email: $email
- Contraseña Temporal: $password
Instrucciones de Primer Acceso:
1. Inicia sesión con las credenciales proporcionadas
2. Cambia tu contraseña cuando se te solicite
3. Lee el archivo README.txt en tu directorio home
4. Configura tu perfil según las políticas de la empresa
IMPORTANTE:
- Esta contraseña debe cambiarse en el primer acceso
- No compartas tus credenciales con terceros
- Contacta a IT para cualquier problema técnico
Fecha de generación: $(date)
Sistema: $(hostname)
EOF
# Proteger el archivo de credenciales
chmod 600 "$credentials_file"
chown root:root "$credentials_file"
log_message "DEBUG" "Credenciales generadas: $credentials_file"
echo "$credentials_file"
}
# ========================================
# FUNCIONES DE PROCESAMIENTO MASIVO
# ========================================
# Procesar archivo CSV completo
process_csv_file() {
local csv_file="$1"
local dry_run="${2:-false}"
log_message "INFO" "Iniciando procesamiento masivo de usuarios..."
log_message "AUDIT" "BATCH_PROCESS_START: file=$csv_file, dry_run=$dry_run"
# Validar archivo
if ! validate_csv_file "$csv_file"; then
log_message "CRITICAL" "Validación de CSV falló"
return 1
fi
# Contadores
local total_users=0
local successful_creates=0
local failed_creates=0
local skipped_users=0
# Procesar línea por línea (saltando header)
while IFS=',' read -r username first_name last_name email department position phone start_date; do
((total_users++))
log_message "DEBUG" "Procesando usuario $total_users: $username"
# Validar datos del usuario
if ! validate_user_data "$username" "$first_name" "$last_name" "$email" "$department" "$position" "$phone" "$start_date"; then
case $? in
1)
log_message "ERROR" "Datos inválidos para usuario: $username"
((failed_creates++))
;;
2)
log_message "INFO" "Usuario ya existe, saltando: $username"
((skipped_users++))
;;
esac
continue
fi
# Modo dry-run
if [[ "$dry_run" == "true" ]]; then
log_message "INFO" "DRY-RUN: Crearía usuario $username ($department)"
continue
fi
# Crear usuario
if create_single_user "$username" "$first_name" "$last_name" "$email" "$department" "$position" "$phone" "$start_date"; then
((successful_creates++))
log_message "SUCCESS" "Usuario creado exitosamente: $username"
else
((failed_creates++))
log_message "ERROR" "Falló la creación del usuario: $username"
fi
# Pausa pequeña para evitar sobrecarga del sistema
sleep 0.1
done < <(tail -n +2 "$csv_file") # Saltar header
# Generar reporte final
generate_batch_report "$csv_file" "$total_users" "$successful_creates" "$failed_creates" "$skipped_users" "$dry_run"
log_message "AUDIT" "BATCH_PROCESS_END: total=$total_users, success=$successful_creates, failed=$failed_creates, skipped=$skipped_users"
log_message "SUCCESS" "Procesamiento completado: $successful_creates/$total_users usuarios creados exitosamente"
return 0
}
# Generar reporte de procesamiento masivo
generate_batch_report() {
local csv_file="$1"
local total="$2"
local successful="$3"
local failed="$4"
local skipped="$5"
local dry_run="$6"
local report_file="$REPORTS_DIR/batch_report_$(date +%Y%m%d_%H%M%S).txt"
{
echo "REPORTE DE PROCESAMIENTO MASIVO DE USUARIOS"
echo "==========================================="
echo ""
echo "Información General:"
echo "- Archivo procesado: $csv_file"
echo "- Fecha/Hora: $(date)"
echo "- Sistema: $(hostname)"
echo "- Ejecutado por: $(whoami)"
echo "- Modo: $([ "$dry_run" == "true" ] && echo "DRY RUN" || echo "PRODUCCIÓN")"
echo ""
echo "Estadísticas:"
echo "- Total de usuarios procesados: $total"
echo "- Creaciones exitosas: $successful"
echo "- Creaciones fallidas: $failed"
echo "- Usuarios saltados (existentes): $skipped"
echo ""
echo "Tasa de éxito: $(( (successful * 100) / (total > 0 ? total : 1) ))%"
echo ""
if [[ $failed -gt 0 ]]; then
echo "ERRORES ENCONTRADOS:"
echo "- $failed usuarios no pudieron ser creados"
echo "- Revisar $ERROR_LOG para detalles"
echo ""
fi
if [[ "$dry_run" != "true" ]]; then
echo "ARCHIVOS GENERADOS:"
echo "- Credenciales: $REPORTS_DIR/credentials_*.txt"
echo "- Logs: $LOG_DIR/"
echo ""
fi
echo "Para soporte técnico, contactar al administrador del sistema."
} > "$report_file"
log_message "SUCCESS" "Reporte generado: $report_file"
# Mostrar resumen en pantalla
echo -e "\n${GREEN}=== RESUMEN DEL PROCESAMIENTO ===${NC}"
echo "Total procesados: $total"
echo "Exitosos: $successful"
echo "Fallidos: $failed"
echo "Saltados: $skipped"
echo "Reporte completo: $report_file"
}
# ========================================
# FUNCIÓN PRINCIPAL Y MANEJO DE ARGUMENTOS
# ========================================
show_help() {
cat << EOF
Enterprise User Management System v$SCRIPT_VERSION
Creado por: $SCRIPT_AUTHOR
DESCRIPCIÓN:
Sistema profesional para gestión masiva de usuarios empresariales.
Procesa archivos CSV para crear usuarios con configuraciones específicas
por departamento, incluyendo permisos, quotas y estructura de directorios.
USO:
$0 [COMANDO] [OPCIONES]
COMANDOS:
create-batch CSV_FILE - Crear usuarios masivamente desde CSV
create-single - Crear usuario individual (interactivo)
validate CSV_FILE - Validar archivo CSV sin crear usuarios
list-departments - Mostrar departamentos configurados
generate-template - Generar template CSV de ejemplo
cleanup-old-users DAYS - Limpiar usuarios antiguos
backup-system - Crear backup del sistema de usuarios
restore-system BACKUP - Restaurar desde backup
OPCIONES GLOBALES:
--dry-run - Simular sin hacer cambios reales
--verbose - Modo verbose con debug detallado
--config FILE - Usar archivo de configuración específico
--log-level LEVEL - Nivel de log: ERROR,WARN,INFO,DEBUG
-h, --help - Mostrar esta ayuda
FORMATO CSV ESPERADO:
username,first_name,last_name,email,department,position,phone,start_date
EJEMPLOS:
# Validar archivo CSV
$0 validate employees.csv
# Crear usuarios en modo simulación
$0 create-batch employees.csv --dry-run
# Crear usuarios en producción
$0 create-batch employees.csv
# Generar template de ejemplo
$0 generate-template > template.csv
ARCHIVOS DE CONFIGURACIÓN:
- Config principal: $MAIN_CONFIG
- Departamentos: $DEPARTMENTS_CONFIG
- Logs: $LOG_DIR/
- Reportes: $REPORTS_DIR/
Para más información, consulta la documentación o contacta al equipo de IT.
EOF
}
# Función principal
main() {
local command="${1:-help}"
local verbose=false
local dry_run=false
# Procesar opciones globales
while [[ $# -gt 0 ]]; do
case $1 in
--verbose)
verbose=true
export VERBOSE=true
shift
;;
--dry-run)
dry_run=true
shift
;;
--help|-h|help)
show_help
exit 0
;;
*)
break
;;
esac
done
# Re-capturar comando después de procesar opciones
command="${1:-help}"
# Inicialización del sistema
check_prerequisites
init_directory_structure
load_configuration
acquire_lock
log_message "INFO" "=== Enterprise User Manager v$SCRIPT_VERSION iniciado ==="
log_message "INFO" "Comando: $command, Verbose: $verbose, Dry-run: $dry_run"
# Ejecutar comando solicitado
case "$command" in
create-batch)
[[ -z "${2:-}" ]] && { log_message "ERROR" "Archivo CSV requerido"; show_help; cleanup 1; }
process_csv_file "$2" "$dry_run"
;;
validate)
[[ -z "${2:-}" ]] && { log_message "ERROR" "Archivo CSV requerido"; cleanup 1; }
validate_csv_file "$2"
;;
generate-template)
echo "username,first_name,last_name,email,department,position,phone,start_date"
echo "jsmith,John,Smith,[email protected],IT,Developer,555-1234,2024-01-15"
echo "mdoe,Mary,Doe,[email protected],HR,Manager,555-5678,2024-01-16"
;;
list-departments)
grep "^ [A-Z]*:" "$DEPARTMENTS_CONFIG" | sed 's/://g' | awk '{print $1}'
;;
help|--help|-h)
show_help
;;
*)
log_message "ERROR" "Comando desconocido: $command"
show_help
cleanup 1
;;
esac
cleanup 0
}
# ========================================
# PUNTO DE ENTRADA DEL SCRIPT
# ========================================
# Verificar ejecución directa
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi
Archivo CSV de Ejemplo
Formato estándar para la carga masiva de usuarios empresariales.
username,first_name,last_name,email,department,position,phone,start_date
jsmith,John,Smith,[email protected],IT,Senior Developer,555-0101,2024-01-15
mdoe,Mary,Doe,[email protected],HR,HR Manager,555-0102,2024-01-15
rjohnson,Robert,Johnson,[email protected],FINANCE,Financial Analyst,555-0103,2024-01-16
swilliams,Susan,Williams,[email protected],SALES,Sales Representative,555-0104,2024-01-16
dbrown,David,Brown,[email protected],IT,DevOps Engineer,555-0105,2024-01-17
ljones,Lisa,Jones,[email protected],HR,Recruiter,555-0106,2024-01-17
mgarcia,Michael,Garcia,[email protected],SALES,Sales Manager,555-0107,2024-01-18
krodriguez,Karen,Rodriguez,[email protected],FINANCE,Controller,555-0108,2024-01-18
twilson,Thomas,Wilson,[email protected],EXEC,VP Engineering,555-0109,2024-01-19
amartinez,Anna,Martinez,[email protected],IT,Security Specialist,555-0110,2024-01-19
Demostración y Casos de Uso
# Generar template CSV
$ ./enterprise_user_manager.sh generate-template > new_employees.csv
# Validar archivo antes de procesamiento
$ ./enterprise_user_manager.sh validate new_employees.csv
[SUCCESS] CSV válido: 10 usuarios encontrados
# Simulación de creación masiva (dry-run)
$ ./enterprise_user_manager.sh create-batch new_employees.csv --dry-run
[INFO] DRY-RUN: Crearía usuario jsmith (IT)
[INFO] DRY-RUN: Crearía usuario mdoe (HR)
...
# Procesamiento real
$ ./enterprise_user_manager.sh create-batch new_employees.csv
[SUCCESS] Usuario creado exitosamente: jsmith
[SUCCESS] Usuario creado exitosamente: mdoe
[SUCCESS] Procesamiento completado: 10/10 usuarios creados exitosamente
# Verificar usuarios creados
$ tail -10 /etc/passwd
jsmith:x:2001:2001:John Smith (IT):/home/jsmith:/bin/bash
mdoe:x:2002:2002:Mary Doe (HR):/home/mdoe:/bin/bash
...
Funcionalidades Implementadas
- ✅ Validación exhaustiva de datos CSV
- ✅ Creación masiva con configuración por departamento
- ✅ Generación automática de contraseñas seguras
- ✅ Configuración de grupos y permisos granulares
- ✅ Estructura de directorios personalizada
- ✅ Sistema completo de auditoría y logging
- ✅ Reportes detallados de procesamiento
- ✅ Modo dry-run para testing
Ejercicio Final Integrador
Implementa un sistema completo que incluya:
- Carga y validación de empleados desde CSV
- Configuración automática según organigrama empresarial
- Integración con sistema de directorio LDAP (opcional)
- Notificaciones automáticas por email/Slack
- Dashboard web para monitoreo (bonus)
- Sistema de backup y recuperación
Evaluación del Proyecto Final
Tu implementación será evaluada en:
- Funcionalidad (40%): Cumplimiento de todos los requisitos
- Seguridad (25%): Implementación de mejores prácticas
- Código (20%): Calidad, documentación y mantenibilidad
- Escalabilidad (15%): Capacidad de manejar grandes volúmenes