302 lines
7.8 KiB
Bash
Executable File
302 lines
7.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Entrypoint script para Cisco MAC Monitor
|
|
# ========================================
|
|
|
|
set -e
|
|
|
|
# Colores para output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Función para logging
|
|
log() {
|
|
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" >&2
|
|
}
|
|
|
|
warn() {
|
|
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1"
|
|
}
|
|
|
|
success() {
|
|
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] SUCCESS:${NC} $1"
|
|
}
|
|
|
|
# Verificar archivo de configuración
|
|
check_config() {
|
|
if [[ ! -f "${CONFIG_FILE}" ]]; then
|
|
error "Archivo de configuración no encontrado: ${CONFIG_FILE}"
|
|
error "Asegúrese de montar el volumen /config con config.yaml"
|
|
exit 1
|
|
fi
|
|
|
|
log "Usando archivo de configuración: ${CONFIG_FILE}"
|
|
}
|
|
|
|
# Crear directorios necesarios
|
|
setup_directories() {
|
|
log "Configurando directorios..."
|
|
|
|
# Crear directorios si no existen
|
|
mkdir -p /logs /data /tmp
|
|
|
|
# Verificar permisos
|
|
if [[ ! -w /logs ]]; then
|
|
warn "Sin permisos de escritura en /logs, usando /tmp"
|
|
export LOG_DIR=/tmp
|
|
else
|
|
export LOG_DIR=/logs
|
|
fi
|
|
|
|
if [[ ! -w /data ]]; then
|
|
warn "Sin permisos de escritura en /data, usando /tmp"
|
|
export DATA_DIR=/tmp
|
|
else
|
|
export DATA_DIR=/data
|
|
fi
|
|
|
|
success "Directorios configurados correctamente"
|
|
}
|
|
|
|
# Validar conectividad de red
|
|
test_network() {
|
|
log "Verificando conectividad de red..."
|
|
|
|
# Verificar si podemos resolver DNS
|
|
if ! nslookup google.com > /dev/null 2>&1; then
|
|
warn "No se puede resolver DNS externo, verificando conectividad local..."
|
|
fi
|
|
|
|
# Extraer IPs de dispositivos del config para test básico
|
|
if command -v python3 > /dev/null 2>&1 && [[ -f "${CONFIG_FILE}" ]]; then
|
|
python3 -c "
|
|
import yaml
|
|
try:
|
|
with open('${CONFIG_FILE}', 'r') as f:
|
|
config = yaml.safe_load(f)
|
|
for device in config.get('devices', []):
|
|
ip = device.get('ip')
|
|
if ip:
|
|
print(f'Testing connectivity to {ip}...')
|
|
import subprocess
|
|
result = subprocess.run(['ping', '-c', '1', '-W', '3', ip],
|
|
capture_output=True, timeout=5)
|
|
if result.returncode == 0:
|
|
print(f'✓ {ip} reachable')
|
|
else:
|
|
print(f'✗ {ip} not reachable')
|
|
except Exception as e:
|
|
print(f'Error testing network connectivity: {e}')
|
|
"
|
|
fi
|
|
}
|
|
|
|
# Función para mostrar ayuda
|
|
show_help() {
|
|
cat << EOF
|
|
Cisco MAC Monitor - Contenedor Docker
|
|
|
|
USAGE:
|
|
docker run cisco-mac-monitor [COMMAND] [OPTIONS]
|
|
|
|
COMMANDS:
|
|
continuous Ejecutar monitorización continua (por defecto)
|
|
single-run Ejecutar una sola vez y salir
|
|
test-config Validar archivo de configuración
|
|
test-ssh Probar conexiones SSH a dispositivos
|
|
shell Abrir shell interactivo
|
|
help Mostrar esta ayuda
|
|
|
|
VARIABLES DE ENTORNO:
|
|
CONFIG_FILE Ruta al archivo de configuración (default: /config/config.yaml)
|
|
LOG_LEVEL Nivel de logging (default: INFO)
|
|
MONITORING_INTERVAL Intervalo de monitorización en minutos (default: 5)
|
|
|
|
VOLÚMENES:
|
|
/config Directorio de configuración (contiene config.yaml)
|
|
/logs Directorio de logs
|
|
/data Directorio de datos de salida
|
|
|
|
EJEMPLOS:
|
|
# Ejecutar monitorización continua
|
|
docker run -v /host/config:/config cisco-mac-monitor
|
|
|
|
# Ejecutar una sola vez
|
|
docker run -v /host/config:/config cisco-mac-monitor single-run
|
|
|
|
# Probar configuración
|
|
docker run -v /host/config:/config cisco-mac-monitor test-config
|
|
|
|
EOF
|
|
}
|
|
|
|
# Función para probar configuración
|
|
test_config() {
|
|
log "Validando configuración..."
|
|
|
|
if ! python3 -c "
|
|
import yaml
|
|
import sys
|
|
|
|
try:
|
|
with open('${CONFIG_FILE}', 'r') as f:
|
|
config = yaml.safe_load(f)
|
|
|
|
# Validar estructura básica
|
|
if 'devices' not in config:
|
|
print('ERROR: Sección devices no encontrada')
|
|
sys.exit(1)
|
|
|
|
if 'monitoring' not in config:
|
|
print('ERROR: Sección monitoring no encontrada')
|
|
sys.exit(1)
|
|
|
|
# Validar dispositivos
|
|
devices = config['devices']
|
|
if not devices:
|
|
print('ERROR: No hay dispositivos configurados')
|
|
sys.exit(1)
|
|
|
|
print(f'✓ Configuración válida: {len(devices)} dispositivos')
|
|
|
|
for i, device in enumerate(devices):
|
|
hostname = device.get('hostname', f'device-{i}')
|
|
ip = device.get('ip')
|
|
username = device.get('username')
|
|
|
|
if not ip:
|
|
print(f'ERROR: Device {hostname} sin IP')
|
|
sys.exit(1)
|
|
if not username:
|
|
print(f'ERROR: Device {hostname} sin username')
|
|
sys.exit(1)
|
|
|
|
print(f' - {hostname} ({ip})')
|
|
|
|
except Exception as e:
|
|
print(f'ERROR: {e}')
|
|
sys.exit(1)
|
|
"; then
|
|
error "Configuración inválida"
|
|
exit 1
|
|
fi
|
|
|
|
success "Configuración válida"
|
|
}
|
|
|
|
# Función para probar conexiones SSH
|
|
test_ssh() {
|
|
log "Probando conexiones SSH a dispositivos..."
|
|
|
|
python3 << EOF
|
|
import yaml
|
|
import paramiko
|
|
import sys
|
|
|
|
try:
|
|
with open('${CONFIG_FILE}', 'r') as f:
|
|
config = yaml.safe_load(f)
|
|
|
|
devices = config.get('devices', [])
|
|
success_count = 0
|
|
|
|
for device in devices:
|
|
hostname = device.get('hostname', 'unknown')
|
|
ip = device.get('ip')
|
|
username = device.get('username')
|
|
password = device.get('password')
|
|
port = device.get('port', 22)
|
|
|
|
print(f'Probando {hostname} ({ip})...', end=' ')
|
|
|
|
try:
|
|
ssh = paramiko.SSHClient()
|
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
ssh.connect(
|
|
hostname=ip,
|
|
port=port,
|
|
username=username,
|
|
password=password,
|
|
timeout=10,
|
|
look_for_keys=False,
|
|
allow_agent=False
|
|
)
|
|
ssh.close()
|
|
print('✓ CONECTADO')
|
|
success_count += 1
|
|
except Exception as e:
|
|
print(f'✗ ERROR: {e}')
|
|
|
|
print(f'\\nResultado: {success_count}/{len(devices)} dispositivos conectados')
|
|
|
|
if success_count == 0:
|
|
sys.exit(1)
|
|
|
|
except Exception as e:
|
|
print(f'ERROR: {e}')
|
|
sys.exit(1)
|
|
EOF
|
|
}
|
|
|
|
# Función principal
|
|
main() {
|
|
log "Iniciando Cisco MAC Monitor..."
|
|
|
|
# Configurar directorios
|
|
setup_directories
|
|
|
|
# Verificar configuración
|
|
check_config
|
|
|
|
# Procesar comando
|
|
COMMAND=${1:-continuous}
|
|
|
|
case "${COMMAND}" in
|
|
"continuous")
|
|
log "Modo: Monitorización continua"
|
|
test_config
|
|
warn "Iniciando monitorización continua - Presiona Ctrl+C para detener"
|
|
exec python3 /app/cisco_mac_monitor.py --config "${CONFIG_FILE}"
|
|
;;
|
|
"single-run")
|
|
log "Modo: Ejecución única"
|
|
test_config
|
|
exec python3 /app/cisco_mac_monitor.py --config "${CONFIG_FILE}" --single-run --output "${DATA_DIR}/cisco_mac_data.json"
|
|
;;
|
|
"test-config")
|
|
test_config
|
|
success "Configuración OK"
|
|
;;
|
|
"test-ssh")
|
|
test_config
|
|
test_ssh
|
|
;;
|
|
"test-network")
|
|
test_network
|
|
;;
|
|
"shell")
|
|
log "Abriendo shell interactivo..."
|
|
exec /bin/bash
|
|
;;
|
|
"help"|"--help"|"-h")
|
|
show_help
|
|
;;
|
|
*)
|
|
error "Comando desconocido: ${COMMAND}"
|
|
show_help
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Manejo de señales
|
|
trap 'log "Recibida señal de terminación, cerrando..."; exit 0' SIGTERM SIGINT
|
|
|
|
# Ejecutar función principal
|
|
main "$@" |