Merge remote-tracking branch 'origin/main' into codex/ai-automation-codebase-review-20260710
This commit is contained in:
@@ -527,6 +527,7 @@ async def enqueue_iwooos_wazuh_manager_posture_candidate_once(
|
||||
proposal_data={
|
||||
"source": "iwooos_wazuh_manager_posture_scheduler",
|
||||
"risk_level": "low",
|
||||
"execution_priority": 0,
|
||||
"action": "run_bounded_no_write_wazuh_manager_posture_readback",
|
||||
},
|
||||
decision_path=_BACKFILL_DECISION_PATH,
|
||||
|
||||
@@ -586,6 +586,10 @@ def build_ansible_decision_audit_payload(
|
||||
and str((signal.get("labels") or {}).get("namespace") or "").strip()
|
||||
})
|
||||
proposal_risk_level = str(proposal_data.get("risk_level") or "").strip().lower()
|
||||
execution_priority = proposal_data.get("execution_priority", 100)
|
||||
if not isinstance(execution_priority, int) or isinstance(execution_priority, bool):
|
||||
execution_priority = 100
|
||||
execution_priority = max(0, min(execution_priority, 100))
|
||||
idempotency_key = f"ansible-candidate:{project_id}:{incident_id}"
|
||||
input_payload = {
|
||||
"incident_id": incident_id,
|
||||
@@ -602,6 +606,7 @@ def build_ansible_decision_audit_payload(
|
||||
"executor": "ansible",
|
||||
"execution_backend": "ansible",
|
||||
"single_writer_executor": "awoooi-ansible-executor-broker",
|
||||
"execution_priority": execution_priority,
|
||||
"decision_path": decision_path,
|
||||
"idempotency_key": idempotency_key,
|
||||
"router_source_sha": os.getenv("AWOOOI_BUILD_COMMIT_SHA", "")
|
||||
|
||||
@@ -3185,7 +3185,19 @@ async def claim_pending_check_modes(
|
||||
'ansible_execution_skipped'
|
||||
)
|
||||
)
|
||||
ORDER BY candidate.created_at ASC
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN candidate.input ->> 'work_item_id' LIKE 'P0-%'
|
||||
THEN 0
|
||||
WHEN candidate.input ->> 'execution_priority'
|
||||
~ '^[0-9]{1,3}$'
|
||||
THEN LEAST(
|
||||
(candidate.input ->> 'execution_priority')::int,
|
||||
100
|
||||
)
|
||||
ELSE 100
|
||||
END ASC,
|
||||
candidate.created_at ASC
|
||||
LIMIT :limit
|
||||
FOR UPDATE SKIP LOCKED
|
||||
"""),
|
||||
|
||||
@@ -46,10 +46,10 @@ ProbeRunner = Callable[..., Awaitable[ReadOnlyProbeResult]]
|
||||
_POSTCONDITION_REGISTRY: dict[str, tuple[AssetPostcondition, ...]] = {
|
||||
"ansible:wazuh-manager-posture-readback": (
|
||||
AssetPostcondition(
|
||||
"host_112_wazuh_manager_control_binary",
|
||||
"host_112_wazuh_manager_unit_loaded",
|
||||
"security",
|
||||
"host_112",
|
||||
"test -f /var/ossec/bin/wazuh-control",
|
||||
"systemctl show --property=LoadState --value wazuh-manager.service | grep -Fxq loaded",
|
||||
),
|
||||
AssetPostcondition(
|
||||
"host_112_wazuh_manager_runtime",
|
||||
|
||||
@@ -1346,6 +1346,7 @@ def test_ansible_decision_audit_payload_is_dry_run_only() -> None:
|
||||
assert payload["input"]["check_mode"] is True
|
||||
assert payload["input"]["apply_enabled"] is False
|
||||
assert payload["input"]["approval_required"] is True
|
||||
assert payload["input"]["execution_priority"] == 100
|
||||
assert payload["input"]["executor_candidates"]
|
||||
assert payload["output"]["decision_effect"] == "audit_only"
|
||||
assert payload["dry_run_result"]["check_mode_executed"] is False
|
||||
@@ -1373,6 +1374,7 @@ def test_ansible_decision_audit_payload_marks_repair_candidate_queue_claimable()
|
||||
proposal_data={
|
||||
"source": "repair_candidate_controlled_queue",
|
||||
"risk_level": "medium",
|
||||
"execution_priority": 0,
|
||||
"action": "systemctl restart node-exporter-188",
|
||||
},
|
||||
decision_path="repair_candidate_controlled_queue",
|
||||
@@ -1389,6 +1391,7 @@ def test_ansible_decision_audit_payload_marks_repair_candidate_queue_claimable()
|
||||
assert payload["input"]["executor_candidates"]
|
||||
assert payload["dry_run_result"]["check_mode_executed"] is False
|
||||
assert payload["input"]["project_id"] == "awoooi"
|
||||
assert payload["input"]["execution_priority"] == 0
|
||||
|
||||
|
||||
def test_ansible_decision_audit_payload_exposes_check_mode_safety_flags(
|
||||
@@ -2701,6 +2704,16 @@ def test_ansible_claim_query_limits_recent_candidate_backlog() -> None:
|
||||
assert "AWOOOP_ANSIBLE_CHECK_MODE_CANDIDATE_MAX_AGE_HOURS" in source
|
||||
|
||||
|
||||
def test_ansible_claim_query_honors_bounded_execution_priority_before_fifo() -> None:
|
||||
source = inspect.getsource(claim_pending_check_modes)
|
||||
|
||||
assert "candidate.input ->> 'work_item_id' LIKE 'P0-%'" in source
|
||||
assert "candidate.input ->> 'execution_priority'" in source
|
||||
assert "LEAST(" in source
|
||||
assert "100" in source
|
||||
assert source.index("execution_priority") < source.index("candidate.created_at ASC")
|
||||
|
||||
|
||||
def test_ansible_transport_blocker_detects_repair_forced_command_denial() -> None:
|
||||
blockers = detect_ansible_transport_blockers(
|
||||
"fatal: host unreachable REPAIR_DENIED:invalid_command",
|
||||
|
||||
@@ -7,6 +7,7 @@ from pathlib import Path
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -158,14 +159,14 @@ def test_wazuh_posture_catalog_and_playbook_are_bounded_no_write() -> None:
|
||||
"ansible:wazuh-manager-posture-readback"
|
||||
)
|
||||
assert {condition.condition_id for condition in postconditions} == {
|
||||
"host_112_wazuh_manager_control_binary",
|
||||
"host_112_wazuh_manager_unit_loaded",
|
||||
"host_112_wazuh_manager_runtime",
|
||||
}
|
||||
assert {condition.inventory_host for condition in postconditions} == {
|
||||
"host_112"
|
||||
}
|
||||
assert {condition.probe for condition in postconditions} == {
|
||||
"test -f /var/ossec/bin/wazuh-control",
|
||||
"systemctl show --property=LoadState --value wazuh-manager.service | grep -Fxq loaded",
|
||||
"systemctl is-active --quiet wazuh-manager.service",
|
||||
}
|
||||
|
||||
@@ -187,6 +188,25 @@ def test_wazuh_posture_catalog_and_playbook_are_bounded_no_write() -> None:
|
||||
):
|
||||
assert forbidden not in source
|
||||
|
||||
inventory = yaml.safe_load(
|
||||
(repo_root / "infra/ansible/inventory/hosts.yml").read_text()
|
||||
)
|
||||
host_112 = inventory["all"]["children"]["security"]["hosts"]["host_112"]
|
||||
assert host_112["ansible_user"] == "kali"
|
||||
assert "ansible_skip_tags" not in host_112
|
||||
|
||||
service_registry = yaml.safe_load(
|
||||
(repo_root / "ops/monitoring/service-registry.yaml").read_text()
|
||||
)
|
||||
wazuh_manager = next(
|
||||
node
|
||||
for node in service_registry["nodes"]
|
||||
if node.get("name") == "wazuh-manager"
|
||||
)
|
||||
assert wazuh_manager["ip"] == "192.168.0.112"
|
||||
assert wazuh_manager["port"] == 55000
|
||||
assert wazuh_manager["criticality"] == "P0"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_wazuh_posture_scheduler_enqueues_after_mcp_and_log_evidence(
|
||||
@@ -247,6 +267,7 @@ async def test_wazuh_posture_scheduler_enqueues_after_mcp_and_log_evidence(
|
||||
assert recorded["incident"]["run_id"] == result["automation_run_id"]
|
||||
assert recorded["incident"]["work_item_id"] == ("P0-03-WAZUH-MANAGER-POSTURE")
|
||||
assert recorded["incident"]["asset_scope_aliases"] == ["security_manager_primary"]
|
||||
assert recorded["proposal_data"]["execution_priority"] == 0
|
||||
assert recorded["incident"]["incident_id"] == "IWZ-POSTURE-2026071100"
|
||||
assert (
|
||||
recorded["incident"]["source_receipt_ref"]
|
||||
|
||||
Reference in New Issue
Block a user