Fix config status and missing historical filter imports

1) Added _get_active_jail_names import in jail_config_service 2) Added _get_active_jail_names and _parse_jails_sync imports in filter_config_service and resolved constants/exceptions 3) Added bangui_version=__version__ in config_service.get_service_status and tests
This commit is contained in:
2026-03-22 20:54:44 +01:00
parent 8e1b4fa978
commit ed184f1c84
4 changed files with 82 additions and 12 deletions

View File

@@ -15,7 +15,6 @@ from __future__ import annotations
import asyncio
import contextlib
import re
from collections.abc import Awaitable, Callable
from pathlib import Path
from typing import TYPE_CHECKING, TypeVar, cast
@@ -24,8 +23,12 @@ import structlog
from app.utils.fail2ban_client import Fail2BanCommand, Fail2BanResponse, Fail2BanToken
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable
import aiosqlite
from app import __version__
from app.exceptions import ConfigOperationError, ConfigValidationError, JailNotFoundError
from app.models.config import (
AddLogPathRequest,
BantimeEscalation,
@@ -44,11 +47,13 @@ from app.models.config import (
RegexTestResponse,
ServiceStatusResponse,
)
from app.exceptions import ConfigOperationError, ConfigValidationError, JailNotFoundError
from app.utils.fail2ban_client import Fail2BanClient
from app.utils.log_utils import preview_log as util_preview_log, test_regex as util_test_regex
from app.utils.log_utils import preview_log as util_preview_log
from app.utils.log_utils import test_regex as util_test_regex
from app.utils.setup_utils import (
get_map_color_thresholds as util_get_map_color_thresholds,
)
from app.utils.setup_utils import (
set_map_color_thresholds as util_set_map_color_thresholds,
)
@@ -815,6 +820,7 @@ async def get_service_status(
return ServiceStatusResponse(
online=server_status.online,
version=server_status.version,
bangui_version=__version__,
jail_count=server_status.active_jails,
total_bans=server_status.total_bans,
total_failures=server_status.total_failures,

View File

@@ -17,16 +17,21 @@ from pathlib import Path
import structlog
from app.exceptions import FilterInvalidRegexError
from app.models.config import (
AssignFilterRequest,
FilterConfig,
FilterConfigUpdate,
FilterCreateRequest,
FilterListResponse,
FilterUpdateRequest,
AssignFilterRequest,
)
from app.exceptions import FilterInvalidRegexError, JailNotFoundError
from app.services.config_file_service import _TRUE_VALUES, ConfigWriteError, JailNotFoundInConfigError
from app.utils import conffile_parser
from app.utils.config_file_utils import (
_get_active_jail_names,
_parse_jails_sync,
)
from app.utils.jail_utils import reload_jails
log: structlog.stdlib.BoundLogger = structlog.get_logger()
@@ -90,6 +95,7 @@ class JailNameError(Exception):
"""Raised when a jail name contains invalid characters."""
_SAFE_FILTER_NAME_RE: re.Pattern[str] = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$")
_SAFE_JAIL_NAME_RE: re.Pattern[str] = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$")

View File

@@ -26,22 +26,17 @@ from app.models.config import (
InactiveJail,
InactiveJailListResponse,
JailActivationResponse,
JailValidationIssue,
JailValidationResult,
RollbackResponse,
)
from app.utils.config_file_utils import (
_build_inactive_jail,
_ordered_config_files,
_get_active_jail_names,
_parse_jails_sync,
_validate_jail_config_sync,
)
from app.utils.fail2ban_client import Fail2BanClient
from app.utils.jail_utils import reload_jails
from app.utils.fail2ban_client import (
Fail2BanClient,
Fail2BanConnectionError,
Fail2BanResponse,
)
log: structlog.stdlib.BoundLogger = structlog.get_logger()

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from pathlib import Path
from typing import Any
from unittest.mock import AsyncMock, patch
@@ -748,8 +749,11 @@ class TestGetServiceStatus:
probe_fn=AsyncMock(return_value=online_status),
)
from app import __version__
assert result.online is True
assert result.version == "1.0.0"
assert result.bangui_version == __version__
assert result.jail_count == 2
assert result.total_bans == 5
assert result.total_failures == 3
@@ -771,3 +775,62 @@ class TestGetServiceStatus:
assert result.jail_count == 0
assert result.log_level == "UNKNOWN"
assert result.log_target == "UNKNOWN"
@pytest.mark.asyncio
class TestConfigModuleIntegration:
async def test_jail_config_service_list_inactive_jails_uses_imports(self, tmp_path: Any) -> None:
from app.services.jail_config_service import list_inactive_jails
# Arrange: fake parse_jails output with one active and one inactive
def fake_parse_jails_sync(path: Path) -> tuple[dict[str, dict[str, str]], dict[str, str]]:
return (
{
"sshd": {
"enabled": "true",
"filter": "sshd",
"logpath": "/var/log/auth.log",
},
"apache-auth": {
"enabled": "false",
"filter": "apache-auth",
"logpath": "/var/log/apache2/error.log",
},
},
{
"sshd": str(path / "jail.conf"),
"apache-auth": str(path / "jail.conf"),
},
)
with patch(
"app.services.jail_config_service._parse_jails_sync",
new=fake_parse_jails_sync,
), patch(
"app.services.jail_config_service._get_active_jail_names",
new=AsyncMock(return_value={"sshd"}),
):
result = await list_inactive_jails(str(tmp_path), "/fake.sock")
names = {j.name for j in result.jails}
assert "apache-auth" in names
assert "sshd" not in names
async def test_filter_config_service_list_filters_uses_imports(self, tmp_path: Any) -> None:
from app.services.filter_config_service import list_filters
# Arrange minimal filter and jail config files
filter_d = tmp_path / "filter.d"
filter_d.mkdir(parents=True)
(filter_d / "sshd.conf").write_text("[Definition]\nfailregex = ^%(__prefix_line)s.*$\n")
(tmp_path / "jail.conf").write_text("[sshd]\nfilter = sshd\nenabled = true\n")
with patch(
"app.services.filter_config_service._get_active_jail_names",
new=AsyncMock(return_value={"sshd"}),
):
result = await list_filters(str(tmp_path), "/fake.sock")
assert result.total == 1
assert result.filters[0].name == "sshd"
assert result.filters[0].active is True