Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
統帥批准 Phase 5 全 Sprint,Sprint 5.0 產出:
1. callback_action_spec.yaml (24 actions)
- 10 查類 (info 2-part callback, 無副作用): check_process, check_port,
check_log_*, check_health, check_pod_logs, describe_pod, open_signoz,
open_flywheel
- 10 寫類 (nonce 4-part, 有副作用): k8s_restart/scale_up/scale_down/rollback,
host_restart_service/clear_log, docker_restart, minio_restart,
reload_nginx, renew_cert
- 4 secops (Multi-Sig CRITICAL): secops_isolate/block_ip/evict/authorize
2. callback_dispatcher.py
- Registry pattern (lru_cache): get_action_spec / list_actions_for_category
- 模板變數替換: {incident_id} / {labels.xxx} / {signals[0].xxx}
- dispatch_action() 骨架 (Sprint 5.2+ 接 MCP)
- _format_reply: text/code/truncated/url 4 種格式
3. test_callback_dispatcher.py (22 tests全過)
- Registry loading 正確性
- Category filtering
- Template resolution (含 nested list index)
- dispatch stub 返回正確 spec 提示
下一步 Sprint 5.1: 接入 MCP registry + telegram callback_handler 整合
MCP 底層能力已有 (k8s 10+ tools, ssh 15 tools)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
431 lines
11 KiB
YAML
431 lines
11 KiB
YAML
# Telegram 分類按鈕 Action 規格註冊表
|
||
# ============================================
|
||
# Phase 5 Sprint 5.0 — 2026-04-14 Claude Sonnet 4.6
|
||
# 相關: docs/superpowers/plans/2026-04-14-PHASE-5-category-buttons-completion.md
|
||
#
|
||
# 格式:
|
||
# actions:
|
||
# <action_name>:
|
||
# label: <UI 顯示文字>
|
||
# emoji: <按鈕 emoji>
|
||
# risk: low | medium | high | critical
|
||
# callback_format: info | nonce # info=2-part (查類), nonce=4-part (寫類)
|
||
# category: <alert_category> # 綁定於 classify_alert_early 輸出
|
||
# mcp:
|
||
# provider: k8s | ssh | prometheus | signoz | database | internal
|
||
# tool: <MCP tool name>
|
||
# params: # 參數模板 (支援 {incident_id}/{labels.xxx}/{signals[0].xxx})
|
||
# <key>: <template>
|
||
# reply_format: text | code | url | truncated # 執行結果 reply 樣式
|
||
# requires_multi_sig: false # secops 類設 true
|
||
# timeout_sec: 10 # MCP 呼叫 timeout
|
||
# description: <說明>
|
||
|
||
version: "1.0"
|
||
last_updated: "2026-04-14"
|
||
|
||
actions:
|
||
# ==========================================================================
|
||
# 查類按鈕(無副作用,2-part info callback)
|
||
# ==========================================================================
|
||
|
||
check_process:
|
||
label: "查程序"
|
||
emoji: "🔍"
|
||
risk: low
|
||
callback_format: info
|
||
category: host_resource
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_get_top_processes
|
||
params:
|
||
host: "{labels.instance}"
|
||
limit: 10
|
||
reply_format: code
|
||
timeout_sec: 8
|
||
description: "列出主機上 CPU 最高的 10 個程序"
|
||
|
||
check_log_nginx:
|
||
label: "查 Nginx Log"
|
||
emoji: "📋"
|
||
risk: low
|
||
callback_format: info
|
||
category: network
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_get_nginx_error_log
|
||
params:
|
||
host: "{labels.instance}"
|
||
lines: 50
|
||
reply_format: truncated
|
||
timeout_sec: 10
|
||
description: "最後 50 行 Nginx error log"
|
||
|
||
check_log_container:
|
||
label: "查容器 Log"
|
||
emoji: "📋"
|
||
risk: low
|
||
callback_format: info
|
||
category: devops_tool
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_get_container_logs
|
||
params:
|
||
host: "{labels.instance}"
|
||
container: "{labels.container}"
|
||
lines: 50
|
||
reply_format: truncated
|
||
timeout_sec: 10
|
||
description: "最後 50 行容器 stdout/stderr log"
|
||
|
||
check_log_minio:
|
||
label: "查 MinIO Log"
|
||
emoji: "📋"
|
||
risk: low
|
||
callback_format: info
|
||
category: storage
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_get_container_logs
|
||
params:
|
||
host: "192.168.0.188"
|
||
container: "minio"
|
||
lines: 50
|
||
reply_format: truncated
|
||
timeout_sec: 10
|
||
description: "MinIO 容器最後 50 行 log"
|
||
|
||
check_port:
|
||
label: "查 Port"
|
||
emoji: "🔌"
|
||
risk: low
|
||
callback_format: info
|
||
category: network
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_check_port
|
||
params:
|
||
host: "{labels.instance}"
|
||
port: "{labels.port}"
|
||
reply_format: text
|
||
timeout_sec: 5
|
||
description: "檢查主機上指定 port 是否 LISTEN"
|
||
|
||
check_health:
|
||
label: "查健康狀態"
|
||
emoji: "🔍"
|
||
risk: low
|
||
callback_format: info
|
||
category: external_site
|
||
mcp:
|
||
provider: prometheus
|
||
tool: prometheus_query
|
||
params:
|
||
query: 'probe_success{{instance="{labels.instance}"}}'
|
||
reply_format: text
|
||
timeout_sec: 5
|
||
description: "Blackbox probe 健康狀態"
|
||
|
||
check_pod_logs:
|
||
label: "查 Pod Log"
|
||
emoji: "📋"
|
||
risk: low
|
||
callback_format: info
|
||
category: kubernetes
|
||
mcp:
|
||
provider: k8s
|
||
tool: k8s_get_pod_logs
|
||
params:
|
||
namespace: "{labels.namespace}"
|
||
pod: "{labels.pod}"
|
||
tail_lines: 50
|
||
reply_format: truncated
|
||
timeout_sec: 8
|
||
description: "Pod 最後 50 行 log"
|
||
|
||
describe_pod:
|
||
label: "詳細 Pod"
|
||
emoji: "📜"
|
||
risk: low
|
||
callback_format: info
|
||
category: kubernetes
|
||
mcp:
|
||
provider: k8s
|
||
tool: k8s_describe_pod
|
||
params:
|
||
namespace: "{labels.namespace}"
|
||
pod: "{labels.pod}"
|
||
reply_format: truncated
|
||
timeout_sec: 5
|
||
description: "kubectl describe pod 完整資訊"
|
||
|
||
open_signoz:
|
||
label: "查 SignOz"
|
||
emoji: "🔍"
|
||
risk: low
|
||
callback_format: info
|
||
category: business
|
||
mcp:
|
||
provider: internal
|
||
tool: build_signoz_url
|
||
params:
|
||
service: "{labels.service}"
|
||
reply_format: url
|
||
timeout_sec: 1
|
||
description: "返回 SignOz deeplink"
|
||
|
||
open_flywheel:
|
||
label: "飛輪面板"
|
||
emoji: "📊"
|
||
risk: low
|
||
callback_format: info
|
||
category: flywheel_health
|
||
mcp:
|
||
provider: internal
|
||
tool: build_flywheel_url
|
||
params: {}
|
||
reply_format: url
|
||
timeout_sec: 1
|
||
description: "返回飛輪儀表板 URL"
|
||
|
||
# ==========================================================================
|
||
# 寫類按鈕(有副作用,4-part nonce callback)
|
||
# ==========================================================================
|
||
|
||
k8s_restart:
|
||
label: "重啟"
|
||
emoji: "🔄"
|
||
risk: medium
|
||
callback_format: nonce
|
||
category: kubernetes
|
||
mcp:
|
||
provider: k8s
|
||
tool: kubectl_restart
|
||
params:
|
||
namespace: "{labels.namespace}"
|
||
deployment: "{labels.deployment}"
|
||
reply_format: text
|
||
timeout_sec: 30
|
||
description: "kubectl rollout restart deployment"
|
||
|
||
k8s_scale_up:
|
||
label: "擴容 +1"
|
||
emoji: "📈"
|
||
risk: medium
|
||
callback_format: nonce
|
||
category: kubernetes
|
||
mcp:
|
||
provider: k8s
|
||
tool: kubectl_scale
|
||
params:
|
||
namespace: "{labels.namespace}"
|
||
deployment: "{labels.deployment}"
|
||
replicas_delta: 1
|
||
reply_format: text
|
||
timeout_sec: 10
|
||
description: "副本數 +1(單調遞增)"
|
||
|
||
k8s_scale_down:
|
||
label: "縮容 -1"
|
||
emoji: "📉"
|
||
risk: medium
|
||
callback_format: nonce
|
||
category: kubernetes
|
||
mcp:
|
||
provider: k8s
|
||
tool: kubectl_scale
|
||
params:
|
||
namespace: "{labels.namespace}"
|
||
deployment: "{labels.deployment}"
|
||
replicas_delta: -1
|
||
min_replicas: 1 # 禁止 scale to 0
|
||
reply_format: text
|
||
timeout_sec: 10
|
||
description: "副本數 -1(禁止到 0)"
|
||
|
||
k8s_rollback:
|
||
label: "回滾"
|
||
emoji: "⏪"
|
||
risk: high
|
||
callback_format: nonce
|
||
category: kubernetes
|
||
mcp:
|
||
provider: k8s
|
||
tool: kubectl_rollout_undo # 需 Sprint 5.3 新增此 MCP tool
|
||
params:
|
||
namespace: "{labels.namespace}"
|
||
deployment: "{labels.deployment}"
|
||
reply_format: text
|
||
timeout_sec: 60
|
||
description: "kubectl rollout undo(回到上一版)"
|
||
|
||
host_restart_service:
|
||
label: "重啟服務"
|
||
emoji: "🔄"
|
||
risk: high
|
||
callback_format: nonce
|
||
category: host_resource
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_systemctl_restart
|
||
params:
|
||
host: "{labels.instance}"
|
||
service: "{labels.service}"
|
||
reply_format: text
|
||
timeout_sec: 30
|
||
description: "systemctl restart 服務(主機層)"
|
||
|
||
host_clear_log:
|
||
label: "清 Log"
|
||
emoji: "🗑"
|
||
risk: low
|
||
callback_format: nonce
|
||
category: host_resource
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_clear_docker_logs
|
||
params:
|
||
host: "{labels.instance}"
|
||
container: "{labels.container}"
|
||
reply_format: text
|
||
timeout_sec: 10
|
||
description: "清空容器 log file"
|
||
|
||
docker_restart:
|
||
label: "重啟容器"
|
||
emoji: "🔄"
|
||
risk: high
|
||
callback_format: nonce
|
||
category: devops_tool
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_docker_restart
|
||
params:
|
||
host: "{labels.instance}"
|
||
container: "{labels.container}"
|
||
reply_format: text
|
||
timeout_sec: 30
|
||
description: "docker restart <container>"
|
||
|
||
minio_restart:
|
||
label: "重啟 MinIO"
|
||
emoji: "🔄"
|
||
risk: high
|
||
callback_format: nonce
|
||
category: storage
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_docker_restart
|
||
params:
|
||
host: "192.168.0.188"
|
||
container: "minio"
|
||
reply_format: text
|
||
timeout_sec: 30
|
||
description: "重啟 MinIO Docker 容器"
|
||
|
||
reload_nginx:
|
||
label: "重載 Nginx"
|
||
emoji: "🔄"
|
||
risk: low
|
||
callback_format: nonce
|
||
category: network
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_reload_nginx
|
||
params:
|
||
host: "{labels.instance}"
|
||
reply_format: text
|
||
timeout_sec: 10
|
||
description: "nginx -s reload(不停機)"
|
||
|
||
renew_cert:
|
||
label: "更新憑證"
|
||
emoji: "🔐"
|
||
risk: medium
|
||
callback_format: nonce
|
||
category: ssl_cert
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_renew_ssl
|
||
params:
|
||
host: "{labels.instance}"
|
||
domain: "{labels.domain}"
|
||
reply_format: text
|
||
timeout_sec: 60
|
||
description: "certbot renew"
|
||
|
||
# ==========================================================================
|
||
# 資安按鈕(CRITICAL,Multi-Sig 必要)
|
||
# ==========================================================================
|
||
|
||
secops_isolate:
|
||
label: "隔離資源"
|
||
emoji: "🚫"
|
||
risk: critical
|
||
callback_format: nonce
|
||
category: secops
|
||
requires_multi_sig: true
|
||
mcp:
|
||
provider: k8s
|
||
tool: kubectl_exec # 需 Sprint 5.4 實作 NetworkPolicy apply
|
||
params:
|
||
namespace: "{labels.namespace}"
|
||
command: "apply_network_policy_isolate"
|
||
target_pod: "{labels.pod}"
|
||
reply_format: text
|
||
timeout_sec: 30
|
||
description: "套用 NetworkPolicy 阻斷所有流量進入 Pod"
|
||
|
||
secops_block_ip:
|
||
label: "封鎖來源 IP"
|
||
emoji: "⛔"
|
||
risk: critical
|
||
callback_format: nonce
|
||
category: secops
|
||
requires_multi_sig: true
|
||
mcp:
|
||
provider: ssh
|
||
tool: ssh_systemctl_restart # 需擴充加 iptables rule
|
||
params:
|
||
host: "{labels.instance}"
|
||
service: "iptables-block"
|
||
source_ip: "{labels.attacker_ip}"
|
||
reply_format: text
|
||
timeout_sec: 30
|
||
description: "iptables DROP 來源 IP"
|
||
|
||
secops_evict:
|
||
label: "強制驅逐 Pod"
|
||
emoji: "🔄"
|
||
risk: critical
|
||
callback_format: nonce
|
||
category: secops
|
||
requires_multi_sig: true
|
||
mcp:
|
||
provider: k8s
|
||
tool: kubectl_delete
|
||
params:
|
||
namespace: "{labels.namespace}"
|
||
resource_type: pod
|
||
name: "{labels.pod}"
|
||
reply_format: text
|
||
timeout_sec: 30
|
||
description: "kubectl delete pod(會自動重建)"
|
||
|
||
secops_authorize:
|
||
label: "確認授權"
|
||
emoji: "✅"
|
||
risk: high
|
||
callback_format: nonce
|
||
category: secops
|
||
requires_multi_sig: false # 確認授權不需 multi-sig
|
||
mcp:
|
||
provider: internal
|
||
tool: record_authorization
|
||
params:
|
||
user_id: "{callback.user_id}"
|
||
source: "{labels.instance}"
|
||
reply_format: text
|
||
timeout_sec: 5
|
||
description: "記錄授權,後續同 source 不再告警(24h)"
|