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
11 changes: 11 additions & 0 deletions osism/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
_secondary_nb_initialized = False
_cleanup_registered = False

# Hosts whose cached facts are a byproduct of locally executed or delegated
# plays rather than regular inventory hosts. Their facts are never refreshed by
# 'osism sync facts' (which only targets inventory hosts), so excluding them
# from the freshness check avoids permanent, unactionable stale warnings.
LOCAL_FACT_HOSTS = frozenset({"localhost", "127.0.0.1", "::1"})


def _init_redis():
global _redis
Expand Down Expand Up @@ -605,6 +611,11 @@ def check_ansible_facts(max_age=None):
key_str = key.decode() if isinstance(key, bytes) else key
hostname = key_str.replace("ansible_facts", "", 1)

# Skip localhost and friends: their facts are never refreshed via
# 'osism sync facts', so reporting them as stale is misleading.
if hostname in LOCAL_FACT_HOSTS:
continue

data = r.get(key)
if not data:
continue
Expand Down
44 changes: 44 additions & 0 deletions tests/unit/utils/test_init_task_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,3 +695,47 @@ def test_check_ansible_facts_explicit_max_age_overrides_settings(mocker, loguru_

warnings = [r["message"] for r in loguru_logs if r["level"] == "WARNING"]
assert any("older than 10 seconds" in m for m in warnings)


@pytest.mark.parametrize("host", ["localhost", "127.0.0.1", "::1"])
def test_check_ansible_facts_local_hosts_never_stale(mocker, loguru_logs, host):
import time as time_mod

now = time_mod.time()
mock_r = mocker.MagicMock()
mock_r.scan.return_value = (0, [f"ansible_facts{host}".encode("utf-8")])
# Far older than the threshold, but local hosts must be skipped because
# 'osism sync facts' never refreshes them (not part of the inventory).
mock_r.get.return_value = _facts_payload(now - 9999)
mocker.patch("osism.utils._init_redis", return_value=mock_r)

utils_pkg.check_ansible_facts(max_age=10)

warnings = [r["message"] for r in loguru_logs if r["level"] == "WARNING"]
assert not any("stale" in m for m in warnings)


def test_check_ansible_facts_local_host_skipped_real_host_still_stale(
mocker, loguru_logs
):
import time as time_mod

now = time_mod.time()
mock_r = mocker.MagicMock()
mock_r.scan.return_value = (
0,
[b"ansible_factslocalhost", b"ansible_factshost-a"],
)
mock_r.get.side_effect = [
_facts_payload(now - 9999),
_facts_payload(now - 9999),
]
mocker.patch("osism.utils._init_redis", return_value=mock_r)

utils_pkg.check_ansible_facts(max_age=10)

warnings = [r["message"] for r in loguru_logs if r["level"] == "WARNING"]
# Only the real inventory host is reported; localhost is excluded.
assert any("stale for 1 host(s)" in m for m in warnings)
assert any("host-a" in m for m in warnings)
assert not any("localhost" in m for m in warnings)