feat(ops-patrol): Layer 3 巡检与 Telegram 配置打通

保存 Telegram 时同步至 .env,health_monitor 支持 MySQL 回退,
设置页展示巡检状态,部署时自动安装 cron。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Nexus Agent
2026-06-07 20:17:24 +08:00
parent 66a4cba39b
commit f9934bd4f1
13 changed files with 642 additions and 2 deletions
+68
View File
@@ -377,6 +377,14 @@ async def set_setting(
ip_address=request.client.host if request.client else "",
))
if key in ("telegram_bot_token", "telegram_chat_id"):
try:
from server.application.services.ops_patrol_sync import sync_telegram_to_env
sync_telegram_to_env(_settings.TELEGRAM_BOT_TOKEN, _settings.TELEGRAM_CHAT_ID)
except Exception as exc:
_logger.warning("Layer-3 Telegram env sync failed after %s update: %s", key, exc)
return {"key": setting.key, "value": setting.value}
@@ -898,6 +906,66 @@ async def alert_stats(
}
# ── Layer-3 Host Patrol (health_monitor.sh) ──
@router.get("/ops-patrol/status", response_model=dict)
async def ops_patrol_status(
admin: Admin = Depends(get_current_admin),
):
"""Report Telegram readiness for Layer-3 cron patrol and env sync state."""
from server.config import settings as _settings
from server.application.services.ops_patrol_sync import read_telegram_env_status
app_configured = bool(_settings.TELEGRAM_BOT_TOKEN and _settings.TELEGRAM_CHAT_ID)
env_status = read_telegram_env_status()
return {
"telegram_app_configured": app_configured,
"telegram_layer3_ready": app_configured,
"telegram_env_synced": env_status["env_synced"],
"env_status": env_status,
"db_fallback_enabled": True,
"cron_install_command": "sudo nx cron",
"health_log_path": "/var/log/nexus_health.log",
}
@router.post("/ops-patrol/sync-telegram", response_model=dict)
async def ops_patrol_sync_telegram(
request: Request,
admin: Admin = Depends(get_current_admin),
db: AsyncSession = Depends(get_db),
):
"""Sync DB Telegram credentials to .env files readable by health_monitor.sh."""
from server.config import settings as _settings
from server.application.services.ops_patrol_sync import (
read_telegram_env_status,
sync_telegram_to_env,
)
if not _settings.TELEGRAM_BOT_TOKEN or not _settings.TELEGRAM_CHAT_ID:
raise HTTPException(status_code=400, detail="请先在上方保存 Bot Token 与 Chat ID")
result = sync_telegram_to_env(_settings.TELEGRAM_BOT_TOKEN, _settings.TELEGRAM_CHAT_ID)
if result.get("skipped"):
raise HTTPException(status_code=400, detail="Telegram 未配置,无法同步")
audit_repo = AuditLogRepositoryImpl(db)
await audit_repo.create(AuditLog(
admin_username=admin.username,
action="sync_patrol_telegram",
target_type="setting",
detail=f"app_env={result.get('app_env')} host_env_prod={result.get('host_env_prod')}",
ip_address=request.client.host if request.client else "",
))
env_status = read_telegram_env_status()
return {
"synced": result,
"env_status": env_status,
"telegram_layer3_ready": True,
}
# ── Telegram Test + Chat ID Detection ──
async def _telegram_clear_webhook_if_set(client, base_url: str) -> None: