Merge pull request #484 from jcastro/docs/review-monitor

docs: review Monitor documentation in all seven translations
This commit is contained in:
MacRimi
2026-10-18 18:18:57 +02:00
committed by GitHub
208 changed files with 43772 additions and 1936 deletions
+62 -62
View File
@@ -1,8 +1,8 @@
{
"meta": {
"title": "Autenticación del panel de Proxmox — 2FA, API Tokens, perfil de usuario, reverse proxy | ProxMenux Monitor",
"title": "Autenticación del panel de Proxmox — 2FA, tokens API, perfil de usuario, proxy inverso | ProxMenux Monitor",
"description": "Acceder y asegurar ProxMenux Monitor: flujo de proteger-tu-panel en el primer arranque, autenticación con contraseña con nombre visible + avatar, página de perfil, alta de TOTP 2FA, API tokens de larga duración para scripts, configuración HTTPS, snippets de reverse proxy para Nginx, Caddy y Traefik, el log de auditoría y el jail Fail2Ban opcional.",
"ogTitle": "Autenticación del panel de Proxmox — 2FA, API Tokens, reverse proxy",
"ogTitle": "Autenticación del panel de Proxmox — 2FA, tokens API, proxy inverso",
"ogDescription": "Asegura ProxMenux Monitor con contraseña + TOTP 2FA, API tokens de larga duración, HTTPS, snippets de reverse proxy y un jail Fail2Ban opcional.",
"twitterTitle": "Autenticación del panel de Proxmox | ProxMenux Monitor",
"twitterDescription": "Contraseña + TOTP 2FA, API tokens, HTTPS, snippets de Nginx/Caddy/Traefik y log de auditoría."
@@ -10,16 +10,16 @@
"header": {
"title": "Acceso y autenticación",
"description": "Cómo llegar al panel, el flujo de seguridad de primer arranque y cada capa que puede situarse entre un atacante y el host: contraseña + TOTP, sesiones JWT, API tokens de larga duración, HTTPS, reverse proxies, Secure Gateway y el jail Fail2Ban opcional.",
"section": "ProxMenux Monitor"
"section": "Monitor de ProxMenux"
},
"intro": {
"title": "La autenticación es opt-in",
"body": "En el primer arranque el panel muestra un único diálogo — <em>\"¿Proteger tu panel?\"</em> — con dos botones: <strong>Sí, configurar contraseña</strong> y <strong>No, continuar sin protección</strong>. Decir que no deja todos los endpoints de la API abiertos en el puerto TCP 8008 — aceptable en una LAN de laboratorio aislada, peligroso en cualquier otro escenario. La autenticación de dos factores (2FA) <strong>no</strong> forma parte de esta elección inicial; se configura más tarde desde <strong>la pestaña Security</strong> una vez que hay una contraseña."
"body": "Al abrir el panel por primera vez aparece un diálogo: <em>«¿Proteger el panel?»</em>, con los botones <strong>Sí, configurar contraseña</strong> y <strong>No, continuar sin protección</strong>. Al elegir que no, los endpoints de la API quedan abiertos en TCP 8008: puede servir en una LAN de laboratorio aislada, pero resulta peligroso en otros entornos. La autenticación de dos factores (2FA) <strong>no</strong> forma parte de esta primera elección; se configura después desde <strong>la pestaña Seguridad</strong>, una vez establecida la contraseña."
},
"reaching": {
"heading": "Cómo llegar al panel",
"intro": "ProxMenux Monitor escucha en <code>0.0.0.0:8008</code>. Hay tres formas habituales de llegar a él:",
"outro": "El acceso directo coincide con lo que la unidad systemd trae por defecto. Las secciones de reverse proxy y Secure Gateway a continuación cubren las otras dos. El Monitor respeta <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> y <code>X-Forwarded-Host</code> para que las URLs y CORS funcionen detrás de cualquiera de ellos sin configuración manual."
"outro": "El acceso directo corresponde a la unidad systemd predeterminada. El proxy inverso y Secure Gateway se describen más abajo. Para confiar en la IP de <code>X-Forwarded-For</code> se requiere PROXMENUX_TRUST_PROXY=1 y un proxy que controles. La presencia de <code>X-Forwarded-Proto</code> o <code>X-Forwarded-Host</code> no activa esa confianza. En los puertos 80/443 el frontend usa URL relativas <code>/api/*</code>; en cualquier otro puerto llama al puerto 8008 del mismo nombre de host."
},
"firstLaunch": {
"heading": "Flujo de primer arranque",
@@ -32,27 +32,27 @@
"rows": [
{
"button": "Sí, configurar contraseña",
"what": "Abre un formulario con el usuario + contraseña obligatorios y un <em>nombre visible</em> + <em>imagen de avatar</em> opcionales. Los guarda en <code>auth.json</code> con <code>enabled: true</code>. Devuelve un JWT así que quedas logueado inmediatamente. El formulario se documenta en detalle más abajo.",
"what": "Abre un formulario con nombre de usuario y contraseña obligatorios, más <em>nombre visible</em> e <em>imagen de avatar</em> opcionales. Activa la autenticación en <code>auth.json</code> con <code>enabled: true</code> y devuelve un JWT para iniciar sesión. Los campos opcionales del perfil se guardan mediante llamadas posteriores, como se explica abajo.",
"api": "POST /api/auth/setup"
},
{
"button": "No, continuar sin protección",
"what": "Marca <code>declined: true</code> en <code>auth.json</code>. Todos los endpoints de la API son accesibles públicamente hasta que cambies de idea desde Settings.",
"what": "Marca <code>declined: true</code> en <code>auth.json</code>. Los endpoints de la API permanecen abiertos hasta que actives la protección desde Ajustes.",
"api": "POST /api/auth/skip"
}
],
"twofaCalloutTitle": "El 2FA se configura después, no aquí",
"twofaCalloutBody": "El diálogo de primer arranque solo cubre la decisión de la contraseña. La <strong>autenticación de dos factores (TOTP)</strong> se configura después desde <strong>la pestaña Security</strong> una vez logueado con una contraseña. El walkthrough completo de TOTP está más abajo en esta página.",
"twofaCalloutBody": "El diálogo inicial solo decide la protección con contraseña. La <strong>autenticación de dos factores (TOTP)</strong> se configura después desde <strong>la pestaña Seguridad</strong>, una vez iniciada la sesión con contraseña. El procedimiento completo de TOTP se explica más abajo.",
"createTitle": "Crear el primer usuario",
"createIntro": "Pulsar <em>Sí, configurar contraseña</em> abre un único formulario que crea la cuenta y, opcionalmente, siembra el perfil del usuario de una sola vez para que el avatar aparezca en la cabecera nada más guardar. Los campos son:",
"createIntro": "Al pulsar <em>Sí, configurar contraseña</em>, un formulario crea la cuenta y permite completar el perfil para que el avatar aparezca en la cabecera al guardar. Los campos son:",
"headerField": "Campo",
"headerRequired": "Requerido",
"headerNotes": "Notas",
"fieldRows": [
{
"field": "Username",
"field": "Nombre de usuario",
"required": "Sí",
"notes": "El identificador de login. No se puede cambiar después desde la UI; editarlo requiere tocar <code>auth.json</code> directamente."
"notes": "Identificador de inicio de sesión. No se puede cambiar desde la interfaz; hay que editar <code>auth.json</code> directamente."
},
{
"field": "Contraseña",
@@ -62,7 +62,7 @@
{
"field": "Nombre visible",
"required": "No",
"notes": "Etiqueta amistosa que se muestra en el dropdown de la cabecera y en la página de perfil. Cae al username cuando está vacío. Se puede cambiar después desde <strong>Avatar → Ver perfil</strong>."
"notes": "Nombre que aparece en el menú de la cabecera y en el perfil. Si está vacío se usa el nombre de usuario. Puedes cambiarlo desde <strong>Avatar → Ver perfil</strong>."
},
{
"field": "Imagen de avatar",
@@ -71,11 +71,11 @@
}
],
"createImageAlt": "Formulario de creación de usuario con campos obligatorios Username + Contraseña y la sección opcional Nombre visible + subida de Avatar",
"createImageCaption": "El formulario de creación de usuario del primer arranque. El nombre visible y el avatar son opcionales — dejarlos vacíos crea la cuenta y cae a un círculo con una sola letra en la cabecera.",
"createImageCaption": "Formulario inicial de creación de usuario. El nombre visible y el avatar son opcionales; si los dejas vacíos, la cuenta se crea y la cabecera muestra un círculo con una letra.",
"saveCalloutTitle": "Un único guardado, tres llamadas a la API por dentro",
"saveCalloutBody": "El formulario envía primero <code>POST /api/auth/setup</code> (username + contraseña). Si tiene éxito usa el JWT recién emitido para hacer a continuación <code>PUT /api/auth/profile</code> (nombre visible) y <code>POST /api/auth/profile/avatar</code> (bytes del avatar) si esos campos se rellenaron. Los fallos en las llamadas de perfil no son fatales — la cuenta ya está creada y puedes terminar el perfil después desde la página dedicada.",
"avatarTitle": "Menú del avatar y página de perfil",
"avatarBody1": "Una vez configurada la autenticación, aparece un círculo de avatar en la parte superior derecha de cada página del panel junto al toggle de tema. Pulsarlo abre un pequeño dropdown con accesos directos a la página de perfil y a la pestaña Security, además de una acción <strong>Sign out</strong> — cerrar la sesión se puede hacer desde aquí o desde la pestaña Security, lo que esté más cerca de donde te encuentres.",
"avatarBody1": "Tras configurar la autenticación, aparece el avatar arriba a la derecha, junto al selector de tema. Su menú contiene accesos al perfil, a Seguridad y la acción <strong>Cerrar sesión</strong>. También puedes cerrar la sesión desde Seguridad.",
"avatarBody2": "La página de perfil en sí es una pequeña tarjeta con una vista previa del avatar, el username (solo lectura) y el nombre visible con un botón de edición en línea. Las subidas, reemplazos y eliminaciones de avatar son atómicas — el avatar de la cabecera se refresca automáticamente cuando cualquiera tiene éxito, así que no hay necesidad de recargar la página. El mismo conjunto de endpoints documentado en la siguiente sección lo usan tanto el formulario de creación de usuario como la página de perfil.",
"profileImageAlt": "Página de perfil con círculo de vista previa del avatar, botones Subir / Reemplazar / Eliminar, username de solo lectura y campo de nombre visible editable",
"profileImageCaption": "La página de perfil dedicada. El username es solo lectura; el nombre visible y el avatar se pueden editar desde aquí sin tocar la pestaña Security.",
@@ -88,7 +88,7 @@
},
{
"endpoint": "PUT /api/auth/profile",
"what": "Actualiza el nombre visible. Body: <code>'{' \"display_name\": \"...\" '}'</code>."
"what": "Actualiza el nombre visible. Cuerpo de la petición: <code>'{' \"display_name\": \"...\" '}'</code>."
},
{
"endpoint": "GET /api/auth/profile/avatar",
@@ -100,15 +100,15 @@
},
{
"endpoint": "DELETE /api/auth/profile/avatar",
"what": "Elimina el avatar. La cabecera cae al placeholder de inicial-sobre-círculo-coloreado."
"what": "Elimina el avatar. La cabecera vuelve a mostrar una inicial en un círculo de color."
}
],
"reversibleTitle": "Continuar sin protección es reversible — pero solo desde el host",
"reversibleBody": "Una vez que pulsas <em>No, continuar sin protección</em>, el diálogo de bienvenida ya no vuelve a aparecer. Puedes reactivar la autenticación desde <strong>la pestaña Security</strong> dentro del panel, o editando <code>/root/.config/proxmenux-monitor/auth.json</code> y quitando el flag <code>declined</code>, luego reiniciando el servicio."
"reversibleTitle": "Puedes activar la protección más adelante",
"reversibleBody": "Tras pulsar <em>No, continuar sin protección</em>, el diálogo inicial no vuelve a aparecer. Puedes activar la autenticación desde <strong>la pestaña Seguridad</strong> o editar <code>/root/.config/proxmenux-monitor/auth.json</code>, quitar el indicador <code>declined</code> y reiniciar el servicio."
},
"password": {
"heading": "Autenticación con contraseña",
"intro": "Tras Setup, cada llamada a la API (excepto los pocos endpoints públicos listados abajo) requiere un JWT en <code>Authorization: Bearer &lt;token&gt;</code>:",
"intro": "Tras configurar la protección, las llamadas protegidas requieren un JWT en <code>Authorization: Bearer &lt;token&gt;</code>:",
"items": [
"<strong>Token de sesión (login):</strong> expiración de 24 horas. Emitido por <code>POST /api/auth/login</code>.",
"<strong>API token (integraciones):</strong> expiración de 365 días. Emitido por <code>POST /api/auth/generate-api-token</code>. Documentado por separado en la siguiente sección."
@@ -118,16 +118,16 @@
"loginFlowTitle": "Flujo de login",
"twofaIntro": "Con 2FA activado, la misma llamada devuelve primero <code>requires_totp: true</code>. Reemite con el código de 6 dígitos:",
"publicTitle": "Endpoints públicos (sin token)",
"publicIntro": "Estos son los únicos endpoints que funcionan sin autenticación, incluso cuando auth está activado:",
"publicIntro": "El inicio de sesión, su estado, la configuración inicial y el endpoint ligero <code>/api/system-info</code> son públicos:",
"publicItems": [
"<code>/api/auth/login</code>, <code>/api/auth/status</code>, <code>/api/auth/setup</code> — el propio flujo de auth, por necesidad.",
"<code>/api/system-info</code> — snapshot ligero del sistema (hostname, uptime, <code>health.status</code>). El endpoint adecuado para probes externos (Uptime Kuma, health checks de balanceador, páginas de estado)."
"<code>/api/auth/login</code> y <code>/api/auth/status</code> son públicos. <code>/api/auth/setup</code> crea la cuenta inicial y rechaza sobrescribir credenciales existentes.",
"<code>/api/system-info</code> es un endpoint público de información básica del sistema, incluido <code>health.status</code>. No lleva el requisito de token. /api/auth/status también es público y sirve para comprobar disponibilidad."
],
"cryptoTitle": "Criptografía y almacenamiento",
"cryptoIntro": "ProxMenux Monitor es código abierto — nada de esto es secreto. Documentar el stack aquí de forma explícita es una decisión deliberada: los operadores que guardan credenciales en su host merecen saber cómo se protegen esas credenciales antes de decidir confiar en ellas. Los algoritmos de abajo son los mismos que usa el código en <code>scripts/auth_manager.py</code>; esta sección es un contrato, no una promesa de marketing.",
"headerAsset": "Activo",
"cryptoIntro": "ProxMenux Monitor es código abierto — nada de esto es secreto. Documentar el stack aquí de forma explícita es una decisión deliberada: los usuarios que guardan credenciales en su host merecen saber cómo se protegen esas credenciales antes de decidir confiar en ellas. Los algoritmos de abajo son los mismos que usa el código en <code>scripts/auth_manager.py</code>; esta sección es un contrato, no una promesa de marketing.",
"headerAsset": "Elemento",
"headerAlgo": "Algoritmo",
"headerWhere": "Dónde vive",
"headerWhere": "Ubicación",
"cryptoRows": [
{
"asset": "Contraseña",
@@ -146,7 +146,7 @@
},
{
"asset": "Secret TOTP de 2FA",
"algorithm": "TOTP estándar (RFC 6238) codificado en base32. Los códigos de backup se pregeneran, son de un solo uso, hasheados con el mismo esquema PBKDF2 que la contraseña.",
"algorithm": "TOTP estándar (RFC 6238), con secreto codificado en base32. Los ocho códigos de backup son de un solo uso y se almacenan como hashes SHA-256.",
"where": "<code>auth.json</code> → <code>totp_secret</code> + <code>backup_codes[]</code>"
},
{
@@ -158,9 +158,9 @@
"authJsonTitle": "auth.json — qué contiene y cómo se protege",
"authJsonBody": "Todo lo que ProxMenux Monitor necesita para autenticarte vive en un único archivo: <code>/root/.config/proxmenux-monitor/auth.json</code>, modo <code>0600</code>, propietario <code>root</code>. El archivo guarda <em>hashes</em> (PBKDF2) y <em>material de firma</em> (<code>jwt_secret</code>, <code>totp_secret</code>) — nunca una contraseña en texto plano. Trátalo como cualquier otro secreto de solo-root: si haces backup o replicas el host, cifra el destino y nunca lo subas a control de versiones.",
"rotateTitle": "Rotar jwt_secret invalida todos los JWTs existentes",
"rotateBody": "Si <code>auth.json</code> se regenera (borrado manual, reinstalación, restauración desde un backup con un secret distinto) el <code>jwt_secret</code> cambia y cada JWT previamente emitido — tanto sesiones interactivas como API tokens de larga duración — falla la verificación con \"Invalid or expired token\". La UI marca los API tokens afectados con un badge <strong>Invalid — regenerate</strong> para que el operador sepa que tiene que revocarlos y volver a emitirlos; Home Assistant / scripts / cualquier cliente externo necesita un token fresco después de eso.",
"rotateBody": "Si <code>auth.json</code> se regenera (borrado manual, reinstalación, restauración desde un backup con un secret distinto) el <code>jwt_secret</code> cambia y cada JWT previamente emitido — tanto sesiones interactivas como API tokens de larga duración — falla la verificación con \"Invalid or expired token\". La UI marca los API tokens afectados con un badge <strong>Invalid — regenerate</strong> para que el usuario sepa que tiene que revocarlos y volver a emitirlos; Home Assistant / scripts / cualquier cliente externo necesita un token fresco después de eso.",
"recoverTitle": "Recuperar una contraseña perdida",
"recoverIntro": "No hay un flujo online de \"olvidé mi contraseña\" — por diseño, ya que el panel corre en el propio host del operador y el camino de recuperación es acceso shell a ese host. ProxMenux trae un reset guiado dentro del menú de configuración para que no tengas que editar a mano <code>auth.json</code>:",
"recoverIntro": "No hay un flujo online de \"olvidé mi contraseña\" — por diseño, ya que el panel corre en el propio host del usuario y el camino de recuperación es acceso shell a ese host. ProxMenux trae un reset guiado dentro del menú de configuración para que no tengas que editar a mano <code>auth.json</code>:",
"survivesTitle": "Qué sobrevive al reset",
"survivesBody": "Solo el login interactivo se borra. El <code>jwt_secret</code> y los <code>api_tokens</code> registrados se preservan — así que Home Assistant y cualquier otro script que use un API token de larga duración siguen funcionando sin reconfiguración. Si quieres una pizarra totalmente limpia (también rotar el secret JWT), borra <code>auth.json</code> manualmente y reinicia el servicio. El siguiente arranque genera un secret fresco y todos los tokens viejos se vuelven inválidos.",
"physicalTitle": "Prerrequisito de acceso físico",
@@ -170,8 +170,8 @@
"heading": "Autenticación de dos factores (TOTP)",
"intro": "El 2FA añade un segundo factor encima de tu contraseña: un código de 6 dígitos que rota cada 30 segundos, generado en un móvil o gestor de contraseñas que controlas. Aunque alguien obtenga la contraseña, sigue sin poder entrar sin el código de tu dispositivo. ProxMenux Monitor implementa el protocolo estándar <strong>TOTP</strong> (RFC 6238), así que cualquier app autenticadora funciona.",
"pickTitle": "Elige una app autenticadora",
"pickIntro": "Si ya usas una para Google / GitHub / tu banco, esa funcionará — salta al walkthrough de setup. Si no, aquí tienes un repaso de opciones habituales. Todas son gratis; las diferencias son sobre todo en qué plataformas corren y cómo (o si) hacen backup de tus secrets.",
"headerApp": "App",
"pickIntro": "Si ya tienes una aplicación TOTP, puedes usarla aquí. La tabla recoge opciones habituales: algunas son gratuitas y otras requieren suscripción. También cambian las plataformas y los métodos de backup.",
"headerApp": "Aplicación",
"headerPlatforms": "Plataformas",
"headerAppNotes": "Notas",
"apps": [
@@ -190,8 +190,8 @@
{
"name": "Authy",
"href": "https://authy.com/",
"platforms": "iOS, Android, escritorio",
"notes": "Sync cifrado multi-dispositivo (la app de escritorio se está retirando — comprueba el estado más reciente)."
"platforms": "iOS, Android",
"notes": "Sincronización cifrada entre dispositivos. La aplicación de escritorio dejó de recibir soporte el 19 de marzo de 2024."
},
{
"name": "Apple Passwords",
@@ -203,7 +203,7 @@
"name": "Bitwarden",
"href": "https://bitwarden.com/",
"platforms": "iOS, Android, escritorio, navegador",
"notes": "Código abierto. El TOTP vive junto a la contraseña que protege (cómodo si también usas BW para contraseñas; rompe el \"dispositivo separado\" si no)."
"notes": "Código abierto. Permite guardar TOTP junto a las contraseñas en la bóveda. Resulta cómodo, pero guardar ambos en ella no los separa en un segundo dispositivo."
},
{
"name": "1Password",
@@ -238,40 +238,40 @@
{
"name": "FreeOTP+",
"href": "https://github.com/helloworld1/FreeOTPPlus",
"platforms": "Android, iOS",
"notes": "Código abierto (impulsado por Red Hat). Mínimo — sin nube, sin cuenta."
"platforms": "Android",
"notes": "Bifurcación de código abierto de FreeOTP para Android, con importación y exportación. No requiere cuenta."
}
],
"backupTitle": "Para qué importa realmente el \"backup\"",
"backupBody": "Si pierdes el dispositivo que tiene el autenticador, las únicas formas de volver a entrar son (1) un código de backup guardado cuando activaste el 2FA, o (2) un backup de la bóveda del autenticador. Las apps con sync en la nube (Google Auth, Microsoft Auth, Authy, Apple Passwords, Ente, 2FAS, Bitwarden, 1Password) pueden restaurar en un dispositivo nuevo. Las apps sin nube (Aegis, Raivo, FreeOTP+) necesitan un archivo de exportación cifrado que hayas copiado a un sitio seguro. Cualquier enfoque funciona — el caso malo es \"sin backup en absoluto\".",
"backupBody": "Si pierdes el dispositivo autenticador, usa un código de backup guardado o restaura un backup de la app que hubieras configurado previamente. La sincronización en la nube y las exportaciones varían según la aplicación; comprueba que restauren los secretos TOTP. El acceso root al host también permite recuperar el acceso, como se explica abajo. Conserva un backup separado y seguro.",
"setupTitle": "Configuración paso a paso desde el panel",
"setupImageAlt": "Pantalla de configuración de 2FA con código QR y códigos de backup",
"setupImageCaption": "El diálogo de configuración de 2FA — código QR, secret en Base32 (para entrada manual) y los diez códigos de backup de un solo uso. Los códigos solo se muestran aquí; si cierras el diálogo sin copiarlos, se pierden.",
"setupImageCaption": "El diálogo de 2FA muestra un código QR, el secreto Base32 para introducirlo manualmente y, tras la verificación, ocho códigos de backup de un solo uso. Cópialos antes de cerrar; no volverán a mostrarse.",
"setupSteps": [
"<strong>Instala la app autenticadora en tu móvil</strong> (o abre tu gestor de contraseñas). Una de las apps de la tabla de arriba. Solo necesitas hacerlo una vez — la misma app guardará códigos para cada servicio que protejas.",
"<strong>Loguéate en el panel</strong> con tu usuario y contraseña.",
"<strong>Abre la pestaña Security</strong> en la barra lateral del panel, luego pulsa <strong>Enable 2FA</strong>. Se abre un diálogo con un código QR, una cadena larga en formato Base32 y diez códigos cortos etiquetados como \"códigos de backup\".",
"<strong>Abre la pestaña Seguridad</strong> en la barra lateral y pulsa <strong>Activar 2FA</strong> y <strong>Iniciar configuración</strong>. El diálogo muestra un QR y la clave manual; los ocho códigos de backup aparecen tras verificar el código.",
"<strong>Añade la entrada a la app autenticadora:</strong>",
"<strong>Guarda los códigos de backup.</strong> Copia los diez códigos a un sitio seguro — un gestor de contraseñas, una nota cifrada, una copia impresa en un cajón. Trátalos como llaves de repuesto: cada uno funciona exactamente una vez y te deja entrar si tu móvil se pierde o rompe.",
"<strong>Confirma escribiendo el código actual de 6 dígitos</strong> de la app en el campo \"Código de verificación\" del diálogo de setup y envía. Los códigos se refrescan cada 30 segundos, así que si caduca mientras escribes, simplemente introduce el siguiente.",
"<strong>Confirma escribiendo el código actual de 6 dígitos</strong> de la app en el campo \"Código de verificación\" del diálogo de configuración y envía. Los códigos se renuevan cada 30 segundos, así que si caduca mientras escribes, introduce el siguiente.",
"<strong>Guarda los códigos de backup.</strong> Tras la verificación, conserva los ocho en un gestor de contraseñas, nota cifrada o copia impresa segura. Cada uno funciona una vez si no tienes el autenticador.",
"<strong>Hecho.</strong> El 2FA está ahora activo. La próxima vez que te logues, el panel pide primero la contraseña; una vez aceptada pide el código actual de 6 dígitos."
],
"setupStep4Sub": [
"<em>Camino fácil:</em> en la app, pulsa <em>Añadir cuenta</em> → <em>Escanear código QR</em>, apunta la cámara al QR en la pantalla. La app nombra la entrada automáticamente (algo como <code>ProxMenux Monitor (your-username)</code>) y empieza a mostrar un código de 6 dígitos que se refresca cada 30 segundos.",
"<em>Plan B manual</em> (cuando escanear no es posible — p. ej. configurando en el mismo móvil con el que abriste el panel): pulsa <em>Añadir cuenta</em> → <em>Introducir clave de setup</em>. Escribe cualquier nombre (p. ej. <em>Proxmox Monitor</em>), pega la cadena Base32 del diálogo, deja <em>Tipo</em> como <em>Basado en tiempo</em>, guarda."
],
"testTitle": "Prueba antes de hacer logout",
"testBody": "Una vez que pulses Guardar, haz logout y vuelve a entrar <em>inmediatamente</em>, mientras el diálogo de setup esté todavía fresco en tu memoria. Si el código se rechaza (la causa más común es el desfase de reloj entre servidor y móvil), aún puedes arreglarlo desde la sesión abierta. Hacer logout sin probar primero significa un viaje de ida sin retorno — en ese punto solo un código de backup o editar <code>auth.json</code> en el host te deja volver a entrar.",
"testTitle": "Prueba antes de cerrar sesión",
"testBody": "Mantén la sesión actual abierta y prueba un nuevo acceso en una ventana privada <em>inmediatamente</em> después de configurar 2FA. Si el código falla, comprueba los relojes del servidor y del móvil antes de cerrar la sesión válida. Si ya perdiste el acceso, usa un código de backup o edita <code>auth.json</code> desde la consola del host.",
"lostTitle": "Autenticador perdido",
"lostIntro": "Tres salidas de emergencia, en orden de cuán disruptivas son:",
"lostItems": [
"<strong>Usa un código de backup.</strong> En la pantalla de login, en el campo TOTP, escribe uno de los diez códigos que guardaste durante el setup. Cada uno funciona una vez y luego se consume; los códigos restantes siguen funcionando. Una vez dentro, regenera el 2FA desde Settings para conseguir diez nuevos.",
"<strong>Usa un código de backup.</strong> Introduce uno de los ocho códigos guardados en el campo TOTP. Funciona una vez; los no usados siguen siendo válidos. Tras entrar, abre Seguridad, elige <strong>Desactivar 2FA</strong> y después <strong>Activar 2FA</strong> para obtener ocho códigos nuevos.",
"<strong>Restaura el autenticador desde la nube / backup.</strong> Si tu app tiene sync en la nube (Google, Microsoft, Authy, Apple Passwords vía iCloud Keychain, Ente, 2FAS) instálala en un dispositivo nuevo, loguéate y las entradas reaparecen. Si tu app usa un archivo de exportación cifrado (Aegis, Raivo, FreeOTP+), instala la app en el dispositivo nuevo e importa el archivo.",
"<strong>Desactiva el 2FA desde la shell del host.</strong> Cuando las opciones anteriores no están disponibles, edita <code>/root/.config/proxmenux-monitor/auth.json</code> en el host Proxmox (necesitas SSH root o acceso por consola), pon <code>totp_enabled</code> a <code>false</code>, guarda y reinicia el servicio:"
],
"lostShellOutro": "Puedes loguearte con usuario + contraseña solo, luego reactivar el 2FA desde Settings.",
"disableTitle": "Desactivar el 2FA",
"disableBody": "Desde el panel, abre la pestaña <strong>Security</strong> y pulsa <strong>Disable 2FA</strong>. El endpoint <code>POST /api/auth/totp/disable</code> requiere la contraseña actual como confirmación, luego elimina el secret TOTP y limpia los códigos de backup. Recuerda también quitar la entrada en la app autenticadora — la app no sabe que el lado del servidor ha desaparecido, así que la entrada muerta se quedaría ahí para siempre si no.",
"disableBody": "Abre <strong>Seguridad</strong> y elige <strong>Desactivar 2FA</strong>. <code>POST /api/auth/totp/disable</code> exige la contraseña actual y un código TOTP o de backup válido. Elimina el secreto TOTP y los códigos de backup. Elimina también la entrada antigua en la aplicación autenticadora.",
"rejectedTitle": "El código de 6 dígitos se rechaza siempre",
"rejectedIntro": "El TOTP está basado en tiempo — el reloj del servidor y el del móvil deben coincidir dentro de unos ~30 s. Dos comprobaciones:",
"rejectedItems": [
@@ -288,57 +288,57 @@
"generateTitle": "Generar un token",
"generateIntro": "Desde el panel:",
"generateSteps": [
"Navega a la sección <strong>pestaña Security → API Access Tokens</strong>.",
"Abre <strong>Seguridad → Tokens de acceso API</strong>.",
"Escribe un nombre descriptivo (<em>p. ej. \"Home Assistant\"</em>).",
"Vuelve a introducir tu contraseña. Si el 2FA está activado, también el código actual de 6 dígitos.",
"Pulsa <strong>Generate Token</strong>. El token aparece <strong>una vez</strong> — cópialo inmediatamente."
"Pulsa <strong>Generar token</strong>. Se muestra <strong>una sola vez</strong>: cópialo al momento."
],
"generateCli": "Desde la línea de comandos:",
"useTitle": "Usar un token",
"revokeTitle": "Revocar un token",
"revokeBody": "Desde el panel de arriba: cada fila tiene una acción <strong>Revoke</strong> que añade el hash del token a <code>revoked_tokens</code> en <code>auth.json</code>. Los tokens revocados fallan la validación inmediatamente en la siguiente petición.",
"revokeBody": "Cada fila ofrece <strong>Revocar</strong>, que añade el hash del token a <code>revoked_tokens</code> en <code>auth.json</code>. El token revocado falla la validación en la siguiente petición.",
"cheatTitle": "Chuleta de seguridad de tokens",
"cheatItems": [
"Guarda los tokens en el almacén de secrets nativo de tu integración — Homepage <code>secrets.yaml</code>, Home Assistant <code>!secret</code>, variables de entorno, etc. Nunca los subas a git.",
"Un token por integración, nombrado por el consumidor. Revoca individualmente al retirar una integración.",
"Rota cada 6-12 meses. La expiración es un límite duro, no una recomendación."
],
"outro": "Las mejores prácticas completas de almacenamiento y recetas de integración viven en <apiLink>API Reference → Token Management</apiLink> e <intLink>Integrations</intLink>."
"outro": "Consulta las recomendaciones de almacenamiento y los ejemplos en <apiLink>Referencia de la API → Gestión de tokens</apiLink> e <intLink>Integraciones</intLink>."
},
"https": {
"heading": "HTTPS",
"intro": "Dos rutas hacia TLS:",
"items": [
"<strong>Reverse proxy (recomendado).</strong> Termina TLS en Nginx / Caddy / Traefik y reenvía HTTP en el puerto 8008 al proceso Flask. Snippets más abajo.",
"<strong>HTTPS directo en el AppImage.</strong> Configura un certificado vía <code>POST /api/ssl/configure</code> (UI: <strong>Settings → SSL</strong>). Cuando SSL está configurado el proceso cambia del servidor dev de Flask a <code>gevent.pywsgi</code> con el handler gevent-websocket para que el terminal WebSocket también funcione sobre WSS. Los archivos del cert viven donde tú los pongas; las rutas se guardan en la configuración SSL."
"<strong>HTTPS directo en AppImage.</strong> Configura un certificado con <code>POST /api/ssl/configure</code> (interfaz: <strong>Ajustes → SSL</strong>). HTTPS usa <code>gevent.pywsgi</code> con su manejador estándar; flask-sock gestiona la conexión WebSocket para WSS. Las rutas de los certificados se guardan en la configuración SSL."
],
"calloutTitle": "Limitaciones del HTTPS directo",
"calloutBody": "La ruta gevent empaquetada es adecuada para certificados autofirmados o solo-LAN. Para Let's Encrypt / ACME y renovación automática, pon un reverse proxy real delante — Caddy autorrenueva y Traefik / Nginx tienen patrones bien conocidos. El Monitor no implementa ACME por sí mismo."
"calloutBody": "Monitor puede usar un certificado gestionado por Proxmox o archivos de certificados propios. No emite certificados ACME. Para emitirlos y renovarlos automáticamente, usa ACME de Proxmox o un proxy inverso como Caddy, Traefik o Nginx y asegúrate de cargar los certificados renovados."
},
"gateway": {
"heading": "Secure Gateway (Tailscale)",
"intro": "Los reverse proxies son la respuesta clásica a \"llegar al panel desde fuera\" pero requieren un dominio público, certificado y un puerto abierto en el borde. <strong>Secure Gateway</strong> es la alternativa cero-puertos que viene dentro del propio Monitor — una app desplegable preconstruida que levanta un LXC Alpine ejecutando <a>Tailscale</a> como subnet router. Una vez unido a tu tailnet, cada dispositivo en él puede llegar al Monitor en la propia IP LAN del host — desde un portátil de vacaciones, un móvil con 5G u otro nodo — sin exponer TCP 8008 a internet.",
"intro": "Un proxy inverso es una opción de acceso remoto. <strong>Secure Gateway</strong> permite acceder sin exponer TCP 8008: despliega un LXC Alpine con <a>Tailscale</a> como router de subred. El acceso a la IP LAN del host depende de las rutas aprobadas y de las reglas de acceso de la tailnet.",
"calloutTitle": "Por qué esto es cómodo",
"calloutBody": "La URL se mantiene igual que en la LAN — <code>http://&lt;proxmox-lan-ip&gt;:8008</code> funciona donde Tailscale funcione. Sin certificados, sin DNS, sin port forwarding. El propio Monitor ve la petición viniendo de una IP de tailnet (típicamente <code>100.x.y.z</code>), así que el log de auth y el hook de Fail2Ban siguen funcionando como en la LAN.",
"calloutBody": "Usa la URL LAN <code>http://&lt;proxmox-lan-ip&gt;:8008</code> mediante la ruta de subred aprobada. Tailscale usa SNAT por defecto, por lo que Monitor suele ver la IP LAN de la pasarela, no la dirección <code>100.x.y.z</code> del cliente. Los registros y Fail2Ban identifican la dirección de origen que recibe el host.",
"deployBody": "El flujo de despliegue es una sola pantalla — elige el storage LXC del host, pega un auth-key de Tailscale (generado en <a>login.tailscale.com/admin/settings/keys</a>), elige qué subnets anunciar, pulsa Deploy. El LXC tarda ~30 segundos en arrancar y se registra en el tailnet automáticamente.",
"outro": "El despliegue paso a paso, la configuración de subnet-routes, las ACLs de Tailscale y el modo Exit Node se documentan por separado en <link>Dashboard → Security → Secure Gateway</link> — ahí vive el wizard de despliegue en la UI del panel. Esta página solo cubre el patrón de acceso."
},
"proxy": {
"heading": "Snippets de reverse proxy",
"intro": "La distribución más simple es un <strong>nombre de host dedicado</strong> para el Monitor (p. ej. <code>monitor.example.com</code>) apuntando al puerto 8008 del host Proxmox. Los snippets de abajo usan ese patrón. Los montajes en sub-path (<code>example.com/proxmenux-monitor/</code>) son posibles pero requieren reescritura extra y no son el valor por defecto — mira el callout al final.",
"intro": "Usa un <strong>nombre de host dedicado</strong>, como <code>monitor.example.com</code>, que reenvíe al puerto 8008 del host Proxmox. Los ejemplos siguen ese patrón. Una subruta como <code>example.com/proxmenux-monitor/</code> requiere cambios adicionales en frontend y proxy; quitar el prefijo no basta.",
"nginxTitle": "Nginx",
"caddyTitle": "Caddy",
"traefikTitle": "Traefik (labels — Docker / Kubernetes)",
"traefikTitle": "Traefik (etiquetas: Docker / Kubernetes)",
"subPathTitle": "Avanzado: montajes en sub-path bajo un dominio existente",
"subPathBody": "Si no quieres un nombre de host dedicado, puedes montar el Monitor bajo un path de un dominio existente — por ejemplo <code>example.com/proxmenux-monitor/</code>. El build de Next.js usa rutas relativas para los assets así que los archivos estáticos resuelven, pero el proxy debe <strong>quitar el prefijo</strong> antes de reenviar para que el Monitor reciba URLs <code>/api/*</code> sin más. En Nginx eso es un <code>location /proxmenux-monitor/ &rbrace; proxy_pass http://127.0.0.1:8008/; &lbrace;</code> (la barra final en <code>proxy_pass</code> hace el strip). En Caddy, usa <code>handle_path /proxmenux-monitor/*</code>. Un nombre de host dedicado es más simple."
"subPathBody": "El frontend actual no tiene una base de subruta configurada y crea llamadas desde la raíz mediante URL <code>/api/*</code>. Quitar un prefijo como <code>example.com/proxmenux-monitor/</code> no resuelve esas llamadas ni todos los recursos de la interfaz. Usa un nombre de host dedicado. Una subruta exige cambios coordinados en frontend y proxy y pruebas específicas."
},
"audit": {
"heading": "Log de auditoría",
"intro": "Cada evento de autenticación (éxito y fallo) se añade a <code>/var/log/proxmenux-auth.log</code> en formato de una sola línea, estilo syslog:",
"intro": "Los fallos de inicio de sesión y los avisos del límite de intentos se escriben en <code>/var/log/proxmenux-auth.log</code>, con una línea por evento. Este logger no registra los accesos correctos:",
"outro": "Sigue la cola con el método habitual: <code>tail -F /var/log/proxmenux-auth.log</code>. El archivo se rota con <code>logrotate</code> si se añade un drop-in de configuración; el Monitor no lo rota por sí mismo."
},
"fail2ban": {
"heading": "Opcional: jail Fail2Ban",
"heading": "Opcional: jail de Fail2Ban",
"calloutTitle": "Fail2Ban no viene incluido con el Monitor",
"calloutBody": "Fail2Ban <strong>no</strong> lo instala ProxMenux Monitor por sí mismo. Instálalo vía <link>Seguridad → Fail2Ban</link> en el menú de ProxMenux (o con el paquete estándar de Debian). Sin él, el Monitor sigue escribiendo el log de auditoría de arriba — simplemente no banea automáticamente a los repetidores.",
"intro": "Cuando Fail2Ban está instalado, la integración de ProxMenux trae un jail <code>[proxmenux]</code> que:",
@@ -346,7 +346,7 @@
"Lee <code>/var/log/proxmenux-auth.log</code>.",
"Hace match con el patrón <code>authentication failure; rhost=&lt;ip&gt;</code> con un filtro dedicado.",
"Banea la IP infractora a nivel del firewall del kernel por defecto.",
"Se consulta desde el hook <code>before_request</code> de Flask cada 30 s — así que incluso cuando el firewall no puede bloquear (porque la conexión viene del reverse proxy), la aplicación devuelve HTTP 403 a las IPs baneadas según lo que Fail2Ban sabe."
"El hook <code>before_request</code> de Flask contrasta las peticiones con la lista de bloqueos, almacenada en caché durante 30 s. Tras un proxy inverso, el bloqueo por IP requiere también PROXMENUX_TRUST_PROXY=1 y un proxy controlado que establezca cabeceras fiables."
],
"outro": "La configuración, el ajuste del tiempo de ban y los procedimientos de desbaneo están en <link>Seguridad → Fail2Ban</link>."
},
@@ -367,17 +367,17 @@
"heading": "Por dónde seguir",
"items": [
{
"label": "API Reference → Token Management",
"label": "Referencia de la API → Gestión de tokens",
"href": "/docs/monitor/api",
"tail": " — ciclo de vida completo de API tokens (generar / listar / revocar), mejores prácticas de seguridad, patrones de almacenamiento de secrets."
},
{
"label": "Integrations",
"label": "Integraciones",
"href": "/docs/monitor/integrations",
"tail": " — Homepage, Home Assistant, Grafana / Prometheus, Uptime Kuma, cURL genérico."
},
{
"label": "Dashboard → Security → Secure Gateway",
"label": "Dashboard → Seguridad → Secure Gateway",
"href": "/docs/monitor/dashboard/security",
"tail": " — despliega el LXC gateway Tailscale paso a paso (subnet routes, ACLs, modo Exit Node)."
},
@@ -387,7 +387,7 @@
"tail": " — cómo instalar y configurar el jail opcional."
},
{
"label": "Settings → ProxMenux Monitor",
"label": "Ajustes → ProxMenux Monitor",
"href": "/docs/settings/proxmenux-monitor",
"tail": " — arranca / para el servicio systemd desde la TUI de ProxMenux."
}
+47 -47
View File
@@ -1,7 +1,7 @@
{
"meta": {
"title": "Asistente de IA de Proxmox — OpenAI, Claude, Gemini, Groq, Ollama | ProxMenux Monitor",
"description": "El Asistente de IA opcional de ProxMenux Monitor reescribe los cuerpos de las notificaciones de Proxmox VE en lenguaje natural. Seis proveedores soportados: OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter y Ollama local. Doce idiomas, tres niveles de detalle por canal, modo de prompt personalizado con una biblioteca comunitaria y una capa de enriquecimiento de contexto que añade uptime, recurrencia y datos SMART a los eventos de disco.",
"description": "El asistente de IA opcional reescribe las notificaciones de Proxmox VE en lenguaje claro. Seis proveedores: OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter y Ollama. La interfaz ofrece trece idiomas, tres niveles de detalle por canal, prompts personalizados con una biblioteca comunitaria y contexto del evento con tiempo de actividad, recurrencia y datos SMART.",
"ogTitle": "Asistente de IA de Proxmox — OpenAI, Claude, Gemini, Groq, Ollama",
"ogDescription": "Reescribe las notificaciones de Proxmox VE en lenguaje natural con OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter u Ollama local.",
"twitterTitle": "Asistente de IA de Proxmox | ProxMenux Monitor",
@@ -9,16 +9,16 @@
},
"header": {
"title": "Asistente de IA",
"description": "El reescritor opt-in que pasa cada notificación saliente por un LLM antes del fan-out — convirtiendo templates estructuradas en mensajes en lenguaje natural, con niveles de detalle por canal, doce idiomas, un modo de prompt personalizado con una biblioteca comunitaria pública y una capa de enriquecimiento de contexto que añade uptime, recurrencia, datos SMART y coincidencias con errores conocidos al prompt.",
"section": "ProxMenux Monitor"
"description": "La reescritura opcional con IA convierte las plantillas de notificación admitidas en mensajes claros, con detalle por canal, trece idiomas en la interfaz, prompts personalizados, una biblioteca comunitaria pública y contexto adicional. Los informes <code>backup_complete</code> y <code>backup_fail</code> omiten la IA por completo.",
"section": "Monitor de ProxMenux"
},
"intro": {
"title": "Desactivado por defecto, un solo interruptor para activarlo",
"body": "La reescritura con IA es opt-in. Hasta que pulses el toggle maestro dentro de <em>Settings → Notifications → Advanced: AI Enhancement</em>, cada evento se despacha con el cuerpo templated original. Cuando el toggle está activado y una llamada al proveedor falla o caduca, el dispatcher cae silenciosamente al cuerpo templated — tus notificaciones nunca se bloquean por el LLM."
"body": "La reescritura con IA viene desactivada. Actívala en <em>Ajustes → Notificaciones → Avanzado: mejora con IA</em>. Si falla el enriquecimiento o la reescritura, se envía la plantilla original. Las reescrituras de la cola de eventos tienen un tiempo límite de 25 segundos; al alcanzarlo se envía la plantilla en lugar de esperar."
},
"howItWorks": {
"heading": "Cómo funciona",
"intro": "Cada evento que despacha el Monitor pasa por la misma pipeline. El reescritor de IA es una etapa opcional que se sitúa entre el cuerpo templated y el envío del canal. De principio a fin, un solo evento camina por cuatro pasos:",
"intro": "Los eventos enviados por Monitor siguen el mismo proceso. La reescritura con IA es una etapa opcional entre el texto generado por la plantilla y el envío al canal. Un evento pasa por cuatro pasos:",
"steps": [
"<strong>Evento + template.</strong> Un evento llega desde uno de los seis colectores y se renderiza en un cuerpo estructurado de texto plano por <code>notification_templates.py</code>. Este es el cuerpo que el canal enviaría si la reescritura con IA estuviese desactivada.",
"<strong>Enriquecimiento de contexto.</strong> El dispatcher inspecciona el evento y añade condicionalmente las señales extra relevantes — uptime del sistema (solo para fallos críticos del sistema), frecuencia del evento, datos SMART (solo para eventos de disco), coincidencias con la base de datos de errores conocidos y líneas de log del journal.",
@@ -83,7 +83,7 @@
"intro1": "Cada proveedor comercial cobra por <em>token</em>, así que merece la pena entender qué es un token antes de elegir un plan. Un token son aproximadamente cuatro caracteres de texto en inglés o unas tres cuartas partes de una palabra. La frase <em>\"Backup completed on storage local-bak\"</em> son unos ocho tokens. Un extracto corto de journal de diez líneas puede ser 200-400 tokens según la densidad técnica.",
"intro2": "Se facturan dos cosas en cada llamada:",
"items": [
"<strong>Tokens de entrada</strong> — el system prompt más el user message (severidad, título, cuerpo, contexto enriquecido). Para ProxMenux el system prompt solo es del orden de 1.5-2 KB (≈ 400-500 tokens) y el user message varía de 50 tokens (un backup-complete limpio) a ~1500 tokens (un error de disco con 30 líneas de contexto del journal).",
"<strong>Tokens de entrada</strong>: incluyen las instrucciones del sistema y el mensaje de usuario: severidad, título, texto de la plantilla y contexto adicional. La cantidad depende del prompt y del evento. Cada canal reescrito puede consumir sus propios tokens de entrada; los informes de backup completado y fallido omiten la IA.",
"<strong>Tokens de salida</strong> — lo que el modelo escribe de vuelta. El Monitor lo limita con <code>max_tokens</code> (mira la tabla de abajo). El límite es un <em>tope</em>, no un cargo: si el modelo produce 250 tokens con un tope de 1500, pagas 250."
],
"capsIntro": "Estos son los topes reales que aplica el dispatcher, tomados directamente de <code>AI_DETAIL_TOKENS</code> en <code>notification_templates.py</code>:",
@@ -92,24 +92,24 @@
"headerConsumption": "Consumo real típico",
"capRows": [
{
"level": "brief",
"level": "breve",
"cap": "500",
"consumption": "50-200 tokens de salida para eventos cortos."
},
{
"level": "standard",
"level": "estándar",
"cap": "1500",
"consumption": "200-700 tokens de salida para eventos típicos con contexto ligero."
},
{
"level": "detailed",
"level": "detallado",
"cap": "3000",
"consumption": "500-2000 tokens de salida para reportes completos de email con logs y tablas SMART."
}
],
"customNote": "El modo de prompt personalizado usa un tope fijo de 500 tokens de salida independientemente del nivel de detalle — el prompt personalizado está bajo tu control y el tope protege contra respuestas descontroladas.",
"sizingTitle": "Dimensionamiento práctico",
"sizingBody": "Un homelab con 50-100 eventos al día en <code>standard</code> consume típicamente unos pocos miles de tokens al día. Con los niveles gratuitos que ofrecen Groq y Gemini, eso encaja sin tocar un plan de pago. Con OpenAI o Anthropic, facturados por token, el coste se queda en el rango de céntimos al mes para ese volumen. Si tu volumen de eventos es mucho mayor, la sección <link>Nivel de detalle por canal</link> explica cómo mantener los canales de chat en <code>brief</code> dejando que Email lleve el reporte completo."
"sizingBody": "Estima el consumo como eventos reescritos × canales con IA × tokens de entrada y salida por llamada. Por ejemplo: 50 eventos × un canal × (2.000 de entrada + 300 de salida) son unos 115.000 tokens al día, porque el prompt de sistema predeterminado ya ocupa unos 1.500 tokens. El consumo y coste reales dependen del modelo, contexto, caché y límites del proveedor. <link>Nivel de detalle por canal</link> explica cómo usar <code>brief</code> para chat en lugar de <code>standard</code>, manteniendo informes detallados por correo."
},
"providers": {
"heading": "Proveedores de IA",
@@ -120,18 +120,18 @@
"heading": "Groq",
"tagline": "Muy rápido, nivel gratuito generoso (30 req/min). Ideal para empezar.",
"items": [
"API key: <a>console.groq.com/keys</a>",
"Modelos verificados: <code>llama-3.3-70b-versatile</code>, <code>llama-3.1-70b-versatile</code>, <code>llama-3.1-8b-instant</code>, <code>llama3-70b-8192</code>, <code>llama3-8b-8192</code>, <code>mixtral-8x7b-32768</code>, <code>gemma2-9b-it</code>.",
"Recomendado: <strong><code>llama-3.3-70b-versatile</code></strong> — mejor calidad a la velocidad de inferencia completa de Groq."
"Clave API: <a>console.groq.com/keys</a>",
"Ejemplos de la lista de modelos incluida: <code>allam-2-7b</code>, <code>qwen/qwen3.8-27b</code>, <code>openai/gpt-oss-20b</code>, <code>groq/compound-mini</code>.",
"Recomendación incluida: <strong><code>openai/gpt-oss-20b</code></strong>. Comprueba su disponibilidad para tu cuenta con el selector del proveedor y la prueba de conexión."
]
},
"openai": {
"heading": "OpenAI",
"tagline": "Estándar de la industria. Muy preciso y ampliamente usado.",
"items": [
"API key: <a>platform.openai.com/api-keys</a>",
"Modelos verificados: <code>gpt-4.1-nano</code>, <code>gpt-4.1-mini</code>, <code>gpt-4o-mini</code>, <code>gpt-4.1</code>, <code>gpt-4o</code>, <code>gpt-5-chat-latest</code>, <code>gpt-5.4-nano</code>, <code>gpt-5.4-mini</code>.",
"Recomendado: <strong><code>gpt-4.1-nano</code></strong> — el miembro más barato de la familia chat, calidad suficiente para traducción y reformateo. Los modelos de razonamiento (serie o, gpt-5 non-chat) están soportados por el plumbing del proveedor pero se mantienen fuera de la lista verificada: mayor latencia sin ganancia medible de calidad en esta carga de trabajo."
"Clave API: <a>platform.openai.com/api-keys</a>",
"Ejemplos de la lista de modelos incluida: <code>gpt-4.1-nano</code>, <code>gpt-4.1-mini</code>, <code>gpt-4o-mini</code>, <code>gpt-4.1</code>, <code>gpt-4o</code>, <code>gpt-5-nano</code>.",
"Recomendación incluida: <strong><code>gpt-4.1-nano</code></strong>. El adaptador también gestiona requisitos específicos de los modelos de razonamiento; la lista incluye gpt-5-nano, por lo que no se excluyen todos esos modelos."
],
"baseUrlTitle": "Base URL compatible con OpenAI",
"baseUrlBody": "El proveedor OpenAI también acepta una <em>Base URL</em> personalizada, que te permite apuntar el Monitor a cualquier endpoint compatible con OpenAI. Confirmado que funciona con <strong>BytePlus / ByteDance (Kimi K2.5)</strong>, <strong>LocalAI</strong>, <strong>LM Studio</strong>, <strong>vLLM</strong>, <strong>Together AI</strong>, <strong>Fireworks AI</strong> y cualquier otro servicio que hable el dialecto OpenAI <code>/v1/chat/completions</code>. Configura la URL en la pestaña OpenAI junto al campo de API key."
@@ -140,17 +140,17 @@
"heading": "Anthropic (Claude)",
"tagline": "Excelente para escritura y traducción. Rápido y económico.",
"items": [
"API key: <a>console.anthropic.com/settings/keys</a>",
"Modelos verificados: <code>claude-3-5-haiku-latest</code>, <code>claude-3-5-sonnet-latest</code>, <code>claude-3-opus-latest</code>.",
"Recomendado: <strong><code>claude-3-5-haiku-latest</code></strong> — el modelo más pequeño y rápido de Claude, con calidad lingüística fuerte para la carga de traducción."
"Clave API: <a>console.anthropic.com/settings/keys</a>",
"Ejemplos de la lista de modelos incluida: <code>claude-haiku-4-5-20251001</code>, <code>claude-sonnet-4-6</code>, <code>claude-opus-4-6</code>.",
"Recomendación incluida: <strong><code>claude-haiku-4-5-20251001</code></strong>, una versión fija y no un alias que cambie."
]
},
"gemini": {
"heading": "Google Gemini",
"tagline": "Nivel gratuito disponible, gran ratio calidad/precio.",
"items": [
"API key: <a>aistudio.google.com/app/apikey</a>",
"Modelos verificados: <code>gemini-2.5-flash-lite</code>, <code>gemini-2.5-flash</code>, <code>gemini-3-flash-preview</code>.",
"Clave API: <a>aistudio.google.com/app/apikey</a>",
"Ejemplos de la lista de modelos incluida: <code>gemini-2.5-flash-lite</code>, <code>gemini-2.5-flash</code>, <code>gemini-3-flash-preview</code>.",
"Recomendado: <strong><code>gemini-2.5-flash-lite</code></strong> — flash y flash-lite pasan el verificador consistentemente. Las variantes pro rechazan el ajuste <code>thinkingBudget=0</code> que usa el Monitor y son excesivas para esta carga."
]
},
@@ -158,14 +158,14 @@
"heading": "OpenRouter",
"tagline": "Agregador con acceso a más de 100 modelos usando una única API key. Máxima flexibilidad.",
"items": [
"API key: <a>openrouter.ai/keys</a>",
"Modelos verificados: <code>meta-llama/llama-3.3-70b-instruct</code>, <code>meta-llama/llama-3.1-70b-instruct</code>, <code>meta-llama/llama-3.1-8b-instruct</code>, <code>anthropic/claude-3.5-haiku</code>, <code>anthropic/claude-3.5-sonnet</code>, <code>google/gemini-flash-1.5</code>, <code>openai/gpt-4o-mini</code>, <code>mistralai/mistral-7b-instruct</code>, <code>mistralai/mixtral-8x7b-instruct</code>.",
"Clave API: <a>openrouter.ai/keys</a>",
"Ejemplos de la lista de modelos incluida: <code>meta-llama/llama-3.3-70b-instruct</code>, <code>meta-llama/llama-3.1-70b-instruct</code>, <code>meta-llama/llama-3.1-8b-instruct</code>, <code>anthropic/claude-haiku-4.5</code>, <code>google/gemini-2.5-flash-lite</code>, <code>openai/gpt-4o-mini</code>, <code>mistralai/mistral-medium-3</code>.",
"Recomendado: <strong><code>meta-llama/llama-3.3-70b-instruct</code></strong> — mismo modelo que la entrada de Groq pero enrutado por OpenRouter, lo que significa una sola key para todos los modelos listados."
]
},
"ollama": {
"heading": "Ollama (Local)",
"tagline": "Usa los modelos disponibles en tu servidor Ollama. 100% local, sin costes, privacidad total.",
"heading": "Ollama (local)",
"tagline": "Usa los modelos expuestos por el servidor Ollama configurado. Los modelos locales se ejecutan allí; los modelos cloud de Ollama envían las peticiones a un proveedor externo. La ejecución local evita cargos de API alojada, pero utiliza tu hardware y electricidad.",
"items": [
"Sin API key. Configura el campo <em>Ollama URL</em> a tu servidor (por defecto <code>http://localhost:11434</code> o el host que ejecute tu instancia de Ollama).",
"Modelos: <strong>no filtrados.</strong> El Monitor lee los modelos que hayas descargado en el lado de Ollama vía <code>ollama pull &lt;model&gt;</code>. El dropdown se llena desde <code>GET /api/tags</code> en tu servidor Ollama.",
@@ -175,14 +175,14 @@
},
"models": {
"heading": "Por qué estos modelos en concreto",
"intro": "El dropdown de modelos para cada proveedor comercial se llena desde una lista curada que viene con el Monitor (<code>verified_ai_models.json</code>). Los modelos en esta lista se han probado de principio a fin con el formato de la API chat / completions que usa el Monitor, con la forma exacta <code>system_prompt + user_message + max_tokens</code> que envía el AI Enhancer. La lista se refresca antes de cada release de ProxMenux con una herramienta verificadora privada que prueba cada modelo candidato y poda los que se comportan mal.",
"intro": "Los modelos comerciales proceden del catálogo de compatibilidad incluido <code>verified_ai_models.json</code>, combinado con las comprobaciones del adaptador de cada proveedor. Los adaptadores convierten la petición interna <code>system_prompt + user_message + max_tokens</code> al formato de su API. El catálogo incluye entradas probadas y añadidos manuales; es una lista fechada, sin garantía de acceso actual ni de que todas las entradas hayan pasado el mismo verificador.",
"consequencesIntro": "Dos consecuencias que merece la pena conocer:",
"consequences": [
"<strong>El modelo recomendado</strong> para cada proveedor es el que tiene el mejor equilibrio de calidad, latencia y coste específicamente para traducción de notificaciones — no el modelo más capaz que vende el proveedor. Las reescrituras de notificaciones no necesitan razonamiento de modelo frontera; necesitan rapidez y bajo coste.",
"<strong>Aun así puedes elegir otro modelo verificado</strong> del dropdown — a veces tienes una cuota de nivel gratuito que quieres gastar en un modelo concreto, o tienes una preferencia fuerte. Elige cualquiera de las entradas listadas; todas han pasado el verificador."
"<strong>La recomendación incluida</strong> es un punto de partida para formatear notificaciones. Evalúa calidad lingüística, latencia y coste con tus eventos y tu cuenta; no es una clasificación universal de modelos.",
"<strong>Puedes elegir otro modelo de la lista</strong> según tu cuota o preferencias. Comprueba su disponibilidad con la prueba de conexión; aparecer en la lista no garantiza acceso actual para tu cuenta."
],
"ollamaTitle": "Ollama es la excepción",
"ollamaBody": "Los modelos de Ollama son locales y el Monitor no los filtra — el dropdown refleja lo que hayas descargado. Elige un modelo del rango 7B-13B con al menos una ventana de contexto de 8K para que la reescritura con IA se comporte razonablemente con los bloques de contexto de journal."
"ollamaBody": "La lista de Ollama no se filtra por el catálogo comercial; refleja los modelos del servidor Ollama. Para ejecución local, elige un modelo local que quepa en RAM y tenga contexto suficiente para los logs. Los modelos cloud son remotos aunque se acceda a ellos mediante un servidor Ollama local."
},
"defaultPrompt": {
"heading": "Prompt por defecto",
@@ -205,8 +205,8 @@
"changes": [
"<strong>El prompt por defecto se reemplaza por completo.</strong> Los mappings de Proxmox, las reglas de manejo de contexto y las instrucciones de emoji desaparecen todas. Si quieres conservar cualquiera de ellas, pégalas en tu prompt — el <code>EXAMPLE_CUSTOM_PROMPT</code> empaquetado mostrado abajo es un punto de partida.",
"<strong>El selector de Language se ignora.</strong> El prompt por defecto tiene un placeholder <code>'{'language'}'</code>; el prompt personalizado no. Si quieres salida en un idioma específico, declárala dentro de tu prompt (\"Translate to Spanish\", \"Output everything in French\").",
"<strong>El nivel de detalle sigue aplicando</strong> en el sentido de que está disponible como ajuste por canal, pero el tope de tokens de salida pasa a ser fijo de 500 en modo custom (vs la rampa 500 / 1500 / 3000 del prompt por defecto). Si tu prompt personalizado pide un reporte largo, sube el tope editando el prompt o divide la petición.",
"<strong>Los marcadores de Output Format siguen siendo obligatorios.</strong> El Monitor parsea la respuesta buscando <code>[TITLE]</code> y <code>[BODY]</code> en sus propias líneas. Un prompt personalizado que no emita esos marcadores romperá el parser y caerá al cuerpo templated original.",
"<strong>El tope del modo personalizado es fijo: 500 tokens</strong>, independientemente del detalle guardado por canal. El modo predeterminado usa 500 / 1500 / 3000. Editar el prompt no eleva el tope; pide una respuesta más breve o usa un nivel predeterminado adecuado.",
"<strong>Los marcadores de salida siguen siendo obligatorios.</strong> Incluye <code>[TITLE]</code> y <code>[BODY]</code> en el formato de respuesta. El analizador extrae su contenido; si falta uno, devuelve la plantilla original.",
"<strong>Las reglas de emoji de Rich messages no se autoinyectan.</strong> Si quieres emojis, dile al prompt que los use. Si quieres texto plano, dile que no. El toggle solo gatea los bloques empaquetados del prompt por defecto, no tu cadena personalizada."
],
"starterTitle": "Prompt inicial",
@@ -215,19 +215,19 @@
"shareTitle": "Compartir prompts con la comunidad",
"shareIntro": "El botón <em>Export</em> escribe tu prompt personalizado actual en un archivo (<code>.txt</code> / <code>.md</code>) que puedes guardar como backup o pasar a otra persona. <em>Import</em> lo trae de vuelta. El tercer botón al lado enlaza con una galería comunitaria pública en GitHub:",
"shareLinkLabel": "github.com/MacRimi/ProxMenux/discussions — Comparte prompts personalizados para notificaciones de IA",
"shareOutro": "Navega la discusión para ver qué han construido otros operadores — alertas escuetas tipo pager, reportes técnicos verbosos, variantes específicas por idioma. Si tuneas el tuyo y te gusta el resultado, publícalo allí: incluso una descripción de un párrafo de para qué optimiza tu prompt ayuda a la gente a elegir un buen punto de partida. El feedback sobre lo que funciona y lo que no es igualmente bienvenido."
"shareOutro": "Navega la discusión para ver qué han construido otros usuarios — alertas escuetas tipo pager, reportes técnicos verbosos, variantes específicas por idioma. Si tuneas el tuyo y te gusta el resultado, publícalo allí: incluso una descripción de un párrafo de para qué optimiza tu prompt ayuda a la gente a elegir un buen punto de partida. El feedback sobre lo que funciona y lo que no es igualmente bienvenido."
},
"suggestions": {
"heading": "AI Suggestions (BETA)",
"heading": "Sugerencias de IA (BETA)",
"intro": "AI Suggestions es un addon opt-in que deja al LLM añadir <strong>un</strong> consejo corto y accionable al final del cuerpo. Solo se activa cuando el modo de prompt es <em>Default</em>, el toggle maestro de IA está activado y el switch <em>AI Suggestions</em> está pulsado — e incluso entonces, el prompt instruye al modelo a saltarse el consejo cuando la causa o solución no esté clara.",
"formatIntro": "Cuando se añade un consejo, sigue este formato exacto:",
"rulesIntro": "Las reglas integradas en el addon (visibles en el bloque colapsable bajo la sección Default prompt de arriba):",
"rules": [
"El consejo se incluye <em>solo</em> si el contexto del journal o la base de datos de errores conocidos apunta claramente a una solución específica.",
"El consejo está limitado a 100 caracteres.",
"Debe ser específico (comando o ruta concretos) — los consejos genéricos los rechaza el propio prompt.",
"El prompt pide un consejo de menos de 100 caracteres; el analizador no comprueba ese límite por separado.",
"El prompt exige un comando o ruta concretos e indica al modelo que evite consejos genéricos.",
"Si un error conocido proporciona una solución, el LLM debe usar esa solución, no inventar una nueva.",
"Si nada en la entrada le da al LLM suficiente certeza para sugerir un arreglo concreto, el consejo se omite — sin adivinar."
"El prompt indica al modelo que omita el consejo si los datos no justifican una solución concreta."
],
"betaTitle": "Por qué BETA",
"betaBody": "La calidad del consejo depende de dos cosas fuera de ProxMenux: el modelo elegido y lo rico que era el contexto del journal para el evento. Con un modelo fuerte (Claude 3.5 Haiku, GPT-4.1 Mini, Llama 3.3 70B) y un error de disco que viene con smartctl + líneas de journal, el consejo es consistentemente útil. Con un modelo Ollama local pequeño y un evento de una línea, el consejo puede quedar pobre o saltarse por completo. Desactiva el toggle si encuentras los consejos ruidosos y reactívalo cuando lo quieras de vuelta."
@@ -241,19 +241,19 @@
"headerProduce": "Qué le pide el prompt al LLM que produzca",
"rows": [
{
"level": "brief",
"level": "breve",
"label": "2-3 líneas, solo esencial",
"cap": "500 tokens",
"produce": "\"Qué pasó + dónde\". Nada más."
},
{
"level": "standard",
"level": "estándar",
"label": "Conciso con contexto básico",
"cap": "1500 tokens",
"produce": "3-6 líneas: qué, dónde, causa, dispositivos afectados."
},
{
"level": "detailed",
"level": "detallado",
"label": "Detalles técnicos completos",
"cap": "3000 tokens",
"produce": "Reporte completo: qué, dónde, causa, afectados, logs, datos SMART, historial."
@@ -265,12 +265,12 @@
"<strong>Email</strong> — <code>detailed</code>. Email es el canal donde típicamente quieres la foto completa para archivo."
],
"emailTitle": "El nivel de detalle de Email añade el original",
"emailBody": "Cuando Email está en <code>detailed</code> y el cuerpo templated original tiene contenido sustancial (más de 50 caracteres), el dispatcher añade el mensaje original al final de la reescritura con IA, separado por un divisor de 40 guiones y una etiqueta <code>Original message:</code>. Esto significa que un email detallado siempre lleva tanto la versión amigable de IA como el template crudo amigable de máquina — útil cuando quieres hacer grep de una alerta antigua más tarde."
"emailBody": "Si el formateador devuelve un resultado para el correo en <code>detailed</code> y el texto original supera 50 caracteres, añade ese texto tras 40 guiones y la etiqueta <code>Original message:</code>. Así conserva los detalles para búsquedas posteriores. Cuando se omite la IA o falla, puede enviarse solo la plantilla original."
},
"language": {
"heading": "Idioma",
"intro": "Doce idiomas están cableados. El dropdown configura <code>ai_language</code> en la config y el valor se interpola en el system prompt en el sitio donde el prompt dice <em>\"translate alerts into '{'language'}'\"</em>. La lista completa:",
"list": "Inglés (<code>en</code>), Español (<code>es</code>), Francés (<code>fr</code>), Alemán (<code>de</code>), Portugués (<code>pt</code>), Italiano (<code>it</code>), Ruso (<code>ru</code>), Sueco (<code>sv</code>), Noruego (<code>no</code>), Japonés (<code>ja</code>), Chino (<code>zh</code>), Neerlandés (<code>nl</code>).",
"intro": "El selector de la interfaz ofrece trece idiomas. Guarda <code>ai_language</code>, que el prompt predeterminado usa en <em>\"translate alerts into '{'language'}'\"</em>. La lista es:",
"list": "Inglés (<code>en</code>), eslovaco (<code>sk</code>), español (<code>es</code>), francés (<code>fr</code>), alemán (<code>de</code>), portugués (<code>pt</code>), italiano (<code>it</code>), ruso (<code>ru</code>), sueco (<code>sv</code>), noruego (<code>no</code>), japonés (<code>ja</code>), chino (<code>zh</code>), neerlandés (<code>nl</code>).",
"rulesIntro": "Dos reglas importantes sacadas directamente del prompt:",
"rules": [
"<strong>Traducir</strong>: etiquetas, descripciones, palabras de estado, unidades (p. ej. GB → Go en francés).",
@@ -280,7 +280,7 @@
},
"templates": {
"heading": "Una nota sobre templates",
"body1": "El cuerpo que recibe la IA no es data cruda de evento — es una template prerrenderizada. Cada tipo de evento (<code>backup_complete</code>, <code>vm_start</code>, <code>auth_fail</code>, <code>health_degraded</code>, etc.) tiene una template en <code>notification_templates.py</code> que sabe cómo formatear ese evento específico en un cuerpo estructurado de texto plano. La IA reescribe ese cuerpo, no reemplaza el paso de templating.",
"body1": "La IA recibe una plantilla ya generada, no datos de evento sin procesar. Tipos como <code>vm_start</code>, <code>auth_fail</code> y <code>health_degraded</code> tienen plantillas en <code>notification_templates.py</code>. La IA reescribe los textos admitidos; <code>backup_complete</code> y <code>backup_fail</code> conservan sus informes deterministas y omiten la IA.",
"body2": "Dos implicaciones prácticas: la IA nunca ve un hostname o VMID que tenga que inventar — esos campos los pone la template antes de la reescritura. Y si la IA está desactivada, el cuerpo templated es lo que se despacha directamente. La página de <link>Notifications</link> documenta la pipeline de despacho completa y es la referencia cruzada correcta para todo lo que le pasa a un evento antes de llegar a esta capa."
},
"privacy": {
@@ -291,11 +291,11 @@
"rows": [
{
"provider": "Ollama",
"destination": "Se queda en el host Ollama. Si Ollama corre en el mismo nodo Proxmox, nada sale de la red en absoluto."
"destination": "Los modelos locales se ejecutan en el host Ollama configurado. Si es el propio nodo Proxmox, sus peticiones permanecen allí. Los modelos cloud de Ollama envían las peticiones fuera del host, incluso mediante un servidor Ollama local."
},
{
"provider": "OpenAI",
"destination": "<code>api.openai.com</code> (o tu endpoint Base URL personalizado). Sujeto a la política de manejo de datos de OpenAI en el momento de la llamada."
"destination": "<code>api.openai.com</code> de forma predeterminada o la URL base personalizada. Se aplica la política de datos del operador real de ese endpoint."
},
{
"provider": "Anthropic",
@@ -315,13 +315,13 @@
}
],
"calloutTitle": "Si el contenido del evento no puede salir de la red",
"calloutBody": "Usa Ollama, o desactiva el reescritor de IA. No hay terreno intermedio — el dispatcher no intenta redactar hostnames o IPs antes de enviar; el prompt se construye a partir del payload real del evento tal como lo ve el Monitor."
"calloutBody": "Usa un endpoint alojado en tu red con un modelo local, como Ollama local o un servidor compatible con OpenAI, o desactiva la IA. Los modelos cloud de Ollama no mantienen el procesamiento local. El sistema no anonimiza nombres de host ni IP; crea el prompt con el contenido real del evento."
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{
"label": "Notifications",
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tail": " — la pipeline de despacho, canales, toggles por evento y la integración del webhook de PVE que rodea esta capa."
},
+122 -122
View File
@@ -1,48 +1,48 @@
{
"meta": {
"title": "API de Proxmox Monitor — Referencia de integración | ProxMenux",
"description": "Endpoints HTTP expuestos por ProxMenux Monitor para integraciones: Home Assistant, Homepage, Grafana, Prometheus, n8n y paneles propios. Exportación de datos en solo lectura más las operaciones de escritura seguras que necesitan las automatizaciones — control de VMs, disparo de backup, despacho de notificaciones, acknowledgement de alertas.",
"description": "Endpoints HTTP de ProxMenux Monitor para Home Assistant, Homepage, Grafana, Prometheus, n8n y paneles propios. Consulta el estado y ejecuta operaciones documentadas: control de VM, inicio de backups, notificaciones y confirmación de alertas.",
"ogTitle": "API de Proxmox Monitor — Referencia de integración",
"ogDescription": "Endpoints expuestos por ProxMenux Monitor para Home Assistant, Homepage, Grafana, Prometheus, n8n y paneles propios.",
"ogDescription": "Endpoints de ProxMenux Monitor para Home Assistant, Homepage, Grafana, Prometheus, n8n y paneles propios.",
"twitterTitle": "API de Proxmox Monitor | ProxMenux",
"twitterDescription": "Endpoints para Home Assistant, Homepage, Grafana, Prometheus, n8n y paneles propios."
},
"header": {
"title": "API Reference",
"description": "Los endpoints HTTP que usan los integradores para leer estado y disparar acciones seguras en ProxMenux Monitor — sensores de Home Assistant, tarjetas de Homepage, paneles de Grafana, scrapes de Prometheus, flujos de n8n y scripts propios. Cada categoría, más una lista completa de métricas Prometheus, con ejemplos en curl.",
"title": "Referencia de la API",
"description": "Endpoints HTTP para consultar el estado y ejecutar acciones documentadas en ProxMenux Monitor: sensores de Home Assistant, tarjetas de Homepage, paneles Grafana, recogida de Prometheus, flujos n8n y scripts propios. Incluye categorías, métricas exportadas y ejemplos curl.",
"section": "ProxMenux Monitor"
},
"intro": {
"title": "Para qué es esta página",
"body": "Esta página lista los endpoints que esperamos que usen las integraciones externas — exportación de datos en solo lectura para cada parte del Monitor, más el pequeño conjunto de operaciones de escritura que las automatizaciones necesitan legítimamente (disparar un backup, enviar una notificación personalizada, dar acknowledgement a una alerta). Toda la API corre desde el mismo proceso Flask que sirve la UI del panel en TCP <strong>8008</strong>; la dirección de bind y TLS se configuran en <link>Access & Authentication</link>."
"body": "Esta página reúne endpoints para integraciones externas: datos de lectura y operaciones como iniciar backups, enviar avisos y confirmar alertas. La API usa el mismo proceso Flask que sirve el panel en TCP <strong>8008</strong>. La dirección de escucha y TLS se explican en <link>Acceso y autenticación</link>."
},
"headerEndpoint": "Endpoint",
"headerMethod": "Método",
"headerUse": "Uso",
"auth": {
"heading": "Autenticación",
"intro": "Cada endpoint marcado como \"authenticated\" espera un token bearer JWT en la cabecera de la petición:",
"intro": "Con la autenticación activada, los endpoints protegidos esperan un JWT Bearer en la cabecera de la petición:",
"tokensIntro": "Dos formas de obtener el token:",
"items": [
"<strong>API tokens (recomendado para integraciones).</strong> Tokens de larga duración emitidos desde <strong>Settings → Security → API Tokens</strong> en el panel. Cada token tiene un nombre, se puede revocar individualmente y es lo que deberías pasar a Home Assistant / Homepage / Grafana / n8n.",
"<strong>Flujo de login (JWT de corta duración).</strong> <code>POST /api/auth/login</code> con un username, password y token TOTP si el 2FA está activado. El JWT devuelto es de corta duración y el panel lo refresca automáticamente; útil para scripts ad-hoc que se autentican como un usuario humano."
"<strong>Tokens API, recomendados para integraciones.</strong> Valen 365 días y se crean en <strong>Seguridad → Tokens API</strong>. Tienen nombre y revocación individual. Usa read_only para datos y full_admin solo para acciones administrativas necesarias.",
"<strong>Inicio de sesión, JWT de 24 horas.</strong> <code>POST /api/auth/login</code> con usuario, contraseña y TOTP si lo exige 2FA. El JWT caduca a las 24 horas; los scripts deben volver a autenticarse después."
],
"flowLink": "El flujo de auth, la política de contraseñas, la configuración de 2FA, el log de auditoría y la configuración TLS viven todos en <link>Access & Authentication</link>.",
"flowLink": "El acceso, contraseñas, 2FA, auditoría y TLS se explican en <link>Acceso y autenticación</link>.",
"rows": [
{
"endpoint": "/api/auth/login",
"method": "POST",
"use": "Body: <code>'{'\"username\",\"password\",\"totp_token?\"'}'</code>. Devuelve un JWT de corta duración."
"use": "Campos del cuerpo (esquema): <code>'{'\"username\",\"password\",\"totp_token?\"'}'</code>. Devuelve un JWT de 24 horas."
},
{
"endpoint": "/api/auth/api-tokens",
"method": "GET",
"use": "Lista los API tokens (solo metadatos — nombres, prefijos, fechas; nunca el secret real)."
"use": "Lista los tokens API: nombres, prefijos y fechas; el valor secreto no se devuelve."
},
{
"endpoint": "/api/auth/api-tokens",
"endpoint": "/api/auth/generate-api-token",
"method": "POST",
"use": "Emite un nuevo API token de larga duración. Body: <code>'{'\"name\":\"'<'label'>'\"'}'</code>. El valor del token se devuelve una vez y no se puede recuperar de nuevo."
"use": "Crea un token API de 365 días con una sesión autenticada. Campos: <code>password, token_name?, totp_token?, scope?</code>. Se comprueban otra vez contraseña y TOTP requerido. scope usa read_only por defecto; full_admin se elige expresamente. El secreto se devuelve una sola vez."
},
{
"endpoint": "/api/auth/api-tokens/<id>",
@@ -54,10 +54,10 @@
"conventions": {
"heading": "Convenciones",
"items": [
"Todas las peticiones y respuestas son JSON salvo que se indique explícitamente (la descarga de logs es texto plano, <code>/api/prometheus</code> es text/plain en formato OpenMetrics, el log de tareas es texto plano).",
"Los endpoints que modifican estado con éxito devuelven <code>'{'\"success\": true, ...'}'</code>. Las respuestas de error usan un estado HTTP no-2xx con <code>'{'\"success\": false, \"error\": \"'<'reason'>'\"'}'</code>.",
"Los endpoints de listado aceptan <code>limit</code>, <code>offset</code>, <code>since</code> opcionales y filtros específicos por categoría vía query string.",
"Los campos de tiempo se devuelven como segundos epoch Unix o ISO-8601 con zona horaria explícita, nunca como cadenas de locale."
"La mayoría usa JSON. Algunas descargas son texto plano y <code>/api/prometheus</code> devuelve el formato de exposición de Prometheus 0.0.4, en vez de OpenMetrics. Comprueba el tipo de respuesta de cada ruta.",
"Muchas operaciones devuelven <code>'{'\"success\": true, ...'}'</code>. Los errores varían; una forma habitual es <code>'{'\"success\": false, \"error\": \"'<'reason'>'\"'}'</code>. Comprueba estado HTTP y campos: algunos retos de autenticación usan HTTP 200 con success false.",
"Los parámetros dependen del endpoint. Usa <code>limit</code>, <code>offset</code>, <code>since</code> y filtros por categoría solo si esa ruta los admite.",
"Los tiempos varían por endpoint: marcas Unix, cadenas ISO-8601 y fechas con formato systemd. No supongas una unidad común ni una zona horaria explícita en todos los campos."
]
},
"system": {
@@ -66,7 +66,7 @@
{
"endpoint": "/api/system",
"method": "GET",
"use": "CPU, memoria, swap, uptime, load — snapshot actual."
"use": "Valores actuales de CPU, memoria, swap, tiempo encendido y carga."
},
{
"endpoint": "/api/info",
@@ -76,93 +76,93 @@
{
"endpoint": "/api/system-info",
"method": "GET",
"use": "Snapshot extendido del sistema usado por la cabecera del panel (métricas globales + boot time)."
"use": "Datos ampliados usados por la cabecera del panel: métricas generales y hora de arranque."
},
{
"endpoint": "/api/hardware",
"method": "GET",
"use": "Inventario hardware detallado — dispositivos PCI, GPUs, mapa de sensores."
"use": "Inventario detallado de hardware: dispositivos PCI, GPU y sensores."
},
{
"endpoint": "/api/hardware/live",
"method": "GET",
"use": "Valores en vivo para sensores que cambian de segundo en segundo."
"use": "Valores actuales de sensores que cambian rápidamente."
},
{
"endpoint": "/api/temperature/history",
"method": "GET",
"use": "Serie temporal de temperaturas CPU / package."
"use": "Historial de temperaturas de CPU y encapsulado."
},
{
"endpoint": "/api/gpu/<slot>/realtime",
"method": "GET",
"use": "Métricas en vivo de GPU NVIDIA / Intel / AMD por slot PCI."
"use": "Métricas actuales de GPU NVIDIA, Intel y AMD por posición PCI."
}
]
},
"actions": {
"heading": "Acciones del sistema",
"intro": "Endpoints fire-and-forget que disparan las mismas operaciones que el usuario ejecutaría desde la interfaz del Monitor o desde el menú shell — pensados para Home Assistant, Homepage, Ansible, paneles personalizados y cualquier otra automatización que necesite alcanzar al host por HTTP. Toda ruta que muta el estado requiere un token con scope <code>full_admin</code>; los tokens <code>read_only</code> pueden consultar los endpoints <code>.../status</code> sin disparar nada. Cada acción devuelve 202 con una instantánea del estado; el cliente hace polling al <code>.../status</code> correspondiente para observar el progreso.",
"intro": "Estas acciones asíncronas se ejecutan en unidades systemd transitorias. Con autenticación activa, sus rutas de escritura exigen <code>full_admin</code>; <code>read_only</code> puede consultar <code>.../status</code>. El inicio aceptado devuelve HTTP 202 y estado; consulta <code>.../status</code> para el progreso. El control de invitados y los backups usan respuestas distintas, explicadas abajo.",
"shapeTitle": "Formato de respuesta común",
"shapeIntro": "Todos los endpoints de acción devuelven el mismo objeto JSON — una sola forma que parsear desde cualquier cliente:",
"shapeIntro": "Las acciones asíncronas del sistema comparten este objeto JSON de estado. El control de invitados y los backups tienen formatos distintos:",
"shapeCode": "{\n \"unit\": \"proxmenux-action-pve-update.service\",\n \"state\": \"idle | running | success | failed | cancelled\",\n \"started_at\": \"Sat 2026-08-01 11:01:32 CEST\",\n \"finished_at\": null,\n \"exit_code\": null,\n \"result\": null\n}",
"concurrencyTitle": "Concurrencia y cancelación",
"concurrencyBody": "Un segundo POST mientras una ejecución está en curso devuelve 409 con el estado actual. Cancela una ejecución en curso con un DELETE a la URL base de la acción; el estado pasa a <code>cancelled</code> y los timestamps se conservan para que el cliente vea cuándo se disparó y se detuvo. El último estado terminal (success / failed / cancelled) se recuerda hasta que la siguiente ejecución lo reemplace.",
"concurrencyBody": "Iniciar otra ejecución de la misma acción activa devuelve HTTP 409. Solo se cancela si hay una ruta DELETE documentada, como en la actualización PVE. Su estado pasa a <code>cancelled</code> y conserva fechas. Los estados finales se guardan en memoria del proceso y pueden perderse al reiniciar Monitor.",
"rows": [
{
"endpoint": "/api/system/power/reboot",
"method": "POST",
"use": "Reiniciar el host Proxmox. Fire-and-forget — la conexión HTTP cae cuando systemd inicia la secuencia de apagado."
"use": "Inicia el reinicio del host Proxmox. La conexión HTTP puede cerrarse cuando systemd comienza el apagado."
},
{
"endpoint": "/api/system/power/reboot/status",
"method": "GET",
"use": "Estado de la última / actual acción de reinicio."
"use": "Estado del reinicio actual o anterior."
},
{
"endpoint": "/api/system/power/shutdown",
"method": "POST",
"use": "Apagar el host Proxmox. Útil como efecto conectado a una señal de apagado del SAI."
"use": "Apaga el host Proxmox; puede conectarse a una señal de apagado del SAI."
},
{
"endpoint": "/api/system/power/shutdown/status",
"method": "GET",
"use": "Estado de la última / actual acción de apagado."
"use": "Estado del apagado actual o anterior."
},
{
"endpoint": "/api/system/pve-update/run",
"method": "POST",
"use": "Disparar el flujo seguro de actualización de PVE (el mismo que ejecuta el botón Update Now del Health Monitor y el menú shell — delega en update-pve-safe.sh)."
"use": "Inicia la actualización de PVE usada por Actualizar ahora de Health Monitor y el menú de consola; delega en update-pve-safe.sh."
},
{
"endpoint": "/api/system/pve-update/status",
"method": "GET",
"use": "Estado de la última / actual ejecución de actualización de PVE."
"use": "Estado de la actualización PVE actual o anterior."
},
{
"endpoint": "/api/system/pve-update",
"method": "DELETE",
"use": "Cancelar una actualización de PVE en curso (SIGTERM al script en ejecución)."
"use": "Cancela una actualización PVE en curso mediante SIGTERM al proceso."
},
{
"endpoint": "/api/proxmenux/self-update/run",
"method": "POST",
"use": "Actualizar el propio ProxMenux canalizando el instalador estable canónico. Corre en su propia unit systemd para que la actualización complete a pesar del reinicio de proxmenux-monitor que el instalador realiza."
"use": "Actualiza ProxMenux con el instalador del canal estable o beta configurado. Usa su propia unidad systemd para poder continuar durante el reinicio de proxmenux-monitor que realiza el instalador."
},
{
"endpoint": "/api/proxmenux/self-update/status",
"method": "GET",
"use": "Estado de la última / actual ejecución de self-update de ProxMenux."
"use": "Estado de la actualización de ProxMenux actual o anterior."
},
{
"endpoint": "/api/vms/<vmid>/control",
"method": "POST",
"use": "Encender / apagar / apagar limpio / reiniciar una VM o contenedor LXC (las mismas operaciones que expone la modal VM & LXC del Monitor). El cuerpo lleva <code>action</code>: <code>start</code>, <code>stop</code>, <code>shutdown</code> o <code>reboot</code>. Síncrono — devuelve el resultado directo sin necesidad de polling."
"use": "Envía una orden de control de VM o LXC. El campo <code>action</code> admite <code>start</code>, <code>stop</code>, <code>shutdown</code> o <code>reboot</code>. La respuesta correcta devuelve una tarea PVE confirmada, sin indicar que ya haya terminado. Consulta el endpoint control-task del invitado para obtener el resultado."
},
{
"endpoint": "/api/vms/<vmid>/backup",
"method": "POST",
"use": "Crear un backup vzdump de una VM o LXC. Campos del cuerpo, todos opcionales salvo cuando los valores por defecto no encajan con la distribución del almacenamiento: <code>storage</code> (un almacenamiento de PVE), <code>mode</code> (<code>snapshot</code>, <code>suspend</code> o <code>stop</code>), <code>compress</code> (<code>zstd</code>, <code>lzo</code>, <code>gz</code> o <code>none</code>), <code>protected</code> (<code>true</code> o <code>false</code>), <code>notes</code>, <code>notification</code> (<code>auto</code>, <code>always</code>, <code>failure</code> o <code>never</code>) y <code>pbs_change_detection</code> (<code>default</code>, <code>legacy</code> o <code>data</code>). Devuelve el UPID de la tarea PVE."
"use": "Crea un backup vzdump de una VM o LXC. Campos opcionales, ajustables según el almacenamiento: <code>storage</code> (destino PVE), <code>mode</code> (<code>snapshot</code>, <code>suspend</code> o <code>stop</code>), <code>compress</code> (<code>zstd</code>, <code>lzo</code>, <code>gzip</code> o <code>none</code>), <code>protected</code> (<code>true</code> o <code>false</code>), <code>notes</code> y <code>pbs_change_detection</code> (<code>default</code>, <code>legacy</code> o <code>data</code>). Devuelve el UPID de la tarea PVE."
},
{
"endpoint": "/api/vms/<vmid>/backups",
@@ -170,14 +170,14 @@
"use": "Listar backups anteriores de una VM o LXC en todos los storages accesibles."
}
],
"syncVsAsyncTitle": "Dos estilos de acción",
"syncVsAsyncBody": "Las acciones a nivel de sistema (power del host, PVE update, self-update de ProxMenux) pueden tardar minutos — corren en su propia unit systemd transitoria y exponen un endpoint <code>.../status</code> más un <code>DELETE</code> para cancelar. Las acciones VM / LXC (start, stop, shutdown, reboot, backup) son rápidas y usan el estilo fire-and-return que la UI del Monitor ya expone: el POST devuelve el resultado directo. Ambos estilos comparten el mismo modelo de autenticación (JWT o token de API de larga duración).",
"curlTitle": "Ejemplo con curl",
"curlBody": "Disparar una actualización de PVE y hacer polling hasta que termine — exactamente la misma secuencia que ejecutaría una automatización de Home Assistant o un playbook de Ansible:",
"syncVsAsyncTitle": "Dos tipos de acción",
"syncVsAsyncBody": "Encendido, apagado y actualizaciones del host usan unidades systemd transitorias con <code>.../status</code>. Solo la actualización PVE tiene aquí una ruta de cancelación <code>DELETE</code>. El control VM/LXC devuelve una tarea que debe consultarse; el backup devuelve un UPID de trabajo en segundo plano. Aceptar la petición no equivale a terminarla. Autenticación y permisos dependen de la ruta.",
"curlTitle": "Ejemplo curl",
"curlBody": "Inicia una actualización PVE y consulta hasta que termine: la secuencia que usaría una automatización Home Assistant o un playbook Ansible.",
"curlCode": "TOKEN=<your full_admin token>\n\ncurl -sSf -X POST \\\n -H \"Authorization: Bearer $TOKEN\" \\\n https://<host>:8008/api/system/pve-update/run\n\nwhile true; do\n state=$(curl -sSf -H \"Authorization: Bearer $TOKEN\" \\\n https://<host>:8008/api/system/pve-update/status | jq -r .state)\n [ \"$state\" != \"running\" ] && break\n sleep 30\ndone\necho \"final state: $state\"",
"haTitle": "Snippet de integración con Home Assistant",
"haBody": "Un sensor <code>rest</code> hace polling del estado y un <code>rest_command</code> dispara la actualización. Conecta ambos a un botón del dashboard y a las automatizaciones que quieras:",
"haCode": "# configuration.yaml\nsensor:\n - platform: rest\n resource: https://pve.local:8008/api/system/pve-update/status\n name: pve_update_state\n value_template: \"{{ value_json.state }}\"\n scan_interval: 60\n headers:\n Authorization: \"Bearer !secret proxmenux_token\"\n\nrest_command:\n pve_update:\n url: https://pve.local:8008/api/system/pve-update/run\n method: POST\n headers:\n Authorization: \"Bearer !secret proxmenux_token\"\n\n # Encender VM 100 (funciona igual para LXC — mismo endpoint)\n vm_100_start:\n url: https://pve.local:8008/api/vms/100/control\n method: POST\n content_type: 'application/json'\n payload: '{\"action\": \"start\"}'\n headers:\n Authorization: \"Bearer !secret proxmenux_token\"\n\n # Backup de la VM 100 al storage 'pbs-main'\n vm_100_backup:\n url: https://pve.local:8008/api/vms/100/backup\n method: POST\n content_type: 'application/json'\n payload: '{\"storage\": \"pbs-main\", \"mode\": \"snapshot\", \"compress\": \"zstd\"}'\n headers:\n Authorization: \"Bearer !secret proxmenux_token\""
"haTitle": "Ejemplo para Home Assistant",
"haBody": "Un sensor <code>rest</code> consulta el estado y <code>rest_command</code> inicia la actualización. Úsalos con un botón del panel y las automatizaciones que necesites:",
"haCode": "# configuration.yaml\nsensor:\n - platform: rest\n resource: https://pve.local:8008/api/system/pve-update/status\n name: pve_update_state\n value_template: \"{{ value_json.state }}\"\n scan_interval: 60\n headers:\n Authorization: \"Bearer !secret proxmenux_token\"\n\nrest_command:\n pve_update:\n url: https://pve.local:8008/api/system/pve-update/run\n method: POST\n headers:\n Authorization: \"Bearer !secret proxmenux_token\"\n\n # Start VM 100 (works for LXC too — same endpoint)\n vm_100_start:\n url: https://pve.local:8008/api/vms/100/control\n method: POST\n content_type: 'application/json'\n payload: '{\"action\": \"start\"}'\n headers:\n Authorization: \"Bearer !secret proxmenux_token\"\n\n # Backup VM 100 to the 'pbs-main' storage\n vm_100_backup:\n url: https://pve.local:8008/api/vms/100/backup\n method: POST\n content_type: 'application/json'\n payload: '{\"storage\": \"pbs-main\", \"mode\": \"snapshot\", \"compress\": \"zstd\"}'\n headers:\n Authorization: \"Bearer !secret proxmenux_token\""
},
"health": {
"heading": "Monitor de salud",
@@ -185,22 +185,22 @@
{
"endpoint": "/api/health",
"method": "GET",
"use": "Probe pequeño de salud — devuelve JSON con <code>status</code>, <code>timestamp</code>, <code>version</code>. Adecuado para keyword checks de Uptime Kuma; el receptor debe enviar la cabecera bearer."
"use": "Comprobación ligera que devuelve JSON con <code>status</code>, <code>timestamp</code> y <code>version</code>. Sirve para palabras clave de Uptime Kuma; con autenticación activa, el cliente debe enviar la cabecera Bearer."
},
{
"endpoint": "/api/health/status",
"method": "GET",
"use": "Veredicto global de salud — severidad única + cadena de resumen."
"use": "Estado global: un nivel de gravedad y un resumen."
},
{
"endpoint": "/api/health/details",
"method": "GET",
"use": "Las diez categorías con estados por categoría y el payload estructurado que produjo cada uno."
"use": "Las diez categorías con estado y datos estructurados de cada comprobación."
},
{
"endpoint": "/api/health/full",
"method": "GET",
"use": "Snapshot completo — categorías + errores activos + lista de dismissed + ajustes de supresión personalizados. Alimenta el modal en un round-trip; usa una caché de fondo de 6 min para respuesta instantánea."
"use": "Datos completos: categorías, errores activos, alertas descartadas y ajustes de silenciamiento. Usa resultados de fondo con menos de seis minutos; si no hay caché reciente o fuerzas la actualización, ejecuta una comprobación nueva."
},
{
"endpoint": "/api/health/active-errors",
@@ -210,12 +210,12 @@
{
"endpoint": "/api/health/dismissed",
"method": "GET",
"use": "Lista de dismissed con las horas de supresión restantes."
"use": "Alertas descartadas con horas de silencio restantes."
},
{
"endpoint": "/api/health/settings",
"method": "GET",
"use": "Valores de Suppression Duration por categoría configurados actualmente."
"use": "Duración de silenciamiento configurada para cada categoría."
},
{
"endpoint": "/api/health/remote-storages",
@@ -225,12 +225,12 @@
{
"endpoint": "/api/health/interfaces",
"method": "GET",
"use": "Inventario de interfaces de red con tipo (bridge / bond / physical), IP y velocidad de enlace."
"use": "Interfaces de red con tipo (bridge / bond / física), IP y velocidad del enlace."
},
{
"endpoint": "/api/health/acknowledge",
"method": "POST",
"use": "Body: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Descarta una alerta con la Suppression Duration configurada de la categoría."
"use": "Cuerpo: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Silencia una alerta durante el periodo configurado para su categoría."
},
{
"endpoint": "/api/health/cleanup-orphans",
@@ -238,7 +238,7 @@
"use": "Limpieza manual de errores cuyo dispositivo o VM subyacente ha desaparecido. Idempotente."
}
],
"outro": "Las formas de respuesta y la semántica de las categorías viven en <link>Monitor de salud</link>."
"outro": "Los formatos de respuesta y las categorías se explican en <link>Health Monitor</link>."
},
"storage": {
"heading": "Almacenamiento",
@@ -246,7 +246,7 @@
{
"endpoint": "/api/storage",
"method": "GET",
"use": "Todos los discos visibles al host (block devices, pools ZFS, LVM)."
"use": "Discos visibles para el host: dispositivos de bloques, pools ZFS y LVM."
},
{
"endpoint": "/api/storage/summary",
@@ -261,7 +261,7 @@
{
"endpoint": "/api/storage/observations",
"method": "GET",
"use": "Historial permanente de observaciones de disco — advertencias SMART, errores I/O, eventos de pool ZFS, conservados a través de auto-resoluciones de errores."
"use": "Historial persistente de observaciones: avisos SMART, errores de E/S y eventos ZFS. Se conserva aunque se resuelva la alerta."
},
{
"endpoint": "/api/storage/smart/<disk>",
@@ -286,7 +286,7 @@
{
"endpoint": "/api/storage/smart/<disk>/test",
"method": "POST",
"use": "Dispara un self-test SMART. Body: <code>'{'\"type\":\"short\"|\"long\"'}'</code>."
"use": "Inicia una prueba SMART. Esquema del cuerpo: <code>'{'\"test_type\":\"short\"|\"long\"'}'</code>."
},
{
"endpoint": "/api/storage/smart/schedules",
@@ -296,7 +296,7 @@
{
"endpoint": "/api/storage/smart/tools",
"method": "GET",
"use": "Detecta si <code>smartctl</code> y compañía están instalados."
"use": "Comprueba si están instalados <code>smartctl</code> y las herramientas asociadas."
}
]
},
@@ -316,12 +316,12 @@
{
"endpoint": "/api/network/<iface>/metrics",
"method": "GET",
"use": "RX / TX por interfaz, contadores de errores, serie temporal RRD."
"use": "RX/TX por interfaz, contadores de errores y series temporales RRD."
},
{
"endpoint": "/api/network/latency/current",
"method": "GET",
"use": "Último probe de latencia al gateway."
"use": "Última medición de latencia hasta la puerta de enlace."
},
{
"endpoint": "/api/network/latency/history",
@@ -336,7 +336,7 @@
{
"endpoint": "/api/vms",
"method": "GET",
"use": "Lista de todas las VMs y CTs con estado, vmid, nombre."
"use": "VM y CT del nodo local con estado, vmid y nombre."
},
{
"endpoint": "/api/vms/<vmid>",
@@ -351,22 +351,22 @@
{
"endpoint": "/api/vms/<vmid>/logs",
"method": "GET",
"use": "Logs de tareas recientes acotados a ese guest."
"use": "Registros de tareas recientes de ese invitado."
},
{
"endpoint": "/api/vms/<vmid>/backups",
"method": "GET",
"use": "Lista los backups actualmente conservados para este guest."
"use": "Backups conservados para este invitado."
},
{
"endpoint": "/api/vms/<vmid>/control",
"method": "POST",
"use": "Body: <code>'{'\"action\":\"start|stop|reboot|shutdown\"'}'</code>. Power-cycle de un guest."
"use": "Selecciona una acción del esquema: <code>'{'\"action\":\"start|stop|reboot|shutdown\"'}'</code>. Controla el estado de encendido del invitado."
},
{
"endpoint": "/api/vms/<vmid>/backup",
"method": "POST",
"use": "Dispara <code>vzdump</code> para ese guest. El body elige storage y modo (<code>snapshot</code> / <code>suspend</code> / <code>stop</code>)."
"use": "Inicia <code>vzdump</code> para el invitado. El cuerpo indica almacenamiento y modo (<code>snapshot</code> / <code>suspend</code> / <code>stop</code>)."
},
{
"endpoint": "/api/vms/<vmid>/config",
@@ -376,7 +376,7 @@
{
"endpoint": "/api/node/metrics",
"method": "GET",
"use": "Métricas agregadas a nivel de nodo (RRD)."
"use": "Métricas agregadas del nodo en series RRD."
}
]
},
@@ -386,12 +386,12 @@
{
"endpoint": "/api/backups",
"method": "GET",
"use": "Lista de backups a nivel de cluster."
"use": "Backups encontrados en almacenamientos dir, NFS, CIFS y PBS consultados desde el nodo local. No explora todos los nodos del clúster."
},
{
"endpoint": "/api/backup-storages",
"method": "GET",
"use": "Almacenamientos marcados como destinos de backup, con espacio libre."
"use": "Almacenamientos que admiten backups, con espacio libre."
}
]
},
@@ -406,7 +406,7 @@
{
"endpoint": "/api/logs/download",
"method": "GET",
"use": "Volcado en texto plano del rango filtrado."
"use": "Exporta el intervalo filtrado como texto plano."
},
{
"endpoint": "/api/events",
@@ -416,13 +416,13 @@
{
"endpoint": "/api/task-log/<upid>",
"method": "GET",
"use": "Log completo en texto plano para una tarea Proxmox por UPID."
"use": "Registro completo de una tarea Proxmox, en texto plano, identificado por UPID."
}
]
},
"notifications": {
"heading": "Notifications e IA",
"intro": "La pipeline de despacho, los walk-throughs de canales y la configuración del reescritor de IA viven en <notifLink>Notifications</notifLink> y <aiLink>Asistente de IA</aiLink>.",
"heading": "Notificaciones e IA",
"intro": "El envío, la configuración de canales y la reformulación con IA se explican en <notifLink>Notificaciones</notifLink> y <aiLink>Asistente de IA</aiLink>.",
"rows": [
{
"endpoint": "/api/notifications",
@@ -432,42 +432,42 @@
{
"endpoint": "/api/notifications/download",
"method": "GET",
"use": "Exporta notificaciones como texto."
"use": "Exporta las notificaciones como texto."
},
{
"endpoint": "/api/notifications/status",
"method": "GET",
"use": "Estado del dispatcher — si el hilo de fondo está corriendo, profundidad de cola, último envío."
"use": "Estado del envío: proceso de fondo activo, longitud de cola y último envío."
},
{
"endpoint": "/api/notifications/settings",
"method": "GET",
"use": "Lee la configuración completa de notificaciones (canales, toggles por evento, reescritor de IA, Display Name)."
"use": "Lee la configuración de notificaciones: canales, controles por evento, reformulación con IA y nombre visible."
},
{
"endpoint": "/api/notifications/history",
"method": "GET",
"use": "Historial de despacho. Query: <code>?limit=&offset=&severity=&channel=</code>."
"use": "Historial de envío. Parámetros: <code>?limit=&offset=&severity=&channel=</code>."
},
{
"endpoint": "/api/notifications/history",
"method": "DELETE",
"use": "Borra la tabla de historial de despacho."
"use": "Borra la tabla del historial de envío."
},
{
"endpoint": "/api/notifications/test",
"method": "POST",
"use": "Envía una notificación de prueba a un canal. Body: <code>'{'\"channel\":\"telegram\"'}'</code>."
"use": "Envía un aviso de prueba a un canal. Cuerpo: <code>'{'\"channel\":\"telegram\"'}'</code>."
},
{
"endpoint": "/api/notifications/send",
"method": "POST",
"use": "Emite un evento personalizado. Body: <code>'{'\"event_type\":\"custom\",\"severity\":\"WARNING\",\"title\":\"...\",\"body\":\"...\",\"data\":'{''}''}'</code>."
"use": "Emite un evento personalizado. Cuerpo: <code>'{'\"event_type\":\"custom\",\"severity\":\"WARNING\",\"title\":\"...\",\"body\":\"...\",\"data\":'{''}''}'</code>."
},
{
"endpoint": "/api/notifications/test-ai",
"method": "POST",
"use": "Prueba la conexión del proveedor de IA. Body: <code>'{'\"provider\",\"api_key\",\"model\",\"ollama_url?\"'}'</code>."
"use": "Prueba la conexión con el proveedor de IA. Campos del cuerpo (esquema): <code>'{'\"provider\",\"api_key\",\"model\",\"ollama_url?\"'}'</code>."
},
{
"endpoint": "/api/notifications/provider-models",
@@ -502,22 +502,22 @@
{
"endpoint": "/api/security/fail2ban/details",
"method": "GET",
"use": "Estado del jail Fail2Ban — solo útil cuando el jail opcional está instalado."
"use": "Estado del jail Fail2Ban; requiere tener instalado ese componente opcional."
},
{
"endpoint": "/api/security/fail2ban/activity",
"method": "GET",
"use": "Eventos recientes de Fail2Ban (bans, unbans, arranques de jail)."
"use": "Eventos recientes de Fail2Ban: bloqueos, desbloqueos y arranques del jail."
},
{
"endpoint": "/api/security/lynis/status",
"method": "GET",
"use": "Estado de última ejecución de Lynis (si está instalado, timestamp de último scan)."
"use": "Estado de Lynis: instalación y fecha del último análisis."
},
{
"endpoint": "/api/security/lynis/report",
"method": "GET",
"use": "Último reporte de auditoría Lynis (warnings, sugerencias, hardening index)."
"use": "Último informe Lynis: avisos, sugerencias e índice de refuerzo de seguridad."
},
{
"endpoint": "/api/security/tools",
@@ -532,7 +532,7 @@
{
"endpoint": "/api/proxmenux/update-status",
"method": "GET",
"use": "Si ProxMenux Monitor tiene actualización disponible, versión actual y última."
"use": "Disponibilidad de actualización de ProxMenux Monitor, versión instalada y más reciente."
},
{
"endpoint": "/api/proxmenux/installed-tools",
@@ -542,13 +542,13 @@
{
"endpoint": "/api/proxmenux/tool-source/<key>",
"method": "GET",
"use": "Código fuente de una función post-instalación específica — el bash exacto que se aplicó."
"use": "Código de la función posterior a la instalación asociada, extraído del script actual del host o de código antiguo conservado. No garantiza una copia del código exacto ejecutado originalmente."
}
]
},
"prometheus": {
"heading": "Métricas Prometheus",
"intro": "ProxMenux Monitor expone un endpoint de scrape formato Prometheus en <code>GET /api/prometheus</code> (autenticado) devolviendo texto formato OpenMetrics. Cada métrica está etiquetada con <code>node=\"&lt;hostname&gt;\"</code> y lleva un timestamp explícito para que ingese limpio en Prometheus, VictoriaMetrics, Mimir o cualquier TSDB compatible.",
"intro": "<code>GET /api/prometheus</code> con autenticación devuelve el formato de texto Prometheus 0.0.4. Cada métrica incluye <code>node=\"&lt;hostname&gt;\"</code> y una marca de tiempo explícita. Recógela con Prometheus u otra base temporal compatible.",
"exportedTitle": "Métricas exportadas",
"headerGroup": "Grupo",
"headerMetric": "Métrica",
@@ -559,7 +559,7 @@
"metrics": [
{
"metric": "proxmox_cpu_usage",
"desc": "Porcentaje de uso de CPU (gauge)."
"desc": "Porcentaje de uso de CPU, de tipo gauge."
},
{
"metric": "proxmox_memory_total_bytes",
@@ -567,7 +567,7 @@
},
{
"metric": "proxmox_memory_used_bytes",
"desc": "Memoria usada en bytes."
"desc": "Memoria utilizada en bytes."
},
{
"metric": "proxmox_memory_usage_percent",
@@ -575,16 +575,16 @@
},
{
"metric": "proxmox_load_average",
"desc": "Load average del sistema. Etiqueta <code>period=\"1m\" | \"5m\" | \"15m\"</code>."
"desc": "Carga media del sistema. Etiqueta <code>period=\"1m\" | \"5m\" | \"15m\"</code>."
}
]
},
{
"group": "Uptime",
"group": "Tiempo de actividad",
"metrics": [
{
"metric": "proxmox_uptime_seconds",
"desc": "Segundos desde el último boot."
"desc": "Segundos desde el último arranque."
}
]
},
@@ -593,15 +593,15 @@
"metrics": [
{
"metric": "proxmox_cpu_temperature_celsius",
"desc": "Temperatura del package de CPU."
"desc": "Temperatura del encapsulado de CPU."
},
{
"metric": "proxmox_disk_temperature_celsius",
"desc": "Temperatura por disco. Etiqueta <code>device</code>."
"desc": "Temperatura por disco. Etiqueta <code>disk</code>."
},
{
"metric": "proxmox_fan_speed_rpm",
"desc": "Velocidades de ventilador. Etiqueta <code>fan</code>."
"desc": "Velocidades de ventiladores. Etiqueta <code>fan</code>."
}
]
},
@@ -610,15 +610,15 @@
"metrics": [
{
"metric": "proxmox_disk_total_bytes",
"desc": "Espacio total de disco por mount. Etiqueta <code>mountpoint</code>."
"desc": "Capacidad total de cada entrada de disco exportada. Etiqueta <code>disk</code>."
},
{
"metric": "proxmox_disk_used_bytes",
"desc": "Espacio usado de disco por mount."
"desc": "Capacidad utilizada de cada entrada de disco exportada."
},
{
"metric": "proxmox_disk_usage_percent",
"desc": "Porcentaje de uso de disco por mount."
"desc": "Porcentaje utilizado de cada entrada de disco exportada."
}
]
},
@@ -627,11 +627,11 @@
"metrics": [
{
"metric": "proxmox_network_bytes_sent_total",
"desc": "Total de bytes enviados (counter)."
"desc": "Total de bytes enviados, de tipo counter."
},
{
"metric": "proxmox_network_bytes_received_total",
"desc": "Total de bytes recibidos (counter)."
"desc": "Total de bytes recibidos, de tipo counter."
},
{
"metric": "proxmox_interface_bytes_sent_total",
@@ -652,23 +652,23 @@
},
{
"metric": "proxmox_vms_running",
"desc": "Número de guests en ejecución."
"desc": "Número de invitados en ejecución."
},
{
"metric": "proxmox_vms_stopped",
"desc": "Número de guests parados."
"desc": "Número de invitados detenidos."
},
{
"metric": "proxmox_vm_status",
"desc": "Estado por VM/CT (1 = running, 0 = stopped). Etiquetas <code>vmid</code>, <code>name</code>, <code>type</code>."
"desc": "Estado por VM/CT: 1 en ejecución, 0 en otro estado. Etiquetas <code>node</code>, <code>vmid</code> y <code>name</code>."
},
{
"metric": "proxmox_vm_cpu_usage",
"desc": "Uso de CPU por VM/CT. Mismas etiquetas."
"desc": "Uso de CPU por VM/CT, con las mismas etiquetas."
},
{
"metric": "proxmox_vm_memory_used_bytes / _max_bytes",
"desc": "Memoria usada por VM/CT y máximo configurado."
"desc": "Memoria utilizada y máximo configurado por VM/CT."
}
]
},
@@ -677,7 +677,7 @@
"metrics": [
{
"metric": "proxmox_gpu_temperature_celsius",
"desc": "Temperatura de GPU. Etiquetas <code>slot</code>, <code>vendor</code>."
"desc": "Temperatura GPU. Etiquetas <code>slot</code> y <code>vendor</code>; también incluye el nombre de GPU en gpu."
},
{
"metric": "proxmox_gpu_utilization_percent",
@@ -685,19 +685,19 @@
},
{
"metric": "proxmox_gpu_memory_total_bytes",
"desc": "Total de memoria de GPU."
"desc": "Memoria total de la GPU."
},
{
"metric": "proxmox_gpu_power_draw_watts",
"desc": "Consumo de potencia de GPU en vatios."
"desc": "Consumo eléctrico de la GPU en vatios."
},
{
"metric": "proxmox_gpu_clock_speed_mhz",
"desc": "Velocidad de reloj del core de GPU."
"desc": "Frecuencia del núcleo de la GPU."
},
{
"metric": "proxmox_gpu_memory_clock_mhz",
"desc": "Velocidad de reloj de memoria de GPU."
"desc": "Frecuencia de la memoria de la GPU."
}
]
},
@@ -706,7 +706,7 @@
"metrics": [
{
"metric": "proxmox_ups_battery_charge_percent",
"desc": "Porcentaje de carga de batería."
"desc": "Porcentaje de carga de la batería."
},
{
"metric": "proxmox_ups_load_percent",
@@ -714,7 +714,7 @@
},
{
"metric": "proxmox_ups_runtime_seconds",
"desc": "Autonomía estimada en batería."
"desc": "Autonomía estimada con batería."
},
{
"metric": "proxmox_ups_input_voltage_volts",
@@ -724,36 +724,36 @@
}
],
"scrapeTitle": "Configuración de scrape de Prometheus",
"scrapeIntro": "El endpoint requiere autenticación. Pasa el API token como cabecera bearer en tu configuración de scrape de Prometheus:",
"perHostTitle": "Scrape por host",
"perHostBody": "Cada instancia de ProxMenux Monitor exporta métricas para el host en el que corre. En un cluster, apunta Prometheus a cada nodo — la etiqueta <code>node</code> en cada serie te permite distinguirlos en consultas Grafana (<code>proxmox_vms_running'{'node=\"pve01\"'}'</code>)."
"scrapeIntro": "Con autenticación activa, añade un token API a la cabecera Bearer de la configuración de recogida de Prometheus:",
"perHostTitle": "Recogida por host",
"perHostBody": "Cada instancia exporta métricas de su propio host. En un clúster, configura Prometheus para consultar cada nodo. La etiqueta <code>node</code> distingue las series en Grafana (<code>proxmox_vms_running'{'node=\"pve01\"'}'</code>)."
},
"puttingItTogether": {
"heading": "Juntándolo todo",
"body": "Para guías de principio a fin que conectan estos endpoints con sensores de Home Assistant, tarjetas de Homepage, paneles de Grafana, flujos de n8n y otras herramientas, mira la página dedicada <link>Integrations</link> — recorre la configuración típica de cada plataforma con ejemplos copia-pega. Esta página se mantiene centrada en el catálogo en sí."
"heading": "Combinar las integraciones",
"body": "Consulta <link>Integraciones</link> para conectar estos endpoints con sensores Home Assistant, tarjetas Homepage, paneles Grafana, flujos n8n y otras herramientas. Incluye la configuración habitual de cada plataforma con ejemplos copiables. Esta página reúne el catálogo de endpoints."
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{
"label": "Access & Authentication",
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tail": " — emisión de tokens, log de auditoría, jail Fail2Ban opcional, configuración TLS."
"tail": " — creación de tokens, registro de auditoría, jail opcional de Fail2Ban y TLS."
},
{
"label": "Notifications",
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tailRich": " — qué transporta cada tipo de evento en <code>data</code> cuando llamas a <code>/api/notifications/send</code>."
"tailRich": " — contenido de <code>data</code> para cada evento al llamar a <code>/api/notifications/send</code>."
},
{
"label": "Asistente de IA",
"href": "/docs/monitor/ai-assistant",
"tailRich": " — cómo están cableados <code>/api/notifications/test-ai</code> y <code>/api/notifications/provider-models</code>."
"tailRich": " — funcionamiento de <code>/api/notifications/test-ai</code> y <code>/api/notifications/provider-models</code>."
},
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tailRich": " — la forma de respuesta de <code>/api/health/*</code> y la semántica de las diez categorías."
"tailRich": " — formato de respuesta de <code>/api/health/*</code> y significado de las diez categorías."
}
]
}
+91 -91
View File
@@ -1,37 +1,37 @@
{
"meta": {
"title": "Arquitectura de ProxMenux Monitor — AppImage, Flask, SQLite, WebSocket | ProxMenux",
"description": "Cómo está construido ProxMenux Monitor: estructura del AppImage, blueprints de Flask, hilos de fondo, fuentes de datos (psutil, pvesh, smartctl, journalctl), persistencia en SQLite, terminal WebSocket, proveedores de IA, canales de notificación, reverse proxy e integración opcional con Fail2Ban.",
"description": "Cómo se construye ProxMenux Monitor: estructura AppImage, blueprints Flask, tareas de fondo, datos de psutil, pvesh, smartctl y journalctl, almacenamiento SQLite, terminal WebSocket, proveedores de IA, canales de aviso, proxy inverso y Fail2Ban opcional.",
"ogTitle": "Arquitectura de ProxMenux Monitor",
"ogDescription": "Dentro de ProxMenux Monitor — estructura del AppImage, blueprints de Flask, hilos de fondo, SQLite, WebSocket, proveedores de IA, canales de notificación.",
"ogDescription": "Dentro de ProxMenux Monitor: AppImage, blueprints Flask, tareas de fondo, SQLite, WebSocket, proveedores de IA y canales de aviso.",
"twitterTitle": "Arquitectura de ProxMenux Monitor",
"twitterDescription": "AppImage, Flask, SQLite, WebSocket, proveedores de IA y canales de notificación — por dentro del Monitor."
},
"header": {
"title": "Arquitectura",
"description": "Cómo se empaqueta ProxMenux Monitor, qué corre dentro del AppImage y cómo fluyen las peticiones desde el navegador a través del backend Flask hasta las herramientas del host y el almacén SQLite.",
"description": "Cómo se distribuye ProxMenux Monitor, qué contiene el AppImage y cómo las peticiones del navegador pasan por Flask hasta las herramientas del host y el almacenamiento SQLite.",
"section": "ProxMenux Monitor"
},
"intro": {
"title": "Un proceso, muchas responsabilidades",
"body": "Un único proceso Python escucha en el puerto TCP 8008. Sirve el build estático de Next.js, expone la API REST, gestiona el terminal WebSocket, ejecuta el Monitor de salud periódico y despacha notificaciones. No hay un servidor web aparte, ni un broker de mensajes, ni una base de datos externa."
"body": "Un proceso Python escucha en TCP 8008. Sirve la web estática Next.js, ofrece la API REST, gestiona el terminal WebSocket, ejecuta Health Monitor y envía notificaciones. No necesita un servidor web separado, un intermediario de mensajes ni una base de datos externa."
},
"requestFlow": {
"heading": "Flujo de petición",
"intro": "Del navegador al kernel, cada vista del panel sigue el mismo camino:",
"diagramCaption": "Cada petición se autentica por JWT (cuando la autenticación está activada), se enruta a un blueprint y se responde con datos recogidos bajo demanda desde las herramientas del host. Si Fail2Ban está instalado y el jail proxmenux está activo, el middleware también comprueba la petición contra la lista de IPs baneadas del jail. El reverse proxy opcional es transparente para Flask — reenvía las cabeceras X-Forwarded-* y la app recupera la IP real del cliente a partir de ellas. El estado que necesita sobrevivir a una petición vive en SQLite.",
"heading": "Recorrido de una petición",
"intro": "Una petición de datos típica sigue este recorrido; las preferencias del navegador pueden gestionarse localmente:",
"diagramCaption": "Las rutas protegidas validan JWT si la autenticación está activa. Flask devuelve datos del host almacenados en caché o recién obtenidos. El control opcional de Fail2Ban consulta su lista de bloqueos en caché. Solo se confía en cabeceras de IP reenviadas con PROXMENUX_TRUST_PROXY=1; si no, se usa la IP de la conexión. El estado persistente incluye SQLite y archivos JSON como auth.json.",
"diagramArrowLabel": "HTTP / WS",
"nodes": {
"clientLabel": "Cliente",
"clientDetail": "Navegador o PWA\n+ proxy opcional\nNginx / Caddy /\nTraefik",
"flaskLabel": "Flask :8008",
"flaskDetail": "Blueprints\nMiddleware JWT\nHook Fail2Ban\n(si está instalado)",
"flaskDetail": "Blueprints\nMiddleware JWT\nControl Fail2Ban\n(si está instalado)",
"hostLabel": "Herramientas del host",
"hostDetail": "psutil\npvesh\nsmartctl\njournalctl",
"stateLabel": "Estado local",
"stateDetail": "DB SQLite\n+ auth.json"
},
"threadsIntro": "El mismo proceso también ejecuta cuatro <strong>hilos de fondo</strong> arrancados al boot — no sirven HTTP, empujan estado a SQLite o a la cola de notificaciones mientras el host está activo:",
"threadsIntro": "El proceso también ejecuta <strong>hilos en segundo plano</strong>. Estos ejemplos recogen datos, actualizan cachés y SQLite, y envían notificaciones. Hay más tareas y el envío depende de que esté activado:",
"headerThread": "Hilo",
"headerCadence": "Cadencia",
"headerJob": "Tarea",
@@ -39,50 +39,50 @@
{
"thread": "_temperature_collector_loop",
"cadence": "60 s",
"job": "Registra la temperatura de la CPU y una muestra de latencia de red en la DB de historial para que las gráficas del panel tengan datos incluso cuando ningún cliente está conectado."
"job": "Guarda temperatura CPU y muestras de latencia en la base de historial, de modo que haya datos para gráficas sin un navegador conectado."
},
{
"thread": "_health_collector_loop",
"cadence": "5 min",
"job": "Ejecuta el ciclo completo del Monitor de salud (10 categorías), persiste errores activos, dismissals y observaciones de disco, y alimenta nuevos eventos al motor de notificaciones."
"job": "Ejecuta el ciclo Health Monitor de diez categorías, guarda errores y observaciones de disco, mantiene los descartes y envía nuevos eventos al motor de avisos."
},
{
"thread": "_vital_signs_sampler",
"cadence": "~1 s",
"job": "Muestreador de alta frecuencia de CPU + temperatura usado por los widgets en vivo del panel Overview."
"cadence": "CPU 5 s; temperatura 15 s; memoria 30 s",
"job": "Muestrea uso CPU, memoria y temperatura CPU para los indicadores y la detección sostenida, con independencia del análisis general de cinco minutos."
},
{
"thread": "notification_manager.start()",
"cadence": "dirigido por eventos",
"job": "Lanza los watchers de journal / task / hook (<code>JournalWatcher</code>, <code>TaskWatcher</code>, <code>ProxmoxHookWatcher</code>) y despacha a los canales configurados con reescritura opcional con IA."
"job": "Inicia observadores del journal, tareas y hooks (<code>JournalWatcher</code>, <code>TaskWatcher</code>, <code>ProxmoxHookWatcher</code>) y envía a los canales configurados, con reformulación IA opcional."
}
]
},
"systemd": {
"heading": "Unidad systemd",
"intro": "El instalador deja una unidad en <code>/etc/systemd/system/proxmenux-monitor.service</code>. Contenido por defecto:",
"intro": "El instalador crea la unidad <code>/etc/systemd/system/proxmenux-monitor.service</code>. Configuración predeterminada:",
"items": [
"<strong><code>User=root</code></strong> — obligatorio: SMART, <code>pvesh</code>, scopes de journal, comandos ZFS y el terminal web requieren todos root.",
"<strong><code>Restart=on-failure</code></strong> con back-off de 10 segundos — las salidas con código distinto de cero relanzan automáticamente.",
"<strong><code>After=network.target</code></strong> — espera a que el stack de red del host esté online."
"<strong><code>User=root</code></strong>: el servicio usa privilegios root para operaciones del host como SMART, <code>pvesh</code> y gestión ZFS. Los procesos del terminal heredan esos permisos.",
"<strong><code>Restart=on-failure</code></strong> con espera de 10 segundos: se reinicia automáticamente tras una salida con error.",
"<strong><code>After=network.target</code></strong>: ordena el inicio después de ese objetivo; no garantiza IP asignada, DNS ni conectividad externa."
],
"inspectTitle": "Inspeccionar la unidad en vivo"
"inspectTitle": "Consultar la unidad actual"
},
"appimage": {
"heading": "Qué contiene el AppImage",
"intro": "El AppImage es un sistema de archivos automontable. <code>AppRun</code> en la raíz prepara el entorno y ejecuta <code>flask_server.py</code>:",
"intro": "AppImage es un sistema de archivos que se monta al ejecutarlo. <code>AppRun</code> en su raíz prepara el entorno y lanza <code>flask_server.py</code>:",
"consequencesIntro": "Dos consecuencias de esta estructura:",
"consequences": [
"<strong>Sin polución del Python del host.</strong> El intérprete y los paquetes empaquetados están aislados dentro del AppImage — actualizar el Python del sistema host no afecta al Monitor y viceversa.",
"<strong>Las herramientas de hardware también vienen incluidas.</strong> <code>ipmitool</code>, <code>lm-sensors</code> y <code>upsc</code> viajan dentro del AppImage para que el panel pueda leer sensores fuera de banda y el estado de la UPS sin forzar al usuario a instalar paquetes Debian."
"<strong>Paquetes Python incluidos.</strong> Los paquetes Python vienen en la AppImage y se ejecutan con el intérprete Python 3.11 (PVE 8) o 3.13 (PVE 9) del propio host, sin instalar nada en su Python del sistema. La aplicación sigue usando interfaces del kernel y herramientas externas del host.",
"<strong>Clientes de hardware incluidos.</strong> Contiene <code>ipmitool</code>, <code>lm-sensors</code> y <code>upsc</code>. Las lecturas dependen del hardware compatible, acceso a sensores y, para el SAI, un servidor NUT configurado."
]
},
"flask": {
"heading": "Estructura de la app Flask",
"intro": "<code>flask_server.py</code> crea una única instancia <code>Flask(__name__)</code>, habilita CORS y registra seis blueprints más un inicializador de WebSocket:",
"heading": "Estructura de la aplicación Flask",
"intro": "<code>flask_server.py</code> crea una instancia <code>Flask(__name__)</code> con CORS restringido, registra directamente diez blueprints e inicializa el terminal. La tabla destaca módulos principales; también registra PBS, enlaces del Monitor, auditoría y backups de VM. Las precargas PVE solo se ejecutan en hosts PVE.",
"headerBlueprint": "Blueprint / módulo",
"headerPrefix": "Prefijo de rutas",
"headerOwns": "Responsable de",
"headerOwns": "Responsabilidad",
"rows": [
{
"blueprint": "flask_server.py",
@@ -95,208 +95,208 @@
"/api/logs",
"/api/prometheus"
],
"owns": "Endpoints de datos principales + servir el panel estático + comprobación opcional de Fail2Ban a nivel de aplicación (activa solo cuando Fail2Ban está instalado en el host con el jail <code>proxmenux</code>)."
"owns": "Endpoints principales, web estática y control opcional Fail2Ban, activo si existe el jail <code>proxmenux</code> en el host."
},
{
"blueprint": "flask_auth_routes.py",
"prefix": [
"/api/auth/*"
],
"owns": "Login, emisión de JWT, configuración / verificación de TOTP, cambio de contraseña, generación de API tokens."
"owns": "Inicio de sesión, emisión JWT, configuración y verificación TOTP, cambio de contraseña y tokens API."
},
{
"blueprint": "flask_health_routes.py",
"prefix": [
"/api/health/*"
],
"owns": "Probe de salud público, estado detallado, errores activos / dismissed, ajustes de supresión."
"owns": "Comprobaciones de salud, estado detallado, errores activos y descartados, y silenciamientos. Las rutas protegidas exigen autenticación si está activada."
},
{
"blueprint": "flask_terminal_routes.py",
"prefix": [
"/api/terminal/* + WS"
],
"owns": "Asignación de PTY por sesión y pipe WebSocket hacia <code>xterm.js</code> en el navegador."
"owns": "Crea un PTY por sesión y lo conecta por WebSocket con <code>xterm.js</code> del navegador."
},
{
"blueprint": "flask_notification_routes.py",
"prefix": [
"/api/notifications/*"
],
"owns": "CRUD de canales, envío de prueba, configuración del proveedor de IA, historial, envíos manuales."
"owns": "Crear, consultar, editar y borrar canales; pruebas, IA, historial y envíos manuales."
},
{
"blueprint": "flask_security_routes.py",
"prefix": [
"/api/security/*"
],
"owns": "Fallos de autenticación y, cuando Fail2Ban está instalado, estado del jail, eventos de ban y desbaneo manual."
"owns": "Fallos de acceso y, con Fail2Ban instalado, estado del jail, bloqueos y desbloqueo manual."
},
{
"blueprint": "flask_proxmenux_routes.py",
"prefix": [
"/api/proxmenux/*"
],
"owns": "Lee qué optimizaciones post-instalación de ProxMenux están instaladas en el host."
"owns": "Lee las optimizaciones ProxMenux registradas en el host."
},
{
"blueprint": "flask_oci_routes.py",
"prefix": [
"/api/oci/*"
],
"owns": "Ayudantes de despliegue de apps OCI / container (Proxmox VE 9.1+)."
"owns": "Funciones de despliegue de aplicaciones OCI y contenedores en Proxmox VE 9.1+."
}
],
"endpointsLink": "La lista completa de endpoints con la forma de petición / respuesta está en <link>API Reference</link>."
"endpointsLink": "Los endpoints de integración y sus formatos se explican en <link>Referencia de la API</link>."
},
"dataSources": {
"heading": "Fuentes de datos",
"intro": "Nada se recoge a través de un agente propio — el Monitor lee los mismos archivos y ejecuta los mismos comandos que un administrador humano:",
"intro": "Los datos del host proceden principalmente de bibliotecas, archivos y comandos habituales de administración. Algunos datos del invitado dependen además de QEMU Guest Agent o de comandos ejecutados en el CT:",
"headerSource": "Fuente",
"headerUsedFor": "Usado para",
"rows": [
{
"source": "psutil",
"usedFor": "Carga de CPU, memoria, swap, uso de puntos de montaje, contadores de NIC, lista de procesos."
"usedFor": "Carga CPU, memoria, swap, ocupación de montajes, contadores de red y procesos."
},
{
"source": "pvesh / qm / pct",
"usedFor": "Información del nodo Proxmox, inventario y configuración de VMs y CTs, pools de almacenamiento, historial de tareas."
"usedFor": "Información del nodo Proxmox, inventario y configuración VM/CT, almacenamiento e historial de tareas."
},
{
"source": "smartctl",
"usedFor": "Atributos SATA / NVMe, salud SMART, desgaste / vida útil, modelo y número de serie."
"usedFor": "Atributos SATA/NVMe, estado SMART, desgaste, vida útil, modelo y número de serie."
},
{
"source": "zpool / zfs",
"usedFor": "Estado del pool (ONLINE / DEGRADED / FAULTED / UNAVAIL), progreso de scrub, uso de datasets."
"usedFor": "Estado del pool (ONLINE / DEGRADED / FAULTED / UNAVAIL), progreso del scrub y uso de datasets."
},
{
"source": "journalctl",
"usedFor": "Logs del sistema, OOM kills, errores ATA / NVMe / dm, eventos de seguridad, unidades de servicio propias."
"usedFor": "Registros del sistema, procesos terminados por OOM, errores ATA/NVMe/dm, seguridad y unidades de servicio propias."
},
{
"source": "ip / iproute2",
"usedFor": "Interfaces, direcciones, bridges, bonds, dispositivos gestionados por OVS."
"usedFor": "Interfaces, direcciones, bridges, bonds y dispositivos gestionados por OVS."
},
{
"source": "nvidia-smi · intel_gpu_top",
"usedFor": "Utilización de GPU, VRAM, temperatura, carga de encoder / decoder."
"usedFor": "Datos GPU disponibles de utilización, VRAM, temperatura y codificación/decodificación. Los campos dependen del fabricante, herramienta y controlador."
},
{
"source": "lspci · lscpu · dmidecode",
"usedFor": "Topología PCIe, modelo y topología de CPU, información de placa y BIOS."
"usedFor": "Topología PCIe, modelo y topología CPU, placa base y BIOS."
},
{
"source": "ipmitool · sensors",
"usedFor": "Sensores fuera de banda, velocidades de ventilador, temperaturas de placa (cuando son compatibles)."
"usedFor": "Sensores fuera de banda, ventiladores y temperaturas de la placa, si el hardware lo admite."
},
{
"source": "upsc (NUT)",
"usedFor": "Estado de batería de UPS, carga, autonomía — cuando hay un servidor NUT configurado en el host."
"usedFor": "Estado de batería, carga y autonomía del SAI si hay un servidor NUT configurado."
}
],
"cacheTitle": "La salida se cachea — no toda petición llega al host",
"cacheBody": "Las fuentes costosas (<code>smartctl -a</code>, <code>pvesh get</code>) se envuelven en cachés temporizadas dentro del proceso Flask para que una pestaña ocupada del panel no martillee el disco o la API del cluster. Los TTLs de la caché están ajustados por fuente (unos pocos segundos para métricas en vivo, varios minutos para SMART)."
"cacheTitle": "Caché para reducir las consultas al host",
"cacheBody": "Los resultados costosos de <code>smartctl -a</code> y <code>pvesh get</code> se guardan temporalmente en el proceso Flask para reducir consultas repetidas al disco y a la API del clúster. La duración depende de la fuente: segundos para métricas y minutos para SMART."
},
"persistence": {
"heading": "Persistencia",
"intro": "Dos ubicaciones del sistema de archivos separan el estado por sensibilidad:",
"headerPath": "Ruta",
"intro": "Varios archivos guardan estados con distinto contenido y requisitos de acceso:",
"headerPath": "Path",
"headerOwner": "Propietario",
"headerContents": "Contenido",
"rows": [
{
"path": "/usr/local/share/proxmenux/health_monitor.db",
"owner": "root:root",
"contents": "DB SQLite. Tablas: <code>errors</code>, <code>events</code>, <code>disk_registry</code>, <code>disk_observations</code>, <code>user_settings</code>, <code>notification_history</code>, <code>excluded_storages</code>, <code>excluded_interfaces</code>. Modo journal WAL."
"contents": "Base SQLite. Tablas: <code>errors</code>, <code>events</code>, <code>disk_registry</code>, <code>disk_observations</code>, <code>user_settings</code>, <code>notification_history</code>, <code>excluded_storages</code>, <code>excluded_interfaces</code>. Modo de registro WAL."
},
{
"path": "/usr/local/share/proxmenux/.notification_key",
"owner": "root <code>0600</code>",
"contents": "Clave XOR de 32 bytes usada para cifrar ajustes sensibles de notificaciones antes de guardarlos en la DB (tokens de Telegram, API keys de IA, etc.)."
"contents": "Clave maestra de 32 bytes para secretos de notificación ENC2. Usa sal aleatoria por valor, claves derivadas y MAC. Los valores XOR antiguos se admiten para migrarlos."
},
{
"path": "/root/.config/proxmenux-monitor/auth.json",
"owner": "root:root",
"contents": "Estado de autenticación: flag de activación, nombre de usuario, hash SHA-256 de la contraseña, secret TOTP, códigos de backup, lista de API tokens emitidos, lista de hashes de tokens revocados."
"contents": "Configuración de acceso: activación, usuario, hash de contraseña PBKDF2-HMAC-SHA256 con sal, secreto TOTP, códigos de recuperación, clave JWT propia de la instalación, metadatos de tokens API y hashes de revocación. Los hashes SHA-256 antiguos migran al iniciar sesión correctamente."
},
{
"path": "/var/log/proxmenux-auth.log",
"owner": "root:root",
"contents": "Log de eventos de autenticación en texto plano. Siempre se escribe. Si Fail2Ban está instalado con el jail <code>[proxmenux]</code>, el jail lee este archivo para banear intentos de fuerza bruta; si no, el archivo simplemente acumula las entradas del log."
"contents": "Registro de autenticación en texto plano, independiente de Fail2Ban. Si el jail <code>[proxmenux]</code> está instalado y activo, lee este archivo para detectar fallos repetidos de acceso. Sin ese jail, el registro sigue disponible para consulta."
}
],
"backupTitle": "Haz backup de auth.json antes de reinstalar",
"backupBody": "Reinstalar el AppImage reemplaza el binario pero deja <code>/root/.config/proxmenux-monitor/auth.json</code> y <code>/usr/local/share/proxmenux/health_monitor.db</code> intactos. Si restauras desde un backup del host, mantén ambos archivos juntos — los API tokens guardados en <code>auth.json</code> se validan contra <code>JWT_SECRET</code>; si la DB y auth.json se desincronizan, los errores dismissed y los tokens guardados pueden comportarse mal."
"backupTitle": "Guarda auth.json antes de reinstalar",
"backupBody": "Sustituir AppImage suele conservar <code>/root/.config/proxmenux-monitor/auth.json</code> y <code>/usr/local/share/proxmenux/health_monitor.db</code>. Conserva <code>auth.json</code> con su jwt_secret para mantener validez y metadatos de tokens. La base guarda estado de salud y avisos por separado. Guarda <code>.notification_key</code> con ella para restaurar secretos de canales; restaurar solo la base no restaura la autenticación API."
},
"health": {
"heading": "Ciclo del Monitor de salud",
"intro": "Cada 5 minutos <code>health_monitor.py</code> ejecuta un ciclo determinista a través de las diez categorías mostradas en el panel:",
"heading": "Ciclo Health Monitor",
"intro": "Aproximadamente cada cinco minutos, el proceso de fondo llama a <code>health_monitor.py</code> para comprobar las diez categorías del panel:",
"items": [
"Servicios críticos de PVE (<code>pveproxy</code>, <code>pvedaemon</code>, <code>pvestatd</code>, <code>pve-cluster</code>).",
"Pools de almacenamiento Proxmox (<code>pvesh get /storage</code> + disponibilidad por almacenamiento).",
"Discos y sistemas de archivos: SMART, errores de I/O en dmesg, salud de pool ZFS, capacidad de puntos de montaje.",
"VMs y CTs: arranques fallidos, guests caídos, errores QMP, fallos de apagado.",
"Red: estado de bridge / bond, estado de enlace, latencia al gateway.",
"Actualizaciones: actualizaciones de paquetes pendientes y parches de seguridad.",
"Logs: detección de patrones persistentes / spike / cascada en el journal del sistema.",
"Memoria: actividad del OOM killer, presión alta sostenida.",
"Temperatura: sensores CPU / chasis contra umbrales del fabricante.",
"Seguridad: fallos de autenticación, eventos de ban, estado del jail fail2ban."
"Almacenamientos Proxmox: <code>pvesh get /storage</code> y disponibilidad de cada uno.",
"Discos y sistemas de archivos: SMART, errores de E/S en dmesg, estado ZFS y capacidad de montajes.",
"VM y CT: fallos de arranque, caídas, errores QMP y fallos de apagado.",
"Red: estado de bridges y bonds, enlaces y latencia hasta la puerta de enlace.",
"Actualizaciones: paquetes pendientes y parches de seguridad.",
"Registros: patrones persistentes, picos y cascadas en el journal del sistema.",
"Memoria: actividad del OOM killer y presión RAM sostenida.",
"CPU: uso y temperatura de la CPU frente a los umbrales configurables; los sensores disponibles dependen del hardware.",
"Seguridad: fallos de acceso, bloqueos y estado del jail Fail2Ban."
],
"afterIntro": "Cada hallazgo se normaliza a un <code>error_key</code> + categoría + severidad estable. La capa de persistencia deduplica contra la tabla <code>errors</code> existente — los eventos repetidos actualizan <code>last_seen</code> y el contador de ocurrencias sin spamear notificaciones.",
"cycleEnd": "El ciclo también auto-resuelve errores obsoletos usando el ajuste de <em>Suppression Duration</em> por categoría, limpia errores de recursos que ya no existen (VMs eliminadas / discos retirados / almacenamientos desmontados) y poda el log <code>events</code> con más de 30 días. El catálogo completo de categorías y la vista del panel que las expone está documentado en <link>Dashboard → Monitor de salud</link>."
"afterIntro": "Los hallazgos usan <code>error_key</code>, categoría y gravedad estables. Las filas de <code>errors</code> se actualizan en el sitio (<code>last_seen</code>, gravedad, motivo), sin duplicarlas. El envío de avisos tiene además sus propias huellas y tiempos de espera.",
"cycleEnd": "La limpieza puede resolver errores obsoletos con la <em>duración de silenciamiento</em> por categoría y reglas de estado, retirar registros huérfanos de recursos eliminados y borrar <code>events</code> de más de 30 días. Las categorías se explican en <link>Panel → Health Monitor</link>."
},
"notifications": {
"heading": "Motor de notificaciones",
"intro": "<code>notification_manager.py</code> es el orquestador. Carga los canales configurados, posee la cola de entrega y expone tanto una API Python (para rutas Flask y el ciclo del Monitor de salud) como un punto de entrada CLI (para los scripts <code>.sh</code> de hooks que vienen con ProxMenux).",
"intro": "<code>notification_manager.py</code> coordina el envío: carga canales, gestiona la cola y ofrece una API Python para Flask y Health Monitor, además de una entrada de consola para los hooks <code>.sh</code> de ProxMenux.",
"items": [
"<strong>Los watchers</strong> empujan eventos: <code>JournalWatcher</code> sigue el journal del sistema, <code>TaskWatcher</code> hace polling de la lista de tareas Proxmox, <code>ProxmoxHookWatcher</code> reacciona a hooks de backup / replicación / snapshot y <code>PollingCollector</code> gestiona fuentes de datos lentas.",
"<strong>Las templates</strong> convierten un evento en un par (título, cuerpo). La misma template puede pasar por el proveedor de IA configurado (OpenAI / Anthropic / Gemini / Groq / Ollama / OpenRouter) para producir una reescritura en lenguaje natural; ambas versiones se guardan en <code>notification_history</code>.",
"<strong>Los canales</strong> entregan los mensajes: Telegram, Discord, Email, Gotify, Pushover y Apprise (multicanal). Cada uno está implementado en <code>notification_channels.py</code> mediante la misma interfaz <code>create_channel()</code> / <code>send()</code>.",
"<strong>Cifrado.</strong> Los ajustes sensibles (<code>telegram.bot_token</code>, <code>discord.webhook_url</code>, <code>pushover.user_key</code>, <code>pushover.api_token</code>, <code>ai_api_key_*</code>, <code>email.password</code>) se cifran con la clave de <code>.notification_key</code> antes de escribirse en la base de datos y aparecen ocultos en la interfaz."
"Los <strong>observadores</strong> generan eventos: <code>JournalWatcher</code> sigue el journal, <code>TaskWatcher</code> consulta tareas Proxmox, <code>ProxmoxHookWatcher</code> recibe hooks de backups, replicación y snapshots, y <code>PollingCollector</code> gestiona fuentes lentas.",
"Las <strong>plantillas</strong> convierten eventos en título y texto. El proveedor de IA configurado (OpenAI / Anthropic / Gemini / Groq / Ollama / OpenRouter) puede reformularlos en lenguaje natural. Ambas versiones se guardan en <code>notification_history</code>.",
"Los <strong>canales</strong> envían por Telegram, Discord, correo, Gotify, Pushover y Apprise, entre otros. Las implementaciones en <code>notification_channels.py</code> comparten <code>create_channel()</code> / <code>send()</code>.",
"<strong>Cifrado.</strong> Los ajustes sensibles (<code>telegram.bot_token</code>, <code>discord.webhook_url</code>, <code>pushover.user_key</code>, <code>pushover.api_token</code>, <code>ai_api_key_*</code>, <code>email.password</code>) se cifran con la clave de <code>.notification_key</code> antes de guardarse en la base de datos y se muestran enmascarados en la interfaz."
],
"linksFooter": "Los toggles por evento, los overrides por canal y la configuración de IA se exponen en <notifLink>Settings → Notifications</notifLink> y <aiLink>Settings → AI Assistant</aiLink>."
"linksFooter": "Los controles por evento, ajustes por canal e IA se explican en <notifLink>Ajustes → Notificaciones</notifLink> y <aiLink>Ajustes → Asistente de IA</aiLink>."
},
"websocket": {
"heading": "Terminal WebSocket",
"intro": "La pestaña <em>Terminal</em> del panel es un cliente fino <code>xterm.js</code> cableado a un PTY del lado servidor a través de un WebSocket. Dos modos de transporte:",
"intro": "La pestaña <em>Terminal</em> conecta un cliente ligero <code>xterm.js</code> a un PTY del servidor por WebSocket. Hay dos modos:",
"items": [
"<strong>Modo HTTP (por defecto):</strong> el servidor de desarrollo de Flask con <code>flask-sock</code> gestiona las peticiones de upgrade. Suficiente para LAN / acceso directo.",
"<strong>Modo HTTPS / WSS:</strong> cuando hay un certificado SSL configurado, el proceso cambia a <code>gevent.pywsgi.WSGIServer</code> con <code>geventwebsocket.handler.WebSocketHandler</code>, para que los WebSockets funcionen sobre TLS sin polyfills."
"<strong>Modo HTTP, predeterminado:</strong> el servidor Flask incluido y <code>flask-sock</code> gestionan el cambio de protocolo a WebSocket.",
"<strong>Modo HTTPS / WSS:</strong> usa <code>gevent.pywsgi.WSGIServer</code> con su gestor predeterminado; <code>flask-sock</code> atiende las conexiones WebSocket sobre TLS."
],
"outro": "El PTY es un hijo del proceso Flask, así que hereda <code>User=root</code> de la unidad. Cada petición de terminal pasa por auth JWT; el usuario debe estar ya logueado en el panel antes de que se asigne un PTY.",
"proxyNote": "Si accedes al Monitor a través de un reverse proxy, asegúrate de habilitar el reenvío de WebSocket (cabeceras <code>Upgrade</code> y <code>Connection</code>). Sin eso, el terminal no funcionará."
"outro": "Los procesos del terminal heredan <code>User=root</code>. Abrir WebSocket exige un ticket breve y de un solo uso, obtenido del endpoint de tickets autenticado con permisos administrativos.",
"proxyNote": "Si usas un proxy inverso, permite el tráfico WebSocket y sus cabeceras <code>Upgrade</code> y <code>Connection</code>. El terminal necesita ese reenvío."
},
"proxy": {
"heading": "Reverse proxy y Fail2Ban",
"intro": "Dos salvaguardas se aseguran de que la seguridad funcione igual tanto si el panel se accede directamente como a través de un reverse proxy:",
"heading": "Proxy inverso y Fail2Ban",
"intro": "La elección de IP del cliente y el bloqueo opcional en la aplicación dependen de estos ajustes y componentes:",
"items": [
"<strong>Recuperación de la IP real del cliente.</strong> Un hook <code>before_request</code> lee <code>X-Forwarded-For</code> y <code>X-Real-IP</code> en ese orden, cayendo a <code>request.remote_addr</code>. La dirección recuperada es la que ven el log de autenticación y el rate limiting. Esto está siempre activo.",
"<strong>Comprobación de Fail2Ban a nivel de aplicación (opcional).</strong> Cuando el panel está detrás de un proxy, el firewall del kernel no puede bloquear la IP real del atacante — la conexión siempre viene del proxy. Para tapar ese hueco, el mismo hook de arriba consulta el jail <code>proxmenux</code> de Fail2Ban cada 30 segundos, cachea el conjunto de IPs baneadas y corta las peticiones desde esas IPs con HTTP 403 dentro de Flask."
"<strong>Elección de IP.</strong> El control <code>before_request</code> y el registro de acceso solo confían en <code>X-Forwarded-For</code> y después <code>X-Real-IP</code> con PROXMENUX_TRUST_PROXY=1. Si no, usan <code>request.remote_addr</code>. Las cabeceras reenviadas no se aceptan automáticamente.",
"<strong>Fail2Ban opcional en la aplicación.</strong> Una conexión por proxy puede mostrar la IP del proxy como origen TCP. Si se obtiene la IP fiable del cliente y está activo el jail <code>proxmenux</code>, Flask rechaza las IP bloqueadas con HTTP 403. La lista se guarda 30 segundos y se renueva al procesar peticiones tras caducar, sin un temporizador de consultas."
],
"calloutTitle": "Fail2Ban no viene incluido",
"calloutBody": "Fail2Ban <strong>no</strong> lo instala ProxMenux Monitor por sí mismo. La comprobación a nivel de aplicación es un no-op hasta que instales Fail2Ban en el host (p. ej. vía <link>Seguridad → Fail2Ban</link> en el menú de ProxMenux). Cuando el binario <code>fail2ban-client</code> o el jail <code>proxmenux</code> está ausente, la llamada falla silenciosamente y las peticiones no se filtran — la autenticación sigue aplicándose, pero no hay baneo a nivel de IP.",
"outro": "Los snippets de reverse proxy (Nginx / Caddy / Traefik) y el walkthrough del jail Fail2Ban están en <accessLink>Access & Authentication</accessLink> y <fail2banLink>Seguridad → Fail2Ban</fail2banLink>."
"calloutBody": "Fail2Ban <strong>no</strong> viene incluido ni se instala automáticamente. Puede instalarse desde Seguridad del Monitor o <link>Seguridad → Fail2Ban</link> en ProxMenux Scripts. Si faltan <code>fail2ban-client</code> o el jail <code>proxmenux</code>, este control no bloquea peticiones. La autenticación sigue la política configurada.",
"outro": "Los ejemplos de proxy inverso Nginx/Caddy/Traefik y la guía del jail están en <accessLink>Acceso y autenticación</accessLink> y <fail2banLink>Seguridad → Fail2Ban</fail2banLink>."
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{
"label": "Access & Authentication",
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tail": " — configuración de primer arranque, contraseña + TOTP 2FA, snippets de reverse proxy, jail Fail2Ban."
"tail": " — primer inicio, contraseña y TOTP 2FA, ejemplos de proxy inverso y jail Fail2Ban."
},
{
"label": "API Reference",
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — cada endpoint, gestión de tokens, mejores prácticas de seguridad."
"tail": " — endpoints de integración, tokens y convenciones de autenticación."
},
{
"label": "Settings → ProxMenux Monitor",
"label": "Ajustes → ProxMenux Monitor",
"href": "/docs/settings/proxmenux-monitor",
"tail": " — el toggle del servicio dentro del menú y el flujo de verificación del estado dentro de la TUI de ProxMenux."
"tail": " — control del servicio y comprobación del estado en el menú de texto de ProxMenux."
}
]
}
@@ -1,7 +1,7 @@
{
"meta": {
"title": "Evaluación e inventario | Auditoría e informes",
"description": "La evaluación de Auditoría e informes: perfiles de informe, clasificación de los resultados, riesgos aceptados, fuentes ilegibles, Lynis e inventario del nodo."
"description": "Evaluación de Auditoría e informes: perfiles de informe, clasificación de resultados, riesgos aceptados, fuentes ilegibles, Lynis e inventario del nodo."
},
"header": {
"title": "Evaluación e inventario",
@@ -19,7 +19,7 @@
}
},
{
"p": "<strong>Ejecutar evaluación</strong> inicia una ejecución con el perfil seleccionado en <strong>Informe</strong>. La vista muestra la fecha de la última ejecución y cuánto tiempo ha pasado."
"p": "<strong>Ejecutar evaluación</strong> inicia una ejecución con el perfil seleccionado en <strong>Informe</strong>. La vista muestra la fecha de la última ejecución y el tiempo transcurrido."
}
]
},
@@ -30,14 +30,35 @@
"blocks": [
{
"table": {
"headers": ["Perfil", "Qué abarca"],
"headers": [
"Perfil",
"Qué abarca"
],
"rows": [
["Auditoría completa", "Todas las comprobaciones y toda la estructura disponible."],
["Diagnóstico rápido", "Todas las comprobaciones; el resultado empieza por los hallazgos críticos, las advertencias y las lecturas que no pudieron verificarse."],
["Inventario", "Una descripción del nodo, sin comprobaciones ni clasificación."],
["Revisión de seguridad", "Exposición, acceso, privilegios, certificados, actualizaciones, repositorios y Lynis."],
["Garantía de backups", "Cobertura, antigüedad, resultados, verificación, retención y recuperación de los backups."],
["Capacidad y desgaste", "Margen de crecimiento, memoria, ocupación y vida útil de los discos."]
[
"Auditoría completa",
"Todas las comprobaciones y toda la estructura disponible."
],
[
"Diagnóstico rápido",
"Todas las comprobaciones; el resultado empieza por los hallazgos críticos, las advertencias y las lecturas que no pudieron verificarse."
],
[
"Inventario",
"Una descripción del nodo, sin comprobaciones ni clasificación."
],
[
"Revisión de seguridad",
"Exposición, acceso, privilegios, certificados, actualizaciones, repositorios y Lynis."
],
[
"Garantía de backups",
"Cobertura, antigüedad, resultados, verificación, retención y recuperación de los backups."
],
[
"Capacidad y desgaste",
"Margen de crecimiento, memoria, ocupación y vida útil de los discos."
]
]
}
},
@@ -52,16 +73,43 @@
"blocks": [
{
"table": {
"headers": ["Clasificación", "Significado"],
"headers": [
"Clasificación",
"Significado"
],
"rows": [
["Crítico", "Una condición fallida con prioridad."],
["Advertencia", "Una condición que requiere revisión, según la evidencia o la política."],
["Observación", "Información sobre el nodo que no se presenta como fallo."],
["Sin verificar", "La fuente que necesita la comprobación no pudo leerse. No significa que el problema no exista."],
["Conforme", "La condición cumple el criterio aplicado."],
["No aplicable", "Dentro del alcance de la comprobación no hay nada a lo que aplicarla."],
["Riesgo aceptado", "El hallazgo existe y hay registrada una decisión sobre él."],
["Excluido por política", "La política declara que el elemento queda fuera del recuento."]
[
"Crítico",
"Una condición fallida con prioridad."
],
[
"Advertencia",
"Una condición que requiere revisión, según la evidencia o la política."
],
[
"Observación",
"Información sobre el nodo que no se presenta como fallo."
],
[
"Sin verificar",
"No se pudo leer la fuente que requiere la comprobación. Esto no significa que el problema no exista."
],
[
"Conforme",
"La condición cumple el criterio aplicado."
],
[
"No aplicable",
"Dentro del alcance de la comprobación no hay nada a lo que aplicarla."
],
[
"Riesgo aceptado",
"El hallazgo existe y hay registrada una decisión sobre él."
],
[
"Excluido por política",
"La política declara que el elemento queda fuera del recuento."
]
]
}
},
@@ -76,11 +124,23 @@
"blocks": [
{
"table": {
"headers": ["Caso", "Comportamiento"],
"headers": [
"Caso",
"Comportamiento"
],
"rows": [
["Sin verificar", "La comprobación conserva su identidad, indica en su evidencia qué fuente falló y no convierte la falta de datos en un resultado conforme."],
["Evidencia incompleta", "El informe nombra la fuente y el momento de la recogida, de modo que un problema real puede distinguirse de una lectura insuficiente."],
["Una nueva ejecución", "Una vez corregido el acceso, el paquete o el servicio, el mismo perfil se ejecuta de nuevo y la comparación muestra si el resultado pudo verificarse."]
[
"Sin verificar",
"La comprobación conserva su identidad, indica qué fuente falló en su evidencia y no convierte datos ausentes en un resultado conforme."
],
[
"Evidencia incompleta",
"El informe indica la fuente y el momento de recogida para distinguir un problema real de una lectura insuficiente."
],
[
"Una nueva ejecución",
"Una vez corregido el acceso, el paquete o el servicio, el mismo perfil se ejecuta de nuevo y la comparación muestra si el resultado pudo verificarse."
]
]
}
}
@@ -91,7 +151,7 @@
"title": "Lynis",
"blocks": [
{
"p": "La revisión de seguridad usa el informe de Lynis del host. Cuando Lynis no se ha ejecutado todavía, o su informe supera el umbral de antigüedad de la política, un diálogo ofrece <strong>Ejecutar con Lynis</strong>, que tarda unos minutos más, o <strong>Ejecutar sin Lynis</strong>, que usa el informe existente."
"p": "La revisión de seguridad usa el informe Lynis del host. Si Lynis nunca se ha ejecutado o el informe supera la antigüedad permitida por la política, un diálogo ofrece <strong>Ejecutar con Lynis</strong>, que tarda unos minutos más, o <strong>Ejecutar sin Lynis</strong>, que usa el informe existente."
},
{
"figure": {
@@ -107,20 +167,32 @@
"title": "Aceptar un riesgo",
"blocks": [
{
"p": "<strong>Aceptar riesgo</strong> registra una decisión sobre un hallazgo. El motivo es obligatorio y se guarda junto al autor y la fecha."
"p": "<strong>Aceptar riesgo</strong> registra una decisión sobre un hallazgo. El motivo es obligatorio y se guarda con el autor y la fecha."
},
{
"table": {
"headers": ["Campo", "Opciones"],
"headers": [
"Campo",
"Opciones"
],
"rows": [
["Motivo", "Texto libre, obligatorio."],
["Deja de aplicarse tras", "90 días, 180 días, 1 año o no caduca. Al cumplirse el plazo, el hallazgo vuelve a estar activo."],
["Recordarme revisarla", "Un recordatorio que devuelve la decisión a la atención mientras sigue en vigor."]
[
"Motivo",
"Texto libre, obligatorio."
],
[
"Deja de aplicarse tras",
"90 días, 180 días, 1 año o no caduca. Al cumplirse el plazo, el hallazgo vuelve a estar activo."
],
[
"Recordarme revisarla",
"Un recordatorio que devuelve la decisión a la atención mientras sigue en vigor."
]
]
}
},
{
"p": "Un hallazgo aceptado sigue visible con su decisión, y <strong>Volver a activo</strong> la revoca. Un riesgo aceptado no es una corrección: la comparación lo presenta como aceptado, no como resuelto."
"p": "El hallazgo aceptado sigue visible con su decisión; <strong>Volver a activo</strong> revoca la aceptación. Aceptar un riesgo no lo corrige: la comparación lo muestra como aceptado y no como resuelto."
}
]
},
@@ -1,11 +1,11 @@
{
"meta": {
"title": "Cambios | Auditoría e informes",
"description": "El registro de cambios de Auditoría e informes: qué ha cambiado ProxMenux en el host, qué había antes, la diferencia y si puede deshacerse."
"description": "Registro de cambios de Auditoría e informes: qué modificó ProxMenux en el host, el estado anterior, las diferencias y si puede deshacerse."
},
"header": {
"title": "Cambios",
"description": "El registro de las operaciones que ProxMenux realiza en el host y, cuando se capturó, el estado antes y después de cada una.",
"description": "Registro de las operaciones realizadas por ProxMenux en el host y, cuando se capturó, el estado anterior y posterior de cada una.",
"section": "Auditoría e informes"
},
"sections": [
@@ -14,25 +14,37 @@
"blocks": [
{
"calloutInfo": {
"title": "Del script que se ejecutó al cambio que hizo",
"body": "Una función extensa puede cambiar solo dos líneas. El registro conserva cada operación concreta con el script, la función y la versión responsables, el recurso afectado, la diferencia y si puede deshacerse."
"title": "Del script ejecutado al cambio realizado",
"body": "Una función extensa puede cambiar solo dos líneas. El registro guarda cada operación concreta con el script, función y versión responsables, el recurso afectado, las diferencias y la posibilidad de deshacerla."
}
},
{
"flow": {
"nodes": [
{ "label": "Script", "detail": "función + versión" },
{ "label": "Captura", "detail": "contenido previo" },
{ "label": "Operación", "detail": "archivo · paquete · servicio" },
{ "label": "Registro", "detail": "atribución + diferencia" }
{
"label": "Script",
"detail": "función + versión"
},
{
"label": "Captura",
"detail": "contenido previo"
},
{
"label": "Operación",
"detail": "archivo · paquete · servicio"
},
{
"label": "Registro",
"detail": "atribución + diferencia"
}
],
"caption": "La captura se toma al ejecutarse la operación y se consolida cuando el Monitor lee el registro."
"caption": "La captura se realiza al ejecutar la operación y se consolida cuando Monitor lee el registro."
}
},
{
"figure": {
"src": "/monitor/audit/changes-view.png",
"alt": "Vista Cambios de Auditoría e informes con las entradas agrupadas por opción de post-install y por script",
"alt": "Vista Cambios de Auditoría e informes con entradas agrupadas por opción de postinstalación y script",
"caption": "La vista Cambios, con la diferencia de un archivo editado por ProxMenux."
}
}
@@ -45,12 +57,27 @@
"blocks": [
{
"table": {
"headers": ["Tipo", "Qué registra"],
"headers": [
"Tipo",
"Qué registra"
],
"rows": [
["Configuración", "ProxMenux escribió, editó o eliminó un archivo, cambió un ajuste o alteró un servicio."],
["Instalaciones", "ProxMenux añadió un paquete o componente, y se registran los paquetes que aparecieron realmente."],
["Ejecuciones", "ProxMenux ejecutó un comando; lo que cambió depende del propio comando."],
["Aplicado", "Una función se aplicó antes de que existiera el registro; el estado previo no se capturó."]
[
"Configuración",
"ProxMenux escribió, editó o eliminó un archivo, cambió un ajuste o alteró un servicio."
],
[
"Instalaciones",
"ProxMenux añadió un paquete o componente, y se registran los paquetes que aparecieron realmente."
],
[
"Ejecuciones",
"ProxMenux ejecutó un comando; sus efectos dependen del propio comando."
],
[
"Aplicado",
"Una función se aplicó antes de que existiera el registro; no se capturó su estado anterior."
]
]
}
}
@@ -62,11 +89,23 @@
"blocks": [
{
"table": {
"headers": ["Sección", "Contenido"],
"headers": [
"Sección",
"Contenido"
],
"rows": [
["Optimizaciones de post-install", "Agrupadas por la opción de post-install que seleccionó el usuario."],
["Scripts de ProxMenux", "GPU, Coral, red, almacenamiento, seguridad, utilidades y el resto de scripts instrumentados, incluidos el instalador de ProxMenux y ProxMenux Monitor."],
["Paquetes y utilidades instalados", "Software que ProxMenux instaló en el host."]
[
"Optimizaciones de post-install",
"Agrupadas por la opción de post-install que seleccionó el usuario."
],
[
"Scripts de ProxMenux",
"GPU, Coral, red, almacenamiento, seguridad, utilidades y el resto de scripts instrumentados, incluidos el instalador de ProxMenux y ProxMenux Monitor."
],
[
"Paquetes y utilidades instalados",
"Software instalado por ProxMenux en el host."
]
]
}
},
@@ -88,7 +127,7 @@
"Las líneas añadidas y eliminadas.",
"Los paquetes que se añadieron realmente.",
"La transición de estado de un servicio.",
"<strong>Deshacer esto</strong>: <em>Restaura exactamente lo que había</em>, <em>Elimina el fichero (no había ninguno antes)</em>, <em>Se puede desinstalar el paquete</em>, un deshacer parcial o <em>No se puede deshacer desde el registro</em>."
"<strong>Deshacer esto</strong>: <em>Restaura exactamente lo que había</em>, <em>Elimina el archivo (no existía antes)</em>, <em>Se puede desinstalar el paquete</em>, una reversión parcial o <em>No puede deshacerse desde el registro</em>."
]
}
}
@@ -96,10 +135,10 @@
},
{
"id": "before",
"title": "Qué significa el estado previo",
"title": "Qué significa el estado anterior",
"blocks": [
{
"p": "El estado previo puede ser contenido capturado, un archivo creado por primera vez o un estado desconocido. Los cambios hechos antes de que existiera el registro no pueden reconstruirse; al volver a ejecutar la función se captura primero el estado encontrado en ese momento."
"p": "El estado anterior puede ser contenido capturado, un archivo creado por primera vez o un estado desconocido. Los cambios anteriores al registro no pueden reconstruirse; al volver a ejecutar la función, primero se captura el estado encontrado en ese momento."
}
]
},
@@ -125,21 +164,42 @@
"blocks": [
{
"table": {
"headers": ["Elemento", "Comportamiento"],
"headers": [
"Elemento",
"Comportamiento"
],
"rows": [
["Entradas", "Se conservan en el host; del registro no se elimina nada automáticamente."],
["Contenido capturado", "Un objeto capturado se conserva mientras alguna entrada lo referencia."],
["Tamaño de una captura", "El contenido de más de 1 MiB no se guarda entero; la entrada registra que la captura se omitió por su tamaño."],
["Lectura", "El Monitor no carga objetos guardados de más de 2 MiB."],
["Diferencia", "Se muestran como máximo 400 líneas, y una diferencia más larga se marca como truncada."],
["Listado", "La API devuelve 200 entradas por petición por defecto y hasta 1000."]
[
"Entradas",
"Se conservan en el host; del registro no se elimina nada automáticamente."
],
[
"Contenido capturado",
"Un objeto capturado se conserva mientras alguna entrada lo referencia."
],
[
"Tamaño de una captura",
"El contenido de más de 1 MiB no se guarda entero; la entrada registra que la captura se omitió por su tamaño."
],
[
"Lectura",
"El Monitor no carga objetos guardados de más de 2 MiB."
],
[
"Diferencia",
"Se muestran como máximo 400 líneas; una diferencia más larga se marca como truncada."
],
[
"Listado",
"La API devuelve por defecto 200 entradas por petición, con un máximo de 1000."
]
]
}
},
{
"calloutWarning": {
"title": "Conservar el contenido no es deshacer automáticamente",
"body": "El contenido previo a un cambio puede consultarse y restaurarse a mano, pero la vista Cambios no revierte operaciones. Una entrada de ejecución registra el comando sin conocer todos los efectos de la herramienta que ejecutó."
"title": "Guardar el contenido no implica deshacer automáticamente",
"body": "El contenido anterior puede consultarse y restaurarse a mano, pero la vista Cambios no revierte operaciones. Una entrada de ejecución registra el comando sin conocer todos los efectos de la herramienta ejecutada."
}
}
]
@@ -1,11 +1,11 @@
{
"meta": {
"title": "Auditoría e informes | ProxMenux Monitor",
"description": "Evaluación de un nodo Proxmox VE, registro de lo que ProxMenux ha cambiado en él y declaración de lo que se espera de sus invitados y almacenamientos, con informes imprimibles."
"description": "Evalúa un nodo Proxmox VE, registra los cambios de ProxMenux y declara qué se espera de sus invitados y almacenamiento, con informes imprimibles."
},
"header": {
"title": "Auditoría e informes",
"description": "Una evaluación del nodo, el registro de lo que ProxMenux ha cambiado en él y la declaración de lo que se espera de él, con documentos que pueden imprimirse o guardarse como PDF.",
"description": "Evaluación del nodo, registro de los cambios realizados por ProxMenux y declaración de expectativas, con documentos imprimibles o guardables en PDF.",
"section": "ProxMenux Monitor"
},
"sections": [
@@ -15,26 +15,47 @@
{
"calloutInfo": {
"title": "Tres vistas, tres preguntas",
"body": "Auditoría e informes separa los hechos del nodo, las intervenciones de ProxMenux y las expectativas declaradas para él. Una configuración que la evaluación no puede contrastar con una finalidad declarada se describe, no se presenta como un fallo."
"body": "Auditoría e informes separa los hechos del nodo, las intervenciones de ProxMenux y las expectativas declaradas. Si una configuración no puede contrastarse con una finalidad declarada, se describe sin considerarla un fallo."
}
},
{
"cards": {
"items": [
{ "icon": "shield", "title": "Evaluación: ¿cómo está el nodo?", "body": "Ejecuta las comprobaciones del perfil elegido, compone el inventario y clasifica lo que requiere atención, con la evidencia de cada resultado." },
{ "icon": "refresh", "title": "Cambios: ¿qué ha hecho ProxMenux?", "body": "Enumera los archivos, paquetes, servicios y comandos que han cambiado los scripts instrumentados de ProxMenux, con lo que había antes cuando se capturó." },
{ "icon": "fileText", "title": "Política: ¿qué se espera?", "body": "Declara qué invitados necesitan backup o deben arrancar con el host, qué almacenamiento es esencial y los umbrales de las comprobaciones." }
{
"icon": "shield",
"title": "Evaluación: ¿cómo está el nodo?",
"body": "Ejecuta las comprobaciones del perfil elegido, compone el inventario y clasifica lo que requiere atención, con la evidencia de cada resultado."
},
{
"icon": "refresh",
"title": "Cambios: ¿qué ha hecho ProxMenux?",
"body": "Enumera los archivos, paquetes, servicios y comandos modificados por los scripts de ProxMenux con instrumentación de auditoría, e incluye el estado anterior cuando se capturó."
},
{
"icon": "fileText",
"title": "Política: ¿qué se espera?",
"body": "Declara qué invitados necesitan backup o deben arrancar con el host, qué almacenamiento es esencial y los umbrales de las comprobaciones."
}
]
}
},
{
"flow": {
"nodes": [
{ "label": "Evaluación", "detail": "hechos" },
{ "label": "Política", "detail": "contexto" },
{ "label": "Cambios", "detail": "intervenciones" }
{
"label": "Evaluación",
"detail": "hechos"
},
{
"label": "Política",
"detail": "contexto"
},
{
"label": "Cambios",
"detail": "intervenciones"
}
],
"caption": "La evaluación aporta los hechos, la política les da contexto y el registro recoge lo que ha hecho ProxMenux."
"caption": "La evaluación aporta los hechos, la política les da contexto y el registro recoge lo que hizo ProxMenux."
}
},
{
@@ -52,11 +73,23 @@
"blocks": [
{
"table": {
"headers": ["Función", "Qué hace"],
"headers": [
"Función",
"Qué hace"
],
"rows": [
["<healthLink>Health Monitor</healthLink>", "Observa métricas y eventos de forma continua y puede generar notificaciones."],
["Auditoría e informes", "Ejecuta una evaluación cuando se pide, documenta el nodo y compara ejecuciones entre sí."],
["Registro de cambios", "Registra las operaciones que ProxMenux realiza a través de sus primitivas de auditoría."]
[
"<healthLink>Monitor de estado</healthLink>",
"Observa métricas y eventos continuamente y puede generar notificaciones."
],
[
"Auditoría e informes",
"Ejecuta una evaluación bajo demanda, documenta el nodo y compara ejecuciones entre sí."
],
[
"Registro de cambios",
"Registra las operaciones realizadas por ProxMenux mediante sus primitivas de auditoría."
]
]
}
}
@@ -69,11 +102,31 @@
{
"next": {
"items": [
{ "label": "Evaluación e inventario", "href": "/docs/monitor/audit-report/assessment", "tail": "perfiles, resultados, riesgos aceptados e inventario." },
{ "label": "Cambios", "href": "/docs/monitor/audit-report/changes", "tail": "el registro de lo que ProxMenux ha cambiado en el host." },
{ "label": "Política", "href": "/docs/monitor/audit-report/policy", "tail": "invitados, almacenamiento y umbrales." },
{ "label": "Informes y comparaciones", "href": "/docs/monitor/audit-report/reports", "tail": "los seis documentos y la ejecución de referencia." },
{ "label": "Alcance y garantías", "href": "/docs/monitor/audit-report/scope", "tail": "fuentes, límites y datos guardados." }
{
"label": "Evaluación e inventario",
"href": "/docs/monitor/audit-report/assessment",
"tail": "perfiles, resultados, riesgos aceptados e inventario."
},
{
"label": "Cambios",
"href": "/docs/monitor/audit-report/changes",
"tail": "el registro de lo que ProxMenux ha cambiado en el host."
},
{
"label": "Política",
"href": "/docs/monitor/audit-report/policy",
"tail": "invitados, almacenamiento y umbrales."
},
{
"label": "Informes y comparaciones",
"href": "/docs/monitor/audit-report/reports",
"tail": "los seis documentos y la ejecución de referencia."
},
{
"label": "Alcance y garantías",
"href": "/docs/monitor/audit-report/scope",
"tail": "fuentes, límites y datos guardados."
}
]
}
}
@@ -1,11 +1,11 @@
{
"meta": {
"title": "Política | Auditoría e informes",
"description": "La política del nodo en Auditoría e informes: backup, arranque y objetivo de recuperación de cada invitado, el papel de cada almacenamiento y los umbrales de las comprobaciones."
"description": "Política del nodo en Auditoría e informes: backups, arranque automático y objetivo de recuperación de cada invitado, función de cada almacenamiento y umbrales de comprobación."
},
"header": {
"title": "Política",
"description": "La política declara lo que ninguna inspección puede deducir: para qué sirve cada invitado y almacenamiento y los umbrales que aplican las comprobaciones.",
"description": "La política declara lo que una inspección no puede deducir: la finalidad de cada invitado y almacenamiento y los umbrales que deben aplicar las comprobaciones.",
"section": "Auditoría e informes"
},
"sections": [
@@ -34,11 +34,27 @@
"blocks": [
{
"table": {
"headers": ["Campo", "Valores", "Efecto en la evaluación"],
"headers": [
"Campo",
"Valores",
"Efecto en la evaluación"
],
"rows": [
["Backup", "Obligatorio, No obligatorio, Sin especificar", "La falta de backup es una advertencia si es obligatorio, una observación si no se especifica, y queda fuera del recuento si no es obligatorio."],
["Arranque", "Obligatorio, No obligatorio, Sin especificar", "Si el invitado debe arrancar con el host."],
["Objetivo de recuperación", "Horas", "La antigüedad máxima aceptable del último backup."]
[
"Backups",
"Obligatorio, No obligatorio, Sin especificar",
"La falta de backup es una advertencia si es obligatorio, una observación si no se especifica, y queda fuera del recuento si no es obligatorio."
],
[
"Arranque automático",
"Obligatorio, No obligatorio, Sin especificar",
"Si el invitado debe arrancar con el host."
],
[
"Objetivo de recuperación",
"Horas",
"La antigüedad máxima aceptable del último backup."
]
]
}
}
@@ -47,30 +63,30 @@
{
"id": "storage",
"title": "Almacenamiento",
"intro": "Cada almacenamiento del nodo se declara Esencial, Opcional o Sin especificar.",
"blocks": [
{
"p": "Un almacenamiento inaccesible se presenta como crítico cuando se declara esencial o sirve a un invitado en marcha, como advertencia cuando su papel no se especifica, y como observación cuando se declara opcional."
}
]
],
"intro": "Cada almacenamiento del nodo se declara Esencial, Opcional o Sin especificar."
},
{
"id": "thresholds",
"title": "Umbrales",
"intro": "Un umbral vacío usa el valor de fábrica, que se muestra como texto de ejemplo.",
"intro": "Un umbral vacío usa el valor incluido por defecto, mostrado como texto de ejemplo.",
"blocks": [
{
"list": {
"items": [
"Revisión de capacidad de almacenamiento (%) y revisión de ocupación de thin pool (%).",
"Ratio de sobreaprovisionamiento thin y ratio de sobreasignación de memoria.",
"Revisión de capacidad de almacenamiento (%) y ocupación del thin pool (%).",
"Ratio de sobreaprovisionamiento thin y de sobreasignación de memoria.",
"Intervalo de scrub de ZFS (días).",
"Plazo de respaldo para la antigüedad (días) y margen sobre el calendario (ratio).",
"Plazo alternativo para la antigüedad del backup (días) y margen sobre el calendario (ratio).",
"Aviso de caducidad de certificado (días).",
"Vida útil del disco (horas) y ventana de errores de disco recientes (días).",
"Antigüedad del informe de Lynis (días) y antigüedad de los índices de paquetes (días).",
"Journal frente a su tope (%).",
"Revisión de espacio del sistema de archivos (%) y revisión de inodos del sistema de archivos (%)."
"Antigüedad del informe de Lynis (días) y del índice de paquetes (días).",
"Uso del journal respecto a su límite (%).",
"Revisión del espacio (%) y de los inodos (%) del sistema de archivos."
]
}
}
@@ -81,12 +97,12 @@
"title": "Cómo se guarda la política",
"blocks": [
{
"p": "La declaración se valida y se guarda de forma atómica en <code>/usr/local/share/proxmenux/audit_policy.json</code>. Cada guardado lleva una revisión: si la declaración cambió en otra sesión, el borrador no se guarda y la vista ofrece recargar la declaración guardada."
"p": "La declaración se valida y guarda de forma atómica en <code>/usr/local/share/proxmenux/audit_policy.json</code>. Cada guardado incluye una revisión: si otra sesión cambió la declaración, el borrador no se guarda y la vista ofrece recargar la versión guardada."
},
{
"calloutWarning": {
"title": "La política nunca se deduce",
"body": "ProxMenux no añade ningún requisito por su cuenta. Un campo vacío conserva el valor de fábrica o queda sin especificar, y una declaración parcial solo afecta a los elementos que nombra."
"body": "ProxMenux no añade requisitos por su cuenta. Un campo vacío conserva el valor incluido por defecto o queda sin especificar; una declaración parcial solo afecta a los elementos que menciona."
}
}
]
@@ -1,11 +1,11 @@
{
"meta": {
"title": "Informes y comparaciones | Auditoría e informes",
"description": "Los seis documentos de Auditoría e informes, cómo se imprimen o guardan como PDF y cómo se comparan las ejecuciones con una ejecución de referencia."
"description": "Los seis documentos de Auditoría e informes, su impresión o guardado en PDF y la comparación de ejecuciones con una referencia."
},
"header": {
"title": "Informes y comparaciones",
"description": "Seis documentos, cada uno compuesto para una pregunta distinta, y la comparación de cada ejecución con una ejecución de referencia.",
"description": "Seis documentos que responden a preguntas distintas y comparación de cada ejecución con una referencia.",
"section": "Auditoría e informes"
},
"sections": [
@@ -29,11 +29,17 @@
"items": [
{
"title": "Auditoría completa",
"body": "Documenta el nodo de extremo a extremo como registro técnico.",
"body": "Documenta todo el nodo como registro técnico.",
"href": "/monitor/audit/sample-audit-full-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "Todas las disponibles." },
{ "label": "Contenido", "value": "Resumen ejecutivo; identidad y clúster; hardware; red y latencia; almacenamiento; invitados; passthrough; aplicaciones; hallazgos con evidencia; fuentes y alcance." }
{
"label": "Comprobaciones",
"value": "Todas las comprobaciones disponibles."
},
{
"label": "Contenido",
"value": "Resumen ejecutivo; identidad y clúster; hardware; red y latencia; almacenamiento; invitados; passthrough; aplicaciones; hallazgos con evidencia; fuentes y alcance."
}
]
},
{
@@ -41,8 +47,14 @@
"body": "Muestra lo que requiere atención sin el inventario completo.",
"href": "/monitor/audit/sample-audit-diagnostic-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "Las mismas que la auditoría completa." },
{ "label": "Contenido", "value": "Identidad mínima; hallazgos críticos; advertencias; observaciones relevantes; lecturas sin verificar y acciones prioritarias. Deja fuera diagramas, inventario y anexos extensos." }
{
"label": "Comprobaciones",
"value": "Las mismas que la auditoría completa."
},
{
"label": "Contenido",
"value": "Identidad mínima; hallazgos críticos; advertencias; observaciones relevantes; lecturas sin verificar y acciones prioritarias. Deja fuera diagramas, inventario y anexos extensos."
}
]
},
{
@@ -50,8 +62,14 @@
"body": "Describe lo que existe en el nodo sin evaluarlo.",
"href": "/monitor/audit/sample-audit-inventory-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "Ninguna; no se clasifica ningún hallazgo." },
{ "label": "Contenido", "value": "Identidad; clúster; CPU y memoria; placa, BIOS y controladoras; red; almacenamiento; VM y LXC; passthrough; aplicaciones y elementos gestionados por ProxMenux." }
{
"label": "Comprobaciones",
"value": "Ninguna; no se clasifica ningún hallazgo."
},
{
"label": "Contenido",
"value": "Identidad; clúster; CPU y memoria; placa, BIOS y controladoras; red; almacenamiento; VM y LXC; passthrough; aplicaciones y elementos gestionados por ProxMenux."
}
]
},
{
@@ -59,8 +77,14 @@
"body": "Abarca la exposición y los controles de acceso al nodo.",
"href": "/monitor/audit/sample-audit-security-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "El área de seguridad, más los privilegios de los contenedores, las actualizaciones, los repositorios y la cadena APT." },
{ "label": "Contenido", "value": "Identidad y clúster; red y latencia; acceso; cortafuegos; 2FA; certificados; privilegios; actualizaciones; repositorios; estado y antigüedad de Lynis." }
{
"label": "Comprobaciones",
"value": "El área de seguridad, más los privilegios de los contenedores, las actualizaciones, los repositorios y la cadena APT."
},
{
"label": "Contenido",
"value": "Identidad y clúster; red y latencia; acceso; cortafuegos; 2FA; certificados; privilegios; actualizaciones; repositorios; estado y antigüedad de Lynis."
}
]
},
{
@@ -68,8 +92,14 @@
"body": "Comprueba que la protección declarada existe y que sus backups son utilizables.",
"href": "/monitor/audit/sample-audit-backup-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "El área de backups, más la conectividad del almacenamiento y la entrega de notificaciones." },
{ "label": "Contenido", "value": "Cobertura por invitado; objetivo de recuperación declarado; antigüedad y resultado; destino; retención; verificación; trabajos fallidos; recuperación y fuentes incompletas." }
{
"label": "Comprobaciones",
"value": "El área de backups, más la conectividad del almacenamiento y la entrega de notificaciones."
},
{
"label": "Contenido",
"value": "Cobertura por invitado; objetivo de recuperación declarado; antigüedad y resultado; destino; retención; verificación; trabajos fallidos; recuperación y fuentes incompletas."
}
]
},
{
@@ -77,8 +107,14 @@
"body": "Mide el margen de crecimiento y las señales de agotamiento o envejecimiento.",
"href": "/monitor/audit/sample-audit-capacity-report.pdf",
"facts": [
{ "label": "Comprobaciones", "value": "Las áreas de almacenamiento y hardware, más memoria, swap, journal y el sistema de archivos del host." },
{ "label": "Contenido", "value": "Ocupación y umbrales; thin pools; sobreaprovisionamiento; memoria; inodos; ZFS; temperaturas; horas de funcionamiento; errores SMART y vida útil de NVMe/SSD." }
{
"label": "Comprobaciones",
"value": "Las áreas de almacenamiento y hardware, más memoria, swap, journal y el sistema de archivos del host."
},
{
"label": "Contenido",
"value": "Ocupación y umbrales; thin pools; sobreaprovisionamiento; memoria; inodos; ZFS; temperaturas; horas de funcionamiento; errores SMART y vida útil NVMe/SSD."
}
]
}
]
@@ -92,7 +128,7 @@
}
},
{
"p": "Un documento contiene la identidad del nodo y la fecha de la evaluación, el resultado ejecutivo, un resumen por áreas, la estructura de hardware, red y almacenamiento, la protección de los invitados, los hallazgos con su evidencia, las fuentes que no pudieron leerse, y el alcance y la política aplicada, en la medida en que cada perfil los incluye."
"p": "Cada perfil incluye, según corresponda, identidad del nodo y fecha de evaluación, resumen ejecutivo, resumen por áreas, estructura de hardware, red y almacenamiento, protección de invitados, hallazgos con evidencia, fuentes ilegibles y alcance y política aplicados."
}
]
},
@@ -103,10 +139,22 @@
{
"steps": {
"items": [
{ "title": "Ejecutar", "body": "Una evaluación se ejecuta con el perfil seleccionado en <strong>Informe</strong>." },
{ "title": "Revisar", "body": "La ejecución terminada muestra sus hallazgos, las fuentes que no pudo leer y la política que aplicó." },
{ "title": "Generar informe", "body": "<strong>Generar informe</strong> abre la vista preparada como documento." },
{ "title": "Imprimir", "body": "<strong>Imprimir o guardar como PDF</strong> abre el diálogo de impresión del navegador, donde se selecciona una impresora o <em>Guardar como PDF</em>." }
{
"title": "Ejecutar",
"body": "La evaluación usa el perfil seleccionado en <strong>Informe</strong>."
},
{
"title": "Revisar",
"body": "La ejecución terminada muestra sus hallazgos, las fuentes que no pudo leer y la política que aplicó."
},
{
"title": "Generar informe",
"body": "<strong>Generar informe</strong> abre la vista preparada como documento."
},
{
"title": "Imprimir",
"body": "<strong>Imprimir o guardar como PDF</strong> abre el diálogo de impresión del navegador para elegir una impresora o <em>Guardar como PDF</em>."
}
]
}
},
@@ -121,37 +169,76 @@
{
"id": "compare",
"title": "Comparar con una ejecución de referencia",
"intro": "<strong>Usar como referencia</strong> marca una ejecución terminada como referencia. Las ejecuciones posteriores se comparan con ella y sus hallazgos se separan en:",
"intro": "<strong>Usar como referencia</strong> marca una ejecución terminada. Las siguientes se comparan con ella y sus hallazgos se agrupan en:",
"blocks": [
{
"table": {
"headers": ["Grupo", "Significado"],
"headers": [
"Grupo",
"Significado"
],
"rows": [
["Nuevos", "Presentes ahora y no antes."],
["Empeoraron", "Siguen presentes, y son más graves o afectan a más que antes."],
["Mejoraron", "Siguen presentes, pero son menos graves o afectan a menos que antes."],
["Resueltos", "Ya no aparecen, y nadie los aceptó."],
["Aceptados", "Ya no cuentan porque se aceptó un riesgo, no porque haya cambiado el host."],
["Ya no se evalúan", "Estaban antes y no aparecen en esta ejecución; nada ha verificado que hayan dejado de existir."]
[
"Nuevos",
"Presentes ahora y no antes."
],
[
"Empeoraron",
"Siguen apareciendo, pero son más graves o afectan a más que antes."
],
[
"Mejoraron",
"Siguen apareciendo, pero son menos graves o afectan a menos que antes."
],
[
"Resueltos",
"Ya no aparecen y nadie los ha aceptado."
],
[
"Aceptados",
"Ya no cuentan porque se aceptó un riesgo, no porque haya cambiado el host."
],
[
"Ya no se evalúan",
"Aparecían antes pero no en esta ejecución; no se ha verificado que hayan desaparecido."
]
]
}
},
{
"table": {
"headers": ["Ejecución de referencia", "Comportamiento"],
"headers": [
"Ejecución de referencia",
"Comportamiento"
],
"rows": [
["Marcarla", "Puede marcarse cualquier ejecución terminada; ninguna se marca automáticamente."],
["Cambiarla", "Marcar otra ejecución mueve la referencia sin borrar el historial."],
["Comparar", "Si no se seleccionan dos ejecuciones, la comparación usa la referencia y la ejecución seleccionada o la más reciente."],
["Conservar ejecuciones", "Se conservan las 30 ejecuciones más recientes, y la ejecución de referencia nunca se elimina."],
["Sin referencia", "La vista indica que todavía no se ha elegido una ejecución de referencia, así que no hay con qué comparar."]
[
"Marcarla",
"Puede marcarse cualquier ejecución terminada; ninguna se marca automáticamente."
],
[
"Cambiarla",
"Marcar otra ejecución cambia la referencia sin borrar el historial."
],
[
"Comparar",
"Si no se seleccionan dos ejecuciones, la comparación usa la referencia y la ejecución seleccionada o la más reciente."
],
[
"Conservar ejecuciones",
"Se conservan las 30 ejecuciones más recientes; la de referencia nunca se elimina."
],
[
"Sin referencia",
"La vista indica que aún no se ha elegido una ejecución de referencia, así que no hay con qué comparar."
]
]
}
},
{
"calloutWarning": {
"title": "Un informe describe un momento",
"body": "Una evaluación no certifica un periodo completo. Los resultados antiguos dejan de describir el estado actual; la vista muestra la antigüedad de la última ejecución y cada fuente conserva el momento en que se recogió."
"body": "Una evaluación no certifica un periodo completo. Los resultados antiguos dejan de representar el estado actual; la vista muestra la antigüedad de la última ejecución y cada fuente conserva su momento de recogida."
}
}
]
@@ -1,11 +1,11 @@
{
"meta": {
"title": "Alcance y garantías | Auditoría e informes",
"description": "De dónde proceden los datos de Auditoría e informes, qué queda fuera de su alcance, las garantías de su diseño y dónde se guardan sus datos."
"description": "Origen de los datos de Auditoría e informes, límites de su alcance, garantías del diseño y ubicación de sus datos."
},
"header": {
"title": "Alcance y garantías",
"description": "De dónde proceden los datos de una evaluación, qué queda fuera de su alcance y dónde guarda Auditoría e informes sus datos.",
"description": "De dónde proceden los datos de una evaluación, qué queda fuera de su alcance y dónde guarda sus datos Auditoría e informes.",
"section": "Auditoría e informes"
},
"sections": [
@@ -38,7 +38,7 @@
"El equipamiento de red fuera del host.",
"Las dependencias remotas que el nodo no puede observar.",
"El estado físico que el hardware no expone.",
"Las acciones manuales o de otro software, en el registro de cambios."
"El registro de cambios no incluye acciones manuales ni de otros programas."
]
}
},
@@ -62,7 +62,7 @@
"Una política validada y guardada de forma atómica.",
"Riesgos aceptados con motivo y visibles.",
"Atribución de los cambios al script y a la función.",
"Captura del estado anterior y posterior cuando está disponible.",
"Captura del estado anterior y posterior, cuando está disponible.",
"Un resultado explícito cuando algo no puede medirse o capturarse."
]
}
@@ -75,20 +75,38 @@
"blocks": [
{
"table": {
"headers": ["Datos", "Ubicación"],
"headers": [
"Datos",
"Ubicación"
],
"rows": [
["Política", "<code>/usr/local/share/proxmenux/audit_policy.json</code>"],
["Evaluaciones", "La base de datos de auditoría del Monitor"],
["Objetos capturados", "<code>/usr/local/share/proxmenux/changes/objects/</code>"],
["Entradas pendientes", "<code>/usr/local/share/proxmenux/changes/spool/</code>"],
["Registro consolidado", "<code>/usr/local/share/proxmenux/changes.db</code>"]
[
"Política",
"<code>/usr/local/share/proxmenux/audit_policy.json</code>"
],
[
"Evaluaciones",
"La base de datos de auditoría del Monitor"
],
[
"Objetos capturados",
"<code>/usr/local/share/proxmenux/changes/objects/</code>"
],
[
"Entradas pendientes",
"<code>/usr/local/share/proxmenux/changes/spool/</code>"
],
[
"Registro consolidado",
"<code>/usr/local/share/proxmenux/changes.db</code>"
]
]
}
},
{
"calloutInfo": {
"title": "Una herramienta de revisión, no una certificación",
"body": "Auditoría e informes revisa, compara y documenta el nodo. Sus resultados se leen junto con la finalidad del sistema, la política declarada y las fuentes disponibles."
"body": "Auditoría e informes revisa, compara y documenta el nodo. Sus resultados se interpretan según la finalidad del sistema, la política declarada y las fuentes disponibles."
}
}
]
@@ -10,7 +10,7 @@
},
"intro": {
"title": "Un lanzador, no un instalador de aplicaciones",
"body": "La pestaña <strong>Apps</strong> no instala software ni descubre servicios por sí sola. Convierte los enlaces web guardados en una cuadrícula con búsqueda. Los enlaces que pertenecen a un LXC se configuran en la <appTabLink>pestaña App</appTabLink> del contenedor; los enlaces personalizados permiten incluir servicios de VMs, proxies inversos y paneles externos."
"body": "La pestaña <strong>Apps</strong> no instala ni descubre servicios. Convierte enlaces guardados en una cuadrícula con búsqueda. Los enlaces de LXC se configuran en su <appTabLink>pestaña App</appTabLink>; los personalizados permiten incluir servicios VM, proxies inversos y paneles externos."
},
"sources": {
"heading": "Qué aparece en Apps",
@@ -31,12 +31,12 @@
},
{
"source": "Enlace personalizado sin asociación",
"appears": "Cualquier destino HTTP(S), incluido un servicio externo o publicado mediante proxy inverso.",
"appears": "Cualquier destino HTTP(S), incluidos servicios externos o publicados mediante proxy inverso.",
"managedFrom": "Apps → Editar"
}
],
"relationshipTitle": "Apps y la pestaña App del LXC tienen funciones diferentes",
"relationshipBody": "La <appTabLink>pestaña App</appTabLink> del LXC gestiona la identidad de la aplicación, sus enlaces web y el seguimiento opcional de versión. La pestaña principal <strong>Apps</strong> utiliza esos enlaces para ofrecer un acceso rápido. Por eso, al editar una tarjeta que pertenece a un LXC se vuelve a su registro original en lugar de crear una segunda configuración."
"relationshipBody": "La <appTabLink>pestaña App</appTabLink> del LXC gestiona identidad, enlaces web y seguimiento opcional de versión. <strong>Apps</strong> usa esos enlaces para abrirlos rápidamente. Editar una tarjeta LXC vuelve al registro del invitado sin duplicar la configuración."
},
"cards": {
"heading": "Cómo utilizar una tarjeta",
@@ -45,7 +45,7 @@
"Pulsa la tarjeta para abrir su URL en una pestaña nueva del navegador.",
"El logotipo utiliza primero el definido para el enlace web y, cuando corresponde, recurre al logotipo general de la aplicación.",
"La etiqueta de categoría utiliza el mismo color y nombre que el enlace correspondiente en la pestaña App del LXC.",
"La etiqueta del invitado identifica la VM o el LXC asociado. Púlsala para abrir su modal; los enlaces de LXC abren directamente <strong>App</strong> y los de VM abren <strong>Estado</strong>.",
"La etiqueta del invitado identifica la VM o LXC asociado. Púlsala para abrir su ventana: LXC abre <strong>App</strong> y VM abre <strong>Estado</strong>.",
"La flecha morada hacia arriba indica que existe una actualización para esa aplicación o imagen Docker concreta. No representa el total de actualizaciones del invitado."
]
},
@@ -55,8 +55,8 @@
"items": [
"La búsqueda tiene en cuenta el nombre de la aplicación, el nombre del invitado, el VMID y la categoría.",
"El filtro de categoría permite mostrar una categoría concreta o todas las aplicaciones.",
"Se puede ordenar por <strong>Nombre</strong>, <strong>ID</strong> o <strong>Categoría</strong>. Al ordenar por categoría se insertan encabezados entre los grupos de tarjetas.",
"El orden seleccionado se recuerda en este navegador. El texto de búsqueda y el filtro de categoría se restablecen al volver a la página.",
"Ordena por <strong>Nombre</strong>, <strong>ID</strong> o <strong>Categoría</strong>. Ordenar por categoría añade encabezados entre grupos de tarjetas.",
"El orden se recuerda en este navegador. Búsqueda y filtro de categoría se restablecen al volver a la página.",
"La pestaña Apps permanece disponible aunque la cuadrícula esté vacía, de modo que se pueda añadir el primer enlace personalizado sin registrar antes una aplicación LXC."
]
},
@@ -67,21 +67,41 @@
"Pulsa <strong>Añadir enlace</strong> en la barra de herramientas o en el estado vacío.",
"Introduce un nombre y una URL completa que empiece por <code>http://</code> o <code>https://</code>.",
"Opcionalmente, añade un logotipo, elige o crea una categoría y asocia el enlace a una VM o un LXC.",
"Guarda el enlace. La nueva tarjeta se añade a la cuadrícula de inmediato.",
"Para modificar o eliminar un enlace personalizado, pulsa <strong>Editar</strong> y utiliza el lápiz de su tarjeta."
"Guarda el enlace. Su tarjeta aparece inmediatamente en la cuadrícula.",
"Para modificar o eliminar un enlace personalizado, pulsa <strong>Editar</strong> y el lápiz de su tarjeta."
],
"colField": "Campo",
"colRequired": "Obligatorio",
"colPurpose": "Finalidad",
"fields": [
{ "field": "Nombre", "required": "Sí", "purpose": "Título de la tarjeta y término de búsqueda." },
{ "field": "URL", "required": "Sí", "purpose": "Destino HTTP(S) completo que abre la tarjeta." },
{ "field": "URL del logotipo", "required": "No", "purpose": "Imagen remota que se muestra en la tarjeta." },
{ "field": "Categoría", "required": "No", "purpose": "Añade una etiqueta común y permite filtrar por categoría." },
{ "field": "Asociación a invitado", "required": "No", "purpose": "Vincula el enlace a una VM o un LXC y activa su acceso directo." }
{
"field": "Nombre",
"required": "Sí",
"purpose": "Título de la tarjeta y término de búsqueda."
},
{
"field": "URL",
"required": "Sí",
"purpose": "Destino HTTP(S) completo que abre la tarjeta."
},
{
"field": "URL del logotipo",
"required": "No",
"purpose": "Imagen remota que se muestra en la tarjeta."
},
{
"field": "Categoría",
"required": "No",
"purpose": "Añade una etiqueta común y permite filtrar por categoría."
},
{
"field": "Asociación al invitado",
"required": "No",
"purpose": "Vincula el enlace a una VM o un LXC y activa su acceso directo."
}
],
"editTitle": "Edita la fuente original",
"editBody": "El modo de edición solo muestra lápices en los enlaces personalizados. Para cambiar una tarjeta generada desde una aplicación LXC registrada, abre la <appTabLink>pestaña App</appTabLink> de ese contenedor y edita allí el enlace web guardado."
"editBody": "El modo de edición solo muestra lápices en enlaces personalizados. Para una tarjeta de aplicación LXC, abre la <appTabLink>pestaña App</appTabLink> del invitado y cambia allí el enlace guardado."
},
"categories": {
"heading": "Categorías y señales de actualización",
@@ -90,17 +110,17 @@
"El registro asistido por catálogo puede proponer una categoría para una aplicación LXC, pero el usuario siempre puede modificarla.",
"Desde el mismo selector se pueden crear categorías propias y reutilizarlas después en el filtro.",
"Los colores de las categorías son estables y se adaptan al tema claro u oscuro. El morado y el rojo se reservan para actualizaciones y estados de peligro.",
"En los enlaces web de Docker, ProxMenux relaciona la tarjeta con su contenedor o imagen y muestra el estado de actualización de esa imagen. Las actualizaciones de Docker Engine permanecen en la <updatesLink>pestaña Updates</updatesLink> del LXC."
"En Docker, la tarjeta se relaciona con su contenedor o imagen y muestra las actualizaciones de esa imagen. Las de Docker Engine permanecen en la <updatesLink>pestaña Actualizaciones</updatesLink> del LXC."
]
},
"persistence": {
"heading": "Persistencia y comportamiento de la caché",
"intro": "El panel está diseñado para abrirse con los datos ya disponibles en el Monitor, sin volver a analizar todos los invitados.",
"items": [
"Los enlaces personalizados se guardan de forma atómica en <code>/etc/proxmenux/custom_links.json</code> y se cargan en memoria al iniciar el Monitor.",
"Los enlaces personalizados se guardan atómicamente en <code>/etc/proxmenux/custom_links.json</code> y se cargan en memoria al iniciar Monitor.",
"Los enlaces registrados en LXCs siguen formando parte del registro guardado de cada aplicación; el panel Apps no los duplica en el archivo de enlaces personalizados.",
"Al crear, editar o eliminar un enlace personalizado, la lista en memoria se actualiza de inmediato.",
"La preferencia de ordenación se guarda solo en el navegador. No se sincroniza entre dispositivos ni usuarios.",
"La preferencia de orden solo se guarda en este navegador, sin sincronizarse entre dispositivos o usuarios.",
"La posición de Apps en la navegación principal se configura por separado en <settingsLink>Ajustes → Orden de navegación</settingsLink>."
]
},
@@ -109,19 +129,46 @@
"colProblem": "Situación",
"colResolution": "Solución",
"rows": [
{ "problem": "Una aplicación LXC está registrada, pero no aparece ninguna tarjeta", "resolution": "Abre su pestaña App y añade al menos un enlace web. El seguimiento de versión por sí solo no crea una tarjeta en el lanzador." },
{ "problem": "La URL o el logotipo son incorrectos", "resolution": "Edita el enlace personalizado desde Apps o modifica el enlace web en la pestaña App del LXC correspondiente." },
{ "problem": "Falta un servicio Docker", "resolution": "Edita la aplicación Docker registrada y guarda el puerto web publicado por el servicio como enlace web." },
{ "problem": "La flecha morada corresponde a otra actualización Docker", "resolution": "Revisa el nombre y la descripción del enlace web para que se puedan relacionar con el contenedor o la imagen correctos." },
{ "problem": "Apps se abre antes que Resumen del sistema", "resolution": "El primer elemento guardado en Ajustes → Orden de navegación se convierte en la pestaña inicial. Restaura el orden predeterminado o mueve Resumen a la primera posición." }
{
"problem": "Una aplicación LXC está registrada, pero no aparece ninguna tarjeta",
"resolution": "Abre su pestaña App y añade al menos un enlace web. El seguimiento de versión por sí solo no crea una tarjeta en el lanzador."
},
{
"problem": "La URL o el logotipo son incorrectos",
"resolution": "Edita el enlace personalizado desde Apps o modifica el enlace web en la pestaña App del LXC correspondiente."
},
{
"problem": "Falta un servicio Docker",
"resolution": "Edita la aplicación Docker registrada y guarda el puerto web publicado por el servicio como enlace web."
},
{
"problem": "La flecha morada corresponde a otra actualización Docker",
"resolution": "Revisa el nombre y la descripción del enlace web para que se puedan relacionar con el contenedor o la imagen correctos."
},
{
"problem": "Apps se abre antes que Resumen del sistema",
"resolution": "El primer elemento guardado en Ajustes → Orden de navegación se convierte en la pestaña inicial. Restaura el orden predeterminado o mueve Resumen a la primera posición."
}
]
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{ "label": "Pestaña App del LXC", "href": "/docs/monitor/dashboard/vms-lxcs/app", "tail": " — registrar aplicaciones, enlaces web y seguimiento opcional de versión." },
{ "label": "Pestaña Updates del LXC", "href": "/docs/monitor/dashboard/vms-lxcs/updates", "tail": " — configurar y ejecutar actualizaciones de aplicaciones, Docker Engine e imágenes." },
{ "label": "Pestaña Ajustes", "href": "/docs/monitor/dashboard/settings#navigation-order", "tail": " — cambiar el orden de navegación y la pestaña inicial." }
{
"label": "Pestaña App del LXC",
"href": "/docs/monitor/dashboard/vms-lxcs/app",
"tail": " — registrar aplicaciones, enlaces web y seguimiento opcional de versión."
},
{
"label": "Pestaña Updates del LXC",
"href": "/docs/monitor/dashboard/vms-lxcs/updates",
"tail": " — configurar y ejecutar actualizaciones de aplicaciones, Docker Engine e imágenes."
},
{
"label": "Pestaña Ajustes",
"href": "/docs/monitor/dashboard/settings#navigation-order",
"tail": " — cambiar el orden de navegación y la pestaña inicial."
}
]
}
}
@@ -1,6 +1,6 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Hardware | ProxMenux Documentation",
"title": "ProxMenux Monitor — Panel: Hardware | Documentación de ProxMenux",
"description": "La pestaña Hardware inventaría la máquina física: CPU y placa base, módulos de memoria, sensores térmicos, GPUs (con monitorización en tiempo real por slot e instalador de drivers en un clic), aceleradoras Coral TPU, resumen de almacenamiento con comprobaciones de velocidad de enlace, listas completas de dispositivos PCI y USB, consumo de energía, PSUs, ventiladores y estado del UPS."
},
"header": {
@@ -14,29 +14,29 @@
},
"thresholds": {
"title": "Colores de estado y umbrales aplicados aquí",
"intro": "Cada chip de temperatura y lectura de esta pestaña sigue la misma clasificación — <green/> <strong>verde</strong> por debajo de Warning, <amber/> <strong>ámbar</strong> entre Warning y Critical, <red/> <strong>rojo</strong> en Critical y por encima. Valores por defecto recomendados que vienen con ProxMenux:",
"intro": "Cada indicador y lectura de temperatura usa la misma escala: <green/> <strong>verde</strong> por debajo de Advertencia, <amber/> <strong>ámbar</strong> entre Advertencia y Crítico, <red/> <strong>rojo</strong> desde Crítico. Valores recomendados incluidos con ProxMenux:",
"items": [
"<strong>Temperatura de CPU</strong> — Warning 80 °C, Critical 90 °C.",
"<strong>Temperatura de disco</strong> — HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (warning / critical)."
"<strong>Temperatura de CPU</strong>: advertencia 80 °C, crítico 90 °C.",
"<strong>Temperatura de disco</strong>: HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (advertencia / crítico)."
],
"outro": "Cada valor es configurable por host — <link>Settings → Health Monitor Thresholds</link> es la fuente única de verdad y explica cómo ajustarlos."
"outro": "Los valores se configuran por host; <link>Ajustes → Umbrales del monitor de salud</link> documenta y centraliza su ajuste."
},
"sections": {
"heading": "Secciones",
"intro": "La pestaña renderiza de arriba abajo en este orden. Algunas secciones solo aparecen cuando el host tiene el hardware o la herramienta correspondiente instalada — se marcan <em>(condicional)</em> abajo.",
"systemInfoTitle": "System Information",
"intro": "Las secciones aparecen en este orden de arriba abajo. Algunas requieren el hardware o la herramienta correspondiente; se indican como <em>(condicional)</em>.",
"systemInfoTitle": "Información del sistema",
"systemInfoIntro": "Dos bloques uno al lado del otro, siempre presentes:",
"systemInfoItems": [
"<strong>CPU</strong> — nombre del modelo, microarquitectura, sockets / cores / threads, frecuencia base / boost, flags de virtualización (VT-x / AMD-V), topología de caché.",
"<strong>Placa base</strong> — vendor, modelo, versión de BIOS, fecha de BIOS, UUID SMBIOS. Útil para emparejar con páginas de descarga del fabricante al buscar actualizaciones de firmware."
"<strong>CPU</strong>: modelo, microarquitectura, sockets, núcleos, hilos, frecuencias base y turbo, capacidades de virtualización (VT-x / AMD-V) y topología de caché.",
"<strong>Placa base</strong>: fabricante, modelo, versión y fecha de BIOS y UUID SMBIOS. Sirve para localizar la página de descarga correcta del fabricante al buscar firmware."
],
"memoryTitle": "Memory Modules",
"memoryBody": "Una fila por slot poblado desde <code>dmidecode</code>: etiqueta del slot, tamaño del módulo, tipo (DDR4 / DDR5 / variantes ECC), velocidad (configurada y nominal), fabricante, part number y serial. Los slots vacíos se listan atenuados para que veas de un vistazo el margen de ampliación.",
"thermalTitle": "Thermal Monitoring",
"thermalIntro": "Siete sub-bloques alimentados por <code>lm-sensors</code>, <code>sysfs</code> y scrapers específicos por herramienta. Los sensores hwmon de almacenamiento se correlacionan con el dispositivo de bloques físico, por lo que cada unidad detectada incluye su modelo y la ruta <code>/dev/...</code>. Un bloque permanece oculto cuando no hay sensores en esa categoría.",
"memoryTitle": "Módulos de memoria",
"memoryBody": "Una fila por slot ocupado según <code>dmidecode</code>: etiqueta, capacidad del módulo, tipo (DDR4 / DDR5 / variantes ECC), velocidad configurada y nominal, fabricante, referencia y número de serie. Los slots vacíos aparecen atenuados para mostrar el margen de ampliación.",
"thermalTitle": "Monitoreo Térmico",
"thermalIntro": "Siete bloques alimentados por <code>lm-sensors</code>, <code>sysfs</code> y lectores específicos de cada herramienta. Los sensores hwmon de almacenamiento se asocian al dispositivo de bloques físico, con su modelo y ruta <code>/dev/...</code>. Cada bloque se oculta si no hay sensores en su categoría.",
"thermalItems": [
"<strong>CPU</strong> — temperaturas de package y por core.",
"<strong>GPU</strong> — sensores de GPU discreta vía <code>nvidia-smi</code> / <code>amdgpu_top</code> / iGPU Intel. Incluye hot-spot y memory-junction cuando el driver los expone.",
"<strong>CPU</strong>: temperatura del encapsulado y de cada núcleo.",
"<strong>GPU</strong>: sensores de GPU dedicada mediante <code>nvidia-smi</code> / <code>amdgpu_top</code> y de iGPU Intel. Incluye punto caliente y unión de memoria cuando el controlador los ofrece.",
"<strong>NVME</strong> — temperatura composite del controlador asociada a su namespace NVMe exacto.",
"<strong>HDD</strong> — lecturas de <code>drivetemp</code> para dispositivos de bloques rotacionales.",
"<strong>SSD</strong> — lecturas de <code>drivetemp</code> para dispositivos de bloques SATA/SAS no rotacionales.",
@@ -45,16 +45,16 @@
]
},
"graphics": {
"heading": "Graphics Cards",
"intro": "Cada controlador de vídeo detectado renderiza como su propia tarjeta con vendor, modelo, tipo (<em>Integrada</em> / <em>PCI</em> / BMC), slot PCI (BDF), kernel driver y lista de módulos. La tarjeta también expone un control inline <strong>Switch Mode</strong> que alterna la GPU entre compartición LXC (driver nativo) y passthrough a VM (<code>vfio-pci</code>) — mira <link>Switch GPU Mode (VM ↔ LXC)</link> para entender qué pasa en el host cuando lo pulsas.",
"heading": "Tarjetas gráficas",
"intro": "Cada controlador de vídeo aparece en una tarjeta con fabricante, modelo, tipo (<em>Integrada</em> / <em>PCI</em> / BMC), dirección PCI (BDF), controlador del kernel y módulos. <strong>Cambiar modo</strong> alterna entre compartir la GPU con LXC (controlador nativo) y passthrough a VM (<code>vfio-pci</code>). <link>Cambiar modo GPU (VM ↔ LXC)</link> explica sus efectos en el host.",
"vfioImageAlt": "Sección Graphics Cards mostrando una GPU integrada Matrox G200EH atada a mgag200 (Ready for LXC) y una NVIDIA Quadro P400 atada a vfio-pci (Ready for VM passthrough)",
"vfioImageCaption": "Dos GPUs detectadas: el chip BMC Matrox está en el driver nativo y listo para LXC; la NVIDIA Quadro P400 está atada a <code>vfio-pci</code>, lista para passthrough a VM.",
"lxcImageAlt": "Sección Graphics Cards mostrando una iGPU Intel UHD Graphics en i915 y una NVIDIA Quadro P1000 en el driver nvidia, ambas etiquetadas Ready for LXC containers",
"lxcImageAlt": "Tarjetas gráficas: iGPU Intel UHD Graphics con i915 y NVIDIA Quadro P1000 con nvidia, ambas listas para contenedores LXC",
"lxcImageCaption": "Mismo nodo después de devolver la tarjeta NVIDIA al driver nativo — ambas GPUs ahora Ready for LXC containers.",
"realtimeTitle": "Modal de monitorización en tiempo real",
"realtimeBody": "Pulsar una tarjeta de GPU abre una modal de monitorización por slot que sondea la herramienta del vendor adecuada cada tres segundos. La modal expone vendor, tipo, slot PCI, driver, módulo(s) del kernel, utilización en vivo de motores (Render/3D, Video, Blitter, VideoEnhance), clocks de gráficos y memoria, temperatura, consumo de potencia (cuando se reporta), uso de VRAM y una tabla Active Processes con carga de motor por proceso. Los datos se sirven desde <code>/api/gpu/&lt;slot&gt;/realtime</code>.",
"toolsIntro": "La herramienta de vendor usada por GPU:",
"headerVendor": "Vendor",
"realtimeTitle": "Ventana de monitorización en tiempo real",
"realtimeBody": "Pulsa una GPU para abrir su monitorización por slot, que consulta la herramienta del fabricante cada tres segundos. Muestra fabricante, tipo, slot PCI, controlador, módulos del kernel, uso de motores (Render/3D, Video, Blitter, VideoEnhance), frecuencias de gráficos y memoria, temperatura, consumo si está disponible, VRAM y procesos activos con carga por proceso. Datos de <code>/api/gpu/&lt;slot&gt;/realtime</code>.",
"toolsIntro": "Herramienta del fabricante usada para cada GPU:",
"headerVendor": "Proveedor",
"headerTool": "Herramienta",
"headerProject": "Proyecto",
"tools": [
@@ -65,7 +65,7 @@
"projectHref": "https://developer.nvidia.com/nvidia-system-management-interface"
},
{
"vendor": "Intel iGPU",
"vendor": "iGPU Intel",
"tool": "intel_gpu_top (igt-gpu-tools)",
"projectLabel": "gitlab.freedesktop.org",
"projectHref": "https://gitlab.freedesktop.org/drm/igt-gpu-tools"
@@ -78,97 +78,97 @@
},
{
"vendor": "Matrox / ASPEED (BMC)",
"tool": "— (solo display)",
"tool": "— (solo visualización)",
"projectLabel": "Detectado y etiquetado como BMC; sin bloque realtime."
}
],
"nvidiaImageAlt": "Modal de monitorización de GPU para una NVIDIA Quadro P1000: vendor NVIDIA, driver nvidia cargado, clock gráfico 1.26 GHz, clock de memoria 2.50 GHz, temperatura 50 °C, todas las barras de utilización de motor al 0 %, sin procesos activos, memoria total 4096 MiB",
"nvidiaImageCaption": "NVIDIA Quadro P1000 con el driver propietario cargado — clocks, temperatura, barras de motores y procesos activos todos visibles.",
"intelImageAlt": "Modal de monitorización de GPU para una iGPU Intel UHD Graphics en driver i915, mostrando 11.31 W de consumo, 1 % de carga en motor de video y un proceso ffmpeg consumiendo 8 MB",
"nvidiaImageAlt": "Monitorización de NVIDIA Quadro P1000: fabricante NVIDIA, controlador nvidia cargado, frecuencia gráfica 1.26 GHz, memoria 2.50 GHz, temperatura 50 °C, motores al 0 %, sin procesos activos y memoria total 4096 MiB",
"nvidiaImageCaption": "NVIDIA Quadro P1000 con controlador propietario: frecuencias, temperatura, barras de uso de motores y procesos activos.",
"intelImageAlt": "Monitorización de iGPU Intel UHD Graphics con controlador i915: consumo 11.31 W, carga de vídeo 1 % y proceso ffmpeg con 8 MB",
"intelImageCaption": "iGPU Intel con <code>i915</code> activo. La tabla Active Processes recoge un job ffmpeg usando el motor de video.",
"amdImageAlt": "Modal de monitorización de GPU para una GPU integrada AMD Lucienne en driver amdgpu, con barras de utilización de motor al 0 % y amdgpu_top listado como proceso activo",
"amdImageCaption": "iGPU AMD monitorizada a través de <code>amdgpu_top</code> — la propia herramienta aparece como proceso activo porque es el backend de polling en vivo.",
"installTitle": "Instalar el driver NVIDIA desde la modal",
"installBody": "Cuando una GPU NVIDIA está atada a <code>nouveau</code>/<code>nvidiafb</code> (sin driver propietario instalado), el bloque realtime no puede leer clocks, potencia ni carga por proceso. La modal entonces reemplaza las métricas con un botón <strong>Install NVIDIA Drivers</strong> que conecta directamente con el mismo script documentado en <link>Install NVIDIA Drivers (Host)</link>.",
"noDriverAlt": "Modal de monitorización de GPU para una NVIDIA Quadro P620 con módulos de kernel nvidiafb y nouveau cargados, un callout Extended Monitoring Not Available y un botón azul Install NVIDIA Drivers",
"amdImageAlt": "Monitorización de GPU integrada AMD Lucienne con amdgpu: motores al 0 % y amdgpu_top como proceso activo",
"amdImageCaption": "iGPU AMD monitorizada con <code>amdgpu_top</code>. La herramienta aparece como proceso activo porque obtiene los datos en vivo.",
"installTitle": "Instalar el controlador NVIDIA desde la ventana",
"installBody": "Si una GPU NVIDIA usa <code>nouveau</code>/<code>nvidiafb</code> sin controlador propietario, no se pueden leer frecuencias, consumo ni carga por proceso. La ventana muestra <strong>Instalar controladores NVIDIA</strong>, que ejecuta el script de <link>Instalar controladores NVIDIA (Host)</link>.",
"noDriverAlt": "Monitorización de NVIDIA Quadro P620 con nvidiafb y nouveau cargados, aviso Monitorización ampliada no disponible y botón azul Instalar controladores NVIDIA",
"noDriverCaption": "Sin driver propietario instalado todavía — la modal muestra un instalador de un solo clic.",
"promptAlt": "Diálogo de confirmación NVIDIA GPU Driver Installation listando las GPUs detectadas, contenedores LXC con passthrough NVIDIA y un par Yes/Cancel",
"promptAlt": "Confirmación de instalación de controladores NVIDIA, con GPU detectadas, contenedores LXC con passthrough NVIDIA y botones Sí/Cancelar",
"promptCaption": "Resumen pre-instalación: GPUs detectadas, contenedores LXC que ya tienen passthrough NVIDIA y qué hará el script. No se toca nada hasta que confirmas.",
"successAlt": "Salida de terminal mostrando el driver NVIDIA 580.105.08 instalado correctamente y nvidia-smi reportando una Quadro P620",
"successCaption": "Instalación correcta — el <code>.run</code> de NVIDIA construido vía DKMS, el servicio de persistencia en su sitio y <code>nvidia-smi</code> reportando la GPU.",
"warningTitle": "Elige una versión de driver que tu GPU soporte de verdad",
"warningBody": "Las ramas más nuevas de driver NVIDIA dejan de dar soporte a familias de GPU antiguas (p. ej. Maxwell / Kepler). Si la instalación termina pero <code>nvidia-smi</code> reporta <em>\"No devices were found\"</em> o DKMS da error, lo más probable es que la rama elegida no cubra tu GPU — vuelve a lanzar el instalador y elige una rama más antigua (legacy 470.x para tarjetas de era Kepler, etc.). NVIDIA publica la compatibilidad por GPU en la <a>página oficial de búsqueda de drivers</a>.",
"warningBody": "Las ramas nuevas de NVIDIA eliminan soporte para GPU antiguas, como Maxwell o Kepler. Si termina la instalación pero <code>nvidia-smi</code> muestra <em>\"No devices were found\"</em> o falla DKMS, puede que la rama no sea compatible. Repite el instalador con una rama anterior, como legacy 470.x para Kepler. Consulta la compatibilidad en la <a>página oficial de búsqueda de controladores</a>.",
"whereGoIntro": "Por dónde seguir desde aquí:",
"whereGoItems": [
"<link1>Install NVIDIA Drivers (Host)</link1> — recorrido completo del instalador, matriz de compatibilidad de kernel, parche opcional NVENC y propagación a LXC.",
"<link2>Switch GPU Mode (VM ↔ LXC)</link2> — qué hace realmente el control inline <em>Switch Mode</em>.",
"<link3>Add GPU to VM (Passthrough)</link3> y <link4>Add GPU to LXC</link4> — asignación por primera vez de una GPU sin atar."
"<link1>Instalar controladores NVIDIA (Host)</link1>: guía del instalador, matriz de compatibilidad del kernel, parche NVENC opcional y propagación a LXC.",
"<link2>Cambiar modo GPU (VM ↔ LXC)</link2>: efectos del control <em>Cambiar modo</em> de la tarjeta.",
"<link3>Añadir GPU a VM (passthrough)</link3> y <link4>Añadir GPU a LXC</link4>: primera asignación de una GPU sin asociar."
]
},
"coral": {
"heading": "Coral TPU / Aceleradoras de IA",
"subHeading": "(condicional)",
"intro": "Se renderiza cuando el host tiene dispositivos Google Coral u otras aceleradoras de IA conectadas. Cada dispositivo abre una modal con su tipo de conexión (M.2 / mini-PCIe / USB), ancho de enlace PCIe, vendor / product ID, kernel driver (<code>apex</code> para PCIe, <code>libedgetpu</code> para USB), módulos del kernel (<code>gasket</code> + <code>apex</code>), nodos de dispositivo (<code>/dev/apex_*</code>), estado del runtime Edge TPU, temperatura en vivo y los umbrales de aviso de hardware del firmware.",
"intro": "Aparece cuando hay dispositivos Google Coral u otras aceleradoras de IA conectadas. Cada dispositivo abre sus detalles: conexión (M.2 / mini-PCIe / USB), ancho PCIe, ID de fabricante/producto, soporte de software (<code>apex</code> del kernel para PCIe, <code>libedgetpu</code> de usuario para USB), módulos (<code>gasket</code> + <code>apex</code>), nodos (<code>/dev/apex_*</code>), estado del runtime Edge TPU, temperatura en vivo y umbrales de aviso del firmware.",
"imageAlt": "Modal de detalle Coral Edge TPU: conexión PCIe / M.2, enlace PCIe 5.0 GT/s x1, vendor 1ac1:089a, kernel driver apex, módulos gasket y apex cargados, /dev/apex_0 presente, Edge TPU Runtime no instalado, temperatura 53.5 °C con umbrales de aviso de hardware",
"imageCaption": "Coral M.2 con los módulos de kernel del host cargados, el nodo de dispositivo arriba y los avisos de temperatura del firmware expuestos. La línea del runtime se pone verde una vez instalado el runtime Edge TPU correspondiente.",
"pathsIntro": "Existen dos rutas de instalación dependiendo del form factor:",
"pathsIntro": "Hay dos vías de instalación según el formato:",
"pathsItems": [
"<strong>M.2 / Mini-PCIe</strong> — el host necesita los módulos de kernel <code>gasket</code> + <code>apex</code> construidos vía DKMS para que el nodo de dispositivo <code>/dev/apex_0</code> aparezca en el arranque.",
"<strong>USB Accelerator</strong> — el host solo necesita el runtime de espacio de usuario Edge TPU (<code>libedgetpu1-std</code>) desde el repositorio APT de Google."
],
"outro": "Ambas las gestiona una única entrada de ProxMenux — <installLink>Install Coral TPU on the Host</installLink> — que auto-detecta lo que tienes. El contexto y el runtime oficial viven en <a>coral.ai/docs</a>. Una vez listo el lado del host, entrega el dispositivo a un contenedor con <lxcLink>Add Coral TPU to LXC</lxcLink>."
"outro": "Una sola entrada, <installLink>Instalar Coral TPU en el host</installLink>, detecta y gestiona ambos tipos. Consulta el contexto y runtime oficial en <a>coral.ai/docs</a>. Después, asígnalo a un contenedor con <lxcLink>Añadir Coral TPU a LXC</lxcLink>."
},
"storage": {
"heading": "Storage Summary",
"intro": "Cada dispositivo de bloque que conoce el kernel, agrupado por tipo. Para cada disco obtienes el nombre del kernel (<code>sda</code>, <code>nvme0n1</code>, <code>zram0</code> …), la etiqueta de tipo (<em>SSD</em>, <em>HDD</em>, <em>NVMe SSD</em>), la cadena del modelo y la información del enlace negociado. Pulsa cualquier disco para abrir una modal de info de hardware con modelo, serial, capacidad, interfaz y velocidad de enlace actual vs máxima.",
"heading": "Resumen de almacenamiento",
"intro": "Todos los dispositivos de bloques conocidos por el kernel, agrupados por tipo. Cada disco muestra su nombre (<code>sda</code>, <code>nvme0n1</code>, <code>zram0</code>…), tipo (<em>SSD</em>, <em>HDD</em>, <em>NVMe SSD</em>), modelo y enlace negociado. Pulsa para abrir modelo, número de serie, capacidad, interfaz y velocidad actual y máxima.",
"imageAlt": "Tarjeta Storage Summary listando once dispositivos de bloque (SSDs SATA, HDDs SATA, SSDs NVMe y zram) con cadenas de modelo y velocidades de enlace negociadas; los dos discos NVMe muestran 3.0 x4 con la velocidad actual resaltada",
"imageCaption": "Once dispositivos en este nodo. Los enlaces SATA se imprimen como <em>SATA &lt;version&gt;, &lt;Gb/s&gt; (current: ...)</em>; los discos NVMe se imprimen como <em>&lt;PCIe gen&gt; x&lt;width&gt;</em>.",
"nvmeBody": "Para los discos NVMe la línea por tarjeta muestra tanto el enlace negociado como el máximo que soporta el dispositivo. Cuando ambos no coinciden (p. ej. un SSD Gen3 x4 corriendo a <strong>3.0 x1</strong> porque está sentado en un slot del chipset cableado a un solo lane), la velocidad actual se renderiza en ámbar para que el downgrade sea visible de un vistazo — útil al diagnosticar discos inesperadamente lentos o después de que una actualización de BIOS reorganice los lanes.",
"imageCaption": "Once dispositivos en este nodo. Los enlaces SATA aparecen como <em>SATA &lt;version&gt;, &lt;Gb/s&gt; (current: ...)</em>; los NVMe como <em>&lt;PCIe gen&gt; x&lt;width&gt;</em>.",
"nvmeBody": "La línea de cada NVMe compara el enlace negociado con el máximo admitido. Si difieren, como un SSD Gen3 x4 funcionando a <strong>3.0 x1</strong> en un slot de un solo carril, el valor actual aparece en ámbar. Permite detectar enlaces limitados al investigar discos lentos o cambios de carriles tras actualizar BIOS.",
"nvmeModalAlt": "Modal de detalle de disco NVMe para nvme0n1: tipo NVMe SSD, 953.9 GB de capacidad, velocidad actual de enlace 3.0 x1 resaltada en ámbar, velocidad máxima 3.0 x4, modelo WDC CL SN720, número de serie, interfaz PCIe/NVMe",
"nvmeModalCaption": "Modal NVMe mostrando el downgrade de lanes — el disco soporta x4 pero el slot está cableado x1.",
"outro": "Los datos SMART, los self-tests, el historial y el informe PDF de disco viven una pestaña a la derecha, en <storageLink>Panel: pestaña Almacenamiento</storageLink>. Los mismos datos alimentan el script en <smartLink>SMART Disk Health & Test</smartLink> — lanzar un test long desde el script escribe el JSON que el Monitor muestra en <em>Storage → History</em>."
"nvmeModalCaption": "Detalles NVMe con enlace limitado: el disco admite x4, pero el slot está conectado a x1.",
"outro": "Los datos SMART, autopruebas, historial e informe PDF están en <storageLink>Panel: Almacenamiento</storageLink>. Los mismos datos alimentan <smartLink>Salud y pruebas SMART de discos</smartLink>. Una prueba larga desde el script escribe el JSON mostrado por Monitor en <em>Almacenamiento → Historial</em>."
},
"pci": {
"heading": "PCI Devices",
"intro": "Cada dispositivo direccionable por PCI, identificado por su <strong>BDF PCI</strong> (Bus:Device.Function — p. ej. <code>03:00.0</code>) y su clase de dispositivo (<em>Storage Controller</em>, <em>USB Controller</em>, <em>Graphics Card</em>, <em>Network Controller</em>, <em>Audio Controller</em> …). Cada tarjeta muestra el fabricante, el nombre del dispositivo y el <strong>kernel driver actualmente atado</strong> — que es el campo que realmente quieres al diagnosticar passthrough, grupos IOMMU o una tarjeta que el host no esté manejando correctamente.",
"heading": "Dispositivos PCI",
"intro": "Dispositivos PCI identificados por <strong>BDF PCI</strong> (Bus:Device.Function, p. ej. <code>03:00.0</code>) y clase (<em>Controlador de almacenamiento</em>, <em>Controlador USB</em>, <em>Tarjeta gráfica</em>, <em>Controlador de red</em>, <em>Controlador de audio</em>…). Cada tarjeta muestra fabricante, nombre y <strong>controlador del kernel asociado</strong>, útil para diagnosticar passthrough, grupos IOMMU o controladores incorrectos.",
"imageAlt": "Sección PCI Devices listando quince dispositivos agrupados por clase: storage controllers en ahci/nvme, USB controllers, tarjetas gráficas (una en vfio-pci, otra en el driver nativo), network controllers en igb / tg3, un audio controller junto a una GPU pasada por passthrough",
"imageCaption": "Quince dispositivos en este nodo. Fíjate en la GPU y su función de audio compañera, ambas atadas a <code>vfio-pci</code> — esa es una tarjeta preparada para passthrough a VM.",
"bdfTitle": "Leer el BDF",
"bdfBody": "<code>03:00.0</code> significa bus PCI <code>03</code>, dispositivo <code>00</code>, función <code>0</code>. Los dispositivos multifunción como las GPUs discretas suelen reclamar <code>.0</code> para la GPU y <code>.1</code> para la función de audio HDMI — ambos hay que pasarlos por passthrough juntos, por eso <link>Switch GPU Mode</link> también gestiona la limpieza de la función de audio huérfana al salir del modo VM."
"bdfBody": "<code>03:00.0</code> indica bus PCI <code>03</code>, dispositivo <code>00</code> y función <code>0</code>. Las GPU dedicadas suelen usar <code>.0</code> para gráficos y <code>.1</code> para audio HDMI. Ambas funciones se pasan juntas a la VM; por eso <link>Cambiar modo GPU</link> limpia también el audio que quedaría sin asociar al salir del modo VM."
},
"usb": {
"heading": "USB Devices",
"intro": "Cada dispositivo USB que enumera el host, con cadenas de fabricante / producto, versión USB, la dirección <code>bus:device</code>, el par <code>vendor:product</code> y el kernel driver. El renderer también clasifica roles comunes — <em>Communications</em> (sticks Z-Wave / Zigbee), <em>UPS</em>, almacenamiento, HID — para que veas de un vistazo cuál de tus sticks es cuál sin cruzar IDs.",
"imageAlt": "Tarjeta USB Devices listando tres dispositivos: un Z-Stick Z-Wave Aeotec, un coordinador Zigbee ConBee II y un UPS Ellipse ECO, cada uno con versión USB, dirección, vendor:product ID y driver atado",
"heading": "Dispositivos USB",
"intro": "Dispositivos USB con fabricante y producto, versión USB, dirección <code>bus:device</code>, ID <code>vendor:product</code> y controlador del kernel. Se clasifican por función: <em>Comunicaciones</em> (adaptadores Z-Wave / Zigbee), <em>SAI</em>, almacenamiento o HID. Así se identifican sin comparar sus ID.",
"imageAlt": "Dispositivos USB: Aeotec Z-Wave Z-Stick, coordinador Zigbee ConBee II y SAI Ellipse ECO, con versión USB, dirección, ID vendor:product y controlador asociado",
"imageCaption": "Tres dispositivos USB — dos radios de domótica en <code>usbfs</code> y un UPS en <code>usbfs</code> (NUT le habla a través de libusb)."
},
"power": {
"heading": "Power Consumption",
"heading": "Consumo de energía",
"subHeading": "(condicional)",
"intro": "Se renderiza solo cuando el host expone telemetría de energía. Se exponen dos fuentes independientes cuando están disponibles:",
"intro": "Aparece si el host ofrece telemetría de potencia. Muestra dos fuentes independientes cuando están disponibles:",
"items": [
"<strong>Consumo total ACPI / IPMI</strong> — watios de todo el sistema desde un sensor a nivel de placa o el BMC. Típico en placas de servidor.",
"<strong>Consumo de package CPU</strong> — leído de los contadores Intel RAPL (o equivalente AMD). Útil para separar el consumo de CPU del resto del sistema en placas consumer que no exponen una cifra total."
"<strong>Consumo total ACPI / IPMI</strong>: potencia de todo el sistema desde un sensor de la placa o el BMC. Habitual en placas de servidor.",
"<strong>Consumo del encapsulado CPU</strong>: contadores Intel RAPL o equivalente AMD. Distingue el consumo de CPU del resto en placas de consumo sin sensor total."
],
"supplyImageAlt": "Sección Power Consumption mostrando 198 W de consumo total vía interfaz ACPI, más una tarjeta Power Supplies con dos PSUs ambas reportando OK (salida de 185 W y 5 W)",
"supplyImageAlt": "Consumo: 198 W totales por ACPI y dos fuentes de alimentación con estado OK y salida de 185 W y 5 W",
"supplyImageCaption": "Placa de servidor con un único sensor de energía ACPI y PSUs duales reportadas a través de IPMI — la segunda PSU es la redundante, en idle a 5 W.",
"cpuImageAlt": "Sección Power Consumption en una placa consumer mostrando solo CPU Power 8.7 W vía Intel RAPL",
"cpuImageCaption": "Placa consumer sin sensor de todo el sistema — la sección cae a RAPL solo-CPU."
"cpuImageAlt": "Consumo en una placa de uso doméstico: solo 8.7 W de CPU medidos por Intel RAPL",
"cpuImageCaption": "Placa de uso doméstico sin sensor de consumo total: se muestra solo CPU mediante RAPL."
},
"psu": {
"heading": "Power Supplies",
"heading": "Fuentes de alimentación",
"subHeading": "(condicional)",
"body": "Máquinas con placa de servidor / PSU dual vía IPMI: presencia (PSU 1 / PSU 2 / …), voltaje de entrada, watios de salida, flag OK / failed. Lo primero que compruebas tras un parpadeo de luz en un nodo con PSUs redundantes."
"body": "En máquinas con placa de servidor o fuentes dobles, IPMI muestra presencia (PSU 1 / PSU 2 / …), tensión de entrada, potencia de salida y estado correcto/fallo. Compruébalo tras una interrupción eléctrica en nodos con fuentes redundantes."
},
"fans": {
"heading": "System Fans",
"heading": "Ventiladores del sistema",
"subHeading": "(condicional)",
"body": "RPM por ventilador con un pequeño sparkline (cuando se soporta). En placas sin reporte por ventilador la sección cae a una única lectura del ventilador de chasis."
"body": "RPM de cada ventilador con minigráfico de tendencia, si se admite. Sin datos individuales, muestra una sola lectura del ventilador del chasis."
},
"ups": {
"heading": "UPS Status",
"heading": "Estado del SAI",
"subHeading": "(condicional)",
"body": "Se renderiza cuando hay un servidor NUT (Network UPS Tools) configurado y accesible. Muestra: estado (online / on battery / charging / low battery), porcentaje de carga de batería, estimación de runtime, porcentaje de carga, voltaje de entrada, modelo y firmware. Los mismos datos alimentan la categoría <em>Security & Certificates</em> del Monitor de salud — un UPS que pasa a batería sale inmediatamente."
"body": "Aparece si hay un servidor NUT (Network UPS Tools) configurado y accesible. Muestra estado (en línea / batería / cargando / batería baja), carga de batería, autonomía estimada, porcentaje de carga soportada, tensión de entrada, modelo y firmware. Alimenta también <em>Seguridad y certificados</em> del monitor de salud: el paso a batería se señala inmediatamente."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -184,12 +184,12 @@
{
"section": "Valores de sensores en vivo",
"endpoint": "/api/hardware/live",
"source": "<code>sensors</code> (lm-sensors) junto con <code>/sys/class/hwmon</code> y <code>/sys/block</code> para identificar los dispositivos de almacenamiento. Las temperaturas permanecen en vivo; solo la topología hwmon-dispositivo se guarda en caché durante 60 segundos."
"source": "<code>sensors</code> (lm-sensors), <code>/sys/class/hwmon</code> y <code>/sys/block</code> identifican los dispositivos de almacenamiento. Las temperaturas son en vivo; solo se guarda en caché 60 segundos la asociación hwmon-dispositivo."
},
{
"section": "Historial de temperatura de CPU",
"endpoint": "/api/temperature/history",
"source": "Serie temporal muestreada por el Monitor de salud cada 5 min y persistida a SQLite."
"source": "Serie temporal registrada cada 60 segundos por el recolector de temperatura y almacenada en SQLite."
},
{
"section": "Métricas en vivo de GPU",
@@ -197,31 +197,31 @@
"source": "NVIDIA: <code>nvidia-smi --query-gpu=...</code>. Intel: <code>intel_gpu_top</code>. AMD: sysfs <code>/sys/class/drm/cardN</code>."
}
],
"codeComment1": "# Cross-check del inventario contra la vista del SO",
"codeComment1": "# Contrastar el inventario con la información del sistema operativo",
"codeComment2": "# Confirmar la tarjeta GPU que ve el panel"
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{
"label": "Install NVIDIA Drivers (Host)",
"label": "Instalar controladores NVIDIA (Host)",
"href": "/docs/hardware/nvidia-host",
"tail": " — lo que ejecuta el botón de instalación de la modal de GPU."
"tail": " — script que ejecuta el botón de instalación de la ventana de GPU."
},
{
"label": "Switch GPU Mode (VM ↔ LXC)",
"label": "Cambiar modo GPU (VM ↔ LXC)",
"href": "/docs/hardware/switch-gpu-mode",
"tail": " — lo que el conmutador de modo inline en cada tarjeta de GPU le hace al host."
},
{
"label": "Install Coral TPU on the Host",
"label": "Instalar Coral TPU en el host",
"href": "/docs/hardware/install-coral-tpu-host",
"tail": " — la instalación del módulo de kernel / runtime de Coral."
"tail": " — instalación del módulo del kernel y runtime de Coral."
},
{
"label": "SMART Disk Health & Test",
"label": "Prueba de salud de disco SMART",
"href": "/docs/disk-manager/smart-disk-test",
"tail": " — el script detrás de los datos SMART que muestra la vista en detalle de disco de la pestaña Almacenamiento."
"tail": " — script que produce los datos SMART de los detalles de disco en Almacenamiento."
},
{
"label": "Panel: pestaña Almacenamiento",
@@ -231,12 +231,12 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la categoría CPU y Temperatura que consume los mismos sensores."
"tail": " — categoría CPU y Temperatura, que usa los mismos sensores."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints de hardware y GPU."
"tail": " — endpoints de hardware y GPU."
},
{
"label": "Índice del panel",
@@ -1,16 +1,16 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel | ProxMenux Documentation",
"description": "El panel es la interfaz principal de ProxMenux Monitor: diez pestañas de contenido, incluido el lanzador Apps, además de la cabecera global y un orden de navegación configurable."
"title": "ProxMenux Monitor — Panel | Documentación de ProxMenux",
"description": "El panel es la interfaz principal de ProxMenux Monitor: diez pestañas, incluido el lanzador Apps, una cabecera global y un orden de navegación configurable."
},
"header": {
"title": "Panel",
"description": "El panel es la vista diaria de ProxMenux Monitor: diez pestañas de contenido, incluido el lanzador Apps, además de una cabecera global y un orden de navegación configurable.",
"description": "La vista diaria de ProxMenux Monitor: diez pestañas, incluido el lanzador Apps, una cabecera global y un orden de navegación configurable.",
"section": "ProxMenux Monitor"
},
"oneHeader": {
"title": "Una cabecera, diez pestañas",
"body": "La cabecera (logo, nombre del nodo, información de estado, uptime, refresco, conmutador de tema) permanece visible en todo momento. La pestaña activa que hay debajo cambia el área de contenido entera. El color de la información de estado refleja la peor categoría del <link>Monitor de salud</link> — es el mismo dato visto desde el panel."
"body": "La cabecera (logo, nombre del nodo, indicador de estado, tiempo activo, actualización y tema) permanece visible. La pestaña activa cambia toda el área de contenido. El color del indicador refleja la peor categoría del <link>Monitor de estado</link>: el mismo dato mostrado en el panel."
},
"tabs": {
"heading": "Las diez pestañas",
@@ -24,9 +24,9 @@
"owns": "Widgets de CPU, memoria y temperatura; contador de VMs y LXCs activos; gráficas históricas y resúmenes de almacenamiento y red. Es la pestaña inicial mientras no se personalice el orden de navegación."
},
{
"name": "Apps",
"name": "Aplicaciones",
"linksTo": "/docs/monitor/dashboard/apps",
"owns": "Lanzador unificado para enlaces web registrados en LXCs y enlaces personalizados, con categorías, búsqueda, acceso al invitado y señales de actualización por aplicación."
"owns": "Lanzador unificado de enlaces web de LXC registrados y enlaces personalizados, con categorías, búsqueda, accesos al invitado y señales de actualización por aplicación."
},
{
"name": "Almacenamiento",
@@ -34,11 +34,11 @@
},
{
"name": "Red",
"owns": "Cada interfaz (física / bond / bridge / OVS), IP/MAC, gráficas RX/TX, RRD histórica por interfaz."
"owns": "Interfaces físicas, bond, bridge y OVS, direcciones IP/MAC, gráficas RX/TX e histórico RRD por interfaz."
},
{
"name": "VMs y LXCs",
"owns": "Inventario de guests, vista en detalle de config / métricas / logs, acciones start / stop / reboot / shutdown."
"owns": "Inventario de invitados, detalles de configuración, métricas y registros, acciones de iniciar, detener, reiniciar y apagar."
},
{
"name": "Hardware",
@@ -50,7 +50,7 @@
},
{
"name": "Terminal",
"owns": "Shell en el navegador al host o a cualquier VM/CT, sobre <code>xterm.js</code> y WebSockets."
"owns": "Shell del host o de cualquier VM/CT en el navegador, con <code>xterm.js</code> sobre WebSockets."
},
{
"name": "Seguridad",
@@ -58,19 +58,19 @@
},
{
"name": "Ajustes",
"owns": "Idioma del Monitor, orden de navegación, canales de notificación, proveedor de IA, umbrales de salud, exclusiones e inventario de optimizaciones."
"owns": "Idioma de Monitor, orden de navegación, canales de notificación, proveedor IA, umbrales de estado, exclusiones e inventario de optimizaciones posteriores a la instalación."
}
]
},
"headerAnatomy": {
"heading": "Anatomía de la cabecera",
"items": [
"<strong>Logo de ProxMenux.</strong> El logo cambia a la variante \"actualización disponible\" cuando se detecta una nueva release del Monitor.",
"<strong>Identidad del nodo</strong> — el nombre del nodo Proxmox resuelto desde <code>pvesh get /nodes</code>, con fallback a <code>hostname</code>.",
"<strong>Información del estado de salud</strong> — Healthy (verde), Warning (amarillo), Critical (rojo). Pulsa encima para abrir la modal del Monitor de salud. Aparece una insignia azul extra de <em>info</em> cuando hay items descartados que siguen dentro de su ventana de supresión.",
"<strong>Uptime</strong> — tiempo desde el último arranque del host, formateado de forma legible.",
"<strong>Botón de refresco</strong> — relanza todas las llamadas API en vivo sin recargar la página entera.",
"<strong>Conmutador de tema</strong> — claro / oscuro / sistema. Persiste en <code>localStorage</code>."
"<strong>Logo y nombre del producto</strong> a la izquierda. El logo adopta la variante «actualización disponible» cuando se detecta una versión más reciente de Monitor.",
"<strong>Identidad del nodo</strong>: nombre obtenido con <code>pvesh get /nodes</code>, usando <code>hostname</code> como alternativa.",
"<strong>Indicador de estado</strong>: Correcto (verde), Advertencia (amarillo), Crítico (rojo). Abre el Monitor de estado al pulsarlo. Una insignia azul <em>info</em> aparece si hay elementos descartados cuyo periodo de supresión sigue vigente.",
"<strong>Tiempo activo</strong>: tiempo de funcionamiento del host en formato legible.",
"<strong>Botón de actualización</strong>: repite las llamadas API de datos en directo sin recargar toda la página.",
"<strong>Selector de tema</strong>: claro, oscuro o sistema. Se guarda en <code>localStorage</code>."
]
},
"whereNext": {
@@ -79,7 +79,7 @@
{
"label": "Pestaña Apps",
"href": "/docs/monitor/dashboard/apps",
"tail": " — el lanzador unificado de enlaces web y su relación con las aplicaciones registradas en LXCs."
"tail": " — lanzador unificado de enlaces web y relación con las aplicaciones LXC registradas."
},
{
"label": "Pestaña Resumen del sistema",
@@ -89,7 +89,7 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la modal detrás de la información de estado, vista en profundidad de las diez categorías."
"tail": " — ventana del indicador de estado, con detalle de diez categorías."
},
{
"label": "Arquitectura",
@@ -1,16 +1,16 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Red | ProxMenux Documentation",
"description": "La pestaña Red inventaría cada interfaz del host: NICs físicas, bridges, bonds, VLANs y las interfaces virtuales de VM/LXC. La vista en detalle por interfaz muestra IP / MAC / estado / miembros del bond / tráfico desde el arranque y una gráfica RRD histórica."
"title": "ProxMenux Monitor — Panel: pestaña Red | Documentación de ProxMenux",
"description": "La pestaña Red enumera todas las interfaces del host: físicas, puentes, enlaces agrupados, VLAN e interfaces virtuales VM/LXC. El detalle muestra IP, MAC, estado, miembros del enlace agrupado, tráfico desde el arranque e historial RRD."
},
"header": {
"title": "Panel: pestaña Red",
"description": "Cada interfaz que reporta el kernel — NICs físicas, bridges, bonds, VLANs y puertos virtuales de VM/LXC — agrupadas en tres tarjetas. Cada fila es pulsable y abre una vista en detalle con direccionamiento, contadores de tráfico y datos RRD históricos.",
"description": "Todas las interfaces que detecta el kernel —físicas, puentes, enlaces agrupados, VLAN y puertos virtuales VM/LXC— se agrupan en tres tarjetas. Pulsa una fila para ver direcciones, contadores de tráfico e historial RRD.",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "En vivo + histórico, ambos incluidos",
"body": "El estado en vivo viene de <code>psutil.net_if_stats()</code> y <code>ip</code>; el ancho de banda histórico del almacén RRD de Proxmox vía <code>/api/network/&lt;interface&gt;/metrics</code>. La página refresca cada ~5 segundos los contadores en vivo y obtiene datos RRD frescos bajo demanda para la gráfica."
"title": "Datos actuales e históricos",
"body": "El estado actual procede de <code>psutil.net_if_stats()</code> e <code>ip</code>; el historial de ancho de banda, del almacén RRD de Proxmox mediante <code>/api/network/&lt;interface&gt;/metrics</code>. Los contadores se actualizan cada 5 segundos aproximadamente y el gráfico obtiene datos RRD cuando se solicitan."
},
"topRow": {
"heading": "Fila superior: cuatro tarjetas de estadísticas",
@@ -18,122 +18,122 @@
"headerWhat": "Qué muestra",
"rows": [
{
"card": "Network Traffic",
"card": "Tráfico de red",
"what": "Tasa agregada RX / TX a lo largo de todas las interfaces, formateada en la unidad correcta (bps / Kbps / Mbps / Gbps)."
},
{
"card": "Active Interfaces",
"what": "Dos contadores: <em>Physical X / Y</em> y <em>Bridges X / Y</em> (activas sobre total). El primer contador que miras cuando algo deja de funcionar."
"card": "Interfaces activas",
"what": "Dos contadores: <em>Physical X / Y</em> y <em>Bridges X / Y</em>, con interfaces activas respecto al total. Es un primer punto de comprobación cuando algo deja de funcionar."
},
{
"card": "Network Status",
"what": "Veredicto rápido — Healthy / Warning / Critical en función del estado del enlace, alcanzabilidad del gateway e integridad del bridge. Refleja la categoría <em>Network Interfaces</em> del Monitor de salud."
"card": "Estado de la red",
"what": "Estado rápido: Correcto / Aviso / Crítico según el enlace, la accesibilidad de la puerta de enlace y la integridad del puente. Refleja la categoría <em>Interfaces de red</em> de Health Monitor."
},
{
"card": "Network Latency",
"what": "Round-trip time al gateway con un sparkline. Pulsar la tarjeta abre la <strong>modal Network Latency</strong> documentada más abajo — vista histórica + test de ping bajo demanda contra gateway / Cloudflare / Google con un informe PDF descargable."
"card": "Latencia de red",
"what": "Tiempo de ida y vuelta a la puerta de enlace con un minigráfico. Al pulsar, abre el <strong>diálogo Latencia de red</strong> descrito más abajo: historial y prueba de ping a petición contra la puerta de enlace, Cloudflare o Google, con informe PDF descargable."
}
]
},
"flow": {
"heading": "Diagrama Network Flow",
"intro": "Entre la fila superior y las tres tarjetas de grupos, la pestaña renderiza una vista de topología en vivo llamada <strong>Network Flow</strong>. Dibuja cada camino que un paquete puede tomar a través del host — NICs físicas en un extremo, bridges en el medio, VMs y contenedores en el otro — con pulsos animados que muestran el tráfico rx/tx en tiempo real sobre cada enlace.",
"intro": "Entre la fila superior y las tres tarjetas aparece la topología en directo <strong>Network Flow</strong>. Muestra los recorridos de los paquetes: interfaces físicas en un extremo, puentes en medio y máquinas virtuales y contenedores en el otro. Los pulsos animados representan el tráfico rx/tx actual de cada enlace.",
"imageAlt": "Diagrama Network Flow — NICs a la izquierda, host y bridges en el medio, VMs y LXCs a la derecha, con pulsos animados en cada conexión",
"imageCaption": "Network Flow — nodos con código de color más cometas animados cuya dirección y grosor reflejan el tráfico en vivo.",
"elementsTitle": "Qué muestra el diagrama",
"elementsIntro": "Cada nodo es una entidad del mismo inventario que usan las tarjetas de abajo, pero organizadas como topología para que las relaciones se vean de un vistazo:",
"elementsIntro": "Cada nodo representa una entidad del mismo inventario que las tarjetas inferiores. La disposición como topología permite ver sus relaciones de un vistazo:",
"elements": [
"<strong>NICs</strong> (ámbar) — cada interfaz física con enlace activo. Las interfaces reportadas como down se dibujan atenuadas.",
"<strong>Host</strong> (ámbar) — el propio host Proxmox, situado entre las NICs y los bridges. Renderizado como anclaje fijo; no clicable.",
"<strong>Bridges</strong> (cian) — bridges Linux y OVS. Sólo se dibujan los bridges que llevan al menos un guest activo; los bridges sin uso se ocultan para que el diagrama muestre lo que realmente mueve tráfico.",
"<strong>LXCs</strong> (cian) — contenedores en ejecución conectados a un bridge.",
"<strong>VMs</strong> (púrpura) — máquinas virtuales en ejecución conectadas a un bridge.",
"Los guests offline (VMs / contenedores parados) se ocultan."
"<strong>NIC</strong> (ámbar): interfaces físicas con enlace activo; las inactivas aparecen atenuadas.",
"<strong>Host</strong> (ámbar): el host Proxmox entre las interfaces físicas y los puentes. Es un punto fijo y no se puede pulsar.",
"<strong>Puentes</strong> (cian): puentes Linux y OVS con al menos una máquina invitada activa. Los que no se usan se ocultan para centrar el diagrama en el tráfico actual.",
"<strong>LXC</strong> (cian): contenedores en ejecución conectados a un puente.",
"<strong>VM</strong> (morado): máquinas virtuales en ejecución conectadas a un puente.",
"Las máquinas virtuales y los contenedores detenidos se ocultan."
],
"pulsesTitle": "Qué codifica la animación",
"pulsesBody": "Los cometas animados que viajan por cada arista representan tráfico en vivo:",
"pulses": [
"<strong>Dirección</strong> — un pulso que fluye hacia la NIC es <em>tx</em> del guest; hacia el guest es <em>rx</em>.",
"<strong>Grosor de trazo</strong> escala con el rate combinado rx+tx del guest. Un guest inactivo dibuja una línea animada tenue; uno con carga la dibuja gruesa.",
"<strong>Halo de la cabeza del cometa</strong> — templado hacia ~1 MB/s, caliente a ≥30 MB/s. Útil para detectar de un vistazo qué guest está dominando una NIC.",
"<strong>Click</strong> — cada nodo excepto el host es clicable y abre el mismo modal de detalle por interfaz documentado más abajo. Pulsar el host es intencionadamente un no-op — no hay modal a nivel de host en esta vista."
"<strong>Dirección</strong>: hacia la NIC significa <em>tx</em> de la máquina invitada; hacia la máquina, <em>rx</em>.",
"El <strong>grosor del trazo</strong> aumenta con la tasa rx+tx de la máquina invitada. Sin tráfico se mantiene una línea animada tenue; con mucho tráfico, la línea es gruesa.",
"<strong>Brillo de la cabeza del cometa</strong>: tono cálido hacia 1 MB/s e intenso a partir de 30 MB/s. Permite identificar qué máquina invitada concentra el tráfico de una NIC.",
"<strong>Clic</strong>: todos los nodos salvo el host abren el diálogo de detalle por interfaz descrito más abajo. Pulsar el host no tiene efecto; esta vista no incluye un diálogo para él."
],
"useTitle": "Cuándo es útil",
"useBody": "Las tarjetas de grupos de abajo te dicen <em>qué</em> existe; el diagrama te dice <em>cómo está conectado</em> y por dónde fluye el tráfico ahora mismo. Patrones fáciles de ver de un vistazo: un bridge sin ningún guest activo conectado, dos guests pesados usando la misma NIC (candidato a cuello de botella), o una única VM saturando un enlace mientras el resto está tranquilo."
"useBody": "Las tarjetas muestran <em>qué</em> existe; el diagrama, <em>cómo está conectado</em> y por dónde fluye el tráfico. Permite detectar máquinas que comparten un puente, dos máquinas con mucho tráfico en una misma NIC —posible cuello de botella— o una VM que satura un enlace mientras las demás apenas transmiten."
},
"groups": {
"heading": "Tres grupos de interfaces",
"intro": "Bajo la fila superior, tres tarjetas dividen el inventario por rol. Cada tarjeta tiene su propia insignia de recuento de activas en la cabecera. El <strong>tipo</strong> de interfaz se identifica de un vistazo mediante una insignia coloreada en cada fila:",
"intro": "Tres tarjetas agrupan las interfaces por función. La cabecera de cada una indica cuántas están activas. Una etiqueta de color identifica el <strong>tipo</strong> de cada interfaz:",
"badges": [
"Azul <strong>Physical</strong> — NIC real.",
"Verde <strong>Bridge</strong> — bridge Linux o bridge OVS (<code>vmbr*</code>).",
"Morado <strong>Bond</strong> — agregador bond / LACP / active-backup.",
"Cian <strong>VLAN</strong> — sub-interfaz VLAN (<code>vmbr0.10</code>, <code>eno1.42</code>, …)."
"Cian <strong>VLAN</strong>: subinterfaz VLAN (<code>vmbr0.10</code>, <code>eno1.42</code>, …)."
],
"clickable": "<strong>Cada fila es pulsable</strong> — física, virtual, bridge o bond — y abre la vista en detalle por interfaz descrita más abajo (info básica, IPs, contadores de tráfico, gráfica RX/TX histórica del almacén RRD de Proxmox).",
"physicalTitle": "Physical Interfaces",
"physicalBody": "Cada NIC que el kernel ve como un dispositivo real — <code>eno1</code>, <code>enp4s0</code>, <code>eth0</code>, <code>wlp3s0</code>, etc. Una fila por dispositivo con la insignia azul <strong>Physical</strong> y el estado del enlace. Los <em>miembros del bond</em> (NICs esclavizadas a un bond) también se muestran aquí, con una pista que apunta al bond padre.",
"bridgeTitle": "Bridge Interfaces",
"bridgeBody": "Bridges Linux (<code>vmbr0</code>, <code>vmbr1</code>, …) y los bridges OVS que gestiona Proxmox. Cada fila muestra la insignia verde <strong>Bridge</strong>, la interfaz física subyacente (cuando es un bridge de un solo puerto) y el estado del bridge. Los bonds visibles en esta capa reciben la insignia morada <strong>Bond</strong>; las sub-interfaces VLAN reciben la insignia cian <strong>VLAN</strong>.",
"vmTitle": "VM / LXC Interfaces",
"vmBody": "Las interfaces <code>tap*</code> y <code>veth*</code> creadas cuando arrancan los guests — una por NIC virtual. La cabecera de la tarjeta muestra <em>X / Y Active</em>; las filas enlazan con el VM/CT al que pertenecen, así que puedes saltar directamente al guest en la pestaña VMs y LXCs. Las entradas inactivas quedan por un instante después de que un guest se pare; envejecen y se eliminan en el siguiente ciclo de refresco."
"clickable": "<strong>Todas las filas se pueden pulsar</strong>: físicas, virtuales, puentes y bonds. Abren el detalle descrito más abajo: información básica, IP, contadores y gráfico histórico RX/TX del almacén RRD Proxmox.",
"physicalTitle": "Interfaces físicas",
"physicalBody": "Interfaces físicas reconocidas por el kernel: <code>eno1</code>, <code>enp4s0</code>, <code>eth0</code>, <code>wlp3s0</code>, etc. Cada dispositivo tiene una fila con etiqueta azul <strong>Physical</strong> y estado del enlace. Los <em>miembros de un bond</em> también aparecen, con una referencia al bond al que pertenecen.",
"bridgeTitle": "Interfaces de puente",
"bridgeBody": "Puentes Linux (<code>vmbr0</code>, <code>vmbr1</code>, …) y OVS gestionados por Proxmox. Cada fila muestra la etiqueta verde <strong>Bridge</strong>, la interfaz física subyacente si tiene un solo puerto y su estado. Los enlaces agrupados llevan la etiqueta morada <strong>Bond</strong>; las subinterfaces VLAN, la cian <strong>VLAN</strong>.",
"vmTitle": "Interfaces de VM / LXC",
"vmBody": "Interfaces <code>tap*</code> y <code>veth*</code> creadas al arrancar las máquinas invitadas, una por NIC virtual. La cabecera muestra <em>X / Y Active</em> y las filas enlazan a su VM/CT en la pestaña VMs y LXCs. Tras detener una máquina, las entradas inactivas desaparecen en el siguiente ciclo de actualización."
},
"drillIn": {
"heading": "Vista en detalle por interfaz",
"intro": "Pulsar cualquier fila abre una modal con cinco bloques:",
"heading": "Detalle por interfaz",
"intro": "Al pulsar una fila, se abre un diálogo con cinco bloques:",
"headerBlock": "Bloque",
"headerContents": "Contenido",
"rows": [
{
"block": "Basic Information",
"contents": "Nombre de la interfaz, tipo (física / bridge / bond / VLAN / vm), dirección MAC, estado (up / down), MTU y la interfaz física subyacente para los tipos no físicos."
"block": "Información básica",
"contents": "Nombre, tipo (física / puente / bond / VLAN / vm), MAC, estado (activo / inactivo), MTU e interfaz física subyacente para los tipos virtuales."
},
{
"block": "Bond Members",
"contents": "Solo para bonds. Lista cada NIC esclavizada con el flag active / failed, el modo del bond (active-backup / 802.3ad / balance-alb / …) y la interfaz primaria cuando está configurada."
"block": "Miembros del bond",
"contents": "Solo para bonds: cada NIC integrante con estado activo o fallido, modo del bond (active-backup / 802.3ad / balance-alb / …) e interfaz principal si está configurada."
},
{
"block": "IP Addresses",
"block": "Direcciones IP",
"contents": "Cada dirección IPv4 / IPv6 con su longitud de prefijo. Las direcciones link-local autoconfiguradas se listan pero salen atenuadas."
},
{
"block": "Gráfica histórica",
"contents": "Ancho de banda RX / TX sobre el timeframe seleccionado (1 hora / 24 horas / 7 días / 30 días / 1 año), traído de <code>/api/network/&lt;interface&gt;/metrics</code> (RRD de Proxmox)."
"contents": "Ancho de banda RX/TX durante el periodo elegido (1 hora / 24 horas / 7 días / 30 días / 1 año), obtenido de <code>/api/network/&lt;interface&gt;/metrics</code> (RRD Proxmox)."
},
{
"block": "Tráfico desde el último arranque",
"contents": "Bytes y paquetes totales RX / TX desde el último arranque del host, más contadores de errores y descartes."
"contents": "Total de bytes y paquetes RX/TX desde el último arranque del host, con contadores de errores y descartes."
}
],
"inactiveTitle": "Las interfaces inactivas siguen abriendo la vista en detalle",
"inactiveBody": "Para una interfaz <em>down</em>, la modal renderiza un pequeño banner \"Interface Inactive\" y omite los contadores en vivo. La configuración (direcciones, miembros del bond) y los datos históricos siguen mostrándose — útil al diagnosticar por qué falló algo y cuándo."
"inactiveTitle": "También puedes ver el detalle de las interfaces inactivas",
"inactiveBody": "Si la interfaz está <em>inactiva</em>, el diálogo muestra el aviso «Interfaz inactiva» y omite los contadores actuales. Conserva la configuración —direcciones y miembros del bond— y el historial para diagnosticar qué falló y cuándo."
},
"latency": {
"heading": "Modal Network Latency",
"intro": "Pulsar la tarjeta <em>Network Latency</em> de la fila superior abre una modal dedicada. Tiene dos modos (histórico y test bajo demanda), tres opciones de destino y un informe PDF descargable.",
"heading": "Diálogo Latencia de red",
"intro": "Pulsa <em>Latencia de red</em> en la fila superior para abrir su diálogo. Incluye historial, pruebas a petición, tres destinos y un informe PDF descargable.",
"targetsTitle": "Destinos",
"targetsIntro": "Un desplegable de destino en lo alto de la modal selecciona contra qué se hace ping:",
"targetsIntro": "El desplegable de la parte superior selecciona el destino del ping:",
"targets": [
"<strong>Gateway</strong> — tu router de la LAN. Solo testea el tramo de red local; útil cuando sospechas de un problema de switch / cableado y quieres descartar la WAN.",
"<strong>Cloudflare (1.1.1.1)</strong> — resolutor DNS público, red anycast. Testea el tramo WAN.",
"<strong>Google (8.8.8.8)</strong> — destino público alternativo, útil como verificación sanity o cuando Cloudflare está degradado regionalmente."
"<strong>Puerta de enlace</strong>: tu router LAN. Comprueba solo el tramo local para investigar problemas del switch o del cableado sin incluir la WAN.",
"<strong>Cloudflare (1.1.1.1)</strong>: resolutor DNS público en una red anycast. Comprueba el tramo WAN.",
"<strong>Google (8.8.8.8)</strong>: destino público alternativo para contrastar resultados o comprobar incidencias regionales de Cloudflare."
],
"mode1Title": "Modo 1 — Vista histórica",
"mode1Alt": "Modal Network Latency en modo histórico — destino Gateway con un timeframe de 1 hora y las muestras pasadas ploteadas",
"mode1Caption": "Vista histórica — destino Gateway sobre la última hora, alimentada desde la base de datos de historial de latencia que el hilo recolector de temperatura/latencia escribe cada 60 segundos.",
"mode1Body1": "El modo por defecto al abrir la modal. Un segundo desplegable elige el timeframe (<em>1 Hour / 24 Hours / 7 Days / 30 Days / 1 Year</em>); la resolución de los datos baja con la ventana para que la gráfica se mantenga legible. Las estadísticas titulares — Current / Min / Avg / Max — se renderizan encima de la gráfica, con una pastilla de estado (Excellent / Good / Fair / Poor) que refleja el valor actual frente a los umbrales de abajo.",
"mode1Body2": "Fuente: las mismas muestras de latencia que usa el Monitor de salud para detectar ralentizaciones persistentes de red — muestreadas cada 60 segundos contra el gateway por el hilo en background <code>_temperature_collector_loop</code>, escritas a un historial SQLite local.",
"mode1Alt": "Diálogo de latencia en modo histórico, con destino Puerta de enlace, periodo de una hora y muestras anteriores representadas",
"mode1Caption": "Historial de la puerta de enlace durante la última hora. El recolector de temperatura y latencia guarda las muestras en la base de datos cada 60 segundos.",
"mode1Body1": "Es el modo inicial del diálogo. Un segundo desplegable elige el periodo (<em>1 hora / 6 horas / 24 horas / 3 días / 7 días</em>). Encima aparecen Actual / Mínimo / Media / Máximo y un indicador Excelente / Bueno / Regular / Malo según los umbrales siguientes.",
"mode1Body2": "Fuente: las muestras que usa Health Monitor para detectar ralentizaciones persistentes. El hilo <code>_temperature_collector_loop</code> mide la latencia de la puerta de enlace cada 60 segundos y la guarda en un historial SQLite local.",
"mode2Title": "Modo 2 — Test en tiempo real",
"mode2Alt": "Modal Network Latency ejecutando un test de ping en tiempo real contra Cloudflare — barra de progreso al 50%, muestras en vivo acumulándose en la gráfica",
"mode2Caption": "Test en tiempo real contra Cloudflare — ejecución de 2 minutos con una lectura cada 5 segundos, muestras ploteadas según llegan. Pulsa <em>Stop</em> para terminar antes; <em>Test Again</em> añade más muestras al mismo dataset.",
"mode2Alt": "Diálogo de latencia ejecutando un ping a Cloudflare en tiempo real, con progreso al 50 % y nuevas muestras en el gráfico",
"mode2Caption": "Prueba de dos minutos contra Cloudflare, con una lectura cada cinco segundos que se añade al gráfico al llegar. Pulsa <em>Detener</em> para finalizar antes; <em>Repetir prueba</em> añade muestras al mismo conjunto de datos.",
"mode2Intro": "Cambiar el destino a Cloudflare o Google arranca un test de ping bajo demanda. Comportamiento:",
"mode2Items": [
"<strong>Duración</strong> — 2 minutos por ejecución, con barra de progreso y un contador de segundos restantes.",
"<strong>Cadencia</strong> — una lectura cada 5 segundos (24 lecturas por ejecución).",
"<strong>Método</strong> — ICMP Echo Request (<code>ping</code>), 3 pings consecutivos por muestra, latencia promediada.",
"<strong>Duración</strong>: dos minutos por ejecución, con barra de progreso y segundos restantes.",
"<strong>Frecuencia</strong>: una lectura cada cinco segundos, 24 por ejecución.",
"<strong>Método</strong>: ICMP Echo Request (<code>ping</code>), con tres pings seguidos por muestra y su latencia media.",
"<strong>Stop</strong> — termina el test inmediatamente; los datos parciales se preservan.",
"<strong>Test Again</strong> — añade nuevas muestras al dataset existente en lugar de empezar de cero, así puedes construir un registro más largo a lo largo de varias ejecuciones.",
"<strong>Pastilla de estado en vivo</strong> — se reevalúa tras cada muestra con los mismos umbrales Excellent / Good / Fair / Poor."
"<strong>Repetir prueba</strong>: añade muestras a los datos existentes para construir un registro más largo con varias ejecuciones.",
"<strong>Indicador de estado actual</strong>: se recalcula tras cada muestra con los mismos umbrales Excelente / Bueno / Regular / Malo."
],
"thresholdsTitle": "Umbrales de rendimiento",
"headerStatus": "Estado",
@@ -141,47 +141,47 @@
"headerImpact": "Impacto práctico",
"thresholdRows": [
{
"status": "Excellent",
"status": "Excelente",
"range": "< 50 ms",
"impact": "Óptimo para apps en tiempo real, gaming y videollamadas."
},
{
"status": "Good",
"status": "Bueno",
"range": "50 – 100 ms",
"impact": "Aceptable para la mayoría de aplicaciones con impacto mínimo."
},
{
"status": "Fair",
"status": "Regular",
"range": "100 – 200 ms",
"impact": "Retardo perceptible. Puede afectar a VoIP y apps interactivas."
},
{
"status": "Poor",
"status": "Malo",
"range": "> 200 ms",
"impact": "Latencia significativa. Se recomienda investigar."
}
],
"reportTitle": "Network Latency Report (PDF)",
"reportIntro": "Ambos modos tienen un botón <strong>Report</strong> junto al selector de destino. Pulsarlo genera un PDF con todo lo que enviarías a tu ISP si quisieras argumentar un mal servicio.",
"reportPreviewAlt": "Primera página del PDF Network Latency Report — Executive Summary con el gauge, estadísticas de latencia, la gráfica de latencia y la guía de umbrales",
"reportPreviewCaption": "Primera página del Network Latency Report — Executive Summary con el dial del gauge y las estadísticas titulares, la gráfica de latencia por segundo y la guía de umbrales. De la página 2 en adelante está la tabla por muestra y la metodología.",
"downloadLabel": "Descargar informe de ejemplo Network Latency (PDF)",
"reportTitle": "Informe de latencia de red (PDF)",
"reportIntro": "Ambos modos tienen un botón <strong>Informe</strong> junto al selector de destino. Abre un informe imprimible de las mediciones; guárdalo como PDF desde el diálogo de impresión del navegador y adjúntalo a una solicitud de asistencia a tu proveedor de Internet.",
"reportPreviewAlt": "Primera página del informe PDF de latencia: resumen ejecutivo, indicador, estadísticas, gráfico y guía de umbrales",
"reportPreviewCaption": "La primera página contiene resumen ejecutivo, indicador, estadísticas principales, serie temporal de latencia y guía de umbrales. Desde la página 2 aparecen la tabla de muestras y la metodología.",
"downloadLabel": "Descargar informe de ejemplo de latencia (PDF)",
"sectionsIntro": "El informe tiene seis secciones:",
"sections": [
"<strong>Executive Summary</strong> — dial del gauge (0–300+ ms con zonas verde / amarilla / roja), el veredicto de estado (EXCELLENT / GOOD / FAIR / POOR), el destino / modo / recuento de muestras y un resumen de una línea sobre packet loss.",
"<strong>Latency Statistics</strong> — Current / Min / Avg / Max como cuatro tiles grandes, más Sample Count, Packet Loss (avg) y Test Period.",
"<strong>Latency Graph</strong> — gráfica de área de cada muestra a lo largo de la ventana del test con una rejilla en el eje y de min/avg/max.",
"<strong>Performance Thresholds</strong> — la misma escala de cuatro niveles documentada arriba, con un punto coloreado por nivel.",
"<strong>Detailed Test Results</strong> — tabla numerada con timestamp, latencia, packet loss y estado para cada muestra. Útil para detectar micro-ráfagas que esconden los promedios titulares.",
"<strong>Methodology</strong> — método del test (ICMP Echo Request), muestras por test (3 pings consecutivos), nombre del destino, IP del destino y un párrafo final \"Performance Assessment\" derivado del veredicto."
"<strong>Resumen ejecutivo</strong>: indicador de 0 a más de 300 ms con zonas verde, amarilla y roja; estado Excelente / Bueno / Regular / Malo; destino, modo, número de muestras y resumen de pérdida de paquetes.",
"<strong>Estadísticas de latencia</strong>: cuatro indicadores con valor actual, mínimo, media y máximo, además del número de muestras, pérdida media de paquetes y periodo de prueba.",
"<strong>Gráfico de latencia</strong>: gráfico de área de las muestras durante la prueba, con referencias de mínimo, media y máximo en el eje vertical.",
"<strong>Umbrales de rendimiento</strong>: la misma escala de cuatro niveles anterior, con un punto de color por nivel.",
"<strong>Resultados detallados</strong>: tabla numerada con fecha y hora, latencia, pérdida de paquetes y estado de cada muestra. Permite detectar picos breves ocultos por las medias.",
"<strong>Metodología</strong>: ICMP Echo Request, tres pings consecutivos por muestra, nombre e IP del destino y evaluación final derivada del estado."
],
"useCaseTitle": "Caso de uso: reclamaciones a tu ISP",
"useCaseBody": "Ejecuta el test en tiempo real contra Cloudflare durante 2 minutos en un momento de lentitud percibida, después pulsa <em>Test Again</em> unas cuantas veces para extender el dataset y finalmente <em>Report</em>. El PDF lleva la tabla completa por muestra más el bloque de metodología — los ISPs suelen aceptar esto como evidencia, sobre todo si está correlacionado con timestamps de una reclamación aparte."
"useCaseTitle": "Caso de uso: asistencia de tu proveedor de Internet",
"useCaseBody": "Ejecuta dos minutos de prueba contra Cloudflare cuando notes lentitud, usa <em>Repetir prueba</em> para ampliar el registro y selecciona <em>Informe</em>. El PDF incluye todas las muestras y la metodología. Puedes adjuntarlo a una solicitud de asistencia con las horas de la incidencia; tu proveedor decide qué pruebas necesita."
},
"excluding": {
"heading": "Excluir interfaces ruidosas",
"body1": "Igual que los almacenamientos, las interfaces individuales se pueden excluir de la monitorización de salud — útil para bridges deshabilitados a propósito, interfaces de test o NICs físicamente retiradas pero que siguen en la configuración. El flag se guarda en la tabla <code>excluded_interfaces</code> y lo respeta el ciclo del Monitor de salud: sin warnings, sin notificaciones, sin contribución a la pastilla de estado de la cabecera.",
"body2": "Desde el menú contextual de la fila, elige <em>Exclude from monitoring</em>. La interfaz sigue visible en el panel con una insignia morada <strong>excluded</strong>, y puedes reactivar la monitorización desde el mismo menú."
"heading": "Excluir interfaces de la supervisión",
"body1": "Puedes excluir interfaces de la supervisión, por ejemplo puentes desactivados a propósito, interfaces de prueba o NIC retiradas que siguen en la configuración. El ajuste se guarda en <code>excluded_interfaces</code>: Health Monitor no genera avisos ni notificaciones ni incluye esas interfaces en el indicador general.",
"body2": "En el menú contextual de la fila, elige <em>Excluir de la supervisión</em>. La interfaz sigue visible con una etiqueta morada <strong>excluida</strong>. Puedes reactivar la supervisión desde el mismo menú."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -192,31 +192,31 @@
{
"section": "Inventario de interfaces",
"endpoint": "/api/network",
"source": "<code>ip -j addr</code> + <code>ip -j link</code> + introspección de bond / bridge."
"source": "<code>ip -j addr</code> + <code>ip -j link</code> y consulta de bonds y puentes."
},
{
"section": "Tarjetas resumen",
"endpoint": "/api/network/summary",
"source": "Agregación sobre el inventario más recuentos up/down por interfaz."
"source": "Resumen del inventario y recuento de interfaces activas e inactivas."
},
{
"section": "Serie temporal RX/TX por interfaz",
"endpoint": "/api/network/<iface>/metrics",
"source": "<code>/proc/net/dev</code> muestreado por el Monitor de salud con cálculo de byte-rate."
"source": "Los contadores actuales usan <code>/proc/net/dev</code>; el historial del gráfico procede de RRD Proxmox mediante pvesh. Las interfaces VM/LXC usan datos del invitado; las físicas y los puentes, datos del nodo."
},
{
"section": "Latencia: actual",
"endpoint": "/api/network/latency/current",
"source": "Una ráfaga corta de <code>ping</code> contra el gateway / destino configurado."
"source": "Serie corta de <code>ping</code> a la puerta de enlace o al destino configurado."
},
{
"section": "Latencia: histórica",
"endpoint": "/api/network/latency/history",
"source": "Muestras persistidas — cada 5 min por el ciclo del Monitor de salud."
"source": "Muestras guardadas aproximadamente cada 60 segundos por el recolector de temperatura y latencia en segundo plano."
}
],
"codeComment1": "# Cross-check del estado de interfaz que ve el panel",
"codeComment2": "# Verificar una sonda de latencia actual de extremo a extremo"
"codeComment1": "# Contrastar el estado de las interfaces que muestra el panel",
"codeComment2": "# Comprobar una medición actual de latencia de extremo a extremo"
},
"whereNext": {
"heading": "Por dónde seguir",
@@ -224,17 +224,17 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la categoría Red y los umbrales del historial de latencia."
"tail": " — categoría Red y umbrales del historial de latencia."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints de red y latencia."
"tail": " — endpoints de red y latencia."
},
{
"label": "Integraciones",
"href": "/docs/monitor/integrations",
"tail": " — el scrape de Prometheus expone las mismas métricas de red."
"tail": " — la recopilación de Prometheus ofrece las mismas métricas de red."
},
{
"label": "Índice del panel",
@@ -1,174 +1,174 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Seguridad | ProxMenux Documentation",
"description": "La pestaña Seguridad agrupa cada control relacionado con protección en dos columnas: ProxMenux Monitor (Autenticación, SSL/HTTPS, tokens API, Secure Gateway) y Proxmox VE (Firewall, Fail2Ban, auditoría Lynis). Asistente paso a paso de Secure Gateway, recorrido de auditoría Lynis, instalación de Fail2Ban y ajuste de reglas."
"title": "ProxMenux Monitor — Panel: pestaña Seguridad | Documentación de ProxMenux",
"description": "La pestaña Seguridad reúne los controles de protección en dos columnas: ProxMenux Monitor (autenticación, SSL/HTTPS, tokens de API y Secure Gateway) y Proxmox VE (cortafuegos, Fail2Ban y auditoría de Lynis). Incluye el asistente de Secure Gateway, la auditoría de Lynis y la instalación y el ajuste de reglas de Fail2Ban."
},
"header": {
"title": "Panel: pestaña Seguridad",
"description": "Cada control de seguridad del panel, agrupado en dos bloques claramente etiquetados: configuración del propio Monitor (auth, SSL, tokens, Secure Gateway) y configuración del host Proxmox al que vigila (firewall, Fail2Ban, Lynis).",
"description": "Los controles de seguridad del panel se agrupan en dos bloques: la configuración del propio Monitor (autenticación, SSL, tokens y Secure Gateway) y la del host Proxmox que supervisa (cortafuegos, Fail2Ban y Lynis).",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "Dos ámbitos, una pestaña",
"body": "La pestaña Seguridad está dividida en dos secciones claramente separadas: <strong>ProxMenux Monitor</strong> (settings para el propio panel) y <strong>Proxmox VE</strong> (settings para el host de debajo). Las tarjetas se renderizan de forma condicional — Fail2Ban y Lynis solo aparecen una vez instalados."
"body": "La pestaña Seguridad tiene dos secciones: <strong>ProxMenux Monitor</strong> (ajustes del panel) y <strong>Proxmox VE</strong> (ajustes del host). Las tarjetas de Fail2Ban y Lynis ofrecen instalar estas herramientas si faltan y muestran sus controles una vez instaladas."
},
"monitor": {
"heading": "ProxMenux Monitor",
"intro": "Cuatro tarjetas controlan cómo se alcanza y autentica el propio panel."
"intro": "Cuatro tarjetas permiten configurar el acceso al panel y su autenticación."
},
"auth": {
"heading": "Autenticación",
"imageAlt": "Tarjeta Authentication mostrando estado Enabled, Logout, Change Password, info de Two-Factor Authentication, botones Enable Two-Factor Authentication y Disable Authentication",
"imageCaption": "Tarjeta Authentication con auth activa — insignia de estado, Change Password, Enable 2FA y la acción (destructiva) Disable Authentication.",
"intro": "La tarjeta te permite gestionar el login del propio panel. El flujo completo de primer arranque, política de contraseñas, pantallas de alta de TOTP y recuperación de authenticator perdido están documentados en <link>Acceso y autenticación</link> — esta tarjeta es la superficie del día a día para esos settings:",
"imageAlt": "Tarjeta de autenticación con estado Activada, botones Cerrar sesión y Cambiar contraseña, información sobre la autenticación de dos factores y botones para activarla o desactivar la autenticación",
"imageCaption": "Tarjeta con la autenticación activada: indicador de estado, Cambiar contraseña, Activar 2FA y la acción destructiva Desactivar autenticación.",
"intro": "La tarjeta permite gestionar el inicio de sesión del panel. El primer inicio, la política de contraseñas, el alta de TOTP y la recuperación por pérdida del autenticador se explican en <link>Acceso y autenticación</link>. Esta tarjeta permite gestionar esos ajustes a diario:",
"items": [
"<strong>Authentication Status</strong> — insignia mostrando <em>Enabled</em> / <em>Disabled</em> / <em>Declined</em>.",
"<strong>Change Password</strong> — contraseña actual + nueva contraseña + confirmación.",
"<strong>Enable / Disable Two-Factor Authentication</strong> — abre el diálogo de alta con QR al activar, pide la contraseña actual al desactivar.",
"<strong>Disable Authentication</strong> — acción destructiva que vuelve a mostrar el diálogo de primer arranque <em>Protect your dashboard?</em> en la siguiente visita."
"<strong>Estado de autenticación</strong>: indicador con <em>Activada</em> / <em>Desactivada</em> / <em>Rechazada</em>.",
"<strong>Cambiar contraseña</strong>: contraseña actual + nueva contraseña + confirmación.",
"<strong>Activar / Desactivar autenticación de dos factores</strong>: al activarla, abre el diálogo de registro con QR; al desactivarla, solicita la contraseña actual.",
"<strong>Desactivar autenticación</strong>: acción destructiva que vuelve a mostrar el diálogo inicial <em>¿Proteger tu panel?</em> en la siguiente visita."
]
},
"ssl": {
"heading": "SSL / HTTPS",
"imageAlt": "Tarjeta SSL / HTTPS mostrando estado HTTP No SSL, certificado del host Proxmox detectado con Subject, Issuer, Expires, botón Use Proxmox Certificate y opción Use Custom Certificate",
"imageCaption": "Tarjeta SSL / HTTPS con HTTPS apagado. El Monitor detecta el certificado ya instalado en el host Proxmox y lo ofrece como opción de un solo clic, con un fallback a <em>Use Custom Certificate</em> si tienes tus propios archivos en otro sitio.",
"intro": "Sirve el panel sobre HTTPS sin ningún reverse proxy por delante. La tarjeta auto-detecta el certificado que usa el propio Proxmox (bajo <code>/etc/pve/local/</code>) y muestra el subject, issuer y expiración para que lo puedas verificar antes de activar. Dos rutas para activar HTTPS:",
"heading": "SSL/HTTPS",
"imageAlt": "Tarjeta SSL/HTTPS con estado HTTP sin SSL, certificado del host Proxmox detectado con sujeto, emisor y caducidad, botón Usar certificado de Proxmox y opción Usar certificado personalizado",
"imageCaption": "Tarjeta SSL/HTTPS con HTTPS desactivado. Monitor detecta el certificado instalado en el host Proxmox y permite usarlo con un clic. Si tienes otros archivos, puedes elegir <em>Usar certificado personalizado</em>.",
"intro": "Permite servir el panel por HTTPS sin un proxy inverso. La tarjeta detecta el certificado usado por Proxmox en <code>/etc/pve/local/</code> y muestra su sujeto, emisor y caducidad para verificarlo antes de activarlo. Hay dos formas de activar HTTPS:",
"items": [
"<strong>Use Proxmox Certificate</strong> — un clic. El Monitor reutiliza el certificado instalado en el host. Buena opción para usuarios que ya tienen su PVE corriendo en el mismo nombre DNS que el panel.",
"<strong>Use Custom Certificate</strong> — pega rutas absolutas a tus propios archivos <code>.pem</code> de certificado y <code>.key</code> de clave privada. Las rutas se validan antes de reiniciar el servicio; si la carga falla, el panel cae a HTTP automáticamente (sin estado roto)."
"<strong>Usar certificado de Proxmox</strong>: con un clic, Monitor reutiliza el certificado del host. Es adecuado si PVE y el panel ya usan el mismo nombre DNS.",
"<strong>Usar certificado personalizado</strong>: pega las rutas absolutas de tu certificado <code>.pem</code> y clave privada <code>.key</code>. Se validan antes de reiniciar el servicio. Si no pueden cargarse, el panel vuelve automáticamente a HTTP y permanece accesible."
],
"enabledAlt": "Tarjeta SSL/HTTPS con estado HTTPS Enabled, Active Certificate mostrando rutas pve-ssl.pem y pve-ssl.key, y un botón Disable HTTPS",
"enabledCaption": "HTTPS activo — la tarjeta expone el certificado actualmente en uso, las rutas de archivos y una acción <em>Disable HTTPS</em> que vuelve a HTTP en el mismo puerto.",
"enabledAlt": "Tarjeta SSL/HTTPS con HTTPS activado, certificado activo con las rutas de pve-ssl.pem y pve-ssl.key y botón Desactivar HTTPS",
"enabledCaption": "HTTPS activo: la tarjeta muestra el certificado en uso, sus rutas y la acción <em>Desactivar HTTPS</em>, que vuelve a HTTP en el mismo puerto.",
"acmeTitle": "ACME / Let's Encrypt vía Proxmox",
"acmeBody": "Si tu nodo Proxmox ya tiene Let's Encrypt configurado en <em>Datacenter → Certificates → ACME</em>, ese es el certificado que el host sirve a los navegadores — y eso es lo que el panel reutiliza al pulsar <em>Use Proxmox Certificate</em>. No necesitas fontanería ACME separada para el Monitor.",
"walkthroughLink": "Para un recorrido paso a paso — incluyendo cómo el Monitor auto-detecta el certificado subido por ACME, qué se escribe a disco y cómo caer a un par <code>.pem</code> / <code>.key</code> custom — mira <link>HTTPS para ProxMenux Monitor</link>."
"acmeBody": "Si tu nodo Proxmox ya tiene Let’s Encrypt configurado en <em>Datacenter → Certificates → ACME</em>, el panel reutiliza ese mismo certificado al pulsar <em>Usar certificado de Proxmox</em>. No necesitas configurar ACME por separado para Monitor.",
"walkthroughLink": "Consulta <link>HTTPS para ProxMenux Monitor</link> para ver paso a paso cómo se detecta el certificado de ACME, qué se guarda en disco y cómo usar un par <code>.pem</code> / <code>.key</code> propio."
},
"apiTokens": {
"heading": "Tokens de acceso API",
"emptyAlt": "Tarjeta API Access Tokens en estado vacío con caja info About API Tokens y botón Generate New API Token",
"emptyCaption": "Tarjeta API Access Tokens en una instalación recién hecha — la caja <em>About API Tokens</em> resume lifetime, uso y cómo embeber el token en cabeceras <code>Authorization: Bearer</code>.",
"intro": "Tokens de vida larga (1 año) para integraciones desatendidas — widgets Homepage, sensores REST de Home Assistant, scrapers de Grafana, flujos n8n, scripts propios. La tarjeta te lleva por tres estados: vacío → formulario → generado.",
"generateBody": "<strong>Generar un token.</strong> Pulsa <em>Generate New API Token</em>. El formulario pide un <em>Token Name</em> descriptivo (ayuda a identificarlo después en la lista activa) y tu <em>contraseña</em> como confirmación de segundo factor. Si 2FA está activo, el formulario pide adicionalmente el código TOTP actual.",
"generateAlt": "Formulario API Access Tokens generate con input Token Name, input Password, botones Generate Token y Cancel",
"generateCaption": "El formulario Generate API Token — rellena un nombre y confirma con tu contraseña (y TOTP si 2FA está activo).",
"saveBody": "<strong>Guarda el token inmediatamente.</strong> La cadena completa del token se muestra <strong>solo una vez</strong> tras generarlo. La tarjeta lo destaca con un aviso ámbar y un botón de copia. No hay forma de recuperarlo después — solo verás el prefix en la lista Active Tokens.",
"generatedAlt": "Token API generado correctamente con token enmascarado, botón de copia, instrucciones para cabecera Authorization Bearer y lista Active Tokens con prefix",
"generatedCaption": "Token generado — el valor se muestra una vez con un botón de copia y el snippet exacto <code>Authorization: Bearer</code>. Debajo, la lista Active Tokens mantiene nombre + prefix + fecha de creación para que puedas revocar tokens individuales después.",
"outro": "La tarjeta muestra cada token activo con un botón <em>Revoke</em> por fila. Revocar invalida el token inmediatamente; cualquier integración que lo use deja de funcionar desde ese momento. Los cookbooks para Homepage, Home Assistant, n8n y Prometheus están en <link>Integraciones</link>."
"emptyAlt": "Tarjeta de tokens de acceso a la API vacía, con información sobre los tokens y botón Generar nuevo token de API",
"emptyCaption": "Tarjeta de tokens en una instalación nueva. El cuadro <em>Acerca de los tokens de API</em> resume su duración, uso y cómo incluirlos en cabeceras <code>Authorization: Bearer</code>.",
"intro": "Tokens con un año de validez para integraciones desatendidas: widgets de Homepage, sensores REST de Home Assistant, recolectores de Grafana, flujos de n8n y scripts propios. La tarjeta pasa por tres estados: vacío → formulario → generado.",
"generateBody": "<strong>Generar un token.</strong> Pulsa <em>Generar nuevo token de API</em>. Introduce un <em>nombre del token</em> descriptivo para identificarlo después y tu <em>contraseña</em> como confirmación adicional. Si 2FA está activo, también solicita el código TOTP actual.",
"generateAlt": "Formulario de generación de tokens de API con campos Nombre del token y Contraseña y botones Generar token y Cancelar",
"generateCaption": "Formulario Generar token de API: introduce un nombre y confirma con tu contraseña y, si 2FA está activo, el código TOTP.",
"saveBody": "<strong>Guarda el token inmediatamente.</strong> Su valor completo se muestra <strong>solo una vez</strong> tras generarlo. La tarjeta lo señala con un aviso naranja y un botón de copia. No podrás recuperarlo después; la lista de tokens activos solo mostrará su prefijo.",
"generatedAlt": "Token de API generado, con valor oculto, botón de copia, instrucciones para la cabecera Authorization: Bearer y lista de tokens activos con sus prefijos",
"generatedCaption": "Token generado: el valor se muestra una vez, con botón de copia y el fragmento exacto <code>Authorization: Bearer</code>. Debajo, la lista de tokens activos muestra nombre, prefijo y fecha de creación para revocarlos individualmente.",
"outro": "Cada token activo tiene un botón <em>Revocar</em>. La revocación lo invalida inmediatamente y las integraciones que lo usen dejan de funcionar. Encontrarás ejemplos para Homepage, Home Assistant, n8n y Prometheus en <link>Integraciones</link>."
},
"gateway": {
"heading": "Secure Gateway",
"cardAlt": "Tarjeta Secure Gateway con botón Deploy Secure Gateway antes de que se haya desplegado ningún gateway",
"cardCaption": "Tarjeta Secure Gateway en setup recién hecho — un botón arranca el asistente.",
"intro": "Alcanza el panel, la UI web de Proxmox y cualquier guest desde cualquier sitio en tu tailnet de <a>Tailscale</a>, sin exponer ningún puerto a la internet pública. El Monitor despliega un contenedor LXC Alpine en el host corriendo <code>tailscaled</code> como subnet router; una vez aprobado en la consola de admin de Tailscale, tus dispositivos remotos alcanzan la IP de LAN del host desde cualquier sitio.",
"cardAlt": "Tarjeta Secure Gateway con el botón Desplegar Secure Gateway antes de desplegar la primera pasarela",
"cardCaption": "Tarjeta Secure Gateway en una instalación nueva: un botón inicia el asistente.",
"intro": "Accede al panel, a la interfaz web de Proxmox y a cualquier máquina invitada desde tu red <a>Tailscale</a>, sin exponer puertos a Internet. Monitor despliega en el host un contenedor LXC Alpine con <code>tailscaled</code> como router de subred. Tras aprobarlo en la consola de administración de Tailscale, los dispositivos remotos pueden acceder a la IP LAN del host desde cualquier lugar.",
"wizardTitle": "Asistente paso a paso",
"wizardIntro": "Antes de pulsar <em>Deploy Secure Gateway</em>, genera una auth key en tu consola de admin de Tailscale — el asistente la pedirá en el paso 2.",
"step0Title": "0. Generar la auth key de Tailscale",
"step0Body": "Entra en <a>login.tailscale.com/admin/settings/keys</a> y pulsa <em>Generate auth key…</em>. Elige una key <em>pre-autenticada</em> (para que el gateway no necesite un login interactivo de Tailscale) y copia el valor — se muestra solo una vez.",
"step0Alt": "Consola de admin de Tailscale, página Settings Keys con el botón Generate auth key resaltado",
"wizardIntro": "Antes de pulsar <em>Deploy Secure Gateway</em>, genera una clave de autenticación en la consola de Tailscale. El asistente la pedirá en el paso 2.",
"step0Title": "0. Generar la clave de autenticación de Tailscale",
"step0Body": "Entra en <a>login.tailscale.com/admin/settings/keys</a> y pulsa <em>Generate auth key…</em>. Elige una clave <em>preautenticada</em> para que la pasarela no necesite un inicio de sesión interactivo. Copia el valor: solo se muestra una vez.",
"step0Alt": "Página Settings → Keys de la consola de administración de Tailscale, con el botón Generate auth key resaltado",
"step0Caption": "Consola de admin de Tailscale — <em>Settings → Keys → Generate auth key…</em>. Usa una cuenta gratuita de Tailscale si aún no tienes (link dentro del asistente).",
"step1Title": "1. Abrir el asistente",
"step1Body": "De vuelta en la pestaña Seguridad, pulsa <em>Deploy Secure Gateway</em>. El primer paso es una intro con lo que vas a obtener y lo que necesitas.",
"step1Alt": "Paso intro del asistente Secure Gateway Setup explicando qué provee el gateway: acceso VPN, sin port forwarding, cifrado de extremo a extremo",
"step1Body": "Vuelve a la pestaña Seguridad y pulsa <em>Deploy Secure Gateway</em>. El primer paso presenta sus funciones y requisitos.",
"step1Alt": "Introducción del asistente Secure Gateway con acceso VPN, sin redirección de puertos y con cifrado de extremo a extremo",
"step1Caption": "Paso 1 — resumen de lo que provee el Secure Gateway y recordatorio de que necesitarás una cuenta gratuita de Tailscale.",
"step2Title": "2. Tailscale Authentication",
"step2Body": "Pega la auth key del paso 0 y elige un hostname (así es como aparecerá el gateway en la consola de admin de Tailscale — típicamente <code>proxmox-gateway</code> o el nombre de tu nodo).",
"step2Alt": "Paso del asistente Secure Gateway pidiendo Tailscale Auth Key y Device Hostname con link para generar la key",
"step2Caption": "Paso 2 — pega la pre-auth key y elige el hostname del dispositivo. El link debajo del campo abre la página de Tailscale del paso 0 si te lo saltaste.",
"step3Title": "3. Access Scope",
"step2Title": "2. Autenticación de Tailscale",
"step2Body": "Pega la clave de autenticación del paso 0 y elige un nombre de host. Será el nombre de la pasarela en la consola de Tailscale, normalmente <code>proxmox-gateway</code> o el nombre de tu nodo.",
"step2Alt": "Paso del asistente Secure Gateway que solicita la clave de autenticación de Tailscale y el nombre de host del dispositivo, con enlace para generar la clave",
"step2Caption": "Paso 2: pega la clave preautenticada y elige el nombre de host. Si omitiste el paso 0, el enlace bajo el campo abre la página de Tailscale correspondiente.",
"step3Title": "3. Alcance de acceso",
"step3Intro": "Elige a qué puede llegar tu tailnet a través del gateway:",
"step3Items": [
"<strong>Proxmox Only</strong> — solo la UI de Proxmox y el Monitor. La menor superficie de ataque.",
"<strong>Full Local Network</strong> — la subred LAN entera (auto-detectada desde la interfaz primaria del host). Te permite alcanzar NAS, impresoras, VMs y cualquier otro dispositivo de la LAN.",
"<strong>Custom Subnets</strong> — lista CIDRs específicos. Para setups multi-VLAN donde quieres exponer algunos segmentos pero no otros."
"<strong>Subredes personalizadas</strong>: indica los CIDR concretos. Permite dar acceso solo a determinados segmentos en instalaciones con varias VLAN."
],
"step3Alt": "Paso Access Scope del asistente Secure Gateway con tres opciones: Proxmox Only, Full Local Network, Custom Subnets",
"step3Caption": "Paso 3 — elige el access scope. <em>Full Local Network</em> se autorrellena con la subred LAN detectada.",
"step4Title": "4. Advanced Options (opcional)",
"step4Intro": "Dos toggles opcionales. Ambos <strong>off por defecto</strong>:",
"step3Alt": "Paso Ámbito de acceso del asistente Secure Gateway, con las opciones Solo Proxmox, Toda la red local y Subredes personalizadas",
"step3Caption": "Paso 3: elige el ámbito de acceso. <em>Toda la red local</em> rellena automáticamente la subred LAN detectada.",
"step4Title": "4. Opciones avanzadas (opcional)",
"step4Intro": "Dos interruptores opcionales, ambos <strong>desactivados por defecto</strong>:",
"step4Items": [
"<strong>Exit Node</strong> — cuando se activa y se selecciona desde un dispositivo remoto, todo el tráfico de internet de ese dispositivo sale por la WAN del host Proxmox. Útil para escenarios de viaje donde quieres que el tráfico de tu móvil parezca de casa.",
"<strong>Accept Routes</strong> — deja que este gateway alcance redes anunciadas por <em>otros</em> subnet routers del tailnet (para setups multi-sitio)."
"<strong>Exit Node</strong>: al activarlo y seleccionarlo desde un dispositivo remoto, todo el tráfico de Internet de ese dispositivo sale por la WAN del host Proxmox. Es útil al viajar para que el tráfico del móvil salga por tu conexión de casa.",
"<strong>Aceptar rutas</strong>: permite que esta pasarela acceda a redes anunciadas por <em>otros</em> routers de subred de la red Tailscale, para instalaciones en varias ubicaciones."
],
"step4Alt": "Paso Advanced Options del asistente Secure Gateway con checkboxes Exit Node y Accept Routes",
"step4Caption": "Paso 4 — Exit Node y Accept Routes. Salta ambos si lo único que quieres es acceso al panel desde tu móvil o portátil.",
"step5Title": "5. Review & Deploy",
"step5Body": "Resumen final antes de que arranque el deploy. El asistente te recuerda que aún queda un paso manual en el admin de Tailscale tras desplegar: <strong>aprobar la subnet route</strong>.",
"step5Alt": "Paso Review and Deploy del asistente Secure Gateway con Configuration Summary mostrando hostname, access mode, networks, exit node, accept routes y un botón Deploy Gateway",
"step4Alt": "Paso Opciones avanzadas de Secure Gateway con las casillas Exit Node y Accept Routes",
"step4Caption": "Paso 4: Exit Node y Accept Routes. Deja ambas opciones desactivadas si solo necesitas acceder al panel desde el móvil o el portátil.",
"step5Title": "5. Revisar y desplegar",
"step5Body": "Resumen final antes del despliegue. El asistente recuerda que después queda un paso manual en la consola de Tailscale: <strong>aprobar la ruta de subred</strong>.",
"step5Alt": "Paso Revisar y desplegar de Secure Gateway, con el resumen del nombre de host, modo de acceso, redes, Exit Node y Accept Routes y el botón Desplegar pasarela",
"step5Caption": "Paso 5 — revisa la configuración y despliega. El aviso azul al pie señala la aprobación de ruta pendiente.",
"approvalTitle": "Un último paso manual en el admin de Tailscale",
"approvalBody": "Tras desplegar, vuelve a <a>login.tailscale.com/admin/machines</a> y aprueba la subnet route que el gateway está anunciando. Hasta que lo hagas, los dispositivos remotos de tu tailnet no podrán alcanzar realmente IPs de LAN a través del gateway. Tailscale marca las rutas pendientes con un aviso amarillo en la fila del dispositivo — pulsa <em>Edit route settings</em> y marca la casilla de la ruta."
"approvalBody": "Tras el despliegue, vuelve a <a>login.tailscale.com/admin/machines</a> y aprueba la ruta de subred anunciada por la pasarela. Hasta entonces, los dispositivos remotos de tu red Tailscale no podrán acceder a las IP LAN a través de ella. Las rutas pendientes aparecen con un aviso amarillo en la fila del dispositivo: pulsa <em>Edit route settings</em> y marca la casilla de la ruta."
},
"pve": {
"heading": "Proxmox VE",
"intro": "Las protecciones del propio host — firewall, prevención de intrusiones y auditoría de seguridad. Los dos últimos solo se renderizan cuando sus herramientas respectivas están instaladas."
"intro": "Las protecciones del host: cortafuegos, prevención de intrusiones y auditoría de seguridad. Las tarjetas de Fail2Ban y Lynis ofrecen instalarlos si faltan y después muestran sus controles de gestión."
},
"firewall": {
"heading": "Proxmox Firewall",
"imageAlt": "Tarjeta Proxmox Firewall mostrando estado de Cluster Firewall y Host Firewall, Quick Access Rules para ProxMenux Monitor y Proxmox Web UI, contadores Rules Overview y una lista de Firewall Rules con botón Add Rule",
"imageCaption": "Tarjeta Proxmox Firewall — toggles enable / disable a nivel cluster y host, puertos comunes como <em>Quick Access Rules</em>, totales en <em>Rules Overview</em> y la lista completa de reglas con <em>+ Add Rule</em>.",
"intro": "La tarjeta expone el firewall integrado de Proxmox VE (que es independiente de cualquier <code>iptables</code> / <code>nftables</code> a nivel host que puedas correr en paralelo). Tres bloques:",
"imageAlt": "Tarjeta del cortafuegos Proxmox con estado del clúster y del host, reglas de acceso rápido para Monitor y la interfaz web Proxmox, contadores, lista de reglas y botón Añadir regla",
"imageCaption": "Tarjeta del cortafuegos Proxmox: interruptores para el clúster y el host, puertos comunes en <em>Reglas de acceso rápido</em>, contadores en <em>Resumen de reglas</em> y lista completa con <em>+ Añadir regla</em>.",
"intro": "La tarjeta gestiona la configuración del cortafuegos de Proxmox VE. El backend clásico usa <code>iptables</code> y el alternativo usa <code>nftables</code>. No gestiona reglas arbitrarias creadas fuera de Proxmox. Tres bloques:",
"items": [
"<strong>Cluster Firewall + Host Firewall</strong> — toggles globales. El cluster firewall debe estar activo para que cualquier regla a nivel host surta efecto; la tarjeta señala esta dependencia inline.",
"<strong>Quick Access Rules</strong> — filas predefinidas para puertos que importan al propio ProxMenux: <code>8008/TCP</code> (Monitor), <code>8006/TCP</code> (UI web de Proxmox). Cada fila muestra el estado actual allow / deny / unprotected. La UI web de Proxmox se permite vía el macro de firewall <em>integrado</em> de Proxmox y no se puede eliminar por accidente.",
"<strong>Rules Overview</strong> — contadores de reglas totales, reglas accept, reglas drop / reject y puertos distintos protegidos. Los números se leen de <code>/etc/pve/firewall/cluster.fw</code> y <code>/etc/pve/nodes/&lt;node&gt;/host.fw</code>.",
"<strong>Firewall Rules</strong> — lista completa con action / protocolo / puerto / source / level. <em>+ Add Rule</em> abre un editor inline; el icono de papelera en cada fila elimina la regla. Las ediciones escriben a los mismos archivos que usa Proxmox, así que los cambios también aparecen en la UI de Proxmox (Datacenter / Node → Firewall)."
"<strong>Cortafuegos del clúster + cortafuegos del host</strong>: interruptores globales. El del clúster debe estar activado para que se apliquen las reglas del host. La tarjeta indica esta dependencia junto al ajuste.",
"<strong>Reglas de acceso rápido</strong>: filas predefinidas para <code>8008/TCP</code> (Monitor) y <code>8006/TCP</code> (interfaz web Proxmox), con estado permitido, bloqueado o sin protección. La interfaz de Proxmox se permite mediante su macro de cortafuegos <em>integrada</em>, que no puede eliminarse por accidente.",
"<strong>Resumen de reglas</strong>: contadores del total de reglas, reglas accept, reglas drop/reject y puertos distintos protegidos. Los datos se leen de <code>/etc/pve/firewall/cluster.fw</code> y <code>/etc/pve/nodes/&lt;node&gt;/host.fw</code>.",
"<strong>Reglas del cortafuegos</strong>: lista con acción, protocolo, puerto, origen y nivel. <em>+ Añadir regla</em> abre el editor en la tarjeta; la papelera elimina la regla. Los cambios se guardan en los archivos de Proxmox y también aparecen en su interfaz (Datacenter / Node → Firewall)."
]
},
"fail2ban": {
"heading": "Fail2Ban",
"subHeading": "(condicional)",
"whatIs": "<strong>Qué es.</strong> Fail2Ban es un daemon open-source de prevención de intrusiones que vigila archivos de log buscando intentos repetidos fallidos de login y banea la IP ofensora a nivel de firewall. Es la respuesta de facto a los escáneres de fuerza bruta que pegan SSH y formularios de login web 24/7. ProxMenux lo conecta a tres jails por defecto: SSH, el login de la UI web de Proxmox (puerto 8006) y el login del ProxMenux Monitor (puerto 8008).",
"notBundled": "Fail2Ban <strong>no viene de fábrica</strong>. La tarjeta detecta si está instalado y se adapta: cuando falta ofrece una instalación de un clic; una vez instalado muestra estado en vivo de jails, IPs baneadas y te deja ajustar retries / ban time por jail.",
"notInstalledAlt": "Tarjeta Fail2Ban mostrando estado Not Installed con explicación de lo que configuraría: SSH, UI web de Proxmox y protección de ProxMenux Monitor con backend nftables, más un botón Install and Configure Fail2Ban",
"subHeading": "(según el estado)",
"whatIs": "<strong>Qué es.</strong> Fail2Ban es un servicio de código abierto que detecta intentos de inicio de sesión fallidos repetidos en los registros y bloquea la IP en el cortafuegos. Protege frente a ataques de fuerza bruta continuos contra SSH y los formularios web. ProxMenux configura tres jails: SSH, acceso web de Proxmox (puerto 8006) y acceso de ProxMenux Monitor (puerto 8008).",
"notBundled": "Fail2Ban <strong>no viene incluido</strong>. La tarjeta detecta si está instalado y adapta su contenido: si falta, ofrece instalarlo con un clic; una vez instalado, muestra el estado de las jails y las IP bloqueadas, y permite ajustar los reintentos y el tiempo de bloqueo de cada jail.",
"notInstalledAlt": "Tarjeta Fail2Ban sin instalar, con descripción de la protección de SSH, la interfaz web Proxmox y Monitor mediante nftables y botón Instalar y configurar Fail2Ban",
"notInstalledCaption": "Tarjeta Fail2Ban antes de instalar — la caja azul previsualiza lo que configuraría la instalación.",
"clickBody": "Pulsa <em>Install and Configure Fail2Ban</em> y obtienes una modal de confirmación listando cada cambio que hará el script en el host:",
"confirmAlt": "Modal de confirmación Install Fail2Ban listando protección SSH modo agresivo, protección de interfaz web Proxmox puerto 8006, protección ProxMenux Monitor puerto 8008, backend nftables auto-detectado, ajuste del log level de journald y hardening de SSH MaxAuthTries",
"confirmCaption": "Confirmación de instalación — lista explícita de jails, ajustes al log level de journald (para que el jail de auth pueda leer eventos SSH) y un efecto colateral de hardening SSH (<code>MaxAuthTries=3</code>).",
"confirmIntro": "La confirmación dispara un panel de instalación en streaming (apt + config de jails + tests). La misma fontanería que el instalador CLI de ProxMenux.",
"progressAlt": "Panel Fail2Ban Installation mostrando log de instalación en vivo: instalación del paquete, journald MaxLevelStore ajustado para logging de auth, jails configurados, backend nftables detectado, hardening MaxAuthTries, test de comunicación fail2ban-client, mensaje de finalización",
"progressCaption": "Instalación en curso — cada paso se loguea en el panel. Connection-closed al final marca el fin de la sesión de streaming.",
"afterInstall": "Tras instalar la tarjeta pasa a la vista de estado en vivo: jails configurados, contador de IPs baneadas, eventos recientes de ban. Las pestañas grandes separan <em>Jails & Banned IPs</em> de <em>Recent Activity</em> (las últimas N entradas del log de Fail2Ban).",
"activeAlt": "Tarjeta Fail2Ban tras instalar con estado Active, tres jails configurados (proxmenux, proxmox, sshd), contador Banned IPs, Total Bans, Failed Attempts, y filas por jail con retries, ban time, window e icono de rueda dentada",
"activeCaption": "Fail2Ban activo — los tres jails por defecto (<code>proxmenux</code>, <code>proxmox</code>, <code>sshd</code>) con sus settings de retries / ban time / window.",
"tuneBody": "<strong>Ajustar reglas del jail.</strong> Pulsa el icono de rueda dentada en cualquier fila de jail para ajustar <em>Max Retries</em>, <em>Ban Time</em> (usa ban permanente si quieres que los ofensores queden bloqueados hasta que tú los desbanees manualmente) y <em>Find Time</em> (la ventana deslizante para contar retries). Los valores comunes están documentados dentro del formulario.",
"configAlt": "Formulario Configure jail sshd con Max Retries, Ban Time en segundos con opción Permanent Ban, Find Time, recordatorio de valores comunes y botón Save Configuration",
"configCaption": "Editando el jail sshd — elige un <em>Max Retries</em> más estricto para SSH si solo te logueas desde tu propia subred, o extiende el <em>Ban Time</em> para el panel de cara al público.",
"outro": "El recorrido completo <em>Qué instala / cómo se configura / cómo desinstalar</em> — incluyendo la ruta de instalación manual, el efecto colateral de SSH MaxAuthTries y la relación con el journal <code>proxmenux-auth.log</code> — está en <link>ProxMenux → Seguridad → Fail2Ban</link>.",
"calloutTitle": "Sin Fail2Ban, la protección contra fuerza bruta es best-effort",
"calloutBody": "ProxMenux Monitor tiene su propio hook de ban a <em>nivel de aplicación</em> en el pipeline de peticiones de Flask — pero solo surte efecto si Fail2Ban está instalado y escribe a la tabla de bans. Sin Fail2Ban, el Monitor loguea los logins fallidos a <code>proxmenux-auth.log</code> para inspección futura pero no bloquea IPs activamente."
"clickBody": "Pulsa <em>Instalar y configurar Fail2Ban</em> para abrir un diálogo de confirmación que enumera todos los cambios del script en el host:",
"confirmAlt": "Confirmación de Fail2Ban con modo agresivo para SSH, protección de Proxmox en el puerto 8006 y Monitor en el 8008, detección de nftables, ajuste de registros de journald y refuerzo de SSH MaxAuthTries",
"confirmCaption": "Confirmación de instalación: lista de jails, ajuste del nivel de registro de journald para leer eventos SSH y refuerzo adicional de SSH (<code>MaxAuthTries=3</code>).",
"confirmIntro": "Al confirmar, se abre un panel con el registro de instalación en directo: apt, configuración de jails y pruebas. Usa el mismo mecanismo que el instalador CLI de ProxMenux.",
"progressAlt": "Panel con el registro de instalación de Fail2Ban: paquete, journald MaxLevelStore para autenticación, jails, detección de nftables, refuerzo MaxAuthTries, prueba de comunicación fail2ban-client y mensaje de finalización",
"progressCaption": "Instalación en curso: el panel registra cada paso. El mensaje Connection closed al final indica que ha terminado la sesión de transmisión.",
"afterInstall": "Tras instalarse, la tarjeta muestra el estado en directo: jails configurados, IP bloqueadas y bloqueos recientes. Las pestañas separan <em>Jails e IP bloqueadas</em> de <em>Actividad reciente</em>, con las últimas N entradas del registro de Fail2Ban.",
"activeAlt": "Tarjeta Fail2Ban activa con tres jails (proxmenux, proxmox, sshd), contadores de IP bloqueadas, bloqueos totales e intentos fallidos, y filas con intentos, tiempo de bloqueo, intervalo y rueda dentada",
"activeCaption": "Fail2Ban activo: los tres jails predeterminados (<code>proxmenux</code>, <code>proxmox</code> y <code>sshd</code>) con sus ajustes de intentos, duración del bloqueo e intervalo de detección.",
"tuneBody": "<strong>Ajustar las reglas del jail.</strong> Pulsa su rueda dentada para cambiar <em>Max Retries</em>, <em>Ban Time</em> y <em>Find Time</em>, el intervalo móvil en que se cuentan los intentos. Un bloqueo permanente dura hasta que lo retires manualmente. El formulario explica los valores habituales.",
"configAlt": "Formulario del jail sshd con Max Retries, Ban Time en segundos, opción Permanent Ban, Find Time, ayuda con valores habituales y botón Guardar configuración",
"configCaption": "Edición del jail sshd: reduce <em>Max Retries</em> para SSH si solo accedes desde tu subred, o amplía <em>Ban Time</em> para el panel expuesto a Internet.",
"outro": "La guía <em>Qué instala, cómo se configura y cómo desinstalar</em> incluye la instalación manual, el cambio de SSH MaxAuthTries y la relación con el registro <code>proxmenux-auth.log</code>. Consulta <link>ProxMenux → Seguridad → Fail2Ban</link>.",
"calloutTitle": "Sin Fail2Ban, este mecanismo no bloquea las IP",
"calloutBody": "ProxMenux Monitor comprueba las IP bloqueadas en la jaula <code>proxmenux</code> de Fail2Ban a <em>nivel de aplicación</em> antes de procesar las peticiones de Flask, con el resultado en caché durante 30 segundos. Sin Fail2Ban, los intentos fallidos se registran en <code>proxmenux-auth.log</code> y el inicio de sesión se limita a 5 intentos por IP cada 5 minutos, pero no se bloquea ninguna IP."
},
"lynis": {
"heading": "Lynis Security Audit",
"subHeading": "(condicional)",
"whatIs": "<strong>Qué es.</strong> Lynis es una herramienta open-source de auditoría de seguridad que ejecuta ~280 tests en el host (permisos de archivos, hardening del kernel, config SSH, vulnerabilidades de paquetes, política de cripto, tareas programadas, banner grabbing, etc.) y produce una puntuación de hardening 0–100, una lista de warnings y una lista de sugerencias. Es la baseline de facto para \"¿este servidor está en buena forma?\" en servidores basados en Debian.",
"whyUseful": "<strong>Por qué es útil.</strong> Conocer la postura de seguridad de tu servidor es difícil de hacer leyendo archivos de config uno a uno. Lynis captura las cosas que rutinariamente se pasan por alto: flags de hardening del kernel ausentes, cifrados SSH débiles activos, journal no persistente, <code>NOPASSWD</code> en sudoers para cuentas por defecto, y muchas más. Volver a ejecutarlo tras aplicar los ajustes post-instalación de ProxMenux te da un número objetivo de la mejora.",
"notInstalledAlt": "Tarjeta Lynis Security Audit con estado Not Installed y botón Install Lynis, listando features: scoring de hardening, detección de vulnerabilidades, comprobación de compliance y fuente GitHub",
"heading": "Auditoría de seguridad de Lynis",
"subHeading": "(según el estado)",
"whatIs": "<strong>Qué es.</strong> Lynis es una herramienta de auditoría de seguridad de código abierto que realiza unas 280 pruebas del host: permisos, protección del kernel, SSH, vulnerabilidades de paquetes, política criptográfica, tareas programadas e identificación de servicios, entre otras. Genera un índice de seguridad de 0 a 100, avisos y sugerencias. Se usa como referencia para evaluar servidores basados en Debian.",
"whyUseful": "<strong>Por qué es útil.</strong> Evaluar la seguridad leyendo cada archivo de configuración resulta difícil. Lynis detecta fallos habituales: opciones de protección del kernel ausentes, cifrados SSH débiles, registros no persistentes o <code>NOPASSWD</code> en sudoers para cuentas predeterminadas. Repetir el análisis tras los ajustes de ProxMenux permite comparar la mejora con una puntuación.",
"notInstalledAlt": "Tarjeta Lynis sin instalar con botón Instalar Lynis y funciones: puntuación de seguridad, detección de vulnerabilidades, cumplimiento y código en GitHub",
"notInstalledCaption": "Tarjeta Lynis antes de instalar — la caja azul resume lo que hace la herramienta.",
"notBundled": "Lynis tampoco <strong>viene de fábrica</strong>. ProxMenux instala la última release directamente desde la fuente oficial en GitHub (no el paquete Debian, que va varias versiones menores por detrás).",
"confirmAlt": "Modal de confirmación Install Lynis listando lo que hace Lynis: scoring de hardening, detección de vulnerabilidades, análisis de configuración, comprobación de compliance, fuente desde el repositorio oficial de GitHub",
"confirmCaption": "Confirmación de instalación — explícita sobre la fuente GitHub.",
"progressAlt": "Panel en streaming Lynis Installation: instalando la última herramienta de scan, versión 3.1.6 confirmada, mensaje de instalación completada",
"progressCaption": "Instalación en curso — el mismo patrón de panel en streaming que Fail2Ban.",
"afterInstall": "Tras instalar la tarjeta muestra la versión y un historial de auditorías vacío. Pulsa <em>Run Security Audit</em> para arrancar el primer scan.",
"installedAlt": "Tarjeta Lynis Security Audit tras instalar con insignia versión 3.1.6 Installed, timestamp Last Scan, Hardening Index 0, Warnings 0, Suggestions 0, fila de audit report vacía y botón Run Security Audit",
"installedCaption": "Lynis instalado, sin auditoría todavía. La tarjeta prerrellena los tiles de métricas con ceros.",
"runningAlt": "Tarjeta Lynis Security Audit mientras la auditoría está corriendo mostrando mensaje Security audit in progress, duración estimada de 2-5 minutos y un botón Running Audit deshabilitado",
"runningCaption": "Auditoría en curso — el botón de acción muestra un spinner y la tarjeta avisa explícitamente de que el scan puede llevar 2–5 minutos.",
"finishedBody": "Cuando termina, la tarjeta pasa a la vista de resultados: hardening index, warnings, suggestions y una lista <em>Audit Reports</em> con cada scan histórico.",
"resultsAlt": "Tarjeta Lynis Security Audit con resultados: Hardening Index 71 con desglose Lynis 66 PVE 71, 3 warnings, 40 suggestions, barra de progreso Security Hardening Score Proxmox Adjusted 71 de 100 en el rango Good, lista de audit reports con descarga PDF y botón Run Security Audit",
"resultsCaption": "Resultados de auditoría — Hardening Index <strong>71/100 (Good)</strong> en una ejecución de ejemplo. La tarjeta también muestra la \"puntuación raw de Lynis\" (66) frente a la puntuación ajustada para Proxmox (71) que devuelve 11 puntos por hallazgos que el corpus de tests de Lynis marca pero que son comportamiento esperado en Proxmox VE.",
"scoreTitle": "Puntuación raw de Lynis vs puntuación ajustada para Proxmox",
"scoreIntro": "Lynis trae reglas ajustadas para Debian de propósito general. Proxmox diverge legítimamente de algunas (servicios corriendo como root por razones de cluster, tuning custom de <code>journald</code>, etc.). La tarjeta muestra ambos números para que puedas:",
"notBundled": "Lynis tampoco <strong>viene incluido</strong>. ProxMenux lo instala directamente desde el código oficial de GitHub en lugar del paquete de Debian.",
"confirmAlt": "Diálogo de confirmación de Lynis con sus funciones: puntuación de seguridad, detección de vulnerabilidades, análisis de configuración, comprobación de cumplimiento y origen en el repositorio oficial de GitHub",
"confirmCaption": "Confirmación de instalación que indica expresamente el origen en GitHub.",
"progressAlt": "Panel de instalación de Lynis en directo, con instalación de la herramienta más reciente, versión 3.1.6 confirmada y mensaje de finalización",
"progressCaption": "Instalación en curso: el panel muestra el registro en directo, igual que con Fail2Ban.",
"afterInstall": "Tras la instalación, la tarjeta muestra la versión y un historial de auditorías vacío. Pulsa <em>Ejecutar auditoría de seguridad</em> para iniciar el primer análisis.",
"installedAlt": "Tarjeta Lynis tras instalarse con versión 3.1.6, fecha del último análisis, índice de seguridad 0, avisos 0, sugerencias 0, informe vacío y botón Ejecutar auditoría de seguridad",
"installedCaption": "Lynis instalado, aún sin auditorías. Los indicadores muestran ceros inicialmente.",
"runningAlt": "Tarjeta Lynis durante la auditoría con mensaje de análisis en curso, duración estimada de 2 a 5 minutos y botón Auditoría en curso deshabilitado",
"runningCaption": "Auditoría en curso: el botón muestra un indicador de carga y la tarjeta avisa de que el análisis puede tardar de 2 a 5 minutos.",
"finishedBody": "Al terminar, la tarjeta muestra los resultados: índice de seguridad, avisos, sugerencias y la lista de <em>Informes de auditoría</em> con los análisis anteriores.",
"resultsAlt": "Tarjeta Lynis con índice 71, desglose Lynis 66 y PVE 71, 3 avisos, 40 sugerencias, puntuación ajustada a Proxmox 71 de 100 en el rango Bueno, informes con descarga PDF y botón Ejecutar auditoría de seguridad",
"resultsCaption": "Resultados de ejemplo: índice de seguridad <strong>71/100 (Bueno)</strong>. La tarjeta muestra la puntuación original de Lynis (66) y la ajustada para Proxmox (71). El ajuste depende de la puntuación original y de la proporción de hallazgos considerados normales en Proxmox VE; no suma 11 puntos fijos.",
"scoreTitle": "Puntuación original de Lynis y puntuación ajustada para Proxmox",
"scoreIntro": "Las reglas de Lynis están pensadas para Debian de uso general. Proxmox se aparta de algunas por motivos válidos, como servicios de clúster ejecutados como root o ajustes propios de <code>journald</code>. La tarjeta muestra ambas puntuaciones para:",
"scoreItems": [
"Trackear tu <em>puntuación raw de Lynis</em> igual que lo harían auditores externos.",
"Trackear la puntuación <em>ajustada para Proxmox</em> — una baseline más justa si estás comparando nodos dentro del mismo cluster."
"Seguir la evolución de la <em>puntuación original de Lynis</em>, como haría un auditor externo.",
"Seguir la puntuación <em>ajustada para Proxmox</em>, una referencia más adecuada para comparar nodos del mismo clúster."
],
"reportBody": "<strong>El informe completo.</strong> Cada fila de auditoría en la lista tiene un botón <em>PDF</em> que descarga un informe de varias páginas con el resumen ejecutivo, info del sistema, postura de seguridad, cada warning con explicación, cada sugerencia rankeada por impacto y el inventario de paquetes. Es el artefacto que adjuntarías a una revisión de seguridad.",
"reportAlt": "Primera página de ejemplo del PDF Lynis Security Audit Report mostrando resumen ejecutivo con hardening 71 de 100, contadores de warnings y suggestions, bloque de System Information con hostname, kernel, versión de Lynis, fecha del informe, resumen de postura de seguridad",
"reportCaption": "Primera página de un informe descargado — resumen ejecutivo, System Information y resumen de postura de seguridad. El informe completo continúa con warnings detallados, sugerencias y la lista de paquetes instalados. Hay un <a>PDF de ejemplo</a> adjunto como referencia.",
"reportBody": "<strong>Informe completo.</strong> El botón <em>PDF</em> de cada auditoría descarga un informe de varias páginas: resumen ejecutivo, información del sistema, estado de seguridad, avisos explicados, sugerencias ordenadas por impacto e inventario de paquetes. Puedes adjuntarlo a una revisión de seguridad.",
"reportAlt": "Primera página de ejemplo del informe PDF de Lynis con resumen ejecutivo, índice 71 de 100, contadores de avisos y sugerencias, nombre de host, kernel, versión de Lynis, fecha y resumen del estado de seguridad",
"reportCaption": "Primera página del informe descargado: resumen ejecutivo, información del sistema y estado de seguridad. Después incluye avisos detallados, sugerencias y paquetes instalados. Se adjunta un <a>PDF de ejemplo</a> como referencia.",
"runPeriodically": "Ejecuta la auditoría periódicamente (tras grandes upgrades de Proxmox, tras aplicar ajustes post-instalación, antes de abrir una ruta de acceso remoto) y guarda los informes — la tendencia importa más que cualquier número aislado.",
"outro": "El recorrido completo <em>Qué instala / cómo se configura / cómo desinstalar</em> y un análisis escrito del informe de ejemplo están en <link>ProxMenux → Seguridad → Lynis</link>."
"outro": "La guía completa de <em>instalación, configuración y desinstalación</em> y el análisis de un informe de ejemplo están en <link>ProxMenux → Seguridad → Lynis</link>."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -179,22 +179,22 @@
{
"card": "Autenticación, 2FA, cambio de contraseña",
"endpoint": "/api/auth/*",
"source": "SQLite local + JWT emitido por el Monitor."
"source": "Configuración local de autenticación en ~/.config/proxmenux-monitor/auth.json; JWT emitidos por Monitor."
},
{
"card": "SSL / HTTPS",
"card": "SSL/HTTPS",
"endpoint": "/api/auth/ssl/*",
"source": "<code>openssl x509</code> sobre <code>/etc/pve/local/pve-ssl.pem</code> + <code>/etc/proxmenux/ssl_config.json</code>."
},
{
"card": "Listar / generar / revocar tokens API",
"card": "Listar, generar y revocar tokens de API",
"endpoint": "/api/auth/api-tokens",
"source": "Filas de token guardadas localmente; nada sale del host."
},
{
"card": "Secure Gateway (deploy + estado)",
"endpoint": "/api/oci/*",
"source": "Provisiona LXC Alpine + <code>tailscaled</code> vía <code>pct create</code> / <code>pct exec</code>."
"source": "Crea un LXC Alpine y configura <code>tailscaled</code> mediante <code>pct create</code> / <code>pct exec</code>."
},
{
"card": "Estado y reglas de firewall",
@@ -219,27 +219,27 @@
{
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tail": " — flujo completo de primer arranque, selector de app 2FA, recuperación de authenticator perdido, snippets de reverse proxy."
"tail": " — configuración inicial completa, selección de app 2FA, recuperación por pérdida del autenticador y ejemplos de proxy inverso."
},
{
"label": "Integraciones",
"href": "/docs/monitor/integrations",
"tail": " — cookbooks para usar tokens API con Homepage, Home Assistant, Prometheus, n8n y el Secure Gateway de extremo a extremo."
"tail": " — ejemplos de uso de tokens de API con Homepage, Home Assistant, Prometheus y n8n, y configuración completa de Secure Gateway."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tailRich": " — cada endpoint <code>/api/auth</code>, <code>/api/security</code> y <code>/api/oci</code> con método, body y ejemplos curl."
"tailRich": " — endpoints de <code>/api/auth</code>, <code>/api/security</code> y <code>/api/oci</code> con método, cuerpo de petición y ejemplos de curl."
},
{
"label": "ProxMenux → Seguridad → Fail2Ban",
"href": "/docs/security/fail2ban",
"tail": " — recorrido de instalación, jails configurados, ruta de instalación manual."
"tail": " — guía de instalación, jails configurados e instalación manual."
},
{
"label": "ProxMenux → Seguridad → Lynis",
"href": "/docs/security/lynis",
"tail": " — informe de ejemplo, interpretación del score, cuándo volver a ejecutarlo."
"tail": " — informe de ejemplo, interpretación de la puntuación y cuándo repetir la auditoría."
}
]
}
@@ -1,173 +1,173 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Ajustes | Documentación de ProxMenux",
"description": "La pestaña Ajustes controla el idioma del Monitor, el orden de navegación, las preferencias del panel, los umbrales y exclusiones de salud, las notificaciones, la IA y el inventario de optimizaciones."
"description": "La pestaña Ajustes controla idioma, orden de navegación, preferencias del panel, umbrales y exclusiones de supervisión, notificaciones, IA e inventario de optimizaciones posteriores a la instalación."
},
"header": {
"title": "Panel: pestaña Ajustes",
"description": "Idioma del Monitor, orden de navegación, preferencias del panel, exclusiones de monitorización, notificaciones, configuración de IA e inventario de optimizaciones de ProxMenux.",
"description": "Idioma de Monitor, orden de navegación, preferencias del panel, exclusiones, notificaciones, IA e inventario actualizado de optimizaciones de ProxMenux.",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "Dónde vive realmente cada setting",
"body": "La pestaña Ajustes reúne varias funciones distintas: cómo se muestra el panel, qué vigila el Monitor de salud, cómo se envían las alertas y qué cambios ha aplicado ProxMenux en el host. Las tarjetas que tienen su propia página de documentación enlazan a ella en lugar de duplicar el contenido: Ajustes es el punto de entrada."
"title": "Dónde se guarda cada ajuste",
"body": "Ajustes reúne la presentación del panel, la supervisión de Health Monitor, el envío de alertas y los cambios ya aplicados al host por ProxMenux. Las tarjetas con documentación detallada enlazan a ella; aquí encontrarás su punto de acceso."
},
"interfaceLanguage": {
"heading": "Idioma de la interfaz",
"intro": "Selecciona el idioma de la <strong>interfaz web del Monitor</strong>. El cambio se aplica de inmediato; no reinicia el servicio ni modifica el idioma de los menús de ProxMenux ejecutados en la terminal.",
"intro": "Elige el idioma de la <strong>interfaz web del Monitor</strong>. Se aplica de inmediato, sin reiniciar el servicio ni cambiar el idioma de los menús de terminal de ProxMenux.",
"items": [
"ProxMenux Monitor ofrece actualmente inglés, alemán, español, francés, italiano, portugués, eslovaco y sueco.",
"En la primera visita, el Monitor utiliza el idioma del navegador si está disponible; en caso contrario, utiliza inglés.",
"Al cambiar la selección, se actualiza el idioma de la página y también el de otras pestañas abiertas con el mismo perfil del navegador.",
"Si falta una cadena traducida, solo ese texto se muestra en inglés en lugar de presentar una clave rota."
"En la primera visita usa el idioma del navegador si está disponible; en caso contrario, inglés.",
"Cambiar la selección actualiza el idioma de la página y lo sincroniza con las demás pestañas del mismo perfil del navegador.",
"Si falta una traducción, solo ese texto aparece en inglés en lugar de una clave o marcador roto."
],
"scopeTitle": "Preferencia local del navegador",
"scopeBody": "La selección se guarda en <code>localStorage</code> con la clave <code>proxmenux-ui-language</code>. Por tanto, pertenece a este perfil de navegador y dispositivo; no es un ajuste global del nodo. Cada administrador puede utilizar un idioma distinto."
"scopeBody": "La selección se guarda en <code>localStorage</code> con la clave <code>proxmenux-ui-language</code>. Pertenece al perfil y dispositivo actuales, no a todo el nodo. Cada administrador puede elegir su idioma."
},
"navigationOrder": {
"heading": "Orden de navegación",
"intro": "Esta tarjeta permite ordenar los siete elementos principales: <strong>Resumen, Apps, VMs y LXCs, Nodo, Copias, Terminal y Administración</strong>. Pulsa <strong>Editar</strong>, arrastra las filas y guarda el resultado.",
"intro": "Ordena los siete elementos principales: <strong>Resumen, Apps, VMs y LXCs, Nodo, Backup, Terminal y Administración</strong>. Pulsa <strong>Editar</strong>, arrastra las filas y guarda.",
"items": [
"Con el ratón, el arrastre comienza al pulsar. En una pantalla táctil se utiliza una pulsación mantenida de 250 ms para no confundir el desplazamiento normal con una reordenación.",
"Los grupos <strong>Nodo</strong> y <strong>Administración</strong> se mueven como unidades completas; sus páginas internas conservan el orden establecido por ProxMenux.",
"El menú móvil respeta el mismo orden guardado.",
"<strong>Restaurar valores predeterminados</strong> restablece el borrador. Es necesario guardar para aplicar el cambio.",
"Si una versión futura añade una nueva pestaña principal, esta se incorpora al final del orden personalizado sin borrar la organización del usuario."
"Con el ratón, el arrastre empieza al pulsar. En pantallas táctiles requiere mantener la pulsación 250 ms para distinguirlo del desplazamiento.",
"Los grupos <strong>Nodo</strong> y <strong>Administración</strong> se mueven completos; sus páginas internas conservan el orden establecido.",
"El menú móvil respeta el orden guardado.",
"<strong>Restaurar valores predeterminados</strong> restablece el orden en edición. Guarda para aplicar el cambio.",
"Las nuevas pestañas principales de futuras versiones se añaden al final del orden personalizado, conservando tu organización."
],
"landingTitle": "El primer elemento se convierte en la pestaña inicial",
"landingBody": "El primer elemento guardado es la página que abre el Monitor al cargar. Si <strong>Nodo</strong> ocupa la primera posición, se abre Almacenamiento; si la ocupa <strong>Administración</strong>, se abren los Logs del sistema. El orden se guarda solo en este navegador con la clave <code>proxmenux-nav-order</code>, por lo que cada dispositivo puede utilizar una organización distinta."
"landingTitle": "El primer elemento es la pestaña inicial",
"landingBody": "Monitor abre el primer elemento guardado. Si es <strong>Nodo</strong>, abre Almacenamiento; si es <strong>Administración</strong>, abre Registros del sistema. El orden se guarda en este navegador bajo <code>proxmenux-nav-order</code>, por lo que cada dispositivo puede tener su propia organización."
},
"networkUnits": {
"heading": "Network Units",
"imageAlt": "Tarjeta Network Units con desplegable Network Unit Display puesto en Bytes",
"imageCaption": "Elige entre bits por segundo y bytes por segundo para cada rate de red mostrado en el panel.",
"body": "Elige cómo se muestra el throughput de red a lo largo del panel: <strong>bits por segundo</strong> (Mbps / Gbps) o <strong>bytes por segundo</strong> (MB/s / GB/s). Bits es el valor por defecto porque es como los fabricantes de NICs e ISPs etiquetan sus productos; bytes es lo que reportan la mayoría de herramientas de transferencia de archivos. El setting afecta cada gráfica, insignia y tooltip que muestra rate de red — aplicado inmediatamente, sin recargar."
"heading": "Unidades de red",
"imageAlt": "Tarjeta Unidades de red con el selector de visualización en Bytes",
"imageCaption": "Elige bits por segundo o bytes por segundo para todas las velocidades de red del panel.",
"body": "Muestra la velocidad de red en <strong>bits por segundo</strong> (Mbps/Gbps) o <strong>bytes por segundo</strong> (MB/s/GB/s). Por defecto se usan bits, como en las especificaciones de interfaces y proveedores; las transferencias de archivos suelen usar bytes. El cambio se aplica de inmediato a gráficos, etiquetas y ayudas, sin recargar."
},
"health": {
"heading": "Monitor de salud",
"intro": "La tarjeta expone el setting <strong>Suppression Duration</strong> por categoría — una vez se descarta una alerta, cuánto tiene que pasar antes de que se permita al escáner volver a dispararla. Cada una de las diez categorías del Monitor de salud (CPU, Memoria, Almacenamiento, Discos, Red, VMs, Servicios PVE, Logs, Updates, Seguridad) tiene su propio desplegable con estos valores:",
"intro": "La tarjeta configura la <strong>duración del silenciamiento</strong>: cuánto debe esperar el análisis antes de volver a avisar de una alerta descartada. Cada categoría —CPU, memoria, almacenamiento, discos, red, VM, servicios PVE, registros, actualizaciones y seguridad— tiene su desplegable:",
"items": [
"<strong>24 h</strong> — por defecto para la mayoría de categorías transitorias.",
"<strong>72 h</strong> — para eventos sobre los que quieres unos días de silencio.",
"<strong>72 h</strong> — para silenciar estos eventos durante unos días.",
"<strong>168 h</strong> (1 semana) y <strong>720 h</strong> (1 mes) — chequeos periódicos.",
"<strong>8760 h</strong> (1 año) — efectivamente \"silencio en el futuro previsible\".",
"<strong>8760 h</strong> (1 año) — silencio durante un periodo largo.",
"<strong>-1</strong> — silencio permanente hasta que lo reactives manualmente.",
"<strong>Custom hours</strong> — cualquier entero si necesitas un valor intermedio."
"<strong>Horas personalizadas</strong>: cualquier número entero si necesitas un valor intermedio."
],
"imageAlt": "Card Settings → Monitor de salud con los desplegables de supresión por categoría y la sección Active Suppressions",
"imageCaption": "Card Monitor de salud — los desplegables por categoría fijan los valores por defecto para nuevos dismisses; la sección Active Suppressions debajo lista cada alerta actualmente silenciada y permite revertirlas.",
"editTitle": "Modo Edit",
"editBody": "La tarjeta es de solo-lectura por defecto. Pulsa <strong>Edit</strong> en la esquina superior derecha de la card para activar los desplegables y los botones Re-enable. <strong>Save</strong> confirma todos los cambios pendientes (cambios de Suppression Duration y re-enables encolados) en un solo lote; <strong>Cancel</strong> los descarta todos. El botón Save solo se activa cuando hay al menos un cambio pendiente.",
"activeTitle": "Active Suppressions",
"activeIntro": "Debajo de los desplegables de Suppression Duration, la sección <strong>Active Suppressions</strong> lista cada alerta actualmente silenciada — tanto los dismisses time-limited (24 h, 7 días, ventanas custom) como los <em>Permanent</em>. Cada fila muestra:",
"imageAlt": "Ajustes, tarjeta Health Monitor con duración por categoría y sección de silenciamientos activos",
"imageCaption": "Los desplegables definen la duración para futuros descartes. La sección inferior muestra las alertas silenciadas y permite reactivarlas.",
"editTitle": "Modo de edición",
"editBody": "La tarjeta comienza en solo lectura. Pulsa <strong>Editar</strong> arriba a la derecha para activar desplegables y botones de reactivación. <strong>Guardar</strong> aplica en un lote las duraciones y reactivaciones pendientes; <strong>Cancelar</strong> las descarta. Guardar solo se activa cuando hay cambios.",
"activeTitle": "Silenciamientos activos",
"activeIntro": "Bajo las duraciones, <strong>Silenciamientos activos</strong> enumera las alertas silenciadas temporalmente —24 h, 7 días u otro periodo— y las <em>permanentes</em>. Cada fila muestra:",
"activeItems": [
"Un badge coloreado — <strong>Permanent</strong> (ámbar) o una cuenta atrás como <strong>24h remaining</strong> / <strong>7d remaining</strong> (azul).",
"El identificador de la alerta, normalizado para legibilidad (p. ej. <code>pve_storage_full_PBS-Cloud</code> → <em>PVE Storage Full: PBS-Cloud</em>).",
"Categoría, severidad y el timestamp en que se descartó la alerta.",
"Un botón <strong>Re-enable</strong> (activo solo en modo Edit) que encola la alerta para ser un-acknowledged al siguiente Save."
"Una insignia de color: <strong>Permanente</strong> en ámbar o una cuenta atrás, como <strong>24 h restantes</strong> / <strong>7 días restantes</strong>, en azul.",
"El identificador de la alerta, adaptado para facilitar su lectura (p. ej. <code>pve_storage_full_PBS-Cloud</code> → <em>Almacenamiento PVE lleno: PBS-Cloud</em>).",
"Categoría, gravedad y fecha y hora en que se descartó la alerta.",
"Un botón <strong>Reactivar</strong>, disponible al editar, deja pendiente retirar el silenciamiento al guardar."
],
"activeReenableTitle": "Flujo de Re-enable",
"activeReenableBody": "Pulsar <strong>Re-enable</strong> en modo Edit marca la fila en verde y tacha su identificador — está encolada pero todavía no aplicada. Volver a hacer clic en la misma fila la <strong>Undo</strong> (la saca de la cola). Cuando pulsas <strong>Save</strong>, cada re-enable encolado dispara <code>POST /api/health/un-acknowledge</code> en paralelo y las filas afectadas desaparecen de la lista. Si la condición subyacente sigue presente y la categoría soporta re-fire, la alerta reaparece en la lista Active del Monitor de salud en el siguiente ciclo de escaneo.",
"activePermanentNote": "Los dismisses permanentes (alertas descartadas con <em>Permanently</em> desde el modal del Monitor, o aquellas cuya categoría tenga el default puesto a <code>-1</code>) <strong>solo se pueden revertir desde aquí</strong>. El modal del dashboard no expone un botón un-dismiss para ellas — el panel Active Suppressions es el único log de auditoría + UI de revert.",
"activeAutoRefreshTitle": "Auto-refresh",
"activeAutoRefreshBody": "La lista se refresca automáticamente cuando descartas o un-dismiss una alerta desde el modal del Monitor de salud (vía un evento in-browser), cuando la pestaña recupera el foco y al cambio de visibilidad. No necesitas recargar la página tras descartar una alerta desde el dashboard.",
"calloutTitle": "La semántica completa vive en la página del Monitor de salud",
"calloutBody": "Las reglas de escalada (cuándo un re-fire pasa a critical), el comportamiento de auto-resolve para eventos cuyo dispositivo subyacente desaparece y la diferencia entre dismissed y resolved — todo documentado bajo <link>Monitor de salud → Descartar alertas y la Suppression Duration</link>. Esta tarjeta solo expone los desplegables por categoría y el panel Active Suppressions."
"activeReenableTitle": "Cómo reactivar una alerta",
"activeReenableBody": "<strong>Reactivar</strong> al editar marca la fila en verde y tacha su identificador; aún no se aplica. Pulsa de nuevo para <strong>Deshacer</strong>. <strong>Guardar</strong> envía en paralelo <code>POST /api/health/un-acknowledge</code> por cada reactivación y retira sus filas. Si el problema persiste y la categoría permite repetir avisos, la alerta volverá a Activas en el próximo análisis.",
"activePermanentNote": "Los descartes permanentes —mediante <em>Permanente</em> o duración predeterminada <code>-1</code>— <strong>solo se revierten aquí</strong>. El diálogo general no ofrece ese botón; esta sección reúne el registro y la reactivación.",
"activeAutoRefreshTitle": "Actualización automática",
"activeAutoRefreshBody": "La lista se actualiza al descartar o reactivar una alerta desde Health Monitor, al volver a la pestaña y al cambiar su visibilidad. No necesitas recargar la página.",
"calloutTitle": "Detalles en la página de Health Monitor",
"calloutBody": "Las reglas de escalado, la resolución automática cuando desaparece un dispositivo y la diferencia entre descartar y resolver se explican en <link>Health Monitor → Descartar alertas y duración del silenciamiento</link>. Esta tarjeta ofrece los desplegables y los silenciamientos activos."
},
"thresholds": {
"heading": "Health Monitor Thresholds",
"intro": "Donde la tarjeta anterior decide <em>cuánto tiempo quedarse callado tras un dismiss</em>, esta decide <strong>a qué valor se dispara una alerta en primer lugar</strong>. Cada chequeo que ejecuta el Monitor de salud está parametrizado por un par de números — un umbral <strong>Warning</strong> y un umbral <strong>Critical</strong> — y ambos se exponen aquí para que el operador los ajuste.",
"heading": "Umbrales de Health Monitor",
"intro": "La tarjeta anterior define <em>cuánto dura el silencio tras descartar</em>; esta define <strong>el valor que activa una alerta</strong>. La mayoría de controles tienen valores <strong>Aviso</strong> y <strong>Crítico</strong> ajustables. La tabla explica excepciones como la regla combinada de swap.",
"whatForTitle": "Para qué sirve",
"whatForIntro": "Los valores por defecto que vienen con ProxMenux son sensatos para el host Proxmox medio, pero cada entorno tiene su propio sobre operativo:",
"whatForIntro": "Los valores predeterminados sirven como punto de partida, pero cada entorno tiene sus propias condiciones:",
"whatForItems": [
"Un homelab pequeño con un SSD único puede querer avisar antes en capacidad (75 / 90 %) para dejar margen a snapshots.",
"Un host de datacenter con nodos Ceph redundantes puede ser más relajado en avisos de memoria (un working set al 90 % es normal bajo ARC de ZFS).",
"Un mini-PC con refrigeración pasiva necesita umbrales de temperatura más bajos que un servidor con refrigeración forzada por aire — misma clase de drive, sobre físico distinto.",
"Un host muy virtualizado que clava CPU durante builds no debería avisar en cada pico del 80 %, pero sí debe seguir alertando sobre presión sostenida."
"Un homelab con un único SSD puede avisar antes de llenarse, por ejemplo al 75/90 %, para dejar margen a los snapshots.",
"Los umbrales de memoria deben reflejar las mediciones y la carga del host. La redundancia Ceph no justifica por sí sola relajar avisos, y el uso elevado de ARC de ZFS no equivale a memoria de trabajo irrecuperable.",
"Elige umbrales de temperatura según las especificaciones del disco y sus condiciones reales. La refrigeración pasiva o forzada no determina por sí sola un límite seguro universalmente más bajo o más alto.",
"Un host muy virtualizado puede alcanzar picos de CPU durante compilaciones sin necesitar avisos por cada pico del 80 %, pero debe seguir avisando de saturación sostenida."
],
"whatForOutro": "Editar un umbral surte efecto <strong>en el siguiente scan</strong> — el Monitor de salud relee los valores desde <code>/usr/local/share/proxmenux/health_thresholds.json</code> en cada ciclo, sin reinicio de servicio. Los mismos números también alimentan los rangos de color de los widgets del panel (la línea de temperatura en la modal de temperatura de disco, las barras de las tarjetas de almacenamiento) para que la clasificación visual coincida con lo que dispara la alerta.",
"coloursTitle": "Colores de estado: cómo renderizan Warning y Critical en el panel",
"coloursIntro": "Cada umbral de abajo produce la misma clasificación de tres estados a lo largo del panel — los mismos colores para barras de almacenamiento, anillos de CPU/memoria, chips de temperatura y el punto de la modal de disco. Leer un color en cualquier sitio del Monitor mapea a un rango definido relativo al par configurado:",
"whatForOutro": "Los cambios admitidos se aplican <strong>en el siguiente análisis</strong>. Health Monitor lee <code>/usr/local/share/proxmenux/health_thresholds.json</code> cada ciclo sin reinicio. Algunos indicadores, como temperatura de disco, usan estos valores; ciertas barras de capacidad conservan sus propios cortes.",
"coloursTitle": "Colores de estado de Aviso y Crítico",
"coloursIntro": "Los widgets que usan el par Aviso/Crítico siguen los tres estados siguientes. Algunos indicadores, como las barras de capacidad PVE, tienen límites propios; su color no basta para deducir una alerta de Health Monitor.",
"headerColour": "Color",
"headerRange": "Rango",
"headerMeaning": "Significado",
"colourRows": [
{
"colour": "Verde",
"range": "valor < Warning",
"meaning": "Rango operativo normal. No se dispara alerta."
"range": "Valor < Aviso",
"meaning": "Rango normal. No se genera alerta."
},
{
"colour": "Ámbar",
"range": "Warning ≤ valor < Critical",
"meaning": "Estado warning. El Monitor de salud dispara un evento de severidad WARNING; las notificaciones respetan los filtros del canal y las Quiet Hours."
"range": "Aviso ≤ valor < Crítico",
"meaning": "Estado de aviso. Health Monitor genera un evento WARNING; las notificaciones respetan filtros de canal y horario de silencio."
},
{
"colour": "Rojo",
"range": "valor ≥ Critical",
"meaning": "Estado critical. El Monitor de salud dispara un evento CRITICAL; CRITICAL salta las Quiet Hours y siempre alcanza al canal."
"range": "Valor ≥ Crítico",
"meaning": "Estado crítico. Health Monitor genera un evento CRITICAL que omite el horario de silencio. Siguen aplicándose los ajustes de categoría y evento del canal; la entrega también depende de su disponibilidad."
}
],
"sectionsTitle": "Secciones y valores por defecto recomendados",
"sectionsIntro": "Estos son los valores con los que viene ProxMenux — la baseline recomendada. Es lo que ves en un host recién montado hasta que sobreescribes algo. Las secciones están ordenadas de arriba abajo de <em>cómputo</em> → <em>calor</em> → <em>capacidad de almacenamiento</em>, así que leer hacia abajo va de lo concreto (carga actual) al estado acumulado (espacio libre).",
"sectionsTitle": "Secciones y valores predeterminados recomendados",
"sectionsIntro": "Son los valores iniciales de ProxMenux hasta que los cambies. Las secciones van de <em>carga de cómputo</em> a <em>temperatura</em> y <em>capacidad de almacenamiento</em>, desde la carga actual al espacio ocupado.",
"headerSection": "Sección",
"headerWarning": "Warning",
"headerCritical": "Critical",
"headerWarning": "Aviso",
"headerCritical": "Crítico",
"headerGates": "Qué controla",
"thresholdRows": [
{
"section": "Uso de CPU",
"warning": "85 %",
"critical": "95 %",
"gates": "Alerta de carga sostenida cuando la CPU promedia por encima del umbral durante la ventana de scan."
"gates": "Alerta de carga sostenida cuando la CPU media supera el umbral durante el periodo de análisis."
},
{
"section": "Memoria",
"warning": "85 %",
"critical": "95 %",
"gates": "Presión de RAM en el host."
"gates": "Presión de RAM del host."
},
{
"section": "Swap (solo critical)",
"section": "Uso de swap (solo crítico)",
"warning": "—",
"critical": "5 %",
"gates": "Swap realmente en uso. El número es intencionadamente bajo: un host Proxmox sano apenas debería tocar swap, así que incluso un 5 % es una señal significativa de presión de RAM."
"critical": "80 %",
"gates": "El estado CRITICAL de swap exige superar el 80 % de swap y tener menos del 15 % de RAM disponible, sostenido en las muestras. El swap ocupado por sí solo no activa esta regla."
},
{
"section": "Temperatura de CPU",
"warning": "80 °C",
"critical": "90 °C",
"gates": "Lectura de temperatura de package / core de CPU desde <code>lm-sensors</code>."
"gates": "Temperatura del conjunto o de los núcleos de CPU obtenida de <code>lm-sensors</code>."
},
{
"section": "Temp de disco — HDD",
"warning": "60 °C",
"critical": "65 °C",
"gates": "Drives spinning estándar. El sobre del fabricante topa alrededor de 60–65 °C, así que Critical se fija justo en el límite duro."
"gates": "Temperatura HDD. Valores iniciales: aviso a 60 °C y crítico a 65 °C. Son valores de supervisión, no un límite universal del fabricante; consulta las especificaciones del modelo."
},
{
"section": "Temp de disco — SSD",
"warning": "70 °C",
"critical": "75 °C",
"gates": "SSDs SATA 2.5'' / M.2 — corren más frescos que NVMe pero más calientes que HDDs."
"gates": "SSD SATA de 2,5 pulgadas o M.2. Esta clase usa valores iniciales de 70/75 °C; los límites reales dependen del modelo."
},
{
"section": "Temp de disco — NVMe",
"warning": "80 °C",
"critical": "85 °C",
"gates": "Los drives NVMe corren más calientes por diseño; los controladores auto-throttlean por encima de ~85 °C, así que Warning captura la escalada antes de que entre el throttling."
"gates": "Temperatura NVMe. Esta clase usa valores iniciales de 80/85 °C. La temperatura de limitación del controlador varía por modelo y no siempre es 85 °C."
},
{
"section": "Temp de disco — SAS",
"warning": "55 °C",
"critical": "65 °C",
"gates": "Los drives SAS enterprise comparten el mismo límite de fabricante de ~65 °C que los HDDs, pero se despliegan normalmente en chasis rack con refrigeración activa. Una lectura a 55 °C ya señala un problema de refrigeración (ventilador fallando, problema de HVAC) <em>antes</em> de que el propio drive esté en riesgo — de ahí un Warning más bajo que HDD, no porque SAS sea menos tolerante al calor."
"gates": "Temperatura SAS. Esta clase usa aviso a 55 °C y crítico a 65 °C. Son <em>valores de supervisión</em>, no una prueba de fallo de refrigeración a 55 °C ni un límite universal del fabricante."
},
{
"section": "Espacio de disco — host",
"warning": "85 %",
"critical": "95 %",
"gates": "Capacidad de <code>/</code> y cada mountpoint del host (<code>/var/lib/vz</code>, <code>/mnt/*</code>…)."
"gates": "Capacidad de <code>/</code> y de cada punto de montaje del host (<code>/var/lib/vz</code>, <code>/mnt/*</code>…)."
},
{
"section": "Espacio de disco — rootfs LXC",
@@ -176,105 +176,105 @@
"gates": "Disco raíz por contenedor, evaluado contra el tamaño del rootfs según PVE."
},
{
"section": "Mount points LXC",
"section": "Puntos de montaje LXC",
"warning": "85 %",
"critical": "95 %",
"gates": "Capacidad de mountpoints dentro de CTs en ejecución (mp0, mp1, NFS, bind mounts). Excluye rootfs."
"gates": "Capacidad de montajes en CT en ejecución: mp0, mp1, NFS y bind mounts. Excluye rootfs."
},
{
"section": "Almacenamiento PVE",
"warning": "85 %",
"critical": "95 %",
"gates": "Almacenamientos PVE estilo bloque (LVM, LVM-thin, ZFS-pool, RBD/Ceph, PBS)."
"gates": "Solo almacenamientos PVE de tipo LVM, LVM-thin, ZFS-pool, RBD, CephFS y PBS. Los de tipo directorio, NFS y CIFS los cubre la fila de espacio en disco del host."
},
{
"section": "Pool ZFS",
"warning": "85 %",
"critical": "95 %",
"gates": "Pools ZFS a nivel host — independiente del registro PVE."
"gates": "Pools ZFS del host, con independencia de su registro en PVE."
}
],
"defaultsTitle": "Valores por defecto, overrides y reset",
"defaultsBody": "El backend expone una vista fundida: cada sección parte de los valores por defecto de ProxMenux (los que ves cuando el host está recién hecho) y sobreescribes solo los knobs que te importan. La tarjeta muestra el valor <em>efectivo</em> — la sobreescritura si pones una, en otro caso el valor por defecto. Un botón <strong>Reset</strong> limpia cada override y vuelve a los valores por defecto en todas las secciones de una vez.",
"defaultsTitle": "Valores predeterminados, modificaciones y restablecimiento",
"defaultsBody": "Cada sección parte de los valores predeterminados y solo guardas las modificaciones necesarias. La tarjeta muestra el valor <em>efectivo</em>: tu modificación o el valor inicial. <strong>Restablecer</strong> borra todas las modificaciones y restaura los valores de todas las secciones.",
"validationTitle": "Validación",
"validationBody": "Guardar rechaza valores que no tienen sentido (porcentajes fuera de 0–100, critical por debajo de warning, temperaturas negativas). El frontend muestra el error inline; el backend valida otra vez antes de persistir, así que no se puede engañar a la API con un PUT hecho a mano para que acepte un umbral roto."
"validationBody": "Al guardar se comprueban los rangos permitidos y se rechaza Crítico por debajo de Aviso. La interfaz muestra errores y el servidor vuelve a validar las peticiones API antes de guardar."
},
"lxcDetection": {
"heading": "LXC Update Detection",
"imageAlt": "Tarjeta LXC Update Detection con un único switch — cuando está activo, el Monitor escanea periódicamente contenedores LXC Debian/Ubuntu/Alpine en ejecución buscando paquetes con update pendiente.",
"imageCaption": "El toggle para el scan periódico <code>apt list --upgradable</code> / <code>apk list -u</code> a lo largo de cada CT en ejecución. Por defecto ON. El toggle de notificación correspondiente en Notifications → Services solo aparece mientras la detección está activa.",
"intro": "Un toggle dedicado para el scan de actualizaciones LXC, situado entre Health Monitor Thresholds y la tarjeta Notifications. Cuando está ON, ProxMenux recorre cada CT en ejecución del host y consulta al gestor de paquetes dentro del contenedor por updates pendientes; los resultados aterrizan en los contadores de insignias de la pestaña Hardware y alimentan la notificación <code>lxc_updates_available</code>. Cuando está OFF, el scan se detiene por completo (sin llamadas <code>pct exec</code>) y cualquier entrada LXC existente en <code>managed_installs.json</code> se purga inmediatamente, así el panel y el endpoint <code>/api/managed-installs</code> dejan de reportar estado de update LXC sin esperar al siguiente ciclo de 24h.",
"whatRunsTitle": "Qué ejecuta realmente el scan",
"whatRunsIntro": "Para cada CT en estado <code>running</code> con un gestor de paquetes soportado:",
"heading": "Detección de actualización de LXC",
"imageAlt": "Tarjeta de detección de actualizaciones LXC con interruptor para buscar paquetes pendientes en contenedores Debian, Ubuntu y Alpine en ejecución",
"imageCaption": "Interruptor del análisis periódico con <code>apt list --upgradable</code> / <code>apk list -u</code> en los CT en ejecución. Viene activado. El interruptor de aviso en Notificaciones → Servicios aparece mientras la detección está activa.",
"intro": "El interruptor entre Umbrales y Notificaciones controla el análisis LXC. Al activarlo, consulta los gestores de paquetes de CT en ejecución; los resultados aparecen en Hardware y alimentan <code>lxc_updates_available</code>. Al desactivarlo, cesan sus llamadas <code>pct exec</code> y se eliminan las entradas LXC de <code>managed_installs.json</code>, por lo que <code>/api/managed-installs</code> deja de mostrar ese estado sin esperar 24 h.",
"whatRunsTitle": "Qué ejecuta el análisis",
"whatRunsIntro": "Para cada CT en estado <code>running</code> con un gestor de paquetes compatible:",
"whatRunsItems": [
"<strong>Gate de frescura de caché.</strong> Si la caché de metadatos apt/apk dentro del contenedor es más vieja que <strong>24 horas</strong>, primero corre un refresh best-effort (<code>apt-get update -qq</code> en Debian/Ubuntu, <code>apk update</code> en Alpine) con un timeout de 60 s. Cualquier fallo (sin red, repo roto, timeout) se traga en silencio — el listado de abajo sigue corriendo contra la caché que exista, así que un problema transitorio de repo nunca puede empeorar la detección.",
"<strong>Listing.</strong> Después ProxMenux ejecuta <code>apt list --upgradable</code> / <code>apk list -u</code> y parsea la salida en un recuento estructurado más una muestra de los nombres de paquetes top.",
"<strong>Dedup por CT.</strong> Una fingerprint construida a partir del recuento, security-count y los nombres top ordenados se almacena para que un conjunto estable de updates pendientes no re-notifique diariamente, mientras que un conjunto significativamente distinto sí lo haga."
"<strong>Actualización de metadatos.</strong> Si la caché apt/apk supera <strong>24 horas</strong>, intenta renovarla con <code>apt-get update -qq</code> en Debian/Ubuntu o <code>apk update</code> en Alpine, con límite de 60 s. Si falla, el listado usa la caché disponible y puede estar desactualizado.",
"<strong>Listado.</strong> Ejecuta <code>apt list --upgradable</code> / <code>apk list -u</code> y obtiene el número de paquetes y una muestra de sus nombres.",
"<strong>Evitar duplicados por CT.</strong> Guarda una huella del total, las actualizaciones de seguridad y los nombres ordenados para no repetir avisos diarios del mismo conjunto. Un cambio relevante sí vuelve a avisar."
],
"selfUpdateTitle": "Los CTs que se auto-actualizan fuera de apt pueden legítimamente reportar 0",
"selfUpdateBody": "La detección solo ve lo que el gestor de paquetes dentro del contenedor conoce. Un CT cuyo software clave se actualiza fuera de apt (el cron <code>plexupdate</code> de Plex, contenedores Docker actualizados vía <code>docker pull</code>, el actualizador integrado de Frigate, etc.) seguirá reportando updates apt bajos o cero aunque el appliance se mantenga al día activamente — eso es correcto, no es un bug. El sistema base a nivel apt del mismo CT puede aún tener sus propios updates pendientes, que sí saca a la luz el scan.",
"refreshTitle": "Por qué el auto-refresh de 24 h",
"refreshBody": "Los CTs appliance de larga vida con frecuencia acaban con cachés apt meses desactualizadas porque nadie ejecuta rutinariamente <code>apt update</code> dentro de ellos. Sin el refresh, <code>apt list --upgradable</code> reporta 0 updates desde una snapshot congelada y el operador nunca ve el backlog. El umbral coincide con el resto del ciclo de chequeo — si el CT se refrescó en las últimas 24 h, ProxMenux confía en esa señal y se salta el refresh.",
"toggleTitle": "Toggle de notificación condicional",
"toggleBody": "El toggle de notificación por canal <code>lxc_updates_available</code> en <strong>Notifications → Services</strong> solo se renderiza mientras la detección está activa. Cuando pones la detección en OFF, esa fila desaparece de la lista de categorías de cada canal — pero su preferencia almacenada se preserva en la DB, así que reactivar la detección trae el toggle de vuelta al valor que tenía antes.",
"purgeTitle": "Qué se purga al desactivar la detección",
"purgeBody": "Apagar el switch elimina inmediatamente cada entrada <code>type=lxc</code> de <code>/usr/local/share/proxmenux/managed_installs.json</code>. Las insignias de la pestaña Hardware caen a cero en el siguiente refresco del panel. Volver a activarlo repuebla el registro en el siguiente ciclo de detección (o antes si disparas un refresh manual desde la API)."
"selfUpdateTitle": "Los CT con actualizaciones fuera de apt pueden mostrar 0",
"selfUpdateBody": "La detección solo cubre el gestor de paquetes del CT. Software actualizado fuera de apt, como un trabajo <code>plexupdate</code> configurado o imágenes obtenidas con <code>docker pull</code>, queda fuera del recuento. Cero actualizaciones apt no demuestra que todas las aplicaciones estén al día. El sistema base del CT puede tener paquetes pendientes que sí se detectan.",
"refreshTitle": "Por qué renovar los metadatos cada 24 h",
"refreshBody": "Un CT de larga duración puede tener metadatos apt antiguos si nadie ejecuta <code>apt update</code>. Entonces <code>apt list --upgradable</code> puede omitir actualizaciones recientes. ProxMenux intenta renovarlos si tienen más de 24 horas y omite el paso si son más recientes.",
"toggleTitle": "Interruptor de aviso condicionado a la detección",
"toggleBody": "El interruptor por canal <code>lxc_updates_available</code> en <strong>Notificaciones → Servicios</strong> solo aparece con la detección activa. Al desactivarla, la fila se oculta en todos los canales. Su preferencia se conserva en la base de datos y recupera el mismo valor al reactivarla.",
"purgeTitle": "Qué se elimina al desactivar la detección",
"purgeBody": "Desactivarlo elimina de inmediato las entradas <code>type=lxc</code> de <code>/usr/local/share/proxmenux/managed_installs.json</code>. Los contadores de actualizaciones LXC de la pestaña VM y LXC desaparecen en el siguiente refresco. Al reactivarlo, el próximo ciclo de detección repuebla el registro, o antes con una actualización manual de la API."
},
"storageExclusions": {
"heading": "Remote Storage Exclusions",
"imageAlt": "Tarjeta Remote Storage Exclusions listando almacenamientos PBS-Cloud, PBS y PBS2 con toggles Health y Alerts por fila",
"imageCaption": "Toggles <em>Health</em> y <em>Alerts</em> por almacenamiento. Los almacenamientos con ambos toggles en off dejan de contar contra el Monitor de salud y dejan de generar notificaciones — pero siguen renderizándose en la pestaña Almacenamiento marcados como excluidos.",
"intro": "Marca los almacenamientos gestionados por Proxmox (NFS / CIFS / PBS / Ceph / iSCSI / etc.) como excluidos de monitorización. Dos toggles independientes por almacenamiento:",
"heading": "Exclusiones de almacenamiento remoto",
"imageAlt": "Tarjeta de exclusiones de almacenamiento remoto con PBS-Cloud, PBS y PBS2 y controles de Estado y Alertas por fila",
"imageCaption": "Controles <em>Estado</em> y <em>Alertas</em> por almacenamiento. Con ambos desactivados, deja de participar en Health Monitor y de enviar avisos. Sigue visible en Almacenamiento, marcado como excluido.",
"intro": "Puedes excluir almacenamientos gestionados por Proxmox (NFS / CIFS / PBS / Ceph / iSCSI / etc.) con dos controles independientes:",
"items": [
"<strong>Health</strong> — cuando está off, el almacenamiento deja de contribuir a la categoría Almacenamiento del Monitor de salud. Útil para volúmenes de archivo que están intencionadamente offline la mayor parte del tiempo o destinos de backup remotos que solo se encienden a horario.",
"<strong>Alerts</strong> — cuando está off, las alertas sobre este almacenamiento dejan de salir a través de los canales configurados, aunque los chequeos Health sigan activos. Útil cuando quieres la vista del panel pero no las notificaciones."
"<strong>Estado</strong> — al desactivar este control, el almacenamiento deja de contar en la categoría Almacenamiento de Health Monitor. Útil para volúmenes de archivo habitualmente desconectados o destinos remotos de backup que solo se encienden según un horario.",
"<strong>Alertas</strong> — desactivarlo impide enviar avisos de este almacenamiento por los canales configurados, aunque los controles de estado sigan activos. Útil si quieres ver su estado en el panel sin recibir avisos."
],
"outro": "Los almacenamientos excluidos siguen renderizándose en la <link>pestaña Almacenamiento</link> con una insignia morada <em>excluded</em> para que la entrada no desaparezca silenciosamente de tu inventario. El estado se persiste en la tabla SQLite <code>excluded_storages</code>."
"outro": "Los almacenamientos excluidos siguen en la <link>pestaña Almacenamiento</link> con la insignia morada <em>excluido</em>, para mantener visible el inventario. El estado se guarda en la tabla SQLite <code>excluded_storages</code>."
},
"interfaceExclusions": {
"heading": "Network Interface Exclusions",
"imageAlt": "Tarjeta Network Interface Exclusions listando vmbr0, vmbr1, vmbr2, bond0 y eno1 con toggles Health y Alerts por interfaz",
"imageCaption": "La misma forma que Storage Exclusions — toggles <em>Health</em> y <em>Alerts</em> por interfaz. Cada fila muestra la interfaz, insignia de tipo (bridge / bond / física), la IP y la velocidad del enlace.",
"intro": "La misma forma que Storage Exclusions pero para interfaces de red. Por interfaz: excluir de los chequeos Health y/o excluir de las notificaciones. Casos de uso típicos:",
"heading": "Exclusiones de interfaz de red",
"imageAlt": "Tarjeta de exclusiones de interfaces con vmbr0, vmbr1, vmbr2, bond0 y eno1 y controles de Estado y Alertas por interfaz",
"imageCaption": "Igual que las exclusiones de almacenamiento, ofrece <em>Estado</em> y <em>Alertas</em> por interfaz. Cada fila muestra nombre, tipo (bridge / bond / física), IP y velocidad del enlace.",
"intro": "El mismo principio se aplica a las interfaces: excluir cada una de los controles de estado, de los avisos o de ambos. Ejemplos habituales:",
"items": [
"Un bridge spare intencionadamente down.",
"Una NIC que se retiró físicamente pero sigue referenciada en <code>/etc/network/interfaces</code>.",
"Una sub-interfaz VLAN usada solo durante ventanas de mantenimiento.",
"Un bridge de gestión que está up pero no lleva tráfico — flappeando ruidosamente en cada ciclo."
"Un bridge de reserva desactivado intencionadamente.",
"Una NIC retirada físicamente que aún figura en <code>/etc/network/interfaces</code>.",
"Una subinterfaz VLAN usada solo durante tareas de mantenimiento.",
"Un bridge de gestión con cambios de estado del enlace conocidos y repetidos durante el mantenimiento."
],
"outro": "El estado se persiste en la tabla SQLite <code>excluded_interfaces</code>. La misma insignia morada <em>excluded</em> en la <link>pestaña Red</link> para que las interfaces excluidas sigan visibles."
"outro": "El estado se guarda en la tabla SQLite <code>excluded_interfaces</code>. La insignia morada <em>excluida</em> de la <link>pestaña Red</link> mantiene visibles las interfaces excluidas."
},
"notifications": {
"heading": "Notificaciones e IA",
"body1": "Esta sección de la pestaña Settings es donde se activan las notificaciones de ProxMenux Monitor y el reescritor con IA. Pulsar <em>Enable Notifications</em> arranca el hilo de envío en background, registra un target de webhook de Proxmox VE en el host para que los eventos emitidos por PVE fluyan al mismo pipeline y despliega el formulario de canales para que puedas conectar Telegram, Discord, Email, Gotify y el resto. El reescritor con IA vive dentro del mismo panel como una sección avanzada colapsable.",
"body2": "Ambas superficies tienen muchas piezas en movimiento — canales, toggles por evento, mensajes Rich, el Display Name, el pipeline de envío (dedup, cooldown, agregación, quiet hours), la integración del webhook PVE, proveedores de IA, modos de prompt — y viven en sus propias páginas dedicadas en lugar de repetirse aquí:",
"body1": "Aquí se activan las notificaciones de ProxMenux Monitor y la reformulación con IA. <em>Activar notificaciones</em> inicia el proceso de envío en segundo plano, registra un destino webhook de Proxmox VE para incorporar sus eventos y abre el formulario de canales: Telegram, Discord, correo, Gotify y otros. La reformulación con IA está en una sección avanzada desplegable del mismo panel.",
"body2": "Sus opciones se explican en páginas propias: canales, controles por evento, mensajes enriquecidos, nombre visible, envío (duplicados, espera, agrupación y horario de silencio), webhook PVE, proveedores de IA y modos de instrucciones:",
"items": [
"<notifLink>Notificaciones</notifLink> — recorridos por canal (Telegram, Discord, Gotify, Email + app passwords de Gmail / Microsoft, ntfy, Slack, Teams, webhook genérico), categorías por evento, mensajes Rich, Display Name, pipeline de envío, integración del webhook PVE, historial y API.",
"<aiLink>Asistente de IA</aiLink> — proveedores (OpenAI, Anthropic, Gemini, Groq, OpenRouter, Ollama), selección de modelo, modos de prompt (default / custom), idioma de salida, niveles de detalle por canal y sugerencias de IA."
"<notifLink>Notificaciones</notifLink>: configuración de canales (Telegram, Discord, Gotify, correo y contraseñas de aplicación de Gmail / Microsoft, ntfy, Slack, Teams y webhook genérico), categorías por evento, mensajes enriquecidos, nombre visible, envío, webhook PVE, historial y API.",
"<aiLink>Asistente de IA</aiLink>: proveedores (OpenAI, Anthropic, Gemini, Groq, OpenRouter, Ollama), modelos, instrucciones predeterminadas o personalizadas, idioma de salida, detalle por canal y sugerencias de IA."
]
},
"optimizations": {
"heading": "ProxMenux Optimizations",
"intro": "Un inventario en vivo y transparente de cada optimización post-instalación de ProxMenux actualmente activa en el host. Cada vez que aplicas una opción post-instalación desde el lado Scripts — ya sea vía el <autoLink>Automated post-install</autoLink> o vía el <customLink>Customizable post-install</customLink> a la carta — el script correspondiente se registra a sí mismo en <code>/usr/local/share/proxmenux/installed_tools.json</code>. El Monitor lee ese archivo y renderiza esta tarjeta para que veas, de un vistazo, qué se ha cambiado en tu servidor.",
"imageAlt": "Tarjeta ProxMenux Optimizations con rejilla de herramientas instaladas, cada fila mostrando un punto verde, nombre de la herramienta y versión. Ejemplos incluyen APT IPv4 Force, Bashrc Customization, Fastfetch, Log2ram SSD Protection, Memory Settings Optimization, Setting persistent network interfaces, System Limits Increase, APT Language Skip, Entropy Generation haveged con insignia Legacy, Kernel Panic Configuration, Logrotate Optimization, Network Optimizations, Subscription Banner Removal, VFIO IOMMU Passthrough — 14 activas en total",
"imageCaption": "La tarjeta lista cada optimización activa con su nombre, versión, un punto coloreado y un contador naranja <em>14 active</em> arriba a la derecha. Las herramientas cuyo source es alcanzable son pulsables.",
"heading": "Optimizaciones ProxMenux",
"intro": "Inventario de optimizaciones posteriores a la instalación registradas por ProxMenux en el host. Las opciones de <autoLink>Instalación posterior automatizada</autoLink> y <customLink>Instalación posterior personalizable</customLink> registran su aplicación en <code>/usr/local/share/proxmenux/installed_tools.json</code>. Monitor usa ese registro para la tarjeta. Una entrada no comprueba de nuevo que todos los ajustes sigan intactos.",
"imageAlt": "Tarjeta de optimizaciones ProxMenux con 14 entradas: punto de color, nombre y versión. Figuran APT IPv4 Force, Bashrc Customization, Fastfetch, Log2ram SSD Protection, Memory Settings Optimization, Setting persistent network interfaces, System Limits Increase, APT Language Skip, Entropy Generation haveged con Legacy, Kernel Panic Configuration, Logrotate Optimization, Network Optimizations, Subscription Banner Removal y VFIO IOMMU Passthrough.",
"imageCaption": "Cada optimización aparece con nombre, versión y punto de color. Arriba a la derecha hay un contador naranja <em>14 activas</em>. Las herramientas con código fuente disponible se pueden abrir.",
"dotsTitle": "Qué significan los puntos",
"dotsItems": [
"<green/> <strong>Punto verde</strong> — optimización actual, registrada por la versión activa de ProxMenux. El código fuente es alcanzable: pulsa la fila para abrirlo.",
"<amber/> <strong>Punto ámbar + insignia <em>legacy</em></strong> — aplicada por una versión más vieja de ProxMenux cuyo script ha sido renombrado o reemplazado desde entonces. Sigue activa en el host; el source abre en modo \"legacy\" (con un acento ámbar) para que puedas auditar qué se ejecutó realmente."
"<green/> <strong>Punto verde</strong>: optimización registrada sin marca Legacy ni actualización indicada. Pulsa la fila si tiene código fuente disponible.",
"<amber/> <strong>Punto ámbar e insignia <em>legacy</em></strong>: optimización registrada cuyo script cambió de nombre o fue sustituido. Abre su código conservado en modo Legacy con detalles ámbar. No comprueba de nuevo la configuración actual del host."
],
"clickTitle": "Acceso al código fuente",
"clickBody": "Pulsar una herramienta abre una modal con la función bash exacta que aplicó el cambio, más la ruta del archivo de script en el que vive (<code>auto_post_install.sh</code> para el bundle Automated, <code>customizable_post_install.sh</code> para el lado à la carte). Los comentarios y constructos de shell tienen syntax highlighting; un botón Copy pone el source en tu portapapeles. Esta es la superficie \"muestra tu trabajo\" — verifica lo que ProxMenux le hizo a tu host antes de cualquier cambio manual que añadas encima.",
"detailAlt": "Modal de código fuente de herramienta para APT IPv4 Force mostrando la función bash force_apt_ipv4 desde customizable_post_install.sh versión 1.0 con código resaltado que configura /etc/apt/apt.conf.d/99-force-ipv4 con Acquire ForceIPv4 true, registra la herramienta y emite un mensaje translate APT IPv4 configuration completed",
"detailCaption": "Modal de source para <em>APT IPv4 Force</em> — función <code>force_apt_ipv4()</code> exacta de <code>customizable_post_install.sh v1.0</code>, con syntax highlighting y un Copy de un clic.",
"clickTitle": "Abrir el código fuente",
"clickBody": "Pulsar una herramienta abre su función bash asociada y el nombre del script (<code>auto_post_install.sh</code> o <code>customizable_post_install.sh</code>). Para herramientas actuales se extrae del archivo del host; las antiguas pueden usar código conservado. Hay resaltado de sintaxis y Copiar. No garantiza una copia del código exacto ejecutado al instalar.",
"detailAlt": "Ventana de código de APT IPv4 Force con la función bash force_apt_ipv4 de customizable_post_install.sh versión 1.0. El código resaltado configura /etc/apt/apt.conf.d/99-force-ipv4 con Acquire ForceIPv4 true, registra la herramienta y muestra un mensaje traducido de configuración APT IPv4 completada.",
"detailCaption": "Código de <em>APT IPv4 Force</em>: función <code>force_apt_ipv4()</code> de <code>customizable_post_install.sh v1.0</code>, con resaltado de sintaxis y copia con un clic.",
"whyTitle": "Por qué importa esto",
"whyBody": "ProxMenux cambia cosas en tu host: parámetros de kernel, configuración de repositorios, bits de red, rotación de logs, passthrough de GPU, etc. Saber exactamente qué está activo es esencial antes de empezar a añadir customización manual encima — y aún más si un admin distinto opera el host del que lo montó. Esta tarjeta es el registro auditable de cada optimización actualmente en efecto, con el código exacto que la produjo.",
"updatesTitle": "Banner Updates available",
"updatesBody": "Cuando una optimización post-instalación tiene en disco una versión más nueva que la actualmente registrada en el host, la tarjeta muestra un banner \"Updates available\" arriba con el recuento y un botón <strong>Apply</strong>. Pulsar <strong>Apply</strong> abre un selector por optimización (el mismo disponible desde la entrada <em>Apply available updates</em> del menú Post-Install). Elige qué optimizaciones aplicar; ProxMenux relanza la función correspondiente y refresca la versión en el registro. Cuando todo está al día, el banner desaparece.",
"updatesAlt": "Tarjeta ProxMenux Optimizations con un banner Updates available arriba — recuento de updates pendientes más un botón Apply que abre el selector por optimización",
"updatesCaption": "El banner solo se renderiza cuando al menos una optimización tiene una versión más nueva en disco. Mira <link>Apply Available Updates</link> para el flujo completo de update y el equivalente Path-A en el menú de la shell.",
"revertTitle": "Revertir una optimización",
"revertBody": "La tarjeta es de solo lectura — para deshacer una optimización, ejecuta la opción correspondiente <link>Uninstall Optimizations</link> del menú ProxMenux Scripts. El paso de desinstalación elimina la entrada de <code>installed_tools.json</code>, así que desaparece de esta tarjeta en el siguiente refresco."
"whyBody": "ProxMenux puede cambiar parámetros del kernel, repositorios, red, rotación de registros y passthrough de GPU. Revisa las optimizaciones registradas antes de añadir cambios manuales, sobre todo si otro administrador preparó el host. La tarjeta muestra el registro y el código disponible; no audita todos los ajustes actuales ni conserva un historial exacto de ejecución.",
"updatesTitle": "Aviso de actualizaciones disponibles",
"updatesBody": "Si la versión de una optimización disponible en disco supera la registrada en el host, aparece un aviso con el total y <strong>Aplicar</strong>. <strong>Aplicar</strong> abre un selector de optimizaciones, como <em>Aplicar actualizaciones disponibles</em> del menú posterior a la instalación. Elige cuáles actualizar: ProxMenux vuelve a ejecutar sus funciones y actualiza el registro. El aviso desaparece cuando no quedan versiones pendientes.",
"updatesAlt": "Tarjeta de optimizaciones ProxMenux con aviso de actualizaciones disponibles, número pendiente y botón Aplicar para seleccionar optimizaciones",
"updatesCaption": "El aviso aparece si al menos una optimización tiene una versión más reciente en disco. Consulta <link>Aplicar actualizaciones disponibles</link> para el proceso completo y la opción equivalente Path-A del menú de consola.",
"revertTitle": "Deshacer una optimización",
"revertBody": "Para deshacer una optimización, usa la opción correspondiente de <link>Desinstalar optimizaciones</link> en ProxMenux Scripts. Al desinstalar se elimina su entrada de <code>installed_tools.json</code> y desaparece de la tarjeta en el siguiente refresco."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -285,22 +285,22 @@
{
"card": "Idioma de la interfaz",
"endpoint": "localStorage",
"source": "Preferencia del navegador <code>proxmenux-ui-language</code>, obtenida inicialmente del idioma del navegador cuando todavía no existe una selección guardada."
"source": "Preferencia <code>proxmenux-ui-language</code> del navegador; inicialmente usa su idioma si no hay una elección guardada."
},
{
"card": "Orden de navegación",
"endpoint": "localStorage",
"source": "Preferencia del navegador <code>proxmenux-nav-order</code>; también determina la pestaña inicial."
"source": "Preferencia <code>proxmenux-nav-order</code> del navegador; también determina la pestaña inicial."
},
{
"card": "Network Units",
"card": "Unidades de red",
"endpoint": "/api/settings",
"source": "Persistido en la tabla SQLite de settings del panel."
"source": "Guardado en la tabla de ajustes SQLite del panel."
},
{
"card": "Duraciones del Monitor de salud",
"card": "Duraciones de Health Monitor",
"endpoint": "/api/health/settings",
"source": "Duraciones de supresión por categoría en la DB de Health."
"source": "Duración de silenciamiento por categoría en la base de datos de Health Monitor."
},
{
"card": "Exclusiones de almacenamiento / interfaz",
@@ -310,17 +310,17 @@
{
"card": "Panel Notificaciones e IA",
"endpoint": "/api/notifications/*",
"source": "Mira las páginas dedicadas <notifLink>Notificaciones</notifLink> / <aiLink>Asistente de IA</aiLink>."
"source": "Consulta <notifLink>Notificaciones</notifLink> y <aiLink>Asistente de IA</aiLink>."
},
{
"card": "Lista ProxMenux Optimizations",
"card": "Lista de optimizaciones ProxMenux",
"endpoint": "/api/proxmenux/installed-tools",
"source": "Lee <code>/usr/local/share/proxmenux/installed_tools.json</code>, escrito por llamadas <code>register_tool</code> dentro de los scripts post-instalación."
"source": "Lee <code>/usr/local/share/proxmenux/installed_tools.json</code>, escrito mediante llamadas a <code>register_tool</code> en los scripts posteriores a la instalación."
},
{
"card": "Modal de código fuente de optimización",
"card": "Ventana de código de optimización",
"endpoint": "/api/proxmenux/tool-source",
"source": "Extrae la función bash correspondiente de <code>auto_post_install.sh</code> o <code>customizable_post_install.sh</code> en el host."
"source": "Extrae la función bash asociada de <code>auto_post_install.sh</code> o <code>customizable_post_install.sh</code> del host; las antiguas pueden usar código conservado."
}
]
},
@@ -330,37 +330,37 @@
{
"label": "Pestaña Apps",
"href": "/docs/monitor/dashboard/apps",
"tail": " — el lanzador cuya posición se puede cambiar desde Orden de navegación."
"tail": " — el lanzador cuya posición se cambia con Orden de navegación."
},
{
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tail": " — canales, toggles por evento, overrides de canal, historial, test-send."
"tail": " — canales, controles por evento, ajustes particulares por canal, historial y envíos de prueba."
},
{
"label": "Asistente de IA",
"href": "/docs/monitor/ai-assistant",
"tail": " — proveedores, modelos, modos de prompt, idiomas, niveles de detalle por canal."
"tail": " — proveedores, modelos, modos de instrucciones, idiomas y detalle por canal."
},
{
"label": "Monitor de salud → Descartar alertas y la Suppression Duration",
"label": "Health Monitor → Descartar alertas y duración del silenciamiento",
"href": "/docs/monitor/health-monitor#dismissing-alerts-and-the-suppression-duration",
"tail": " — la semántica detrás de los desplegables por categoría de arriba."
"tail": " — cómo funcionan los desplegables de duración por categoría."
},
{
"label": "ProxMenux Scripts → Automated post-install",
"label": "ProxMenux Scripts → Ajustes posteriores a la instalación automatizados",
"href": "/docs/post-install/automated",
"tailRich": " y <customLink>Customizable post-install</customLink> — los scripts reales que se registran en la lista de optimizaciones de arriba."
"tailRich": " y <customLink>Ajustes posteriores a la instalación personalizables</customLink>: los scripts que registran las optimizaciones en la lista anterior."
},
{
"label": "Uninstall Optimizations",
"label": "Desinstalar optimizaciones",
"href": "/docs/post-install/uninstall",
"tail": " — cómo revertir una optimización registrada arriba."
"tail": " — cómo deshacer una optimización de la lista anterior."
},
{
"label": "Índice del panel",
"href": "/docs/monitor/dashboard",
"tail": " — volver al resumen de la pestaña."
"tail": " — volver al resumen de pestañas."
}
]
}
@@ -1,193 +1,193 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Almacenamiento | ProxMenux Documentation",
"description": "La pestaña Almacenamiento consolida cuatro vistas: almacenamientos gestionados por Proxmox con su estado, pools ZFS, discos físicos internos con datos SMART y unidades externas (USB). La vista en detalle de cada disco expone atributos SMART, desgaste y vida útil y el historial permanente de observaciones."
"title": "ProxMenux Monitor — Panel: pestaña Almacenamiento | Documentación de ProxMenux",
"description": "La pestaña Almacenamiento reúne cuatro vistas: almacenamientos Proxmox con su estado, pools ZFS, discos internos con SMART y unidades USB externas. El detalle de cada disco muestra atributos SMART, desgaste, vida útil e historial permanente de observaciones."
},
"header": {
"title": "Panel: pestaña Almacenamiento",
"description": "El estado de almacenamiento del host en una pantalla — pools de Proxmox (NFS / CIFS / LVM / ZFS / dir), salud de pools ZFS, discos internos SATA / NVMe con SMART y unidades USB externas. Pulsa cualquier disco para abrir una vista en detalle con la tabla completa de atributos SMART y el historial de observaciones por disco.",
"description": "Todo el almacenamiento del host en una pantalla: NFS / CIFS / LVM / ZFS / dir de Proxmox, estado de pools ZFS, discos internos SATA/NVMe con SMART y unidades USB externas. Pulsa un disco para abrir sus atributos SMART y su historial de observaciones.",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "Respaldado por tres fuentes",
"body": "Los almacenamientos Proxmox vienen de <code>pvesm status</code>; el estado ZFS de <code>zpool status</code>; los discos físicos de <code>lsblk</code> + <code>smartctl</code> (y <code>nvme</code> para campos específicos de NVMe). La pestaña refresca cada ~60 segundos; la vista en detalle por disco dispara una lectura SMART fresca bajo demanda."
"body": "Los almacenamientos Proxmox proceden de <code>pvesm status</code>; ZFS, de <code>zpool status</code>; los discos físicos, de <code>lsblk</code> + <code>smartctl</code>, y <code>nvme</code> para campos específicos. La pestaña se actualiza aproximadamente cada 60 segundos; abrir el detalle solicita una lectura SMART."
},
"thresholds": {
"title": "Colores de estado y umbrales aplicados aquí",
"intro": "Cada barra, chip y punto de esta pestaña sigue la misma clasificación de tres estados — <green/> <strong>verde</strong> por debajo de Warning, <amber/> <strong>ámbar</strong> entre Warning y Critical, <red/> <strong>rojo</strong> en Critical y por encima. Valores por defecto recomendados que vienen con ProxMenux:",
"intro": "Health Monitor clasifica el estado como <green/> <strong>verde</strong> por debajo de Aviso, <amber/> <strong>ámbar</strong> entre Aviso y Crítico y <red/> <strong>rojo</strong> desde Crítico. Sus valores predeterminados se indican a continuación. Las barras del panel pueden usar otros límites visuales, descritos más abajo.",
"items": [
"<strong>Capacidad</strong> (discos del host, almacenamientos PVE, pools ZFS, mounts de LXC) — Warning 85 %, Critical 95 %.",
"<strong>Capacidad</strong> (discos del host, almacenamientos PVE, pools ZFS y montajes LXC): aviso 85 %, crítico 95 %.",
"<strong>Temperatura de disco</strong> — HDD 60/65 °C · SSD 70/75 °C · NVMe 80/85 °C · SAS 55/65 °C (warning / critical)."
],
"outro": "Cada valor es configurable por host — <link>Settings → Health Monitor Thresholds</link> es la fuente única de verdad y explica cómo ajustarlos."
"outro": "Puedes configurar cada valor por host. <link>Ajustes → Umbrales de Health Monitor</link> recoge los valores y explica cómo ajustarlos."
},
"topRow": {
"heading": "Fila superior: almacenamiento de un vistazo",
"intro": "Al abrir la pestaña Almacenamiento aterrizas en un resumen de cuatro tarjetas del estado de almacenamiento del host — capacidad total, qué se está usando localmente, qué se está usando en almacenamientos remotos y el inventario de discos físicos. Cada tarjeta es una respuesta de una línea a una pregunta común; las tarjetas debajo de la fila son donde profundizas en el detalle.",
"imageAlt": "Pestaña Almacenamiento — fila superior de cuatro tarjetas de estadísticas: Total Storage, Local Used, Remote Used, Physical Disks",
"imageCaption": "Fila superior de la pestaña Almacenamiento — capacidad total y recuento de discos, bytes usados separados en almacenamientos locales vs remotos y un desglose por tipo de discos físicos con su resumen de salud.",
"heading": "Fila superior: resumen del almacenamiento",
"intro": "Al abrir Almacenamiento, cuatro tarjetas resumen capacidad total, uso local, uso remoto e inventario de discos físicos. Ofrecen respuestas rápidas; las tarjetas inferiores contienen los detalles.",
"imageAlt": "Pestaña Almacenamiento, con cuatro tarjetas: capacidad total, uso local, uso remoto y discos físicos",
"imageCaption": "Fila superior: capacidad total y número de discos, bytes usados localmente y en remoto y desglose de discos físicos por tipo con resumen de estado.",
"headerCard": "Tarjeta",
"headerWhat": "Qué muestra",
"totalLabel": "Total Storage",
"totalWhat": "Capacidad bruta combinada de todos los discos físicos. La línea al pie muestra el recuento de discos físicos descubiertos.",
"localLabel": "Local Used",
"localWhat": "Bytes usados en almacenamientos locales (LVM / LVM-thin / ZFS / dir en los discos del propio host). Muestra los bytes usados de forma prominente, con una línea al pie <em>X.XX % de Y TB</em> para que veas el porcentaje de llenado al mismo tiempo.",
"remoteLabel": "Remote Used",
"remoteWhat": "La misma forma que Local Used pero para almacenamientos remotos (NFS / CIFS / PBS / Ceph / iSCSI). Se cuentan por separado porque las caídas remotas no afectan a los datos locales y normalmente los dimensionas y monitorizas de forma diferente.",
"disksLabel": "Physical Disks",
"totalLabel": "Almacenamiento total",
"totalWhat": "Capacidad bruta total de todos los discos físicos. El pie indica cuántos discos se han detectado.",
"localLabel": "Local usado",
"localWhat": "Bytes usados en almacenamientos locales: LVM / LVM-thin / ZFS / dir en los discos del host. El valor principal indica los bytes usados y el pie <em>X.XX % de Y TB</em> muestra también el porcentaje de ocupación.",
"remoteLabel": "Uso remoto",
"remoteWhat": "El mismo formato que Uso local, para almacenamientos remotos NFS / CIFS / PBS / Ceph / iSCSI. Se cuentan por separado porque los fallos remotos y locales tienen un alcance distinto y estos recursos suelen dimensionarse y supervisarse de forma diferente.",
"disksLabel": "Discos físicos",
"disksIntro": "Dos líneas de desglose para el inventario:",
"disksItems": [
"<strong>Por tipo</strong> — recuentos de NVMe (morado), SSD (azul) y HDD (azul) descubiertos. Los hosts con discos mixtos reciben los tres; un host todo-NVMe muestra solo el recuento NVMe.",
"<strong>Por salud</strong> — recuentos de discos <em>normal</em> (verde), <em>warning</em> (amarillo) y <em>critical</em> (rojo). El estado sano normalmente muestra solo \"X normal\"; warnings y critical aparecen solo cuando algo escala."
"<strong>Por tipo</strong>: número de NVMe en morado y de SSD y HDD en azul. Se muestran los tipos detectados; un host solo con NVMe muestra únicamente ese recuento.",
"<strong>Por estado</strong>: número de discos <em>normales</em> en verde, con <em>aviso</em> en amarillo y <em>críticos</em> en rojo. Sin problemas, solo aparece «X normales»; los otros estados aparecen cuando hay incidencias."
]
},
"pveStorage": {
"heading": "Tarjeta Proxmox Storage",
"intro": "Una fila por almacenamiento configurado en <code>/etc/pve/storage.cfg</code>. Cada fila muestra la insignia de tipo (<code>nfs</code> / <code>cifs</code> / <code>zfspool</code> / <code>lvm</code> / <code>lvmthin</code> / <code>dir</code> / <code>pbs</code>), el nombre del almacenamiento, una insignia active / error / not-monitored, el porcentaje de uso y una barra de progreso coloreada:",
"intro": "Una fila por almacenamiento de <code>/etc/pve/storage.cfg</code>, con tipo (<code>nfs</code> / <code>cifs</code> / <code>zfspool</code> / <code>lvm</code> / <code>lvmthin</code> / <code>dir</code> / <code>pbs</code>), nombre, estado activo/error/no supervisado, porcentaje de uso y barra de color:",
"items": [
"<strong>&lt; 75 %</strong> — barra de progreso azul, valor en azul.",
"<strong>75 – 90 %</strong> — barra de progreso amarilla, valor en amarillo (el Monitor de salud avisa en este punto).",
"<strong>> 90 %</strong> — barra de progreso roja, valor en rojo (el Monitor de salud escala).",
"<strong>error</strong> — fila entera con borde rojo, se usa cuando el almacenamiento está configurado pero inalcanzable (servidor NFS caído, credenciales CIFS caducadas).",
"<strong>excluded</strong> — borde morado + la insignia \"not monitored\". Almacenamientos excluidos explícitamente por el usuario de los chequeos de salud (cómodo para volúmenes manuales / de archivo que están intencionadamente offline)."
"<strong>Hasta el 75 %</strong>: barra y valor azules.",
"<strong>Más del 75 % y hasta el 90 %</strong>: barra y valor amarillos. Son límites visuales distintos de los umbrales de Health Monitor.",
"<strong>> 90 %</strong>: barra y valor rojos. Este límite visual es distinto del escalado de Health Monitor.",
"<strong>Error</strong>: borde rojo en toda la fila cuando el almacenamiento está configurado pero no es accesible, por ejemplo por caída de NFS o credenciales CIFS caducadas.",
"<strong>Excluido</strong>: borde morado y etiqueta «no supervisado». Almacenamientos que has excluido de las comprobaciones, como volúmenes de archivo que mantienes desconectados."
],
"calloutTitle": "Excluir un almacenamiento ruidoso",
"calloutBody": "Desde la fila del almacenamiento, el menú por almacenamiento te permite marcarlo como <em>excluded from monitoring</em>. El flag se guarda en la tabla <code>excluded_storages</code> y lo respetan tanto la vista del panel como el ciclo del Monitor de salud — no se disparan notificaciones para almacenamientos excluidos, y no empujan la pastilla de la cabecera."
"calloutTitle": "Excluir un almacenamiento de la supervisión",
"calloutBody": "El menú de cada almacenamiento permite marcarlo como <em>excluido de la supervisión</em>. Se guarda en <code>excluded_storages</code> y lo respetan el panel y Health Monitor: no genera notificaciones ni afecta al indicador general."
},
"zfs": {
"heading": "Tarjeta ZFS Pools",
"intro": "Se renderiza solo cuando ZFS está instalado y existe al menos un pool. Una fila por pool con una insignia de salud, size / allocated / free y un icono que refleja el estado de salud:",
"intro": "Solo aparece si ZFS está instalado y existe al menos un pool. Cada fila muestra un pool con estado, tamaño, espacio asignado y libre e icono de estado:",
"items": [
"<strong>ONLINE</strong> — verde. Todo sano.",
"<strong>DEGRADED</strong> — amarillo. El pool sigue sirviendo datos pero al menos un dispositivo no está disponible; arranca la ventana de reemplazo.",
"<strong>FAULTED</strong> / <strong>UNAVAIL</strong> / <strong>SUSPENDED</strong> — rojo. El pool no sirve datos; se requiere intervención inmediata."
"<strong>DEGRADED</strong>: amarillo. El pool sirve datos, pero al menos un dispositivo no está disponible; hay que gestionar su sustitución.",
"<strong>FAULTED</strong> / <strong>UNAVAIL</strong> / <strong>SUSPENDED</strong>: rojo. El pool no sirve datos y requiere intervención inmediata."
],
"outro": "Tanto el estado ZFS como el estado SMART por disco alimentan la categoría <em>Disks & I/O</em> del <link>Monitor de salud</link>."
"outro": "El estado ZFS y SMART de cada disco contribuyen a la categoría <em>Discos y E/S</em> de <link>Health Monitor</link>."
},
"physical": {
"heading": "Physical Disks & SMART Status",
"heading": "Discos físicos y estado SMART",
"intro": "Discos internos (SATA / NVMe). Cada fila condensa los campos más útiles de un vistazo:",
"items": [
"<strong>Ruta del dispositivo</strong> — <code>/dev/sda</code>, <code>/dev/nvme0n1</code>.",
"<strong>Insignia de tipo</strong> — SATA / NVMe (y el icono correspondiente).",
"<strong>Insignia System</strong> — etiqueta naranja que marca los discos desde los que se está ejecutando el SO del host. El panel lo deriva de los mountpoints de <code>/</code> y <code>/boot</code>: cualquier disco físico que los aloje recibe la etiqueta <em>System</em> para que no lo borres o reasignes por accidente. Los discos sin la etiqueta son unidades puras de datos.",
"<strong>Modelo</strong> — vendor + cadena del modelo de <code>smartctl -i</code>.",
"<strong>Capacidad</strong> — formateada de forma legible.",
"<strong>Temperatura</strong> — °C actuales, coloreada por el umbral de tipo de disco (NVMe corre más caliente que SATA).",
"<strong>Estado SMART</strong> — passed / failed / unknown.",
"<strong>Insignia de observaciones</strong> — cuando el historial permanente <code>disk_observations</code> tiene entradas para este disco, aparece una insignia azul con el recuento (p. ej. <em>3 obs.</em>). Pulsa el disco para entrar y revisarlas.",
"<strong>Insignia de salud</strong> — Healthy / Warning / Critical, derivada del chequeo SMART + observaciones recientes."
"<strong>Etiqueta de tipo</strong>: SATA / NVMe y su icono.",
"<strong>Etiqueta de sistema</strong>: marca naranja para los discos en uso por el host: montajes del sistema (<code>/</code>, <code>/boot</code>, <code>/usr</code>, <code>/var</code>…), swap activa, miembros de pools ZFS, volúmenes físicos LVM, miembros de RAID activos o etiquetas de partición del sistema. La ausencia de etiqueta no demuestra que se puedan borrar o reutilizar sin riesgo.",
"<strong>Modelo</strong>: fabricante y modelo de <code>smartctl -i</code>.",
"<strong>Capacidad</strong>: expresada en unidades legibles.",
"<strong>Temperatura</strong>: °C actuales, con color según el umbral del tipo de disco; NVMe admite umbrales más altos que SATA.",
"<strong>Estado SMART</strong>: correcto / fallido / desconocido.",
"<strong>Etiqueta de observaciones</strong>: si el historial permanente <code>disk_observations</code> contiene entradas del disco, aparece una etiqueta azul con el número, como <em>3 obs.</em>. Pulsa el disco para revisarlas.",
"<strong>Etiqueta de estado</strong>: Correcto / Aviso / Crítico, según SMART y las observaciones recientes."
],
"clickHint": "La fila entera es pulsable y abre la vista en detalle por disco descrita abajo.",
"warningTitle": "No toques los discos con etiqueta System a la ligera",
"warningBody": "Los discos con la insignia naranja <strong>System</strong> alojan el SO en ejecución. El panel expone la etiqueta como guardarraíl — las acciones destructivas lanzadas desde <link>ProxMenux → Disk Manager → Format / Wipe</link> se niegan explícitamente a actuar sobre ellos. Si de verdad necesitas reasignar el disco de arranque, hazlo desde un entorno de rescate, no desde dentro de Proxmox."
"clickHint": "Toda la fila se puede pulsar para abrir el detalle del disco descrito más abajo.",
"warningTitle": "Cuidado con los discos etiquetados como System",
"warningBody": "Los discos con etiqueta naranja <strong>System</strong> alojan el SO activo. La etiqueta ayuda a identificarlos; <link>ProxMenux → Gestor de discos → Formatear / Borrar</link> rechaza las acciones destructivas sobre ellos. Para reutilizar un disco de arranque, usa un entorno de rescate externo al Proxmox en ejecución."
},
"external": {
"heading": "External Storage (USB)",
"body": "Una tarjeta separada para unidades conectadas por USB, solo se renderiza cuando hay al menos una presente. Los mismos campos que los discos internos más una etiqueta naranja <strong>USB</strong>. Las unidades USB suelen aparecer y desaparecer (backups en frío, jobs ocasionales de descarga), así que el Monitor de salud es conservador con ellas — las observaciones se retienen, pero los errores de E/S en una unidad USB desconectada no escalan."
"heading": "Almacenamiento externo (USB)",
"body": "Las unidades USB tienen una tarjeta propia, visible cuando hay alguna conectada. Muestra los mismos campos que los discos internos y una etiqueta naranja <strong>USB</strong>. Como suelen conectarse solo para backups o transferencias ocasionales, se conservan sus observaciones, pero los errores de E/S de una unidad USB desconectada no se escalan."
},
"drillIn": {
"heading": "Modal de vista en detalle de disco",
"intro": "Pulsar cualquier fila de disco abre una modal con cuatro pestañas: <strong>Overview</strong> · <strong>SMART</strong> · <strong>History</strong> · <strong>Schedule</strong>. La cabecera siempre muestra la ruta del dispositivo, el modelo + capacidad y la insignia naranja <em>System</em> si aplica.",
"overviewTitle": "Pestaña 1 — Overview",
"overviewImageAlt": "Modal de vista en detalle de disco — pestaña Overview con estado de salud, anillo Wear & Lifetime y atributos SMART rápidos",
"overviewImageCaption": "Pestaña Overview — identidad, insignia de salud, anillo de vida restante con el desgaste actual y los datos escritos, además de un bloque rápido con los atributos SMART más vigilados.",
"overviewIntro": "La pestaña por defecto al entrar — todo lo que necesitas para responder \"¿este disco está bien?\" sin lanzar un test. Tres bloques:",
"heading": "Diálogo de detalle del disco",
"intro": "Pulsa un disco para abrir cuatro pestañas: <strong>Resumen</strong> · <strong>SMART</strong> · <strong>Historial</strong> · <strong>Programación</strong>. La cabecera muestra ruta, modelo, capacidad y, si corresponde, la etiqueta naranja <em>System</em>.",
"overviewTitle": "Pestaña 1 — Resumen",
"overviewImageAlt": "Detalle de disco, pestaña Resumen con estado, indicador circular de desgaste y vida útil y atributos SMART principales",
"overviewImageCaption": "Resumen: identificación, estado, vida restante con desgaste actual y datos escritos, y atributos SMART principales.",
"overviewIntro": "Pestaña inicial para consultar el estado del disco sin ejecutar una prueba. Tiene tres bloques:",
"overviewItems": [
"<strong>Identity</strong> — modelo, serial, capacidad, insignia Health (Healthy / Warning / Critical).",
"<strong>Wear & Lifetime</strong> — anillo grande de vida restante (97 %, 50 %, …) con el atributo de origen explícito (<em>Media Wearout Indicator</em>, <em>Percentage Used</em>, …), una barra de desgaste (% de consumo actual), una proyección <em>Est. Life</em> en años y los Data Written totales. Los discos NVMe también muestran <em>Available Spare</em>.",
"<strong>SMART Attributes</strong> — seis campos titulares en una rejilla de 2 columnas: Temperature, Power On Hours (con duración humanizada como <em>3y 116d</em>), Rotation Rate (o <em>SSD</em>), Power Cycles, SMART Status, Reallocated Sectors, Pending Sectors, CRC Errors. La tabla de atributos completa vive en la pestaña SMART."
"<strong>Identificación</strong>: modelo, número de serie, capacidad y estado Correcto / Aviso / Crítico.",
"<strong>Desgaste y vida útil</strong>: indicador circular de vida restante (97 %, 50 %, …) con atributo de origen (<em>Media Wearout Indicator</em>, <em>Percentage Used</em>, …), barra del porcentaje consumido, proyección <em>Vida estimada</em> en años y total de datos escritos. NVMe también muestra <em>Available Spare</em>.",
"<strong>Atributos SMART</strong>: los datos principales se muestran en dos columnas: temperatura, horas de encendido (con una duración legible, como <em>3 años y 116 días</em>), velocidad de rotación (o <em>SSD</em>), ciclos de encendido, estado SMART, sectores reasignados, sectores pendientes y errores CRC. La tabla completa de atributos se encuentra en la pestaña SMART."
],
"smartTitle": "Pestaña 2 — SMART",
"smartImageAlt": "Modal de vista en detalle de disco — pestaña SMART con botones Run SMART Test (Short / Extended), resultado del último test y la tabla completa de atributos SMART",
"smartImageCaption": "Pestaña SMART — lanza un test Short o Extended, mira el resultado del último test, scrollea la tabla completa de atributos SMART y genera el informe PDF completo de salud.",
"smartIntro": "Donde viven las acciones. Tres secciones:",
"smartImageAlt": "Detalle del disco, pestaña SMART con pruebas corta y extendida, resultado anterior y tabla completa de atributos",
"smartImageCaption": "Pestaña SMART: ejecuta pruebas cortas o extendidas, consulta el último resultado, revisa todos los atributos y abre el informe completo para imprimirlo o guardarlo como PDF.",
"smartIntro": "Acciones disponibles, en tres secciones:",
"smartItems": [
"<strong>Run SMART Test</strong> — dos botones. <em>Short Test (~2 min)</em> corre síncrono y muestra el resultado inline. <em>Extended Test (background)</em> puede tardar horas en discos grandes, corre en el servidor y dispara una notificación cuando termina.",
"<strong>Last Test</strong> — tipo, insignia de estado (<em>passed</em> / <em>failed</em>) y timestamp de la ejecución más reciente.",
"<strong>SMART Attributes</strong> — la tabla completa de atributos (ID / nombre / valor / worst / estado con iconos OK / warning / critical). Para SATA / SAS, la lista numerada clásica. Para NVMe, los campos estructurados de <code>nvme smart-log</code> (temperatura, available spare, percentage used, data units written / read, host reads / writes, controller busy time, power cycles, unsafe shutdowns, media errors, error-log entries, warning / critical composite temperature time)."
"<strong>Ejecutar prueba SMART</strong>: dos botones. <em>Prueba corta (~2 min)</em> espera al resultado y lo muestra en el diálogo. <em>Prueba extendida (segundo plano)</em> puede tardar horas en discos grandes, continúa en el servidor y avisa al terminar.",
"<strong>Última prueba</strong>: tipo, estado (<em>correcta</em> / <em>fallida</em>) y fecha y hora de la última ejecución.",
"<strong>Atributos SMART</strong>: tabla completa con ID, nombre, valor, peor valor y estado correcto, aviso o crítico. SATA/SAS muestra la lista numerada. NVMe usa <code>nvme smart-log</code>: temperatura, reserva disponible, porcentaje usado, unidades leídas/escritas, lecturas/escrituras del host, tiempo ocupado del controlador, ciclos de encendido, apagados inseguros, errores del medio, entradas del registro de errores y tiempo con temperatura compuesta en aviso/crítico."
],
"pdfTitle": "View Full SMART Report (PDF)",
"pdfIntro": "Al pie de la pestaña SMART, el botón <strong>View Full SMART Report</strong> genera un PDF imprimible y listo para archivo — el mismo informe estructurado que enviarías a un fabricante para un RMA.",
"pdfPreviewAlt": "Primera página del PDF SMART Health Report generado — Executive Summary con el anillo PASSED + bloque Disk Information",
"pdfPreviewCaption": "Primera página del SMART Health Report — Executive Summary con el anillo PASSED y el bloque Disk Information completo. El PDF completo de abajo lleva el anillo de desgaste SSD, cada atributo SMART y el historial de tests.",
"pdfTitle": "Ver informe SMART completo (PDF)",
"pdfIntro": "Al pie de SMART, <strong>Ver informe SMART completo</strong> abre un informe imprimible. Usa el diálogo de impresión del navegador para guardarlo como PDF, archivarlo o compartirlo con el fabricante en un RMA.",
"pdfPreviewAlt": "Primera página del informe SMART: resumen ejecutivo con indicador PASSED e información del disco",
"pdfPreviewCaption": "Primera página: resumen, indicador PASSED e información completa del disco. El PDF de ejemplo incluye desgaste SSD, todos los atributos SMART e historial de pruebas.",
"pdfDownloadLabel": "Descargar informe SMART de ejemplo (PDF)",
"pdfSectionsIntro": "El informe tiene cinco secciones de alto nivel:",
"pdfSectionsIntro": "El informe incluye estas secciones principales:",
"pdfSections": [
"<strong>Executive Summary</strong> — gran veredicto PASSED / FAILED, párrafo de evaluación de salud del disco en lenguaje claro (\"tu disco está sano / muestra signos de desgaste / está fallando\") y cuatro estadísticas rápidas (timestamp del informe, tipo del último test, resultado del test, atributos comprobados).",
"<strong>Disk Information</strong> — modelo, serial, capacidad, tipo (HDD / SSD / NVMe), familia, form factor, interfaz (SATA 3.3 · 6.0 Gb/s, …), soporte de TRIM, temperatura actual con el umbral óptimo, tiempo de power-on, ciclos de encendido, estado SMART, además de los contadores titulares (pending sectors, CRC errors, reallocated sectors).",
"<strong>SSD Wear & Lifetime</strong> (solo SSD / NVMe) — anillo de vida restante, atributo de origen, nivel actual de desgaste, datos escritos, horas de power-on.",
"<strong>SMART Attributes (full)</strong> — cada atributo que reporta el drive, con ID, nombre, valor, worst, threshold, valor raw y una pastilla de estado. Los más relevantes para el usuario (Reallocated Sector Ct, Power On Hours, Reported Uncorrect, UDMA CRC Error Count, Media Wearout Indicator, …) incluyen una explicación de una línea en lenguaje claro bajo la fila.",
"<strong>Last Self-Test Result + Full Self-Test History</strong> — el último test (tipo, resultado, mensaje de finalización, en qué marca de power-on-hours) más una tabla numerada de cada test retenido.",
"<strong>Recommendations</strong> — items de acción basados en el veredicto: <em>Disk is Healthy / Schedule periodic tests / Backup strategy</em> para discos sanos, lenguaje en escalada con guía de reemplazo cuando los atributos se salen de rango."
"<strong>Resumen ejecutivo</strong>: estado PASSED/FAILED, evaluación clara del disco —correcto, con desgaste o fallando— y cuatro datos: fecha del informe, tipo de última prueba, resultado y atributos comprobados.",
"<strong>Información del disco</strong>: modelo, serie, capacidad, tipo HDD/SSD/NVMe, familia, formato, interfaz (SATA 3.3 · 6.0 Gb/s, …), TRIM, temperatura y umbral óptimo, horas y ciclos de encendido, SMART, sectores pendientes y reasignados y errores CRC.",
"<strong>Desgaste y vida útil SSD</strong> (solo SSD/NVMe): indicador de vida restante, atributo de origen, desgaste actual, datos escritos y horas de encendido.",
"<strong>Atributos SMART completos</strong>: ID, nombre, valor, peor valor, umbral, valor bruto y estado de cada atributo. Los principales —Reallocated Sector Ct, Power On Hours, Reported Uncorrect, UDMA CRC Error Count, Media Wearout Indicator, …— incluyen una explicación breve bajo su fila.",
"<strong>Última autoprueba e historial completo</strong>: última prueba con tipo, resultado, mensaje final y horas de encendido en ese momento, más una tabla numerada de todas las pruebas conservadas.",
"<strong>Recomendaciones</strong>: acciones según el resultado. Para discos correctos: <em>disco sano / pruebas periódicas / estrategia de backups</em>. Si los atributos salen de rango, incluye indicaciones de sustitución."
],
"pdfOutro": "El PDF se produce en el servidor y se descarga con un patrón de nombre estable (<code>SMART-&lt;short-id&gt;.pdf</code>) para que múltiples snapshots a lo largo del tiempo puedan convivir en tu archivo. Útil cuando estás rastreando degradación a lo largo de meses o enviando evidencia al soporte del fabricante.",
"historyTitle": "Pestaña 3 — History",
"historyImageAlt": "Modal de vista en detalle de disco — pestaña History listando tests SMART pasados con acciones de descarga y borrado",
"historyImageCaption": "Pestaña History — cada test SMART retenido para este disco. Por fila: tipo, timestamp, etiqueta \"X days ago\", marca latest, descargar (salida raw de <code>smartctl</code>) y acciones de borrado.",
"historyIntro": "El pool retenido de tests SMART para este disco — tanto las ejecuciones short como extended que se completaron. Cada entrada es la salida raw de <code>smartctl</code> capturada en tiempo de ejecución, más los campos estructurados que el Monitor parseó para el panel. Acciones por fila:",
"pdfOutro": "El navegador crea el informe imprimible; Imprimir y Guardar como PDF abren su diálogo de impresión. Elige un nombre como <code>SMART-&lt;short-id&gt;.pdf</code>. Conserva copias fechadas para comparar cambios o compartirlas con el fabricante.",
"historyTitle": "Pestaña 3 — Historial",
"historyImageAlt": "Detalle del disco, pestaña Historial con pruebas SMART anteriores y acciones de descarga y eliminación",
"historyImageCaption": "Historial de pruebas SMART del disco. Cada fila muestra tipo, fecha y hora, antigüedad, marca de última prueba y acciones de descarga de la salida <code>smartctl</code> y eliminación.",
"historyIntro": "Pruebas cortas y extendidas completadas y conservadas para el disco. Cada entrada guarda la salida original de <code>smartctl</code> y los campos que Monitor interpreta para el panel. Acciones por fila:",
"historyItems": [
"<strong>Download</strong> — guarda la salida raw de <code>smartctl -a</code> como un archivo de texto. Idéntico a lo que parsea el informe PDF, útil cuando necesitas la línea exacta que pide un fabricante.",
"<strong>Delete</strong> — elimina el test del historial. El límite de retención fijado en la pestaña Schedule (<em>Last 5 / 10 / 20</em>) borra el más viejo primero automáticamente; esta acción es la sobreescritura manual."
"<strong>Descargar</strong>: guarda el snapshot JSON de esa prueba (salida de <code>smartctl -a --json</code>, o <code>nvme smart-log</code> en NVMe cuando falla smartctl). Útil si el fabricante necesita los campos de diagnóstico originales.",
"<strong>Eliminar</strong>: borra una prueba del historial manualmente. La retención de Programación (<em>últimas 5 / 10 / 20</em>) elimina automáticamente las más antiguas."
],
"scheduleTitle": "Pestaña 4 — Schedule",
"scheduleImageAlt": "Modal de vista en detalle de disco — pestaña Schedule con el toggle Automatic SMART Tests, la lista de schedules configurados y el botón Add Schedule",
"scheduleImageCaption": "Pestaña Schedule — elige tipo de test, frecuencia y retención; el Monitor lo conecta a <code>cron</code> para que los tests corran sin atención.",
"scheduleIntro": "Tests SMART automáticos guiados por cron, sin shell. La página tiene tres áreas:",
"scheduleTitle": "Pestaña 4 — Programación",
"scheduleImageAlt": "Detalle del disco, pestaña Programación con interruptor de pruebas SMART automáticas, lista de horarios y botón Añadir programación",
"scheduleImageCaption": "Programación: elige tipo, frecuencia y retención; Monitor configura <code>cron</code> para ejecutar las pruebas automáticamente.",
"scheduleIntro": "Pruebas SMART automáticas mediante cron, sin usar la terminal. Tres áreas:",
"scheduleItems": [
"<strong>Toggle Automatic SMART Tests</strong> — interruptor global on/off para cada schedule de este disco. Útil cuando quieres pausar todo durante mantenimiento sin perder las definiciones de schedule.",
"<strong>Configured Schedules</strong> — una fila por schedule existente con la insignia de tipo de test (<em>short</em> / <em>long</em>), la expresión cron en forma humana (<em>\"Day 1 of month at 03:00\"</em>, <em>\"Every Sunday at 02:00\"</em>), los discos que cubre y el ajuste de retención.",
"<strong>Add Schedule / Edit Schedule</strong> — formulario con: Test Type (<em>Short ~2 min</em> / <em>Long 1-4 h</em>), Frequency (<em>Daily / Weekly / Monthly</em>), Day of Month / Day of Week, Time, Keep Results (<em>Last 5 / 10 / 20</em>)."
"<strong>Pruebas SMART automáticas</strong>: interruptor general de todos los horarios del disco. Permite pausarlos durante el mantenimiento sin borrar su configuración.",
"<strong>Programaciones configuradas</strong>: una fila por horario con tipo (<em>corto</em> / <em>largo</em>), expresión cron legible (<em>«Día 1 de cada mes a las 03:00»</em>, <em>«Cada domingo a las 02:00»</em>), discos incluidos y retención.",
"<strong>Añadir / Editar programación</strong>: tipo (<em>corta ~2 min</em> / <em>larga 1–4 h</em>), frecuencia (<em>diaria / semanal / mensual</em>), día del mes o semana, hora y resultados guardados (<em>últimos 5 / 10 / 20</em>)."
],
"scheduleOutro": "El schedule se materializa como una entrada cron en el host que llama de vuelta al Monitor; los resultados se guardan en el mismo historial SMART mostrado en la pestaña 3, y el ajuste de retención auto-poda el test más viejo cuando termina uno nuevo.",
"tempTitle": "Modal de historial de temperatura",
"tempIntro": "Cada disco que expone un sensor de temperatura tiene sus lecturas muestreadas de forma continua por el Monitor y persistidas a una serie temporal local. El valor actual aparece como uno de los seis atributos SMART titulares en la pestaña Overview; pulsar ese bloque abre una modal dedicada de historial de temperatura con la imagen completa.",
"tempImageAlt": "Modal de historial de temperatura de disco — cabecera con la ruta y modelo del disco, un selector de timeframe (1 Hour / 24 Hours / 7 Days / 30 Days), una fila de cuatro tarjetas de estadísticas (Current / Min / Avg / Max) y una gráfica de línea de la temperatura sobre el rango seleccionado coloreada por los umbrales por tipo de disco",
"tempImageCaption": "Detalle de temperatura — se abre desde la pestaña Overview en cualquier disco cuyo sensor devuelva una lectura no-cero. La gráfica se colorea contra el umbral de tipo de disco (HDD / SSD / NVMe / SAS).",
"tempShowsTitle": "Lo que muestra la modal",
"scheduleOutro": "El horario crea una entrada cron en el host que llama a Monitor. Los resultados se guardan en el historial SMART de la pestaña 3 y la retención elimina automáticamente los más antiguos al terminar una prueba nueva.",
"tempTitle": "Diálogo de historial de temperatura",
"tempIntro": "Monitor toma periódicamente las lecturas de los discos con sensor de temperatura y las guarda en un historial local. El valor actual aparece en Resumen; al pulsarlo, se abre el detalle del historial de temperatura.",
"tempImageAlt": "Historial de temperatura del disco con ruta y modelo, periodos de 1 hora, 24 horas, 7 días o 30 días, indicadores Actual/Mínimo/Media/Máximo y gráfico de líneas coloreado según los umbrales del tipo de disco",
"tempImageCaption": "El detalle de temperatura se abre desde Resumen si el sensor devuelve un valor distinto de cero. El gráfico usa umbrales de HDD / SSD / NVMe / SAS.",
"tempShowsTitle": "Qué muestra el diálogo",
"tempShowsItems": [
"<strong>Selector de timeframe</strong> con cuatro rangos: <em>1 Hour</em>, <em>24 Hours</em> (por defecto), <em>7 Days</em>, <em>30 Days</em>. Cada uno consulta al mismo backend con un downsampling distinto para que la gráfica siga legible en cada horizonte.",
"<strong>Cuatro tarjetas de estadísticas</strong> en lo alto de la modal: <em>Current</em>, <em>Min</em>, <em>Avg</em>, <em>Max</em> para el rango seleccionado. La tarjeta <em>Current</em> se colorea con los mismos umbrales de estado que usan la pestaña Almacenamiento y las notificaciones, para que veas de un vistazo si el disco está en territorio normal / warm / hot.",
"<strong>Gráfica de línea</strong> de la temperatura a lo largo del tiempo, con la línea y el área sombreada coloreadas por tipo de disco:"
"<strong>Selector de periodo</strong>: <em>1 hora</em>, <em>24 horas</em> por defecto, <em>7 días</em> o <em>30 días</em>. Cada consulta ajusta la resolución para mantener el gráfico legible.",
"<strong>Cuatro indicadores</strong>: <em>Actual</em>, <em>Mínimo</em>, <em>Media</em> y <em>Máximo</em> del periodo. <em>Actual</em> usa los umbrales de la pestaña Almacenamiento y las notificaciones para distinguir temperatura normal, elevada o alta.",
"<strong>Gráfico de líneas</strong> de la temperatura a lo largo del tiempo, con línea y área sombreada coloreadas según el tipo de disco:"
],
"tempDiskTypes": [
"HDD — umbrales típicamente más frescos.",
"SSD — umbrales moderados.",
"NVMe — umbrales más altos (NVMe corre más caliente por diseño).",
"SAS — mismos valores por defecto que HDD."
"SAS: aviso a 55 °C y crítico a 65 °C, con umbral de aviso distinto al HDD."
],
"tempConfigurable": "Los cuatro son configurables desde <em>Settings → Health Monitor Thresholds</em>.",
"tempWhyTitle": "Por qué importa aquí un historial",
"tempConfigurable": "Los cuatro tipos se configuran en <em>Ajustes → Umbrales de Health Monitor</em>.",
"tempWhyTitle": "Por qué importa el historial",
"tempWhyItems": [
"<strong>Detección de drift.</strong> Los discos que se calientan progresivamente a lo largo de semanas (ventilador fallando, acumulación de polvo, disco vecino muriéndose y empujando aire caliente) son invisibles para una lectura única de \"temperatura actual\". Las vistas de 7 días y 30 días sacan el drift a la superficie.",
"<strong>Correlación de picos.</strong> Cuando una ventana de backup o un rebuild empujaron el disco brevemente por encima de su umbral, los rangos de 1 hora y 24 horas muestran si fue puntual o un patrón recurrente.",
"<strong>Ajuste de umbrales.</strong> Antes de subir o bajar un umbral en <em>Settings → Health Monitor Thresholds</em>, la gráfica de 30 días muestra el rango operativo real del disco para que el nuevo valor encaje con lo que el hardware realmente hace en vez de un cálculo a ojo."
"<strong>Detectar tendencias.</strong> Una lectura aislada no revela que un disco lleva semanas calentándose, por ejemplo por fallos de ventilación, polvo o calor cercano. Las vistas de 7 y 30 días permiten ver la evolución.",
"<strong>Relacionar picos.</strong> Si un backup o una reconstrucción elevó brevemente la temperatura por encima del umbral, las vistas de 1 y 24 horas muestran si fue puntual o recurrente.",
"<strong>Ajustar umbrales.</strong> Antes de cambiarlos en <em>Ajustes → Umbrales de Health Monitor</em>, consulta el gráfico de 30 días para conocer el rango real de funcionamiento del disco."
],
"obsTitle": "Historial de observaciones (a lo largo de pestañas)",
"obsIntro": "Los discos modernos fallan de forma gradual. Un disco puede reportar SMART <strong>PASSED</strong> y aún así loguear errores ocasionales de lectura en dmesg, perder enlaces SATA o exponer pending sectors que van y vienen. La UI estándar de Proxmox te muestra el veredicto SMART actual — no mantiene un historial de esas <em>señales</em>. ProxMenux sí, y las expone directamente dentro de la modal de disco.",
"obsImageAlt": "Pestaña Overview de la modal Disk Details mostrando un disco sano con estado SMART Passed, 0 errores reallocated/pending/CRC y una sección Observations listando un evento I/O Error registrado con el mensaje raw del kernel, una traducción humana del código de error ATA, timestamps de primera y última ocurrencia y un contador de ocurrencias",
"obsImageCaption": "Un disco que <strong>SMART dice que está bien</strong> puede aún así tener un historial de observaciones. La tarjeta es la capa de señales histórica bajo el veredicto SMART.",
"obsTitle": "Historial de observaciones en las pestañas",
"obsIntro": "Los fallos de disco pueden desarrollarse gradualmente. Un disco puede indicar SMART <strong>PASSED</strong> y registrar errores de lectura en dmesg, perder enlaces SATA o mostrar sectores pendientes intermitentes. ProxMenux conserva estas <em>señales</em> y las muestra en el diálogo junto al estado SMART actual.",
"obsImageAlt": "Resumen de un disco con SMART correcto y cero sectores reasignados, pendientes y errores CRC, pero una observación de error E/S con mensaje original del kernel, explicación ATA, primera y última fecha y contador",
"obsImageCaption": "Un disco que <strong>supera SMART</strong> puede tener observaciones anteriores. La tarjeta añade el historial de señales al estado actual.",
"obsWhatTitle": "Qué es una observación",
"obsWhatIntro": "Cualquier cosa que ProxMenux capture en el log del kernel, dmesg o salida SMART que parezca un evento a nivel de disco — y que por sí sola sería demasiado granular para una notificación — se registra como una <strong>observación</strong>. Cada fila muestra:",
"obsWhatIntro": "ProxMenux registra como <strong>observación</strong> los eventos de disco detectados en el registro del kernel, dmesg o SMART que por sí solos serían demasiado específicos para una notificación. Cada fila muestra:",
"obsWhatItems": [
"<strong>Insignia de tipo</strong> (I/O Error, SMART Error, Filesystem Error, ZFS Pool Error, Connection Error).",
"<strong>Mensaje raw del kernel</strong> tal cual apareció en dmesg — útil al copiar y pegar en un buscador o en un ticket de soporte.",
"<strong>Una frase humana</strong> bajo el mensaje raw para códigos ATA conocidos (<code>IDNF</code> → \"Sector address not found — posible bad sector o problema de cable\", <code>UNC</code> → \"Uncorrectable read error — bad sector\", y el resto de códigos estándar).",
"<strong>Timestamps de primera y última ocurrencia</strong>, más un <strong>contador de ocurrencias</strong> deduplicado por signature de error."
"<strong>Tipo</strong>: error E/S, SMART, sistema de archivos, pool ZFS o conexión.",
"<strong>Mensaje original del kernel</strong> tal como aparece en dmesg, para copiarlo a un buscador o solicitud de soporte.",
"<strong>Explicación breve</strong> para códigos ATA conocidos: <code>IDNF</code>, dirección de sector no encontrada, posible sector defectuoso o cable; <code>UNC</code>, error de lectura irrecuperable, sector defectuoso; y otros códigos estándar.",
"<strong>Primera y última fecha</strong> y <strong>número de apariciones</strong>, agrupadas por firma del error."
],
"obsWhyTitle": "Por qué ProxMenux las registra y las muestra",
"obsWhyTitle": "Por qué ProxMenux las registra y muestra",
"obsWhyItems": [
"<strong>El fallo de disco rara vez es un evento único.</strong> Normalmente empieza con errores esporádicos de bus ATA, algún sector UNC o un par de errores medium semanas antes de que SMART pase a <em>FAILED</em>. Sin persistencia esos avisos tempranos desaparecen de dmesg en el siguiente arranque.",
"<strong>SMART puede mentir.</strong> Un drive puede mostrar todos los atributos en verde y aún así estar a punto de irse — la capa de observaciones captura los síntomas que SMART no expone (en especial ICRC, IDNF, link resets a velocidades SATA más bajas).",
"<strong>Separa \"está pasando ahora\" de \"pasó recientemente\".</strong> El Monitor de salud auto-resuelve errores transitorios en cuanto dejan de dispararse, lo cual es genial para mantener limpia la lista de alertas activas — pero aún quieres ver, días después, que este disco tuvo tres errores de E/S esa noche. La tabla de observaciones es la respuesta.",
"<strong>Alimenta el modelo de notificación por niveles.</strong> El detector disk_io lee la tasa de observaciones de esta tabla para decidir silent / WARNING / CRITICAL (la ventana deslizante de 24h introducida en 1.2.1.2). El historial es lo que hace posible esa clasificación."
"<strong>Los fallos pueden evolucionar.</strong> Pueden aparecer errores de bus ATA, sectores UNC o errores del medio antes de que SMART indique <em>FAILED</em>. El búfer dmesg no los conserva tras reiniciar; el historial de observaciones sí.",
"<strong>SMART no descarta todos los fallos.</strong> Un disco puede tener atributos verdes y presentar problemas. Las observaciones conservan síntomas adicionales, como ICRC, IDNF, reinicios de enlace SATA o reducción de velocidad.",
"<strong>Distingue lo actual de lo reciente.</strong> Health Monitor resuelve automáticamente errores transitorios que dejan de aparecer. El historial permite comprobar días después que el disco tuvo, por ejemplo, tres errores de E/S esa noche.",
"<strong>Alimenta las notificaciones por niveles.</strong> disk_io usa la frecuencia de observaciones de la tabla para elegir silencio, WARNING o CRITICAL mediante una ventana móvil de 24 horas introducida en 1.2.1.2."
],
"obsDedupTitle": "Cómo funcionan dedup y re-notificación",
"obsDedupBody1": "Las observaciones se deduplican por su <strong>signature</strong> — una huella estable del tipo de error, dispositivo y campos clave de la línea del kernel. El mismo evento repitiéndose sube el <code>occurrence_count</code> de la fila existente en lugar de crear una nueva. Una <strong>signature diferente</strong> en el mismo disco crea una nueva observación y se trata como un evento nuevo para efectos de notificación.",
"obsDedupBody2": "Las notificaciones siguen una regla anti-cascada: la primera ocurrencia de una combinación (disco, signature, severidad) dada avisa al operador, y entonces ProxMenux espera 24 horas antes de volver a pingar sobre la misma combinación — aunque el contador siga subiendo. Una severidad escalando (WARNING → CRITICAL) rompe el cooldown para que se le cuente al operador cuando las cosas empeoran, no solo cuando ocurren.",
"obsDismissTitle": "Historial permanente vs errores activos",
"obsDismissBody1": "Una observación no se puede descartar, ocultar ni eliminar. Cada observación distinta de un disco es una tarjeta; la misma observación vista de nuevo suma a su contador de ocurrencias y actualiza su última fecha en lugar de crear otra tarjeta. El historial pertenece al disco, identificado por su número de serie: un disco conectado donde había otro empieza sin ninguna, y un disco que el kernel renombra conserva las suyas.",
"obsDismissBody2": "Resolver o descartar del lado de error activo (Monitor de salud) es independiente de las observaciones — la observación persiste más allá del auto-resolve del error activo. Ese es justo el punto: sobrevive, para que un warning transitorio de la semana pasada siga visible hoy en la tarjeta del disco. Mira <link>Monitor de salud</link> para el lado de error activo de la misma imagen."
"obsDedupTitle": "Agrupación de duplicados y repetición de avisos",
"obsDedupBody1": "Las observaciones se agrupan por <strong>firma</strong>, una huella estable del tipo de error, dispositivo y campos clave del mensaje. Las repeticiones aumentan <code>occurrence_count</code> en la fila existente. Una <strong>firma distinta</strong> crea otra observación y cuenta como evento nuevo para las notificaciones.",
"obsDedupBody2": "Para evitar avisos en cascada, la primera combinación de disco, firma y gravedad notifica al usuario. La misma combinación no vuelve a avisar hasta pasadas 24 horas, aunque aumente el contador. Un cambio de WARNING a CRITICAL interrumpe esa espera y avisa del empeoramiento.",
"obsDismissTitle": "Historial permanente y errores activos",
"obsDismissBody1": "Las observaciones no se pueden descartar, ocultar ni borrar. Cada firma tiene una tarjeta; si se repite, aumenta el contador y actualiza la última fecha. El historial sigue al número de serie: otro disco empieza vacío aunque use el mismo puerto, y un cambio de nombre del kernel no pierde el historial.",
"obsDismissBody2": "Resolver o descartar un error activo en Health Monitor no modifica sus observaciones. Se conservan después de la resolución automática, de modo que un aviso transitorio de la semana pasada siga visible hoy. Consulta <link>Health Monitor</link> para gestionar los errores activos."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -196,14 +196,14 @@
"headerSource": "Fuente",
"rows": [
{
"section": "Tarjetas resumen superiores",
"section": "Tarjetas de resumen superiores",
"endpoint": "/api/storage/summary",
"source": "Agregado desde <code>lsblk</code>, <code>zpool list</code>, <code>vgs</code> / <code>lvs</code>."
},
{
"section": "Inventario por disco",
"endpoint": "/api/storage",
"source": "<code>lsblk -O</code> + <code>smartctl -i</code> por dispositivo, con caché estable de identidad de disco (limpiado en eventos de hot-plug)."
"source": "<code>lsblk -O</code> + <code>smartctl -i</code> por dispositivo, con caché de identidad que se vacía al conectar o desconectar discos en caliente."
},
{
"section": "Almacenamientos Proxmox",
@@ -213,22 +213,22 @@
{
"section": "Valores SMART actuales",
"endpoint": "/api/storage/smart/<disk>",
"source": "<code>smartctl -A &lt;dev&gt;</code> — refrescado bajo demanda, no cacheado."
"source": "<code>smartctl -A &lt;dev&gt;</code> es una de las consultas disponibles; el endpoint de detalle también usa JSON SMART completo y datos específicos de NVMe."
},
{
"section": "Historial de self-tests SMART",
"section": "Historial de autopruebas SMART",
"endpoint": "/api/storage/smart/<disk>/history",
"source": "Almacenado bajo <code>/var/lib/proxmenux-monitor/smart/&lt;disk&gt;/</code> como snapshots JSON."
"source": "Se guarda en <code>/usr/local/share/proxmenux/smart/&lt;disk&gt;/</code> como snapshots JSON."
},
{
"section": "Observaciones permanentes",
"endpoint": "/api/storage/observations",
"source": "Tabla SQLite alimentada por el Monitor de salud cada ciclo (se mantiene tras auto-resolve)."
"source": "Tabla SQLite actualizada por Health Monitor en cada ciclo, conservada después de resolver errores activos."
}
],
"outro": "Verificar la cadena de recolección en el host:",
"codeComment1": "# Traer la snapshot actual desde un script",
"codeComment2": "# Cross-check de lo que ve el panel contra la vista raw del SO"
"codeComment1": "# Obtener el estado actual desde un script",
"codeComment2": "# Contrastar los datos del panel con el estado directo del sistema operativo"
},
"whereNext": {
"heading": "Por dónde seguir",
@@ -236,17 +236,17 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la categoría discos y E/S y el modelo de supresión."
"tail": " — categoría Discos y E/S y reglas de supresión."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints de storage y SMART."
"tail": " — endpoints de almacenamiento y SMART."
},
{
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tailRich": " — qué disparan aguas abajo <code>disk_io_error</code>, <code>storage_unavailable</code> y <code>smart_test_failed</code>."
"tailRich": " — qué acciones posteriores desencadenan <code>disk_io_error</code>, <code>storage_unavailable</code> y <code>smart_test_failed</code>."
},
{
"label": "Índice del panel",
@@ -254,14 +254,14 @@
"tail": " — el resto de pestañas."
},
{
"label": "ProxMenux → Disk Manager",
"label": "ProxMenux → Gestor de discos",
"href": "/docs/disk-manager",
"tail": " — la cara de las acciones: format / wipe / SMART tests / importar discos a VMs y CTs desde la TUI."
"tail": " — acciones de la TUI: formatear, borrar, pruebas SMART e importar discos a VM y contenedores."
},
{
"label": "ProxMenux → SMART Disk Health & Test",
"label": "ProxMenux → Estado y pruebas SMART del disco",
"href": "/docs/disk-manager/smart-disk-test",
"tail": " — la contraparte CLI de esta pestaña: programar tests SMART, exportar el JSON que renderiza el panel y la referencia más profunda de tipos de test / interpretación."
"tail": " — equivalente CLI: programar pruebas SMART, exportar el JSON mostrado en el panel y consultar los tipos de prueba y su interpretación."
}
]
}
@@ -1,41 +1,41 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Logs del sistema | ProxMenux Documentation",
"title": "ProxMenux Monitor — Panel: Logs del sistema | Documentación de ProxMenux",
"description": "La pestaña Logs del sistema reúne tres fuentes en una sola pantalla: journalctl en vivo con filtros y descarga, historial de tareas de Proxmox (UPIDs) y log de notificaciones — todo buscable, filtrable por severidad / rango temporal y descargable como paquetes de texto."
},
"header": {
"title": "Panel: pestaña Logs del sistema",
"description": "Tres sub-pestañas bajo un mismo techo: el journal del sistema (journalctl con filtros), el historial de tareas de Proxmox y el log de notificaciones. Las tres son buscables, filtrables y descargables como paquetes de texto.",
"description": "Tres subpestañas en una pantalla: journal del sistema (journalctl con filtros), historial de tareas de Proxmox y registro de notificaciones. Las tres permiten buscar, filtrar y descargar los datos como paquetes de texto.",
"section": "ProxMenux Monitor · Panel"
},
"readOnly": {
"title": "Solo lectura por diseño",
"body": "Nada en esta pestaña modifica los archivos de log. Los filtros viven en la URL / estado, las descargas son paquetes generados en el servidor. El panel nunca borra entradas de log — para mantenimiento usa el propio <code>journalctl --vacuum-time=&lt;N&gt;</code> o <code>logrotate</code> del host."
"body": "Esta pestaña no modifica los archivos de log. Los filtros se mantienen en la URL o en el estado de la interfaz y las descargas se generan en el servidor. El panel nunca borra entradas; para su mantenimiento usa <code>journalctl --vacuum-time=&lt;N&gt;</code> o <code>logrotate</code> en el host."
},
"topRow": {
"heading": "Fila superior: cuatro contadores",
"items": [
"<strong>Total Entries</strong> — número de registros dentro de la ventana de filtro activa.",
"<strong>Errors</strong> — recuento de severidad ≤ 3 (<code>err</code> / <code>crit</code> / <code>alert</code> / <code>emerg</code>).",
"<strong>Warnings</strong> — recuento de severidad 4 (<code>warning</code>).",
"<strong>Backups</strong> — recuento de entradas de tareas vzdump / PBS en la misma ventana."
"<strong>Entradas totales</strong>: número de registros dentro del intervalo del filtro activo.",
"<strong>Errores</strong>: número de entradas con severidad ≤ 3 (<code>err</code> / <code>crit</code> / <code>alert</code> / <code>emerg</code>).",
"<strong>Advertencias</strong>: número de entradas con severidad 4 (<code>warning</code>).",
"<strong>Backups</strong>: número de entradas de tareas vzdump / PBS en el mismo intervalo."
]
},
"subtabs": {
"heading": "Tres sub-pestañas",
"logsTitle": "Logs",
"logsIntro": "El journal del sistema, servido por <code>journalctl</code> en el backend. Filtros disponibles en la barra de herramientas:",
"logsTitle": "Registros",
"logsIntro": "El journal del sistema, obtenido en el servidor con <code>journalctl</code>. La barra de herramientas ofrece estos filtros:",
"logsFilters": [
"<strong>Severidad</strong> — emerg / alert / crit / err / warning / notice / info / debug, o cualquier combinación.",
"<strong>Severidad</strong>: emerg / alert / crit / err / warning / notice / info / debug o cualquier combinación.",
"<strong>Rango temporal</strong> — últimos 5 min / 15 min / 1 h / 6 h / 24 h / 7 d / personalizado.",
"<strong>Búsqueda de texto libre</strong> — substring o regex (<code>journalctl --grep</code>).",
"<strong>Filtro por unidad</strong> — restringir a una unidad systemd concreta (<code>pveproxy.service</code>, <code>nginx.service</code>, …)."
"<strong>Búsqueda de texto libre</strong>: subcadena o expresión regular (<code>journalctl --grep</code>).",
"<strong>Filtro de unidad</strong>: restringe a una unidad systemd concreta (<code>pveproxy.service</code>, <code>nginx.service</code>, …)."
],
"logsRowsAfter": "Cada fila muestra timestamp, insignia de severidad, unidad de origen y el mensaje. Los mensajes largos se colapsan con un conmutador \"mostrar más\". La acción <strong>Download</strong> empaqueta el filtro actual en un único archivo <code>.txt</code> vía <code>GET /api/logs/download</code> — útil cuando quieres compartir un trozo del journal con alguien.",
"logDetailsModalTitle": "Modal Log Details",
"logDetailsBody": "Pulsar cualquier fila abre una modal <strong>Log Details</strong> con cada campo estructurado que journald capturó para esa entrada — la misma vista que construirías a mano ejecutando <code>journalctl --output=verbose</code> en el host.",
"logDetailsBody": "Al pulsar una fila se abre <strong>Detalles del log</strong> con todos los campos estructurados que journald capturó para esa entrada, como al ejecutar <code>journalctl --output=verbose</code> en el host.",
"logDetailsImageAlt": "Modal Log Details — una entrada del journal desplegada con Level, Service, Timestamp, Source, Systemd Unit, Process ID, Hostname y el mensaje completo",
"logDetailsImageCaption": "Modal Log Details — cada campo estructurado que journald lleva para esta entrada, con el mensaje íntegro sin truncar al final. Útil para logs de cron y de servicios donde importa la línea de comandos ejecutada.",
"logDetailsImageCaption": "Detalles del log: todos los campos estructurados de journald para la entrada, con el mensaje completo sin truncar al final. Útil para logs de cron y servicios donde importa la línea de comando ejecutada.",
"fieldsIntro": "Campos mostrados:",
"fields": [
"<strong>Level</strong> — insignia de severidad coloreada (INFO / WARNING / ERROR / CRITICAL).",
@@ -45,15 +45,15 @@
"<strong>Systemd Unit</strong> — la unidad <code>.service</code> / <code>.timer</code> / <code>.socket</code> real si la entrada estaba asociada a una.",
"<strong>Process ID</strong> — PID del proceso emisor.",
"<strong>Hostname</strong> — útil cuando los journals se reenvían entre nodos de cluster.",
"<strong>Message</strong> — el mensaje completo sin truncar en un bloque monoespaciado, listo para copiar."
"<strong>Mensaje</strong>: mensaje completo sin truncar, en un bloque monoespaciado listo para copiar."
],
"maxLevelStoreTitle": "MaxLevelStore de journald",
"maxLevelStoreBody": "En una instalación recién hecha de Proxmox, journald usa por defecto <code>MaxLevelStore=warning</code>, lo que descarta en silencio los mensajes de nivel info. El Monitor lo detecta en el arranque y añade un drop-in (<code>/etc/systemd/journald.conf.d/proxmenux-loglevel.conf</code>) que sube el umbral a <code>info</code> para que la pestaña Logs tenga algo que mostrar en todas las severidades.",
"maxLevelStoreBody": "En una instalación nueva de Proxmox, journald usa por defecto <code>MaxLevelStore=warning</code>, que descarta los mensajes info. Monitor lo detecta al arrancar y añade un archivo de configuración complementario (<code>/etc/systemd/journald.conf.d/proxmenux-loglevel.conf</code>) con el umbral <code>info</code> para conservar los mensajes informativos y los de mayor gravedad. Esto no incluye debug.",
"backupsTitle": "Backups",
"backupsBody": "Historial de tareas de Proxmox filtrado a las entradas relacionadas con backup. Una fila por tarea (<code>vzdump</code>, transferencias PBS, Garbage Collect, Verify) con el estado (OK / WARNINGS / ERROR), el guest implicado, el almacenamiento de origen, la duración y el UPID. Pulsa una fila para cargar el log completo de la tarea vía <code>GET /api/task-log/&lt;upid&gt;</code> — los mismos datos que Proxmox expone a través de <em>Datacenter → Tasks</em>, acotado a backups.",
"notificationsTitle": "Notifications",
"notificationsBody1": "Cada notificación enviada por el Monitor — Telegram, Discord, Email, Gotify, ntfy, Slack, Teams, webhook. Cada fila: timestamp, canal, tipo de evento, severidad, el título renderizado, el cuerpo renderizado y (si IA está activa) un conmutador para ver la reescritura con IA junto al original.",
"notificationsBody2": "Usa esta pestaña para verificar que un canal está entregando de verdad y para comparar lo que produjo la reescritura con IA frente a la plantilla base. La configuración de canales vive en la página detallada de <link>Notificaciones</link>."
"notificationsTitle": "Notificaciones",
"notificationsBody1": "Todas las notificaciones enviadas por Monitor: Telegram, Discord, correo electrónico, Gotify, ntfy, Slack, Teams y webhook. Cada fila muestra fecha y hora, canal, tipo de evento, severidad, título y cuerpo generados y, si la IA está activa, un selector para comparar su reescritura con el original.",
"notificationsBody2": "Usa esta pestaña para verificar la entrega de un canal y comparar la reescritura de IA con la plantilla base. Los canales se configuran en la página detallada de <link>Notificaciones</link>."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -64,10 +64,10 @@
{
"subtab": "Logs (filtro en vivo)",
"endpoint": "/api/logs",
"source": "<code>journalctl --output json --since &lt;range&gt;</code> con filtros de severidad / unidad / búsqueda aplicados en el servidor."
"source": "<code>journalctl --output json --since &lt;range&gt;</code> con filtros de severidad, unidad y búsqueda aplicados en el servidor."
},
{
"subtab": "Download",
"subtab": "Descargar",
"endpoint": "/api/logs/download",
"source": "La misma consulta, devuelta como texto plano para grep / less."
},
@@ -77,14 +77,14 @@
"source": "Historial de tareas PVE filtrado por <code>vzdump</code>, transferencias PBS, Garbage Collect, Verify."
},
{
"subtab": "Vista en detalle de una tarea de backup",
"subtab": "Detalles de una tarea de backup",
"endpoint": "/api/task-log/&lt;upid&gt;",
"source": "Log completo de la tarea en texto plano leído de <code>/var/log/pve/tasks/&lt;index&gt;/&lt;upid&gt;</code>."
},
{
"subtab": "Historial de notificaciones",
"endpoint": "/api/notifications/history",
"source": "Tabla SQLite <code>notification_history</code> alimentada por el loop de envío."
"source": "Tabla SQLite <code>notification_history</code>, alimentada por el bucle de envío."
}
],
"apiIntro": "Tanto el filtro en vivo como las descargas también son accesibles vía API:",
@@ -98,17 +98,17 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la categoría Logs del sistema que vigila patrones persistentes / picos / cascadas."
"tail": " — la categoría Logs del sistema, que vigila patrones persistentes, picos y cascadas."
},
{
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tail": " — el watcher del journal lee la misma fuente y convierte coincidencias en notificaciones."
"tail": " — el observador del journal lee la misma fuente y convierte las coincidencias en notificaciones."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints logs y task-log con sus parámetros de consulta."
"tail": " — endpoints logs y task-log y sus parámetros de consulta."
},
{
"label": "Índice del panel",
@@ -1,85 +1,85 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Resumen del sistema | ProxMenux Documentation",
"description": "La pestaña por defecto al abrir ProxMenux Monitor: cuatro tarjetas de métricas (CPU, memoria, VMs y LXCs activos, temperatura) con actualizaciones en vivo y sparkline, la gráfica de métricas históricas y los paneles condensados de Almacenamiento y Red con acceso directo a sus pestañas dedicadas."
"title": "ProxMenux Monitor — Panel: Resumen del sistema | Documentación de ProxMenux",
"description": "La pestaña inicial por defecto de ProxMenux Monitor: cuatro tarjetas (CPU, memoria, VM y LXC activos, temperatura) con actualización en vivo y minigráfico de tendencia, gráfica histórica y resúmenes de almacenamiento y red con enlaces a sus pestañas."
},
"header": {
"title": "Panel: pestaña Resumen del sistema",
"description": "La primera pestaña que abre el panel. Cuatro tarjetas de métricas en vivo arriba, la gráfica de métricas históricas en el medio y paneles condensados de almacenamiento / red abajo — todo derivado de las mismas APIs que alimentan las pestañas dedicadas.",
"description": "La pestaña que el panel abre por defecto. Cuatro tarjetas con métricas en vivo arriba, gráfica histórica en el centro y resúmenes de almacenamiento y red abajo, usando las mismas API que sus pestañas dedicadas.",
"section": "ProxMenux Monitor · Panel"
},
"readOnly": {
"title": "Un vistazo de solo lectura",
"body": "Nada en esta pestaña es una superficie de control — todos los paneles son informativos. Las acciones viven en las pestañas dedicadas a las que enlazan: entra en Almacenamiento para gestionar discos, en VMs y LXCs para arrancar / parar guests, en la pestaña Seguridad para configurar autenticación, y así sucesivamente."
"body": "Todos los paneles de esta pestaña son informativos. Las acciones están en las pestañas enlazadas: Almacenamiento para gestionar discos, VMs y LXCs para iniciar o detener invitados y Seguridad para configurar la autenticación."
},
"captureAlt": "Pestaña Resumen del sistema — cuatro tarjetas de métricas (CPU, Memoria, VMs activos, Temperatura), gráfica de métricas del nodo y tarjetas resumen de Almacenamiento / Red",
"captureCaption": "La pestaña Resumen del sistema — la que abre el panel. Las cuatro tarjetas están en vivo, la gráfica de debajo es histórica y las dos tarjetas de abajo resumen Almacenamiento y Red.",
"captureCaption": "Resumen del sistema, la pestaña inicial por defecto. Las cuatro tarjetas se actualizan en vivo, la gráfica muestra el historial y las dos tarjetas inferiores resumen almacenamiento y red.",
"topRow": {
"heading": "Fila superior: tarjetas de métricas en vivo",
"intro": "Cuatro tarjetas en una rejilla 2×2 en móvil, una sola fila en escritorio. Cada una se actualiza desde <code>/api/system</code> cada pocos segundos.",
"intro": "Cuatro tarjetas en rejilla 2×2 en móvil y una fila en escritorio. Cada una recibe datos de <code>/api/system</code> cada pocos segundos.",
"headerCard": "Tarjeta",
"headerWhat": "Qué muestra",
"headerSource": "Fuente",
"rows": [
{
"card": "CPU Usage",
"card": "Uso de CPU",
"what": "Porcentaje actual con barra de progreso. Se actualiza cada ~1 s vía el sampler de signos vitales.",
"source": "psutil.cpu_percent()"
},
{
"card": "Memory Usage",
"what": "GB usados, porcentaje, GB totales. La barra de progreso sigue al porcentaje.",
"card": "Uso de la memoria",
"what": "GB usados, porcentaje y GB totales. La barra representa el porcentaje.",
"source": "psutil.virtual_memory()"
},
{
"card": "Active VM & LXC",
"what": "Recuento de guests actualmente en ejecución, con una insignia de desglose Running / Stopped y una línea al pie con los totales de VMs y LXCs.",
"card": "VM y LXC activos",
"what": "Número de invitados en ejecución, con desglose En ejecución / Detenidos y totales de VMs y LXCs al pie.",
"source": "/api/vms (consolidado)"
},
{
"card": "Temperature",
"what": "Temperatura de CPU en °C con insignia de estado (cool / warm / hot) y un sparkline de 5 minutos detrás. Muestra <em>N/A</em> cuando no se detecta sensor. Pulsa para abrir la modal de detalle de temperatura.",
"card": "Temperatura",
"what": "Temperatura de CPU en °C, estado (fría / templada / caliente) y minigráfico de los últimos 5 minutos detrás. Muestra <em>N/A</em> si no hay sensor. Pulsa para abrir los detalles.",
"source": "sensors / coretemp"
}
],
"thresholdsTitle": "Colores de estado y umbrales aplicados aquí",
"thresholdsIntro": "Cada anillo, barra y sparkline en las cuatro tarjetas de métricas sigue la misma clasificación — <green/> <strong>verde</strong> por debajo de Warning, <amber/> <strong>ámbar</strong> entre Warning y Critical, <red/> <strong>rojo</strong> en Critical y por encima. Valores por defecto recomendados que vienen con ProxMenux:",
"thresholdsIntro": "Cada anillo, barra y minigráfico usa la misma escala: <green/> <strong>verde</strong> por debajo de Advertencia, <amber/> <strong>ámbar</strong> entre Advertencia y Crítico, <red/> <strong>rojo</strong> desde Crítico. Valores recomendados incluidos con ProxMenux:",
"thresholdsItems": [
"<strong>Uso de CPU</strong> — Warning 85 %, Critical 95 %.",
"<strong>Memoria</strong> — Warning 85 %, Critical 95 % (el swap también dispara Critical al 5 % usado — un host Proxmox sano apenas debería tocar swap).",
"<strong>Temperatura de CPU</strong> — Warning 80 °C, Critical 90 °C."
"<strong>Uso de CPU</strong>: advertencia 85 %, crítico 95 %.",
"<strong>Memoria</strong>: advertencia 85 %, crítico 95 %. Swap también activa Crítico al 5 % de uso; un host Proxmox sano debería usarlo rara vez.",
"<strong>Temperatura de CPU</strong>: advertencia 80 °C, crítico 90 °C."
],
"thresholdsOutro": "Cada valor es configurable por host — <link>Settings → Health Monitor Thresholds</link> es la fuente única de verdad y explica cómo ajustarlos.",
"sparklineTitle": "El sparkline es significativo",
"thresholdsOutro": "Los valores se configuran por host; <link>Ajustes → Umbrales del monitor de salud</link> documenta y centraliza su ajuste.",
"sparklineTitle": "El minigráfico muestra la tendencia",
"sparklineBody": "La tarjeta de temperatura dibuja una traza de 5 minutos bajo el valor, con la línea y el degradado siguiendo el mismo par Warning/Critical documentado arriba. Es la forma más rápida de ver si el host está en escalada térmica sin abrir la modal de detalle."
},
"processes": {
"heading": "Top procesos por CPU / Memoria",
"intro": "Las tarjetas CPU Usage y Memory de la pestaña Resumen son clicables. Al pulsar cualquiera de ellas se abre una lista ordenable con los 25 procesos top — ordenada por uso de CPU si la abriste desde la tarjeta de CPU, o por memoria residente si la abriste desde la de Memory.",
"intro": "Las tarjetas Uso de CPU y Memoria son pulsables. Abren una lista ordenable con los 25 procesos principales, por uso de CPU desde la primera tarjeta o por memoria residente desde la segunda.",
"listTitle": "El diálogo con la lista",
"listItems": [
"<strong>Auto-refresco</strong> — la lista se actualiza cada 5 segundos mientras el diálogo está abierto y deja de pedir datos en cuanto se cierra.",
"<strong>Filtro</strong> — la caja de búsqueda acota la lista por command, user o PID.",
"<strong>Actualización automática</strong>: la lista se actualiza cada 5 segundos mientras está abierta y deja de consultar datos al cerrar.",
"<strong>Filtro</strong>: el buscador acota la lista por comando, usuario o PID.",
"<strong>Barra en línea</strong> — la columna de la métrica principal dibuja una barra pequeña escalada al mayor valor de la lista filtrada, para que el orden siga siendo visible aunque ningún proceso esté cerca del 100 %.",
"<strong>Layout móvil</strong> — por debajo de 640 px las columnas PID y User se ocultan para que Command, CPU % y Memory sigan cabiendo en la pantalla de un teléfono sin scroll horizontal."
],
"captureListAlt": "Modal Top processes by Memory — tabla con columnas PID, USER, COMMAND, CPU %, Memory ordenada por RSS",
"captureListCaption": "La tarjeta Memory abre la lista ordenada por RSS (acento índigo). La tarjeta CPU abre la misma lista ordenada por uso de CPU (acento azul).",
"detailTitle": "Detalle por proceso",
"detailIntro": "Al pulsar cualquier fila de la lista se abre un segundo diálogo con la foto en vivo de ese proceso, organizada en cuatro secciones:",
"detailIntro": "Pulsa una fila para abrir un segundo diálogo con los datos en vivo del proceso, organizados en cuatro secciones:",
"detailItems": [
"<strong>Overview</strong> — estado, proceso padre, número de hilos, descriptores de fichero abiertos, usuario y grupo.",
"<strong>Resources</strong> — CPU %, Memoria %, Resident (RSS), Virtual size, Swap, totales de I/O de lectura y escritura.",
"<strong>Command</strong> — nombre corto, línea de comandos completa, ruta del ejecutable y directorio de trabajo.",
"<strong>Lifetime</strong> — timestamp de arranque y tiempo transcurrido en ejecución."
"<strong>Resumen</strong>: estado, proceso padre, número de hilos, descriptores de archivo abiertos, usuario y grupo.",
"<strong>Recursos</strong>: CPU %, memoria %, memoria residente (RSS), tamaño virtual, swap y totales de E/S leída y escrita.",
"<strong>Comando</strong>: nombre corto, línea de comandos completa, ruta del ejecutable y directorio de trabajo.",
"<strong>Duración</strong>: fecha y hora de inicio y tiempo transcurrido en ejecución."
],
"detailRefresh": "El diálogo de detalle se refresca cada 3 segundos mientras está abierto. Si el proceso termina con el diálogo abierto, el polling se detiene, aparece un banner ámbar <em>This process has finished</em> y el último snapshot capturado se queda en pantalla (atenuado) para que sigas viendo qué estaba pasando justo antes de que terminara.",
"captureDetailAlt": "Modal de detalle de proceso — secciones Overview, Resources, Command y Lifetime para un único PID",
"detailRefresh": "El detalle se actualiza cada 3 segundos mientras está abierto. Al terminar el proceso, cesan las consultas y aparece el aviso ámbar <em>Este proceso ha terminado</em>. La última captura queda atenuada para ver qué ocurría justo antes de finalizar.",
"captureDetailAlt": "Detalle de proceso: secciones Resumen, Recursos, Comando y Duración para un PID",
"captureDetailCaption": "Diálogo de detalle por proceso abierto desde una fila de la lista. El color de acento sigue al de la tarjeta que lo abrió (azul para CPU, índigo para Memory)."
},
"middle": {
"heading": "Medio: gráficas de métricas del nodo",
"body1": "Bajo la fila superior se encuentra el componente <code>NodeMetricsCharts</code> — gráficas históricas de CPU, memoria y E/S de disco tomadas del propio almacén RRD de Proxmox vía <code>/api/node/metrics</code>. Un selector de timeframe alterna entre <em>1 hora / 24 horas / 7 días / 30 días / 1 año</em>; la resolución de los datos baja a medida que crece la ventana para que la gráfica se mantenga fluida.",
"body1": "Bajo las tarjetas está <code>NodeMetricsCharts</code>, con gráficas históricas de CPU, memoria y E/S de disco del almacén RRD de Proxmox mediante <code>/api/node/metrics</code>. El selector permite <em>1 hora / 24 horas / 7 días / 30 días / 1 año</em>; la resolución baja al ampliar el intervalo para mantener la fluidez.",
"body2": "Son las mismas gráficas que la UI web de Proxmox renderiza para un nodo, simplemente consolidadas en el tema oscuro del Monitor y alineadas con el resto de paneles."
},
"bottom": {
@@ -87,25 +87,25 @@
"storageTitle": "Tarjeta Storage Overview",
"storageIntro": "Una vista condensada del estado de almacenamiento del host, dividida en tres bloques:",
"storageItems": [
"<strong>Total Node Capacity</strong> — suma de todos los almacenamientos de VM/LXC más el almacenamiento local de sistema, con una barra de progreso en degradado del reparto total usado / libre.",
"<strong>Capacidad total del nodo</strong>: suma de los almacenamientos de VM/LXC y del almacenamiento local del sistema, con barra degradada de espacio usado y libre.",
"<strong>Total Capacity / Physical Disks</strong> — titular de capacidad bruta y el recuento de discos físicos descubiertos.",
"<strong>VM/LXC Storage</strong> — usado / libre / porcentaje para los almacenamientos donde viven los guests, más un contador cuando hay más de uno configurado.",
"<strong>Local Storage (System)</strong> — el propio mount raíz / sistema del host, separado del pool de guests."
"<strong>Almacenamiento VM/LXC</strong>: espacio usado, libre y porcentaje de los almacenamientos de invitados, con contador si hay más de uno.",
"<strong>Almacenamiento local (sistema)</strong>: montaje raíz o de sistema del host, separado del pool de invitados."
],
"storageDrillIn": "La vista en detalle vive en la <link>pestaña Almacenamiento</link> — SMART por disco, detalles de pool ZFS, historial de observaciones, etc.",
"storageDrillIn": "Los detalles están en la <link>pestaña Almacenamiento</link>: SMART por disco, pools ZFS, historial de observaciones, etc.",
"networkTitle": "Tarjeta Network Overview",
"networkBody1": "La línea superior muestra el recuento de interfaces activas (físicas + bridges combinados). Debajo, dos filas de insignias coloreadas para las interfaces en <code>up</code> — NICs físicas en azul, bridges en un color secundario. Un selector de timeframe arriba a la derecha (1 hora / 24 horas / 7 días / 30 días / 1 año) controla una pequeña gráfica de tráfico RX / TX.",
"networkBody2": "La vista en detalle por interfaz (IP/MAC, gráfica RRD, miembros del bridge, modo del bond, etc.) vive en la <link>pestaña Red</link>."
"networkBody2": "Los detalles por interfaz (IP/MAC, gráfica RRD, miembros del bridge, modo de bond, etc.) están en la <link>pestaña Red</link>."
},
"refresh": {
"heading": "Modelo de refresco",
"intro": "Cada panel gestiona su propio estado de carga (<code>loadingStates.cpu</code>, <code>loadingStates.storage</code>, …) para que una fuente lenta no bloquee al resto. Mientras un panel está obteniendo datos, muestra un skeleton con animación pulse; los fetchs fallidos degradan con elegancia — por ejemplo, un sensor de temperatura ausente renderiza la tarjeta como <em>N/A</em> en vez de un error.",
"heading": "Modelo de actualización",
"intro": "Cada panel tiene su propio estado de carga (<code>loadingStates.cpu</code>, <code>loadingStates.storage</code>, …), de modo que una fuente lenta no bloquea las demás. Mientras carga muestra un marcador pulsante. Los fallos se presentan sin interrumpir el resto; por ejemplo, sin sensor de temperatura muestra <em>N/A</em> en vez de un error.",
"items": [
"<strong>Tarjetas de métricas superiores</strong> — refresco cada ~5 s. Los paneles de CPU y temperatura también reciben un push de 1 s del sampler de signos vitales.",
"<strong>Gráfica de métricas del nodo</strong> — refresco cada 30 s, o al cambiar de timeframe.",
"<strong>Tarjetas superiores</strong>: se actualizan cada ~5 s. CPU y temperatura también reciben datos cada 1 s del muestreador de signos vitales.",
"<strong>Gráfica de métricas del nodo</strong>: carga al abrir y al cambiar de intervalo o idioma. Si hay que reintentar, espera 60 s.",
"<strong>Tarjeta de almacenamiento</strong> — refresco cada 60 s. Los datos SMART se cachean más tiempo (la pestaña Almacenamiento dispara una lectura fresca bajo demanda).",
"<strong>Tarjeta de red</strong> — refresco cada 5 s en el timeframe activo.",
"<strong>Refresco manual</strong> — el botón Refresh en la cabecera fuerza a todos los paneles a recargar inmediatamente."
"<strong>Tarjeta de red</strong>: resumen cada 59 s y gráfica de tráfico cada 60 s en el intervalo activo.",
"<strong>Actualización manual</strong>: el botón Actualizar de la cabecera vuelve a cargar todos los paneles inmediatamente."
]
},
"dataCollected": {
@@ -115,12 +115,12 @@
"headerSource": "Fuente",
"rows": [
{
"card": "Pastilla de estado de la cabecera",
"card": "Indicador de estado de la cabecera",
"endpoint": "/api/health",
"source": "El estado global cacheado que produce el Monitor de salud en cada ciclo."
},
{
"card": "CPU / RAM / Swap / Uptime",
"card": "CPU / RAM / Swap / Tiempo de actividad",
"endpoint": "/api/system",
"source": "<code>/proc/stat</code>, <code>/proc/meminfo</code>, <code>/proc/uptime</code> con muestreo de CPU en ventana corta."
},
@@ -135,13 +135,13 @@
"source": "Mira las pestañas dedicadas para cada una. Las tarjetas de la cabecera muestran una vista compactada de los mismos endpoints."
},
{
"card": "Cadencia de refresco",
"card": "Frecuencia de actualización",
"endpoint": "—",
"source": "CPU / red 5 s; almacenamiento / VMs 30 s; info estática cada 5 min. El botón Refresh de la cabecera fuerza una recarga inmediata en todos los paneles."
"source": "Sistema cada 5 s; almacenamiento, VMs y resumen de red cada 59 s. El botón Actualizar de la cabecera fuerza la recarga inmediata de todos los paneles."
}
],
"codeComment1": "# Llamada única que alimenta la pastilla de la cabecera",
"codeComment2": "# pública, sin token",
"codeComment1": "# Llamada que alimenta el indicador de estado de la cabecera",
"codeComment2": "# público, sin token",
"codeComment3": "# Snapshot autenticada que usan las tarjetas"
},
"whereNext": {
@@ -150,12 +150,12 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tail": " — la modal detrás de la pastilla de estado de la cabecera (diez categorías, descartes, supresión)."
"tail": " — la ventana del indicador de estado de la cabecera: diez categorías, descartes y supresión de avisos."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints system, info y health."
"tail": " — endpoints system, info y health."
},
{
"label": "Notificaciones",
@@ -165,12 +165,12 @@
{
"label": "Índice del panel",
"href": "/docs/monitor/dashboard",
"tail": " — las otras ocho pestañas de un vistazo."
"tail": " — las demás pestañas del panel de un vistazo."
},
{
"label": "Arquitectura",
"href": "/docs/monitor/architecture",
"tail": " — los hilos en background y las APIs que alimentan esta vista."
"tail": " — los hilos en segundo plano y las API que alimentan esta vista."
}
]
}
@@ -1,16 +1,16 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña Terminal | ProxMenux Documentation",
"description": "Shell en el navegador al host Proxmox: hasta 4 terminales a la vez con vista en rejilla, ayudas de teclado para móvil (ESC, TAB, flechas, combinaciones con Ctrl), una chuleta de comandos integrada con cheat.sh, protegida con JWT."
"title": "ProxMenux Monitor — Panel: Terminal | Documentación de ProxMenux",
"description": "Shell del host Proxmox en el navegador: hasta 4 terminales en rejilla, botones de teclado para móviles (ESC, TAB, flechas, combinaciones Ctrl), guía de comandos integrada con cheat.sh y protección JWT."
},
"header": {
"title": "Panel: pestaña Terminal",
"description": "Una sesión real de shell en el navegador, sobre el host Proxmox. Hasta cuatro terminales a la vez, ayudas de teclado para móvil, una chuleta de comandos integrada — todo en el mismo tema que el resto del panel.",
"description": "Una sesión real de shell en el host Proxmox desde el navegador. Hasta cuatro terminales a la vez, botones de teclado para móviles y una guía de comandos integrada, con el mismo tema que el resto del panel.",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "Un PTY real en el navegador",
"body": "El terminal asigna una PTY del lado del servidor a través de <code>flask_terminal_routes</code>, la canaliza por un WebSocket hacia <code>xterm.js</code> en el navegador y se ejecuta como <code>root</code> (el usuario de la unidad systemd). Cualquier cosa que puedas hacer en <code>ssh root@&lt;host&gt;</code> funciona aquí — incluidos <code>vim</code>, <code>tmux</code>, herramientas ncurses y las CLIs de Proxmox (<code>qm</code>, <code>pct</code>, <code>pvesh</code>, <code>pvecm</code>). Cada PTY lanzada desde esta pestaña exporta la variable de entorno <code>PROXMENUX_TERMINAL=monitor</code>, que hereda todo proceso <code>bash</code> hijo — incluida una llamada posterior a <code>menu</code> — para que los flujos de ProxMenux puedan saber si se están ejecutando dentro del terminal del navegador del Monitor."
"body": "El terminal crea una PTY en el servidor mediante <code>flask_terminal_routes</code>, la conecta por WebSocket con <code>xterm.js</code> en el navegador y se ejecuta como <code>root</code>, el usuario de la unidad systemd. Permite lo mismo que <code>ssh root@&lt;host&gt;</code>: <code>vim</code>, <code>tmux</code>, herramientas ncurses y las CLI de Proxmox (<code>qm</code>, <code>pct</code>, <code>pvesh</code>, <code>pvecm</code>). Cada PTY exporta <code>PROXMENUX_TERMINAL=monitor</code>. Sus procesos hijos <code>bash</code>, incluido un lanzamiento posterior de <code>menu</code>, heredan esta variable para reconocer el terminal de Monitor."
},
"singleAlt": "Pestaña Terminal de ProxMenux Monitor — una única sesión de terminal mostrando el resumen del sistema de Fastfetch al hacer login",
"singleCaption": "Un terminal del host abierto — la barra de arriba muestra el recuento (<em>1 / 4 terminals</em>), <em>+ New</em>, <em>Search</em>, <em>Clear</em> y <em>Close</em>. Las ayudas de teclado para móvil aparecen bajo el terminal en dispositivos táctiles.",
@@ -20,24 +20,24 @@
"body2": "Para llegar a un <strong>contenedor LXC</strong> desde el navegador, usa el botón <em>Console</em> dedicado en cada tarjeta de CT en ejecución de la <link>pestaña VMs y LXCs</link>. Abre una modal que ejecuta <code>pct enter &lt;vmid&gt;</code> y reutiliza la misma barra para móvil descrita abajo."
},
"menuGuard": {
"heading": "Guarda de autoactualización cuando menu corre dentro de este terminal",
"body1": "El <code>menu</code> de ProxMenux se autoactualiza en sitio: aceptar el prompt reemplaza su propio árbol de scripts y recarga. Eso funciona bien por SSH o desde la consola de Proxmox, pero el terminal del navegador no puede sobrevivir a ello — la actualización desmonta la propia PTY sobre la que corre la shell y el WebSocket cae a mitad. Para no dejar la sesión colgada, los handlers internos <code>check_updates_stable</code>, <code>check_updates_beta</code> y <code>apply_release_channel</code> leen <code>PROXMENUX_TERMINAL</code> y detectan el contexto Monitor.",
"body2": "Al detectarlo, el diálogo clásico sí / no se sustituye por un msgbox informativo con el instalador canónico de una línea — <code>bash -c \"$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)\"</code> para el canal estable, y la URL equivalente de <code>install_proxmenux_beta.sh</code> para beta. La actualización propiamente dicha se deja para una sesión SSH o la consola del host Proxmox; el terminal del navegador solo se usa para confirmar y leer el comando."
"heading": "Protección de autoactualización de menu en este terminal",
"body1": "<code>menu</code> se autoactualiza sustituyendo su árbol de scripts y recargándose al aceptar. Funciona por SSH o consola Proxmox, pero en el navegador cerraría la PTY de la shell e interrumpiría el WebSocket. Para evitarlo, <code>check_updates_stable</code>, <code>check_updates_beta</code> y <code>apply_release_channel</code> consultan <code>PROXMENUX_TERMINAL</code> y detectan el contexto Monitor.",
"body2": "Al detectarlo, el diálogo sí/no se sustituye por un mensaje informativo con el comando oficial del instalador: <code>bash -c \"$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)\"</code> para estable y la URL equivalente de <code>install_proxmenux_beta.sh</code> para beta. Ejecuta la actualización por SSH o consola del host Proxmox; el terminal del navegador solo permite leer y confirmar el mensaje."
},
"fourTerminals": {
"heading": "Hasta cuatro terminales a la vez",
"intro": "La pestaña te permite abrir hasta cuatro terminales del host simultáneamente. Cada uno obtiene su propia PTY y su propio WebSocket — son sesiones totalmente independientes. Dos layouts se alternan con los iconos junto al botón \"New\":",
"intro": "La pestaña permite abrir hasta cuatro terminales del host simultáneamente, cada uno con su propia PTY y WebSocket: son sesiones independientes. Los iconos junto a «Nuevo» alternan entre dos disposiciones:",
"items": [
"<strong>Vista en pestañas</strong> — un terminal visible a la vez, los demás como pestañas nombradas arriba (<em>Terminal 1</em>, <em>Terminal 2</em>…). Ideal para trabajar en una tarea con el resto en background.",
"<strong>Vista en rejilla</strong> — todos los terminales abiertos visibles a la vez en una rejilla 2×2. Útil para vigilar <code>htop</code> en un panel, <code>iftop</code> en otro y editar en un tercero sin saltar entre ellos."
"<strong>Vista en pestañas</strong>: un terminal visible y los demás como pestañas con nombre arriba (<em>Terminal 1</em>, <em>Terminal 2</em>…). Adecuado para trabajar en una tarea con las otras en segundo plano.",
"<strong>Vista en rejilla</strong>: todos los terminales abiertos en una rejilla 2×2. Permite vigilar <code>htop</code> en uno, <code>iftop</code> en otro y editar en un tercero sin cambiar de pestaña."
],
"outro": "La barra muestra el recuento actual (<em>1/4 terminals</em>, <em>4/4 terminals</em>). Las nuevas pestañas se abren con <strong>+ New</strong> y las individuales se cierran desde la pequeña <code>×</code> en la cabecera de la pestaña. El botón rojo grande <strong>Close</strong> de arriba derriba todos los terminales a la vez."
"outro": "La barra muestra el recuento (<em>1/4 terminales</em>, <em>4/4 terminales</em>). <strong>+ Nuevo</strong> abre una pestaña y la <code>×</code> de su cabecera cierra solo esa. El botón rojo grande <strong>Cerrar</strong> de arriba cierra todos los terminales."
},
"gridAlt": "Pestaña Terminal de ProxMenux Monitor — vista en rejilla con cuatro terminales del host ejecutando ls, configuración de red, iftop y el menú principal de ProxMenux uno al lado del otro",
"gridCaption": "Vista en rejilla (4 / 4 terminals) — cuatro PTYs del host independientes corriendo en paralelo: listado de directorio, <code>/etc/network/interfaces</code> en un lado, <code>iftop</code> en otro y el menú principal de ProxMenux en el cuarto. Alterna entre rejilla y pestañas con el conmutador de layout en la barra.",
"gridCaption": "Vista en rejilla (4 / 4 terminales): cuatro PTY independientes en paralelo, con listado de directorio, <code>/etc/network/interfaces</code>, <code>iftop</code> y el menú principal de ProxMenux. Alterna entre rejilla y pestañas con el selector de disposición de la barra.",
"keyboard": {
"heading": "Ayudas de teclado para móvil",
"intro": "Los teclados de móvil y tablet normalmente no exponen ESC, TAB, las flechas ni combinaciones con modificadores. Sin ellos, navegar por <code>vim</code>, <code>nano</code>, <code>htop</code> o cualquier menú TUI es imposible. La pestaña Terminal lo resuelve renderizando una fila de botones táctiles bajo el terminal siempre que el dispositivo sea suficientemente pequeño o tenga capacidad táctil:",
"heading": "Botones de teclado para dispositivos móviles",
"intro": "Los teclados de móvil y tablet suelen carecer de ESC, TAB, flechas y combinaciones de modificadores. Estas teclas son necesarias para manejar <code>vim</code>, <code>nano</code>, <code>htop</code> o menús TUI. Terminal añade botones táctiles debajo cuando la pantalla es pequeña o el dispositivo admite interacción táctil:",
"headerButton": "Botón",
"headerSends": "Envía",
"headerUse": "Uso típico",
@@ -50,7 +50,7 @@
{
"button": "TAB",
"sends": "\\t",
"use": "Autocompletado de rutas, navegación de campos en dialog/whiptail."
"use": "Autocompletado de rutas y navegación entre campos en dialog/whiptail."
},
{
"button": "↑ ↓ ← →",
@@ -58,9 +58,9 @@
"use": "Historial de la shell, movimiento del cursor, navegación de menús."
},
{
"button": "↵ Enter",
"button": "↵ Intro",
"sends": "\\r",
"use": "Confirmar. Algunos teclados en pantalla cambian Enter por Go/Done — este botón es inequívoco."
"use": "Confirmar. Algunos teclados en pantalla sustituyen Intro por Ir/Hecho; este botón evita ambigüedades."
},
{
"button": "Ctrl ▾",
@@ -71,46 +71,46 @@
"ctrlIntro": "Tres secuencias de control:",
"ctrlItems": [
"<code>Ctrl+C</code> — cancelar / interrumpir el comando en ejecución (<code>\\x03</code>).",
"<code>Ctrl+X</code> — salir de <code>nano</code> (<code>\\x18</code>).",
"<code>Ctrl+R</code> — búsqueda inversa en el historial de bash (<code>\\x12</code>)."
"<code>Ctrl+X</code>: salir de <code>nano</code> (<code>\\x18</code>).",
"<code>Ctrl+R</code>: búsqueda inversa en el historial de bash (<code>\\x12</code>)."
],
"modalTitle": "Misma barra en la modal de consola LXC",
"modalBody": "La consola del contenedor que lanzas desde <link>VMs y LXCs → Console</link> renderiza las mismas ayudas de teclado bajo la modal. La modal además auto-tipea <code>pct enter &lt;vmid&gt;</code> al conectar, para que aterrices directamente dentro del contenedor."
"modalTitle": "La misma barra en la ventana de consola LXC",
"modalBody": "La consola que abres desde <link>VMs y LXCs → Consola</link> muestra los mismos botones de teclado bajo la ventana. Al conectar, introduce automáticamente <code>pct enter &lt;vmid&gt;</code> para entrar directamente en el contenedor."
},
"lxcAlt": "Modal de consola LXC de ProxMenux Monitor — Terminal: ubuntu (ID: 103) con la misma barra para móvil (ESC, TAB, flechas, Enter, Ctrl) bajo el terminal",
"lxcCaption": "La modal de consola LXC — abierta desde <em>VMs y LXCs → Console</em>. La cabecera muestra el contenedor de destino (<em>Terminal: ubuntu (ID: 103)</em>) y la misma barra táctil aparece bajo el terminal.",
"lxcAlt": "Ventana de consola LXC de ProxMenux Monitor — Terminal: ubuntu (ID: 103), con la misma barra para móviles (ESC, TAB, flechas, Intro, Ctrl) debajo",
"lxcCaption": "Consola LXC abierta desde <em>VMs y LXCs → Consola</em>. La cabecera identifica el contenedor (<em>Terminal: ubuntu (ID: 103)</em>) y debajo del terminal aparece la misma barra táctil.",
"search": {
"heading": "Search Commands — chuleta integrada",
"intro": "El botón azul <strong>Search</strong> de la barra abre una modal con búsqueda difusa de comandos. Escribe unas letras de cualquier comando de Linux o Proxmox (<code>ls</code>, <code>tar</code>, <code>qm</code>, <code>pct</code>, <code>zpool</code>, <code>systemctl</code>…) y la modal lista ejemplos de uso con <em>Send to active terminal</em> de un solo toque. Elimina el viaje de ida y vuelta \"espera, ¿qué flag era esa?\" a otra pestaña del navegador.",
"modalAlt": "Modal Search Commands de ProxMenux Monitor — búsqueda difusa de comandos de Linux y Proxmox con cheat.sh, mostrando varios ejemplos de uso de ls",
"modalCaption": "La modal Search Commands consultando <code>ls</code> — cada resultado muestra el comando, su descripción y una pequeña flecha \"send\" que lo canaliza al terminal activo. La esquina inferior derecha indica la fuente de los datos (<em>Powered by cheat.sh</em>).",
"heading": "Buscar comandos: guía de referencia integrada",
"intro": "El botón azul <strong>Buscar</strong> abre una búsqueda aproximada de comandos. Escribe unas letras de un comando Linux o Proxmox (<code>ls</code>, <code>tar</code>, <code>qm</code>, <code>pct</code>, <code>zpool</code>, <code>systemctl</code>…) para ver ejemplos de uso y <em>Enviar al terminal activo</em> con un toque. Así puedes consultar sus opciones sin cambiar de pestaña.",
"modalAlt": "Ventana Buscar comandos de ProxMenux Monitor: búsqueda aproximada de comandos Linux y Proxmox con cheat.sh y varios ejemplos de ls",
"modalCaption": "Buscar comandos con la consulta <code>ls</code>: cada resultado muestra comando, descripción y una flecha de envío al terminal activo. La esquina inferior derecha indica la fuente (<em>Con tecnología de cheat.sh</em>).",
"aboutLabel": "Sobre cheat.sh:",
"aboutBody": "es una chuleta unificada de código abierto y curada por la comunidad que agrega ejemplos cortos y prácticos de uso para cientos de comandos de Linux, herramientas de sysadmin y lenguajes de programación. Diseñada originalmente para consultarse desde un terminal con <code>curl cheat.sh/&lt;command&gt;</code>, también es accesible desde cualquier navegador. ProxMenux Monitor pasa las consultas por un proxy en el servidor para que la modal siga funcionando bajo el mismo origen que el panel.",
"aboutBody": "es una guía de referencia de código abierto mantenida por la comunidad, con ejemplos breves y prácticos de cientos de comandos Linux, herramientas de administración y lenguajes de programación. Diseñada para consultarse con <code>curl cheat.sh/&lt;command&gt;</code>, también funciona en el navegador. ProxMenux Monitor envía las consultas mediante un proxy del servidor para mantener el mismo origen que el panel.",
"headerSource": "Fuente",
"headerWhen": "Cuándo se usa",
"headerWhat": "Lo que ves",
"onlineLabel": "(online)",
"onlineLabel": "(en línea)",
"onlineWhen": "Cuando el host tiene acceso a internet y el proxy de cheat.sh responde.",
"onlineWhat": "Varios ejemplos del mundo real por comando, tipeados con su descripción encima. El punto de estado en la cabecera de la modal es <green>verde</green>.",
"fallbackLabel": "Fallback local",
"onlineWhat": "Varios ejemplos prácticos por comando con su descripción encima. El punto de estado de la cabecera es <green>verde</green>.",
"fallbackLabel": "Alternativa local",
"fallbackWhen": "Cuando cheat.sh no está disponible (host offline, firewall restrictivo, caída de cheat.sh).",
"fallbackWhat": "Una lista empaquetada de comandos comunes de Linux + Proxmox. Catálogo más pequeño pero siempre disponible. El punto de estado es <red>rojo</red>.",
"sendingNote": "<strong>Cómo funciona el envío</strong>: pulsar la pequeña flecha \"send\" junto a un resultado reenvía el texto del comando al terminal que esté activo en ese momento (la pestaña enfocada, o la última en la que pulsaste en la vista en rejilla). La modal se cierra automáticamente para que puedas darle a Enter inmediatamente."
"fallbackWhat": "Una lista incluida de comandos habituales Linux y Proxmox. El catálogo es menor, pero siempre está disponible. El punto de estado es <red>rojo</red>.",
"sendingNote": "<strong>Cómo funciona el envío</strong>: la flecha junto al resultado envía el texto al terminal activo (la pestaña enfocada o el último terminal pulsado en rejilla). La ventana se cierra automáticamente para que puedas pulsar Intro."
},
"auth": {
"heading": "Autenticación",
"items": [
"El upgrade WebSocket lleva el JWT en la cabecera <code>Authorization</code>. Si la autenticación está activa y el token falta o ha caducado, la conexión se rechaza con HTTP 401 antes de asignar una PTY.",
"El navegador primero solicita un ticket de un solo uso mediante <code>POST /api/terminal/ticket</code>, autenticado con JWT en la cabecera <code>Authorization</code>. Después envía ese ticket al abrir el WebSocket. Caduca a los 5 segundos; si la autenticación está activa y falta o no es válido, se cierra la conexión antes de crear una PTY.",
"Si el Monitor está detrás de un reverse proxy, el proxy debe reenviar los upgrades WebSocket. Mira la página <link>Acceso y autenticación</link> para snippets de Nginx / Caddy / Traefik."
]
},
"clipboard": {
"heading": "Portapapeles, scrollback y resize",
"heading": "Portapapeles, historial de pantalla y tamaño",
"items": [
"<strong>Copiar / pegar</strong> — usa el portapapeles nativo del navegador. Selecciona texto con el ratón / trackpad y usa el atajo del SO (<code>Cmd+C</code> en macOS, <code>Ctrl+Shift+C</code> en Linux/Windows). Los escritorios Linux también soportan pegar con el botón central del ratón.",
"<strong>Scrollback</strong> — rueda / scroll con dos dedos. xterm.js mantiene las últimas varios miles de líneas en memoria.",
"<strong>Resize</strong> — el terminal renegocia el tamaño de ventana de la PTY cuando redimensionas el panel del dashboard, así <code>htop</code> y <code>vim</code> renderizan bien.",
"<strong>Reconexión al recuperar foco de la pestaña</strong> — si cambias de app en móvil o tablet (comportamiento habitual en iPad), el WebSocket normalmente caería. La pestaña Terminal detecta el cambio de visibilidad y reconecta automáticamente al volver, con un timeout de 15 segundos para rutas VPN lentas."
"<strong>Copiar y pegar</strong>: usa el portapapeles del navegador. Selecciona texto con ratón o trackpad y usa el atajo del sistema (<code>Cmd+C</code> en macOS, <code>Ctrl+Shift+C</code> en Linux/Windows). Los escritorios Linux también permiten pegar con clic central.",
"<strong>Historial de pantalla</strong>: rueda o desplazamiento con dos dedos. xterm.js conserva en memoria los últimos miles de líneas.",
"<strong>Cambiar tamaño</strong>: al redimensionar el panel se ajusta la ventana PTY para mostrar correctamente <code>htop</code> y <code>vim</code>.",
"<strong>Reconexión al volver a la pestaña</strong>: cambiar de app en móvil o tablet, especialmente iPad, puede cortar el WebSocket. Terminal detecta el cambio de visibilidad y reconecta al volver, con un tiempo de espera de 15 segundos para VPN lentas."
]
},
"disconnect": {
@@ -120,26 +120,26 @@
"headerFix": "Solución",
"rows": [
{
"cause": "JWT de sesión caducado (ventana de 24 h).",
"cause": "JWT de sesión caducado al abrir o reconectar un terminal (ventana de 24 h).",
"fix": "Refresca la página y vuelve a hacer login. El terminal no está pensado para sesiones desatendidas, así que el tiempo de vida del JWT coincide con el del login normal del panel."
},
{
"cause": "Timeout de idle del reverse proxy.",
"fix": "Sube <code>proxy_read_timeout</code> en Nginx o el equivalente en Caddy / Traefik (snippets en Acceso y autenticación)."
"cause": "Tiempo de espera por inactividad del proxy inverso.",
"fix": "Aumenta <code>proxy_read_timeout</code> en Nginx o su equivalente en Caddy / Traefik (ejemplos en Acceso y autenticación)."
},
{
"cause": "Móvil o tablet en sleep.",
"fix": "Cuando el dispositivo despierta, la pestaña auto-reconecta (timeout de 15 s para rutas VPN). Si no lo hace, recarga la pestaña."
"cause": "Móvil o tablet en reposo.",
"fix": "Al reactivarse el dispositivo, la pestaña reconecta automáticamente (15 s de espera para rutas VPN). Si falla, recárgala."
},
{
"cause": "Reinicio del servicio en el host.",
"fix": "Cualquier reinicio de <code>proxmenux-monitor.service</code> tira todas las PTY. Abre nuevos terminales una vez el panel termine de recargar."
"fix": "Reiniciar <code>proxmenux-monitor.service</code> cierra todas las PTY. Abre nuevos terminales cuando el panel termine de recargarse."
}
]
},
"warning": {
"title": "El terminal es una shell de root sobre el host",
"body": "El terminal hereda la identidad de la unidad systemd (<code>root</code>) y por tanto tiene privilegios totales sobre el host Proxmox. Configura un usuario, contraseña y 2FA en <authLink>Acceso y autenticación</authLink> antes de exponer el panel más allá de tu red local: cualquiera que llegue al puerto 8008 sin autenticación aterrizaría directamente en una shell de root — sin prompts adicionales, sin credenciales SSH. Para acceso desde fuera de la LAN, enruta el panel a través de <gatewayLink>Secure Gateway</gatewayLink> (Tailscale) o un reverse proxy con HTTPS, en lugar de abrir el puerto a la internet pública."
"title": "El terminal es una shell de root en el host",
"body": "El terminal hereda el usuario de la unidad systemd (<code>root</code>) y tiene todos los privilegios del host Proxmox. Configura usuario, contraseña y 2FA en <authLink>Acceso y autenticación</authLink> antes de dar acceso fuera de tu red local. Con la autenticación desactivada, quien llegue al puerto 8008 puede abrir una shell de root sin más confirmaciones ni credenciales SSH. Para acceso externo, usa <gatewayLink>Secure Gateway</gatewayLink> (Tailscale) o un proxy inverso HTTPS en lugar de publicar el puerto en Internet."
},
"whereNext": {
"heading": "Por dónde seguir",
@@ -147,17 +147,17 @@
{
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tail": " — snippets de reverse proxy incluyendo las líneas de upgrade WebSocket que requiere el terminal."
"tail": " — ejemplos de proxy inverso con las líneas de cambio de protocolo WebSocket necesarias para el terminal."
},
{
"label": "Arquitectura",
"href": "/docs/monitor/architecture",
"tail": " — el transporte WebSocket (HTTP vía flask-sock vs HTTPS / WSS vía gevent)."
"tail": " — transporte WebSocket (HTTP mediante flask-sock y HTTPS / WSS mediante gevent)."
},
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — los endpoints WebSocket /ws/terminal y /ws/script/<sid> junto al resto de la API."
"tail": " — endpoints WebSocket /ws/terminal y /ws/script/<sid>, junto al resto de la API."
},
{
"label": "Integraciones → Secure Gateway",
@@ -12,7 +12,7 @@
"p2": "El procedimiento que modifica el software se configura por separado en la <link>pestaña Actualizaciones</link>. Guardar una app nunca ejecuta un instalador ni un actualizador.",
"callout": "El registro, el seguimiento de versiones y la actualización son tres capacidades independientes. Cada una puede utilizarse sin exigir las otras dos.",
"dashboardTitle": "Del registro al lanzador Apps",
"dashboard": "Cada enlace web guardado aquí también se muestra como una tarjeta en la <appsLink>pestaña Apps</appsLink> principal. Esta página del LXC sigue siendo la fuente original para el nombre, el logotipo, los enlaces y el seguimiento de versión de la aplicación."
"dashboard": "Cada enlace web guardado aquí aparece también como tarjeta en la <appsLink>pestaña Apps</appsLink> principal. Esta página del LXC sigue siendo la referencia para nombre, logotipo, enlaces y seguimiento de versiones."
},
"overview": {
"heading": "Qué puede contener un registro",
@@ -31,7 +31,7 @@
"lead": "Las aplicaciones sugeridas forman parte de la caché del modal de cada LXC. El escaneo de arranque las prepara en segundo plano para que la pestaña App pueda mostrar inmediatamente los resultados almacenados.",
"items": [
"Abrir la pestaña App <strong>no</strong> inicia otro escaneo del catálogo ni consulta repetidamente el LXC.",
"<strong>Buscar aplicaciones</strong> ejecuta expresamente una detección nueva solo para ese LXC. Se utiliza después de instalar software mientras ProxMenux ya está en ejecución.",
"<strong>Buscar aplicaciones</strong> ejecuta una detección nueva para ese LXC. Úsalo tras instalar software nuevo mientras ProxMenux ya está en ejecución.",
"La lista anterior permanece visible durante la búsqueda. Las nuevas coincidencias se añaden al finalizar.",
"Si no se encuentra ninguna coincidencia nueva, el resultado aparece junto a las acciones y <strong>Registrar aplicación</strong> continúa disponible para introducirla manualmente.",
"Guardar, eliminar o restaurar una app actualiza la misma caché inmediatamente. El arranque o la restauración de un LXC actualiza únicamente ese sistema mediante su evento de ciclo de vida existente."
@@ -42,10 +42,10 @@
"heading": "Registrar una aplicación",
"lead": "Las sugerencias detectadas y los registros manuales utilizan el mismo editor:",
"steps": [
"Pulsa <strong>Registrar</strong> en una sugerencia o <strong>Registrar aplicación</strong> para elegir una entrada del catálogo o escribir un nombre personalizado.",
"Pulsa <strong>Registrar</strong> en una sugerencia o <strong>Registrar aplicación</strong> para elegir del catálogo o introducir un nombre personalizado.",
"Revisa el nombre y el logotipo propuestos por el catálogo.",
"Añade los enlaces web necesarios. Los puertos en escucha se ofrecen como accesos rápidos, pero ninguno se guarda automáticamente.",
"Deja <strong>Seguir versión disponible</strong> desactivado para un registro de solo enlace o actívalo y revisa el detector instalado y la fuente disponible.",
"Deja <strong>Seguir versión disponible</strong> desactivado para registros de solo enlace, o actívalo y revisa el detector de la versión instalada y la fuente de la versión disponible.",
"Utiliza <strong>Probar detector</strong> cuando el seguimiento esté activado y guarda el registro.",
"Pulsa <strong>Hecho</strong> al terminar la edición. Las pestañas App y Actualizaciones reutilizan el registro actualizado de la caché."
]
@@ -80,7 +80,7 @@
"Cada enlace guarda un esquema, un puerto, una descripción opcional y una URL de logotipo opcional.",
"La URL mostrada utiliza la dirección actual ya detectada para el LXC; esa dirección no se duplica en cada registro.",
"Un enlace sin logotipo propio utiliza el logotipo general de la app.",
"Varios enlaces pueden representar una interfaz de administración, una API, una interfaz secundaria u otro punto final de la misma app.",
"Varios enlaces pueden representar una interfaz de administración, una API, una interfaz secundaria u otro endpoint de la misma app.",
"Una app guardada solo con enlaces también aparece en Actualizaciones, donde se puede configurar posteriormente un actualizador personalizado."
]
},
@@ -90,24 +90,48 @@
"colMethod": "Método de versión instalada",
"colUse": "Uso",
"detectorRows": [
{ "method": "dpkg / apk", "use": "Lee la versión del paquete instalado desde los metadatos de Debian, Ubuntu o Alpine." },
{ "method": "binary", "use": "Ejecuta una ruta binaria absoluta o un nombre de comando con sus parámetros de versión." },
{ "method": "file + regex", "use": "Lee un archivo real y extrae la versión mediante un grupo de captura." },
{ "method": "docker label / docker exec", "use": "Lee una etiqueta de versión OCI o ejecuta un comando de versión dentro de un contenedor Docker." },
{ "method": "python distribution", "use": "Usa importlib.metadata mediante el intérprete de Python seleccionado." },
{ "method": "command", "use": "Ejecuta un comando avanzado en formato argv, sin shell, y extrae la versión de su salida." },
{ "method": "manual", "use": "Guarda una versión introducida manualmente; debe cambiarse después de actualizar la app." },
{ "method": "OCI image", "use": "Para contenedores instalados por OCI manager Apps. Lee las versiones de la aplicación y de la imagen del registro de la instalación y compara el digest instalado con el que publica el registro; no necesita configuración." }
{
"method": "dpkg / apk",
"use": "Lee la versión del paquete instalado desde los metadatos de Debian, Ubuntu o Alpine."
},
{
"method": "binary",
"use": "Ejecuta una ruta binaria absoluta o un nombre de comando con sus parámetros de versión."
},
{
"method": "file + regex",
"use": "Lee un archivo real y extrae la versión mediante un grupo de captura."
},
{
"method": "docker label / docker exec",
"use": "Lee una etiqueta de versión OCI o ejecuta un comando de versión dentro de un contenedor Docker."
},
{
"method": "python distribution",
"use": "Usa importlib.metadata mediante el intérprete de Python seleccionado."
},
{
"method": "command",
"use": "Ejecuta un comando avanzado en formato argv, sin shell, y extrae la versión de su salida."
},
{
"method": "manual",
"use": "Guarda una versión introducida manualmente; debe cambiarse después de actualizar la app."
},
{
"method": "OCI image",
"use": "Para contenedores instalados por OCI manager Apps. Lee las versiones de app e imagen del registro de instalación y compara el digest instalado con el publicado por el registro de imágenes. No necesita configuración."
}
],
"sourcesHeading": "Fuentes para la versión disponible",
"sources": [
"<strong>Repositorio de GitHub</strong>: último lanzamiento o etiqueta de un repositorio público <code>owner/name</code>.",
"<strong>HTTP JSON</strong>: un punto final público y una ruta como <code>data.version</code> o <code>releases[0].tag_name</code>.",
"<strong>HTTP JSON</strong>: un endpoint público y una ruta con puntos, como <code>data.version</code> o <code>releases[0].tag_name</code>.",
"<strong>Docker Hub</strong>: etiquetas versionadas filtradas con una expresión regular. La vista previa muestra etiquetas reales coincidentes antes de guardar.",
"Las etiquetas móviles como <code>latest</code>, <code>stable</code> o <code>lts</code> no contienen una versión. Esas imágenes se siguen por digest desde las actualizaciones de imágenes Docker."
"Etiquetas móviles como <code>latest</code>, <code>stable</code> o <code>lts</code> no contienen una versión. Sigue esas imágenes por digest en las actualizaciones de imágenes Docker."
],
"regexHeading": "Expresión de captura",
"regexLead": "La expresión regular del detector debe devolver la versión en su <strong>primer grupo de captura</strong>.",
"regexLead": "La expresión regular debe devolver la versión en su <strong>primer grupo de captura</strong>.",
"regexRules": [
"Haz coincidir el texto emitido por el binario, archivo, comando o fuente de etiquetas seleccionada; no supongas una ruta genérica.",
"Escapa los puntos literales como <code>\\.</code> para que no coincidan con cualquier carácter.",
@@ -135,11 +159,31 @@
"colDisplay": "Presentación",
"colMeaning": "Significado",
"rows": [
{ "state": "Actualización disponible", "display": "Versión disponible en morado con un icono de flecha ascendente", "meaning": "Las versiones instalada y disponible son diferentes." },
{ "state": "Actualizada", "display": "Versiones instalada y disponible sin la alerta morada", "meaning": "La última comprobación no encontró una versión superior." },
{ "state": "Seguimiento pendiente", "display": "Estado de comprobación o pendiente", "meaning": "El registro está configurado, pero aún no ha completado las dos comprobaciones." },
{ "state": "Seguimiento desactivado", "display": "Solo enlaces web, sin bloque de comparación", "meaning": "El registro sigue siendo válido y puede tener un actualizador." },
{ "state": "Error de comprobación", "display": "Explicación en ámbar dentro de la tarjeta", "meaning": "El estado guardado anterior permanece visible mientras se informa del error del detector o de la fuente." }
{
"state": "Actualización disponible",
"display": "Versión disponible en morado con un icono de flecha ascendente",
"meaning": "Las versiones instalada y disponible son diferentes."
},
{
"state": "Actualizada",
"display": "Versiones instalada y disponible sin la alerta morada",
"meaning": "La última comprobación no encontró una versión superior."
},
{
"state": "Seguimiento pendiente",
"display": "Estado de comprobación o pendiente",
"meaning": "El registro está configurado, pero aún no ha completado las dos comprobaciones."
},
{
"state": "Seguimiento desactivado",
"display": "Solo enlaces web, sin bloque de comparación",
"meaning": "El registro sigue siendo válido y puede tener un actualizador."
},
{
"state": "Error de comprobación",
"display": "Explicación en ámbar dentro de la tarjeta",
"meaning": "El estado guardado anterior permanece visible mientras se informa del error del detector o de la fuente."
}
]
},
"management": {
@@ -158,11 +202,26 @@
"colProblem": "Situación",
"colResolution": "Resolución",
"rows": [
{ "problem": "Se instaló software después de arrancar ProxMenux", "resolution": "Pulsa Buscar aplicaciones. El escaneo explícito actualiza las sugerencias en caché de ese LXC." },
{ "problem": "No se detectó la aplicación", "resolution": "Regístrala manualmente. Un nombre y un enlace web son suficientes; el seguimiento puede añadirse después." },
{ "problem": "El detector sugerido devuelve una versión incorrecta", "resolution": "Abre Editar campos, selecciona el paquete, binario o archivo real y prueba el detector antes de guardar." },
{ "problem": "Una carga Docker no se ofrece como app LXC", "resolution": "Registra Docker y añade la interfaz publicada de la carga como enlace web de Docker. Las actualizaciones de imágenes permanecen en la sección Docker." },
{ "problem": "Una app guardada no tiene botón de actualización", "resolution": "Abre Actualizaciones y configura su método. El seguimiento de versiones no define por sí solo cómo se instala una actualización." }
{
"problem": "Se instaló software después de arrancar ProxMenux",
"resolution": "Pulsa Buscar aplicaciones. El escaneo explícito actualiza las sugerencias en caché de ese LXC."
},
{
"problem": "No se detectó la aplicación",
"resolution": "Regístrala manualmente. Un nombre y un enlace web son suficientes; el seguimiento puede añadirse después."
},
{
"problem": "El detector sugerido devuelve una versión incorrecta",
"resolution": "Abre Editar campos, selecciona el paquete, binario o archivo real y prueba el detector antes de guardar."
},
{
"problem": "Una carga Docker no se ofrece como app LXC",
"resolution": "Registra Docker y añade la interfaz publicada de la carga como enlace web de Docker. Las actualizaciones de imágenes permanecen en la sección Docker."
},
{
"problem": "Una app guardada no tiene botón de actualización",
"resolution": "Abre Actualizaciones y configura su método. El seguimiento de versiones no define por sí solo cómo se instala una actualización."
}
]
},
"figures": {
@@ -19,13 +19,13 @@
"<strong>Paquetes del SO</strong> para contenedores Debian, Ubuntu y Alpine.",
"Una sección por cada <strong>aplicación registrada</strong>, incluidos los registros que solo contienen enlaces.",
"Una sección <strong>Docker</strong> cuando Docker está registrado, con Docker Engine y las imágenes etiquetadas dentro del mismo bloque.",
"Una <strong>Actualización en bloque</strong> configurable, seguida de las opciones de copia, reinicio y programación."
"Una <strong>Actualización en bloque</strong> configurable, seguida de las opciones de backup, reinicio y programación."
]
},
"mechanisms": {
"heading": "Cómo se selecciona el método",
"lead": "La vía integrada de Proxmox VE Helper-Scripts sigue el mecanismo oficial <helper>update-apps</helper>. El resto de instalaciones usa el método de paquetes, Docker o el comando personalizado correspondiente.",
"officialReference": "Referencia oficial: la <helper>documentación de update-apps de Proxmox VE Helper-Scripts</helper> explica los modos interactivo y desatendido, las copias de seguridad, la simulación, los recursos temporales de compilación, los registros y los códigos de salida.",
"officialReference": "Referencia oficial: la <helper>documentación de update-apps de Proxmox VE Helper-Scripts</helper> explica los modos interactivo y desatendido, los backups, la simulación, los recursos temporales de compilación, los registros y los códigos de salida.",
"colSource": "Origen",
"colAction": "Acción mostrada",
"colNotes": "Qué se ejecuta",
@@ -56,7 +56,7 @@
"notes": "Descarga la imagen seleccionada y recrea su grupo de servicios Compose o su contenedor independiente protegido."
}
],
"callout": "El comando personalizado <strong>reemplaza</strong> a Helper-Scripts para esa aplicación. Las ejecuciones manuales, en bloque y programadas respetan la elección guardada. Se conservan los comandos existentes y las selecciones antiguas guardadas en planes o programaciones activadas; una programación antigua nunca activa el actualizador de una app recién registrada."
"callout": "Un comando personalizado <strong>reemplaza</strong> Helper-Scripts para esa app. Las ejecuciones manuales, en bloque y programadas respetan la elección. Se conservan los comandos existentes y las selecciones antiguas guardadas expresamente en planes o programaciones activadas; una programación antigua nunca incorpora una app recién registrada."
},
"docker": {
"heading": "Docker Engine e imágenes Docker",
@@ -84,13 +84,13 @@
"statusColMeaning": "Significado",
"statusRows": [
{
"state": "Actualización verificada",
"state": "Actualización verificada disponible",
"appearance": "Texto morado, icono de flecha ascendente y acción morada",
"meaning": "La versión instalada y la disponible, o los digests de imagen, son diferentes."
},
{
"state": "Actualizado y verificado",
"appearance": "Comprobación verde y acción Actualizado en verde",
"appearance": "Marca de verificación verde y acción Actualizado en verde",
"meaning": "La última comprobación terminada confirma que el objetivo está actualizado."
},
{
@@ -120,16 +120,16 @@
"Los paquetes del SO son obligatorios. Debe seleccionarse al menos una app, Docker Engine o unidad de imagen Docker adicional.",
"Las aplicaciones y unidades Docker se seleccionan individualmente. Un servicio principal de Compose muestra las dependencias que se actualizarán con él.",
"Los objetivos eliminados o no disponibles se marcan como obsoletos y deben retirarse antes de guardar la configuración.",
"El botón <strong>Aplicar actualizaciones</strong> es morado si algún objetivo seleccionado tiene una actualización verificada, verde si todos están verificados como actualizados y neutro cuando el resultado es desconocido.",
"<strong>Aplicar actualizaciones</strong> es morado si algún objetivo tiene una actualización verificada, verde si todos están verificados como actualizados y neutro si el resultado es desconocido.",
"Eliminar la configuración en bloque no borra los métodos individuales ni la programación."
],
"callout": "La actualización en bloque no reemplaza los botones individuales. Es un acceso opcional para una selección que debe ejecutarse junta."
},
"options": {
"heading": "Opciones de copia y reinicio",
"heading": "Opciones de backup y reinicio",
"lead": "Las mismas opciones se aplican a ejecuciones manuales, en bloque y programadas:",
"items": [
"<strong>Instantánea antes de aplicar</strong> crea una copia vzdump en el almacenamiento seleccionado. Si la copia solicitada falla, la actualización no comienza.",
"<strong>Backup antes de aplicar</strong> crea un backup vzdump en el almacenamiento seleccionado. Si el backup solicitado falla, la actualización no comienza.",
"<strong>Reiniciar después de aplicar</strong> reinicia el LXC únicamente tras una ejecución correcta.",
"Las selecciones se guardan por LXC y son independientes de la lista de objetivos."
]
@@ -140,7 +140,7 @@
"items": [
"Selecciona una frecuencia o expresión cron y después objetivos exactos: paquetes del SO, apps individuales, Docker Engine, unidades Docker independientes o grupos de servicios Compose.",
"La espera tras una versión solo se aplica a las apps seleccionadas con seguimiento. Las apps sin seguimiento ejecutan su actualizador cuando vence la programación.",
"El estado de la última ejecución diferencia entre éxito, finalización parcial, error, retención de seguridad y ausencia de elementos pendientes. Después de la primera ejecución programada, <strong>Actualizaciones → Actualizaciones programadas → Ver log</strong> abre la salida completa capturada del actualizador y de los scripts secundarios que haya ejecutado.",
"El estado de la última ejecución distingue éxito, finalización parcial, fallo, retención de seguridad y ausencia de actualizaciones pendientes. Tras la primera ejecución programada, <strong>Actualizaciones → Actualizaciones programadas → Ver registro</strong> abre toda la salida del actualizador y de los scripts secundarios invocados.",
"Después de cada ejecución, ProxMenux comprueba el marcador estándar de Debian que indica si es necesario reiniciar. Cuando hace falta, la pestaña Actualizaciones y la notificación de finalización lo indican; el aviso se elimina cuando ese LXC se inicia o reinicia.",
"En el host Proxmox, los logs de las ejecuciones programadas se guardan en <code>/usr/local/share/proxmenux/logs/lxc-updates/</code> con el nombre <code>&lt;VMID&gt;-scheduled-&lt;run-id&gt;.log</code>. Se conservan los diez últimos logs de cada LXC y los archivos más antiguos se eliminan automáticamente.",
"Este historial corresponde a las actualizaciones programadas. Una actualización manual muestra su salida en tiempo real en la ventana de ejecución del Monitor y no crea un log de ejecución programada en ese directorio.",
@@ -196,8 +196,8 @@
"caption": "La sección del sistema operativo mantiene los paquetes separados de las acciones de aplicaciones y Docker."
},
"options": {
"alt": "Opciones de actualización LXC con copia previa y reinicio posterior",
"caption": "Las preferencias de copia y reinicio se aplican a ejecuciones manuales, en bloque y programadas."
"alt": "Opciones de actualización LXC con backup previo y reinicio posterior",
"caption": "Las preferencias de backup y reinicio se aplican a ejecuciones manuales, en bloque y programadas."
}
}
}
@@ -1,168 +1,168 @@
{
"meta": {
"title": "ProxMenux Monitor — Panel: pestaña VMs y LXCs | ProxMenux Documentation",
"description": "La pestaña VMs y LXCs inventaría cada guest del host con uso de CPU / memoria / disco en vivo. La vista en detalle por guest muestra configuración, recursos, backups, logs completos del guest, notas y controles Start / Shutdown / Reboot / Stop."
"title": "ProxMenux Monitor — Panel: VMs y LXCs | Documentación de ProxMenux",
"description": "Inventario de todos los invitados con CPU, memoria y disco en vivo. Los detalles incluyen configuración, recursos, backups, el log de consola de los contenedores OCI, notas y controles Iniciar / Apagar / Reiniciar / Forzar parada."
},
"header": {
"title": "Panel: pestaña VMs y LXCs",
"description": "El inventario completo de guests del nodo. Cuatro métricas titulares arriba, una lista ordenable con cada VM y LXC abajo y una vista en detalle por guest con config, recursos, backups, logs y los cuatro controles de ciclo de vida (Start / Shutdown / Reboot / Stop).",
"title": "Panel: VMs y LXCs",
"description": "Inventario completo de invitados del nodo: cuatro métricas arriba, lista ordenable de VM y LXC abajo y detalles por invitado con configuración, recursos, backups, el log de consola de los contenedores OCI y cuatro controles de ciclo de vida (Iniciar / Apagar / Reiniciar / Forzar parada).",
"section": "ProxMenux Monitor · Panel"
},
"intro": {
"title": "La superficie de control para guests",
"body": "El resto de pestañas son de solo lectura; esta es desde la que actúas. Todo lo que cambia el estado de un guest pasa por <code>POST /api/vms/&lt;vmid&gt;/control</code> con una confirmación explícita y la respuesta se refleja de vuelta en la fila del guest. No hay force-shutdown sin pasar por el botón Stop dedicado."
"title": "Controles de los invitados",
"body": "Controla el ciclo de vida de los invitados desde esta pestaña. Las acciones pasan por <code>POST /api/vms/&lt;vmid&gt;/control</code>; Reiniciar y Forzar parada piden escribir el VMID para confirmar, y la respuesta se refleja en la fila del invitado. El apagado forzado requiere el botón específico Forzar parada."
},
"topRow": {
"heading": "Fila superior: cuatro tarjetas de estadísticas",
"intro": "Al abrir la pestaña VMs y LXCs aterrizas en un resumen de cuatro tarjetas del estado de los guests — totales, utilización de CPU, compromiso de memoria vs capacidad del host y asignación de disco.",
"intro": "Al abrir VMs y LXCs aparecen cuatro tarjetas: número de invitados, uso CPU, memoria asignada frente a la capacidad del host y espacio de disco asignado.",
"imageAlt": "Pestaña VMs y LXCs — fila superior de cuatro tarjetas de estadísticas: Total VMs & LXCs, Total CPU, Total Memory, Total Disk",
"imageCaption": "Fila superior de la pestaña VMs y LXCs — totales + insignias Running / Stopped, utilización actual de CPU, memoria desglosada en used / running-allocated / total-allocated (con una insignia Within Limits) y espacio de disco asignado.",
"imageCaption": "Fila superior: totales y estados En ejecución / Detenidos, uso actual de CPU, memoria usada / asignada a invitados activos / asignada total (con Dentro de límites) y espacio de disco asignado.",
"headerCard": "Tarjeta",
"headerWhat": "Qué muestra",
"totalLabel": "Total VMs & LXCs",
"totalLabel": "Total de VM y LXC",
"totalWhat": "Recuento total con dos insignias — <em>X Running</em> (verde) y <em>Y Stopped</em> (rojo, solo cuando > 0). El número que miras cuando algo no volvió tras un reinicio.",
"cpuLabel": "Total CPU",
"cpuWhat": "Utilización agregada de CPU en vivo a lo largo de todos los guests como porcentaje de la CPU física del host, con una línea al pie <em>\"Allocated CPU usage\"</em>.",
"memoryLabel": "Total Memory",
"cpuLabel": "CPU total",
"cpuWhat": "Uso CPU total en vivo de todos los invitados como porcentaje de la CPU física del host, con el pie <em>«Uso de CPU asignada»</em>.",
"memoryLabel": "Memoria Total",
"memoryIntro": "Tres lecturas apiladas verticalmente:",
"memoryItems": [
"<strong>Currently used</strong> — valor grande (p. ej. <em>15.4 GB</em>) más <em>X.X % de Y GB</em> contra la RAM total del host. Una barra de progreso azul sigue al porcentaje.",
"<strong>Running allocated</strong> + <strong>Total allocated</strong> — suma de <code>maxmem</code> a lo largo de los guests que están <em>actualmente up</em> junto a la misma suma a lo largo de <em>todos</em> los guests incluyendo los parados. El primero importa hoy; el segundo importa cuando arrancas todo a la vez.",
"<strong>Insignia Within Limits</strong> (verde) — pasa a <em>Over-committed</em> si el total asignado excede la RAM del host. Un over-commit sano de memoria está bien en hosts con KSM, pero la insignia es el aviso temprano cuando ya no es cómodo."
"<strong>Usada actualmente</strong>: valor principal, como <em>15.4 GB</em>, y <em>X.X % de Y GB</em> respecto a la RAM del host. La barra azul indica el porcentaje.",
"<strong>Asignada a activos</strong> + <strong>Asignada total</strong>: suma de <code>maxmem</code> de los invitados <em>en ejecución</em> y de <em>todos</em>, incluidos los detenidos. La primera refleja la situación actual; la segunda, qué pasaría al arrancarlos todos.",
"<strong>Dentro de límites</strong>, en verde, cambia a <em>Sobreasignada</em> si la memoria total asignada supera la RAM del host. Una sobreasignación controlada puede funcionar con KSM; la etiqueta avisa cuando el margen disminuye."
],
"diskLabel": "Total Disk",
"diskWhat": "Suma del espacio de disco asignado a lo largo de todos los guests, en la unidad adecuada (GB / TB), con la línea al pie <em>\"Allocated disk space\"</em>."
"diskLabel": "Disco total",
"diskWhat": "Suma del espacio de disco asignado a todos los invitados, en GB o TB, con el pie <em>«Espacio de disco asignado»</em>."
},
"inventory": {
"heading": "Lista Virtual Machines & Containers",
"heading": "Lista de máquinas virtuales y contenedores",
"intro": "Una fila por guest. La lista se nutre de una única fuente, <code>/api/vms</code>, que consolida <code>qm list</code> + <code>pct list</code> + <code>pvesh /cluster/resources</code> en el host.",
"imageAlt": "Lista Virtual Machines & Containers — una fila por guest con estado, insignia de tipo, nombre, ID y porcentajes inline de CPU / memoria / disco",
"imageCaption": "El layout optimizado para móvil del inventario — los mismos datos que muestra la vista de escritorio, reapilados en una sola columna con los porcentajes e indicadores de estado compactos.",
"rowsIntro": "Cada fila muestra:",
"rows": [
"<strong>Icono de estado</strong> — play verde (running) o cuadrado rojo (stopped). Para guests parados, el resto de la fila se atenúa para que veas al instante qué está offline.",
"<strong>Icono de estado</strong>: triángulo verde (en ejecución) o cuadrado rojo (detenido). Las filas de invitados detenidos se atenúan para identificarlos de inmediato.",
"<strong>Insignia de tipo</strong> — <em>LXC</em> (cian) para contenedores, <em>VM</em> (morado) para máquinas virtuales.",
"<strong>Nombre</strong> — hostname / nombre de display del guest.",
"<strong>Nombre</strong>: nombre de host o nombre visible del invitado.",
"<strong>VMID</strong> — el ID numérico de Proxmox bajo el nombre.",
"<strong>Métricas inline</strong> — tres porcentajes con su icono (CPU %, Memory %, Disk %). Cada icono se pone naranja cuando la métrica cruza un umbral de atención (p. ej. memoria por encima del 90 %), así un vistazo rápido te dice qué guest está bajo presión sin abrirlo."
],
"clickHint": "Pulsar cualquier fila — running o stopped — abre la modal de vista en detalle descrita abajo.",
"mobileTitle": "La lista está construida mobile-first",
"mobileBody": "En móviles y ventanas estrechas el inventario reflowea a una única columna con insignia de tipo, nombre, ID y los tres porcentajes de métricas, uno por línea — exactamente la captura de arriba. En viewports más anchos los mismos datos se reparten horizontalmente con más espacio para los porcentajes. De cualquier modo, cada fila es el mismo target completo: pulsa para entrar."
"clickHint": "Pulsa una fila, esté el invitado en ejecución o detenido, para abrir sus detalles.",
"mobileTitle": "La lista está diseñada para móviles",
"mobileBody": "En móviles y ventanas estrechas, tipo, nombre, ID y tres porcentajes se apilan en una columna, como en la captura. En pantallas anchas se reparten horizontalmente con más espacio. Toda la fila es pulsable para abrir los detalles."
},
"drillIn": {
"heading": "Modal de vista en detalle por guest",
"heading": "Ventana de detalles del invitado",
"intro": "El modal se abre con el nombre, VMID, tipo, estado y tiempo de actividad del sistema. La navegación se adapta al elemento: <strong>Estado</strong>, <strong>App</strong> y <strong>Actualizaciones</strong> para gestionar aplicaciones LXC, <strong>Montajes</strong> cuando existen puntos de montaje, <strong>Logs</strong> en los contenedores instalados por OCI manager Apps, además de <strong>Backups</strong> y <strong>Cortafuegos</strong>. La barra inferior mantiene los controles de ciclo de vida y el terminal LXC disponibles desde cualquier pestaña.",
"statusTitle": "Pestaña 1 — Estado",
"statusImageAlt": "Modal de vista en detalle por guest — pestaña Status con tarjetas en vivo de CPU / Memoria / Disco, totales de E/S de disco y red, el logo de distro del SO y el bloque Resources / IP Addresses",
"statusImageCaption": "Pestaña Status — CPU / Memoria / Disco en vivo con barras de progreso arriba, totales de E/S acumulados (lectura/escritura de disco, descarga/subida de red) abajo, después el bloque estático Resources con expansiones de Notes y + Info y la lista de pastillas IP Addresses.",
"statusIntro": "La pestaña por defecto — la vista \"¿este guest se está portando?\". Tres bloques:",
"statusImageAlt": "Detalles del invitado: Estado con CPU, memoria y disco en vivo, E/S de disco y red, logotipo del SO y Recursos / Direcciones IP",
"statusImageCaption": "Estado: CPU, memoria y disco con barras arriba; totales acumulados de E/S (disco leído/escrito, red recibida/enviada); Recursos con Notas, + Info y lista de direcciones IP.",
"statusIntro": "La pestaña inicial permite comprobar el estado del invitado. Tres bloques:",
"liveTitle": "1. Fila de métricas en vivo",
"liveItems": [
"<strong>CPU Usage (X cores)</strong> — porcentaje actual con barra de progreso. La cabecera muestra el recuento de cores configurado para que sepas qué significaría un 100 %.",
"<strong>Memory</strong> — <em>used / max</em> en GB con barra de progreso.",
"<strong>Disk</strong> — <em>used / max</em> a lo largo de la imagen de disco primaria del guest, misma forma."
"<strong>Uso CPU (X núcleos)</strong>: porcentaje con barra. La cabecera muestra los núcleos configurados para interpretar qué significa 100 %.",
"<strong>Memoria</strong>: <em>usada / máxima</em> en GB con barra.",
"<strong>Disco</strong>: <em>usado / máximo</em> de la imagen principal de disco, con el mismo formato."
],
"ioTitle": "2. Totales de E/S + logo del SO",
"ioItems": [
"<strong>Disk I/O</strong> — totales acumulados de lectura (↓) y escritura (↑) desde el arranque. Útil para detectar un guest que se ha vuelto de repente intensivo en E/S comparado con su baseline.",
"<strong>Network I/O</strong> — descarga (↓) y subida (↑) acumuladas. Misma idea en el lado de red.",
"<strong>Logo de distro del SO</strong> — el icono de Debian / Ubuntu / Alpine / Windows / etc. detectado del tipo de SO del guest. Una pista visual rápida cuando scrolleas varias modales abiertas."
"<strong>E/S de disco</strong>: totales de lectura (↓) y escritura (↑) desde el arranque. Ayuda a detectar aumentos de E/S frente a la actividad habitual del invitado.",
"<strong>E/S de red</strong>: descarga (↓) y subida (↑) acumuladas; el mismo concepto para la red.",
"<strong>Logotipo del SO</strong>: icono Debian / Ubuntu / Alpine / Windows / etc. según el sistema detectado. Ayuda a identificarlo al consultar varias ventanas."
],
"resourcesTitle": "3. Bloque Resources",
"resourcesIntro": "La configuración del guest tal como la ve Proxmox — CPU Cores, Memory (<code>maxmem</code> configurado), Swap. Dos botones colapsables en la cabecera del bloque:",
"resourcesTitle": "3. Bloque Recursos",
"resourcesIntro": "Configuración del invitado según Proxmox: núcleos CPU, memoria (<code>maxmem</code> configurado) y swap. Dos botones despliegan información adicional:",
"resourcesItems": [
"<strong>Notes</strong> — el campo de descripción del guest. Editable: escribir aquí y guardar llama <code>PUT /api/vms/&lt;vmid&gt;/config</code> y escribe de vuelta en <code>/etc/pve/qemu-server/&lt;vmid&gt;.conf</code> o <code>/etc/pve/lxc/&lt;vmid&gt;.conf</code>.",
"<strong>+ Info</strong> — campos extra que son demasiado verbosos para la vista por defecto: bios mode, machine type, agent state, entradas de hostpci passthrough, mount points (CT), boot order."
"<strong>Notas</strong>: descripción editable del invitado. Guardar llama a <code>PUT /api/vms/&lt;vmid&gt;/config</code> y escribe en <code>/etc/pve/qemu-server/&lt;vmid&gt;.conf</code> o <code>/etc/pve/lxc/&lt;vmid&gt;.conf</code>.",
"<strong>+ Info</strong>: modo BIOS, tipo de máquina, estado del agente, asignaciones passthrough hostpci, puntos de montaje CT y orden de arranque."
],
"ipsTitle": "4. IP Addresses",
"ipsBody": "Lista de pastillas con cada dirección IPv4 / IPv6 que el guest expone actualmente — pastilla verde por dirección. Vacía cuando el guest está parado o cuando el QEMU agent no está instalado en una VM (los LXCs siempre reportan direcciones directamente).",
"ipsTitle": "4. Direcciones IP",
"ipsBody": "Cada dirección IPv4 o IPv6 del invitado aparece en una etiqueta verde. La lista queda vacía si está detenido o si una VM carece del agente QEMU; los LXC comunican sus direcciones directamente.",
"appTitle": "Pestaña 2 — App (solo LXC)",
"appIntro": "Registra las aplicaciones que pertenecen al LXC, guarda enlaces web y, opcionalmente, compara las versiones instalada y disponible. Las sugerencias proceden de la caché de arranque; <strong>Buscar aplicaciones</strong> actualiza expresamente la detección de este LXC después de instalar software nuevo.",
"appLinkLead": "Consulta la",
"appLinkLabel": "página específica de App",
"appLinkTail": "para conocer la detección en caché, el registro asistido por catálogo, los enlaces web de Docker y los detectores de versión.",
"updatesTitle": "Pestaña 3 — Actualizaciones (solo LXC)",
"updatesIntro": "Mantiene como objetivos separados los <strong>paquetes del SO</strong>, las aplicaciones registradas, <strong>Docker Engine</strong> y las imágenes Docker. Cada objetivo puede ejecutarse por separado; una acción en bloque y una programación opcionales seleccionan los métodos exactos que deben ejecutarse juntos.",
"updatesIntro": "Mantiene separados <strong>paquetes del SO</strong>, aplicaciones, <strong>Docker Engine</strong> e imágenes Docker. Cada objetivo se ejecuta por separado o se incluye en una selección exacta para actualización en bloque o programada.",
"updatesLinkLead": "Consulta la",
"updatesLinkLabel": "página específica de Actualizaciones",
"updatesLinkTail": "para conocer los actualizadores integrados y personalizados, la recreación Docker, la selección en bloque, las opciones de seguridad y la programación.",
"mountsTitle": "Pestaña 4 — Montajes (solo LXC, cuando existen)",
"mountsImageAlt": "Modal de vista en detalle LXC — pestaña Mounts listando cada mount point que está usando el contenedor: volúmenes PVE, host binds, binds desde almacenamiento PVE y montajes ad-hoc NFS/CIFS que el operador montó desde dentro del CT. Cada tarjeta lleva una insignia de tipo, barra de capacidad, bytes used/total, opciones de montaje y un punto de estado por color (verde sano, ámbar readonly/divergente, rojo stale)",
"updatesLinkTail": "para actualizadores integrados y personalizados, recreación de contenedores Docker, selección en bloque, opciones de seguridad y programación.",
"mountsTitle": "Pestaña 4 — Montajes (solo LXC, si existen)",
"mountsImageAlt": "Detalles LXC, Montajes: volúmenes PVE, bind mounts del host o de almacenamiento PVE y NFS/CIFS montados dentro del CT. Cada tarjeta muestra tipo, capacidad, bytes usados/totales, opciones y estado por color: verde correcto, ámbar solo lectura/divergente, rojo inaccesible.",
"mountsImageCaption": "Pestaña Mounts — solo se renderiza para contenedores LXC, y solo cuando hay al menos un mount point o un montaje remoto ad-hoc presente. Un CT sin mounts no recibe pestaña.",
"mountsIntro": "La propia UI de Proxmox muestra las entradas de mount-point definidas en la config del contenedor (<code>mpX</code>) pero se queda ahí — cualquier cosa que montes desde dentro del CT después (<code>mount.cifs</code>, NFS vía <code>autofs</code>, …) es invisible. Esta pestaña funde <strong>ambas vistas</strong>: los mounts configurados <strong>y</strong> los mounts en runtime que ProxMenux sonda desde dentro del contenedor, con un estado de salud por mount y una barra de capacidad cuando el backend la puede resolver.",
"mountTypesTitle": "Tipos de mount detectados",
"mountsIntro": "Proxmox muestra los montajes configurados como <code>mpX</code>, pero no los añadidos después desde el CT con <code>mount.cifs</code>, NFS mediante <code>autofs</code>, etc. Esta pestaña une <strong>ambas vistas</strong>: montajes configurados <strong>y</strong> detectados dentro del contenedor, con estado por montaje y capacidad cuando el servidor puede obtenerla.",
"mountTypesTitle": "Tipos de montaje detectados",
"mountTypesItems": [
"<strong>PVE volume</strong> — respaldado por un almacenamiento gestionado por Proxmox (un subvol ZFS, una entrada de directorio, un Ceph RBD, …). La capacidad viene de las stats del almacenamiento PVE para que la barra coincida con lo que el propio Proxmox muestra.",
"<strong>Bind from PVE storage</strong> — entrada <code>mpX</code> apuntando a una ruta en un almacenamiento conocido por PVE.",
"<strong>Bind from host</strong> — entrada <code>mpX</code> apuntando a una ruta arbitraria del host (<code>/mnt/something</code>). La capacidad es el <code>df</code> de esa ruta del host.",
"<strong>Volumen PVE</strong>: almacenamiento gestionado por Proxmox (subvolumen ZFS, entrada de directorio, Ceph RBD, etc.). La capacidad usa las estadísticas PVE para coincidir con Proxmox.",
"<strong>Bind de almacenamiento PVE</strong>: entrada <code>mpX</code> que apunta a una ruta de un almacenamiento conocido por PVE.",
"<strong>Bind del host</strong>: entrada <code>mpX</code> con una ruta arbitraria del host (<code>/mnt/something</code>). La capacidad se obtiene con <code>df</code> de esa ruta.",
"<strong>Ad-hoc inside CT</strong> — mount que <em>solo</em> existe en el namespace de mounts del contenedor (p. ej. un share NFS que el CT monta por su cuenta). La capacidad se lee vía <code>pct exec &lt;vmid&gt; df</code>, que es la única forma de verla — <code>/proc/&lt;pid&gt;/root</code> desde el host no expone las stats reales del mount remoto."
],
"mountStateTitle": "Punto de estado por tarjeta y avisos",
"mountStateItems": [
"<green/> <strong>Verde</strong> — mount sano y alcanzable.",
"<amber/> <strong>Ámbar</strong> — divergente (configurado pero no montado en realidad), read-only o <em>zombie bind</em> (el origen en el host fue retirado pero el CT sigue viendo el bind como montado — típico cuando se desconectó una unidad USB o hubo un <code>umount</code> manual en el host).",
"<red/> <strong>Rojo</strong> — stale: la sonda de runtime no pudo alcanzar el mount (común con exports NFS cuyo servidor está caído)."
"<green/> <strong>Verde</strong>: montaje correcto y accesible.",
"<amber/> <strong>Ámbar</strong>: configurado pero no montado, solo lectura o <em>bind zombi</em>. En este último caso se retiró el origen del host, pero el CT aún lo ve montado, por ejemplo tras desconectar un USB o ejecutar <code>umount</code> en el host.",
"<red/> <strong>Rojo</strong>: inaccesible; la comprobación en ejecución no alcanzó el montaje, por ejemplo un recurso NFS con el servidor caído."
],
"mountsCalloutTitle": "Lo que esto te da sobre la UI nativa",
"mountsCalloutTitle": "Información adicional respecto a Proxmox",
"mountsCalloutBody": "Una vista veraz y consciente de la capacidad de cada sitio donde el contenedor lee o escribe. Shares NFS o CIFS montados desde dentro del CT — invisibles para la UI web de Proxmox — aparecen aquí con el mismo aspecto y la misma sonda de salud que cualquier mount point configurado. Mounts remotos stale y zombie binds salen marcados antes de que muerdan durante un backup.",
"logsTitle": "Pestaña 5 — Logs (solo contenedores OCI)",
"logsBody": "Solo aparece en los contenedores instalados por OCI manager Apps. Muestra la salida de consola del proceso principal de la imagen, guardada en el host en <code>/var/log/proxmenux/oci/VMID.console.log</code>: las últimas 100, 500 o 1000 líneas, seguidas en directo con el contenedor en marcha, con un filtro y una descarga. Lee el archivo cada vez que se abre, así que también funciona con el contenedor detenido. Los detalles están en <ociLink>Contenedores OCI en ProxMenux Monitor</ociLink>.",
"logsBody": "Solo para contenedores de OCI manager Apps. Muestra la consola del proceso principal de la imagen, guardada en <code>/var/log/proxmenux/oci/VMID.console.log</code>: últimas 100, 500 o 1000 líneas, seguimiento en vivo mientras está activo, filtro y descarga. Relee el archivo al abrir y funciona detenido. Más en <ociLink>Contenedores OCI en ProxMenux Monitor</ociLink>.",
"backupsTitle": "Pestaña 6 — Backups",
"backupsImageAlt": "Modal de vista en detalle por guest — pestaña Backups con la lista de backups disponibles, etiqueta de destino, tamaños y el botón Create Backup",
"backupsImageCaption": "Pestaña Backups — cada backup almacenado en los almacenamientos Proxmox configurados para este guest, ordenados de más nuevo a más viejo. La cabecera de la pestaña lleva la insignia de recuento.",
"backupsIntro": "Lista cada backup almacenado en los almacenamientos Proxmox configurados para este guest, ordenados de más nuevo a más viejo. El título de la pestaña lleva una insignia de recuento para que veas de un vistazo si el guest está backupeado. Por fila:",
"backupsImageCaption": "Todos los backups del invitado en almacenamientos Proxmox configurados, de más nueva a más antigua. La cabecera muestra su número.",
"backupsIntro": "Lista los backups del invitado en almacenamientos Proxmox, empezando por la más reciente. El contador del título permite comprobar si tiene backups. Cada fila muestra:",
"backupsItems": [
"<strong>Timestamp</strong> — fecha y hora de la ejecución.",
"<strong>Fecha y hora</strong>: momento de la ejecución.",
"<strong>Etiqueta de destino</strong> — el almacenamiento donde vive (PBS-Cloud, PBS-Local, NFS-Backup, …) coloreada por estado.",
"<strong>Size</strong> — tamaño final en disco del backup."
"<strong>Tamaño</strong>: tamaño final en disco del backup."
],
"backupsOutro": "El botón <strong>+ Create Backup</strong> arriba a la derecha arranca una nueva ejecución en el almacenamiento marcado como \"Backup target\" en la config de almacenamiento de Proxmox. El restore vive en la UI web de Proxmox — el Monitor expone la vista \"¿este guest tiene backup reciente?\", no el flujo de recuperación.",
"backupsOutro": "<strong>+ Crear backup</strong> inicia un backup en el almacenamiento marcado «Backup target» en Proxmox. Para restaurar usa la interfaz web de Proxmox; Monitor muestra los backups recientes del invitado y permite crearlos.",
"firewallTitle": "Pestaña 7 — Cortafuegos",
"firewallIntro": "Lee el log de firewall de Proxmox por guest directamente del host (sin servicio extra, sin polling). La pestaña siempre está presente en la barra de navegación; el panel decide qué renderizar dependiendo de si el firewall está activo para ese guest y si alguna regla está logueando realmente:",
"firewallIntro": "Lee el registro del cortafuegos de cada invitado directamente del host, sin servicio extra ni consultas periódicas. La pestaña siempre aparece; el contenido depende de que el cortafuegos esté activado y de que alguna regla registre paquetes.",
"firewallItems": [
"<strong>Firewall disabled</strong> — un aviso ámbar explica exactamente dónde activarlo en la UI de Proxmox (<em>&lt;Container|VM&gt; → Firewall → Options</em>) y te recuerda que al menos una regla necesita <code>log: info</code> (o superior) antes de que aparezcan paquetes.",
"<strong>Firewall enabled, no events yet</strong> — pista de estado vacío con el mismo requisito de logging, útil cuando acabas de activar el firewall.",
"<strong>Events present</strong> — un panel monoespaciado scrolleable con las entradas raw coloreadas por acción: <green>ACCEPT</green> (verde), <orange>REJECT</orange> (naranja), <red>DROP</red> (rojo). Una insignia de recuento en la cabecera muestra cuántas entradas hay cargadas en este momento."
"<strong>Cortafuegos desactivado</strong>: aviso ámbar que indica dónde activarlo en Proxmox (<em>&lt;Container|VM&gt; → Firewall → Options</em>) y que alguna regla requiere <code>log: info</code> o superior para mostrar paquetes.",
"<strong>Cortafuegos activo, sin eventos aún</strong>: el panel vacío recuerda el mismo requisito de registro, útil al activarlo por primera vez.",
"<strong>Hay eventos</strong>: panel monoespaciado con desplazamiento y entradas originales por acción: <green>ACCEPT</green> verde, <orange>REJECT</orange> naranja y <red>DROP</red> rojo. El contador de la cabecera indica las entradas cargadas."
],
"firewallRefresh": "Un botón <em>Refresh</em> arriba a la derecha del panel trae las últimas entradas bajo demanda — no hay auto-refresh dentro de la modal, así que la lista es una snapshot del momento en que abriste la pestaña o pulsaste refresh. Los datos vienen del archivo de log por guest que Proxmox escribe bajo <code>/var/log/pve-firewall.log</code> filtrado por VMID, expuesto vía <code>GET /api/vms/&lt;vmid&gt;/firewall/log</code>.",
"firewallRefresh": "<em>Actualizar</em> carga las entradas más recientes bajo demanda. No hay actualización automática: se muestra el momento de apertura o de la última pulsación. Los datos proceden de <code>/var/log/pve-firewall.log</code>, filtrados por VMID mediante <code>GET /api/vms/&lt;vmid&gt;/firewall/log</code>.",
"firewallCalloutTitle": "¿Por qué tenerlo aquí cuando la UI de Proxmox ya lo muestra?",
"firewallCalloutBody": "Dos razones: elimina el viaje de ida y vuelta a la UI web de Proxmox cuando ya estás inspeccionando un guest desde el panel, y mantiene la misma vista acotada por VMID que usa el resto de la modal — arrancar el guest, comprobar sus mounts, mirar los hits recientes del firewall y pararlo otra vez sin salir del panel. El Monitor nunca edita reglas de firewall; la edición de reglas se queda en la interfaz nativa de Proxmox donde corresponde.",
"firewallCalloutBody": "Evita cambiar a la interfaz Proxmox y mantiene la vista del mismo VMID: inicia el invitado, comprueba montajes y eventos del cortafuegos y vuelve a detenerlo desde el panel. Las reglas se editan en Proxmox; Monitor no las modifica.",
"actionBarTitle": "Barra de acciones del pie",
"actionBarIntro": "Siempre visible al pie de la modal independientemente de qué pestaña esté activa:",
"consoleItem": "<strong>Console</strong> (solo LXC, running) — abre una modal que ejecuta <code>pct enter &lt;vmid&gt;</code> y te deja dentro del contenedor. La misma fontanería xterm.js + WebSocket que la <link>pestaña Terminal</link> independiente, incluyendo la <strong>barra para móvil</strong> con ESC, TAB, flechas, Enter y las combinaciones Ctrl (Ctrl+C / Ctrl+X / Ctrl+R) bajo el terminal — haciendo la modal usable desde el teclado de un móvil o tablet. Las VMs no exponen un botón Console aquí; usa la consola web de Proxmox (noVNC) para acceso al guest.",
"lifecycleIntro": "Debajo, cuatro botones de ciclo de vida en una rejilla 2×2. Cada uno dispara <code>POST /api/vms/&lt;vmid&gt;/control</code> con la <code>action</code> correspondiente; el estado de enabled depende de si el guest está actualmente en ejecución:",
"consoleItem": "<strong>Consola</strong>, solo para LXC en ejecución, abre <code>pct enter &lt;vmid&gt;</code> dentro del contenedor. Usa la misma conexión xterm.js y WebSocket que la <link>pestaña Terminal</link>, incluida la <strong>barra para móviles</strong> con ESC, TAB, flechas, Intro y Ctrl+C / Ctrl+X / Ctrl+R. Permite trabajar con móvil o tablet. Para VM usa la consola Proxmox noVNC.",
"lifecycleIntro": "Debajo hay cuatro botones en rejilla 2×2. Cada uno envía <code>POST /api/vms/&lt;vmid&gt;/control</code> con su <code>action</code>. Se habilitan según el estado actual del invitado.",
"headerButton": "Botón",
"headerEnabled": "Habilitado cuando",
"headerAction": "Acción enviada al host",
"lifecycleRows": [
{
"button": "Start",
"button": "Iniciar",
"color": "green",
"enabled": "El guest está parado.",
"action": "qm start / pct start"
},
{
"button": "Shutdown",
"button": "Apagar",
"color": "blue",
"enabled": "El guest está en ejecución.",
"action": "qm shutdown / pct shutdown — graceful, ACPI"
"enabled": "El invitado está en ejecución.",
"action": "qm shutdown / pct shutdown — apagado ordenado, ACPI"
},
{
"button": "Reboot",
"button": "Reiniciar",
"color": "blue",
"enabled": "El guest está en ejecución.",
"action": "qm reboot / pct reboot — reinicio graceful"
"enabled": "El invitado está en ejecución.",
"action": "qm reboot / pct reboot — reinicio ordenado"
},
{
"button": "Force Stop",
"button": "Forzar parada",
"color": "red",
"enabled": "El guest está en ejecución.",
"action": "qm stop / pct stop — apagado en duro"
"enabled": "El invitado está en ejecución.",
"action": "qm stop / pct stop — apagado forzado"
}
],
"forceStopTitle": "Force Stop es el kill switch, no la opción educada",
"forceStopBody": "<strong>Force Stop</strong> salta la secuencia de apagado del guest — equivalente a tirar del cable de la luz. Usa <strong>Shutdown</strong> cuando el guest responde; recurre a Force Stop solo cuando Shutdown se cuelga y aceptas el riesgo de pérdida de datos de un apagado no coordinado. El botón es rojo y está etiquetado a propósito para que no lo pulses por reflejo."
"forceStopTitle": "Forzar parada corta la ejecución inmediatamente",
"forceStopBody": "<strong>Forzar parada</strong> omite el apagado del invitado, como cortar la alimentación. Usa <strong>Apagar</strong> mientras responda. Fuerza la parada solo si el apagado se bloquea y aceptas el riesgo de perder datos. El botón rojo y su etiqueta ayudan a evitar pulsaciones accidentales."
},
"dataCollected": {
"heading": "Cómo se recopilan los datos",
@@ -186,9 +186,9 @@
"source": "Datos RRD de PVE (<code>pvesh get /nodes/&lt;node&gt;/qemu/&lt;id&gt;/rrddata</code>) condensados a una forma amigable para gráficas."
},
{
"section": "Logs recientes de tareas (modal)",
"endpoint": "/api/vms/<vmid>/logs",
"source": "Tareas para ese <code>vmid</code> desde <code>/var/log/pve/tasks/index</code>."
"section": "Log de consola OCI (pestaña Logs)",
"endpoint": "/api/lxc/<vmid>/console-log",
"source": "Salida de consola del proceso principal de la imagen, leída de <code>/var/log/proxmenux/oci/&lt;vmid&gt;.console.log</code> en el host. Solo para contenedores OCI."
},
{
"section": "Backups disponibles para el guest",
@@ -206,8 +206,8 @@
"source": "<code>qm start|stop|reboot|shutdown</code> o equivalentes <code>pct</code>."
}
],
"codeComment1": "# Cross-check de lo que ve el panel contra PVE",
"codeComment2": "# Inspeccionar la config de un guest concreto tal como la ve la modal",
"codeComment1": "# Contrastar los datos del panel con PVE",
"codeComment2": "# Inspeccionar la configuración de un invitado tal como la muestra la ventana",
"codeComment3": "# VM",
"codeComment4": "# CT"
},
@@ -217,7 +217,7 @@
{
"label": "Monitor de salud",
"href": "/docs/monitor/health-monitor",
"tailRich": " — la categoría VMs y Contenedores (boot fallido, timeouts QMP, fallos de shutdown de CT)."
"tailRich": " — categoría VMs y Contenedores: fallos de arranque, tiempos de espera QMP y errores de apagado CT."
},
{
"label": "Notificaciones",
@@ -227,7 +227,7 @@
{
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tailRich": " — los endpoints de VM y backup."
"tailRich": " — endpoints de VM y backups."
},
{
"label": "Índice del panel",
@@ -235,9 +235,9 @@
"tailRich": " — el resto de pestañas."
},
{
"label": "ProxMenux → Create VM",
"label": "ProxMenux → Crear VM",
"href": "/docs/create-vm",
"tailRich": " — la cara de provisión: plantillas de System NAS (Synology y otros), VMs Linux / Windows, valores por defecto pensados para Proxmox."
"tailRich": " — creación de sistemas: plantillas NAS (Synology y otros), VM Linux/Windows y valores adaptados a Proxmox."
}
]
}
@@ -1,7 +1,7 @@
{
"meta": {
"title": "Monitor de salud de Proxmox — CPU, memoria, almacenamiento, SMART, ZFS, logs | ProxMenux",
"description": "Monitorización proactiva de salud de Proxmox VE: diez categorías escaneadas cada cinco minutos (CPU y temperatura, memoria y swap, almacenamiento, discos/SMART, red, VMs, servicios, logs, actualizaciones, seguridad), cuatro niveles de severidad, duraciones de supresión por categoría, limpieza automática de errores resueltos, un historial permanente de observaciones de disco y el camino desde un evento crudo a una notificación a Telegram, Discord, Gotify o email.",
"description": "Supervisión proactiva de Proxmox VE: diez categorías cada cinco minutos (CPU y temperatura, memoria y swap, almacenamiento, discos/SMART, red, máquinas virtuales, servicios, registros, actualizaciones y seguridad), cuatro niveles de gravedad, silenciamiento por categoría, limpieza automática de errores resueltos, historial permanente de discos y notificaciones por Telegram, Discord, Gotify o correo.",
"ogTitle": "Monitor de salud de Proxmox — CPU, memoria, almacenamiento, SMART, ZFS, logs",
"ogDescription": "Monitorización proactiva de salud de Proxmox VE a través de diez categorías con niveles de severidad, duraciones de supresión y notificaciones dirigidas por eventos.",
"twitterTitle": "Monitor de salud de Proxmox | ProxMenux",
@@ -10,27 +10,27 @@
"header": {
"title": "Monitor de salud",
"description": "El auto-chequeo continuo que escanea diez categorías de estado del host en un ciclo de cinco minutos, muestrea signos vitales continuamente entre ciclos, deduplica hallazgos en un stream de eventos estructurado, y alimenta el panel, el motor de notificaciones y el reescritor opcional de IA desde una única fuente de verdad.",
"section": "ProxMenux Monitor"
"section": "Monitor de ProxMenux"
},
"intro": {
"title": "Un escáner, tres consumidores",
"body": "Un hilo de fondo ejecuta el ciclo completo de salud cada 5 minutos, persiste cada hallazgo en SQLite bajo un <code>error_key</code> estable, y deja que <strong>(1)</strong> el panel renderice el estado actual, <strong>(2)</strong> el motor de notificaciones reparta los eventos nuevos a los canales configurados y <strong>(3)</strong> el asistente opcional de IA reescriba las alertas en lenguaje natural. Configuras el escáner una vez; todo lo de aguas abajo se mantiene en sync."
"body": "Un hilo en segundo plano ejecuta el ciclo completo cada cinco minutos y guarda cada hallazgo en SQLite con un <code>error_key</code> estable. Así, <strong>(1)</strong> el panel muestra el estado actual, <strong>(2)</strong> el sistema de notificaciones distribuye los eventos nuevos a los canales configurados y <strong>(3)</strong> el asistente de IA opcional reformula las alertas en lenguaje sencillo. Configuras el análisis una vez y los componentes utilizan los mismos datos."
},
"howItWorks": {
"heading": "Cómo funciona",
"intro": "El Monitor de salud corre en dos carriles paralelos dentro del proceso del Monitor. Un <strong>muestreador de signos vitales</strong> ligero lee CPU, memoria y temperatura cada pocos segundos para que las condiciones de umbral sostenido se detecten rápido; en paralelo, el <strong>ciclo completo de salud</strong> corre cada cinco minutos y ejercita cada categoría de principio a fin. Ambos carriles convergen en las mismas tablas SQLite — y desde ahí, tres consumidores leen el estado independientemente.",
"intro": "El Monitor de salud usa dos hilos paralelos. Un <strong>muestreador de métricas</strong> ligero llena los historiales de CPU, memoria y temperatura. El <strong>ciclo completo de salud</strong> lee esos datos, evalúa las condiciones sostenidas y realiza las demás comprobaciones aproximadamente cada cinco minutos; después guarda los hallazgos en SQLite para el panel y las notificaciones.",
"scannerTitle": "Del muestreo al hallazgo guardado",
"scannerCaption": "El escáner. Los signos vitales se muestrean rápido para que la presión sostenida de CPU / memoria se detecte antes del siguiente ciclo de 5 min. El ciclo completo lee esos buffers y ejecuta los chequeos más pesados (SMART, estado de pool ZFS, escaneo de journal, salud de servicio, etc.) antes de escribir los hallazgos estructurados a SQLite.",
"scannerCaption": "El muestreador llena los historiales entre ciclos: CPU cada 5 s, memoria cada 30 s y temperatura cada 15 s. No evalúa las alertas. El ciclo completo evalúa esos datos y realiza las comprobaciones más pesadas (SMART, estado ZFS, registros y servicios) antes de guardar los hallazgos en SQLite.",
"scannerArrowLabel": "paso",
"scannerNodes": {
"samplerLabel": "Muestreador de signos vitales",
"samplerDetail": "Uso de CPU 30 s\nMemoria 30 s\nTemperatura 15 s\n→ buffers de historial",
"samplerDetail": "Uso de CPU 5 s\nMemoria 30 s\nTemperatura 15 s\n→ historiales",
"cycleLabel": "Ciclo completo de salud",
"cycleDetail": "Cada 5 min\nLee buffers\n+ probes en vivo\n(SMART, ZFS,\nservicios, journal…)",
"checksLabel": "Chequeos por categoría",
"checksDetail": "Diez categorías\n(CPU, memoria,\nalmacenamiento, discos,\nred, VMs,\nservicios, logs,\nactualizaciones, seguridad)",
"sqliteLabel": "SQLite",
"sqliteDetail": "tabla errors\n(activos +\ndismissed)\n+ disk_observations\n(historial\npermanente por disco)"
"sqliteDetail": "tabla errors\n(activas +\nsilenciadas)\n+ disk_observations\n(historial permanente\npor disco)"
},
"notifTitle": "Del hallazgo guardado al usuario",
"notifCaption": "El camino de la notificación. La misma tabla errors también dirige la vista del panel (listas Active / Dismissed renderizadas en vivo) y la consume la rutina de limpieza al final de cada ciclo para auto-resolver entradas obsoletas — ambas corren desde los mismos datos sin pasar por el dispatcher.",
@@ -43,7 +43,7 @@
"templatesLabel": "Templates + reescritura con IA",
"templatesDetail": "Template\npor evento\n→ reescritura\nopcional con IA\nen lenguaje natural",
"channelsLabel": "Canales",
"channelsDetail": "Telegram\nDiscord\nGotify\nEmail (SMTP)"
"channelsDetail": "Telegram\nDiscord\nGotify\nCorreo electrónico (SMTP)"
}
},
"categories": {
@@ -58,7 +58,7 @@
{
"category": "CPU y Temperatura",
"checks": "Uso de CPU con histéresis, temperatura de sensor",
"events": "Carga sostenida alta; temperatura de CPU cruzando los umbrales warning / critical del fabricante."
"events": "Uso elevado y sostenido de CPU; avisos de temperatura basados en las lecturas muestreadas."
},
{
"category": "Memoria y Swap",
@@ -68,7 +68,7 @@
{
"category": "Almacenamiento",
"checks": "Almacenamientos Proxmox, sistema de archivos raíz",
"events": "Almacenamiento offline (servidor NFS inalcanzable, credenciales CIFS caducadas); montaje raíz > 90 %; pool LVM thin cerca de lleno."
"events": "Uso de espacio por encima de los umbrales configurados en la raíz u otros sistemas de archivos supervisados (85% aviso / 95% crítico por defecto); almacenamientos PVE no disponibles; montajes NFS/CIFS bloqueados o en solo lectura inesperada; LVM-thin y otros almacenamientos de pool que superan los mismos umbrales."
},
{
"category": "Discos y SMART",
@@ -98,7 +98,7 @@
{
"category": "Actualizaciones del sistema",
"checks": "Actualizaciones pendientes, actualizaciones de seguridad, kernel / versión de PVE, antigüedad del sistema",
"events": "Actualizaciones de seguridad disponibles; kernel pinneado varias versiones menores por detrás; uptime del host > 90 días. Cuando hay actualizaciones pendientes, la cabecera de Overview muestra un botón <em>Update Now</em> que ejecuta el flujo completo de actualización de ProxMenux en línea; al cerrar vuelve a golpear el endpoint de health con <code>?refresh=1</code> para que el badge refleje el nuevo estado sin esperar al siguiente ciclo de 5 minutos."
"events": "Actualizaciones pendientes de seguridad o del kernel en uso; sistema sin actualizar desde hace mucho tiempo. Si hay actualizaciones, la categoría Actualizaciones de la ventana de estado de salud muestra <em>Actualizar ahora</em>. Ejecuta todo el proceso de actualización de ProxMenux; al cerrarlo, consulta el estado con <code>?refresh=1</code> para actualizar el indicador sin esperar al próximo ciclo."
},
{
"category": "Seguridad y Certificados",
@@ -141,7 +141,7 @@
],
"infoNote": "Una categoría que está <strong>OK</strong> pero tiene eventos dismissed todavía dentro de su ventana de supresión se renderiza como <strong>INFO</strong> — para recordarte que algo está siendo silenciado en vez de que nunca hubo nada mal.",
"unknownTitle": "UNKNOWN, cuando un chequeo no puede completar",
"unknownBody": "Un chequeo que falla en producir un veredicto durante tres ciclos seguidos (un probe que caduca, un sensor que ha desaparecido, una herramienta que sale con error) se registra internamente como <code>UNKNOWN</code>. El panel lo muestra como un estado amarillo — la vista global capa el <code>UNKNOWN</code> a <strong>WARNING</strong> para que nunca escale un host sano a CRITICAL por sí solo."
"unknownBody": "Una comprobación no disponible devuelve <code>UNKNOWN</code>; tras tres ciclos consecutivos así, se registra un hallazgo persistente. El panel muestra la comprobación en amarillo. El estado general limita <code>UNKNOWN</code> a <strong>WARNING</strong>: por sí sola, una comprobación no disponible no vuelve crítico al host."
},
"dashboardView": {
"heading": "La vista del panel",
@@ -150,7 +150,7 @@
"<strong>Active</strong> — cada categoría con un hallazgo sin resolver. Cada fila expande para mostrar los chequeos individuales que produjeron el estado, la cadena <code>reason</code> cruda, el dispositivo o VM ID involucrado, y (para categorías que enlazan a una pestaña) un click-through a Almacenamiento / Red / VMs / Logs / Hardware para investigar.",
"<strong>Dismissed</strong> — items previamente reconocidos por el usuario que aún están dentro de su ventana de supresión. Cada fila muestra cuánto queda de la supresión y la duración configurada. Cuando la ventana caduca, el item desaparece de esta lista; si la condición subyacente sigue presente y la categoría soporta re-firing, reaparece en <em>Active</em>."
],
"pillTitle": "La pildora refleja la peor categoría",
"pillTitle": "El indicador refleja la categoría más grave",
"pillBody": "El color de la cabecera del panel es la severidad más alta entre las diez categorías: cualquier CRITICAL → rojo, si no cualquier WARNING → amarillo, si no cualquier INFO → azul, si no verde. La misma lógica dirige el punto del favicon y el badge del PWA.",
"updateNowTitle": "Botón Update Now en la cabecera de Overview",
"updateNowBody1": "Cuando la categoría <em>Actualizaciones del sistema</em> reporta una o más actualizaciones pendientes, la cabecera de Overview renderiza un botón <strong>Update Now</strong> al lado de la pildora de salud. El botón abre una modal que ejecuta el mismo flujo del lado del host que <em>ProxMenux → Settings post-install Proxmox → Proxmox System Update</em>: higiene de repos, <code>apt full-upgrade</code> vía el worker seguro <code>update-pve-safe.sh</code>, recompilación DKMS automática de los drivers gestionados por ProxMenux cuando aterriza un kernel nuevo, autoremove / autoclean y prompt de reinicio si el kernel cambió. Las líneas de progreso van llegando a la modal según las va imprimiendo el worker.",
@@ -158,55 +158,55 @@
},
"dismiss": {
"heading": "Hacer dismiss de alertas y la Suppression Duration",
"intro": "Algunos eventos son ruidosos por naturaleza — un <em>System Updates: actualizaciones pendientes disponibles</em> permanece cierto hasta que parches el host, y no quieres una notificación cada cinco minutos durante una semana. El botón <em>Update Now</em> de la cabecera de Overview es el atajo directo para resolver ese caso concreto en sitio; para todo lo demás, o cuando el parche se aplaza, el Monitor de salud ofrece además dos mecanismos de silenciamiento acoplados:",
"step1": "<strong>Acción Dismiss por evento</strong> en el modal. El botón Dismiss abre un dropdown con tres opciones — <strong>24 horas</strong>, <strong>7 días</strong> o <strong>Permanently</strong> — que te permite elegir cuánto tiempo se silencia esta alerta concreta independientemente del valor por defecto de la categoría. Elegir una llama a <code>POST /api/health/acknowledge</code> con el <code>error_key</code> y el <code>suppression_hours</code> escogido (<code>-1</code> para permanente). El evento se mueve a la lista Dismissed con un <code>acknowledged_at</code> con timestamp.",
"dropdownImageAlt": "Dropdown de Dismiss sobre una alerta del Monitor de salud — 24 horas, 7 días o Permanently",
"dropdownImageCaption": "Dropdown Dismiss por evento. La ventana elegida aplica solo a esta alerta; si no eliges ninguna por evento se usa el valor por defecto de la categoría. Los dismisses permanentes se marcan con un badge ámbar distinto <em>Permanent</em> en la lista Dismissed y no se re-disparan.",
"intro": "Algunos eventos son ruidosos por naturaleza: <em>System Updates: actualizaciones pendientes disponibles</em> sigue activo hasta que actualices el host, y no quieres una notificación cada cinco minutos durante una semana. El botón <em>Actualizar ahora</em> de la categoría Actualizaciones de la ventana de estado de salud resuelve ese caso en el sitio; para todo lo demás, o si aplazas la actualización, el Monitor de salud ofrece además dos mecanismos de silenciado relacionados:",
"step1": "<strong>Descartar un evento</strong> desde su ventana. El botón ofrece <strong>24 horas</strong>, <strong>7 días</strong> o <strong>Permanentemente</strong>, independientemente del valor de la categoría. Envía <code>POST /api/health/acknowledge</code> con el <code>error_key</code> y las <code>suppression_hours</code> elegidas (<code>-1</code> para permanente). El evento pasa a Descartados con su fecha <code>acknowledged_at</code>.",
"dropdownImageAlt": "Menú para descartar una alerta: 24 horas, 7 días o permanentemente",
"dropdownImageCaption": "La duración elegida se aplica solo a esta alerta; sin una elección individual, se usa el valor de la categoría. Los descartes permanentes llevan una etiqueta ámbar <em>Permanente</em> y normalmente no reaparecen. La excepción de temperatura crítica de CPU se explica más abajo.",
"step2": "<strong>Ajuste de Suppression Duration por categoría</strong>. Desde la card Settings → Health Monitor (o <code>POST /api/health/settings</code>), cada una de las diez categorías tiene su propia ventana por defecto, aplicada cuando se hace un Dismiss sin elegir ventana por evento:",
"imageAlt": "Card Settings → Health Monitor con los dropdowns de supresión por categoría y la sección Active Suppressions",
"imageCaption": "Card Health Monitor — un dropdown por categoría fija los valores por defecto para nuevos dismisses; la sección Active Suppressions debajo lista todas las alertas actualmente silenciadas (ver más abajo).",
"imageCaption": "Un selector de duración por categoría. Elige una ventana mayor para eventos ruidosos, como actualizaciones pendientes, y menor para los que quieras reevaluar pronto. Debajo se muestran los silenciamientos activos.",
"outro": "Mientras un evento está suprimido, el escáner sigue corriendo y actualiza el timestamp <code>last_seen</code> de la fila, pero no se despacha ninguna notificación nueva y el panel se mantiene calmado. Cuando la ventana caduca, el siguiente ciclo reevalúa la condición y o bien re-dispara fresco o, si la condición se ha aclarado por sí sola, retira la fila de las listas.",
"activeSuppressionsTitle": "Revisar y revertir dismisses — el panel Active Suppressions",
"activeSuppressionsBody": "Cada alerta actualmente silenciada (time-limited y permanente) aparece en <strong>Settings → Health Monitor → Active Suppressions</strong>. Cada fila muestra el identificador de la alerta, categoría, severidad, cuándo se descartó y cuánto tiempo le queda, más un botón <strong>Re-enable</strong> que limpia el reconocimiento para que la alerta pueda volver a disparar en el próximo escaneo. Los dismisses permanentes solo se pueden revertir desde aquí; los time-limited también se pueden revivir a la fuerza sin esperar a la cuenta atrás. La acción Re-enable está protegida por el modo <em>Edit</em> del Health Monitor arriba de la card — pulsa Edit, haz clic en Re-enable en cada fila que quieras revivir (las filas en cola muestran un borde verde y el identificador tachado) y luego pulsa Save para confirmar. Cancel descarta la cola.",
"autoTitle": "Auto-supresión cuando cambias la Duration",
"activeSuppressionsBody": "Las alertas silenciadas, temporales o permanentes, aparecen en <strong>Ajustes → Monitor de salud → Silenciamientos activos</strong>. Cada fila muestra identificador, categoría, gravedad, fecha y tiempo restante. <strong>Reactivar</strong> quita la confirmación para permitir otra alerta en el próximo análisis. Los descartes permanentes se revierten desde aquí; los temporales también pueden reactivarse antes de tiempo. Activa el modo <em>Editar</em> de la tarjeta, pulsa Reactivar en las filas deseadas (quedan con borde verde y tachadas) y Guarda para aplicar. Cancelar vacía la selección.",
"autoTitle": "Silenciamiento automático al cambiar la duración",
"autoBody": "Poner una Suppression Duration de categoría a cualquier cosa distinta del valor por defecto de 24 h tiene un segundo efecto más allá de los dismissals iniciados por el usuario: <strong>los futuros hallazgos en esa categoría entran en la tabla ya reconocidos</strong> con esa duración. Esto es por diseño — si le has dicho al Monitor que quieres los eventos de disco silenciados durante una semana, los hallazgos de disco nuevos honran esa intención sin que tengas que hacer dismiss de cada uno a mano. Aparecen directamente en la lista Dismissed con el tiempo restante configurado. Las categorías dejadas en 24 h no se ven afectadas y se comportan de la forma clásica (los hallazgos nuevos aterrizan en Active hasta que actúes).",
"tempTitle": "La temperatura de CPU CRITICAL es el override de seguridad",
"tempBody": "Un hallazgo específico saltea la supresión por completo: <strong>temperatura de CPU CRITICAL</strong>. Si el sensor cruza el umbral crítico, la alerta re-dispara independientemente de cualquier dismissal previo — una CPU achicharrada es una CPU achicharrada. Este es el único override integrado del modelo de dismiss.",
"nonDismissableTitle": "Hallazgos a los que no se les puede hacer dismiss",
"nonDismissableBody": "Un puñado de hallazgos están marcados como no-descartables a propósito — señalan una condición donde silenciar la alerta podría costar datos, hardware o conectividad. El botón Dismiss está oculto para estas filas; la alerta se aclara solo cuando la condición subyacente se recupera y la limpieza auto-resolve la coge. Otros hallazgos (eventos I/O transitorios en un disco sano, estados recuperados) también están marcados no-descartables pero por la razón opuesta: no hay nada que silenciar porque la fila ya es informativa y se auto-aclara.",
"tempBody": "La persistencia incluye una regla especial para un registro <strong>Temperatura de CPU CRITICAL</strong>: si lo recibe, ignora la confirmación previa y el silenciamiento automático. Esto no significa que todos los comprobadores de temperatura emitan un registro crítico al superar un umbral configurado.",
"nonDismissableTitle": "¿Qué hallazgos pueden descartarse?",
"nonDismissableBody": "La ventana muestra Descartar solo si la comprobación devuelve explícitamente dismissable = true. Si el valor es falso o falta, oculta el botón. La gravedad no determina este permiso: varias comprobaciones críticas permiten la confirmación. Los ejemplos describen los datos actuales; silenciar una alerta no corrige su causa.",
"headerFinding": "Hallazgo",
"headerWhy": "Por qué no se puede hacer dismiss",
"headerWhy": "Comportamiento al descartar",
"rows": [
{
"finding": "Advertencia / crítico de temperatura de CPU",
"why": "Riesgo hardware — sobre-temperatura sostenida daña el silicio. Silenciar dejaría a una CPU achicharrándose pasar desapercibida."
"why": "El aviso de temperatura basado en muestras permite descartarse explícitamente. Una regla separada ignora la confirmación si llega un registro de temperatura de CPU con gravedad CRITICAL."
},
{
"finding": "Espacio crítico de filesystem (montaje raíz)",
"why": "Riesgo de pérdida de datos — un raíz lleno impide escrituras y corrompe estado. La alerta debe permanecer visible hasta que liberes espacio."
"why": "Las comprobaciones de espacio permiten descartarse, incluso con uso crítico. Confirmar la alerta no libera espacio ni elimina el riesgo de fallos de escritura."
},
{
"finding": "Pool ZFS DEGRADED / FAULTED",
"why": "Riesgo de integridad de datos — el fallo del pool amenaza cada dataset en él. Silenciar mientras el pool está enfermo nunca es la respuesta correcta."
"why": "Los hallazgos de estado del pool ZFS (DEGRADED, FAULTED, UNAVAIL) permiten descartarse, igual que las comprobaciones de capacidad del pool. Confirmar no repara un pool degradado o averiado."
},
{
"finding": "Errores I/O de disco con SMART FAILED",
"why": "Fallo de unidad confirmado por SMART — enmascarar oculta hardware real muriendo. La alerta se queda hasta que el dispositivo sea reemplazado (o eliminado del host)."
"why": "Los hallazgos de disco persistidos desde el journal pueden permitir descartarse. SMART FAILED sigue necesitando investigación; el botón depende del indicador de la comprobación, no solo del texto de la alerta."
},
{
"finding": "Interfaz de red DOWN",
"why": "Pérdida de conectividad — bridges, bonds e interfaces físicas con tráfico activo deben permanecer visibles. Silenciarlos enmascararía una pérdida de acceso remoto."
"why": "Las comprobaciones persistidas de interfaz DOWN permiten descartarse. Esto no restaura un bridge, un bond o un enlace físico, ni recupera el acceso remoto."
},
{
"finding": "Eventos I/O en discos sanos (INFO)",
"why": "Eventos ATA / dmesg transitorios en un disco cuyo SMART dice OK — marcado INFO y auto-aclarándose. Nada que descartar porque el siguiente ciclo ya los retira."
"why": "Los eventos ATA o dmesg transitorios con SMART sano pueden ser informativos y resolverse solos. Las filas informativas pueden no ofrecer Descartar; el comprobador decide cuándo se resuelve la condición."
}
],
"principle": "Todo lo demás se puede descartar. El principio es: alertas que indican \"daño real en progreso\" o que ya se han auto-resuelto se mantienen fuera del camino de dismiss; las alertas sobre condiciones sostenidas que puede que quieras reconocer y revisar más tarde (uso alto de CPU, actualizaciones pendientes, certificado cerca de caducar, warnings de log, hipos de arranque de VM, etc.) todas exponen el botón Dismiss."
"principle": "Usa el botón que muestre el hallazgo concreto; no deduzcas su disponibilidad por la categoría o gravedad. La confirmación controla la presentación y las notificaciones. Las comprobaciones de recuperación y el historial del disco son independientes."
},
"autoresolve": {
"heading": "Auto-resolución y limpieza",
"intro": "Muchas alertas deberían aclararse solas cuando la condición desaparece — una VM que estaba fallando al arrancar y ahora está corriendo, un disco que ya no está en el sistema, una temperatura que ha bajado a la normalidad. Una rutina de limpieza corre al final de cada ciclo de cinco minutos y aplica estas reglas:",
"intro": "Muchas alertas deben desaparecer cuando cesa la causa: una VM que ya arranca, un disco retirado o una temperatura que vuelve a la normalidad. La limpieza al final de cada ciclo de cinco minutos aplica estas reglas:",
"headerTrigger": "Disparador",
"headerAction": "Acción",
"rows": [
@@ -228,7 +228,7 @@
},
{
"trigger": "Hallazgos provenientes del journal (categoría <code>logs</code>, entradas SMART, errores ATA / I/O) cuando su ventana de supresión caduca.",
"action": "Retirados limpiamente. Cada scan inspecciona entradas frescas del journal desde ese punto en adelante; la misma línea histórica en el journal no se re-emite."
"action": "Se retiran. Cada análisis examina nuevas entradas del journal a partir de ese punto; la misma línea histórica no vuelve a emitirse."
},
{
"trigger": "Errores resueltos con más de siete días.",
@@ -236,27 +236,27 @@
}
],
"permanentTitle": "La supresión permanente no es lo mismo que resuelto",
"permanentBody": "Poner una Suppression Duration de categoría a <code>-1</code> (<em>permanente</em>) silencia alertas futuras para items que descartas en esa categoría — pero no salta el chequeo de auto-resolve de arriba. Si la condición subyacente desaparece (recurso borrado, umbral ya no rebasado), el item igualmente se limpia automáticamente."
"permanentBody": "Una duración por categoría de <code>-1</code> (<em>permanente</em>) silencia futuras alertas de los elementos descartados, pero no evita la comprobación automática anterior. Si desaparece la causa —recurso eliminado o umbral ya no superado—, el elemento sigue limpiándose automáticamente."
},
"observations": {
"heading": "Observaciones de disco — el historial permanente",
"intro": "Los eventos de disco son especiales. Un warning SMART en <code>/dev/sdh</code> a las 02:14 AM es algo que quieres recordar incluso después de que la tormenta I/O se calmase y el error se auto-resolviese — el disco tiene ahora un track record. Para ese propósito, el Monitor de salud guarda una tabla <strong>permanente</strong> aparte: <code>disk_observations</code>.",
"intro": "Los eventos de disco merecen conservarse. Un aviso SMART en <code>/dev/sdh</code> a las 02:14 sigue siendo relevante cuando termina la ráfaga de E/S y el error se resuelve solo: el disco ya tiene antecedentes. Por eso el Monitor de salud mantiene otra tabla <strong>permanente</strong>: <code>disk_observations</code>.",
"headerProperty": "Propiedad",
"headerErrors": "tabla <code>errors</code> (Active)",
"headerErrors": "Tabla <code>errors</code> (Activos)",
"headerObs": "tabla <code>disk_observations</code>",
"rows": [
{
"property": "Propósito",
"errors": "Dirige la vista <em>actual</em> de salud + despacho de notificaciones.",
"obs": "Audit trail permanente por disco."
"obs": "Registro de auditoría permanente por disco."
},
{
"property": "Auto-resolve",
"errors": "Sí — las filas se aclaran cuando la condición desaparece.",
"property": "Resolución automática",
"errors": "Sí: las filas se retiran cuando desaparece la causa.",
"obs": "No — las entradas persisten para siempre salvo que el usuario las descarte explícitamente."
},
{
"property": "Clave de dedup",
"property": "Clave de deduplicación",
"errors": "<code>error_key</code> (p. ej. <code>smart_sdh</code>).",
"obs": "<code>(disk_registry_id, error_type, error_signature)</code> con firmas estables despojadas de datos volátiles."
},
@@ -268,10 +268,10 @@
{
"property": "Qué registra",
"errors": "Lo que esté fallando actualmente.",
"obs": "Warnings SMART (problemas de sector / temperatura / CRC / self-tests fallidos), errores I/O (ATA / NVMe / dm), errores de filesystem, eventos de pool ZFS."
"obs": "Avisos SMART (sectores, temperatura, CRC o autopruebas fallidas), errores de E/S (ATA / NVMe / dm), errores del sistema de archivos y eventos de pools ZFS."
}
],
"outro": "Consecuencia práctica: una alerta puede aclararse del panel mientras el mismo incidente sigue registrado en el historial del disco. Cuando entras a un disco bajo Almacenamiento, la tarjeta muestra el conteo de observaciones pendientes y una lista con timestamps, severidad y el mensaje crudo original — útil cuando estás decidiendo si una unidad necesita reemplazo.",
"outro": "Una alerta puede desaparecer del panel mientras el incidente sigue registrado en el historial del disco. Al abrir el disco en Almacenamiento, su tarjeta muestra las observaciones pendientes con fecha, gravedad y mensaje original sin procesar. Esto ayuda a decidir si hay que sustituirlo.",
"renameTitle": "Los renombres entre dispositivos se fusionan automáticamente",
"renameBody": "Los discos a veces aparecen bajo nombres transitorios (<code>ata8</code>, <code>nvme0n1p3</code>) antes de conseguir un nombre estable de block-device. La capa de observaciones consolida entradas por número de serie cuando se conoce: si un evento se registró primero como <code>ata8</code> y el mismo disco se identifica más tarde como <code>sdh</code>, las observaciones históricas se reasocian a <code>sdh</code> en el siguiente ciclo para que el historial no se fragmente."
},
@@ -283,13 +283,13 @@
"Si el tipo de evento está <strong>activado</strong> en los ajustes globales de notificación, y el canal no ha silenciado esta categoría, se encola un evento.",
"El motor de templates renderiza un par (título, cuerpo) desde los detalles estructurados. Si el reescritor de IA está activado, el mismo par también pasa por el proveedor configurado para una versión en lenguaje natural.",
"La implementación del canal lo envía: mensaje de Telegram, embed de Discord, push de Gotify o email. El resultado del despacho se guarda en <code>notification_history</code>.",
"Si un dismiss llega más tarde, la ventana de supresión entra en juego y cualquier re-firing posterior del mismo <code>error_key</code> se queda en la cola hasta que la ventana cierre."
"Descartar una alerta inicia su ventana de silenciamiento. Durante ella, las nuevas detecciones del mismo <code>error_key</code> normalmente no generan notificaciones ni quedan en cola para enviarse al terminar. La regla de temperatura crítica de CPU sigue siendo una excepción."
],
"outro": "La configuración de canales (token de bot de Telegram, URLs de webhook, keys de proveedor de IA, toggles por evento, overrides por canal) está documentada en <notifLink>Notifications</notifLink> y <aiLink>Asistente de IA</aiLink>."
"outro": "La configuración de canales —token del bot Telegram, URLs de webhook, claves de IA, opciones por evento y ajustes por canal— se explica en <notifLink>Notificaciones</notifLink> y <aiLink>Asistente de IA</aiLink>."
},
"rest": {
"heading": "Endpoints REST",
"intro": "Todo lo que hace el modal se puede llamar desde la API — útil para scripts, paneles propios o tu propia integración de chat-bot. Cada llamada necesita un token de API; las que modifican algo — descartar una alerta, guardar los ajustes de supresión o limpiar huérfanos — requieren uno con scope full_admin, y un token read_only recibe 403.",
"intro": "Las acciones de la ventana están disponibles por API para scripts, paneles o bots. Las llamadas necesitan un token Bearer válido, obtenido al iniciar sesión o en la pantalla de tokens API. Los cambios, como confirmar alertas, guardar ajustes o limpiar errores huérfanos, exigen full_admin; read_only recibe 403.",
"headerEndpoint": "Endpoint",
"headerMethod": "Método",
"headerUse": "Uso",
@@ -297,7 +297,7 @@
{
"endpoint": "/api/health",
"method": "GET",
"use": "Probe pequeño de salud — devuelve JSON con <code>status</code>, <code>timestamp</code> y <code>version</code>. Adecuado para keyword checks de Uptime Kuma; el receptor debe enviar la cabecera bearer."
"use": "Comprobación ligera que devuelve JSON con <code>status</code>, <code>timestamp</code> y <code>version</code>. Sirve para comprobar palabras clave con Uptime Kuma; el cliente debe enviar una cabecera Bearer."
},
{
"endpoint": "/api/health/status",
@@ -312,27 +312,27 @@
{
"endpoint": "/api/health/full",
"method": "GET",
"use": "Snapshot completo — categorías + errores activos + lista de dismissed + ajustes de supresión personalizados. Alimenta el modal en un round-trip y usa una caché de fondo de 6 min para respuesta instantánea."
"use": "Vista completa: categorías, errores activos, descartados y ajustes de silenciamiento. Alimenta la ventana con una sola petición y usa una caché en segundo plano de seis minutos para responder rápidamente."
},
{
"endpoint": "/api/health/active-errors",
"method": "GET",
"use": "Solo la lista Active. Filtrable por <code>?category=&lt;name&gt;</code>."
"use": "Solo la lista Activos. Admite el filtro <code>?category=&lt;name&gt;</code>."
},
{
"endpoint": "/api/health/dismissed",
"method": "GET",
"use": "Solo la lista Dismissed, con las horas de supresión restantes."
"use": "Solo la lista Descartados, con las horas restantes de silenciamiento."
},
{
"endpoint": "/api/health/acknowledge",
"method": "POST",
"use": "Body: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Descarta una alerta con la ventana configurada de la categoría."
"use": "Cuerpo: <code>'{'\"error_key\":\"smart_sdh\"'}'</code>. Descarta una alerta durante el plazo configurado para su categoría."
},
{
"endpoint": "/api/health/settings",
"method": "GET / POST",
"use": "Lee o escribe los valores de Suppression Duration por categoría."
"use": "Lee o guarda la duración del silenciamiento por categoría."
},
{
"endpoint": "/api/health/cleanup-orphans",
@@ -348,14 +348,14 @@
"heading": "Por dónde seguir",
"items": [
{
"label": "Dashboard",
"label": "Panel",
"href": "/docs/monitor/dashboard",
"tail": " — desde donde se abre el modal del Monitor de salud en la UI."
},
{
"label": "Notifications",
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tail": " — canales, toggles por evento, el hook de reescritura con IA, historial."
"tail": " — canales, opciones por evento, integración de la reformulación IA e historial."
},
{
"label": "Asistente de IA",
+23 -23
View File
@@ -27,7 +27,7 @@
"tableWhat": "Qué muestra",
"sections": [
{
"name": "Health Monitor",
"name": "Monitor de salud",
"description": "Alertas activas y descartadas para CPU, memoria, almacenamiento, discos, red, servicios, logs, VMs, actualizaciones y seguridad. Alimenta el motor de notificaciones."
},
{
@@ -40,7 +40,7 @@
},
{
"name": "VMs y contenedores",
"description": "Inventario de todas las VMs y LXCs con estado, recursos y uptime. El detalle muestra config, métricas históricas, logs completos del guest y acciones de start/stop/reboot/shutdown."
"description": "Inventario de VM y LXC con estado, recursos y tiempo de actividad. El detalle muestra configuración, métricas históricas, descarga de registros de Proxmox y acciones de iniciar/parar/reiniciar/apagar. Los registros dependen del endpoint de Proxmox; no es un archivo completo del sistema invitado."
},
{
"name": "Hardware",
@@ -52,37 +52,37 @@
},
{
"name": "Terminal",
"description": "Shell en el navegador hacia el host o cualquier VM/CT, mediante <code>xterm.js</code> sobre WebSockets. Autenticado y auditado igual que el resto de la API."
"description": "Shell del host y acceso a consolas VM/CT compatibles en el navegador mediante <code>xterm.js</code> y WebSockets. Las sesiones no se auditan comando a comando."
},
{
"name": "Seguridad",
"description": "Fallos de autenticación, estado de jails de Fail2Ban, eventos de bloqueo recientes, integración con el jail <code>[proxmenux]</code> del host."
"description": "Fallos de autenticación, estado de las jails de Fail2Ban, bloqueos recientes e integración con la jail <code>[proxmenux]</code> del host."
}
],
"footer": "Cada sección tiene su propia página de documentación bajo <link>Dashboard</link> en la barra lateral."
"footer": "Cada sección tiene documentación propia bajo <link>Panel</link> en la barra lateral."
},
"howItRuns": {
"heading": "Cómo se ejecuta",
"intro": "ProxMenux Monitor se distribuye como un AppImage autocontenido. Una única unidad systemd (<code>proxmenux-monitor.service</code>) arranca un proceso Flask que:",
"intro": "ProxMenux Monitor se distribuye como una AppImage autónoma. Una única unidad de systemd (<code>proxmenux-monitor.service</code>) inicia un proceso de Flask que:",
"bullets": [
"Escucha en <strong>TCP 8008</strong> en el host (HTTP).",
"Sirve el panel Next.js como activos estáticos bajo <code>/</code> y la API bajo <code>/api/*</code> desde el mismo proceso.",
"Obtiene datos en vivo con herramientas estándar del host: <code>psutil</code>, <code>pvesh</code>, <code>smartctl</code>, <code>journalctl</code>, <code>zpool</code>, <code>ip</code>, <code>nvidia-smi</code>, etc.",
"Persiste su propio estado en una base de datos SQLite local (<code>/usr/local/share/proxmenux/health_monitor.db</code>): alertas descartadas, observaciones de discos, configuración de notificaciones, configuración de IA. El estado de autenticación vive aparte en <code>/root/.config/proxmenux-monitor/auth.json</code>."
],
"footer": "El flujo completo de petición, la disposición de archivos y la integración systemd se describen en <link>Architecture</link>."
"footer": "El flujo de peticiones, la estructura de archivos y la integración systemd se describen en <link>Arquitectura</link>."
},
"noAgent": {
"title": "Sin agente en los guests",
"body": "El Monitor lee todo desde el host. Las VMs y CTs no necesitan ningún agente instalado — los datos del guest provienen de la API de Proxmox y de la visibilidad a nivel de kernel del propio host sobre los guests en ejecución."
"body": "El Monitor obtiene los datos desde el host. No hace falta instalar un agente en las VM ni en los CT: los datos proceden de la API de Proxmox y de la información que el kernel del host ofrece sobre los invitados en ejecución."
},
"access": {
"heading": "Acceder al panel",
"intro": "Se soportan dos patrones de acceso y la aplicación detecta cuál está en uso:",
"codeComment1": "# 1) Acceso directo al host",
"codeComment2": "# 2) Mediante proxy inverso (Nginx / Caddy / Traefik)",
"afterCode": "Cuando hay un proxy inverso por delante, el Monitor respeta <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> y <code>X-Forwarded-Host</code> para que las URLs y CORS funcionen correctamente sin configuración manual.",
"footer": "La configuración inicial, contraseña + TOTP 2FA y snippets de proxy inverso se cubren en <link>Access & Authentication</link>."
"afterCode": "El proxy inverso debe configurar <code>X-Forwarded-For</code>, <code>X-Forwarded-Proto</code> y <code>X-Forwarded-Host</code> correctamente y permitir WebSockets. En puertos estándar el navegador usa su origen actual. El backend solo confía en direcciones reenviadas con PROXMENUX_TRUST_PROXY=1 explícito; restringe su acceso directo si activas esa confianza.",
"footer": "La configuración inicial, contraseña + TOTP 2FA y ejemplos de proxy inverso se explican en <link>Acceso y autenticación</link>."
},
"mobile": {
"heading": "Uso móvil e instalación en la pantalla de inicio",
@@ -95,8 +95,8 @@
"androidLabel": "Android Chrome / Edge:",
"androidBody": "menú de tres puntos → <em>Instalar app</em> (o <em>Añadir a pantalla de inicio</em> en versiones antiguas).",
"afterInstall": "Una vez instalado, abrir el icono lanza el panel en modo standalone con su propia entrada en el conmutador de tareas.",
"onlineOnlyTitle": "Solo online",
"onlineOnlyBody": "La PWA es instalable pero <strong>no</strong> funciona sin conexión — no hay service worker. El lanzador se comporta como una app nativa, pero el dispositivo necesita poder llegar al host en TCP 8008 (LAN, VPN o HTTPS tras proxy inverso) para que el panel cargue."
"onlineOnlyTitle": "Requiere conexión",
"onlineOnlyBody": "La PWA se puede instalar, pero <strong>no</strong> funciona sin conexión: no incluye un service worker. El acceso directo se comporta como una aplicación nativa, pero el dispositivo debe poder conectar con el host por TCP 8008 (mediante LAN, VPN o HTTPS a través de un proxy inverso) para cargar el panel."
},
"health": {
"heading": "El Health Monitor y las notificaciones",
@@ -112,38 +112,38 @@
},
"api": {
"heading": "API REST e integraciones",
"intro": "Todo lo que muestra la interfaz está disponible como JSON sobre HTTP/HTTPS. Los mismos endpoints alimentan widgets de Homepage, sensores de Home Assistant, dashboards de Grafana (vía el exporter Prometheus en <code>/api/prometheus</code>), pruebas de Uptime Kuma y cualquier script personalizado que hable <code>curl</code>.",
"tokens": "Los tokens API de larga duración (365 días) se generan desde <strong>Settings → API Access Tokens</strong> o vía <code>POST /api/auth/generate-api-token</code>.",
"bearer": "Los tokens viajan como <code>Authorization: Bearer …</code>. Los endpoints públicos (<code>/api/health</code>, <code>/api/auth/*</code>) funcionan sin token para que las pruebas externas de uptime puedan llegar al host sin entregar credenciales.",
"catalog": "El catálogo completo de endpoints, la guía de rotación de tokens y las buenas prácticas de seguridad viven en <linkApi>API Reference</linkApi>; los ejemplos listos para Homepage, Home Assistant, Grafana, Uptime Kuma y un patrón genérico de cURL están en <linkIntegrations>Integrations</linkIntegrations>."
"intro": "Los endpoints REST ofrecen datos de monitorización JSON por HTTP/HTTPS para widgets Homepage, sensores Home Assistant, pruebas Uptime Kuma y scripts. Grafana puede usar el exportador de texto Prometheus en <code>/api/prometheus</code>. Las peticiones se pueden hacer con <code>curl</code>.",
"tokens": "Los tokens API de larga duración (365 días) se generan en <strong>Configuración → Tokens de acceso API</strong> o mediante <code>POST /api/auth/generate-api-token</code>.",
"bearer": "Envía tokens con <code>Authorization: Bearer …</code>. <code>/api/health</code> también espera la cabecera Bearer, así que las pruebas de disponibilidad necesitan un token read_only. Bajo <code>/api/auth/*</code> hay rutas públicas de configuración/inicio/estado y rutas protegidas de cuentas y tokens; no todas son anónimas.",
"catalog": "El catálogo de endpoints, rotación de tokens y prácticas de seguridad están en <linkApi>Referencia de la API</linkApi>. Los ejemplos para Homepage, Home Assistant, Grafana, Uptime Kuma y cURL están en <linkIntegrations>Integraciones</linkIntegrations>."
},
"serviceControl": {
"heading": "Control del servicio",
"intro": "Día a día, el Monitor se gestiona exactamente como cualquier otro servicio systemd. También está expuesto como dos entradas dentro del TUI de ProxMenux bajo <em>Settings</em>:",
"intro": "Monitor se gestiona como cualquier servicio systemd. También tiene dos entradas en la interfaz de texto ProxMenux bajo <em>Configuración</em>:",
"codeComment": "# Control manual",
"footer": "Mira <link>Settings → ProxMenux Monitor</link> para el conmutador del menú y el flujo de verificación de estado."
"footer": "Consulta <link>Configuración → ProxMenux Monitor</link> para activar/desactivar el servicio y verificar su estado."
},
"nextSteps": {
"heading": "A dónde ir ahora",
"items": [
{
"label": "Architecture",
"label": "Arquitectura",
"description": "— backend Flask, unidad systemd, esquema SQLite, proveedores IA, canales de notificación."
},
{
"label": "Access & Authentication",
"label": "Acceso y autenticación",
"description": "— primer arranque, configuración de contraseña, TOTP 2FA, configuración de proxy inverso, integración con Fail2Ban."
},
{
"label": "Dashboard",
"label": "Panel",
"description": "— cada sección de la interfaz, una página por cada una."
},
{
"label": "API Reference",
"label": "Referencia de la API",
"description": "— cada endpoint, forma de petición / respuesta y gestión de tokens."
},
{
"label": "Integrations",
"label": "Integraciones",
"description": "— Homepage, Home Assistant, Grafana / Prometheus, Uptime Kuma, patrón genérico de cURL."
}
]
+40 -40
View File
@@ -10,21 +10,21 @@
"header": {
"title": "Integraciones",
"description": "Guías copia-pega para conectar ProxMenux Monitor en los paneles y herramientas que tu homelab ya usa — Homepage, Home Assistant, Grafana vía Prometheus, Uptime Kuma. Cada guía muestra la configuración exacta que espera la herramienta receptora, el endpoint del Monitor con el que habla y el patrón de cabecera de auth que lo une todo.",
"section": "ProxMenux Monitor"
"section": "Monitor de ProxMenux"
},
"intro": {
"title": "Qué puedes construir desde esta página",
"body": "Cada guía de abajo está lista para copiar a tu herramienta elegida. Los endpoints de la API usados aquí están documentados en la <link>API Reference</link> — esta página es el compañero \"cómo usarlos realmente en Homepage / Home Assistant / Grafana\". Las capturas muestran la salida real que verás una vez la guía esté en su sitio."
"body": "Copia cada ejemplo en la herramienta correspondiente. Los endpoints están documentados en la <link>Referencia de la API</link>; esta página explica cómo utilizarlos en Homepage, Home Assistant y Grafana. Las capturas muestran el resultado de esas configuraciones."
},
"auth": {
"heading": "Autenticación: lo único que cada guía necesita",
"intro": "La mayoría de los endpoints usados por estas integraciones están autenticados. Tienes dos formas de satisfacer ese requisito.",
"optAtitle": "Opción A — API token (recomendado para integraciones)",
"optAbody1": "Abre el panel y ve a <strong>Settings → Security → API Tokens</strong>. Pulsa <em>Generate token</em>, dale un nombre (p. ej. <em>homepage</em>, <em>home-assistant</em>, <em>prometheus</em>), y copia el token — se muestra <em>una vez</em>. De larga duración (un año de expiración por defecto), revocable individualmente, y lo que deberías usar para cualquier cliente no-navegador.",
"optAbody1": "Entra en <strong>Ajustes → Seguridad → Tokens API</strong>. Pulsa <em>Generar token</em>, ponle un nombre, como <em>homepage</em>, <em>home-assistant</em> o <em>prometheus</em>, y cópialo: se muestra <em>una sola vez</em>. Caduca al año por defecto y puede revocarse individualmente. Úsalo para los clientes externos al navegador.",
"optAbody2": "A partir de ahí cada petición es simplemente:",
"optBtitle": "Opción B — flujo de login (usuario + contraseña)",
"optBbody": "Útil para scripts que se autentican como un usuario humano. El token devuelto es de corta duración; la mayoría de integraciones deberían preferir la Opción A.",
"outro": "El campo TOTP solo es requerido cuando el 2FA está activado en la cuenta. La rotación de tokens, la revocación, la política de contraseñas y el log de auditoría viven en <link>Access & Authentication</link>.",
"outro": "El campo TOTP solo hace falta con la autenticación en dos pasos activada. La rotación y revocación de tokens, la política de contraseñas y el registro de auditoría se explican en <link>Acceso y autenticación</link>.",
"httpsTitle": "Usando HTTPS en lugar de HTTP",
"httpsIntro": "Cada guía de abajo usa <code>http://</code> en las URLs para mantener los ejemplos cortos. Si has activado TLS en el Monitor (<strong>Settings → Security → SSL/HTTPS</strong>), cambia <code>http://</code> por <code>https://</code> en cada URL — ese es el único cambio. Dos notas específicas para ciertas herramientas:",
"httpsItems": [
@@ -48,16 +48,16 @@
"multiTitle": "Setup multi-widget — sistema, almacenamiento, red",
"multiIntro": "Para una vista más rica, renderiza tres tarjetas separadas respaldadas por distintos endpoints — una para métricas del sistema, una para almacenamiento, una para red. Usa el mismo token en cada tarjeta; es la misma instancia del Monitor.",
"multiCalloutTitle": "Múltiples hosts Proxmox",
"multiCalloutBody": "Repite el bloque de entrada por host para obtener el layout multi-tarjeta de la captura de arriba — cada entrada apunta a la URL <code>http://&lt;host&gt;:8008</code> de su propia instancia de ProxMenux Monitor. El token puede ser distinto por host (una entrada secret por host) o compartido, según cómo los generes."
"multiCalloutBody": "Repite el bloque para cada host y obtendrás las tarjetas de la captura. Cada entrada usa la URL <code>http://&lt;host&gt;:8008</code> de su propia instancia. Genera y guarda un token por host: cada instalación tiene su clave de firma y no debes asumir que el token de otra funcione."
},
"homeAssistant": {
"heading": "Home Assistant",
"headingHref": "https://www.home-assistant.io",
"intro": "No hay una integración HACS nativa para ProxMenux Monitor (todavía) — pero no la necesitas. La integración <code>rest</code> integrada en Home Assistant puede consumir cada endpoint documentado en la <link>API Reference</link> y convertir las respuestas en sensores, atributos y triggers. El build de referencia completo de abajo expone ~25 sensores cubriendo recursos del sistema, el Monitor de salud, VMs / CTs, almacenamiento, red, latencia al gateway y estado de actualización de ProxMenux — pega el YAML en <code>configuration.yaml</code>, reinicia y tienes una capa completa de observabilidad de Proxmox dentro de HA.",
"intro": "Estos ejemplos usan la integración <code>rest</code> de Home Assistant y no necesitan un componente HACS propio. Leen endpoints del Monitor descritos en la <link>Referencia de la API</link> y convierten sus respuestas en sensores y atributos para automatizaciones. La configuración ofrece unos 25 sensores de recursos, salud, VMs/CTs, almacenamiento, red y actualizaciones. Añádela a <code>configuration.yaml</code> y recarga o reinicia HA.",
"imageAlt": "Panel Home Assistant mostrando entidades de ProxMenux Monitor — badge de estado de salud, gauges de CPU / RAM / Temp, contador de VMs, uso de almacenamiento y contador de errores activos",
"imageCaption": "ProxMenux Monitor como integración de primera clase en Home Assistant — sensores construidos desde la guía YAML de abajo.",
"step1Title": "1 · Guarda el API token",
"step1Body": "Mete el token en el <code>secrets.yaml</code> de Home Assistant para que nunca se filtre en un volcado de config. El prefijo bearer entero va en una línea — eso permite al YAML referenciarlo directamente como valor de cabecera. El nombre y ubicación del archivo depende de tu instalación de HA (típicamente <code>/config/secrets.yaml</code> para HA OS / Container).",
"step1Body": "Guarda el token en <code>secrets.yaml</code> para separarlo de la configuración principal. Incluye el prefijo Bearer y el token en un único valor para usarlo como cabecera. El archivo no está cifrado y también debe mantenerse privado. Su ubicación depende de la instalación; normalmente es <code>/config/secrets.yaml</code> en HA OS o Container.",
"step2Title": "2 · Añade la configuración REST",
"step2Body": "Seis bloques REST cubren toda la superficie — uno por área principal del Monitor. Cada bloque tiene un <code>scan_interval</code> sensato ajustado a cuán a menudo cambian los datos subyacentes (recursos del sistema cada 30 s, salud cada 60 s, inventarios que cambian despacio cada 5-10 min). Pega en <code>configuration.yaml</code>:",
"step3Title": "3 · Añade sensores binarios y helpers de template",
@@ -65,21 +65,21 @@
"step4Title": "4 · Recarga y verifica",
"step4Body": "Desde la UI de HA: <em>Developer Tools → YAML → Check Configuration</em> primero para validar la sintaxis, luego recarga <em>All YAML configuration</em> (o reinicia completo). Después de que vuelva, filtra <em>Settings → Devices & Services → Entities</em> por <em>proxmenux</em> — deberías ver las ~25 entidades llenándose dentro de un intervalo de scan.",
"replaceTitle": "¿Reemplazando una versión anterior de esta guía?",
"replaceBody": "Si probaste una versión previa de estos bloques YAML, el registro de entidades de Home Assistant puede haber cacheado los IDs de entidad viejos y entidades obsoletas seguirán apareciendo (con warnings <em>Entidad no encontrada</em> en tus tarjetas Lovelace). Estado limpio en dos pasos: borra los bloques <code>rest:</code> y <code>template:</code> previos de <code>configuration.yaml</code>, recarga, y luego bajo <em>Settings → Devices & Services → Entities</em> filtra por <em>proxmenux</em> y quita cualquier entrada marcada como \"Restored\" o mostrada como indisponible. Luego pega el YAML actual y recarga de nuevo — las entidades nuevas se registran limpiamente.",
"replaceBody": "Si usaste una versión anterior, el registro de entidades puede conservar IDs obsoletos y las tarjetas mostrar <em>Entidad no encontrada</em>. Quita los bloques anteriores <code>rest:</code> y <code>template:</code> de <code>configuration.yaml</code> y recarga. En <em>Ajustes → Dispositivos y servicios → Entidades</em>, filtra por <em>proxmenux</em> y elimina las entradas antiguas restauradas o no disponibles. Añade después el YAML actual y recarga para registrar las nuevas.",
"step5Title": "5 · Panel Lovelace",
"step5Body": "El YAML de abajo es una única tarjeta <strong>vertical-stack</strong> que combina todas las sub-tarjetas en un bloque — cabecera con logo, KPIs rápidos, detalle del sistema, VMs, almacenamiento, red y una tarjeta condicional de problemas de salud. Para usarla: abre tu panel, pulsa el lápiz (editar), pulsa <em>Add card</em>, baja al final y elige <em>Manual</em>, luego pega:",
"viewTipTitle": "¿Lo quieres como vista completa de panel en lugar de una sola tarjeta?",
"viewTipBody": "Abre el menú de 3 puntos del panel → <em>Raw configuration editor</em> y añade una vista nueva con esta cabecera (encima de la lista <code>cards:</code> del YAML de arriba):",
"viewTipOutro": "Eso te da una pestaña/vista dedicada en tu panel con su propio icono y título, en vez de una tarjeta larga en una vista existente.",
"altViewTitle": "Alternativa — una vista de panel dedicada",
"altViewIntro": "Si prefieres tener una página dedicada completa (su propia pestaña en la barra lateral del panel) en vez de una tarjeta dentro de una vista existente, Home Assistant te deja crear una vista nueva directamente con YAML. Pasos:",
"altViewIntro": "Para crear una pestaña propia dentro de un panel existente, añade una vista con el YAML de abajo. Una vista es una pestaña del panel; no crea una entrada nueva en la barra lateral. Pasos:",
"altViewSteps": [
"Abre el panel donde quieres la nueva pestaña.",
"Pulsa el lápiz (editar panel) arriba a la derecha.",
"Pulsa la pestaña <em>+</em> al final de las pestañas existentes para crear una vista nueva.",
"En el diálogo que se abre, cambia a la pestaña <em>Code editor</em> (arriba a la derecha del diálogo — alterna entre editor visual y YAML).",
"Pega el YAML de abajo.",
"Guarda. La nueva pestaña <em>ProxMenux Monitor</em> aparece en la barra lateral con todas las tarjetas renderizadas."
"Guarda. La vista <em>ProxMenux Monitor</em> aparece como pestaña dentro del panel con sus tarjetas."
],
"twoEditorsTitle": "Dos editores YAML en HA — elige el correcto",
"twoEditorsIntro": "Home Assistant tiene dos editores YAML que parecen similares pero esperan formatos distintos:",
@@ -89,7 +89,7 @@
],
"twoEditorsOutro": "Pegar YAML de cuerpo de vista en el editor de panel entero (o viceversa) te deja con una <em>Vista sin nombre</em> y <code>cards: []</code>. El YAML de abajo es para el editor de una sola vista — pega exactamente como se muestra.",
"viewImageAlt": "Vista dedicada de Home Assistant renderizando ProxMenux Monitor — cabecera picture-entity, KPIs glance y tarjetas de entidad Sistema / VMs / Almacenamiento / Red distribuidas automáticamente por HA en múltiples columnas",
"viewImageCaption": "La vista dedicada <em>ProxMenux Monitor</em> como la renderiza Home Assistant en una pantalla ancha — el layout por defecto de HA divide las tarjetas en múltiples columnas automáticamente.",
"viewImageCaption": "La vista <em>ProxMenux Monitor</em> en pantalla ancha. La disposición Masonry distribuye las tarjetas automáticamente en columnas; el resultado depende del tipo de vista configurado.",
"twoColTipTitle": "¿Quieres un layout fijo de dos columnas en lugar del auto layout?",
"twoColTipBody": "Reemplaza cualquier par de tarjetas (p. ej. <em>Sistema</em> + <em>VMs</em>, o <em>Almacenamiento</em> + <em>Red</em>) con un único <code>horizontal-stack</code> envolviendo ambas, para que siempre se rendericen lado a lado independientemente del ancho de pantalla:",
"twoColTipOutro": "En móvil la fila se mantiene comprimida; el auto layout de HA (sin horizontal-stack) refluye mejor a anchos estrechos.",
@@ -105,28 +105,28 @@
"En el YAML Lovelace, reemplaza la URL <code>image:</code> por <code>/local/icons/proxmenux.svg</code>. Guarda y recarga — la imagen se renderiza desde el archivo local, sin internet necesaria."
],
"scanTipTitle": "Regla práctica para scan_interval",
"scanTipBody": "<code>/api/system</code> es barato de llamar — 30 s está bien. <code>/api/health/full</code> usa una caché interna de 6 min, así que hacer polling más a menudo de ~60 s no te aporta nada. <code>/api/storage/summary</code> cambia despacio — cada 5 min sobra. <code>/api/proxmenux/update-status</code> solo importa una vez por hora. Ajusta a tu presupuesto de hardware si tienes muchos sensores en muchos hosts."
"scanTipBody": "Un punto de partida razonable es consultar <code>/api/system</code> cada 30 s. <code>/api/health/full</code> suele leer datos en caché válidos hasta seis minutos; consultarlo cada 60 s no evita esa caché. Prueba cinco minutos para <code>/api/storage/summary</code> y una hora para <code>/api/proxmenux/update-status</code>. Ajusta los intervalos a tu hardware y número de hosts."
},
"grafana": {
"heading": "Prometheus + Grafana",
"promHref": "https://prometheus.io",
"grafanaHref": "https://grafana.com",
"intro": "ProxMenux Monitor expone un endpoint de scrape formato Prometheus en <code>GET /api/prometheus</code> (autenticado) devolviendo texto OpenMetrics. Cabléalo a Prometheus, luego construye un panel Grafana encima — los mismos datos que muestra la UI del panel, en el formato que tu TSDB espera.",
"intro": "ProxMenux Monitor expone <code>GET /api/prometheus</code> con formato de exposición de texto Prometheus 0.0.4. Necesita un token Bearer si la autenticación está activada. Configura Prometheus para recoger las métricas y Grafana para visualizar la base de datos de series temporales.",
"imageAlt": "Panel Grafana renderizando métricas de ProxMenux Monitor — gauge de uso de CPU, timeseries de uso de memoria, contador de VMs en ejecución, throughput de red",
"imageCaption": "Un panel Grafana básico construido desde el scrape Prometheus de ProxMenux — CPU, memoria, VMs en ejecución, throughput de red. El catálogo completo de métricas vive en la <link>API Reference → Métricas Prometheus</link>.",
"step1Title": "1 · Añade el job de scrape a Prometheus",
"step1Body": "Pasa el API token vía el bloque nativo <code>authorization</code> de Prometheus (más limpio que cabeceras personalizadas y funciona con secret stores):",
"step1After": "Recarga Prometheus (<code>kill -HUP</code> o <code>systemctl reload prometheus</code>, o <code>docker compose restart prometheus</code> si lo corres como contenedor) y comprueba <em>Status → Targets</em> — el job proxmenux debería ponerse verde dentro de un intervalo de scrape. Cada métrica lleva una etiqueta <code>node=\"&lt;hostname&gt;\"</code> para que puedas distinguir hosts en las queries.",
"tokenTipTitle": "Token vía archivo o env, no inline",
"step1After": "Recarga Prometheus con <code>kill -HUP &lt;PID&gt;</code> (sustituye PID por su ID de proceso), <code>systemctl reload prometheus</code> si el servicio lo permite o <code>docker compose restart prometheus</code> para el contenedor. Revisa <em>Status → Targets</em>: el job proxmenux debería pasar a UP en un intervalo de recogida. Las métricas llevan <code>node=\"&lt;hostname&gt;\"</code> para distinguir los hosts.",
"tokenTipTitle": "Guarda el token en un archivo separado",
"tokenTipBody": "Para despliegues en producción evita poner el token inline. Prometheus soporta <code>credentials_file: /etc/prometheus/secrets/proxmenux.token</code> como alternativa — guarda el token en un archivo 0600 y deja que Prometheus lo lea.",
"step2Title": "2 · Verifica el scrape con un par de queries",
"step2Body": "Antes de configurar Grafana, confirma que Prometheus realmente tiene los datos. Abre la propia UI de Prometheus en <code>http://&lt;prometheus-host&gt;:9090</code>, pulsa <em>Query</em> y ejecuta cualquiera de estas — deberías obtener números en vivo de tu host Proxmox:",
"headerQuery": "Query",
"headerQuery": "Consulta",
"headerConfirms": "Qué confirma",
"verifyRows": [
{
"query": "up{job=\"proxmenux\"}",
"confirms": "Devuelve <code>1</code> si Prometheus está haciendo scrape del Monitor con éxito, <code>0</code> si no. La comprobación de cordura más rápida."
"confirms": "Devuelve <code>1</code> si Prometheus recoge datos del Monitor correctamente y <code>0</code> si falla. Es la comprobación inicial más rápida."
},
{
"query": "proxmox_cpu_usage",
@@ -134,7 +134,7 @@
},
{
"query": "proxmox_vms_running",
"confirms": "Número de guests en ejecución. Compara con lo que ves en la UI de Proxmox."
"confirms": "Número de máquinas invitadas en ejecución. Compáralo con la interfaz de Proxmox."
},
{
"query": "proxmox_uptime_seconds / 86400",
@@ -142,13 +142,13 @@
}
],
"calloutTitle": "El 401 que puedes ver al pulsar la URL del endpoint es normal",
"calloutBody": "En la página <em>Status → Targets</em>, pulsar el enlace del endpoint (<code>/api/prometheus</code>) hace que tu navegador lo descargue directamente — sin la cabecera bearer que Prometheus usa para sus propios scrapes. Así que verás <code>'{'\"error\":\"Authentication required\"'}'</code>. Eso confirma que la API está correctamente protegida; el propio Prometheus se autentica correctamente porque tiene el token de la configuración de scrape. Confía en el verde <em>State: UP</em>, no en el click-through.",
"calloutBody": "Con la autenticación activa, al pulsar el enlace en <em>Status → Targets</em> el navegador consulta <code>/api/prometheus</code> sin la cabecera Bearer de Prometheus. Puede responder <code>'{'\"error\":\"Authentication required\"'}'</code>. Comprueba el <em>State: UP</em> del destino para confirmar que Prometheus recoge los datos con su token.",
"step3Title": "3 · Añade Prometheus como fuente de datos en Grafana",
"step3Body": "En Grafana: <em>Connections → Data sources → Add new → Prometheus</em>. Configura la URL a tu instancia de Prometheus (p. ej. <code>http://prometheus.lan:9090</code>), guarda y prueba. No se necesita auth extra en esta capa — Prometheus ya se ha autenticado a ProxMenux.",
"step3Body": "En Grafana, abre <em>Connections → Data sources → Add new → Prometheus</em>. Indica la URL de Prometheus, por ejemplo <code>http://prometheus.lan:9090</code>, guarda y prueba. Si tu servidor Prometheus exige autenticación, configúrala aquí por separado. El token del Monitor pertenece al job de recogida de Prometheus.",
"step4Title": "4 · Construye paneles con estas queries PromQL",
"step4Body": "Un set inicial que mapea directamente a lo que los usuarios típicamente vigilan en un host Proxmox:",
"headerPanel": "Idea de panel",
"headerPromql": "Query PromQL",
"headerPromql": "Consulta PromQL",
"panelRows": [
{
"panel": "Gauge de uso de CPU por host",
@@ -179,11 +179,11 @@
"promql": "rate(proxmox_interface_bytes_sent_total[5m])"
},
{
"panel": "Load average (1m)",
"panel": "Promedio de carga (1m)",
"promql": "proxmox_load_average{period=\"1m\"}"
},
{
"panel": "% espacio en disco usado por mountpoint",
"panel": "Porcentaje de espacio usado por punto de montaje",
"promql": "proxmox_disk_usage_percent"
},
{
@@ -198,55 +198,55 @@
"outro": "Añade cada query como un panel Grafana, configura la visualización adecuada (<em>Stat</em> para gauges, <em>Time series</em> para tendencias) y agrupa paneles en filas por categoría. Usa la etiqueta <code>node</code> como variable de panel (<em>Settings → Variables → New → Query → label_values(proxmox_cpu_usage, node)</em>) para filtrar todos los paneles por host."
},
"uptimeKuma": {
"heading": "Uptime Kuma y otros status checkers",
"heading": "Uptime Kuma y otras herramientas de comprobación de estado",
"href": "https://github.com/louislam/uptime-kuma",
"intro": "Para probes externos, usa <code>GET /api/system-info</code> — es el único endpoint que funciona sin token, devolviendo un payload JSON pequeño con hostname, uptime y el estado global de salud (mapeado a <code>healthy</code> / <code>warning</code> / <code>critical</code>). Eso es exactamente lo que necesita un monitor basado en keyword.",
"kumaTitle": "Uptime Kuma — HTTP keyword monitor",
"intro": "Para comprobar una palabra clave, usa <code>GET /api/system-info</code>. Esta ruta no exige token y devuelve nombre del host, tiempo de actividad y salud como <code>healthy</code>, <code>warning</code> o <code>critical</code>. Es una comprobación pública, a diferencia de los endpoints detallados protegidos.",
"kumaTitle": "Uptime Kuma — Monitor HTTP de palabras clave",
"kumaSteps": [
"En Uptime Kuma, pulsa <em>+ Add New Monitor</em>.",
"Monitor Type: <em>HTTP(s) - Keyword</em>.",
"Friendly Name: <em>ProxMenux Monitor — pve01</em>.",
"Tipo de monitor: <em>HTTP(s) - Palabras clave</em>.",
"Nombre descriptivo: <em>ProxMenux Monitor — pve01</em>.",
"URL: <code>http://pve01.lan:8008/api/system-info</code>.",
"Keyword: <code>healthy</code> (el valor de <code>health.status</code> cuando el host está OK).",
"Heartbeat Interval: 60 segundos basta.",
"Guarda. Sin cabeceras necesarias — el endpoint es público."
"Intervalo de comprobación: 60 segundos es suficiente.",
"Guarda. La ruta system-info no necesita una cabecera Bearer."
],
"healthchecksTitle": "healthchecks.io / pings tipo cron",
"healthchecksBody": "Mismo endpoint, misma forma — apunta tu ping tipo cron a <code>/api/system-info</code> y comprueba <code>.health.status == \"healthy\"</code>. La mayoría de estos servicios aceptan un estado HTTP 2xx como señal de \"up\" también, en cuyo caso incluso un curl sin parsing basta.",
"healthchecksBody": "Un trabajo cron puede consultar <code>/api/system-info</code> y comprobar <code>.health.status == \"healthy\"</code>. Solo si supera la prueba debe enviar un ping de éxito a la URL única de Healthchecks.io. Ese servicio recibe pings de los trabajos; no consulta el Monitor. Un HTTP 2xx por sí solo no demuestra buena salud del host.",
"richTitle": "¿Quieres datos de salud más ricos?",
"richBody": "Para el estado completo (las diez categorías del Monitor de salud + errores activos + lista dismissed), usa <code>GET /api/health/full</code> en su lugar — ese requiere un API token pero te da todo lo que el modal del panel renderiza en una sola respuesta."
"richBody": "Para el estado completo —diez categorías de salud, errores activos y descartados— usa <code>GET /api/health/full</code>. Devuelve los datos de la ventana del panel en una respuesta y necesita un token Bearer si la autenticación está activada."
},
"workflows": {
"heading": "n8n, Zapier y scripts propios",
"intro": "Para herramientas de workflow y scripts ad-hoc que necesitan <em>levantar</em> notificaciones a través del Monitor (un fallo de CI, un sensor de smart-home, un cron job que tardó demasiado), la guía es un POST a <code>/api/notifications/send</code>. El evento fluye por la misma pipeline de despacho que cualquier cosa emitida internamente — dedup, cooldown, reescritura con IA opcional, fan-out a los canales configurados.",
"n8nBody": "En n8n, el equivalente es un nodo <em>HTTP Request</em> con método POST, la URL de arriba, una cabecera <em>Authorization</em> configurada a <code>Bearer '{''{'$credentials.proxmenux.token'}''}'</code> (usando credentials de n8n) y un body JSON coincidiendo con el payload de curl. Cabléa cualquier nodo precedente como el trigger (cron, webhook, condición).",
"severityBody": "Los valores de severidad son <code>INFO</code>, <code>WARNING</code> o <code>CRITICAL</code> (en mayúsculas). El payload <code>data</code> es JSON libre — el reescritor de IA, cuando está activado, sacará cualquier cosa útil de ahí para el cuerpo renderizado. La semántica completa de tipos de evento vive en <link>Notifications → Catálogo de eventos</link>."
"intro": "Las herramientas de workflow y scripts pueden <em>enviar</em> notificaciones con un POST a <code>/api/notifications/send</code>, por ejemplo por un fallo de CI o un trabajo cron demasiado largo. Es un envío directo: omite la cola y la espera entre huellas de eventos. Conserva el formato por canal, la IA opcional y la entrega a los canales configurados. Controla los duplicados desde quien llama.",
"n8nBody": "En n8n, usa un nodo <em>HTTP Request</em> con POST, la URL anterior y el mismo JSON que curl. Elige credenciales genéricas Header Auth: nombre <em>Authorization</em> y valor <code>Bearer YOUR_API_TOKEN</code>, sustituyendo el marcador. Conecta una programación, webhook u otro nodo para disparar la petición.",
"severityBody": "La gravedad usa <code>INFO</code>, <code>WARNING</code> o <code>CRITICAL</code> en mayúsculas. El objeto <code>data</code> aporta contexto del evento y campos de plantilla. En este endpoint, la IA solo recibe el título y el mensaje; los campos de <code>data</code> no se envían al proveedor. Consulta <link>Notificaciones → Catálogo de eventos</link>."
},
"pveWebhook": {
"heading": "Webhook nativo de Proxmox VE (entrante)",
"intro1": "Proxmox VE 8.1+ tiene su propio sistema de notificaciones. ProxMenux Monitor se registra como destino webhook para que todo lo que PVE emite por sí mismo (fencing HA, replicación, vzdump desde la GUI, renovación de certificado) aterrice en la misma pipeline de despacho que los propios eventos del Monitor. Esto ocurre automáticamente cuando pulsas <em>Enable Notifications</em> en la pestaña Settings — sin trabajo de integración requerido por parte del usuario.",
"intro1": "El sistema de notificaciones llegó en PVE 8.1; los destinos webhook nativos requieren Proxmox VE 8.3 o posterior. <em>Activar notificaciones</em> en Ajustes intenta registrar el Monitor como destino. Los avisos que PVE enruta allí, como informes de backups o replicación, entran en su flujo de envío. El alta depende de que la configuración esté disponible y permita escritura.",
"intro2": "La mecánica, la plantilla de body que PVE envía, las entradas escritas en <code>/etc/pve/notifications.cfg</code> y el comportamiento en clusters están documentados en <link>Notifications → Integración del webhook de PVE</link>."
},
"whereNext": {
"heading": "Por dónde seguir",
"items": [
{
"label": "API Reference",
"label": "Referencia de la API",
"href": "/docs/monitor/api",
"tail": " — cada endpoint con método, path y el catálogo completo de métricas Prometheus."
},
{
"label": "Notifications",
"label": "Notificaciones",
"href": "/docs/monitor/notifications",
"tail": " — fuentes de eventos, canales, la pipeline de despacho, la integración del webhook de PVE en detalle."
},
{
"label": "Asistente de IA",
"href": "/docs/monitor/ai-assistant",
"tail": " — el reescritor opcional que convierte cuerpos templated en lenguaje natural antes de llegar a Telegram / Discord / email / Gotify."
"tail": " — reformulación opcional de las plantillas en lenguaje sencillo antes de enviarlas a Telegram, Discord, correo o Gotify."
},
{
"label": "Access & Authentication",
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tail": " — emitir y revocar los API tokens que consumen estas guías, log de auditoría, configuración TLS."
}
+150 -150
View File
@@ -1,54 +1,54 @@
{
"meta": {
"title": "Notificaciones de Proxmox — Telegram, Discord, Email, Gotify, Pushover, Apprise | ProxMenux Monitor",
"description": "Envía notificaciones de Proxmox VE a Telegram, Discord, Email, Gotify, Pushover y unos 80 servicios adicionales mediante Apprise. ProxMenux Monitor convierte los eventos del monitor de salud, el journal watcher y el webhook de Proxmox VE en mensajes enriquecidos con deduplicación, cooldown, agregación de ráfagas, una reescritura opcional con IA y un historial completo.",
"ogTitle": "Notificaciones de Proxmox — Telegram, Discord, Email, Gotify, Pushover, Apprise",
"ogDescription": "Envía alertas de Proxmox VE a Telegram, Discord, Email, Gotify, Pushover y unos 80 servicios adicionales mediante Apprise.",
"title": "Notificaciones de Proxmox — Telegram, Discord, correo, Gotify, Pushover, Apprise | ProxMenux Monitor",
"description": "Envía notificaciones de Proxmox VE a Telegram, Discord, correo, Gotify, Pushover y unos 80 servicios mediante Apprise. Los eventos del monitor de salud, los registros y el webhook de PVE se convierten en mensajes con deduplicación, intervalos de repetición, agrupación de ráfagas, reescritura opcional con IA e historial.",
"ogTitle": "Notificaciones de Proxmox — Telegram, Discord, correo, Gotify, Pushover, Apprise",
"ogDescription": "Alertas a Telegram, Discord, correo, Gotify, Pushover y unos 80 servicios mediante Apprise, con deduplicación, intervalos de repetición, agrupación de ráfagas e IA opcional.",
"twitterTitle": "Notificaciones de Proxmox | ProxMenux Monitor",
"twitterDescription": "Envía alertas de Proxmox VE a Telegram, Discord, Email, Gotify, Pushover y unos 80 servicios adicionales mediante Apprise."
},
"header": {
"title": "Notifications",
"description": "El motor de distribución que recibe eventos de todos los colectores del Monitor y los entrega a Telegram, Discord, Email, Gotify, Pushover y unos 80 servicios adicionales mediante Apprise, con deduplicación, cooldown, agregación de ráfagas, controles por evento y por canal, reescritura opcional con IA e historial consultable.",
"section": "ProxMenux Monitor"
"title": "Notificaciones",
"description": "Distribuye eventos de los colectores del Monitor a Telegram, Discord, correo, Gotify, Pushover y unos 80 servicios mediante Apprise. Incluye deduplicación, límites de repetición, agrupación de ráfagas, controles por evento y canal, IA opcional e historial consultable.",
"section": "Monitor de ProxMenux"
},
"intro": {
"title": "De dónde vienen los mensajes",
"body": "Las notificaciones no son un escáner aparte. Son el lado de salida de cada colector que ya está corriendo dentro del Monitor — el <link>Monitor de salud</link>, el journal watcher, el task watcher de Proxmox, el hook del webhook de PVE, el polling collector y los eventos in-process emitidos por scripts de ProxMenux. Cada evento corre por la misma pipeline de despacho antes de llegar a un móvil o a un buzón de correo."
"body": "Las notificaciones distribuyen los eventos de los colectores del Monitor: <link>Monitor de salud</link>, vigilancia del registro y de tareas Proxmox, webhook de PVE, consultas periódicas y emisores internos de los scripts. Cada evento pasa por el mismo proceso de envío antes de llegar al móvil o al correo."
},
"howItWorks": {
"heading": "Cómo funciona",
"intro": "Cada notificación sigue el mismo camino por el proceso del Monitor. Los eventos los producen un puñado de colectores independientes, se normalizan en un payload estructurado, pasan por una pipeline de despacho que decide si enviar y en qué forma, opcionalmente se reescriben por un LLM, y finalmente se reparten a los canales que el usuario haya configurado.",
"intro": "Cada notificación sigue el mismo recorrido: los colectores producen eventos estructurados, el proceso de distribución decide si enviarlos y con qué formato, la IA puede reescribirlos y finalmente se entregan a los canales configurados.",
"arrowLabel": "evento",
"caption": "Flujo de alto nivel. Cada intento real de despacho — exitoso, agregado o fallido — se registra en la tabla de historial SQLite para inspección retrospectiva. Los eventos suprimidos por la etapa de cooldown no se loguean.",
"caption": "Esquema general. Cada intento de envío realizado, correcto, agrupado o fallido, se registra en SQLite. Los eventos suprimidos por el intervalo de repetición no se registran.",
"nodes": {
"sourcesLabel": "Fuentes",
"sourcesDetail": "Monitor de salud\nJournal watcher\nTask watcher\nPVE webhook hook\nPolling collector\nEmisores in-process",
"dispatchLabel": "Pipeline de despacho",
"dispatchDetail": "Toggle por evento\nDedup fingerprint\nCooldown\nAgregación de ráfaga",
"sourcesDetail": "Monitor de salud\nVigilancia del registro\nVigilancia de tareas\nWebhook de PVE\nConsultas periódicas\nEmisores internos",
"dispatchLabel": "Proceso de envío",
"dispatchDetail": "Agrupación de ráfagas\nHuella e intervalo de repetición\nLímites por grupo\nControles por canal",
"aiLabel": "Reescritura IA (opc.)",
"aiDetail": "OpenAI / Anthropic\nGemini / Groq\nOpenRouter / Ollama\n(off por defecto)",
"aiDetail": "OpenAI / Anthropic\nGemini / Groq\nOpenRouter / Ollama\n(desactivado por defecto)",
"channelsLabel": "Canales",
"channelsDetail": "Telegram\nDiscord\nEmail (SMTP)\nGotify\nPushover\nApprise (~80 servicios)"
}
},
"enabling": {
"heading": "Activar el panel",
"intro": "En una instalación recién hecha la tarjeta Notifications en la pestaña Settings muestra un badge <em>Disabled</em> y un único botón <em>Enable Notifications</em>. Nada se despacha y ninguna config de PVE se toca hasta que lo pulsas.",
"disabledAlt": "Tarjeta Notifications en una instalación recién hecha mostrando badge Disabled y un único botón Enable Notifications",
"intro": "En una instalación nueva, la tarjeta Notificaciones de Ajustes muestra <em>Desactivado</em> y el botón <em>Activar notificaciones</em>. Hasta pulsarlo no se envía nada ni se modifica la configuración de PVE.",
"disabledAlt": "Tarjeta de notificaciones inicial con estado Desactivado y botón Activar notificaciones",
"disabledCaption": "El primer estado — un clic para activar.",
"stepsIntro": "Pulsar el botón hace tres cosas en secuencia:",
"steps": [
"Cambia el panel a su estado <em>Active</em> y despliega el formulario de canal debajo.",
"Registra un destino webhook de Proxmox VE en <code>/etc/pve/notifications.cfg</code> apuntando a <code>POST http://127.0.0.1:8008/api/notifications/webhook</code>. Desde este momento, todo lo que Proxmox VE emite por sí mismo (HA, replicación, vzdump desde la GUI) fluye a la misma pipeline que los eventos propios del Monitor. Mira <pvelink>Integración del webhook de PVE</pvelink> más abajo para la mecánica completa.",
"Arranca el hilo de fondo de despacho. El hilo hace polling de la cola de eventos y camina cada evento por la pipeline diagramada arriba."
"Activa el estado <em>Activo</em> y muestra el formulario de canales.",
"Registra un destino webhook de Proxmox en <code>/etc/pve/notifications.cfg</code>. Sin HTTPS usa <code>POST http://127.0.0.1:8008/api/notifications/webhook</code>; con HTTPS usa el receptor HTTP local del puerto 8009. Las notificaciones PVE entran en el proceso de envío del Monitor. Consulta <pvelink>Integración del webhook de PVE</pvelink>.",
"Inicia el hilo de envío en segundo plano, que consulta la cola y procesa cada evento según el esquema anterior."
],
"activeAlt": "Tarjeta de notificaciones activada con pestañas de canales, nombre visible y opciones avanzadas de IA",
"activeCaption": "Estado activo: pestañas de canales en la parte superior (Telegram / Gotify / Discord / correo electrónico / Pushover / Apprise), campo Nombre para mostrar, lista de categorías de cada canal y sección desplegable <em>Avanzado: mejora con IA</em>."
},
"sources": {
"heading": "Fuentes de eventos",
"intro": "Seis colectores independientes alimentan el motor de notificaciones. Corren como hilos de fondo dentro del proceso del Monitor y emiten un <code>NotificationEvent</code> estructurado cada vez que algo pasa.",
"intro": "Seis tipos de fuentes alimentan el motor: colectores en segundo plano, receptor webhook y emisores internos. Producen objetos <code>NotificationEvent</code> estructurados.",
"headerCollector": "Colector",
"headerWatches": "Vigila",
"headerEvents": "Eventos típicos",
@@ -59,51 +59,51 @@
"events": "<code>new_error</code>, <code>error_resolved</code>, <code>error_escalated</code>, <code>health_degraded</code>, <code>health_persistent</code>."
},
{
"collector": "Journal watcher",
"watches": "<code>journalctl --follow</code> con pattern matching para fallos de autenticación SSH / web, bans de Fail2Ban (cuando el jail opcional está instalado), errores I/O del kernel, OOM, eventos de smartd.",
"collector": "Monitor del registro del sistema",
"watches": "<code>journalctl --follow</code> con patrones para fallos de acceso SSH/web, bloqueos Fail2Ban cuando está instalado el jail, errores de E/S del núcleo, OOM y eventos smartd.",
"events": "<code>auth_fail</code>, <code>ip_block</code>, <code>oom_kill</code>, <code>disk_io_error</code>, <code>service_fail</code>."
},
{
"collector": "Task watcher",
"watches": "Hace polling de <code>/var/log/pve/tasks/index</code> para nuevos UPIDs de tareas y sigue sus logs por archivo.",
"collector": "Monitor de tareas",
"watches": "Consulta <code>/var/log/pve/tasks/index</code> para detectar nuevos UPID y sigue sus archivos de registro.",
"events": "<code>backup_start</code>, <code>backup_complete</code>, <code>backup_warning</code>, <code>backup_fail</code>, <code>migration_*</code>, <code>snapshot_complete</code>."
},
{
"collector": "Hook de webhook Proxmox",
"watches": "Escucha en <code>POST /api/notifications/webhook</code>. Proxmox VE 8.1+ empuja sus propias notificaciones aquí una vez configurada la integración (mira <pvelink>abajo</pvelink>).",
"collector": "Receptor webhook de Proxmox",
"watches": "Recibe <code>POST /api/notifications/webhook</code>. Las versiones de PVE con destinos webhook pueden reenviar sus avisos tras configurarlo; consulta <pvelink>más abajo</pvelink>.",
"events": "Cualquier cosa que PVE emita — incluyendo eventos que el Monitor de otro modo perdería (HA, replicación, vzdump desde la GUI)."
},
{
"collector": "Polling collector",
"collector": "Colector de consultas periódicas",
"watches": "Comparaciones periódicas (nodos del cluster online, caducidad de certificado, estado de passthrough de GPU, disponibilidad de actualización PVE / ProxMenux).",
"events": "<code>node_disconnect</code>, <code>node_reconnect</code>, <code>pve_update</code>, <code>proxmenux_update</code>, <code>gpu_mode_switch</code>, <code>pci_passthrough_conflict</code>."
},
{
"collector": "Emisores in-process",
"collector": "Emisores internos",
"watches": "Llamadas directas desde scripts de ProxMenux y desde el propio Monitor (<code>notification_manager.emit_event(...)</code>).",
"events": "<code>system_startup</code>, <code>system_shutdown</code>, <code>system_reboot</code>, <code>ai_model_migrated</code>, eventos de prueba personalizados."
}
],
"after1": "Cada evento lleva un <code>event_type</code> estable (el catálogo está abajo), una <code>severity</code> (<code>INFO</code>, <code>WARNING</code>, <code>CRITICAL</code>), una <code>category</code> (usada para enriquecimiento de emoji y filtros por grupo) y un payload <code>data</code> con lo que la template necesite (<code>vmid</code>, <code>device</code>, <code>source_ip</code>, <code>reason</code>…).",
"after2": "Cada <code>event_type</code> tiene una template coincidente en <code>notification_templates.py</code> que renderiza el evento estructurado en un cuerpo de texto plano antes de que cualquier otra cosa pase. Ese cuerpo templated es lo que viaja por la pipeline de despacho, y lo que la capa opcional de IA reescribe si está activada. Mira la <ailink>página del Asistente de IA</ailink> para cómo la capa de reescritura interactúa con este cuerpo templated."
"after1": "Cada evento incluye un <code>event_type</code> estable, una <code>severity</code> (<code>INFO</code>, <code>WARNING</code>, <code>CRITICAL</code>), una <code>category</code> para emojis y filtros, y los valores <code>data</code> que necesita la plantilla (<code>vmid</code>, <code>device</code>, <code>source_ip</code>, <code>reason</code>…).",
"after2": "Cada <code>event_type</code> tiene una plantilla en <code>notification_templates.py</code> que convierte el evento en texto. Ese texto pasa por el proceso de envío y puede ser reescrito por la IA. La <ailink>página del Asistente de IA</ailink> explica esa interacción."
},
"channels": {
"heading": "Walkthroughs de canales",
"heading": "Configuración de los canales",
"intro": "Actualmente se admiten seis canales: Telegram, Discord, Gotify, Email (SMTP), Pushover y Apprise. Los cinco primeros son integraciones nativas con sus propios campos de configuración. Apprise funciona como un concentrador genérico que añade unos 80 servicios adicionales (ntfy, Matrix, Slack, Teams, Pushbullet, AWS SNS, Mattermost…) mediante una única URL. Todos están documentados paso a paso a continuación.",
"credsTitle": "Dónde viven las credenciales",
"credsBody": "Los tokens, las claves, las URL de webhook y las contraseñas SMTP se guardan localmente en la base de datos SQLite del Monitor dentro de <code>/usr/local/share/proxmenux/</code>. Los valores sensibles están protegidos y se ocultan en la interfaz. Solo salen del host para comunicarse con el servicio correspondiente. Una copia de ese directorio permite recuperar los canales configurados."
"credsTitle": "Dónde se guardan las credenciales",
"credsBody": "Los tokens, las claves, las URL de webhook y las contraseñas SMTP se guardan localmente en la base de datos SQLite del Monitor dentro de <code>/usr/local/share/proxmenux/</code>. Los valores sensibles están protegidos y se ocultan en la interfaz. Solo salen del host para comunicarse con el servicio correspondiente. Un backup de ese directorio permite recuperar los canales configurados."
},
"telegram": {
"heading": "Telegram",
"intro": "Se requieren dos piezas de información: un <strong>Bot Token</strong> (uno por bot, reutilizable entre chats) y un <strong>Chat ID</strong> (donde el bot debe publicar — tu chat privado, un grupo o un tema dentro de un supergrupo). La guía in-app de abajo contiene el paso a paso completo; el resto de esta sección lo repite como texto más las dos formas que puede tomar el Chat ID.",
"guideAlt": "Modal Telegram Bot Setup Guide con cuatro secciones numeradas: Crear un Bot con BotFather, Obtener el Bot Token, Obtener tu Chat ID y Para Grupos o Canales",
"guideCaption": "El enlace <em>+ setup guide</em> dentro de la pestaña Telegram abre este modal — los cuatro pasos numerados van de sin bot a un canal funcionando en unos dos minutos.",
"intro": "Necesitas un <strong>Token del bot</strong>, reutilizable entre chats, y un <strong>ID del chat</strong> de destino: privado, grupo o tema de un supergrupo. La guía integrada muestra el procedimiento; aquí se explica también el formato de cada ID.",
"guideAlt": "Guía de configuración de Telegram con cuatro secciones: crear bot con BotFather, obtener token, obtener ID del chat y configurar grupos o canales",
"guideCaption": "El enlace <em>+ guía de configuración</em> de Telegram abre estos cuatro pasos para crear el bot y configurar el canal en unos dos minutos.",
"step1Title": "1 · Crea un bot con BotFather",
"step1Items": [
"Abre Telegram y empieza un chat con <a>@BotFather</a> (el que tiene el tick azul de verificación — las copias son comunes).",
"Envía <code>/newbot</code>.",
"Elige un nombre visible (p. ej. <em>ProxMenux Lab</em>). Se puede cambiar después.",
"Elige un username terminado en <code>bot</code> (p. ej. <em>proxmenux_lab_bot</em>). Debe ser único en Telegram.",
"Elige un nombre de usuario terminado en <code>bot</code>, como <em>proxmenux_lab_bot</em>. Debe ser único en Telegram.",
"BotFather responde con un token de la forma <code>123456789:ABCdef…</code> — ese es el Bot Token. Trátalo como una contraseña."
],
"step2Title": "2 · Obtén el Chat ID",
@@ -120,61 +120,61 @@
"Añade el bot al grupo como miembro (y hazlo admin si el grupo lo requiere para publicar).",
"Envía cualquier mensaje en el grupo.",
"Abre <code>https://api.telegram.org/bot&lt;YOUR_TOKEN&gt;/getUpdates</code> en un navegador. Busca <code>chat.id</code> en la respuesta JSON — para grupos es un número negativo, para supergrupos empieza con <code>-100</code>.",
"Para supergrupos con <em>Topics</em> activado, anota también el <code>message_thread_id</code> del tema al que quieres apuntar — eso va en el campo opcional <em>Topic ID</em>."
"En supergrupos con <em>Temas</em>, anota el <code>message_thread_id</code> de destino e introdúcelo en el campo opcional <em>ID de tema</em>."
],
"groupAlt": "Formulario de canal Telegram con Bot Token (enmascarado), Chat ID negativo prefijado con -100 indicando un supergrupo, y Topic ID 3 configurado para entregar a un tema específico",
"groupCaption": "Supergrupo — el Chat ID empieza con <code>-100…</code> y el <em>Topic ID</em> opcional apunta a un hilo específico.",
"step3Title": "3 · Guarda y prueba",
"step3Body": "Pega el Bot Token y el Chat ID en la pestaña Telegram, guarda y pulsa <em>Send Test</em> al final del panel. Un mensaje de prueba debería llegar en un segundo; si no llega, la sección History registra el fallo con el motivo exacto (token inválido, bot no en el grupo, bloqueado por el usuario, etc.)."
"step3Body": "Pega el token del bot y el ID del chat en Telegram, guarda y pulsa <em>Enviar prueba</em>. El mensaje debería llegar en un segundo; si no, el Historial muestra el motivo del fallo, como token inválido, bot fuera del grupo o bloqueo por el usuario."
},
"discord": {
"heading": "Discord",
"intro": "Los canales de Discord aceptan mensajes entrantes a través de una <em>Webhook URL</em> ligada a un único canal. El Monitor necesita esa URL y nada más.",
"intro": "Discord recibe mensajes mediante una <em>URL de webhook</em> asociada a un canal. Monitor necesita esa URL.",
"items": [
"En Discord, abre el servidor donde quieres que aterricen las notificaciones y ve a <em>Server Settings → Integrations → Webhooks</em>.",
"Pulsa <em>New Webhook</em>. Dale un nombre (p. ej. <em>ProxMenux</em>) y elige el canal donde debe publicar. Un avatar es opcional.",
"Pulsa <em>Copy Webhook URL</em> — tiene aspecto de <code>https://discord.com/api/webhooks/&lt;id&gt;/&lt;token&gt;</code>.",
"Abre el servidor Discord y ve a <em>Ajustes del servidor → Integraciones → Webhooks</em>.",
"Pulsa <em>Nuevo webhook</em>, ponle un nombre como <em>ProxMenux</em> y elige el canal de destino. El avatar es opcional.",
"Pulsa <em>Copiar URL del webhook</em>. Su formato es <code>https://discord.com/api/webhooks/&lt;id&gt;/&lt;token&gt;</code>.",
"Pégalo en el campo Webhook URL de la pestaña Discord en el panel Notifications y guarda."
],
"imageAlt": "Formulario de canal Discord con campo Webhook URL empezando por https://discord.com/api/webhooks/",
"imageCaption": "Discord — pega la Webhook URL de <em>Server Settings → Integrations → Webhooks</em>."
"imageCaption": "Discord: pega la URL obtenida en <em>Ajustes del servidor → Integraciones → Webhooks</em>."
},
"gotify": {
"heading": "Gotify",
"intro": "Gotify es un servidor push autoalojado. Necesitas su URL base y un <em>Application Token</em> generado desde la UI de admin de Gotify.",
"intro": "Gotify es un servidor de notificaciones que puedes alojar. Necesitas su URL base y un <em>Token de aplicación</em> generado en su interfaz de administración.",
"items": [
"Si aún no tienes una instancia de Gotify, instala una — mira la <a>guía oficial de instalación</a>.",
"Abre la UI web de Gotify, loguéate como admin, ve a <em>Apps</em> → <em>Create Application</em>. Dale un nombre (p. ej. <em>ProxMenux</em>). Gotify genera un token — cópialo.",
"En la pestaña Gotify del panel Notifications, configura <em>Server URL</em> a la URL base de tu instancia (p. ej. <code>https://gotify.example.com</code>) y pega el App Token.",
"Guarda y pulsa <em>Send Test</em>."
"Entra como administrador en Gotify y abre <em>Aplicaciones</em> → <em>Crear aplicación</em>. Ponle un nombre como <em>ProxMenux</em> y copia el token generado.",
"En Gotify, establece <em>URL del servidor</em> en la URL base, por ejemplo <code>https://gotify.example.com</code>, y pega el token.",
"Guarda y pulsa <em>Enviar prueba</em>."
],
"imageAlt": "Formulario de canal Gotify con campo Server URL configurado a https://gotify.example.com y un campo App Token con placeholder A_valid_gotify_token",
"imageCaption": "Gotify — URL del servidor de tu instancia autoalojada más el App Token de la UI de admin de Gotify."
},
"email": {
"heading": "Email (SMTP)",
"heading": "Correo electrónico (SMTP)",
"intro": "Email es el canal más flexible — y el que tiene más campos. Necesitas un servidor SMTP, un puerto, un modo TLS, opcionalmente un usuario y contraseña, una dirección de remitente y al menos un destinatario.",
"imageAlt": "Formulario de canal Email con SMTP Host, Port, dropdown TLS Mode, Username, Password, From Address, To Addresses separadas por coma y campos Subject Prefix",
"imageCaption": "Email — host / puerto / modo TLS de SMTP, usuario + contraseña opcionales, dirección de remitente, destinatarios separados por coma y un prefijo de asunto para hacer las alertas fáciles de filtrar en el lado del inbox.",
"appNote": "Si usas una cuenta personal de Gmail o Microsoft 365, el campo password no puede ser tu contraseña normal de cuenta — ambos proveedores requieren una <strong>app password</strong> generada específicamente para clientes de terceros. Los dos flujos están abajo.",
"gmailTitle": "App password de Gmail",
"imageAlt": "Formulario SMTP con servidor, puerto, modo TLS, usuario, contraseña, remitente, destinatarios separados por comas y prefijo del asunto",
"imageCaption": "Correo: servidor, puerto y TLS de SMTP; usuario y contraseña opcionales; remitente, destinatarios separados por comas y prefijo de asunto para filtrar avisos.",
"appNote": "Monitor usa autenticación SMTP con contraseña. Gmail puede requerir una <strong>contraseña de aplicación</strong>. En Microsoft depende del servicio y de las políticas del tenant: una contraseña de aplicación no permite saltarse el bloqueo de autenticación básica. Comprueba que el servicio admita este método.",
"gmailTitle": "Contraseña de aplicación de Gmail",
"gmailIntro": "Las app passwords de Gmail requieren que la <strong>verificación en 2 pasos</strong> esté activa en la cuenta de Google. Si no lo está, la página <em>App passwords</em> no existirá.",
"gmailItems": [
"Abre <a>myaccount.google.com/security</a> y activa <em>Verificación en 2 pasos</em> si no está activada.",
"Ve a <a>myaccount.google.com/apppasswords</a>.",
"Escribe un nombre (p. ej. <em>ProxMenux</em>) y pulsa <em>Create</em>. Google muestra una contraseña de 16 caracteres — cópiala.",
"Rellena la pestaña Email con: <em>Host</em> <code>smtp.gmail.com</code>, <em>Port</em> <code>587</code>, <em>TLS Mode</em> <code>STARTTLS</code>, <em>Username</em> tu dirección de Gmail, <em>Password</em> la app password de 16 caracteres."
"Escribe un nombre como <em>ProxMenux</em> y pulsa <em>Crear</em>. Copia la contraseña de 16 caracteres.",
"Configura: <em>Servidor</em> <code>smtp.gmail.com</code>, <em>Puerto</em> <code>587</code>, <em>Modo TLS</em> <code>STARTTLS</code>, <em>Usuario</em> tu dirección Gmail y <em>Contraseña</em> la de aplicación de 16 caracteres."
],
"outlookTitle": "App password de Microsoft / Outlook",
"outlookIntro": "Microsoft ahora requiere <strong>verificación en dos pasos</strong> en la cuenta personal antes de que se pueda crear una app password. Los tenants empresariales donde el admin ha deshabilitado SMTP basic auth necesitan un camino distinto (OAuth2) que el Monitor no soporta actualmente — apunta esos a un relay SMTP que controles en su lugar.",
"outlookTitle": "Contraseña de aplicación de Microsoft / Outlook",
"outlookIntro": "Las contraseñas de aplicación de Microsoft exigen <strong>verificación en dos pasos</strong>, pero disponer de una no garantiza compatibilidad SMTP. Si el servicio o tenant exige OAuth2, el cliente SMTP de Monitor no puede autenticarse. Usa un relay que admita la autenticación del proveedor.",
"outlookItems": [
"Abre <a>account.microsoft.com/security</a> y activa la verificación en dos pasos.",
"Abre <em>Advanced security options</em>, baja a <em>App passwords</em> y pulsa <em>Create a new app password</em>.",
"Microsoft muestra una contraseña aleatoria larga — cópiala.",
"Rellena la pestaña Email con: <em>Host</em> <code>smtp-mail.outlook.com</code>, <em>Port</em> <code>587</code>, <em>TLS Mode</em> <code>STARTTLS</code>, <em>Username</em> tu dirección de Outlook / Microsoft 365, <em>Password</em> la app password generada."
"Si tu cuenta ofrece <em>Opciones avanzadas de seguridad</em> → <em>Contraseñas de aplicación</em>, elige <em>Crear una contraseña de aplicación</em>. Eso no garantiza que el correo admita autenticación SMTP con contraseña.",
"Si Microsoft genera la contraseña, cópiala y comprueba que tu servicio SMTP la acepte.",
"Solo si el proveedor admite SMTP con contraseña, usa sus ajustes autorizados: <em>servidor SMTP</em> <code>smtp.office365.com</code> para Exchange Online, <em>Puerto</em> <code>587</code>, <em>modo TLS</em> <code>STARTTLS</code>, <em>Nombre de usuario</em> tu dirección y <em>Contraseña</em> la credencial permitida. Outlook.com personal usa requisitos y ajustes distintos; no presupongas que estas credenciales funcionen."
],
"relayTitle": "Relay SMTP autoalojado",
"relayBody": "Si corres tu propio relay SMTP (Postfix, msmtp, etc.) en la LAN, apunta el Monitor a él y saltea el baile de app-password por completo. El relay maneja la auth upstream y el Monitor envía en cleartext sobre una red de confianza."
"relayBody": "Usa un relay SMTP que controles, como Postfix. El relay gestiona la autenticación hacia el proveedor. Configura la autenticación y TLS de Monitor según lo que exija el relay; que sea local no desactiva el cifrado."
},
"pushover": {
"heading": "Pushover",
@@ -182,8 +182,8 @@
"stepsTitle": "Configuración",
"steps": [
"Crea una <a>cuenta de Pushover</a>, instala la aplicación oficial en los dispositivos que recibirán las alertas e inicia sesión.",
"Copia la <em>User Key</em> que aparece en el panel de Pushover. También puedes usar una clave de grupo si varias personas o dispositivos deben recibir la misma alerta.",
"Abre <a>Create an Application/API Token</a>, crea una aplicación llamada <em>ProxMenux</em> y copia su token API de 30 caracteres.",
"Copia la <em>Clave de usuario</em> del panel Pushover. Puedes usar una clave de grupo si varias personas o dispositivos deben recibir la alerta.",
"Abre <a>Crear aplicación/token API</a>, crea una aplicación llamada <em>ProxMenux</em> y copia su token API de 30 caracteres.",
"En <em>Ajustes → Notificaciones → Pushover</em>, pega la clave de usuario o grupo y el token API de la aplicación. Los campos de dispositivo y sonido son opcionales.",
"Guarda los ajustes y pulsa <em>Enviar prueba</em>. La aplicación Pushover debería recibir el mensaje inmediatamente."
],
@@ -198,160 +198,160 @@
"listIntro": "La lista completa de servicios compatibles y el formato exacto de cada URL están disponibles en la documentación oficial de Apprise:",
"listItems": [
"<a>Documentación de servicios de Apprise</a> — índice completo de servicios compatibles.",
"<a>URL basics</a> — cómo se estructuran las URLs de Apprise."
"<a>Conceptos básicos de las URL</a>: estructura de las URL de Apprise."
],
"stepsTitle": "Pasos",
"steps": [
"Elige el servicio destino en la <a>wiki de Apprise</a> y copia la plantilla de URL para él. Cada página de servicio muestra el esquema exacto a usar (<code>ntfy://</code>, <code>matrix://</code>, <code>pover://</code>, <code>slack://</code>…) más cualquier token, canal u hostname requerido.",
"Sustituye los marcadores por tus credenciales. Ejemplos: ntfy.sh <code>ntfy://ntfy.sh/my-topic</code>; Pushover <code>pover://user@token</code>; Matrix <code>matrix://user:pass@host:port/#room</code>.",
"Pega la URL final en el campo <em>Apprise URL</em> en la pestaña Apprise del panel Notifications y guarda.",
"Pulsa <em>Send Test</em> para verificar que la URL es alcanzable y las credenciales se aceptan."
"Pulsa <em>Enviar prueba</em> para comprobar el acceso y las credenciales."
],
"deliveredTitle": "Qué se entrega",
"deliveredBody": "Apprise recibe el mismo payload que los otros canales — título, cuerpo y una severidad (info / success / warning / failure). La severidad se mapea a lo que el servicio destino exponga (icono, prioridad, color). El formato de mensajes ricos y la capa de reescritura con IA corren todos antes de que se invoque la URL, exactamente como para Telegram o Email.",
"fanoutTitle": "Una URL por canal Apprise",
"fanoutBody": "El Monitor expone un único slot de URL por canal Apprise. Si necesitas hacer fan-out a varios servicios Apprise a la vez (p. ej. ntfy.sh más una sala de Matrix), el enfoque más limpio es alojar un pequeño <a>servidor Apprise API</a> con una config etiquetada y apuntar el Monitor a su endpoint — el servidor luego difunde a cada URL detrás de esa etiqueta."
"fanoutBody": "Monitor ofrece una URL por canal Apprise. Para enviar a varios servicios, como ntfy.sh y Matrix, aloja un <a>servidor Apprise API</a> con una configuración etiquetada. Monitor llama a ese destino y el servidor distribuye a las URL de la etiqueta."
},
"rich": {
"heading": "Mensajes ricos, categorías y filtrado por canal",
"intro": "Bajo el formulario del canal cada canal expone los mismos tres controles: un toggle <em>Rich messages</em> arriba (destacado con la flecha en la captura), once <em>Notification Categories</em> colapsables con toggles por evento y un botón <em>Send Test</em> abajo.",
"imageAlt": "Panel Notification Categories con toggle maestro Rich messages destacado arriba, secciones colapsables para VM/CT, Backups, Resources, Storage, Network, Security, Cluster, Services, Health Monitor, Updates cada una con toggle y contador de eventos, y un botón Send Test",
"imageCaption": "Flecha de arriba — el toggle <em>Rich messages</em> por canal. Abajo — las once categorías colapsables con toggles por evento. <em>Send Test</em> está al final del canal.",
"richTitle": "Mensajes ricos",
"richIntro": "Con <em>Rich messages</em> activado, la cabecera de cada evento se prefija con un emoji de categoría y el cuerpo se renderiza usando el formato nativo del canal (HTML de Telegram, embed de Discord con color de severidad). Con él desactivado, el Monitor envía una versión de texto plano con la misma información menos las pistas visuales. Mismo contenido, distinta presentación:",
"plainHeader": "Plano — Rich messages off",
"richHeader": "Rico — Rich messages on",
"richOutro": "El toggle es por canal: deja Email plano para legibilidad de reglas de inbox dejando que Telegram y Discord rendericen la versión rica. Los canales que no soportan formato inline (email texto plano, Gotify) ignoran el formato y caen a texto de todas formas.",
"heading": "Mensajes enriquecidos, categorías y filtros por canal",
"intro": "Cada canal tiene tres controles: <em>Mensajes enriquecidos</em> arriba, once secciones de <em>Categorías de notificación</em> con interruptores por evento y <em>Enviar prueba</em> abajo.",
"imageAlt": "Categorías con Mensajes enriquecidos destacado, secciones de VM/CT, backups, recursos, almacenamiento, red, seguridad, clúster, servicios, salud y actualizaciones, con interruptores y contadores, y botón Enviar prueba",
"imageCaption": "La flecha señala <em>Mensajes enriquecidos</em>. Debajo están las once categorías desplegables con controles por evento. <em>Enviar prueba</em> está al final.",
"richTitle": "Mensajes enriquecidos",
"richIntro": "Con <em>Mensajes enriquecidos</em>, cada aviso lleva un emoji de categoría y formato nativo del canal, como HTML en Telegram o tarjetas coloreadas en Discord. Desactivado, se envía el mismo contenido en texto simple:",
"plainHeader": "Texto simple: formato enriquecido desactivado",
"richHeader": "Texto enriquecido: formato activado",
"richOutro": "El control es independiente por canal. Puedes dejar el correo en texto simple y usar formato en Telegram y Discord. Los canales sin ese formato, como correo de texto o Gotify, reciben texto.",
"togglesTitle": "Categorías por evento",
"togglesIntro": "Unos setenta tipos de evento están agrupados en once categorías de UI. Cada evento tiene un toggle maestro y un override por canal — dos capas que deciden si un evento dado llega a un canal dado:",
"togglesIntro": "Cada canal controla sus categorías y tipos de evento de forma independiente. Desactivar una categoría suprime sus eventos en ese canal. Los controles individuales se aplican dentro de las categorías activas; el distribuidor no tiene un control maestro global por evento.",
"togglesItems": [
"<strong>Toggle maestro por evento.</strong> Si <code>vm_start</code> está off en todas partes, ningún canal ve nunca un <code>vm_start</code>. Los toggles persisten como <code>event_toggles[event_type] = true | false</code>.",
"<strong>Overrides por canal.</strong> Un tipo de evento también se puede silenciar para un canal específico (<em>\"enviar <code>backup_complete</code> a Discord pero no a Telegram\"</em>). Estos viven en <code>channel_overrides[channel_name][event_type]</code> y solo aplican si el evento pasó el toggle maestro."
"<strong>Control de categoría por canal.</strong> Por ejemplo, desactivar VM/CT suprime <code>vm_start</code> y sus equivalentes para ese canal. Se guarda como <code>&lt;channel&gt;.events.&lt;group&gt;</code>.",
"<strong>Control de evento por canal.</strong> En una categoría activa puedes elegir <em>enviar <code>backup_complete</code> a Discord pero no a Telegram</em>. Se guarda como <code>&lt;channel&gt;.event.&lt;event_type&gt;</code>."
],
"togglesOutro": "Cada cabecera de categoría en la captura también muestra el conteo de eventos <em>actualmente activados</em> / <em>total</em> para ese grupo, y un toggle a nivel de categoría que pone cada evento dentro a on o off en un clic — el atajo para silenciar un grupo entero (p. ej. todos los backups <code>info</code>, todos los eventos relacionados con actualizaciones) sin expandir la sección."
"togglesOutro": "Cada categoría indica los eventos <em>activados</em> frente al <em>total</em> y permite activar o desactivar el grupo completo con un clic, por ejemplo backups <code>info</code> o avisos de actualización, sin abrirlo."
},
"quiet": {
"heading": "Quiet Hours",
"intro": "Quiet Hours es una ventana temporal por canal durante la cual el dispatcher solo deja pasar eventos <strong>CRITICAL</strong>. Todo lo demás — INFO, WARNING, eventos de acción — se retiene, se persiste a disco y se entrega como un único resumen agrupado en el momento en que la ventana cierra. El canal sigue recibiendo las cosas urgentes en tiempo real; el ruido espera hasta que probablemente lo quieras.",
"imageAlt": "Ajustes de canal mostrando ambos knobs lado a lado: tarjeta Quiet Hours con toggle activado, Start 22:00 y End 07:00 más una preview en vivo de la siguiente transición, y justo debajo la tarjeta Daily digest con su propio toggle, un selector de hora de entrega configurado a 09:00 y la nota de que CRITICAL y WARNING nunca se retrasan",
"imageCaption": "Ambos knobs viven lado a lado dentro de la tarjeta de ajustes de cada canal — Quiet Hours arriba, Daily digest debajo. Independientes por canal.",
"heading": "Horas de silencio",
"intro": "Durante las horas de silencio de cada canal solo pasan los eventos <strong>CRITICAL</strong>. INFO, WARNING y las acciones se guardan en disco y se entregan en un resumen al terminar el intervalo.",
"imageAlt": "Ajustes de canal con Horas de silencio de 22:00 a 07:00 y vista del próximo cambio; debajo, Resumen diario a 09:00 con aviso de que este resumen no retrasa CRITICAL ni WARNING",
"imageCaption": "Cada canal tiene ambos ajustes independientes: Horas de silencio arriba y Resumen diario debajo.",
"purposeTitle": "Para qué sirve",
"purposeItems": [
"<strong>No me despiertes a las 03:00 por un aviso de actualización.</strong> Backups, actualizaciones de apps, optimizaciones post-instalación y otros eventos de nivel INFO dejan de avisar a tu móvil por la noche.",
"<strong>Pero aun así despiértame por un fuego.</strong> Fallos de disco, OOM kills, shutdowns del host, bans de fail2ban — cualquier cosa clasificada como CRITICAL — saltea la ventana y llega inmediatamente.",
"<strong>Tampoco pierdas nada.</strong> Los eventos suprimidos durante la ventana no se descartan silenciosamente — se sientan en un buffer SQLite hasta que vuelves al reloj."
"<strong>Los eventos críticos siguen llegando.</strong> Solo los clasificados como CRITICAL evitan el silencio. El nombre no determina la severidad: el monitor del registro emite los bloqueos Fail2Ban y los avisos de apagado/reinicio del host como INFO, por lo que pueden retenerse.",
"<strong>Conserva los avisos aplazados.</strong> Los eventos retenidos se guardan en un búfer SQLite hasta que termine el intervalo."
],
"howTitle": "Cómo funciona",
"howItems": [
"<strong>Toggle por canal.</strong> Cada canal tiene su propia configuración de Quiet Hours — Telegram puede estar silencioso 22:00-07:00 mientras email sigue recibiendo todo 24/7.",
"<strong>Control por canal.</strong> Por ejemplo, Telegram puede guardar silencio de 22:00 a 07:00 mientras el correo recibe avisos todo el día.",
"<strong>Hora de inicio y fin</strong> en tu zona horaria local, intervalo semi-abierto (inicio inclusivo, fin exclusivo). La ventana puede cruzar medianoche (p. ej. 22:00-07:00 significa esta noche hasta mañana por la mañana).",
"<strong>Línea de preview en vivo</strong> justo debajo de los inputs muestra si la ventana está actualmente activa y cuándo ocurre la siguiente transición. Ahorra abrir un reloj.",
"<strong>Durante la ventana:</strong> los eventos CRITICAL siguen disparando por la pipeline de despacho normal. Los eventos INFO y WARNING se enrutan a un buffer persistente (tabla <code>quiet_pending</code> en la DB SQLite del Monitor).",
"<strong>Cuando la ventana cierra:</strong> se envía una única notificación agrupada con todo lo que se acumuló — una línea por evento bufferizado, en orden cronológico. El buffer se limpia solo después de que el canal confirme la entrega, para que un fallo transitorio de Telegram / SMTP no pierda el contexto de la noche.",
"<strong>A través de reinicios.</strong> Si el Monitor reinicia a mitad de ventana, el buffer está intacto en disco. Si el reinicio ocurre justo después de que la ventana cierre, el siguiente ciclo de despacho detecta las filas pendientes y las descarga con un único resumen \"recovery\" — no se pierden notificaciones por un deploy o un reboot."
"<strong>Vista previa en directo.</strong> Bajo los campos se indica si el intervalo está activo y cuándo cambiará.",
"<strong>Durante el intervalo:</strong> CRITICAL sigue por el proceso de envío; INFO y WARNING se guardan en la tabla SQLite <code>quiet_pending</code>.",
"<strong>Al terminar:</strong> se envía un resumen cronológico con una línea por evento guardado. El búfer se borra tras confirmar la entrega, para resistir fallos transitorios de Telegram o SMTP.",
"<strong>Resiste reinicios.</strong> El búfer permanece en disco. Tras reiniciar, el siguiente ciclo detecta las filas pendientes y envía un resumen de recuperación cuando corresponde."
],
"criticalTitle": "Qué cuenta como CRITICAL",
"criticalBody": "La severidad se fija en la creación del evento, no en el momento del despacho. Los fallos de disco, OOM kills, split-brain de cluster, shutdowns del host y el nivel \"duro\" de errores I/O de disco se envían como CRITICAL por diseño. Todo lo demás (backups OK, actualizaciones disponibles, logs INFO, hits de rate-limit) cae por defecto a INFO o WARNING y por tanto es silenciable. Puedes verificar la severidad por defecto de un evento dado en el <link>Catálogo de eventos</link> más abajo en esta página."
"criticalBody": "El productor fija la severidad al crear el evento. Que trate de disco, apagado o seguridad no lo convierte en CRITICAL. El monitor del registro emite ip_block, system_shutdown y system_reboot como INFO. El <link>Catálogo de eventos</link> enumera los tipos; consulta el productor y el evento recibido para conocer su severidad real."
},
"digest": {
"heading": "Resumen diario de eventos INFO",
"intro1": "El Daily Digest es el knob opuesto: un ajuste <strong>opt-in</strong> que dice \"no me envíes cada backup exitoso o aviso de actualización según ocurre — recoléctalos y envíame un resumen al día a las 09:00 (o la hora que elija)\". Mismo objetivo que Quiet Hours (menos ruido) pero un mecanismo distinto (resumen basado en tiempo en vez de una ventana diaria).",
"intro2": "Vive en la misma tarjeta de ajustes de canal que Quiet Hours (mira la figura bajo <link>Quiet Hours</link>), justo debajo. Cada uno se activa independientemente.",
"intro1": "El resumen diario es una opción <strong>que activas expresamente</strong>: agrupa avisos INFO aptos, como actualizaciones disponibles, a las 09:00 o a la hora elegida. Los resultados de backups y replicación y las acciones en directo están excluidos. Las horas de silencio aplazan los avisos no críticos durante un intervalo.",
"intro2": "Está debajo de las horas de silencio en la misma tarjeta; consulta la figura en <link>Horas de silencio</link>. Ambos se activan por separado.",
"purposeTitle": "Para qué sirve",
"purposeItems": [
"<strong>El recap matutino de \"todo lo que pasó\".</strong> Si chequeas el host una vez al día con un café, un digest a las 09:00 lleva la misma información que 20 pings individuales a lo largo del día anterior, sin que leas 20 burbujas de Telegram.",
"<strong>Separa ruido de señal.</strong> Los eventos INFO responden a \"qué pasó\"; CRITICAL y WARNING responden a \"qué necesito hacer ahora mismo\". El digest maneja el primero; todo lo demás mantiene su entrega en vivo."
"<strong>Un repaso matutino de lo ocurrido.</strong> Un resumen a las 09:00 reúne la información de 20 avisos individuales del día anterior y evita leer 20 mensajes de Telegram.",
"<strong>Separa actividad y urgencias.</strong> INFO explica qué pasó; CRITICAL y WARNING indican qué requiere atención. El resumen agrupa los INFO aptos; los demás conservan el envío directo."
],
"howTitle": "Cómo funciona",
"howItems": [
"<strong>Opt-in por canal.</strong> Off por defecto — Telegram no batcheaiza silenciosamente tus alertas. Lo activas en los canales donde quieres un digest, dejando otros en entrega en vivo.",
"<strong>Activación por canal.</strong> Desactivado por defecto. Actívalo solo donde quieras resúmenes y deja los otros canales con avisos directos.",
"<strong>Hora de entrega</strong> en tu zona horaria local. Por defecto 09:00 pero puedes elegir cualquier hora; el dispatcher dispara el digest dentro de ~60 s de ese minuto.",
"<strong>Qué entra en el digest:</strong> cualquier evento que el canal habría recibido en vivo cuya severidad es <strong>INFO</strong>. Ejemplos — <em>vzdump complete</em>, <em>Tailscale update available</em>, <em>ProxMenux optimisation update available</em>, <em>APT security updates pending</em>, <em>rate-limit hit</em>.",
"<strong>Incluye:</strong> eventos generales aptos de nivel <strong>INFO</strong>, como <em>actualización de aplicación disponible</em>, <em>actualización de Tailscale disponible</em>, <em>actualización de optimización de ProxMenux disponible</em> y <em>actualizaciones de seguridad APT pendientes</em>. Los resultados de backups y otras acciones excluidas siguen en directo.",
"<strong>Qué nunca se retrasa:</strong>",
"<strong>Persistencia.</strong> Los eventos pendientes se sientan en una tabla SQLite (<code>digest_pending</code>) hasta la hora configurada. El Monitor puede reiniciar libremente sin perder lo que el digest eventualmente contendrá.",
"<strong>Los días vacíos son silenciosos.</strong> Si nada de nivel INFO pasó, no se envía digest — el canal se mantiene quieto en vez de recibir un mensaje \"no hay eventos para reportar\"."
"<strong>Persistencia.</strong> Los pendientes se guardan en SQLite, tabla <code>digest_pending</code>, hasta la hora elegida y sobreviven a reinicios.",
"<strong>Sin eventos, sin resumen.</strong> Si no hay avisos INFO pendientes, no se envía ningún resumen vacío."
],
"neverDelayedSub": [
"Los eventos <strong>CRITICAL</strong> siempre pasan inmediatamente.",
"Los eventos <strong>WARNING</strong> siempre pasan inmediatamente.",
"Eventos de acción en vivo (VM/CT start / stop / shutdown / restart, vm_fail / ct_fail, backup start / fail, replication start / fail, host shutdown / reboot) saltean el digest incluso con severidad INFO — has hecho opt-in a verlos en vivo, el digest derrotaría ese opt-in."
"Las acciones de VM/CT, sus fallos, inicio y resultados de backups, resultados de replicación y apagado o reinicio del host evitan el resumen incluso con nivel INFO. Las horas de silencio sí pueden retrasarlas si no son críticas."
],
"comboTitle": "Combinar Quiet Hours y Daily Digest",
"comboBody": "Los dos funcionan juntos. Un canal puede tener <em>ambos</em> activos — Quiet Hours de 22:00 a 07:00 más un Daily Digest a las 09:00. Los eventos INFO durante la ventana quiet van al buffer quiet y llegan a las 07:00 como el resumen de cierre de ventana; los eventos INFO durante el día van al buffer digest y llegan a las 09:00 a la mañana siguiente. CRITICAL y WARNING siempre atraviesan ambos. Elige Quiet Hours cuando el objetivo es una <em>ventana de silencio</em>, el Daily Digest cuando el objetivo es un <em>resumen a hora fija</em>; muchos setups quieren ambos."
"comboTitle": "Combinar horas de silencio y resumen diario",
"comboBody": "Puedes activar <em>ambos</em>: silencio de 22:00 a 07:00 y resumen a 09:00. Los avisos no críticos del intervalo se liberan en el resumen de 07:00; los INFO aptos de fuera van al resumen diario. CRITICAL evita ambos; WARNING evita el diario, pero espera durante el silencio. Elige un <em>intervalo sin avisos</em>, un <em>resumen a hora fija</em> o ambos."
},
"displayName": {
"heading": "Display Name",
"intro": "Cada notificación lleva un <em>Display Name</em> — la etiqueta que identifica qué host produjo la alerta. Es el valor que ves al final del ejemplo de mensajes ricos arriba (<code>🏠 home-lab</code>) y dentro del prefijo de asunto del email.",
"imageAlt": "Campo Display Name con el valor amd mostrado como ejemplo, etiqueta Name shown in notifications - edit to customize or leave empty to use the system hostname",
"imageCaption": "El campo Display Name — déjalo vacío para usar el hostname del sistema, o sobreescríbelo con lo que quieras.",
"heading": "Nombre visible",
"intro": "Cada aviso lleva un <em>Nombre visible</em> para identificar el host, como <code>🏠 home-lab</code> al pie del ejemplo y en el prefijo del asunto del correo.",
"imageAlt": "Campo Nombre visible con amd como ejemplo; permite un nombre propio o usar el del sistema si queda vacío",
"imageCaption": "Nombre visible: déjalo vacío para usar el nombre del host o escribe uno propio.",
"outro": "Si el campo está vacío, el Monitor cae al hostname del sistema. El override es sobre todo útil cuando corres varios hosts ProxMenux que envían al mismo chat de Telegram o buzón — una etiqueta más amigable (<em>home-lab</em>, <em>office-pve</em>) es más fácil de leer que <code>pve01.lan</code> o <code>pmx-prod-01</code>."
},
"dispatch": {
"heading": "Pipeline de despacho",
"intro": "Entre que un evento se levanta y un mensaje sale del host, corren tres etapas en este orden:",
"heading": "Proceso de envío",
"intro": "La tabla describe tres mecanismos relacionados. El proceso real empieza con la agrupación de ráfagas, sigue con reserva de entrega, intervalos de repetición y límites por grupo, y termina con formato y controles de cada canal:",
"headerStage": "Etapa",
"headerWhat": "Qué hace",
"headerTunable": "¿Ajustable?",
"rows": [
{
"stage": "1. Deduplicación por huella",
"stage": "Deduplicación por huella",
"what": "Cada evento genera una huella (<code>event_type + key fields from data</code>). Las huellas idénticas dentro de una ventana corta se consideran duplicados del primero.",
"tunable": "No — lógica interna del dispatcher."
},
{
"stage": "2. Cooldown",
"what": "Cuando una huella ya se ha enviado, esa misma huella se silencia durante el cooldown propio de cada severidad. El estado se guarda en la tabla SQLite <code>notification_last_sent</code> para que sobreviva a reinicios. Valores por defecto: <code>CRITICAL</code> 60 s, <code>WARNING</code> 300 s, <code>INFO</code> 900 s, con posibilidad de override por categoría (por ejemplo <code>resources</code> 900 s, <code>updates</code> 86 400 s).",
"tunable": "No — valores por defecto integrados en el dispatcher."
"stage": "Intervalo de repetición",
"what": "Tras un envío correcto se suprimen huellas repetidas y se guarda el estado en <code>notification_last_sent</code>. Las bases de <code>CRITICAL</code>, <code>WARNING</code> e <code>INFO</code> son 86400 s, igual que <code>resources</code> y <code>updates</code>. Excepciones: 5 s para acciones VM/CT y apagado/reinicio, 10 s para resultados de backups/replicación y 1800–3600 s para varias categorías de salud. Los ajustes explícitos por evento o grupo prevalecen.",
"tunable": "Solo mediante la API de ajustes: una clave <code>cooldown.&lt;event_type&gt;</code> o <code>cooldown.&lt;group&gt;</code> sustituye los valores predeterminados; no hay control en la interfaz."
},
{
"stage": "3. Agregación de ráfagas",
"stage": "Agrupación de ráfagas",
"what": "Cuando llegan N eventos del mismo tipo dentro de una ventana corta (por ejemplo un aluvión de intentos de fuerza bruta SSH), se agrupan en un único mensaje <code>burst_*</code> con un contador y una muestra.",
"tunable": "No — ventana y umbral están fijados por tipo de evento."
}
],
"calloutTitle": "El despacho ocurre en un hilo de fondo",
"calloutBody": "El bucle de despacho corre en su propio hilo. La petición HTTP que emite un evento devuelve en cuanto el evento se encola — no espera al RTT de Telegram, SMTP o el webhook. Cada resultado de envío se registra en la tabla de historial para revisarlo después."
"calloutTitle": "El envío se ejecuta en segundo plano",
"calloutBody": "La petición HTTP termina al poner el evento en cola; el hilo de envío espera las respuestas de Telegram, SMTP o webhook y guarda los resultados en el historial."
},
"aiRewrite": {
"heading": "Reescritura con IA opcional",
"body1": "Cualquier evento se puede pasar por un LLM que reescribe su cuerpo en lenguaje natural y (opcionalmente) en el idioma del usuario destino antes del fan-out. El reescritor de IA está off por defecto. Cuando se activa corre en el hilo de despacho; si la llamada al proveedor falla o caduca, se usa el cuerpo templated original en su lugar.",
"body2": "Se soportan seis proveedores (OpenAI, Anthropic, Google Gemini, Groq, OpenRouter y Ollama local), con nivel de detalle por canal (<code>brief</code>, <code>standard</code>, <code>detailed</code>), idioma de salida, modo de prompt (<code>default</code> o <code>custom</code>) y un prompt personalizado opcional. El walkthrough de configuración completo, capturas y ejemplos de prompt viven en la página dedicada <link>Asistente de IA</link>.",
"body1": "Los eventos aptos pueden reescribirse con un LLM. Los resultados backup_complete y backup_fail lo omiten. La IA está desactivada por defecto y se ejecuta en el hilo de envío. Si falla o agota el tiempo, se usa la plantilla original.",
"body2": "Admite OpenAI, Anthropic, Google Gemini, Groq, OpenRouter y Ollama local, con detalle por canal (<code>brief</code>, <code>standard</code>, <code>detailed</code>), idioma, modo de instrucciones (<code>default</code> o <code>custom</code>) e instrucciones propias. Guía y ejemplos en <link>Asistente de IA</link>.",
"privacyTitle": "Nota de privacidad",
"privacyBody": "La reescritura con IA envía el cuerpo del evento — que puede incluir hostnames, direcciones IP, usernames, mensajes de error y líneas de journal — al proveedor configurado. Ollama mantiene todo en el host; los otros cinco proveedores transmiten datos a sus respectivos endpoints. Desactiva el reescritor, o usa Ollama, si el host corre en un entorno donde el contenido de los eventos no puede salir de la red."
"privacyBody": "La petición de IA puede incluir título, severidad, texto, instrucciones del sistema o propias y contexto, con nombres de host, IP, usuarios, errores y registros. Se envía al destino elegido. Ollama solo procesa localmente con servidor y modelo locales; un servidor remoto o modelo en la nube envía datos fuera del host. Desactiva la reescritura o usa un servidor y modelo locales controlados si el contenido debe permanecer en la red."
},
"pveWebhook": {
"heading": "Integración del webhook de PVE",
"intro1": "Proxmox VE 8.1+ tiene su propio sistema de notificaciones con <em>endpoints</em> integrados (sendmail, gotify, SMTP, webhook). Cuando activas Notifications en el Monitor, se registra como uno de esos endpoints — un destino <code>webhook</code> que apunta de vuelta a la propia API del Monitor. Desde ese momento, todo lo que Proxmox mismo emite (fencing HA, replicación, vzdump desde la GUI, renovación de certificado, etc.) fluye por la misma pipeline de despacho que los eventos propios del Monitor.",
"intro2": "El destino es visible desde la GUI de Proxmox en <em>Datacenter → Notifications → Notification Targets</em>:",
"intro1": "El sistema de notificaciones Proxmox tiene <em>destinos</em> sendmail, Gotify, SMTP y, en versiones compatibles, webhook. Monitor registra un destino <code>webhook</code> al activarse. Los avisos de PVE, como HA, replicación y backups desde la interfaz, entran así en el mismo proceso de envío.",
"intro2": "Puedes verlo en <em>Datacenter → Notificaciones → Destinos de notificación</em>.",
"imageAlt": "Diálogo Proxmox VE Edit Webhook mostrando el destino proxmenux-webhook autocreado con método POST, URL http://127.0.0.1:8008/api/notifications/webhook y una plantilla JSON usando escape title, escape message, escape severity, escape timestamp y campos json",
"imageCaption": "El destino webhook del lado PVE como Proxmox lo ve (la GUI está en el locale configurado del host — español en este ejemplo). Los mismos campos aplican en cualquier idioma.",
"registeredIntro": "Qué se registra:",
"registeredItems": [
"<strong>Método y URL.</strong> <code>POST http://127.0.0.1:8008/api/notifications/webhook</code>. Solo loopback — PVE habla con el proceso del Monitor corriendo en el mismo host.",
"<strong>Plantilla de body.</strong> Un body JSON usando los helpers Handlebars nativos de PVE — guardado base64-encoded en el archivo de config por PVE, pero se expande a:",
"<strong>Método y URL.</strong> <code>POST http://127.0.0.1:8008/api/notifications/webhook</code> sin HTTPS en Monitor. Con HTTPS, usa el receptor HTTP local del puerto 8009. Ambos permanecen en el mismo host.",
"<strong>Plantilla del cuerpo.</strong> JSON con funciones Handlebars de PVE, guardado como base64 en la configuración. Al expandirse resulta:",
"<strong>Matcher.</strong> Un bloque compañero <code>matcher: proxmenux-matcher</code> con <code>mode all</code> para que cada notificación de PVE llegue al destino.",
"<strong>Bloque priv compañero.</strong> Una entrada vacía <code>webhook: proxmenux-webhook</code> se añade a <code>/etc/pve/priv/notifications.cfg</code>. PVE se niega a instanciar cualquier endpoint webhook sin un bloque privado coincidente, incluso cuando no se necesitan secrets — así que el Monitor escribe un stub solo de cabecera ahí. No se configuran tokens, cabeceras ni HMAC en el lado PVE."
"<strong>Configuración privada.</strong> Se escribe el bloque <code>webhook: proxmenux-webhook</code> en <code>/etc/pve/priv/notifications.cfg</code> con una entrada <code>secret</code> llamada X-Webhook-Secret, codificada en base64. El bloque del destino público solo contiene la plantilla del cuerpo, el método y la URL. El bloque privado no está vacío."
],
"securityTitle": "Cómo se asegura el receptor",
"securityIntro": "El receptor webhook en <code>POST /api/notifications/webhook</code> aplica distintas capas de seguridad según de dónde venga la petición:",
"securityItems": [
"<strong>Loopback (<code>127.0.0.1</code> / <code>::1</code>).</strong> Solo rate-limit. El endpoint confía en la interfaz loopback — solo procesos corriendo en el host pueden alcanzarlo, y PVE mismo no puede enviar cabeceras de auth personalizadas en el body que genera. Este es el camino que viaja cada notificación emitida por PVE.",
"<strong>Llamadores remotos.</strong> Cinco capas se apilan encima del rate-limiting: un shared secret en la cabecera <code>X-Webhook-Secret</code>, un timestamp de frescura en <code>X-ProxMenux-Timestamp</code> (rechazado si se desvía más allá de la ventana configurada), una búsqueda de caché de replay y una allowlist de IP opcional. El shared secret vive en la tabla de ajustes SQLite del Monitor — no en <code>/etc/pve/priv/notifications.cfg</code> — y se genera en el primer setup. Este camino existe para integraciones personalizadas que hacen POST desde fuera del host; el destino configurado por PVE nunca lo ejercita."
"<strong>Orígenes locales (<code>127.0.0.1</code> / <code>::1</code>).</strong> Se aplica límite de peticiones, pero se omiten las comprobaciones remotas de secreto, tiempo y repetición. También se consideran locales las IP asignadas a las interfaces del host. El destino automático de PVE usa loopback.",
"<strong>Peticiones remotas.</strong> Además del límite de envíos, se comprueban el secreto de <code>X-Webhook-Secret</code>, la fecha en <code>X-ProxMenux-Timestamp</code> o el JSON, las repeticiones y la lista opcional de IP. El secreto está en SQLite y también se copia en base64 a <code>/etc/pve/priv/notifications.cfg</code> para que PVE envíe la cabecera."
],
"practiceTitle": "En la práctica",
"practiceBody": "El setup de PVE escribe el destino como <code>http://127.0.0.1:8008</code>, así que las notificaciones emitidas por PVE siempre pasan por el camino loopback con seguridad solo rate-limit. El camino de llamador remoto con shared secret es opt-in para integraciones personalizadas — apunta un servicio externo a <code>https://&lt;monitor-host&gt;:&lt;port&gt;/api/notifications/webhook</code> y suministra la cabecera <code>X-Webhook-Secret</code> para usarlo.",
"practiceBody": "PVE usa <code>http://127.0.0.1:8008</code> sin HTTPS, o HTTP en 8009 con HTTPS. Las integraciones externas en <code>https://&lt;monitor-host&gt;:&lt;port&gt;/api/notifications/webhook</code> deben enviar <code>X-Webhook-Secret</code> y una fecha actual, y superar las comprobaciones de repetición e IP. El secreto solo no basta.",
"actionsIntro": "El Monitor gestiona este destino a través de tres acciones en la pestaña Settings:",
"actionsItems": [
"<strong>Setup</strong> — corre automáticamente cuando activas Notifications. Crea la entrada en <code>/etc/pve/notifications.cfg</code>. El archivo solo se escribe cuando su contenido tiene que cambiar, y se guarda un backup del anterior en <code>/usr/local/share/proxmenux/backups/pve-notifications/</code> (los tres más recientes). No se escribe nada mientras <code>/etc/pve</code> no está montado: un Monitor que arranca durante un reinicio de <code>pve-cluster</code> registra la entrada cuando vuelve.",
"<strong>Cleanup</strong> — elimina la entrada. El backup previo del archivo se conserva.",
"<strong>Read config</strong> — muestra los destinos y matchers actuales como PVE los ve. Así es como confirmas que la entrada del Monitor es la que dispara cuando PVE tiene múltiples rutas de notificación configuradas."
"<strong>Configurar</strong>: al activar las notificaciones crea la entrada en <code>/etc/pve/notifications.cfg</code>. Solo escribe cambios y conserva las tres copias anteriores más recientes en <code>/usr/local/share/proxmenux/backups/pve-notifications/</code>. Mientras <code>/etc/pve</code> no está montado no escribe; registra la entrada cuando <code>pve-cluster</code> vuelve a estar disponible.",
"<strong>Limpiar</strong>: elimina la entrada y conserva la copia anterior.",
"<strong>Leer configuración</strong>: muestra destinos y reglas para comprobar qué ruta de notificación usa PVE."
],
"clusterTitle": "Nodos de cluster",
"clusterBody": "<code>/etc/pve/</code> se replica entre miembros del cluster, así que el destino webhook es visible en cada nodo. Cada nodo, sin embargo, hace POST a su <em>propio</em> <code>127.0.0.1:8008</code> — lo que significa que el Monitor corriendo en ese nodo recibe los eventos que PVE generó localmente. Ejecuta el Monitor en cada nodo que quieras ver en el historial de Notifications."
"clusterBody": "<code>/etc/pve/</code> se comparte en el clúster, incluida URL y secreto. Cada nodo llama a su receptor <em>local</em>: <code>127.0.0.1:8008</code> sin HTTPS, o HTTP 8009 con HTTPS. Ejecuta Monitor en cada nodo necesario y mantén el destino compartido compatible con sus receptores."
},
"catalogue": {
"heading": "Catálogo de eventos",
"intro": "Unos setenta tipos de evento están agrupados en once categorías de UI. El panel Notifications renderiza una sección colapsable por grupo con un toggle por cada evento dentro. Cada evento está on por defecto salvo que se marque explícitamente lo contrario.",
"intro": "Unos setenta tipos se agrupan en once categorías. Cada sección desplegable permite activar eventos. Están activos por defecto salvo indicación contraria.",
"headerGroup": "Grupo",
"headerEvents": "Eventos",
"rows": [
@@ -380,7 +380,7 @@
"events": "<code>auth_fail</code>, <code>ip_block</code>, <code>firewall_issue</code>, <code>user_permission_change</code>."
},
{
"group": "Cluster",
"group": "Clúster",
"events": "<code>split_brain</code>, <code>node_disconnect</code>, <code>node_reconnect</code>."
},
{
@@ -400,52 +400,52 @@
"events": "<code>gpu_mode_switch</code>, <code>gpu_passthrough_blocked</code>, <code>pci_passthrough_conflict</code>, <code>ai_model_migrated</code>."
}
],
"burstNote": "Un puñado de tipos de agregación <code>burst_*</code> (<code>burst_auth_fail</code>, <code>burst_ip_block</code>, <code>burst_disk_io</code>, etc.) existen solo en el dispatcher — reemplazan ráfagas de eventos individuales con un único mensaje de resumen y no se exponen como toggles en la UI. Heredan el estado on/off de su tipo de evento padre.",
"burstNote": "Los tipos agrupados <code>burst_*</code> (<code>burst_auth_fail</code>, <code>burst_ip_block</code>, <code>burst_disk_io</code>, etc.) sustituyen ráfagas por un resumen. No tienen controles propios en la interfaz y heredan los del evento de origen.",
"backupResults": {
"heading": "Resultados de backup",
"intro": "Una notificación sobre un trabajo de backup de Proxmox indica cómo terminó el trabajo. El resultado se lee del informe que envía Proxmox, y determina el título, el icono que se muestra con <em>Rich messages</em> activado y la fila de estado del email.",
"headerIcon": "Icono",
"intro": "El informe de cada trabajo de backup determina su resultado, título, icono con <em>Mensajes enriquecidos</em> y fila de estado del correo.",
"headerIcon": "Icon",
"headerResult": "Resultado",
"headerWhen": "Cuándo",
"rows": [
{
"icon": "💾✅",
"result": "Backup completado",
"when": "Todos los guests del trabajo terminaron y el informe no contiene advertencias."
"when": "Todos los sistemas invitados terminaron sin advertencias en el informe."
},
{
"icon": "💾⚠️",
"result": "Backup completado con advertencias",
"when": "Todos los guests terminaron y el informe contiene al menos una línea de advertencia."
"when": "Todos los sistemas invitados terminaron y el informe contiene alguna advertencia."
},
{
"icon": "💾❌",
"result": "Backup fallido",
"when": "Un guest falló, o el trabajo se detuvo con un error."
"when": "Falló un sistema invitado o el trabajo terminó con un error."
},
{
"icon": "💾❔",
"result": "Resultado del backup sin confirmar",
"when": "El informe está incompleto o no indica un resultado para cada guest."
"when": "El informe está incompleto o no indica el resultado de cada sistema invitado."
}
],
"items": [
"<strong>El título indica sobre qué era el trabajo.</strong> Incluye el almacenamiento y, en un trabajo con un solo guest, su tipo, nombre e ID. Un trabajo fallido nombra el guest que falló.",
"<strong>El cuerpo lista cada guest</strong> con su propio resultado, tamaño, duración y archivo, seguido de una línea con los totales del trabajo.",
"<strong>El título identifica el trabajo.</strong> Incluye almacenamiento y, si solo hay un invitado, su tipo, nombre e ID. Si falla, identifica el invitado afectado.",
"<strong>El cuerpo detalla cada sistema invitado</strong>, con resultado, tamaño, duración y archivo, seguido de los totales.",
"<strong>Las advertencias y los errores se listan una vez.</strong> Las líneas repetidas se muestran una sola vez con la causa principal primero; a partir de ocho líneas, el resto se cuenta en una línea de cierre y permanece en el log de la tarea de Proxmox.",
"<strong>Un trabajo que falla antes de su primer guest</strong> muestra la causa que dio Proxmox, por ejemplo un almacenamiento que no existe.",
"<strong>Los resúmenes conservan el resultado.</strong> Un backup listado en el resumen de Quiet Hours o en el Daily Digest lleva el icono de su propio resultado."
"<strong>Un trabajo que falla antes del primer invitado</strong> muestra la causa indicada por Proxmox, por ejemplo un almacenamiento inexistente.",
"<strong>Los resúmenes conservan el resultado.</strong> Un backup en el resumen de horas de silencio conserva su icono. Los resultados de backups evitan el resumen diario."
]
}
},
"history": {
"heading": "Historial",
"body1": "Cada <em>intento</em> de despacho que el dispatcher realmente ejecuta se registra en la tabla SQLite <code>notification_history</code>. Cada fila guarda el timestamp (<code>sent_at</code>), canal, tipo de evento, severidad, título, cuerpo de mensaje renderizado, un flag <code>success</code> y — cuando el envío falló — el error devuelto por el proveedor en <code>error_message</code>. Los eventos agregados en ráfaga aparecen como una única fila con el tipo de evento <code>burst_*</code>. Los eventos suprimidos por la etapa de cooldown no se loguean: nunca se convierten en un intento de despacho.",
"body1": "Cada <em>intento</em> de envío realizado se guarda en <code>notification_history</code>: fecha <code>sent_at</code>, canal, evento, severidad, título, cuerpo, indicador <code>success</code> y, si falla, <code>error_message</code>. Las ráfagas usan una fila de tipo <code>burst_*</code>. Los eventos suprimidos por el intervalo de repetición no se registran.",
"body2": "Settings → Notifications tiene una sección <em>Historial de notificaciones</em>, cerrada por defecto, con las últimas 20 entradas: el resultado de cada envío, su canal y su fecha, el error cuando falló y, en cada ejecución del resumen diario, si tenía algo que enviar. La página no ofrece borrarlo: Audit & Report lee ese mismo historial para comprobar la entrega de cada canal.",
"body3": "Los mismos datos se exponen en <code>GET /api/notifications/history</code> con parámetros opcionales <code>limit</code>, <code>offset</code>, <code>severity</code> y <code>channel</code>, y se pueden borrar con <code>DELETE /api/notifications/history</code>."
},
"api": {
"heading": "Endpoints de API",
"heading": "Endpoints de la API",
"headerEndpoint": "Endpoint",
"headerMethod": "Método",
"headerUse": "Uso",
@@ -453,7 +453,7 @@
{
"endpoint": "/api/notifications/settings",
"method": "GET / POST",
"use": "Lee o escribe la configuración completa (canales, toggles por evento, reescritor de IA, Display Name)."
"use": "Lee o escribe la configuración: canales, controles por evento, IA y nombre visible."
},
{
"endpoint": "/api/notifications/test",
@@ -483,7 +483,7 @@
{
"endpoint": "/api/notifications/webhook",
"method": "POST",
"use": "Recibe las notificaciones propias de Proxmox VE. Los llamadores loopback están solo rate-limited; los llamadores remotos deben pasar adicionalmente la cabecera <code>X-Webhook-Secret</code>, comprobación de frescura <code>X-ProxMenux-Timestamp</code>, caché de replay y allowlist de IP opcional."
"use": "Recibe avisos de Proxmox. Los orígenes locales omiten las comprobaciones remotas, pero tienen límite de peticiones. Los remotos se comprueban con <code>X-Webhook-Secret</code>, fecha en <code>X-ProxMenux-Timestamp</code> o JSON, detección de repeticiones y lista de IP configurada."
},
{
"endpoint": "/api/notifications/proxmox/setup-webhook",
@@ -508,7 +508,7 @@
{
"label": "Asistente de IA",
"href": "/docs/monitor/ai-assistant",
"tail": " — proveedores, modelos, modos de prompt, idiomas, niveles de detalle por canal."
"tail": " — proveedores, modelos, modos de instrucciones, idiomas y detalle por canal."
},
{
"label": "Monitor de salud",
@@ -521,14 +521,14 @@
"tailRich": " — dónde encajan las tablas SQLite (<code>notification_last_sent</code>, <code>notification_history</code>) y el hilo de despacho en el proceso más amplio del Monitor."
},
{
"label": "Access & Authentication",
"label": "Acceso y autenticación",
"href": "/docs/monitor/access-auth",
"tailRich": " — cómo se emiten API tokens para scripts que llaman a <code>/api/notifications/send</code>."
},
{
"label": "Dashboard → Logs del sistema",
"href": "/docs/monitor/dashboard/system-logs",
"tail": " — la vista en vivo del mismo journal que alimenta el journal watcher."
"tail": " — vista en directo del registro del sistema que alimenta su monitor de eventos."
}
]
}