fix(awooop): keep external incident ids out of aol bigint
Some checks failed
CD Pipeline / tests (push) Successful in 1m19s
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled

This commit is contained in:
Your Name
2026-05-31 14:26:19 +08:00
parent 1697d91a68
commit 273071b654
3 changed files with 30 additions and 5 deletions

View File

@@ -19,6 +19,12 @@ from src.db.base import get_db_context
logger = structlog.get_logger(__name__)
def _automation_operation_log_incident_id(value: str) -> int | None:
# ADR-090 keeps external INC-* ids in input JSON; the DB column is BIGINT.
normalized = str(value or "").strip()
return int(normalized) if normalized.isdigit() else None
ANSIBLE_OPERATION_TYPES = frozenset({
"ansible_candidate_matched",
"ansible_check_mode_executed",
@@ -422,7 +428,7 @@ async def record_ansible_decision_audit(
:operation_type,
'decision_manager',
:status,
NULLIF(:incident_id, ''),
:incident_db_id,
CAST(:input AS jsonb),
CAST(:output AS jsonb),
CAST(:dry_run_result AS jsonb),
@@ -433,6 +439,7 @@ async def record_ansible_decision_audit(
"operation_type": payload["operation_type"],
"status": payload["status"],
"incident_id": incident_id,
"incident_db_id": _automation_operation_log_incident_id(incident_id),
"input": json.dumps(payload["input"], ensure_ascii=False),
"output": json.dumps(payload["output"], ensure_ascii=False),
"dry_run_result": json.dumps(payload["dry_run_result"], ensure_ascii=False),

View File

@@ -87,6 +87,12 @@ def _incident_id_from_payload(payload: dict[str, Any]) -> str:
return str(payload.get("incident_id") or "").strip()
def _automation_operation_log_incident_id(value: str) -> int | None:
# ADR-090 keeps external INC-* ids in input JSON; the DB column is BIGINT.
normalized = str(value or "").strip()
return int(normalized) if normalized.isdigit() else None
def _check_mode_ssh_key_path() -> Path:
return Path(settings.AWOOOP_ANSIBLE_CHECK_MODE_SSH_KEY_PATH)
@@ -397,7 +403,7 @@ async def claim_pending_check_modes(
'ansible_check_mode_executed',
'ansible_check_mode_worker',
'pending',
NULLIF(:incident_id, ''),
:incident_db_id,
CAST(:input AS jsonb),
'{}'::jsonb,
CAST(:dry_run_result AS jsonb),
@@ -408,6 +414,9 @@ async def claim_pending_check_modes(
"""),
{
"incident_id": _incident_id_from_payload(claim_input),
"incident_db_id": _automation_operation_log_incident_id(
_incident_id_from_payload(claim_input)
),
"input": json.dumps(claim_input, ensure_ascii=False),
"dry_run_result": json.dumps({
"check_mode_executed": False,
@@ -508,7 +517,7 @@ async def _insert_skipped_candidate(
'ansible_execution_skipped',
'ansible_check_mode_worker',
'dry_run',
NULLIF(:incident_id, ''),
:incident_db_id,
CAST(:input AS jsonb),
CAST(:output AS jsonb),
CAST(:dry_run_result AS jsonb),
@@ -518,6 +527,9 @@ async def _insert_skipped_candidate(
"""),
{
"incident_id": _incident_id_from_payload(input_payload),
"incident_db_id": _automation_operation_log_incident_id(
_incident_id_from_payload(input_payload)
),
"input": json.dumps(input_payload, ensure_ascii=False),
"output": json.dumps({
"not_used_reason": reason,

View File

@@ -12,6 +12,7 @@ from src.services.awooop_ansible_audit_service import (
record_ansible_decision_audit,
)
from src.services.awooop_ansible_check_mode_service import (
_automation_operation_log_incident_id,
build_ansible_check_mode_claim_input,
build_ansible_check_mode_command,
claim_pending_check_modes,
@@ -82,14 +83,19 @@ def test_quality_summary_includes_recent_ansible_operation_incidents() -> None:
assert "source_ids.recent_evidence_at DESC" in source
def test_ansible_audit_writes_incident_id_column_for_truth_chain_join() -> None:
def test_ansible_audit_keeps_external_incident_id_in_json_not_bigint_column() -> None:
decision_source = inspect.getsource(record_ansible_decision_audit)
claim_source = inspect.getsource(claim_pending_check_modes)
assert "operation_type, actor, status, incident_id" in decision_source
assert "coalesce(incident_id::text, input ->> 'incident_id')" in decision_source
assert "operation_type, actor, status, incident_id" in claim_source
assert "NULLIF(:incident_id, '')" in claim_source
assert "incident_db_id" in decision_source
assert "incident_db_id" in claim_source
assert "NULLIF(:incident_id, '')" not in decision_source
assert "NULLIF(:incident_id, '')" not in claim_source
assert _automation_operation_log_incident_id("INC-20260530-0E5C5C") is None
assert _automation_operation_log_incident_id("12345") == 12345
def test_ansible_transport_cooldown_uses_asyncpg_safe_interval_parameter() -> None: