|
|
пре 17 часа | |
|---|---|---|
| WhmcsHelpers | пре 17 часа | |
| assets | пре 17 часа | |
| docs | пре 17 часа | |
| lib | пре 17 часа | |
| templates | пре 17 часа | |
| tests | пре 17 часа | |
| tools | пре 17 часа | |
| .gitignore | пре 17 часа | |
| AUDIT.md | пре 17 часа | |
| README.md | пре 17 часа | |
| config.example.php | пре 17 часа | |
| vpsmanager.php | пре 17 часа | |
Módulo VPSManager para WHMCS con controles de reinicio, parada, arranque, firewall, snapshots, suspensión/reactivación, enlace al panel y métricas Graphite de servicios LX.
Esta versión parte del módulo facilitado y conserva su comportamiento de provisioning.
CreateAccount ya devolvía success sin provisionar; TerminateAccount, ChangePackage
y ChangePassword estaban vacíos y siguen así. No se debe asumir que estas funciones
estén implementadas. El tratamiento de errores de los comandos de provisioning sigue
siendo el heredado: un success no acredita por sí solo que el backend ejecutó la acción.
No se ha reescrito suspensión/reactivación ni su contrato HTTP.
Instalar vpsmanager.php, lib/, WhmcsHelpers/, templates/ y assets/ dentro de
<WHMCS>/modules/servers/vpsmanager/. Mantener el nombre del directorio vpsmanager.
No instalar .git/, tests/ ni tools/ en el servidor web. Los ficheros vacíos logo.png
y hooks.php del original no se distribuyen.
No se cambia el orden de las opciones existentes del módulo ni los nombres de sus custom
fields. Es obligatorio que uuid, vtype, gzid, url, username y password sean
campos administrados por el servidor/administrador, no editables ni mostrados al cliente.
Revisar la configuración de custom fields y la plantilla WHMCS: el módulo ya no imprime
contraseñas, pero no puede corregir una plantilla externa que imprima esos campos.
Copiar config.example.php fuera del árbol web y del repositorio, normalmente a:
/etc/open6hosting/whmcs-vpsmanager.php
La variable de entorno O6H_VPSMANAGER_CONFIG permite usar otra ruta absoluta.
Si se utiliza PHP-FPM, comprobar que el pool realmente transmite esa variable.
vpsmanager_api_url: base de la API VPSManager, sin barra final. Se admite HTTP para
conservar la compatibilidad con la API original; preferir HTTPS o transporte privado
protegido. No deshabilitar la verificación TLS.graphite_url: base HTTPS de Graphite, sin /render/, credenciales embebidas,
query string ni fragmento. La implementación añade /render/.graphs_url: base HTTPS de la vista completa antigua, opcional.graphs_authorization_confirmed: poner a true únicamente tras comprobar que la
vista completa autentica al cliente y autoriza el VPS solicitado. Con URL ausente o sin
esa comprobación se conserva el botón Graphs, desactivado. El UUID en la URL no es
un control de acceso. Las nuevas tres gráficas no dependen de esa vista externa.Configurar solamente los valores privados reales en el fichero externo, nunca en el archivo de ejemplo. No se han incluido valores de producción en este repositorio.
Permisos recomendados: directorio 0750, fichero 0640, propietario administrador y
un grupo que permita lectura al usuario real de PHP-FPM/servidor web. Adaptar usuario y
grupo a la instalación. PHP no debe poder escribir esa configuración. Nunca chmod 777.
La configuración PHP es código de confianza controlado por el administrador.
La falta de configuración no debe generar un fatal del módulo: las métricas muestran un aviso discreto, los comandos que requieren la API devuelven un error genérico y los selectores de nodos/paquetes quedan vacíos. No guardar una configuración de producto hasta restablecer estos selectores.
Solo vtype = lx. El UUID debe tener formato hexadecimal 8-4-4-4-12, por ejemplo el
UUID ficticio 00000000-0000-4000-8000-000000000001. Los targets internos son:
| Gráfica / serie | Target bajo lx.<uuid>. |
Transformación |
|---|---|---|
| Carga / 1 min | load.load.shortterm |
Ninguna |
| Carga / 5 min | load.load.midterm |
Ninguna |
| Carga / 15 min | load.load.longterm |
Ninguna |
| Memoria usada | memory.memory-used |
Bytes, presentación IEC |
| Memoria libre | memory.memory-free |
Bytes, usada para calcular el total |
| Red RX | interface-eth0.if_octets.rx |
Bytes/s → bits/s, una vez al presentar |
| Red TX | interface-eth0.if_octets.tx |
Bytes/s → bits/s, una vez al presentar |
La carga no es porcentaje de CPU. Memoria total = usada + libre en el mismo timestamp;
porcentaje = usada / total × 100 si ambos datos existen y el total es positivo. No hay una
capacidad fija. Una serie de memoria ausente no se interpreta como cero. La red ya contiene
tasas: no se aplica derivative ni nonNegativeDerivative, ni se calcula volumen mensual.
Se agrupan los siete targets en una petición, con format=json, until=now y
maxDataPoints=1000. Se conserva la resolución devuelta por Graphite, los timestamps y
los huecos null; no se unen las líneas a través de esos huecos. El resumen corresponde
al timestamp más reciente de la gráfica y muestra su fecha/hora local del navegador;
no sustituye un dato ausente por una muestra antigua. No existe actualización automática.
Rangos: 1h, 6h, 24h por defecto, 7d, 30d. Cualquier otra entrada cae a 24h.
Los enlaces recargan clientarea.php?action=productdetails&id=<servicio>&metrics_range=<rango>.
No hay endpoint AJAX ni endpoint de métricas accesible directamente. WHMCS autoriza el
servicio antes de invocar vpsmanager_ClientArea; el módulo solo toma UUID/tipo de $params
y nunca de GET/POST. Cambiar id vuelve a pasar por la autorización de WHMCS.
PHP mantiene verificación TLS y no sigue redirecciones. Connect timeout 3 s, total 5 s, respuesta limitada a 2 MiB. Un fallo HTTP, timeout, JSON inválido o dato mal formado muestra Las métricas no están disponibles temporalmente. sin bloquear los demás controles. Las series ausentes pueden convivir con las disponibles. No se registran cuerpos HTTP, excepciones detalladas, configuración, credenciales ni parámetros completos de WHMCS.
Graphite admite autenticación HTTP Basic sobre HTTPS mediante configuración privada:
'graphite_auth' => 'basic',
'graphite_username' => '', // Completar solo en el fichero privado.
'graphite_password' => '', // Completar solo en el fichero privado.
Usuario y contraseña son de una cuenta técnica exclusiva para WHMCS, no de los clientes.
Se envían mediante las opciones de autenticación cURL, nunca en la URL, HTML o JavaScript.
Una configuración Basic incompleta o inválida impide enviar la petición; no hay fallback
anónimo. HTTP 401/403 y redirecciones muestran el aviso genérico de métricas no disponibles.
TLS sigue siendo obligatorio. none conserva compatibilidad con instalaciones anteriores,
pero NO protege Graphite: para el despliegue protegido seleccionar basic.
La protección de entrada se configura en Apache; actualizar este módulo no cierra por sí
solo el acceso público. Seguir la guía Apache, incluyendo la
protección de rutas Render/API y puertos de backend. No compartir la cuenta técnica con
clientes. graphs_authorization_confirmed debe permanecer en false para la vista Graphs
antigua, que carece de autorización por VPS.
Las vistas y la lógica Graphite están separadas de las operaciones existentes.
Las tres cards usan clases compatibles con Bootstrap y estilos limitados al módulo.
Se reutiliza window.Chart si es Chart.js 4.x; en otro caso se carga Chart.js 4.4.8
localmente y se restaura cualquier window.Chart previo. No se consultan CDNs en visitas.
No se ha podido inspeccionar la plantilla instalada; comprobar compatibilidad en staging.
El eje temporal numérico permite timestamps irregulares sin adaptador de fechas externo.
Antes: el módulo insertaba usuario/contraseña ISPConfig en JavaScript y los enviaba por AJAX desde el navegador, tanto en cliente como en administración.
Después: Acceder al Panel abre únicamente el login HTTPS en otra pestaña, con
noopener noreferrer. No se incorpora usuario ni contraseña. No hay autologin: el código
recibido no incluía un mecanismo SSO seguro. No se ha inventado ninguno.
Las URLs inseguras, con credenciales, query string o fragmentos no generan enlaces activos.
Las plantillas de acciones conservan las operaciones y añaden escape HTML y el token CSRF de WHMCS. El módulo depende del dispatcher de WHMCS para autenticación, autorización y validación del token. No exponer las acciones mediante un endpoint personalizado.
Desde la raíz del repositorio:
find . -type f -name '*.php' -not -path './.git/*' -print0 | xargs -0 -n1 php -n -l
php -n tests/run.php
node tests/frontend.cjs
node --check assets/metrics.js
python3 tools/audit.py
php -n es deliberado: el test sustituye cURL por dobles y no realiza ninguna conexión.
Cubre configuración, UUID/tipo/rangos, fallos HTTP/JSON/timeout, respuesta grande, series
parciales, huecos, alineación temporal, cálculos, ausencia de secretos en HTML, manipulación
GET/POST y rutas/payloads de las operaciones existentes. Los fixtures usan dominios .invalid,
IPs de documentación y contraseñas ficticias identificadas con FAKE_.
Los tests JS verifican unidades, huecos, carga local y conservación de otra versión de Chart.js.
tools/scope-chart.cjs genera el bundle aislado a partir del fichero upstream, cuya licencia
MIT y procedencia constan en assets/Chart.js.LICENSE.md y assets/THIRD-PARTY.md.
No confundir esa licencia con una licencia para nuestro proyecto.
La prueba de aislamiento de UUID invoca el hook con los parámetros de un servicio y peticiones
GET/POST que intentan elegir otro. La prueba end-to-end del dispatcher requiere WHMCS real:
con dos clientes y servicios distintos, verificar que el cliente A no puede acceder al
id del B, con cualquiera de los cinco rangos, ni alterar los campos UUID/tipo. Verificar
además token CSRF de las acciones, biblioteca/tema instalado, CSP y los controles en staging.
No se han ejecutado reinicios, restauraciones o suspensiones sobre infraestructura real.
El repositorio público debe empezar con un único commit limpio, sin importar historial
anterior. No copiar el ZIP original, backups, configuración real ni el directorio de trabajo.
tools/audit.py revisa árbol, índice o archivos versionados; revisar también sus límites en
AUDIT.md. Ningún escáner prueba la ausencia absoluta de todos los posibles secretos.
Destino previsto: https://gitea.open6hosting.com/Open6Hosting/whmcs-vpsmanager.
No hacer force-push sobre un repositorio existente.
Licencia del proyecto pendiente de decisión del titular. No se concede una licencia
open source por defecto. Se conserva el aviso de copyright original de WhmcsHelpers/CustomField.php;
confirmar también los derechos de redistribución de ese helper antes de declarar una licencia
global. La licencia de Chart.js solo cubre ese componente de terceros.