====== Resumen del Proyecto ====== Este documento resume malísimamente los pasos y desarrollos realizados hasta la fecha en el proyecto de monitoreo y registro de eventos para hosts y Backup Vaults. === 1. Creación de Tablas por Host/Backup Vault === * Se configuró la aplicación para que, al recibir datos, cree dinámicamente una tabla para cada host o Backup Vault si no existe. * Cada tabla individual almacena los siguientes campos: * `id`: INT, AUTO_INCREMENT, PRIMARY KEY * `creationtime`: `VARCHAR(255)` - Hora de creación en formato cadena. * `vmname`: `VARCHAR(255)` - Nombre de la VM o recurso. * `type`: `VARCHAR(255)` - Tipo de tarea. * `result`: `VARCHAR(255)` - Resultado de la tarea. * `detail`: `TEXT` - Detalles adicionales. ---- === 2. Implementación de Nuevas Columnas para Timestamps === * Se agregó una columna adicional `datetime` a las tablas por host. * Esta columna almacena el tiempo de creación (`creationtime`) en formato `DATETIME`, estandarizando las fechas para facilitar futuras consultas y análisis. * Se implementó un script para procesar y convertir los diferentes formatos de fecha/hora recibidos al formato `DATETIME`. ---- === 3. Autenticación en la API === * Se añadió un mecanismo básico de autenticación por token en el endpoint `/upload`. * Solo se permite la carga de datos si el token es válido. ====== Azure Backup Vault Monitoring API ====== This project consists of a Python Flask API that receives data from an Azure Automation Runbook about backup jobs in an Azure Backup Vault. The API processes this data and inserts it into a MariaDB database. ===== How It Works ===== 1. **Azure Automation Runbook**: - Connects to Azure using Managed Identity. - Retrieves the latest backup jobs from the specified Azure Backup Vault. - Sends this data as a JSON payload to the Flask API. 2. **Flask API**: - Receives the JSON payload from the Automation Runbook. - Parses the `hostname` and `restorePoints` from the JSON. - Inserts the backup job data into a dynamically created table in the MariaDB database. ===== Powershell Script ===== The Powershell script retrieves the backup jobs and sends them to the Flask API. Here is a simplified overview: # Login to Azure (Using Managed Identity) Connect-AzAccount -Identity # Get backup jobs from the last 24 hours $vault = Get-AzRecoveryServicesVault $backupJobs = Get-AzRecoveryServicesBackupJob -VaultId $vault.ID -From (Get-Date).AddDays(-1).ToUniversalTime() # Prepare the API request $uri = "https://api.facundoitest.space/upload" $headers = @{ "Content-Type" = "application/json" "Authorization" = "bXktbG9----LongAssBase64String----XN0cmluZw==" } # Create the JSON payload $backupJobsList = $backupJobs | ForEach-Object { [PSCustomObject]@{ "vmname" = $_.WorkloadName "creationtime" = $_.StartTime.ToString("o") "type" = $_.Operation "result" = $_.Status } } $body = @{ "hostname" = $vault.Name "restorePoints" = $backupJobsList } | ConvertTo-Json -Depth 4 # Send the JSON to the API $response = Invoke-WebRequest -Uri $uri -Method Post -Body $body -Headers $headers -SkipHeaderValidation ===== Python Flask API ===== The Python API processes the incoming JSON payload and stores the relevant data in MariaDB. Below is **an outline** of the core logic: from flask import Flask, request, jsonify import mysql.connector app = Flask(__name__) @app.route('/upload', methods=['POST']) def upload_data(): data = request.get_json() hostname = data.get('hostname') restore_points = data.get('restorePoints') conn = mysql.connector.connect(host='db_host', user='db_user', password='db_password', database='VeeamReports') cursor = conn.cursor() table_name = f"{hostname}_backups" create_table_query = f\"\"\" CREATE TABLE IF NOT EXISTS {table_name} ( id INT AUTO_INCREMENT PRIMARY KEY, vmname VARCHAR(255), creationtime DATETIME, type VARCHAR(255), result VARCHAR(255) ) \"\"\" cursor.execute(create_table_query) for restore_point in restore_points: vmname = restore_point.get('vmname') creationtime = restore_point.get('creationtime') type = restore_point.get('type') result = restore_point.get('result') insert_query = f\"\"\"INSERT INTO {table_name} (vmname, creationtime, type, result) VALUES (%s, %s, %s, %s)\"\"\" cursor.execute(insert_query, (vmname, creationtime, type, result)) conn.commit() cursor.close() conn.close() return jsonify({"status": "success"}), 200 This setup allows you to monitor your Azure Backup Vault and store backup job data for further analysis or reporting. ---- === 4. Filtrado de Eventos No Exitosos === * Se implementó una lógica para filtrar los eventos con resultados diferentes a 'Success'. * Estos eventos se almacenan en una tabla central llamada `unsuccessful_tasks`. * El objetivo de esta tabla es permitir la generación de reportes que muestren la frecuencia y distribución de fallos en los últimos 30 días. ====== Guardado de eventos no exitosos ====== === 1. Diseño de la Tabla `unsuccessful_tasks` === * **Columnas**: * `id`: INT, AUTO_INCREMENT, PRIMARY KEY * `creationtime`: `DATETIME` - Timestamp del evento. * `hostname`: `VARCHAR(255)` - El nombre del host o Backup Vault. * `vmname`: `VARCHAR(255)` - El nombre de la VM o recurso. * `type`: `VARCHAR(255)` - El tipo de tarea (e.g., Backup, Snapshot). * `result`: `VARCHAR(255)` - El resultado (e.g., Fail, Warn). * `detail`: `TEXT` - Detalles adicionales del evento. === 2. Proceso de Inserción de Datos === * **Filtrado de Eventos No Exitosos**: * Cada vez que se registre un evento en las tablas por host, la aplicación debe revisar el campo `result`. Si el valor no es 'Success' o el equivalente en Azure, se inserta un registro en `unsuccessful_tasks`. * **Job Automático de Monitoreo**: * Un script de Python podría ejecutarse cada 4 horas para: * Conectar a las tablas de cada host y revisar nuevos registros. * Filtrar los eventos no exitosos (`result != 'Success'`). * Insertar estos eventos en `unsuccessful_tasks`, eliminando cualquier duplicado que ya exista en esa tabla. * Mantener un historial de 30 días y eliminar registros más antiguos para mantener la tabla manejable. === 3. Consultas y Reportes === * **Reporte de Frecuencia de Fallos**: * Crear una consulta que filtre por `hostname` y/o `vmname` para contar cuántas veces se ha registrado un fallo o advertencia en los últimos X días. * Este reporte es útil para identificar patrones de fallos o problemas recurrentes. === 4. Mantenimiento === * **Limpieza Regular**: * Programar un job que elimine registros más antiguos de 30 días (o el período que se decida), para mantener la tabla `unsuccessful_tasks` ligera y rápida en sus consultas. ---- === 5. Desarrollo de Script de Monitoreo Automático === * Se diseñó un job en Python que se ejecuta cada 4 horas. * Este script realiza las siguientes tareas: * Filtrar eventos no exitosos de las tablas por host. * Insertar estos eventos en la tabla `unsuccessful_tasks`. * Eliminar registros duplicados o más antiguos de 30 días. ---- === 6. Optimización de Consultas y Mantenimiento === * Se establecieron planes para la limpieza regular de la tabla `unsuccessful_tasks` para mantener su eficiencia. * Además, se consideró la creación de reportes específicos para detectar patrones de fallos. ---- === 7. Próximos Pasos === * Integrar más controles de calidad y validación de datos. * Optimizar el rendimiento de la base de datos para manejar grandes volúmenes de eventos. * Expandir la lógica de filtrado para incluir otros tipos de eventos importantes. ---- ├── demoBackups │   ├── app.py │   ├── static │   │   └── styles.css │   └── templates │   ├── admin.html │   ├── client_status.html │   └── index.html