fix(awooop): Phase 2 初批 P0 修正 + Phase 1 Task 1.7 integration tests
## P0 安全 / 架構修正
### P0-08 telemetry.py — 移除硬碼 IP assert(ADR-121)
- config.py:新增 OTEL_ALLOWED_ENDPOINTS(預設 192.168.0.188)+ OTEL_FORBIDDEN_ENDPOINTS
- telemetry.py:_validate_endpoint() 改為 config-driven allowlist/forbidlist
- EwoooC 可用 env 覆寫 OTEL_ALLOWED_ENDPOINTS 指向自己的 SigNoz host
### P0-13 mcp_bridge.py — K8s namespace 由 settings 提供
- config.py:新增 AWOOOI_K8S_NAMESPACE(預設 "awoooi-prod")
- mcp_bridge.py:5 處 parameters.get("namespace", "awoooi-prod") → settings.AWOOOI_K8S_NAMESPACE
- EwoooC/Tsenyang 可設自己的 namespace
### P1-24 decision_manager.py — silence key 常數統一
- 新增 from src.services.telegram_gateway import SILENCE_KEY_PREFIX
- f"telegram_silence:{target}" → f"{SILENCE_KEY_PREFIX}{target}"
- 消除跨兩處重複定義(ADR-118 No Island Coding 原則)
## Phase 1 Task 1.7 Integration Tests
- tests/integration/test_awooop_phase1_schema.py:31 個測試案例
- awooop_projects CHECK 約束(4 cases)
- revision 不可變性 trigger(5 cases:draft 可改、published 鎖住、身份欄不可改、非法流轉、DELETE 禁止)
- awooop_published_revisions VIEW draft/published 隔離(2 cases)
- active_pointer_guard(3 cases:不可指向 draft、可指向 active、跨租戶 mismatch)
- RLS fail-closed(3 cases:未設/錯設/正確設 project_id)
- outbox FK + dedup(2 cases)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@ from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
from src.core.config import settings # P0-13: K8s namespace 由 settings.AWOOOI_K8S_NAMESPACE 提供
|
||||
from src.utils.timezone import now_taipei
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -589,7 +590,7 @@ class MCPBridge:
|
||||
|
||||
if tool_name == "kubectl_get":
|
||||
# 使用 kubectl 指令查詢
|
||||
namespace = parameters.get("namespace", "awoooi-prod")
|
||||
namespace = parameters.get("namespace", settings.AWOOOI_K8S_NAMESPACE)
|
||||
resource = parameters.get("resource", "pods")
|
||||
name = parameters.get("name", "")
|
||||
cmd = f"kubectl get {resource} {name} -n {namespace} -o json".strip()
|
||||
@@ -599,7 +600,7 @@ class MCPBridge:
|
||||
return {"error": result.error}
|
||||
|
||||
elif tool_name == "kubectl_delete":
|
||||
namespace = parameters.get("namespace", "awoooi-prod")
|
||||
namespace = parameters.get("namespace", settings.AWOOOI_K8S_NAMESPACE)
|
||||
resource = parameters.get("resource", "pod")
|
||||
name = parameters.get("name", "")
|
||||
if not name:
|
||||
@@ -628,7 +629,7 @@ class MCPBridge:
|
||||
}
|
||||
|
||||
elif tool_name == "kubectl_scale":
|
||||
namespace = parameters.get("namespace", "awoooi-prod")
|
||||
namespace = parameters.get("namespace", settings.AWOOOI_K8S_NAMESPACE)
|
||||
deployment = parameters.get("deployment", "")
|
||||
replicas = parameters.get("replicas", 1)
|
||||
if not deployment:
|
||||
@@ -644,7 +645,7 @@ class MCPBridge:
|
||||
}
|
||||
|
||||
elif tool_name == "kubectl_restart":
|
||||
namespace = parameters.get("namespace", "awoooi-prod")
|
||||
namespace = parameters.get("namespace", settings.AWOOOI_K8S_NAMESPACE)
|
||||
deployment = parameters.get("deployment", "")
|
||||
if not deployment:
|
||||
return {"error": "Missing 'deployment' parameter"}
|
||||
@@ -678,7 +679,7 @@ class MCPBridge:
|
||||
if not service_name:
|
||||
return {"error": "Missing 'service_name' parameter"}
|
||||
|
||||
namespace = parameters.get("namespace", "awoooi-prod")
|
||||
namespace = parameters.get("namespace", settings.AWOOOI_K8S_NAMESPACE)
|
||||
time_window = parameters.get("time_window_minutes", 10)
|
||||
|
||||
metrics = await signoz.get_gold_metrics(
|
||||
|
||||
Reference in New Issue
Block a user