v1.8.60: multi-type status check + --add in skill + skill docs update

- _check_status_one: proper connectivity check per server type
  (SSH/SQL/Redis/Grafana/Prometheus/WinRM/RDP)
- ping_server uses _check_status_one instead of paramiko-only
- check_status shows server type column
- skill-ssh.md: allow --add, document it, update --status description
- CLAUDE.md: add --add/--remove/--set-note to command reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chrome-storm-c442
2026-02-25 05:26:24 -05:00
parent 1c4288ba93
commit 3a5d1b27fc
8 changed files with 108 additions and 12 deletions

View File

@@ -13,7 +13,7 @@
- Скрипт сам читает credentials, подключается, выполняет, возвращает результат
- **МАКСИМУМ 1 попытка** подключения. Если timeout/ошибка — сообщи, НЕ повторяй
- fail2ban банит IP после 5-10 неудач — спам попытками УБЬЁТ доступ к серверу
- **Серверы добавляются ТОЛЬКО через GUI** ServerManager, НЕ через CLI
- **Серверы можно добавлять** через `--add` (см. ниже) или через GUI ServerManager
## Аргументы
@@ -31,10 +31,11 @@ python ~/.server-connections/ssh.py --list
python ~/.server-connections/ssh.py --info ALIAS
```
### Статус всех серверов (alias + online/offline)
### Статус всех серверов (alias + тип + online/offline)
```bash
python ~/.server-connections/ssh.py --status
```
Проверяет каждый сервер по его типу: SSH-подключение, SQL-коннект, Redis PING, HTTP health-check и т.д.
### Обновить заметки сервера
```bash
@@ -47,6 +48,15 @@ python ~/.server-connections/ssh.py --remove ALIAS
```
**Спроси подтверждение у пользователя перед удалением!**
### Добавить сервер
```bash
python ~/.server-connections/ssh.py --add ALIAS IP PORT USER PASSWORD [--note "описание"]
```
- Автоматически устанавливает SSH-ключ после добавления
- Обновляет `~/.ssh/config`
- **Спроси у пользователя все параметры перед добавлением!**
- Тип сервера по умолчанию — ssh. Для других типов (mariadb, redis и т.д.) — добавь через GUI
## SSH-команды (тип: ssh)
### Выполнить команду на сервере

View File

@@ -314,9 +314,8 @@ def install_key(server: dict):
def ping_server(server: dict):
try:
client = get_client(server)
client.close()
print(f"{server['alias']}: ONLINE")
status = _check_status_one(server)
print(f"{server['alias']}: {status}")
except Exception as e:
print(f"{server['alias']}: OFFLINE ({type(e).__name__})")
@@ -388,18 +387,102 @@ def server_info(alias: str):
print(f"Notes: {notes}")
def _check_status_one(server: dict) -> str:
"""Check connectivity for a single server based on its type."""
stype = server.get("type", "ssh")
if stype in ("ssh", "telnet"):
client = get_client(server)
client.close()
return "ONLINE"
if stype in ("mariadb", "mysql", "mssql", "postgresql"):
host = server["ip"]
port = server.get("port", 3306)
user = server.get("user", "root")
password = server.get("password", "")
database = server.get("database", "")
if stype in ("mariadb", "mysql"):
import pymysql
conn = pymysql.connect(host=host, port=port, user=user, password=password,
database=database or None, connect_timeout=10)
elif stype == "mssql":
import pymssql
conn = pymssql.connect(server=host, port=port, user=user, password=password,
database=database or None, login_timeout=10)
elif stype == "postgresql":
import psycopg2
port = server.get("port", 5432)
conn = psycopg2.connect(host=host, port=port, user=user, password=password,
dbname=database or None, connect_timeout=10)
conn.close()
return "ONLINE"
if stype == "redis":
import redis as redis_lib
r = redis_lib.Redis(host=server["ip"], port=server.get("port", 6379),
password=server.get("password", "") or None,
db=server.get("db_index", 0), socket_timeout=10,
ssl=server.get("ssl", False))
r.ping()
r.close()
return "ONLINE"
if stype == "grafana":
import requests
host = server["ip"]
port = server.get("port", 3000)
protocol = "https" if server.get("ssl", False) else "http"
base_url = server.get("base_url", f"{protocol}://{host}:{port}")
resp = requests.get(f"{base_url.rstrip('/')}/api/health", timeout=10,
verify=server.get("ssl_verify", True))
resp.raise_for_status()
return "ONLINE"
if stype == "prometheus":
import requests
host = server["ip"]
port = server.get("port", 9090)
protocol = "https" if server.get("ssl", False) else "http"
base_url = server.get("base_url", f"{protocol}://{host}:{port}")
auth = None
user = server.get("user", "")
password = server.get("password", "")
if user and password:
auth = (user, password)
resp = requests.get(f"{base_url.rstrip('/')}/api/v1/status/buildinfo",
auth=auth, timeout=10, verify=server.get("ssl_verify", True))
resp.raise_for_status()
return "ONLINE"
if stype == "winrm":
session = _get_winrm_session(server)
result = session.run_cmd("echo ok")
if result.status_code == 0:
return "ONLINE"
return "OFFLINE"
# rdp/vnc — just TCP ping
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
port = server.get("port", 3389 if stype == "rdp" else 5900)
sock.connect((server["ip"], port))
sock.close()
return "ONLINE"
def check_status():
_, servers = load_servers()
print(f"{'Alias':<20} {'Status':<10}")
print("-" * 30)
print(f"{'Alias':<20} {'Type':<12} {'Status':<10}")
print("-" * 42)
for alias, s in servers.items():
stype = s.get("type", "ssh")
try:
client = get_client(s)
client.close()
status = "ONLINE"
status = _check_status_one(s)
except Exception:
status = "OFFLINE"
print(f"{alias:<20} {status:<10}")
print(f"{alias:<20} {stype:<12} {status:<10}")
def add_server(args):