Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions scripts/f4_linter_linux_provisioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,142 @@ def linux_distro_mapping_evidence_matrix(
return tuple(records)


def linux_official_distro_evidence_matrix() -> tuple[dict[str, Any], ...]:
"""Return deterministic audit rows for configured official distro evidence."""
return tuple(
_official_distro_evidence_row(artifact_entry_id, tool_id, override)
for (
artifact_entry_id,
tool_id,
), override in OFFICIAL_DISTRO_EVIDENCE_BY_POLICY.items()
)


def _official_distro_evidence_row(
artifact_entry_id: str,
tool_id: str,
override: Mapping[str, Any],
) -> dict[str, Any]:
source_artifact_id = _package_policy_artifact_id(artifact_entry_id)
return {
"artifact_entry_id": artifact_entry_id,
"tool_id": tool_id,
"expected_evidence_record_id": (
f"official-distro-metadata:{source_artifact_id}:{tool_id}"
),
"evidence_source": override.get("evidence_source"),
"evidence_source_type": override.get("evidence_source_type"),
"evidence_status": override.get("evidence_status"),
"official_source_name": override.get("official_source_name"),
"official_source_url": override.get("official_source_url"),
"official_source_kind": override.get("official_source_kind"),
"verification_scope": override.get("verification_scope"),
"release_blocking": override.get("release_blocking"),
"external_verification_required_for_new_mappings": override.get(
"external_verification_required_for_new_mappings"
),
}


def linux_official_distro_evidence_summary() -> dict[str, Any]:
"""Return deterministic counts for configured official distro evidence."""
rows = linux_official_distro_evidence_matrix()
return {
"official_override_count": len(rows),
"artifact_counts": _record_counts(row["artifact_entry_id"] for row in rows),
"evidence_status_counts": _record_counts(
row["evidence_status"] for row in rows
),
"evidence_source_type_counts": _record_counts(
row["evidence_source_type"] for row in rows
),
"official_source_kind_counts": _record_counts(
row["official_source_kind"] for row in rows
),
"verification_scope_counts": _record_counts(
row["verification_scope"] for row in rows
),
"release_blocking_count": sum(
1 for row in rows if row["release_blocking"] is True
),
"non_debian_override_count": sum(
1 for row in rows if row["artifact_entry_id"] != "deb"
),
}


def linux_official_distro_evidence_drift_errors() -> list[str]:
"""Return drift errors between official overrides and generated evidence."""
errors: list[str] = []
for row in linux_official_distro_evidence_matrix():
generated, missing_error = _generated_official_distro_evidence_record(row)
if missing_error is not None:
errors.append(missing_error)
continue
if generated is None:
continue
errors.extend(_official_distro_evidence_record_drift_errors(row, generated))
return errors


def _generated_official_distro_evidence_record(
row: Mapping[str, Any],
) -> tuple[LinuxDistroMappingEvidenceRecord | None, str | None]:
artifact_entry_id = str(row["artifact_entry_id"])
tool_id = str(row["tool_id"])
prefix = f"{artifact_entry_id}/{tool_id}"
try:
policies = linux_provisioning_policy_for_artifact(artifact_entry_id)
except (KeyError, ValueError):
return (
None,
f"{prefix}: official override for unknown artifact/tool policy",
)
matching_policy = next(
(policy for policy in policies if policy.tool_id == tool_id),
None,
)
if matching_policy is None or matching_policy.mechanism != "os-package-manager":
return (
None,
f"{prefix}: official override for unknown artifact/tool policy",
)

generated = linux_distro_mapping_evidence_for_policy(matching_policy)
if generated is None:
return (
None,
f"{prefix}: official override not reflected in generated distro evidence",
)
return generated, None


def _official_distro_evidence_record_drift_errors(
row: Mapping[str, Any],
generated_record: Any,
) -> list[str]:
data = _distro_evidence_record_mapping(generated_record)
prefix = f"{row['artifact_entry_id']}/{row['tool_id']}"
if data is None:
return [f"{prefix}: generated distro evidence is not an object"]

errors: list[str] = []
if data.get("evidence_record_id") != row.get("expected_evidence_record_id"):
errors.append(f"{prefix}: evidence_record_id mismatch")
for field in (
"evidence_source_type",
"evidence_status",
"official_source_kind",
"verification_scope",
"official_source_url",
"release_blocking",
"external_verification_required_for_new_mappings",
):
if data.get(field) != row.get(field):
errors.append(f"{prefix}: {field} mismatch")
return errors


def linux_distro_mapping_evidence_summary_for_artifact(
artifact_entry_id: str,
root: Path | None = None,
Expand Down
66 changes: 66 additions & 0 deletions tests/packaging/test_f4_linter_linux_provisioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,72 @@ def test_debian_official_evidence_registry_is_exactly_expected(
assert {artifact_id for artifact_id, _tool_id in registry_keys} == {"deb"}


def test_official_distro_evidence_matrix_reports_debian_overrides(
linux_helper: ModuleType,
) -> None:
rows = linux_helper.linux_official_distro_evidence_matrix()

assert len(rows) == 6
assert [(row["artifact_entry_id"], row["tool_id"]) for row in rows] == list(
DEBIAN_OFFICIAL_EVIDENCE_KEYS
)
for row in rows:
assert row["evidence_source_type"] == "official-distro-metadata"
assert row["evidence_status"] == "verified-official-source"
assert row["official_source_kind"] == "distro-package-index"
assert row["verification_scope"] == "package-name-and-executable"
assert row["expected_evidence_record_id"] == (
f"official-distro-metadata:deb:{row['tool_id']}"
)
assert row["release_blocking"] is False
assert row["external_verification_required_for_new_mappings"] is False


def test_official_distro_evidence_summary_reports_current_counts(
linux_helper: ModuleType,
) -> None:
summary = linux_helper.linux_official_distro_evidence_summary()

assert summary["official_override_count"] == 6
assert summary["artifact_counts"] == {"deb": 6}
assert summary["evidence_status_counts"] == {"verified-official-source": 6}
assert summary["evidence_source_type_counts"] == {
"official-distro-metadata": 6,
}
assert summary["official_source_kind_counts"] == {"distro-package-index": 6}
assert summary["verification_scope_counts"] == {
"package-name-and-executable": 6,
}
assert summary["release_blocking_count"] == 0
assert summary["non_debian_override_count"] == 0


def test_official_distro_evidence_drift_errors_are_empty(
linux_helper: ModuleType,
) -> None:
assert linux_helper.linux_official_distro_evidence_drift_errors() == []


def test_official_distro_evidence_drift_comparison_rejects_mismatched_url(
linux_helper: ModuleType,
) -> None:
row = linux_helper.linux_official_distro_evidence_matrix()[0]
generated = _evidence_record(
linux_helper.linux_distro_mapping_evidence_catalog_for_artifact("deb"),
"yamllint",
)._asdict()
generated["official_source_url"] = (
"https://packages.debian.org/source/stable/yamllint"
)

errors = linux_helper._official_distro_evidence_record_drift_errors(
row,
generated,
)

assert errors == ["deb/yamllint: official_source_url mismatch"]


def test_every_full_required_tool_has_linux_policy_for_every_linux_artifact(
linux_helper: ModuleType,
) -> None:
Expand Down
Loading