fix(ssh-auto): 主機告警 SSH 自動診斷授權(HostHighCpuLoad 不再卡人工審核)
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 9m7s
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 9m7s
根因:SSH_MCP_ALLOWED_HOSTS 未設定 → _ssh_execute() 全部攔截
+ auto_approve 只認 kubectl 不認 ssh → 主機告警永遠降級人工
修復:
- ConfigMap: 補 SSH_MCP_ALLOWED_HOSTS 四主機白名單
- alert_rules: HostHighCpuLoad 等從 NO_ACTION 改為 ssh_diagnose 指令
- auto_approve: _has_executable 加入 ssh 開頭識別
- decision_manager: _ssh_execute() 加入 ssh_diagnose 路由
- ssh_provider: 新增 ssh_diagnose tool(ps aux + free -h + df -h,只讀)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -301,11 +301,19 @@ class AutoApprovePolicy:
|
||||
# P1-2 改用 NO_EXECUTABLE_ACTION(避免污染 KM 飛輪學習資料)
|
||||
_raw_action = proposal_data.get("action", "") or ""
|
||||
_kubectl_cmd = proposal_data.get("kubectl_command", "") or ""
|
||||
_has_kubectl = "kubectl" in _raw_action.lower() or "kubectl" in _kubectl_cmd.lower()
|
||||
if not _has_kubectl:
|
||||
# 2026-04-27 Claude Sonnet 4.6: 擴充可執行指令識別,加入 SSH 診斷路徑
|
||||
# 根因:_has_kubectl 只認 kubectl,SSH 診斷指令(主機告警)被全部攔截 → 飛輪停轉
|
||||
# 修復:ssh {host} '...' 格式也是可執行指令,允許走 _ssh_execute() 路徑
|
||||
_has_executable = (
|
||||
"kubectl" in _raw_action.lower()
|
||||
or "kubectl" in _kubectl_cmd.lower()
|
||||
or _raw_action.lower().strip().startswith("ssh ")
|
||||
or _kubectl_cmd.lower().strip().startswith("ssh ")
|
||||
)
|
||||
if not _has_executable:
|
||||
return self._reject(
|
||||
reason=AutoApproveReason.NO_EXECUTABLE_ACTION,
|
||||
detail=f"Action '{_raw_action[:60] or _kubectl_cmd[:60]}' is natural language — no kubectl command, requires human review",
|
||||
detail=f"Action '{_raw_action[:60] or _kubectl_cmd[:60]}' is natural language — no kubectl/ssh command, requires human review",
|
||||
risk_level=risk_level,
|
||||
trust_score=trust_score,
|
||||
confidence=confidence,
|
||||
|
||||
@@ -3101,6 +3101,9 @@ class DecisionManager:
|
||||
return
|
||||
|
||||
# 解析 SSH tool + params
|
||||
# 2026-04-27 Claude Sonnet 4.6: 加入主機診斷路徑
|
||||
# 根因:只支援 docker/systemctl restart,主機告警 ssh {host} '...' 格式全降級人工
|
||||
# 修復:識別 ssh_diagnose 模式,路由到 ssh_get_top_processes / ssh_get_disk_usage
|
||||
_action_lower = action.lower().strip()
|
||||
if _action_lower.startswith("docker restart"):
|
||||
_tool = "docker_restart"
|
||||
@@ -3108,6 +3111,9 @@ class DecisionManager:
|
||||
elif _action_lower.startswith("systemctl restart"):
|
||||
_tool = "service_restart"
|
||||
_service = target
|
||||
elif _action_lower.startswith("ssh ") and ("ps aux" in _action_lower or "top" in _action_lower or "free" in _action_lower or "df -h" in _action_lower or "uptime" in _action_lower):
|
||||
# 主機診斷指令:自動收集 CPU/記憶體/磁碟,不修改任何狀態
|
||||
_tool = "ssh_diagnose"
|
||||
else:
|
||||
logger.info(
|
||||
"ssh_execute_unknown_action",
|
||||
@@ -3125,8 +3131,9 @@ class DecisionManager:
|
||||
params: dict = {"host": _host}
|
||||
if _tool == "docker_restart":
|
||||
params["container"] = _container
|
||||
else:
|
||||
elif _tool == "service_restart":
|
||||
params["service"] = _service
|
||||
# ssh_diagnose: 只需 host,無額外 params
|
||||
|
||||
try:
|
||||
result = await self._ssh.execute(tool_name=_tool, parameters=params)
|
||||
|
||||
Reference in New Issue
Block a user