Files
awoooi/k8s/drift-cronjob.yaml
OG T 3455044457
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 38s
Type Sync Check / check-type-sync (push) Failing after 35s
feat(phase25): Nemotron 主動防禦三方向 P0+P1+P2 完整實作
P0 - DIAGNOSE Privacy-First Routing:
- ai_router.py: _local_fallback_chain [NEMOTRON→OLLAMA→REJECT]
- DIAGNOSE 意圖 override 改為 NEMOTRON (原 OLLAMA)
- DIAGNOSE fallback 使用 local-only 鏈,不觸碰雲端
- 全部失敗時 REJECT + Telegram 通知
- config.py: NEMOTRON_DIAGNOSE_TIMEOUT_SECONDS=30, OLLAMA_DIAGNOSE_TIMEOUT_SECONDS=60
- nemotron.py: 根據 context[task_type] 選擇 timeout

P1 - Knowledge Auto-Harvesting:
- models/knowledge.py: EntryType.AUTO_RUNBOOK + ANTI_PATTERN + symptoms_hash
- EntryStatus.PUBLISHED (ANTI_PATTERN 直接發布,無需審核)
- models/playbook.py: SymptomPattern.compute_hash() (16字元確定性 hash)
- services/runbook_generator.py: NemotronRunbookGenerator (v1.1)
  - generate_runbook() → AUTO_RUNBOOK (DRAFT) + Telegram 審核 card
  - generate_anti_pattern() → ANTI_PATTERN (PUBLISHED) + Telegram 通知
  - 使用 nvidia.chat() (正確介面),Nemotron 超時時 Minimal fallback
- knowledge_service.py: check_anti_pattern(symptoms_hash, days=7)
- db/models.py: symptoms_hash VARCHAR(16) + ix_knowledge_symptoms_hash
- repositories/knowledge_repository.py: create() 支援 symptoms_hash + status
- auto_repair_service.py: anti_pattern_gate 在 decide() + runbook hook 在 execute()
- migrations/phase8_symptoms_hash.sql: ALTER TABLE + partial index + PUBLISHED constraint

P2 - Config Drift Detection:
- models/drift.py: DriftItem/DriftReport/DriftLevel/DriftIntent/DriftStatus
- services/drift_detector.py: GitStateReader + K8sStateReader + DriftDetector
- services/drift_analyzer.py: 白名單過濾 + DriftLevel 分級
- services/drift_interpreter.py: NemotronDriftInterpreter(意圖分析,不生成修復指令)
- services/drift_remediator.py: rollback(kubectl apply) + adopt(git push gitea)
- api/v1/drift.py: POST /scan, GET /reports, POST /rollback, POST /adopt
- migrations/phase9_drift_reports.sql: drift_reports 表
- k8s/drift-cronjob.yaml: 每小時自動掃描 CronJob

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:35:05 +08:00

72 lines
2.7 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Config Drift Detection CronJob - Phase 25 P2
# 每小時掃描 awoooi-prod namespace 的配置漂移
#
# 建立時間: 2026-04-04 (台北時區)
# 建立者: Claude Code (Phase 25 P2)
# 關聯設計: docs/superpowers/specs/2026-04-04-nemotron-active-defense-design.md 方向三
# 關聯 ADR: 待起草 ADR-057
#
# 部署: kubectl apply -f k8s/drift-cronjob.yaml -n awoooi-prod
# 手動觸發: kubectl create job --from=cronjob/drift-scanner drift-scan-manual -n awoooi-prod
# 查看 log: kubectl logs -l job-name=drift-scanner -n awoooi-prod
apiVersion: batch/v1
kind: CronJob
metadata:
name: drift-scanner
namespace: awoooi-prod
labels:
app: awoooi
component: drift-scanner
phase: "25"
annotations:
# 2026-04-04 ogt: Phase 25 P2 — Config Drift Detection
description: "每小時掃描 K8s 配置漂移,由 Nemotron 做意圖分析"
spec:
# 每小時整點執行(台北時間 = UTC+8schedule 用 UTC
schedule: "0 * * * *"
concurrencyPolicy: Forbid # 禁止並發:上次未完成則跳過
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
startingDeadlineSeconds: 60 # 錯過時間窗口超過 60s 則跳過
jobTemplate:
spec:
backoffLimit: 0 # 失敗不重試(漂移掃描冪等,下次 cron 自動補掃)
activeDeadlineSeconds: 300 # 最長 5 分鐘
template:
metadata:
labels:
app: awoooi
component: drift-scanner
spec:
restartPolicy: Never
serviceAccountName: awoooi-api # 使用 API 的 ServiceAccount有 kubectl 權限)
containers:
- name: drift-scanner
# 使用 awoooi-api 鏡像(含 kubectl + Python 環境)
image: harbor.wooo.work/awoooi/api:latest
imagePullPolicy: Always
command:
- python
- -c
- |
import asyncio, httpx, os
API_URL = os.environ.get("INTERNAL_API_URL", "http://awoooi-api:8000")
async def run():
async with httpx.AsyncClient(timeout=240) as c:
r = await c.post(f"{API_URL}/api/v1/drift/internal/scan")
print(f"status={r.status_code} body={r.text[:200]}")
asyncio.run(run())
env:
- name: INTERNAL_API_URL
value: "http://awoooi-api.awoooi-prod.svc.cluster.local:8000"
- name: DRIFT_SCAN_NAMESPACES
value: "awoooi-prod"
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "256Mi"