feat(datasources): govern approvals and retention
Module Package Release / publish-packages (push) Successful in 11s
Module Package Release / publish-packages (push) Successful in 11s
This commit is contained in:
@@ -17,6 +17,7 @@ from govoplan_core.core.dsar import (
|
||||
)
|
||||
from govoplan_datasources.backend.db.models import (
|
||||
DatasourceGovernanceReferenceRecord,
|
||||
DatasourceLifecycleEvidenceRecord,
|
||||
DatasourceMaterializationRecord,
|
||||
DatasourcePayloadRecord,
|
||||
DatasourcePublicationRecord,
|
||||
@@ -35,6 +36,7 @@ _DIRECT_ALIASES = {
|
||||
"payload_id": ("datasources.payload",),
|
||||
"stage_id": ("datasources.stage",),
|
||||
"publication_id": ("datasources.publication",),
|
||||
"lifecycle_evidence_id": ("datasources.lifecycle_evidence",),
|
||||
}
|
||||
_RESOURCE_MODELS = {
|
||||
"datasource": DatasourceRecord,
|
||||
@@ -43,6 +45,7 @@ _RESOURCE_MODELS = {
|
||||
"datasource_payload": DatasourcePayloadRecord,
|
||||
"datasource_stage": DatasourceStageRecord,
|
||||
"datasource_publication": DatasourcePublicationRecord,
|
||||
"datasource_lifecycle_evidence": DatasourceLifecycleEvidenceRecord,
|
||||
}
|
||||
|
||||
|
||||
@@ -284,6 +287,10 @@ def _direct_matches(
|
||||
DatasourcePublicationRecord,
|
||||
"datasource_publication",
|
||||
),
|
||||
"lifecycle_evidence_id": (
|
||||
DatasourceLifecycleEvidenceRecord,
|
||||
"datasource_lifecycle_evidence",
|
||||
),
|
||||
}[selector]
|
||||
row = _one(
|
||||
session,
|
||||
@@ -421,6 +428,11 @@ def _canonical_matches(
|
||||
DatasourcePublicationRecord.created_by.in_(actor_ids),
|
||||
"datasource_publication",
|
||||
),
|
||||
(
|
||||
DatasourceLifecycleEvidenceRecord,
|
||||
DatasourceLifecycleEvidenceRecord.actor_ref.in_(actor_ids),
|
||||
"datasource_lifecycle_evidence",
|
||||
),
|
||||
)
|
||||
matches: list[_Match] = []
|
||||
for model, condition, resource_type in specs:
|
||||
@@ -472,6 +484,8 @@ def _direct_category(session: Session, resource_type: str, row: Any) -> str:
|
||||
)
|
||||
if not referenced:
|
||||
return "unreferenced_datasource_payload"
|
||||
if resource_type == "datasource_lifecycle_evidence":
|
||||
return "datasource_operator_attribution"
|
||||
return {
|
||||
"datasource": "datasource_configuration",
|
||||
"datasource_governance_reference": "datasource_governance_configuration",
|
||||
@@ -479,6 +493,7 @@ def _direct_category(session: Session, resource_type: str, row: Any) -> str:
|
||||
"datasource_payload": "referenced_datasource_payload",
|
||||
"datasource_stage": "promoted_datasource_stage",
|
||||
"datasource_publication": "immutable_datasource_publication",
|
||||
"datasource_lifecycle_evidence": "datasource_operator_attribution",
|
||||
}[resource_type]
|
||||
|
||||
|
||||
@@ -498,6 +513,22 @@ def _root_datasource_ids(session: Session, match: _Match) -> set[str]:
|
||||
)
|
||||
.all()
|
||||
}
|
||||
if match.resource_type == "datasource_lifecycle_evidence":
|
||||
if row.subject_ref.startswith("datasource:"):
|
||||
return {row.subject_ref.removeprefix("datasource:")}
|
||||
if row.subject_ref.startswith("stage:"):
|
||||
stage = session.get(
|
||||
DatasourceStageRecord,
|
||||
row.subject_ref.removeprefix("stage:"),
|
||||
)
|
||||
return {stage.target_datasource_id} if stage and stage.target_datasource_id else set()
|
||||
if row.subject_ref.startswith("materialization:"):
|
||||
materialization = session.get(
|
||||
DatasourceMaterializationRecord,
|
||||
row.subject_ref.removeprefix("materialization:"),
|
||||
)
|
||||
return {materialization.datasource_id} if materialization else set()
|
||||
return set()
|
||||
return {row.datasource_id}
|
||||
|
||||
|
||||
@@ -505,7 +536,7 @@ def _correlates(match: _Match, actor_ids: tuple[str, ...]) -> bool:
|
||||
row = match.row
|
||||
return any(
|
||||
str(getattr(row, field, "") or "") in actor_ids
|
||||
for field in ("created_by", "updated_by")
|
||||
for field in ("created_by", "updated_by", "actor_ref")
|
||||
)
|
||||
|
||||
|
||||
@@ -521,6 +552,7 @@ def _directly_targets(selectors: _Selectors, match: _Match) -> bool:
|
||||
"datasource_payload": ("payload_id", "id"),
|
||||
"datasource_stage": ("stage_id", "id"),
|
||||
"datasource_publication": ("publication_id", "id"),
|
||||
"datasource_lifecycle_evidence": ("lifecycle_evidence_id", "id"),
|
||||
}[match.resource_type]
|
||||
value = _strip_prefix(selectors.direct.get(selector, ""))
|
||||
if value == str(getattr(row, field)):
|
||||
@@ -540,6 +572,12 @@ def _root_datasource_ids_for_row(match: _Match) -> set[str]:
|
||||
return {row.target_datasource_id} if row.target_datasource_id else set()
|
||||
if match.resource_type == "datasource_payload":
|
||||
return set()
|
||||
if match.resource_type == "datasource_lifecycle_evidence":
|
||||
return (
|
||||
{row.subject_ref.removeprefix("datasource:")}
|
||||
if row.subject_ref.startswith("datasource:")
|
||||
else set()
|
||||
)
|
||||
return {row.datasource_id}
|
||||
|
||||
|
||||
@@ -605,6 +643,13 @@ def _record_data(resource_type: str, row: Any) -> dict[str, object]:
|
||||
"created_at": _iso(row.created_at),
|
||||
"updated_at": _iso(row.updated_at),
|
||||
}
|
||||
if resource_type == "datasource_lifecycle_evidence":
|
||||
return {
|
||||
"subject_ref": row.subject_ref,
|
||||
"event_type": row.event_type,
|
||||
"policy_version": row.policy_version,
|
||||
"occurred_at": _iso(row.occurred_at),
|
||||
}
|
||||
if resource_type == "datasource_governance_reference":
|
||||
return {"relation": row.relation}
|
||||
if resource_type == "datasource_materialization":
|
||||
@@ -700,7 +745,13 @@ def _title(resource_type: str) -> str:
|
||||
|
||||
|
||||
def _observed_at(row: Any) -> datetime | None:
|
||||
for field in ("promoted_at", "source_timestamp", "updated_at", "created_at"):
|
||||
for field in (
|
||||
"promoted_at",
|
||||
"source_timestamp",
|
||||
"occurred_at",
|
||||
"updated_at",
|
||||
"created_at",
|
||||
):
|
||||
value = getattr(row, field, None)
|
||||
if isinstance(value, datetime):
|
||||
return _aware(value)
|
||||
|
||||
Reference in New Issue
Block a user