# Discovery Azure Health Events

# Introducción

El plugin **Azure Service Health Events** descubre los eventos de estado del servicio que afectan a las suscripciones de Azure accesibles para una aplicación registrada. Los eventos se agrupan por región impactada y se convierten en agentes y módulos de Pandora FMS.

El plugin permite:

- Consultar todas las suscripciones visibles para el Service Principal.
- Recuperar eventos de Azure Service Health mediante la API de Azure Resource Health.
- Agrupar los eventos por región impactada.
- Crear un agente por región o concentrar todos los módulos en un único agente.
- Aplicar filtros en Azure y filtros locales mediante expresiones regulares.
- Detectar eventos nuevos o actualizados entre ejecuciones.
- Mantener un registro JSONL de los eventos para búsquedas posteriores.
- Detectar regiones que dejan de aparecer en la consulta.

# Requisitos

- Pandora FMS con Discovery y capacidad para cargar el paquete `.disco`.
- Conectividad HTTPS desde el servidor de Pandora FMS hacia: 
    - `https://login.microsoftonline.com`
    - `https://management.azure.com`
- Una aplicación registrada en Microsoft Entra ID con Service Principal.
- Un secreto de cliente válido.
- Acceso de lectura a todas las suscripciones que se quieran monitorizar.
- Un grupo de agentes válido en la definición de la tarea Discovery. El grupo `All` no es válido.

# Configuración en Azure

En Microsoft Entra ID se debe crear una aplicación registrada y generar un secreto de cliente. Para configurar la tarea se necesitan:

- **Tenant ID**: identificador del tenant de Microsoft Entra ID.
- **Client ID**: identificador de la aplicación registrada.
- **Client secret**: valor del secreto creado para la aplicación.

El plugin utiliza OAuth 2.0 Client Credentials y solicita un token para el ámbito:

```text
https://management.azure.com/.default

```

# Permisos

La opción recomendada es asignar al Service Principal el rol **Reader** en cada suscripción que se quiera monitorizar. Como mínimo, una función personalizada debe permitir enumerar las suscripciones accesibles y leer los eventos de Service Health, incluyendo `Microsoft.ResourceHealth/events/read`.

Los detalles sensibles de algunos avisos de seguridad pueden estar ocultos para identidades sin permisos elevados. El plugin consulta el listado de eventos, pero no ejecuta la operación adicional `fetchEventDetails` para obtener contenido sensible.

# Configuración de la tarea Discovery

El asistente contiene cuatro pasos visibles.

### 1. Task definition

Se configuran los datos generales de la tarea Discovery:

- Nombre de la tarea.
- Grupo de agentes.
- Intervalo de ejecución.

Debe seleccionarse un grupo real de Pandora FMS. No se debe utilizar `All`, ya que el plugin rechaza identificadores de grupo vacíos o menores o iguales a cero.

### 2. Azure credentials

<table id="bkmrk-campo-obligatorio-de"><thead><tr><th>Campo</th><th>Obligatorio</th><th>Descripción</th></tr></thead><tbody><tr><td>**Tenant ID**</td><td>Sí</td><td>Tenant de Microsoft Entra ID.</td></tr><tr><td>**Client ID**</td><td>Sí</td><td>Identificador de la aplicación registrada.</td></tr><tr><td>**Client secret**</td><td>Sí</td><td>Secreto de la aplicación.</td></tr><tr><td>**API endpoint**</td><td>No</td><td>Vacío utiliza `https://management.azure.com`. Solo se modifica para nubes soberanas o entornos personalizados.</td></tr><tr><td>**Login endpoint**</td><td>No</td><td>Vacío utiliza `https://login.microsoftonline.com`. Solo se modifica para nubes soberanas o entornos personalizados.</td></tr></tbody></table>

### 3. Azure event query and filters

<table id="bkmrk-campo-valor-predeter"><thead><tr><th>Campo</th><th align="right">Valor predeterminado</th><th>Descripción</th></tr></thead><tbody><tr><td>**Event history in days**</td><td align="right">`15`</td><td>Periodo consultado, entre 1 y 365 días.</td></tr><tr><td>**Azure API filter**</td><td align="right">Vacío</td><td>Expresión enviada a Azure mediante `$filter`.</td></tr><tr><td>**Subscription allow regexp**</td><td align="right">Vacío</td><td>Expresiones aplicadas al ID y al nombre de la suscripción.</td></tr><tr><td>**Region allow regexp**</td><td align="right">Vacío</td><td>Regiones que puede aceptar el plugin.</td></tr><tr><td>**Service allow regexp**</td><td align="right">Vacío</td><td>Servicios impactados que puede aceptar el plugin.</td></tr><tr><td>**Event type allow regexp**</td><td align="right">Vacío</td><td>Tipos de evento permitidos.</td></tr><tr><td>**Status allow regexp**</td><td align="right">Vacío</td><td>Estados regionales o generales permitidos.</td></tr><tr><td>**Level allow regexp**</td><td align="right">Vacío</td><td>Niveles permitidos.</td></tr><tr><td>**Event search allow regexp**</td><td align="right">Vacío</td><td>Al menos una expresión debe coincidir con el texto completo del evento.</td></tr><tr><td>**Event search deny regexp**</td><td align="right">Vacío</td><td>Descarta los eventos que coincidan.</td></tr><tr><td>**First run events are new**</td><td align="right">Desactivado</td><td>Si se activa, todos los eventos de la primera ejecución se consideran nuevos.</td></tr></tbody></table>

### 4. Agents modules and execution

<table id="bkmrk-campo-valor-predeter-1"><thead><tr><th>Campo</th><th align="right">Valor predeterminado</th><th>Descripción</th></tr></thead><tbody><tr><td>**Create agent per impacted region**</td><td align="right">Activado</td><td>Crea un agente por cada región. Desactivado utiliza **Target agent**.</td></tr><tr><td>**Target agent**</td><td align="right">`Azure Service Health Events`</td><td>Agente único utilizado cuando no se crea un agente por región.</td></tr><tr><td>**Agent prefix**</td><td align="right">`Azure Service Health `</td><td>Prefijo de los agentes regionales.</td></tr><tr><td>**Module prefix**</td><td align="right">Vacío</td><td>Prefijo añadido al nombre final de los módulos.</td></tr><tr><td>**State modules**</td><td align="right">Activado</td><td>Crea el módulo `Connection`.</td></tr><tr><td>**Event count modules**</td><td align="right">Activado</td><td>Crea los cinco módulos de recuento.</td></tr><tr><td>**Event detail modules**</td><td align="right">Activado</td><td>Crea `Events` y `New events`.</td></tr><tr><td>**Maximum event detail length**</td><td align="right">`16000`</td><td>Máximo de caracteres de los módulos de detalle. El mínimo efectivo es 1000.</td></tr><tr><td>**Modules allow regexp**</td><td align="right">Vacío</td><td>Solo crea módulos cuyo nombre final coincida.</td></tr><tr><td>**Modules deny regexp**</td><td align="right">Vacío</td><td>Descarta módulos cuyo nombre final coincida.</td></tr><tr><td>**Write event log**</td><td align="right">Activado</td><td>Habilita el registro JSONL.</td></tr><tr><td>**Maximum event log size**</td><td align="right">`20`</td><td>Rota el log al alcanzar este tamaño.</td></tr><tr><td>**HTTP timeout**</td><td align="right">`30`</td><td>Tiempo máximo por petición. Cero o un valor negativo se convierte en 30 segundos.</td></tr><tr><td>**Maximum retries**</td><td align="right">`2`</td><td>Reintentos para HTTP 429 y errores temporales de Azure.</td></tr><tr><td>**Verify SSL certificates**</td><td align="right">Activado</td><td>Debe permanecer activo en producción.</td></tr><tr><td>**Proxy URL**</td><td align="right">Vacío</td><td>Proxy HTTP o HTTPS opcional.</td></tr><tr><td>**Mock Azure API URL**</td><td align="right">Vacío</td><td>Campo reservado para pruebas; debe permanecer vacío en producción.</td></tr></tbody></table>

# Filtros

### Filtro aplicado por Azure

**Azure API filter** se envía directamente a la API y reduce los eventos devueltos por Azure. La documentación oficial muestra expresiones sobre servicio y región, por ejemplo:

```text
service eq 'Virtual Machines' or region eq 'West US'

```

El plugin no valida ni modifica esta expresión. Una sintaxis no aceptada por Azure hará que la suscripción correspondiente devuelva un error.

### Filtros locales de eventos

Los demás filtros se aplican localmente después de descargar los eventos. Cada textarea acepta una expresión regular por línea:

```text
^West Europe$
^Spain Central$

```

Las expresiones no distinguen entre mayúsculas y minúsculas. Se ignoran las líneas vacías y las que comienzan por `#`.

Los filtros allow funcionan de esta forma:

- Si están vacíos, permiten todos los valores.
- Si contienen expresiones, al menos una debe coincidir.

El filtro **Event search allow regexp** busca sobre suscripción, tracking ID, título, resumen, estado, nivel, tipo, subtipo, servicio y región. **Event search deny regexp** busca sobre los mismos campos y tiene prioridad para descartar el evento.

### Filtros de módulos

Los filtros **Modules allow regexp** y **Modules deny regexp** se aplican al nombre final del módulo, después de añadir prefijos y, en modo de agente único, el nombre de la región.

Si un módulo coincide simultáneamente con allow y deny, prevalece deny.

Ejemplo para conservar únicamente conexión y contadores:

```text
Connection$|events count$

```

# Agentes y Módulos generados

### Un agente por región

Con **Create agent per impacted region** activado, el nombre se forma así:

```text
<Agent prefix><Impacted region>

```

Ejemplo:

```text
Azure Service Health West Europe

```

### Agente único

Con la opción desactivada, todos los módulos se asignan a **Target agent**. Para evitar colisiones, cada módulo incorpora la región:

```text
West Europe Events count
Spain Central Events count

```

Si también se configura **Module prefix**, este aparece antes de la región.

## Módulos generados

Todos los módulos se asignan al grupo de módulos `Azure Service Health Events`.

<table id="bkmrk-m%C3%B3dulo-tipo-m%C3%B3dulo-p"><thead><tr><th>Módulo</th><th>Tipo Módulo Pandora</th><th>Dato</th></tr></thead><tbody><tr><td>`Connection`</td><td>`generic_proc`</td><td>`1` si la región aparece en la consulta actual y `0` si ha desaparecido.</td></tr><tr><td>`Events count`</td><td>`generic_data`</td><td>Número de eventos únicos que afectan a la región.</td></tr><tr><td>`New events count`</td><td>`generic_data`</td><td>Número de eventos nuevos o actualizados desde la ejecución anterior.</td></tr><tr><td>`Active events count`</td><td>`generic_data`</td><td>Eventos con estado regional o general `Active`</td></tr><tr><td>`Critical events count`</td><td>`generic_data`</td><td>Eventos con nivel `Critical`</td></tr><tr><td>`Warning events count`</td><td>`generic_data`</td><td>Eventos con nivel `Warning`</td></tr><tr><td>`Events`</td><td>`generic_data_string`</td><td>Detalle de todos los eventos coincidentes.</td></tr><tr><td>`New events`</td><td>`generic_data_string`</td><td>Detalle de eventos nuevos o actualizados; devuelve el entero `0` cuando no existen novedades.</td></tr></tbody></table>

Los módulos de detalle incluyen, cuando están disponibles: título, tracking ID, suscripción, estado, nivel, tipo, subtipo, fechas, servicio, región y resumen. Si el texto supera el máximo configurado, se trunca y se indica que el contenido completo está disponible en el log JSONL.