feat: multi-type server support — SQL, Redis, Grafana, Prometheus, Telnet, WinRM, RDP/VNC

Full implementation of multi-type server management across GUI and CLI:

New clients: SQLClient (MariaDB/MSSQL/PostgreSQL), RedisClient, GrafanaClient,
PrometheusClient, TelnetSession, WinRMClient, RemoteDesktopLauncher.

New GUI tabs: QueryTab (SQL editor + Treeview), RedisTab (console + history),
GrafanaTab (dashboards + alerts), PrometheusTab (PromQL + targets),
PowershellTab (PS/CMD), LaunchTab (RDP/VNC external client).

Infrastructure: TAB_REGISTRY for conditional tabs per server type,
adaptive server_dialog fields, colored type badges in sidebar,
status checker for all types (SSH/TCP/SQL/Redis/HTTP), 100+ i18n keys.

CLI: ssh.py extended with --sql, --redis, --grafana-*, --prom-*, --ps, --cmd.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chrome-storm-c442
2026-02-24 09:35:24 -05:00
parent 2d1d942ddc
commit eede67e6a9
26 changed files with 3990 additions and 168 deletions

124
core/remote_desktop.py Normal file
View File

@@ -0,0 +1,124 @@
"""
Remote desktop launchers — RDP and VNC via external clients.
"""
import os
import platform
import subprocess
import tempfile
from core.logger import log
class RemoteDesktopLauncher:
"""Launch external RDP/VNC clients for remote desktop connections."""
@staticmethod
def launch_rdp(server: dict) -> str:
"""Generate a .rdp temp file and launch the system RDP client.
Returns:
Status message string.
"""
hostname = server["ip"]
port = server.get("port", 3389)
user = server.get("user", "Administrator")
rdp_content = (
f"full address:s:{hostname}:{port}\r\n"
f"username:s:{user}\r\n"
"prompt for credentials:i:1\r\n"
"screen mode id:i:2\r\n"
"desktopwidth:i:1920\r\n"
"desktopheight:i:1080\r\n"
"session bpp:i:32\r\n"
"compression:i:1\r\n"
"disable wallpaper:i:0\r\n"
"allow font smoothing:i:1\r\n"
"networkautodetect:i:1\r\n"
"bandwidthautodetect:i:1\r\n"
)
alias = server.get("alias", "remote")
rdp_file = os.path.join(tempfile.gettempdir(), f"sm_{alias}.rdp")
with open(rdp_file, "w", encoding="utf-8") as f:
f.write(rdp_content)
log.info(f"RDP file created: {rdp_file}")
system = platform.system()
if system == "Windows":
os.startfile(rdp_file)
return f"RDP launched via mstsc for {alias}"
elif system == "Linux":
try:
subprocess.Popen(
["xfreerdp", f"/v:{hostname}:{port}", f"/u:{user}", "/dynamic-resolution"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return f"RDP launched via xfreerdp for {alias}"
except FileNotFoundError:
log.warning("xfreerdp not found, trying rdesktop")
subprocess.Popen(
["rdesktop", f"{hostname}:{port}", "-u", user],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return f"RDP launched via rdesktop for {alias}"
elif system == "Darwin":
subprocess.Popen(["open", rdp_file])
return f"RDP launched via macOS for {alias}"
else:
return f"Unsupported platform: {system}. RDP file saved to {rdp_file}"
@staticmethod
def launch_vnc(server: dict) -> str:
"""Launch a VNC viewer for the given server.
Returns:
Status message string.
"""
hostname = server["ip"]
port = server.get("port", 5900)
alias = server.get("alias", "remote")
target = f"{hostname}:{port}"
log.info(f"VNC launching for {alias} at {target}")
system = platform.system()
if system == "Windows":
# Try common VNC viewer paths
viewers = [
r"C:\Program Files\TightVNC\tvnviewer.exe",
r"C:\Program Files (x86)\TightVNC\tvnviewer.exe",
r"C:\Program Files\RealVNC\VNC Viewer\vncviewer.exe",
r"C:\Program Files (x86)\RealVNC\VNC Viewer\vncviewer.exe",
]
for viewer in viewers:
if os.path.exists(viewer):
subprocess.Popen([viewer, target])
return f"VNC launched via {os.path.basename(viewer)} for {alias}"
# Fallback: try vncviewer in PATH
try:
subprocess.Popen(["vncviewer", target])
return f"VNC launched via vncviewer for {alias}"
except FileNotFoundError:
return "No VNC viewer found. Install TightVNC or RealVNC Viewer."
elif system == "Linux":
for cmd in ["vncviewer", "xtigervncviewer", "remmina"]:
try:
args = [cmd, target] if cmd != "remmina" else [cmd, f"vnc://{target}"]
subprocess.Popen(args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
return f"VNC launched via {cmd} for {alias}"
except FileNotFoundError:
continue
return "No VNC viewer found. Install tigervnc-viewer or remmina."
elif system == "Darwin":
subprocess.Popen(["open", f"vnc://{target}"])
return f"VNC launched via macOS Screen Sharing for {alias}"
else:
return f"Unsupported platform: {system}"