Files
vps_monitoring/server/services/ssh_manager.py
Андрей Бобырев e6e88314d5 feat: initial VPS monitoring platform
- FastAPI backend with auth, server CRUD, metrics collection
- Web dashboard with dark theme, server cards, SSH terminal (xterm.js)
- Telegram bot with inline keyboards, server management, reboot
- Telegram Mini App for mobile monitoring
- Background monitoring via asyncssh (CPU, RAM, Disk, Network, Uptime)
- Alert system with configurable thresholds
- WebSocket SSH terminal in browser
- One-command install script
- Systemd service configuration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-20 05:47:28 +03:00

70 lines
2.0 KiB
Python

import asyncio
import logging
from typing import Dict, Optional
import asyncssh
logger = logging.getLogger(__name__)
active_sessions: Dict[str, asyncssh.SSHClientConnection] = {}
async def create_ssh_session(server: dict) -> Optional[asyncssh.SSHClientConnection]:
"""Create SSH connection to server."""
try:
conn_kwargs = {
"host": server["host"],
"port": server.get("port", 22),
"username": server.get("username", "root"),
"known_hosts": None,
"connect_timeout": 15,
}
if server.get("password"):
conn_kwargs["password"] = server["password"]
elif server.get("ssh_key"):
conn_kwargs["client_keys"] = [server["ssh_key"]]
conn = await asyncssh.connect(**conn_kwargs)
active_sessions[server["host"]] = conn
return conn
except Exception as e:
logger.error(f"SSH connection failed to {server['host']}: {e}")
return None
async def execute_command(server: dict, command: str) -> dict:
"""Execute command on remote server."""
try:
conn_kwargs = {
"host": server["host"],
"port": server.get("port", 22),
"username": server.get("username", "root"),
"known_hosts": None,
"connect_timeout": 15,
}
if server.get("password"):
conn_kwargs["password"] = server["password"]
elif server.get("ssh_key"):
conn_kwargs["client_keys"] = [server["ssh_key"]]
async with asyncssh.connect(**conn_kwargs) as conn:
result = await conn.run(command, check=False, timeout=30)
return {
"stdout": result.stdout,
"stderr": result.stderr,
"exit_code": result.exit_status,
}
except Exception as e:
return {"stdout": "", "stderr": str(e), "exit_code": -1}
async def close_session(host: str):
"""Close SSH session."""
conn = active_sessions.pop(host, None)
if conn:
conn.close()