- audit.record_deploy 를 JSONL 파일 → Postgres deploy_audit 테이블로 (재배포 휘발 방지)
- psycopg 지연 import, _write 는 테스트에서 monkeypatch 지점, DATABASE_URL 사용
- 감사 기록 실패는 배포 완료를 막지 않고 UI 경고(audit_ok)
- /healthz: Pulp 무관 라이브니스 {"ok":true} (컨테이너 health check),
Pulp 연결 배지는 /pulp-status 로 분리 (대시보드가 폴링)
- config: DATABASE_URL 추가, audit_log_path 제거
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
"""배포 확정 감사 로그 (스펙 §5-2) — Postgres 영속화.
|
|
|
|
컨테이너 파일시스템은 재배포 시 휘발하므로 감사 기록은 제공된 Postgres(DATABASE_URL)에 남긴다.
|
|
누가 / 언제 / 어떤 repo / 이전 버전 → 대상 버전 (롤백 추적).
|
|
|
|
psycopg 는 지연 import 한다 — DB 미사용 환경/테스트에서 드라이버 없이도 모듈이 로드되도록.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from .config import get_settings
|
|
|
|
_SCHEMA = """
|
|
CREATE TABLE IF NOT EXISTS deploy_audit (
|
|
id bigserial PRIMARY KEY,
|
|
ts timestamptz NOT NULL DEFAULT now(),
|
|
operator text NOT NULL,
|
|
repo_uuid text NOT NULL,
|
|
repo_name text NOT NULL,
|
|
from_version integer,
|
|
to_version integer,
|
|
publication text NOT NULL
|
|
)
|
|
"""
|
|
|
|
_INSERT = """
|
|
INSERT INTO deploy_audit
|
|
(operator, repo_uuid, repo_name, from_version, to_version, publication)
|
|
VALUES
|
|
(%(operator)s, %(repo_uuid)s, %(repo_name)s,
|
|
%(from_version)s, %(to_version)s, %(publication)s)
|
|
"""
|
|
|
|
|
|
def _write(entry: dict[str, Any]) -> None:
|
|
"""감사 항목 1건을 DB 에 기록 (테이블 없으면 생성). 테스트에서 monkeypatch 지점."""
|
|
import psycopg # 지연 import
|
|
|
|
dsn = get_settings().database_url
|
|
if not dsn:
|
|
raise RuntimeError("DATABASE_URL 미설정 — 감사 로그를 기록할 수 없습니다.")
|
|
with psycopg.connect(dsn) as conn, conn.cursor() as cur:
|
|
cur.execute(_SCHEMA)
|
|
cur.execute(_INSERT, entry)
|
|
|
|
|
|
def record_deploy(
|
|
*,
|
|
repo_uuid: str,
|
|
repo_name: str,
|
|
from_version: int | None,
|
|
to_version: int | None,
|
|
publication_href: str,
|
|
operator: str = "operator", # TODO(auth): 로그인 도입 시 실제 사용자. 배포 시 비밀번호 재확인 예정.
|
|
) -> dict[str, Any]:
|
|
entry = {
|
|
"operator": operator,
|
|
"repo_uuid": repo_uuid,
|
|
"repo_name": repo_name,
|
|
"from_version": from_version,
|
|
"to_version": to_version,
|
|
"publication": publication_href,
|
|
}
|
|
_write(entry)
|
|
return entry
|