From 0be508e749098de5b80bd45326cdc80f7d096a42 Mon Sep 17 00:00:00 2001 From: DANYDHSV Date: Wed, 26 Nov 2025 12:16:49 -0600 Subject: [PATCH] =?UTF-8?q?caracter=C3=ADstica:=20Se=20introdujeron=20Endp?= =?UTF-8?q?oints=20API=20REST=20para=20b=C3=BAsqueda=20y=20verificaci?= =?UTF-8?q?=C3=B3n=20de=20IP=20con=20clasificaci=C3=B3n=20de=20tipo=20IP?= =?UTF-8?q?=20y=20eliminar=20el=20script=20de=20IP=20heredado.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 173 +++++++++++++ README.md | 529 ++++++++++++++++++++++++++++++++++++++++ data/plugin.log | 244 ++++++++++++++++++ manifest.json | 2 +- public.php | 87 ++++++- script_obtener_ips.php | 48 ---- src/ApiHandlers.php | 216 ++++++++++++++++ src/IpSearchService.php | 51 ++++ 8 files changed, 1300 insertions(+), 50 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 README.md delete mode 100644 script_obtener_ips.php create mode 100644 src/ApiHandlers.php diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..12d85ee --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,173 @@ +# Changelog + +Todos los cambios notables en este proyecto serán documentados en este archivo. + +El formato está basado en [Keep a Changelog](https://keepachangelog.com/es-ES/1.0.0/), +y este proyecto adhiere a [Semantic Versioning](https://semver.org/lang/es/). + +--- + +## [1.1.0] - 2025-11-26 + +### ✨ Añadido + +#### API REST Completa +- **Endpoint `event.ip_request`**: Búsqueda de IPs disponibles en un segmento de red + - Acepta parámetro `segment` para especificar el tercer octeto (0-255) + - Retorna lista de IPs disponibles y en uso + - Filtra automáticamente IPs administrativas (1-30, 254) + - Incluye contadores de IPs disponibles, en uso y filtradas +- **Endpoint `event.ip_check`**: Verificación de estado de una IP específica + - Acepta parámetro `ip` con dirección completa (172.16.X.X) + - Retorna estado: disponible, en uso o desconocido + - Incluye información del tipo de IP (administrativa vs. cliente) + - Proporciona recomendaciones de uso +- **Soporte para webhooks**: Habilitado `supportsWebhookEvents: true` en manifest +- **Manejo de peticiones JSON**: Detección automática de Content-Type para API vs Frontend + +#### Arquitectura y Código +- **Clase `ApiHandlers.php`**: Manejadores dedicados para eventos de API REST + - `handleApiRequest()`: Router principal de eventos + - `handleIpRequest()`: Procesamiento de búsqueda de IPs + - `handleIpCheck()`: Procesamiento de verificación de IPs +- **Clase `IpSearchService.php`**: Servicio de búsqueda de IPs con lógica de negocio + - `buscarIpsDisponibles()`: Búsqueda de IPs en segmento específico + - `obtenerIpsEnUso()`: Obtención de IPs desde API UNMS + - `isAdminIp()`: Método estático para detectar IPs administrativas + - `getIpType()`: Método estático para obtener información del tipo de IP +- **Sistema de filtrado de IPs**: Clasificación automática de IPs administrativas vs. cliente + - Rango administrativo: .1-.30 y .254 + - Rango cliente: .31-.253 + - Etiquetas visuales en frontend + - Filtrado automático en API REST + +#### Documentación +- **README.md completo**: Documentación profesional del plugin + - Guía de instalación y configuración + - Documentación completa de API REST + - Ejemplos de uso en múltiples lenguajes (cURL, PHP, JavaScript, Python) + - Tabla de códigos de error + - Troubleshooting y soporte +- **CHANGELOG.md**: Archivo dedicado para control de versiones + +### 🔄 Mejorado + +- **Separación de responsabilidades**: Lógica de negocio separada en clases dedicadas +- **Manejo de errores mejorado**: Respuestas JSON estructuradas con códigos de error descriptivos +- **Sistema de logging**: Logs más detallados y organizados para debugging + - Registro de tipo de petición (HTML vs JSON) + - Logging de eventos API procesados + - Información de errores con stack traces +- **Compatibilidad dual**: Frontend HTML y API REST funcionan simultáneamente + - Detección automática del tipo de petición + - Sin interferencia entre modos +- **Validación de datos**: Validación robusta de parámetros en API + - Validación de formato de IP + - Validación de rangos de segmento + - Mensajes de error descriptivos + +### 🔧 Técnico + +- **Namespace PHP**: `SiipAvailableIps` para evitar conflictos +- **Manejo global de errores**: Error handler para convertir errores PHP en respuestas JSON +- **Configuración SSL**: Soporte para certificados autofirmados en desarrollo +- **Timeouts configurados**: Timeouts de conexión y ejecución para API UNMS + +--- + +## [1.0.1] - 2025-11-25 + +### ✨ Añadido + +- **Frontend web moderno**: Interfaz de usuario con diseño responsive y atractivo + - Diseño con gradientes y glassmorphism + - Tipografía Google Fonts (Inter) + - Animaciones suaves y micro-interacciones + - Modo oscuro integrado +- **Búsqueda de IPs por segmento**: Campo de entrada para tercer octeto +- **Función copiar al portapapeles**: Botón de copia rápida para cada IP + - Feedback visual al copiar + - Compatible con navegadores modernos +- **Estadísticas en tiempo real**: Contadores de IPs disponibles y en uso + - Tarjetas de estadísticas visuales + - Actualización dinámica tras búsqueda +- **Integración con API UNMS**: Conexión directa con UISP Network + - Obtención de IPs en uso desde dispositivos + - Soporte para HTTPS + - Manejo de errores de conexión + +### 🔄 Mejorado + +- **Conexión con API UNMS**: Optimización de peticiones HTTP + - Timeouts configurables + - Mejor manejo de errores de red + - Logging de respuestas +- **Búsqueda de IPs**: Algoritmo optimizado para comparación de rangos + - Ordenamiento de IPs por último octeto + - Cálculo eficiente de IPs disponibles + - Validación de segmentos (0-255) + +### 🐛 Corregido + +- Mejoras en la estabilidad de conexión con API UNMS +- Corrección de validación de segmentos fuera de rango +- Fix en ordenamiento de IPs en tabla de resultados + +--- + +## [1.0.0] - 2025-11-25 + +### ✨ Lanzamiento Inicial + +#### Funcionalidades Core +- **Búsqueda básica de IPs**: Funcionalidad principal del plugin + - Búsqueda en rangos 172.16.X.x + - Detección de IPs en uso + - Cálculo de IPs disponibles +- **Integración con UISP CRM**: Plugin nativo para UCRM + - Instalación vía interfaz de plugins + - Configuración desde panel de administración + - Acceso desde menú de reportes +- **Interfaz web básica**: Primera versión del frontend + - Formulario de búsqueda simple + - Tabla de resultados + - Diseño básico responsive + +#### Configuración +- **Parámetros de configuración**: + - Dirección IP/dominio del servidor + - Token de API UCRM + - Token de API UNMS (opcional) + - Modo debug + - Nivel de logging + +#### Integración +- **API UNMS**: Conexión con UISP Network para obtener IPs +- **Sistema de logs**: Archivo `plugin.log` para debugging +- **Compatibilidad**: UCRM 1.0.0+ y UNMS 1.0.0+ + +--- + +## Tipos de Cambios + +- **✨ Añadido**: Para nuevas funcionalidades +- **🔄 Mejorado**: Para cambios en funcionalidades existentes +- **🐛 Corregido**: Para corrección de bugs +- **🔧 Técnico**: Para cambios técnicos internos +- **🗑️ Eliminado**: Para funcionalidades removidas +- **⚠️ Deprecado**: Para funcionalidades que serán removidas +- **🔒 Seguridad**: Para parches de seguridad + +--- + +## Versionamiento + +Este proyecto sigue [Semantic Versioning](https://semver.org/lang/es/): + +- **MAJOR** (X.0.0): Cambios incompatibles con versiones anteriores +- **MINOR** (0.X.0): Nueva funcionalidad compatible con versiones anteriores +- **PATCH** (0.0.X): Correcciones de bugs compatibles con versiones anteriores + +--- + +**Última actualización**: 26 de noviembre de 2025 diff --git a/README.md b/README.md new file mode 100644 index 0000000..059032e --- /dev/null +++ b/README.md @@ -0,0 +1,529 @@ +# SIIP - Buscador de IP's Disponibles UISP + +[![Version](https://img.shields.io/badge/version-1.1.0-blue.svg)](manifest.json) +[![UCRM](https://img.shields.io/badge/UCRM-Compatible-green.svg)](https://uisp.com/) +[![UNMS](https://img.shields.io/badge/UNMS-Compatible-green.svg)](https://uisp.com/) + +Plugin para UISP CRM (anteriormente UCRM) que permite buscar direcciones IP disponibles en la red UISP/UNMS y asignarlas a clientes, evitando duplicados y mejorando la gestión de direcciones IP. + +--- + +## 📋 Tabla de Contenidos + +- [Características](#-características) +- [Requisitos](#-requisitos) +- [Instalación](#-instalación) +- [Configuración](#️-configuración) +- [Uso del Frontend Web](#-uso-del-frontend-web) +- [API REST](#-api-rest) + - [Endpoints Disponibles](#endpoints-disponibles) + - [Ejemplos de Uso](#ejemplos-de-uso) +- [Estructura del Proyecto](#-estructura-del-proyecto) +- [Filtrado de IPs Administrativas](#-filtrado-de-ips-administrativas) +- [Logs y Debugging](#-logs-y-debugging) +- [Changelog](#-changelog) +- [Soporte](#-soporte) + +--- + +## ✨ Características + +- 🔍 **Búsqueda de IPs disponibles** por segmento de red (172.16.X.x) +- 🌐 **Interfaz web moderna** con diseño responsive y atractivo +- 🔌 **API REST completa** para integraciones externas +- 📋 **Copiar al portapapeles** con un solo clic +- 🎯 **Filtrado inteligente** de IPs administrativas vs. IPs para clientes +- 📊 **Estadísticas en tiempo real** de IPs disponibles y en uso +- 🔐 **Integración nativa** con UISP CRM y UNMS +- 🪝 **Soporte para webhooks** y eventos personalizados +- 📝 **Sistema de logs detallado** para debugging + +--- + +## 📦 Requisitos + +- **UISP CRM** versión 1.0.0 o superior +- **UISP UNMS** versión 1.0.0 o superior (opcional) +- **PHP** 7.2 o superior +- **cURL** habilitado en PHP +- **Token de API** de UCRM +- **Token de API** de UNMS (opcional, para búsqueda de IPs) + +--- + +## 🚀 Instalación + +### Método 1: Instalación Manual + +1. Descarga o clona este repositorio +2. Comprime la carpeta del plugin en formato `.zip` +3. En UISP CRM, ve a **Sistema → Plugins** +4. Haz clic en **"Subir nuevo plugin"** +5. Selecciona el archivo `.zip` y súbelo +6. Activa el plugin desde la lista de plugins + +### Método 2: Instalación desde Git + +```bash +cd /path/to/ucrm/data/plugins/ +git clone siip-available-ips +cd siip-available-ips +composer install +``` + +--- + +## ⚙️ Configuración + +Después de instalar el plugin, configura los siguientes parámetros: + +### Parámetros Requeridos + +| Parámetro | Descripción | Ejemplo | +|-----------|-------------|---------| +| **Dirección IP o dominio del servidor** | IP o dominio donde se ejecuta UISP CRM | `172.16.5.120` o `sistema.empresa.com` | +| **Token de la API UCRM** | Token de autenticación de UCRM (36 caracteres) | `3d3fa6c9-e268-6e8b-b4d5-aae394d99d7d` | + +### Parámetros Opcionales + +| Parámetro | Descripción | Uso | +|-----------|-------------|-----| +| **Token de la API UNMS** | Token de UNMS (34 caracteres) | Para búsqueda de IPs en dispositivos de red | +| **Debug Mode** | Modo de depuración | Habilita logs más detallados | +| **Enable debug logs** | Logs verbosos | Información adicional en logs | + +### Cómo obtener los tokens: + +#### Token UCRM: +1. Ve a **Sistema → Seguridad → Claves de aplicación** +2. Crea una nueva clave con permisos de lectura/escritura +3. Copia el token generado + +#### Token UNMS: +1. Accede al módulo **UISP Network** +2. Ve a **Ajustes → Usuarios → API Tokens** +3. Genera un nuevo token +4. Copia el token generado + +--- + +## 🖥️ Uso del Frontend Web + +### Acceso + +El frontend web está disponible en: +- **Menú UCRM**: `Reportes → Consultar IP's Disponibles` +- **URL directa**: `https://tu-servidor/plugins/siip-available-ips/public.php` + +### Interfaz de Usuario + +La interfaz incluye: + +1. **Campo de búsqueda**: Ingresa el tercer octeto del segmento (ej: `5` para buscar en `172.16.5.x`) +2. **Botón "Buscar IPs"**: Ejecuta la búsqueda +3. **Tabla de resultados**: Muestra las IPs disponibles con: + - Dirección IP completa + - Tipo de IP (Cliente / Administración) + - Botón de copiar al portapapeles +4. **Estadísticas**: Muestra contadores de IPs disponibles y en uso + +### Ejemplo de Uso + +``` +1. Ingresa "5" en el campo de búsqueda +2. Haz clic en "Buscar IPs" +3. Se mostrarán todas las IPs disponibles en el rango 172.16.5.x +4. Haz clic en el botón "Copiar" junto a la IP deseada +5. La IP se copia automáticamente al portapapeles +``` + +--- + +## 🔌 API REST + +El plugin expone una API REST completa para integraciones externas, webhooks y automatizaciones. + +### Configuración Base + +- **URL Base**: `https://tu-servidor/plugins/siip-available-ips/public.php` +- **Método**: `POST` +- **Content-Type**: `application/json` +- **Autenticación**: No requerida (el plugin usa los tokens configurados internamente) + +### Endpoints Disponibles + +#### 1. Buscar IPs Disponibles + +Busca todas las IPs disponibles en un segmento de red específico. + +**Evento**: `event.ip_request` + +**Request**: +```json +{ + "type": "event.ip_request", + "segment": "5" +} +``` + +**Response (Éxito)**: +```json +{ + "success": true, + "event": "event.ip_request", + "segment": "172.16.5.x", + "data": { + "available": [ + "172.16.5.31", + "172.16.5.32", + "172.16.5.33" + ], + "used": [ + "172.16.5.1", + "172.16.5.2" + ] + }, + "count": { + "available": 223, + "used": 31, + "admin_filtered": 31 + }, + "message": "Se encontraron 223 IPs aptas para clientes en el segmento 172.16.5.x (31 IPs administrativas filtradas)" +} +``` + +**Parámetros**: +- `type` (string, requerido): Tipo de evento, debe ser `"event.ip_request"` +- `segment` (string, requerido): Tercer octeto del segmento (0-255) + +**Notas**: +- Las IPs administrativas (1-30 y 254) son filtradas automáticamente +- Solo se devuelven IPs aptas para asignar a clientes (31-253) + +--- + +#### 2. Verificar Estado de una IP + +Verifica si una IP específica está disponible o en uso. + +**Evento**: `event.ip_check` + +**Request**: +```json +{ + "type": "event.ip_check", + "ip": "172.16.5.100" +} +``` + +**Response (IP Disponible)**: +```json +{ + "success": true, + "event": "event.ip_check", + "ip": "172.16.5.100", + "status": "available", + "available": true, + "used": false, + "ip_type": { + "type": "client", + "label": "Apta para cliente", + "recommended": true, + "description": "Recomendada para asignar a clientes" + } +} +``` + +**Response (IP en Uso)**: +```json +{ + "success": true, + "event": "event.ip_check", + "ip": "172.16.5.1", + "status": "IP en uso y además para uso administrativo", + "available": false, + "used": true, + "ip_type": { + "type": "admin", + "label": "Administración", + "recommended": false, + "description": "No recomendada para clientes" + } +} +``` + +**Parámetros**: +- `type` (string, requerido): Tipo de evento, debe ser `"event.ip_check"` +- `ip` (string, requerido): Dirección IP completa en formato `172.16.X.X` + +--- + +### Ejemplos de Uso + +#### cURL - Buscar IPs Disponibles + +```bash +curl -X POST https://tu-servidor/plugins/siip-available-ips/public.php \ + -H "Content-Type: application/json" \ + -d '{ + "type": "event.ip_request", + "segment": "5" + }' +``` + +#### cURL - Verificar IP Específica + +```bash +curl -X POST https://tu-servidor/plugins/siip-available-ips/public.php \ + -H "Content-Type: application/json" \ + -d '{ + "type": "event.ip_check", + "ip": "172.16.5.100" + }' +``` + +#### PHP - Buscar IPs Disponibles + +```php + 'event.ip_request', + 'segment' => '5' +]; + +$ch = curl_init($url); +curl_setopt($ch, CURLOPT_POST, 1); +curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); +curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + +$response = curl_exec($ch); +curl_close($ch); + +$result = json_decode($response, true); +print_r($result); +?> +``` + +#### JavaScript/Node.js - Verificar IP + +```javascript +const axios = require('axios'); + +const checkIp = async (ip) => { + try { + const response = await axios.post( + 'https://tu-servidor/plugins/siip-available-ips/public.php', + { + type: 'event.ip_check', + ip: ip + }, + { + headers: { + 'Content-Type': 'application/json' + } + } + ); + + console.log(response.data); + } catch (error) { + console.error('Error:', error.message); + } +}; + +checkIp('172.16.5.100'); +``` + +#### Python - Buscar IPs Disponibles + +```python +import requests +import json + +url = 'https://tu-servidor/plugins/siip-available-ips/public.php' +payload = { + 'type': 'event.ip_request', + 'segment': '5' +} + +response = requests.post( + url, + json=payload, + headers={'Content-Type': 'application/json'}, + verify=False +) + +result = response.json() +print(json.dumps(result, indent=2)) +``` + +--- + +### Códigos de Error + +| Código | Descripción | Solución | +|--------|-------------|----------| +| `Missing event type` | No se especificó el campo `type` | Incluye `"type"` en el JSON | +| `Unknown event type` | Tipo de evento no soportado | Usa `event.ip_request` o `event.ip_check` | +| `Missing segment` | Falta el campo `segment` | Incluye `"segment"` en el request | +| `Missing IP address` | Falta el campo `ip` | Incluye `"ip"` en el request | +| `Invalid IP format` | Formato de IP inválido | Usa formato `172.16.X.X` | +| `Plugin not configured` | Configuración incompleta | Verifica tokens en configuración del plugin | +| `IP search failed` | Error en búsqueda | Revisa logs del plugin | + +--- + +## 📁 Estructura del Proyecto + +``` +siip-available-ips/ +├── manifest.json # Configuración del plugin +├── composer.json # Dependencias PHP +├── main.php # Punto de entrada principal +├── public.php # Frontend web + API REST +├── README.md # Este archivo +├── src/ # Código fuente +│ ├── ApiHandlers.php # Manejadores de API REST +│ └── IpSearchService.php # Servicio de búsqueda de IPs +├── data/ # Datos del plugin +│ ├── config.json # Configuración (generado automáticamente) +│ └── plugin.log # Archivo de logs +└── vendor/ # Dependencias de Composer +``` + +### Archivos Principales + +#### `public.php` +- Punto de entrada para frontend web y API REST +- Detecta automáticamente el tipo de petición (HTML vs JSON) +- Maneja errores globales y logging + +#### `src/ApiHandlers.php` +Funciones para manejar peticiones API: +- `handleApiRequest()`: Router principal de eventos +- `handleIpRequest()`: Procesa `event.ip_request` +- `handleIpCheck()`: Procesa `event.ip_check` + +#### `src/IpSearchService.php` +Clase de servicio para búsqueda de IPs: +- `buscarIpsDisponibles()`: Busca IPs en un segmento +- `obtenerIpsEnUso()`: Obtiene IPs desde API UNMS +- `isAdminIp()`: Determina si una IP es administrativa +- `getIpType()`: Obtiene información del tipo de IP + +--- + +## 🎯 Filtrado de IPs Administrativas + +El plugin implementa un sistema inteligente de filtrado de IPs: + +### Rangos de IPs + +| Rango | Tipo | Uso | Recomendación | +|-------|------|-----|---------------| +| `.1 - .30` | Administrativa | Gateways, servidores, equipos de red | ❌ No asignar a clientes | +| `.31 - .253` | Cliente | Dispositivos de clientes finales | ✅ Apto para clientes | +| `.254` | Broadcast | Dirección de broadcast | ❌ No asignar | + +### Comportamiento + +- **Frontend Web**: Muestra todas las IPs con etiquetas de tipo +- **API REST**: Filtra automáticamente IPs administrativas +- **event.ip_check**: Indica el tipo de IP en la respuesta + +--- + +## 📝 Logs y Debugging + +### Ubicación de Logs + +Los logs se guardan en: +``` +/data/plugin.log +``` + +### Habilitar Debug Mode + +1. Ve a la configuración del plugin +2. Activa **"Debug Mode"** +3. Activa **"Enable debug logs"** +4. Los logs incluirán información detallada de: + - Peticiones recibidas + - Respuestas de API UNMS + - Errores y excepciones + - Tiempos de ejecución + +### Ejemplo de Log + +``` +[2025-11-26 11:30:15] >>> Petición recibida en public.php +[2025-11-26 11:30:15] Método: POST +[2025-11-26 11:30:15] Content-Type: application/json +[2025-11-26 11:30:15] Procesando evento API: event.ip_request +[2025-11-26 11:30:15] API: Buscando IPs en segmento 5 +[2025-11-26 11:30:16] Respuesta HTTP: 200 +[2025-11-26 11:30:16] IPs obtenidas exitosamente: 254 direcciones +[2025-11-26 11:30:16] Búsqueda de IPs en segmento 172.16.5.x - Disponibles: 223, En uso: 31 +``` + +--- + +## 📜 Changelog + +Para ver el historial completo de cambios y versiones, consulta el archivo **[CHANGELOG.md](CHANGELOG.md)**. + +### Versión Actual: 1.1.0 (2025-11-26) + +**Cambios destacados**: +- ✨ API REST completa con endpoints `event.ip_request` y `event.ip_check` +- 🔌 Soporte para webhooks y eventos personalizados +- 🎯 Filtrado automático de IPs administrativas +- 📚 Documentación completa con ejemplos en múltiples lenguajes + +[Ver changelog completo →](CHANGELOG.md) + +--- + +## 🆘 Soporte + +### Problemas Comunes + +#### Error: "Plugin not configured" +**Solución**: Verifica que hayas configurado correctamente los tokens de API en la configuración del plugin. + +#### Error: "Error al conectar con la API de UISP" +**Solución**: +- Verifica que el servidor UNMS esté accesible +- Comprueba que el token de API UNMS sea válido +- Revisa los logs para más detalles + +#### No se muestran IPs disponibles +**Solución**: +- Verifica que el segmento ingresado sea válido (0-255) +- Comprueba que existan dispositivos en ese segmento en UNMS +- Revisa los logs con debug mode activado + +### Contacto + +- **Sitio web**: [https://siip.mx](https://siip.mx) +- **Autor**: SIIP Internet + +--- + +## 📄 Licencia + +Este plugin es propiedad de **SIIP Internet**. Todos los derechos reservados. + +--- + +## 🙏 Agradecimientos + +- Equipo de UISP/Ubiquiti por la plataforma +- Comunidad de desarrolladores de plugins UCRM + +--- + +**Versión**: 1.1.0 +**Última actualización**: 26 de noviembre de 2025 diff --git a/data/plugin.log b/data/plugin.log index 97969ab..b44e099 100644 --- a/data/plugin.log +++ b/data/plugin.log @@ -39,3 +39,247 @@ IPs obtenidas exitosamente: 3098 direcciones Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102 Resultado de búsqueda: {"success":true,"ipsDisponibles":152,"ipsEnUso":102} <<< Finalizando handler de búsqueda AJAX +=== NUEVA PETICIÓN === +Método: GET +POST data: [] +GET data: [] +Content-Type: +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +Acceso a la interfaz pública de búsqueda de IPs +=== NUEVA PETICIÓN === +Método: POST +POST data: {"action":"search","segment":"13"} +GET data: [] +Content-Type: multipart/form-data; boundary=----geckoformboundary6cbbdcac9240b1f8937236c9d112a787 +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +>>> Entrando al handler de búsqueda AJAX +Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true} +Buscando IPs en segmento: 13 +URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48793 bytes +IPs obtenidas exitosamente: 3098 direcciones +Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102 +Resultado de búsqueda: {"success":true,"ipsDisponibles":152,"ipsEnUso":102} +<<< Finalizando handler de búsqueda AJAX +=== NUEVA PETICIÓN === +Método: POST +POST data: {"action":"search","segment":"117"} +GET data: [] +Content-Type: multipart/form-data; boundary=----geckoformboundary7b1ac14e8b058e23f4947656491d5038 +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +>>> Entrando al handler de búsqueda AJAX +Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true} +Buscando IPs en segmento: 117 +URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48793 bytes +IPs obtenidas exitosamente: 3098 direcciones +Búsqueda de IPs en segmento 172.16.117.x - Disponibles: 50, En uso: 204 +Resultado de búsqueda: {"success":true,"ipsDisponibles":50,"ipsEnUso":204} +<<< Finalizando handler de búsqueda AJAX +=== NUEVA PETICIÓN === +Método: POST +POST data: {"action":"search","segment":"118"} +GET data: [] +Content-Type: multipart/form-data; boundary=----geckoformboundary658a77374dd484eccecd0aff8be2683c +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +>>> Entrando al handler de búsqueda AJAX +Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true} +Buscando IPs en segmento: 118 +URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48793 bytes +IPs obtenidas exitosamente: 3098 direcciones +Búsqueda de IPs en segmento 172.16.118.x - Disponibles: 254, En uso: 0 +Resultado de búsqueda: {"success":true,"ipsDisponibles":254,"ipsEnUso":0} +<<< Finalizando handler de búsqueda AJAX +=== NUEVA PETICIÓN === +Método: POST +POST data: {"action":"search","segment":"13"} +GET data: [] +Content-Type: multipart/form-data; boundary=----geckoformboundaryf0fe3eda5f3c2940ddc7bc14b7f17a72 +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +>>> Entrando al handler de búsqueda AJAX +Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true} +Buscando IPs en segmento: 13 +URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48760 bytes +IPs obtenidas exitosamente: 3096 direcciones +Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102 +Resultado de búsqueda: {"success":true,"ipsDisponibles":152,"ipsEnUso":102} +<<< Finalizando handler de búsqueda AJAX +=== NUEVA PETICIÓN === +Método: POST +POST data: [] +GET data: [] +Content-Type: application/json +User Agent: curl/7.53.1 +>>> Petición API JSON detectada +Raw input length: 55 bytes +JSON parseado correctamente: {"type":"event.ip_request","segment":13} +Procesando evento API: event.ip_request +API: Buscando IPs en segmento 13 +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48760 bytes +IPs obtenidas exitosamente: 3096 direcciones +Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102 +=== NUEVA PETICIÓN === +Método: GET +POST data: [] +GET data: [] +Content-Type: application/json +User Agent: PostmanRuntime/7.49.1 +Acceso a la interfaz pública de búsqueda de IPs +=== NUEVA PETICIÓN === +Método: GET +POST data: [] +GET data: [] +Content-Type: +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +Acceso a la interfaz pública de búsqueda de IPs +=== NUEVA PETICIÓN === +Método: POST +POST data: {"action":"search","segment":"13"} +GET data: [] +Content-Type: multipart/form-data; boundary=----geckoformboundarye5c616c1af6248b5a47402549548a751 +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +>>> Entrando al handler de búsqueda AJAX +Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true} +Buscando IPs en segmento: 13 +URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48760 bytes +IPs obtenidas exitosamente: 3096 direcciones +Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102 +Resultado de búsqueda: {"success":true,"ipsDisponibles":152,"ipsEnUso":102} +<<< Finalizando handler de búsqueda AJAX +=== NUEVA PETICIÓN === +Método: POST +POST data: [] +GET data: [] +Content-Type: application/json +User Agent: bruno-runtime/2.13.2 +>>> Petición API JSON detectada +Raw input length: 49 bytes +JSON parseado correctamente: {"type":"event.ip_request","segment":13} +Procesando evento API: event.ip_request +API: Buscando IPs en segmento 13 +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48760 bytes +IPs obtenidas exitosamente: 3096 direcciones +Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102 +=== NUEVA PETICIÓN === +Método: POST +POST data: {"action":"search","segment":"54"} +GET data: [] +Content-Type: multipart/form-data; boundary=----geckoformboundary760324c1fddb52943c44f65bcfecbf9d +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +>>> Entrando al handler de búsqueda AJAX +Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true} +Buscando IPs en segmento: 54 +URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48760 bytes +IPs obtenidas exitosamente: 3096 direcciones +Búsqueda de IPs en segmento 172.16.54.x - Disponibles: 53, En uso: 201 +Resultado de búsqueda: {"success":true,"ipsDisponibles":53,"ipsEnUso":201} +<<< Finalizando handler de búsqueda AJAX +=== NUEVA PETICIÓN === +Método: GET +POST data: [] +GET data: [] +Content-Type: +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +Acceso a la interfaz pública de búsqueda de IPs +=== NUEVA PETICIÓN === +Método: POST +POST data: {"action":"search","segment":"13"} +GET data: [] +Content-Type: multipart/form-data; boundary=----geckoformboundary6a3bb83aaad5136b35d1d031633c43ce +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +>>> Entrando al handler de búsqueda AJAX +Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true} +Buscando IPs en segmento: 13 +URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48807 bytes +IPs obtenidas exitosamente: 3099 direcciones +Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102 +Resultado de búsqueda: {"success":true,"ipsDisponibles":152,"ipsEnUso":102} +<<< Finalizando handler de búsqueda AJAX +=== NUEVA PETICIÓN === +Método: POST +POST data: [] +GET data: [] +Content-Type: application/json +User Agent: bruno-runtime/2.13.2 +>>> Petición API JSON detectada +Raw input length: 49 bytes +JSON parseado correctamente: {"type":"event.ip_request","segment":13} +Procesando evento API: event.ip_request +API: Buscando IPs en segmento 13 +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48807 bytes +IPs obtenidas exitosamente: 3099 direcciones +Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102 +API: Filtrando IPs administrativas. Total disponibles: 152, Aptas para clientes: 135 +=== NUEVA PETICIÓN === +Método: GET +POST data: [] +GET data: [] +Content-Type: +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +Acceso a la interfaz pública de búsqueda de IPs +=== NUEVA PETICIÓN === +Método: POST +POST data: {"action":"search","segment":"12"} +GET data: [] +Content-Type: multipart/form-data; boundary=----geckoformboundary3c043be49dc41eaeecf09ef1c525672b +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +>>> Entrando al handler de búsqueda AJAX +Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true} +Buscando IPs en segmento: 12 +URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48823 bytes +IPs obtenidas exitosamente: 3100 direcciones +Búsqueda de IPs en segmento 172.16.12.x - Disponibles: 134, En uso: 120 +Resultado de búsqueda: {"success":true,"ipsDisponibles":134,"ipsEnUso":120} +<<< Finalizando handler de búsqueda AJAX +=== NUEVA PETICIÓN === +Método: GET +POST data: [] +GET data: [] +Content-Type: +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +Acceso a la interfaz pública de búsqueda de IPs +=== NUEVA PETICIÓN === +Método: POST +POST data: {"action":"search","segment":"13"} +GET data: [] +Content-Type: multipart/form-data; boundary=----geckoformboundaryb636200e57bd870b75c2713be943cc3c +User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0 +>>> Entrando al handler de búsqueda AJAX +Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true} +Buscando IPs en segmento: 13 +URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true +Respuesta HTTP: 200 +Longitud de respuesta: 48875 bytes +IPs obtenidas exitosamente: 3103 direcciones +Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 153, En uso: 101 +Resultado de búsqueda: {"success":true,"ipsDisponibles":153,"ipsEnUso":101} +<<< Finalizando handler de búsqueda AJAX diff --git a/manifest.json b/manifest.json index 42815dc..ff47967 100644 --- a/manifest.json +++ b/manifest.json @@ -5,7 +5,7 @@ "displayName": "SIIP - Buscador de IP's Disponibles UISP", "description": "Este plugin permite buscar IP's disponibles en UISP (UNMS) y asignarlas a los clientes en UCRM. Evitando así la asignación de IP's duplicadas y mejorando la gestión de direcciones IP en la red.", "url": "https://siip.mx", - "version": "1.0.1", + "version": "1.1.0", "ucrmVersionCompliancy": { "min": "1.0.0", "max": null diff --git a/public.php b/public.php index b0ca107..c341ed7 100644 --- a/public.php +++ b/public.php @@ -25,6 +25,7 @@ chdir(__DIR__); require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/src/IpSearchService.php'; +require_once __DIR__ . '/src/ApiHandlers.php'; use Ubnt\UcrmPluginSdk\Service\PluginLogManager; use Ubnt\UcrmPluginSdk\Service\PluginConfigManager; @@ -41,7 +42,41 @@ $log->appendLog('GET data: ' . json_encode($_GET)); $log->appendLog('Content-Type: ' . ($_SERVER['CONTENT_TYPE'] ?? 'no definido')); $log->appendLog('User Agent: ' . ($_SERVER['HTTP_USER_AGENT'] ?? 'no definido')); -// Manejar peticiones AJAX +// ============================================================================ +// API REST - Manejar peticiones JSON (Postman, Webhooks, etc.) +// ============================================================================ +$contentType = $_SERVER['CONTENT_TYPE'] ?? ''; +$isJsonRequest = stripos($contentType, 'application/json') !== false; + +if ($isJsonRequest && $_SERVER['REQUEST_METHOD'] === 'POST') { + $log->appendLog('>>> Petición API JSON detectada'); + + $rawInput = file_get_contents('php://input'); + $log->appendLog('Raw input length: ' . strlen($rawInput) . ' bytes'); + + $jsonData = json_decode($rawInput, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + $log->appendLog('ERROR: JSON inválido - ' . json_last_error_msg()); + header('Content-Type: application/json'); + echo json_encode([ + 'success' => false, + 'error' => 'Invalid JSON', + 'message' => json_last_error_msg() + ]); + exit; + } + + $log->appendLog('JSON parseado correctamente: ' . json_encode($jsonData)); + + // Procesar petición API + handleApiRequest($jsonData, $log); + exit; +} + +// ============================================================================ +// FRONTEND HTML - Manejar peticiones AJAX del formulario +// ============================================================================ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'search') { $log->appendLog('>>> Entrando al handler de búsqueda AJAX'); @@ -495,6 +530,27 @@ $log->appendLog('Acceso a la interfaz pública de búsqueda de IPs'); color: #4facfe; } + .ip-type-badge { + padding: 6px 12px; + border-radius: 6px; + font-size: 0.8rem; + font-weight: 600; + display: inline-block; + text-align: center; + } + + .ip-type-admin { + background: rgba(245, 87, 108, 0.2); + border: 1px solid rgba(245, 87, 108, 0.4); + color: #ff6b6b; + } + + .ip-type-client { + background: rgba(79, 209, 197, 0.2); + border: 1px solid rgba(79, 209, 197, 0.4); + color: #4fd1c5; + } + .footer { text-align: center; color: var(--text-secondary); @@ -596,6 +652,7 @@ $log->appendLog('Acceso a la interfaz pública de búsqueda de IPs'); # Dirección IP + Tipo de IP Acción @@ -704,10 +761,16 @@ $log->appendLog('Acceso a la interfaz pública de búsqueda de IPs'); // Llenar tabla data.data.forEach((ip, index) => { + const ipType = getIpType(ip); const row = document.createElement('tr'); row.innerHTML = ` ${index + 1} ${ip} + + + ${ipType.label} + +