fix(auto-approve): 主機告警 SSH 診斷指令豁免 bad_target 驗證 — 修復 no_executable_action

根因:host_resource_alert 規則使用 {host}(由 instance label 派生),
與 {target} 無關;但 host 告警缺少 K8s deployment label 導致 target=unknown,
_is_bad_target=True → kubectl_command 被清空 → auto_approve 以
no_executable_action 拒絕 → 每日 3 次人工攔截。

修復:
- alert_rule_engine.py: SSH 指令(startswith "ssh ")跳過 bad_target 驗證
- prompts.py: 主 + Nemo prompt 補 Host* 告警 SSH 診斷規則,防 LLM fallback 路徑輸出 kubectl
- ssh_command_whitelist.py: 新建唯讀 SSH 指令白名單模組(供 _ssh_execute() 執行前驗證)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-05-04 14:15:05 +08:00
parent ccffaa5f3e
commit 54a4e59af9
3 changed files with 133 additions and 3 deletions

View File

@@ -108,10 +108,11 @@ The `alertname` field is your PRIMARY signal. Use it to determine the problem ty
| Alert category / alertname pattern | suggested_action | kubectl_command guidance |
|-------------------------------------|-----------------|--------------------------|
| starts with "Host" (HostHighCpuLoad, HostHighMemoryUsage, HostHighLoad, HostOutOfMemory, HostDisk*, etc.) | INVESTIGATE | `ssh <instance_ip> 'ps aux --sort=-%cpu \| head -15; free -h; uptime'` — use labels.instance for host IP; do NOT use kubectl |
| contains "Disk", "Storage", "PVC", "Volume" | NO_ACTION | `kubectl exec <pod> -- df -h` or `kubectl get pvc -n <ns>` |
| contains "Postgres", "MySQL", "Redis", "DB", "Database" | NO_ACTION | `kubectl exec <pod> -- psql` or `kubectl logs <pod>` |
| contains "CrashLoop", "OOMKilled", "Pod" | DELETE_POD or RESTART_DEPLOYMENT | `kubectl delete pod <pod> -n <ns>` |
| contains "CPU", "Memory", "Resource" | TUNE_RESOURCES or SCALE_DEPLOYMENT | `kubectl top pod -n <ns>` or HPA command |
| contains "CPU", "Memory", "Resource" (K8s Pod alerts only — NOT Host* alerts) | TUNE_RESOURCES or SCALE_DEPLOYMENT | `kubectl top pod -n <ns>` or HPA command |
| contains "Node", "NodeNotReady" | NO_ACTION | `kubectl describe node <node>` |
| contains "SSL", "Certificate", "Cert" | NO_ACTION | `kubectl get certificate -n <ns>` |
| alert_category = "database" | NO_ACTION | DB investigation commands only |
@@ -184,10 +185,11 @@ You are an SRE AI. Analyze the alert and respond with ONLY valid JSON.
## CRITICAL: Read alertname first
The `alertname` field tells you what kind of problem this is. Use it:
- starts with "Host" (HostHighCpuLoad, HostHighMemoryUsage, HostHighLoad, HostOutOfMemory, HostDisk*, etc.) → suggested_action=INVESTIGATE, kubectl_command="ssh <labels.instance_ip> 'ps aux --sort=-%cpu | head -15; free -h; uptime'" — NO kubectl commands for host alerts
- "Disk/Storage/PVC/Volume" → suggested_action=NO_ACTION, kubectl_command="kubectl get pvc" or "kubectl exec <pod> -- df -h"
- "Postgres/MySQL/Redis/DB/Database" → suggested_action=NO_ACTION, DB investigation commands
- "CrashLoop/OOM/Pod" → suggested_action=DELETE_POD or RESTART_DEPLOYMENT
- "CPU/Memory/Resource" → suggested_action=TUNE_RESOURCES or SCALE_DEPLOYMENT
- "CPU/Memory/Resource" (K8s Pod alerts only) → suggested_action=TUNE_RESOURCES or SCALE_DEPLOYMENT
- "SSL/Cert" → suggested_action=NO_ACTION
NEVER use "kubectl rollout restart deployment/awoooi-prod" (that is the NAMESPACE, not a deployment).
Make action_title describe the ACTUAL problem (not generic "自動修復 AWOOOI 服務").