from __future__ import annotations import json import sys from pathlib import Path from typing import Any import pytest REPO_ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(REPO_ROOT / "scripts")) import bootstrap_clone_kb_gate as bootstrap # noqa: E402 def _identity(name: str, identifier: str, *, disposable: bool) -> dict[str, Any]: return { "id": identifier, "name": name, "image": "postgres:16", "labels": ( {bootstrap.bound.DISPOSABLE_LABEL_KEY: bootstrap.bound.DISPOSABLE_LABEL_VALUE} if disposable else {} ), "network_mode": "none" if disposable else "bridge", "ports": {}, "mount_sources": [f"/{name}-data"], "started_at": f"{name}-start", } def test_bootstrap_installs_gate_verifies_logins_and_writes_only_private_secret_files( monkeypatch: pytest.MonkeyPatch, tmp_path: Path, ) -> None: tmp_path.chmod(0o700) target = _identity("clone", "clone-id", disposable=True) production = _identity(bootstrap.bound.PRODUCTION_CONTAINER, "production-id", disposable=False) monkeypatch.setattr( bootstrap.bound, "container_identity", lambda name: dict(production if name == bootstrap.bound.PRODUCTION_CONTAINER else target), ) monkeypatch.setattr( bootstrap.bound, "validate_disposable_target_identity", lambda observed, live: {"all": observed["id"] != live["id"], "network_none": True}, ) passwords = iter(("review-test-secret", "apply-test-secret")) monkeypatch.setattr(bootstrap.secrets, "token_urlsafe", lambda _length: next(passwords)) sql_calls: list[dict[str, Any]] = [] monkeypatch.setattr( bootstrap, "_psql", lambda container, database, sql, **kwargs: sql_calls.append( {"container": container, "database": database, "sql": sql, **kwargs} ), ) login_calls: list[tuple[str, str, str, str]] = [] monkeypatch.setattr( bootstrap, "_verify_login", lambda container, database, role, password: login_calls.append((container, database, role, password)), ) manifest = { "approval_table": "kb_stage.kb_proposal_approvals", "review_principals_table": "kb_stage.kb_review_principals", "review_role_exists": True, "apply_role_exists": True, } monkeypatch.setattr(bootstrap.bound, "_psql_json", lambda *_args, **_kwargs: dict(manifest)) result = bootstrap.bootstrap("clone", "teleo", tmp_path) assert result["status"] == "ready" assert result["bound_container_id"] == "clone-id" assert result["gate_manifest"] == manifest assert result["secret_values_or_hashes_recorded"] is False assert login_calls == [ ("clone-id", "teleo", "kb_review", "review-test-secret"), ("clone-id", "teleo", "kb_apply", "apply-test-secret"), ] assert len(sql_calls) == 3 assert sql_calls[-1]["secret_values"] == ("review-test-secret", "apply-test-secret") review_file = tmp_path / "kb-review.env" apply_file = tmp_path / "kb-apply.env" assert review_file.read_text(encoding="utf-8") == "KB_REVIEW_PASSWORD=review-test-secret\n" assert apply_file.read_text(encoding="utf-8") == "KB_APPLY_DB_PASSWORD=apply-test-secret\n" assert review_file.stat().st_mode & 0o777 == 0o600 assert apply_file.stat().st_mode & 0o777 == 0o600 serialized = json.dumps(result, sort_keys=True) assert "review-test-secret" not in serialized assert "apply-test-secret" not in serialized @pytest.mark.parametrize("mode", [0o755, 0o750]) def test_bootstrap_rejects_nonprivate_output_directory( monkeypatch: pytest.MonkeyPatch, tmp_path: Path, mode: int, ) -> None: tmp_path.chmod(mode) target = _identity("clone", "clone-id", disposable=True) production = _identity(bootstrap.bound.PRODUCTION_CONTAINER, "production-id", disposable=False) monkeypatch.setattr( bootstrap.bound, "container_identity", lambda name: dict(production if name == bootstrap.bound.PRODUCTION_CONTAINER else target), ) monkeypatch.setattr(bootstrap.bound, "validate_disposable_target_identity", lambda *_args: {"all": True}) with pytest.raises(bootstrap.bound.CheckpointError, match="private directory"): bootstrap.bootstrap("clone", "teleo", tmp_path) def test_bootstrap_refuses_existing_or_symlinked_secret_paths( monkeypatch: pytest.MonkeyPatch, tmp_path: Path, ) -> None: tmp_path.chmod(0o700) target = _identity("clone", "clone-id", disposable=True) production = _identity(bootstrap.bound.PRODUCTION_CONTAINER, "production-id", disposable=False) monkeypatch.setattr( bootstrap.bound, "container_identity", lambda name: dict(production if name == bootstrap.bound.PRODUCTION_CONTAINER else target), ) monkeypatch.setattr(bootstrap.bound, "validate_disposable_target_identity", lambda *_args: {"all": True}) (tmp_path / "kb-review.env").symlink_to(tmp_path / "missing-target") with pytest.raises(bootstrap.bound.CheckpointError, match="already exist"): bootstrap.bootstrap("clone", "teleo", tmp_path) def test_write_secret_is_exclusive_and_does_not_follow_symlinks(tmp_path: Path) -> None: target = tmp_path / "target" target.write_text("unchanged\n", encoding="utf-8") link = tmp_path / "secret.env" link.symlink_to(target) with pytest.raises(FileExistsError): bootstrap._write_secret(link, "SECRET", "value") assert target.read_text(encoding="utf-8") == "unchanged\n" def test_main_rejects_production_without_calling_bootstrap( monkeypatch: pytest.MonkeyPatch, tmp_path: Path, capsys: pytest.CaptureFixture[str], ) -> None: called = False def unexpected(*_args: Any, **_kwargs: Any) -> dict[str, Any]: nonlocal called called = True return {} monkeypatch.setattr(bootstrap, "bootstrap", unexpected) result = bootstrap.main( ["--container", bootstrap.bound.PRODUCTION_CONTAINER, "--db", "teleo", "--output-dir", str(tmp_path)] ) assert result == 2 assert called is False output = json.loads(capsys.readouterr().out) assert output["status"] == "rejected" assert "non-production" in output["error"]