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:
@@ -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)
|
||||
|
||||
### Выполнить команду на сервере
|
||||
|
||||
101
tools/ssh.py
101
tools/ssh.py
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user