fix(reboot): overlay live stockplatform freshness in slo scorecard
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 59s
CD Pipeline / build-and-deploy (push) Successful in 4m37s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 59s
CD Pipeline / build-and-deploy (push) Successful in 4m37s
CD Pipeline / post-deploy-checks (push) Has been cancelled
This commit is contained in:
@@ -40,6 +40,135 @@ def load_latest_reboot_auto_recovery_slo_scorecard(
|
||||
return payload
|
||||
|
||||
|
||||
def apply_stockplatform_runtime_readback(
|
||||
payload: dict[str, Any],
|
||||
runtime_readback: dict[str, Any],
|
||||
) -> None:
|
||||
"""Overlay live StockPlatform public API data truth onto the scorecard."""
|
||||
readback = _dict(runtime_readback.get("readback"))
|
||||
freshness_status = str(readback.get("freshness_status") or "unknown")
|
||||
ingestion_status = str(readback.get("ingestion_status") or "unknown")
|
||||
freshness_blockers = _strings(readback.get("freshness_blockers"))
|
||||
ingestion_blockers = _strings(readback.get("ingestion_blockers"))
|
||||
latest_trading_date = str(readback.get("freshness_latest_trading_date") or "")
|
||||
freshness_ok = freshness_status == "ok"
|
||||
ingestion_ok = ingestion_status == "ok"
|
||||
stockplatform = _dict(payload.setdefault("stockplatform_data_freshness", {}))
|
||||
stockplatform.update(
|
||||
{
|
||||
"freshness_status": freshness_status,
|
||||
"ingestion_status": ingestion_status,
|
||||
"latest_trading_date": latest_trading_date,
|
||||
"freshness_blockers": freshness_blockers,
|
||||
"ingestion_blockers": ingestion_blockers,
|
||||
"freshness_sla_source_count": _int(
|
||||
readback.get("freshness_sla_source_count")
|
||||
),
|
||||
"freshness_source_count": _int(readback.get("freshness_source_count")),
|
||||
"freshness_non_ok_source_count": _int(
|
||||
readback.get("freshness_non_ok_source_count")
|
||||
),
|
||||
"live_runtime_overlay_applied": True,
|
||||
}
|
||||
)
|
||||
|
||||
required_checks = _dict(payload.setdefault("required_checks", {}))
|
||||
required_checks["stockplatform_freshness_ok"] = freshness_ok
|
||||
required_checks["stockplatform_ingestion_ok"] = ingestion_ok
|
||||
if not (freshness_ok and ingestion_ok):
|
||||
required_checks["product_data_green"] = False
|
||||
payload["product_data_green"] = False
|
||||
post_reboot = _dict(payload.setdefault("post_reboot_readiness", {}))
|
||||
post_reboot["product_data_green"] = False
|
||||
_append_live_stockplatform_blockers(
|
||||
payload=payload,
|
||||
freshness_status=freshness_status,
|
||||
ingestion_status=ingestion_status,
|
||||
freshness_blockers=freshness_blockers,
|
||||
ingestion_blockers=ingestion_blockers,
|
||||
)
|
||||
|
||||
completed_check_count = sum(1 for value in required_checks.values() if value)
|
||||
readiness_percent = _percent(
|
||||
completed_check_count / max(len(required_checks), 1) * 100
|
||||
)
|
||||
active_blockers = _strings(payload.get("active_blockers"))
|
||||
active_blocker_count = len(active_blockers)
|
||||
payload["active_blocker_count"] = active_blocker_count
|
||||
payload["readiness_percent"] = readiness_percent
|
||||
payload["stockplatform_freshness_status"] = freshness_status
|
||||
payload["stockplatform_ingestion_status"] = ingestion_status
|
||||
|
||||
readback_section = _dict(payload.setdefault("readback", {}))
|
||||
readback_section["active_blocker_count"] = active_blocker_count
|
||||
readback_section["readiness_percent"] = readiness_percent
|
||||
|
||||
rollups = _dict(payload.setdefault("rollups", {}))
|
||||
rollups["active_blocker_count"] = active_blocker_count
|
||||
rollups["completed_check_count"] = completed_check_count
|
||||
rollups["readiness_percent"] = readiness_percent
|
||||
rollups["product_data_green"] = payload.get("product_data_green") is True
|
||||
rollups["stockplatform_freshness_status"] = freshness_status
|
||||
rollups["stockplatform_ingestion_status"] = ingestion_status
|
||||
rollups["stockplatform_freshness_blocker_count"] = len(freshness_blockers)
|
||||
rollups["stockplatform_ingestion_blocker_count"] = len(ingestion_blockers)
|
||||
rollups["stockplatform_freshness_sla_source_count"] = _int(
|
||||
readback.get("freshness_sla_source_count")
|
||||
)
|
||||
rollups["stockplatform_freshness_source_count"] = _int(
|
||||
readback.get("freshness_source_count")
|
||||
)
|
||||
rollups["stockplatform_freshness_non_ok_source_count"] = _int(
|
||||
readback.get("freshness_non_ok_source_count")
|
||||
)
|
||||
|
||||
service_backup = _dict(
|
||||
payload.setdefault("controlled_service_data_backup_readback", {})
|
||||
)
|
||||
service_backup["product_data_green"] = payload.get("product_data_green") is True
|
||||
service_backup["stockplatform_freshness_status"] = freshness_status
|
||||
service_backup["stockplatform_ingestion_status"] = ingestion_status
|
||||
blocking_fields = _strings(service_backup.get("blocking_fields"))
|
||||
if not freshness_ok:
|
||||
blocking_fields.append("stockplatform_freshness_status")
|
||||
if not ingestion_ok:
|
||||
blocking_fields.append("stockplatform_ingestion_status")
|
||||
if payload.get("product_data_green") is not True:
|
||||
blocking_fields.append("product_data_green")
|
||||
service_backup["blocking_fields"] = _unique_strings(blocking_fields)
|
||||
service_backup["controlled_service_data_backup_blocker_count"] = len(
|
||||
service_backup["blocking_fields"]
|
||||
)
|
||||
rollups["controlled_service_data_backup_blocker_count"] = len(
|
||||
service_backup["blocking_fields"]
|
||||
)
|
||||
service_backup["status"] = "blocked_service_data_backup_readback_not_green"
|
||||
service_backup["can_clear_service_data_backup_blockers"] = False
|
||||
|
||||
|
||||
def _append_live_stockplatform_blockers(
|
||||
*,
|
||||
payload: dict[str, Any],
|
||||
freshness_status: str,
|
||||
ingestion_status: str,
|
||||
freshness_blockers: list[str],
|
||||
ingestion_blockers: list[str],
|
||||
) -> None:
|
||||
active_blockers = _strings(payload.get("active_blockers"))
|
||||
active_blockers.append("product_data_green_not_1")
|
||||
if freshness_status != "ok" and not freshness_blockers:
|
||||
active_blockers.append("stockplatform_freshness_status_not_ok")
|
||||
if ingestion_status != "ok" and not ingestion_blockers:
|
||||
active_blockers.append("stockplatform_ingestion_status_not_ok")
|
||||
active_blockers.extend(
|
||||
f"stockplatform_freshness_{blocker}" for blocker in freshness_blockers
|
||||
)
|
||||
active_blockers.extend(
|
||||
f"stockplatform_ingestion_{blocker}" for blocker in ingestion_blockers
|
||||
)
|
||||
payload["active_blockers"] = _unique_strings(active_blockers)
|
||||
|
||||
|
||||
def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
|
||||
host_boot_detection = _dict(scorecard.get("host_boot_detection"))
|
||||
post_reboot_readiness = _dict(scorecard.get("post_reboot_readiness"))
|
||||
@@ -764,5 +893,16 @@ def _strings(value: Any) -> list[str]:
|
||||
return [str(item) for item in value if item is not None]
|
||||
|
||||
|
||||
def _unique_strings(values: list[str]) -> list[str]:
|
||||
seen: set[str] = set()
|
||||
unique: list[str] = []
|
||||
for value in values:
|
||||
if value in seen:
|
||||
continue
|
||||
seen.add(value)
|
||||
unique.append(value)
|
||||
return unique
|
||||
|
||||
|
||||
def _taipei_now_iso() -> str:
|
||||
return datetime.now(ZoneInfo("Asia/Taipei")).isoformat(timespec="seconds")
|
||||
|
||||
Reference in New Issue
Block a user