qnap-tools 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qnap_tools-0.4.0/.gitignore +20 -0
- qnap_tools-0.4.0/LICENSE +21 -0
- qnap_tools-0.4.0/PKG-INFO +359 -0
- qnap_tools-0.4.0/README.md +339 -0
- qnap_tools-0.4.0/pyproject.toml +51 -0
- qnap_tools-0.4.0/src/qnap_tools/__init__.py +4 -0
- qnap_tools-0.4.0/src/qnap_tools/claves.py +47 -0
- qnap_tools-0.4.0/src/qnap_tools/comandos.py +139 -0
- qnap_tools-0.4.0/src/qnap_tools/config.py +56 -0
- qnap_tools-0.4.0/src/qnap_tools/deteccion.py +79 -0
- qnap_tools-0.4.0/src/qnap_tools/discos/__init__.py +2 -0
- qnap_tools-0.4.0/src/qnap_tools/discos/comandos.py +199 -0
- qnap_tools-0.4.0/src/qnap_tools/discos/parsers.py +1121 -0
- qnap_tools-0.4.0/src/qnap_tools/discos/servidor.py +685 -0
- qnap_tools-0.4.0/src/qnap_tools/ejecutor.py +189 -0
- qnap_tools-0.4.0/src/qnap_tools/flota/__init__.py +2 -0
- qnap_tools-0.4.0/src/qnap_tools/flota/servidor.py +318 -0
- qnap_tools-0.4.0/src/qnap_tools/inventario.py +142 -0
- qnap_tools-0.4.0/src/qnap_tools/logs/__init__.py +2 -0
- qnap_tools-0.4.0/src/qnap_tools/logs/comandos.py +214 -0
- qnap_tools-0.4.0/src/qnap_tools/logs/parsers.py +604 -0
- qnap_tools-0.4.0/src/qnap_tools/logs/servidor.py +366 -0
- qnap_tools-0.4.0/src/qnap_tools/redes/__init__.py +2 -0
- qnap_tools-0.4.0/src/qnap_tools/redes/comandos.py +159 -0
- qnap_tools-0.4.0/src/qnap_tools/redes/parsers.py +719 -0
- qnap_tools-0.4.0/src/qnap_tools/redes/servidor.py +278 -0
- qnap_tools-0.4.0/src/qnap_tools/servidor.py +96 -0
- qnap_tools-0.4.0/src/qnap_tools/transporte.py +262 -0
- qnap_tools-0.4.0/src/qnap_tools/virtualizacion/__init__.py +2 -0
- qnap_tools-0.4.0/src/qnap_tools/virtualizacion/comandos.py +186 -0
- qnap_tools-0.4.0/src/qnap_tools/virtualizacion/parsers.py +724 -0
- qnap_tools-0.4.0/src/qnap_tools/virtualizacion/servidor.py +525 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Datos reales de los NAS y credenciales: nunca al repositorio
|
|
2
|
+
.env
|
|
3
|
+
CLAUDE.md
|
|
4
|
+
pruebas/claves/
|
|
5
|
+
pruebas/resultados/
|
|
6
|
+
ensayo/
|
|
7
|
+
|
|
8
|
+
# Estado local de herramientas
|
|
9
|
+
.claude/
|
|
10
|
+
.remember/
|
|
11
|
+
.superpowers/
|
|
12
|
+
|
|
13
|
+
# Python
|
|
14
|
+
.venv/
|
|
15
|
+
__pycache__/
|
|
16
|
+
*.pyc
|
|
17
|
+
*.egg-info/
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
dist/
|
|
20
|
+
build/
|
qnap_tools-0.4.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alberto Diaz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: qnap-tools
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Servidores MCP de solo lectura para consultar una flota de NAS QNAP por SSH
|
|
5
|
+
Project-URL: Homepage, https://github.com/Picaresco/qnap-tools
|
|
6
|
+
Project-URL: Repository, https://github.com/Picaresco/qnap-tools
|
|
7
|
+
Project-URL: Issues, https://github.com/Picaresco/qnap-tools/issues
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: claude-code,mcp,nas,qnap,qts,quts-hero,ssh
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: System :: Systems Administration
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Requires-Dist: mcp[cli]<2,>=1
|
|
16
|
+
Requires-Dist: paramiko>=3.4
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# Qnap-Tools
|
|
22
|
+
|
|
23
|
+
https://github.com/user-attachments/assets/6aee9f35-75ca-495e-9eb9-6d8660776749
|
|
24
|
+
|
|
25
|
+
Plugin de Claude Code para consultar una flota de NAS QNAP (QTS y QuTS hero) en **solo
|
|
26
|
+
lectura**, por SSH. Se da de alta cada NAS una vez y después se pregunta en lenguaje natural:
|
|
27
|
+
"¿qué IP y qué velocidad de enlace tiene cada NAS?", "¿cómo están los discos y el RAID?",
|
|
28
|
+
"¿qué volúmenes pasan del 80 %?", "¿qué máquinas virtuales están en marcha y cuánto consumen?",
|
|
29
|
+
"¿qué contenedor no está sano?", "haz un ping desde el NAS a la puerta de enlace",
|
|
30
|
+
"¿qué errores hay en el registro de eventos?", "¿desde qué IP están fallando los inicios de
|
|
31
|
+
sesión?", "¿a qué temperatura está la CPU y giran todos los ventiladores?".
|
|
32
|
+
|
|
33
|
+
**Estado: entregas 1 a 4 hechas.** Están el servidor de administración (`qnap-flota`), el de
|
|
34
|
+
redes (`qnap-redes`), el de discos y carpetas (`qnap-discos`), el de máquinas virtuales y
|
|
35
|
+
contenedores (`qnap-virtualizacion`) y el de registros, avisos y estado del sistema
|
|
36
|
+
(`qnap-logs`). Publicado en GitHub (`Picaresco/qnap-tools`) y en PyPI (`qnap-tools`).
|
|
37
|
+
|
|
38
|
+
## Requisitos
|
|
39
|
+
|
|
40
|
+
- Claude Code (probado con la version 2.1.296).
|
|
41
|
+
- [`uv`](https://docs.astral.sh/uv/) instalado y en el `PATH` (el plugin lanza sus servidores con `uvx`).
|
|
42
|
+
- En cada NAS:
|
|
43
|
+
- SSH activado (Panel de control → Telnet/SSH);
|
|
44
|
+
- un **usuario común a toda la flota**, con la misma contraseña en todos los NAS, que
|
|
45
|
+
pertenezca al grupo `administrators` y tenga permitido el acceso por SSH
|
|
46
|
+
(Telnet/SSH → Editar permiso de acceso).
|
|
47
|
+
|
|
48
|
+
## Instalación
|
|
49
|
+
|
|
50
|
+
En Claude Code:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
/plugin marketplace add Picaresco/qnap-tools
|
|
54
|
+
/plugin install qnap-tools@qnap-tools
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
o desde la terminal:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
claude plugin marketplace add Picaresco/qnap-tools
|
|
61
|
+
claude plugin install qnap-tools@qnap-tools
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Cada servidor se lanza con `uvx` desde PyPI con la versión exacta del plugin
|
|
65
|
+
(`uvx --from qnap-tools==0.4.0 qnap-tools-redes`, etc.); `uv` lo descarga y lo deja en su caché
|
|
66
|
+
la primera vez, y no vuelve a consultar PyPI en cada arranque.
|
|
67
|
+
|
|
68
|
+
Al activarlo, Claude Code pide el **usuario SSH** y su **contraseña**. Se cambian después en
|
|
69
|
+
`/plugin` → qnap-tools → configurar. Hay que reiniciar la sesión para que los servidores los
|
|
70
|
+
reciban. `/mcp` debe mostrar `qnap-flota`, `qnap-redes`, `qnap-discos`, `qnap-virtualizacion`
|
|
71
|
+
y `qnap-logs` conectados.
|
|
72
|
+
|
|
73
|
+
## Dar de alta un NAS
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
/qnap-tools:alta
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
o simplemente "da de alta el NAS 192.0.2.50 con el nombre casa". El alta:
|
|
80
|
+
|
|
81
|
+
1. entra por SSH con el usuario y la contraseña comunes y **fija la clave de host** del NAS
|
|
82
|
+
(devuelve su huella para cotejarla; si más adelante cambia, el plugin se niega a entrar);
|
|
83
|
+
2. comprueba que el usuario es administrador, que `sudo` da privilegios y que el equipo es un QNAP;
|
|
84
|
+
3. salvo que se pida lo contrario, instala en el NAS la **clave pública de este ordenador**
|
|
85
|
+
para entrar después sin contraseña. Es la única escritura que hace el plugin; con
|
|
86
|
+
`instalar_clave=false` no escribe nada y se entra siempre por contraseña.
|
|
87
|
+
|
|
88
|
+
**Comprueba la dirección antes de dar de alta.** En esa primera conexión el plugin envía la
|
|
89
|
+
contraseña común al equipo que se le indique, y la huella de su clave de host solo se puede
|
|
90
|
+
cotejar después. Una IP equivocada recibe la contraseña de toda la flota. Si un alta falla, la
|
|
91
|
+
clave de host que se hubiera fijado en ese intento se descarta.
|
|
92
|
+
|
|
93
|
+
Cada ordenador tiene su propia clave. Para usar la misma flota desde otro equipo: exporta el
|
|
94
|
+
inventario (`inventario_exportar`), impórtalo allí (`inventario_importar`) y ejecuta
|
|
95
|
+
`/qnap-tools:enrolar`.
|
|
96
|
+
|
|
97
|
+
## Herramientas
|
|
98
|
+
|
|
99
|
+
Todas las de consulta aceptan en `nas` el nombre de un NAS o `todos`, y devuelven una entrada
|
|
100
|
+
por NAS: `{"nas", "ok": true, "datos"}` o `{"nas", "ok": false, "error"}`. Si una consulta
|
|
101
|
+
falla o su salida no se reconoce, la respuesta lo dice (`ok: false`, o un `error` dentro del
|
|
102
|
+
bloque afectado cuando es un dato accesorio): no se devuelven datos vacíos como si no hubiera
|
|
103
|
+
nada.
|
|
104
|
+
|
|
105
|
+
**`qnap-flota`** (inventario de este ordenador)
|
|
106
|
+
|
|
107
|
+
| Herramienta | Qué hace |
|
|
108
|
+
|---|---|
|
|
109
|
+
| `nas_lista` | NAS dados de alta (no conecta) |
|
|
110
|
+
| `nas_comprobar` | Conecta y dice cómo se entra, si `sudo` da root, sistema, modelo y firmware |
|
|
111
|
+
| `nas_alta` | Da de alta un NAS |
|
|
112
|
+
| `nas_enrolar` | Prepara este ordenador para todos los NAS del inventario |
|
|
113
|
+
| `nas_baja` | Quita un NAS del inventario (no toca el NAS) |
|
|
114
|
+
| `inventario_exportar` / `inventario_importar` | Lleva el inventario (sin secretos) a otro ordenador |
|
|
115
|
+
|
|
116
|
+
**`qnap-redes`** (solo lectura)
|
|
117
|
+
|
|
118
|
+
| Herramienta | Qué da |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `red_resumen` | Interfaces activas con IP, velocidad y MTU, puerta de enlace y DNS |
|
|
121
|
+
| `red_interfaces` | Estado, contadores, errores y caudal de cada interfaz; con `interfaz`, enlace negociado, controlador y firmware |
|
|
122
|
+
| `red_conmutadores` | Conmutadores virtuales (puentes), sus puertos y las MAC aprendidas |
|
|
123
|
+
| `red_rutas` | Rutas, reglas de encaminamiento, rutas estáticas y vecinos ARP |
|
|
124
|
+
| `red_servicios` | Servicios configurados y puertos en escucha con su proceso |
|
|
125
|
+
| `red_dhcp_dns` | DNS, servidor DHCP del NAS y concesiones |
|
|
126
|
+
| `red_cortafuegos` | Resumen de iptables, bloqueo por IP y QuFirewall |
|
|
127
|
+
| `red_acceso_remoto` | DDNS/myQNAPcloud, UPnP y presencia de VPN |
|
|
128
|
+
| `red_diagnostico` | `ping`, `traceroute` o consulta `dns` lanzados desde el NAS |
|
|
129
|
+
|
|
130
|
+
**`qnap-discos`** (solo lectura)
|
|
131
|
+
|
|
132
|
+
| Herramienta | Qué da |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `almacenamiento_resumen` | Pools (QuTS hero) o grupos RAID (QTS) con su estado, volúmenes con su ocupación, discos por tipo y los `avisos`: redundancia degradada o reconstruyéndose, discos con problemas, pools o volúmenes por encima del 80 % y, en QTS, volúmenes sin montar, en solo lectura o sucios y pools ligeros en fallo |
|
|
135
|
+
| `discos_fisicos` | Cada disco por cabina y bahía: modelo, número de serie, capacidad, tipo, uso (datos, caché, repuesto), temperatura, veredicto SMART, vida consumida de los SSD y a qué grupo y pool pertenece; los discos USB, aparte |
|
|
136
|
+
| `disco_smart` | Atributos SMART de un disco (`bahia`, `cabina`), los que están en su umbral, sectores reasignados, pendientes e incorregibles, y el registro de salud de un NVMe |
|
|
137
|
+
| `raid_estado` | QuTS hero: árbol de cada pool con los errores de cada disco, verificación o reconstrucción y ficheros dañados. QTS: grupos RAID con sus miembros por bahía, discos que faltan, tarea en curso y repuestos |
|
|
138
|
+
| `volumenes` | Tamaño, usado y libre de cada volumen; en QuTS hero, compresión, deduplicación, cifrado y lo que ocupa en el pool contando sus instantáneas; en QTS, pools ligeros con su ocupación de datos y metadatos, caché SSD y los `avisos` de volúmenes y pools |
|
|
139
|
+
| `snapshots` | Cuántas instantáneas hay en total y por volumen, las 50 más recientes, el espacio que retienen (QuTS hero) y la programación y retención |
|
|
140
|
+
| `carpetas_compartidas` | Ruta y volumen de cada carpeta, quién puede entrar según Samba (válidos, denegados, solo lectura, escritura), papelera, el uso que el NAS tiene calculado y las exportaciones NFS |
|
|
141
|
+
| `iscsi` | Servicio iSCSI, destinos, LUN e iniciadores (nunca las claves CHAP) |
|
|
142
|
+
| `rendimiento_discos` | Actividad de cada disco medida durante 5 segundos: operaciones y MB por segundo, espera media y porcentaje de tiempo ocupado |
|
|
143
|
+
|
|
144
|
+
**`qnap-virtualizacion`** (solo lectura)
|
|
145
|
+
|
|
146
|
+
| Herramienta | Qué da |
|
|
147
|
+
|---|---|
|
|
148
|
+
| `virtualizacion_resumen` | Si Virtualization Station y Container Station están activos y con su servicio en marcha, CPU y memoria del NAS, cuántas máquinas virtuales y contenedores hay y en qué estado, vCPU y memoria asignadas a las máquinas en marcha, y los `avisos`: servicio parado, máquina en pausa o caída, contenedor reiniciándose o que no pasa su comprobación de salud, más memoria asignada que la del NAS |
|
|
149
|
+
| `vm_lista` | Cada máquina virtual, también las apagadas: nombre, UUID, estado, vCPU, memoria, sistema declarado, arranque automático y discos |
|
|
150
|
+
| `vm_detalle` | Una máquina (`vm`: nombre o UUID): descripción, firmware, TPM, orden de arranque, discos con su fichero, formato, tamaño y capas, interfaces con MAC, modelo y conmutador virtual, direcciones IP que el NAS conozca y consola (nunca su clave) |
|
|
151
|
+
| `vm_uso` | Consumo de las máquinas en marcha medido durante 5 segundos: CPU, memoria y actividad de cada disco y de cada interfaz de red |
|
|
152
|
+
| `vm_snapshots` | Instantáneas de cada máquina con su fecha y si guardan la memoria, y la cadena de imágenes de cada disco con lo que ocupa cada capa |
|
|
153
|
+
| `contenedores_lista` | Contenedores de Docker, también los parados: imagen, estado, salud, código de salida, puertos, redes y proyecto; y las aplicaciones (proyectos compose) |
|
|
154
|
+
| `contenedor_detalle` | Un contenedor (`contenedor`): estado, salud, reinicios y política de reinicio, límites, redes con su IP, puertos, montajes y proyecto compose (nunca sus variables de entorno ni su orden de arranque) |
|
|
155
|
+
| `contenedores_uso` | CPU, memoria, red, disco y procesos de cada contenedor en marcha, en una muestra |
|
|
156
|
+
| `contenedor_logs` | Las últimas líneas del registro de un contenedor (`lineas`, de 1 a 200; por defecto 50) |
|
|
157
|
+
| `contenedores_redes` | Redes de Docker: driver, subredes, puerta de enlace y contenedores conectados con su IP |
|
|
158
|
+
|
|
159
|
+
En un NAS sin Virtualization Station o sin Container Station (o con el paquete desactivado),
|
|
160
|
+
las herramientas de esa mitad responden `activo: false` y no ejecutan nada en el NAS.
|
|
161
|
+
|
|
162
|
+
**`qnap-logs`** (solo lectura)
|
|
163
|
+
|
|
164
|
+
| Herramienta | Qué da |
|
|
165
|
+
|---|---|
|
|
166
|
+
| `eventos` | Los últimos eventos del sistema, del más reciente al más antiguo: fecha, gravedad, usuario, IP, equipo, aplicación, categoría y descripción. Filtros: `gravedad` (`todos`, `informacion`, `aviso`, `error`), `desde` y `hasta` (AAAA-MM-DD), `texto` y `limite` (1 a 200; por defecto 50) |
|
|
167
|
+
| `eventos_resumen` | Cuántos eventos hay de cada gravedad y desde cuándo, los 10 últimos errores y avisos, y cuántos hay de cada aplicación entre los 200 últimos |
|
|
168
|
+
| `accesos` | Los últimos accesos a los servicios (inicios y cierres de sesión, intentos fallidos, operaciones con ficheros) con servicio, acción y recurso; los intentos fallidos agrupados por IP, usuario y servicio; y desde cuándo guarda accesos el NAS. Filtros: `tipo` y `limite` |
|
|
169
|
+
| `avisos` | Los últimos avisos del centro de notificaciones del escritorio (gravedad, origen, texto, aplicación y código) y cuántos hay de cada gravedad y origen |
|
|
170
|
+
| `kernel` | Mensajes del kernel: cuántos guarda el NAS de cada nivel y desde cuándo, las últimas líneas de un `nivel` (0 a 7; por defecto 3, errores) o más graves y la cola del registro en vivo (`lineas`, 1 a 200) |
|
|
171
|
+
| `salud_hardware` | Temperatura de CPU y del sistema y vueltas de cada ventilador (con `sudo`), cabinas con su estado, cuántas fuentes tiene el modelo y si son redundantes, el SAI configurado y si su servicio responde, y los `avisos`: ventilador parado, cabina en un estado que no es el normal, SAI activado que no responde |
|
|
172
|
+
| `sistema_estado` | Modelo, tiempo encendido, carga, hilos y memoria, firmware instalado con la última comprobación y la última actualización, política de actualización automática, aplicaciones de registro y seguridad con su versión, motores de registro en marcha y volcados del kernel guardados tras cuelgues, y los `avisos`: motor de registro parado, volcados guardados |
|
|
173
|
+
| `alertas_config` | Nivel de alerta, zumbador, aviso de espacio libre, avisos SMART por valor y el servidor syslog del NAS (nunca destinatarios ni credenciales de notificación) |
|
|
174
|
+
|
|
175
|
+
Los bloques marcados `no_probado: true` (agregación de puertos, VLAN, rutas estáticas,
|
|
176
|
+
QuFirewall, iSCSI, avisos SMART configurados) leen el formato visto pero no se han validado
|
|
177
|
+
con un NAS que use esa función.
|
|
178
|
+
|
|
179
|
+
## Qué significa "solo lectura"
|
|
180
|
+
|
|
181
|
+
- Cada orden que se ejecuta en un NAS es una plantilla fija definida en el código
|
|
182
|
+
(`comandos.py` de `src/qnap_tools/redes/`, `discos/`, `virtualizacion/` y `logs/`); no hay
|
|
183
|
+
ninguna herramienta que ejecute una orden libre.
|
|
184
|
+
- Los parámetros (interfaz, destino, bahía, UUID de máquina, nombre de contenedor, número de
|
|
185
|
+
líneas, fechas, texto de búsqueda en un registro) se validan contra un patrón estricto y se
|
|
186
|
+
entrecomillan. El texto de búsqueda solo admite letras, cifras, espacio y `_ . : @ / -`. El nombre de una máquina
|
|
187
|
+
virtual no viaja al NAS: se busca en la lista y se usa su UUID.
|
|
188
|
+
- Una plantilla que redirige a un fichero no se puede ni definir.
|
|
189
|
+
- Las 30 órdenes de redes y las 20 de discos que se usan en QuTS hero se han lanzado contra un
|
|
190
|
+
NAS real comparando el sistema de ficheros antes y después (`pruebas/efectos.py --producto
|
|
191
|
+
redes` y `--producto discos`): ninguna modifica nada. Las 9 propias de QTS son lecturas de
|
|
192
|
+
ficheros de configuración, de `/proc` y de `/sys`, y `dmsetup status`.
|
|
193
|
+
- Las 17 órdenes de virtualización se han lanzado igual (`--producto virtualizacion`): ninguna
|
|
194
|
+
modifica nada. Esa prueba compara el sistema de ficheros entre orden y orden, repite las
|
|
195
|
+
sospechosas y señala lo que aparece nuevo y sigue ahí al acabar; lo que no puede ver es algo
|
|
196
|
+
que un cliente hubiera creado ya en una ejecución anterior a la prueba. Por eso se miró
|
|
197
|
+
aparte la carpeta del usuario en los dos NAS de pruebas, después de cientos de consultas con
|
|
198
|
+
`docker`, `virsh` y `qemu-img`: no hay nada creado por ellos.
|
|
199
|
+
- `virsh` va siempre con `-r` (libvirt rechaza cualquier escritura en esa
|
|
200
|
+
conexión) y contra el libvirt del sistema; `qemu-img` solo con `info -U`; `docker` solo con
|
|
201
|
+
subórdenes de consulta (`info`, `ps`, `inspect` con campos concretos, `stats --no-stream`,
|
|
202
|
+
`logs --tail`, `network`, `compose ls`). No se arranca, para ni cambia ninguna máquina ni
|
|
203
|
+
ningún contenedor, y no se entra en ellos.
|
|
204
|
+
- Los tres registros del NAS (eventos, accesos y avisos) se leen con sus propias utilidades
|
|
205
|
+
(`log_tool`, `conn_log_tool`, `notice_log_tool`) en modo consulta y **nunca con `sudo`**: con
|
|
206
|
+
`sudo`, `log_tool` altera la base de eventos (medido en QuTS hero y en QTS). Toda consulta va
|
|
207
|
+
acotada en filas. Las 22 órdenes de registros y estado del sistema se han lanzado con
|
|
208
|
+
`--producto logs` sin ningún cambio, y el md5 de `event.log` y `notice.log` es el mismo antes y
|
|
209
|
+
después de una pasada de las ocho herramientas; `conn.log` solo gana los inicios y cierres de
|
|
210
|
+
sesión SSH de esa pasada. De `uLinux.conf` solo se leen claves sueltas con `getcfg` y de la
|
|
211
|
+
sección de alertas solo el nivel; no se leen las bases de QuLog Center ni de Notification
|
|
212
|
+
Center.
|
|
213
|
+
- No se lanza ninguna prueba sobre los discos: ni autotest SMART ni lecturas de velocidad. La
|
|
214
|
+
temperatura y los atributos SMART son los que el NAS ya ha leído (los refresca cada pocos
|
|
215
|
+
minutos), y el uso de cada carpeta es el que el NAS tiene calculado: no se recorre ninguna
|
|
216
|
+
carpeta.
|
|
217
|
+
- Que una consulta deje un apunte de sí misma en un registro del NAS no cuenta como
|
|
218
|
+
modificación.
|
|
219
|
+
- `sudo` se usa solo en las órdenes que lo necesitan (puertos en escucha, iptables, ping,
|
|
220
|
+
traceroute, VLAN; temperatura y SMART de los discos, `dmsetup status`; la lista de carpetas
|
|
221
|
+
de LXD; temperatura de CPU y del sistema y ventiladores), con la contraseña por la entrada
|
|
222
|
+
estándar, nunca en la línea de órdenes. `virsh` y
|
|
223
|
+
`docker` van sin `sudo`.
|
|
224
|
+
|
|
225
|
+
## Dónde se guardan los datos
|
|
226
|
+
|
|
227
|
+
En la carpeta de datos del plugin (`~/.claude/plugins/data/qnap-tools-<marketplace>/`):
|
|
228
|
+
|
|
229
|
+
- `inventario.toml`: nombre, host y puerto de cada NAS. Sin secretos.
|
|
230
|
+
- `known_hosts`: claves de host fijadas en el alta.
|
|
231
|
+
- `id_ed25519` y `id_ed25519.pub`: la clave SSH de este ordenador.
|
|
232
|
+
|
|
233
|
+
**Desinstalar el plugin borra esa carpeta.** Exporta antes el inventario con
|
|
234
|
+
`inventario_exportar` si quieres conservarlo.
|
|
235
|
+
|
|
236
|
+
La contraseña la guarda Claude Code, no el plugin. En Windows queda **en claro** en
|
|
237
|
+
`~/.claude/.credentials.json`, dentro del perfil del usuario: protege ese perfil como
|
|
238
|
+
protegerías la contraseña.
|
|
239
|
+
|
|
240
|
+
## Limitaciones conocidas
|
|
241
|
+
|
|
242
|
+
- Las herramientas de redes se han probado en real contra QuTS hero h6.0.2 y contra QTS 5.2.9
|
|
243
|
+
(un NAS con Virtualization Station y Container Station: 92 interfaces y 35 puentes). En un
|
|
244
|
+
NAS así las respuestas son largas: `red_interfaces` ronda los 35 KB.
|
|
245
|
+
- `red_diagnostico` con `traceroute` puede tardar hasta 30 segundos si los saltos no responden.
|
|
246
|
+
- Si una orden agota su tiempo máximo, el plugin deja de esperar pero el proceso puede seguir
|
|
247
|
+
vivo en el NAS hasta que termine por sí solo. La siguiente consulta abre una conexión nueva.
|
|
248
|
+
- Lo que el NAS devuelve como texto (nombres de equipos, de procesos, de servicios) llega a
|
|
249
|
+
Claude como dato. El nombre que anuncia un cliente DHCP se reduce a los caracteres de un
|
|
250
|
+
nombre de equipo, pero un texto así sigue siendo información no fiable.
|
|
251
|
+
- `red_interfaces` tarda unos 2 segundos por NAS: mide el caudal entre dos lecturas.
|
|
252
|
+
- Las herramientas de discos se han probado en real contra QuTS hero h6.0.2 (dos pools ZFS,
|
|
253
|
+
NVMe y caché) y contra QTS 5.2.9 (RAID 6 de 7 discos con repuesto, caché SSD, 27
|
|
254
|
+
instantáneas y 34 carpetas; ahí `carpetas_compartidas` ronda los 22 KB).
|
|
255
|
+
- No se han podido validar con un NAS real: una cabina de expansión, un volumen cifrado, y un
|
|
256
|
+
pool o un grupo RAID degradado o reconstruyéndose (se prueban con salidas escritas con el
|
|
257
|
+
formato del sistema). iSCSI se lee, pero ningún NAS de pruebas tenía destinos ni LUN.
|
|
258
|
+
- `carpetas_compartidas` da los permisos de Samba (`smb.conf`) y las exportaciones NFS. No da
|
|
259
|
+
los permisos avanzados (ACL) ni los de subcarpetas, ni el tamaño real de una subcarpeta: eso
|
|
260
|
+
exigiría recorrer el disco.
|
|
261
|
+
- El espacio que retienen las instantáneas solo lo da QuTS hero. En QTS, el `volumen` de una
|
|
262
|
+
instantánea es el número de volumen lógico (`lv` en `volumenes`), que no siempre coincide
|
|
263
|
+
con el `id` del volumen.
|
|
264
|
+
- Sin `sudo` no hay temperatura ni SMART: `discos_fisicos` lo dice en `errores` en vez de dar
|
|
265
|
+
cero grados.
|
|
266
|
+
- `rendimiento_discos` tarda 5 segundos por NAS.
|
|
267
|
+
- La temperatura de los discos se da, pero no genera avisos: no hay un umbral que valga para
|
|
268
|
+
todos los discos.
|
|
269
|
+
- En QTS, un pool ligero no avisa por su ocupación de datos (los volúmenes gruesos la
|
|
270
|
+
reservan entera y un pool sano está siempre alto): avisa por el umbral que tenga puesto en
|
|
271
|
+
el NAS, por los metadatos, por el modo y por fallo.
|
|
272
|
+
|
|
273
|
+
- Las herramientas de virtualización se han probado en real contra QuTS hero h6.0.2 (6
|
|
274
|
+
máquinas virtuales, 6 contenedores parados) y contra QTS 5.2.9 (9 máquinas, 45 contenedores,
|
|
275
|
+
35 redes). Con 45 contenedores, `contenedores_lista` ronda los 21 KB; `contenedor_logs` con
|
|
276
|
+
200 líneas puede llegar a 80 KB.
|
|
277
|
+
- De una máquina virtual se ve lo que sabe el NAS, no lo que pasa dentro: no hay datos del
|
|
278
|
+
sistema invitado (su agente no se puede consultar en solo lectura), y su IP solo aparece si
|
|
279
|
+
el NAS la tiene en su tabla ARP, que es lo menos frecuente.
|
|
280
|
+
- No se dan las copias de seguridad ni las tareas programadas de Virtualization Station, ni
|
|
281
|
+
capturas de la consola.
|
|
282
|
+
- De `vm_snapshots`: lo que ocupa "una instantánea" no se puede dar; se da lo que ocupa cada
|
|
283
|
+
capa de la imagen y desde cuándo se escribe en ella. Puede haber más capas que instantáneas.
|
|
284
|
+
Si no se encuentra la carpeta de metadatos de una máquina, sus instantáneas salen sin valor
|
|
285
|
+
y se dice en `errores` (no se dan por cero).
|
|
286
|
+
- La descripción de una máquina virtual solo se da si ocupa una línea; si tiene varias, sale
|
|
287
|
+
sin valor. En `virtualizacion_resumen`, `vcpus_en_marcha` y `memoria_en_marcha` cuentan todas
|
|
288
|
+
las máquinas que ocupan memoria del NAS (también las que están en pausa), no solo las del
|
|
289
|
+
estado "en marcha".
|
|
290
|
+
- `contenedor_detalle` da como mucho 50 puertos y 50 montajes de un contenedor, con su cuenta
|
|
291
|
+
(un rango de puertos publicado son miles de entradas).
|
|
292
|
+
- De los contenedores solo se ven los de Docker. De las instancias de LXD, `virtualizacion_resumen`
|
|
293
|
+
dice únicamente que existen (el cliente `lxc` escribe en la carpeta del usuario y no se usa).
|
|
294
|
+
- No se da el espacio que ocupan imágenes, contenedores y volúmenes de Docker: calcularlo
|
|
295
|
+
(`docker system df`, o el tamaño en `docker ps`) no termina en un NAS con muchas imágenes.
|
|
296
|
+
- `vm_uso` tarda 5 segundos por NAS. `contenedores_uso` es una sola muestra y su CPU va referida
|
|
297
|
+
a un núcleo (100 = un núcleo entero).
|
|
298
|
+
- Las líneas del registro de un contenedor son texto que escribe un programa de terceros:
|
|
299
|
+
llegan recortadas a 400 caracteres y sin caracteres de control, y son datos, no instrucciones.
|
|
300
|
+
Un fallo de `docker` al pedirlas se distingue por su código de salida, no por el texto: una
|
|
301
|
+
línea del programa que empiece por "Error" se devuelve como lo que es.
|
|
302
|
+
- No se han podido validar con un NAS real: un paquete activo con su servicio parado, una
|
|
303
|
+
máquina en pausa o caída, un contenedor reiniciándose y las instancias de LXD (se prueban
|
|
304
|
+
con salidas escritas con el formato de cada herramienta).
|
|
305
|
+
|
|
306
|
+
- Las herramientas de registros y estado se han probado en real contra QuTS hero h6.0.2; con
|
|
307
|
+
QTS 5.2.9 se han validado sus órdenes y sus salidas reales (capturadas con el producto).
|
|
308
|
+
- Cada conexión del plugin deja su propio apunte en el registro de accesos del NAS (inicio y
|
|
309
|
+
cierre de sesión SSH), como cualquier otro inicio de sesión. Ese registro tiene tope: con
|
|
310
|
+
muchas consultas seguidas desplaza los accesos más antiguos.
|
|
311
|
+
- El registro de accesos no se recorre entero (en un NAS con mucha actividad tiene millones de
|
|
312
|
+
filas): los intentos fallidos se agrupan sobre los 200 últimos avisos, y se dice.
|
|
313
|
+
- No hay: historial de QuLog Center (vive en una base propia que no se lee), estado en vivo de
|
|
314
|
+
las fuentes de alimentación redundantes (no hay consulta; solo cuántas tiene el modelo), si
|
|
315
|
+
hay firmware nuevo (el NAS no guarda el resultado de la comprobación) ni destinatarios de
|
|
316
|
+
notificación.
|
|
317
|
+
- Sin `sudo` no hay temperaturas ni ventiladores: `salud_hardware` lo dice en `errores` en vez
|
|
318
|
+
de dar cero grados. Un ventilador a 0 RPM con `sudo` sí es un dato (y un aviso).
|
|
319
|
+
- Las fechas de `eventos`, `accesos` y `kernel` van en la hora local del NAS; las de `avisos` y la
|
|
320
|
+
del último apagado forzado, en UTC (acaban en `Z`): el NAS las guarda en segundos y el desfase
|
|
321
|
+
de hoy no vale para las de antes de un cambio de hora.
|
|
322
|
+
- La contraseña común sale como `***` en todo lo que devuelve el plugin, también dentro de un
|
|
323
|
+
registro: alguien puede haberla tecleado en el campo de usuario de la web, y el NAS lo anota.
|
|
324
|
+
- Si una fila de un registro se puede partir en columnas de dos maneras (un texto que imita las
|
|
325
|
+
columnas que lo siguen), la consulta da error en vez de elegir una.
|
|
326
|
+
- Las gravedades 0 y 5 de los avisos del escritorio, el nivel de alerta y los valores de la
|
|
327
|
+
política de actualización automática (`modo`, `modo_v3`, `programa`) salen con el valor que
|
|
328
|
+
guarda el NAS: su significado no se ha podido validar. El SAI solo se ha visto desactivado
|
|
329
|
+
(ningún NAS de pruebas tiene uno conectado).
|
|
330
|
+
|
|
331
|
+
## Desarrollo
|
|
332
|
+
|
|
333
|
+
```
|
|
334
|
+
python -m venv .venv
|
|
335
|
+
.venv\Scripts\python.exe -m pip install -e .[dev]
|
|
336
|
+
.venv\Scripts\python.exe -m pytest -q
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Las pruebas no tocan ningún NAS: usan un NAS simulado que responde con salidas reales
|
|
340
|
+
anonimizadas (`tests/datos/`). Las pruebas contra un NAS real (`tests/test_real_*.py`) solo se
|
|
341
|
+
ejecutan con `QNAP_TOOLS_PRUEBA_REAL=1` y un `.env` con los datos del NAS de laboratorio.
|
|
342
|
+
`pruebas/` es el laboratorio de exploración: arnés de solo lectura, guardia de comandos y
|
|
343
|
+
prueba de efectos secundarios.
|
|
344
|
+
|
|
345
|
+
Para probar el plugin con el código local en vez del paquete de PyPI, cambia en
|
|
346
|
+
`.claude-plugin/plugin.json` el `qnap-tools==<versión>` de cada servidor por
|
|
347
|
+
`${CLAUDE_PLUGIN_ROOT}` e instálalo desde un **clon limpio** (Claude Code copia la carpeta
|
|
348
|
+
entera a su caché de plugins: que no lleve credenciales ni salidas de pruebas):
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
claude plugin marketplace add ./qnap-tools
|
|
352
|
+
claude plugin install qnap-tools@qnap-tools
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Diseño: `docs/superpowers/specs/2026-10-13-qnap-tools-design.md`.
|
|
356
|
+
|
|
357
|
+
## Licencia
|
|
358
|
+
|
|
359
|
+
[MIT](LICENSE).
|