CreaRack-SL

Decisión: Cierre de Hallazgos BAJA/MEDIA del Audit sa4

Contexto

Auditoría Suprema sub-área 4 (monitoring/ITSM/alerting) identificó 36 hallazgos:

  • 8 ALTA (críticos — ja cerrados en PRs anteriores)
  • 13 MEDIA
  • 15 BAJA

Sesión 112 cierra los BAJA/MEDIA en un lote unificado.

Decisiones Técnicas

B1: Validación de risk_level

Problema: Políticas SLA/escalation con risk_level basura (ej. “FOOBAR”) nunca matchean un insight realmente existente → silenciosamente inerte.

Decisión:

  • Constante centralizada RISK_LEVELS = {"HIGH", "MEDIUM", "LOW"} en itsm_schemas.py
  • Validadores Pydantic en EscalationPolicyIn y KnownIssueIn
  • Endpoint update_sla_policy(risk_level) rechaza fuera de set → 400

B5: Honestidad en apply_runbook

Problema: El endpoint “aplica” runbook pero no lo ejecuta realmente. Docstring ambiguo; usage_count se incrementaba en re-asignaciones (inflaba ranking).

Decisión:

  • Docstring aclara: asigna, no ejecuta
  • Response añade campo assigned: True (junto a applied para compat)
  • usage_count solo se incrementa si es la PRIMERA vez asignado a este insight (re-asignar es idempotente)

B6: Body de create_from_insight

Problema: create_from_insight ignoraba description/risk_level del body; usaba solo los del insight.

Decisión: Aplicar campos del body si vienen, respetando entrada del usuario.

B10: SLA Lifecycle con resolved_by

Problema: AlertEvent.resolved_at se poblaba pero sin traza de quién lo hizo.

Decisión:

  • Nueva FK AlertEvent.resolved_by → User
  • resolve_alert endpoint puebla resolved_by con request.user (si autenticado)
  • Al resolver, también marca acknowledged si no lo estaba (ciclo SLA consistente)
  • Migración monitoring/0022

B15: Markdown a Prueba de Fences

Problema: Bloque de código con ``` en commands/output rompía el fence Markdown.

Decisión: Función _code_block() que calcula fence más larga que cualquier run de backticks en el contenido.

M5: Validación de Comandos en Runbooks

Problema: create/update_runbook guardaban comandos embebidos sin validar contra allowlist del vendor.

Decisión:

  • Función _validate_runbook_commands(steps, vendor) llama a validate_commands(cmds, vendor)
  • Rechaza runbook con comando peligroso → 400
  • Se aplica en create_runbook y update_runbook

B7/B11: Paginación en List Endpoints

Problema: Endpoints sin limit → potencial DoS o N+1 masivo.

Decisión:

  • list_alerts, get_active_alerts: limit/offset, cap 1000
  • list_runbooks, list_known_issues: limit/offset, cap 500

B12: N+1 en is_in_maintenance_window

Problema: Cargaba TODAS las ventanas activas, luego probaba M2M por cada una.

Decisión: Query única con Q(targets__isnull=True) | Q(targets=target).

B13: N+1 en check_escalations

Problema: Cada insight disparaba una query de políticas.

Decisión: Precarga TODAS las políticas de las orgs pendientes, groupware por (org_id, risk_level), acceso O(1).

Nota sobre B8/M4/M11

  • B8 (N+1 de evaluación de alertas): La parte cara (N+1 de save) ya se cerró en M10 (PR #70). El resto es inherente al diseño per-target del evaluador — refactor mayor deferido.
  • M4/M11 (tests de autorización): Cubiertos por suite test_monitoring_sa4_sa5.py.

Impacto

  • Correctness: Políticas malformadas ya no quedan silenciosamente inertes
  • Security: Runbooks no pueden ejecutar comandos peligrosos
  • Performance: -N+1 significativos en escalation y maintenance checks
  • Observability: resolved_by traza decisiones de cierre de alerts; usage ranking de runbooks más honesto
  • Safety: Reportes Markdown robustos ante contenido con backticks

Test Coverage

4 tests nuevos en test_monitoring_sa4_sa5.py:

  • B1: risk_level inválido → 400
  • M5: runbook con comando peligroso → 400
  • B10: resolve_alert puebla resolved_by + acknowledged
  • B5: apply_runbook idempotente en usage_count

Véase también

  • [[feature—monitoring—sa4-baja-cleanup]]
  • [[concept—monitoring—risk-stratification]]
  • [[concept—monitoring—escalation-workflow]]
  • [[entity—monitoring—service—escalation-policy-checker]]
  • [[entity—monitoring—service—sla-maintenance-window]]