ForcePilot/backend/package/yuxi/channel/secrets/health.py
Kris 3ce713eb9e feat(secrets): 新增完整的密钥管理工具链
新增了包括密钥加解密、配置健康检查、原子写入、审计、解析器以及 scrubber 在内的完整 secrets 模块,实现了明文密钥检测替换、密钥引用解析和配置安全校验能力
2026-05-21 10:32:14 +08:00

105 lines
3.3 KiB
Python

from __future__ import annotations
import copy
import hashlib
import json
import logging
from collections.abc import Callable
from dataclasses import dataclass, field
from datetime import UTC, datetime
from enum import StrEnum
from typing import Any
logger = logging.getLogger(__name__)
class ConfigHealthStatus(StrEnum):
HEALTHY = "healthy"
SUSPECT = "suspect"
BROKEN = "broken"
@dataclass
class ConfigHealth:
status: ConfigHealthStatus = ConfigHealthStatus.HEALTHY
last_known_good: str | None = None
last_promoted_good: str | None = None
last_checked_at: datetime | None = None
issues: list[str] = field(default_factory=list)
revision: int = 0
last_known_good_config: dict[str, Any] | None = None
@staticmethod
def compute_fingerprint(config: dict[str, Any]) -> str:
raw = json.dumps(config, sort_keys=True, default=str, ensure_ascii=False)
return hashlib.sha256(raw.encode()).hexdigest()[:12]
def promote(self, config: dict[str, Any]) -> None:
fingerprint = self.compute_fingerprint(config)
self.last_known_good = fingerprint
self.last_promoted_good = fingerprint
self.last_known_good_config = copy.deepcopy(config)
self.revision += 1
self.last_checked_at = datetime.now(UTC)
self.status = ConfigHealthStatus.HEALTHY
self.issues.clear()
def mark_suspect(self, reason: str) -> None:
self.status = ConfigHealthStatus.SUSPECT
self.issues.append(reason)
self.last_checked_at = datetime.now(UTC)
def mark_broken(self, reason: str) -> None:
self.status = ConfigHealthStatus.BROKEN
self.issues.append(reason)
self.last_checked_at = datetime.now(UTC)
def can_auto_recover(self) -> bool:
return (
self.last_known_good is not None
and self.last_known_good_config is not None
and self.status
in (
ConfigHealthStatus.SUSPECT,
ConfigHealthStatus.BROKEN,
)
)
def to_dict(self) -> dict[str, Any]:
return {
"status": self.status.value,
"last_known_good": self.last_known_good,
"last_promoted_good": self.last_promoted_good,
"last_checked_at": self.last_checked_at.isoformat() if self.last_checked_at else None,
"issues": self.issues,
"revision": self.revision,
"has_last_known_good_config": self.last_known_good_config is not None,
}
def track_config_health(
health: ConfigHealth,
config: dict[str, Any],
validate_fn: Callable[[dict[str, Any]], list[str]] | None = None,
) -> ConfigHealth:
fingerprint = ConfigHealth.compute_fingerprint(config)
if fingerprint == health.last_known_good:
return health
health.last_checked_at = datetime.now(UTC)
issues = validate_fn(config) if validate_fn else []
if issues:
health.mark_suspect(f"Validation issues: {'; '.join(issues)}")
else:
if health.status in (ConfigHealthStatus.SUSPECT, ConfigHealthStatus.BROKEN):
health.promote(config)
else:
health.status = ConfigHealthStatus.HEALTHY
health.last_known_good = fingerprint
health.last_known_good_config = copy.deepcopy(config)
health.revision += 1
return health