feat: gated deploy with preview, audit log, rollback trail (stage 4)

- pulp_client: create_publication / update_distribution / wait_for_task
- GET /repos/{uuid}/deploy/confirm: 미리보기(현재→대상, 순 변화) + type-to-confirm 모달
- POST /repos/{uuid}/deploy: 검증 게이트(서버측 재확인) → publication 생성 →
  distribution 교체 → 감사 로그. 2단계 실패 시 '운영망 변경 여부' 명확화
- audit.record_deploy: 누가/언제/repo/이전버전→대상버전 JSONL (롤백 추적)
- 배포 버튼은 검증 통과 + 미배포 버전만 활성, 성공 시 버전목록 OOB 갱신
- 인증은 TODO (operator placeholder, 배포 비밀번호 재확인 예정)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 13:31:15 +09:00
parent 72c75252d3
commit 7ad6d65a11
17 changed files with 692 additions and 29 deletions

View File

@@ -135,3 +135,35 @@ def test_verification_detail():
assert d["gpgcheck"] == 1
assert d["repo_gpgcheck"] == 0
assert d["status"]["level"] == "warn"
def test_build_version_view_deployable_only_when_verified_and_not_deployed():
version = {"pulp_href": "/pulp/api/v3/repositories/rpm/rpm/x/versions/3/"}
verified = {"level": "pass", "label": "검증됨"}
unverified = {"level": "unset", "label": "미설정"}
# 검증 통과 + 미배포 → 배포 가능
assert views.build_version_view(version, 2, verified)["deployable"] is True
# 검증 통과 but 현재 배포 중 → 불가
assert views.build_version_view(version, 3, verified)["deployable"] is False
# 미검증 → 불가
assert views.build_version_view(version, 2, unverified)["deployable"] is False
def test_deploy_preview_net_change():
vv = [
{"number": 3, "package_count": 4821},
{"number": 2, "package_count": 4700},
]
p = views.deploy_preview(vv, target_number=3, deployed_number=2)
assert (p["current_version"], p["current_count"]) == (2, 4700)
assert (p["target_version"], p["target_count"]) == (3, 4821)
assert p["net"] == 121
assert p["net_sign"] == "+"
def test_deploy_preview_handles_no_current_deploy():
vv = [{"number": 1, "package_count": 50}]
p = views.deploy_preview(vv, target_number=1, deployed_number=None)
assert p["current_count"] == 0
assert p["net"] == 50
assert p["net_sign"] == "+"