feat: git-based agent version reference and unified outdated badge (0.20.0)
SAC reads latest RDP/ssh-monitor versions from configured git repos for outdated detection, update targets, and settings test-git.
This commit is contained in:
@@ -80,6 +80,30 @@ def db_session(db_engine):
|
||||
session.close()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_agent_git_release(monkeypatch):
|
||||
"""API tests must not clone real git repos."""
|
||||
from app.services.agent_git_release import GitReleaseVersions
|
||||
|
||||
empty = GitReleaseVersions(versions={}, fetched_at=None, from_cache=True)
|
||||
monkeypatch.setattr(
|
||||
"app.services.agent_git_release.get_git_release_versions",
|
||||
lambda cfg, **kwargs: empty,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.api.v1.hosts.get_git_release_versions",
|
||||
lambda cfg, **kwargs: empty,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.api.v1.settings.get_git_release_versions",
|
||||
lambda cfg, **kwargs: empty,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"app.services.agent_update.get_git_release_versions",
|
||||
lambda cfg, **kwargs: empty,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client(db_session, monkeypatch):
|
||||
monkeypatch.setattr("app.main.bootstrap_api_key", lambda: None)
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
"""Tests for git-based agent release version resolution."""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from app.services.agent_git_release import (
|
||||
normalize_git_repo_url,
|
||||
parse_product_version_from_dir,
|
||||
parse_rdp_version_from_files,
|
||||
parse_ssh_version_from_files,
|
||||
recommended_from_git,
|
||||
)
|
||||
from app.services.agent_update_settings import PRODUCT_RDP, PRODUCT_SSH, AgentUpdateConfig
|
||||
from app.services.agent_version import reference_agent_versions_by_product
|
||||
|
||||
|
||||
def test_normalize_git_repo_url():
|
||||
assert normalize_git_repo_url("git.kalinamall.ru/PapaTramp/ssh-monitor").endswith(
|
||||
"ssh-monitor.git"
|
||||
)
|
||||
assert normalize_git_repo_url("https://example.com/repo.git") == "https://example.com/repo.git"
|
||||
|
||||
|
||||
def test_parse_rdp_version_from_files():
|
||||
assert parse_rdp_version_from_files("2.1.2-SAC\n", None) == "2.1.2-SAC"
|
||||
assert (
|
||||
parse_rdp_version_from_files(None, '$ScriptVersion = "2.0.35-SAC"')
|
||||
== "2.0.35-SAC"
|
||||
)
|
||||
|
||||
|
||||
def test_parse_ssh_version_from_files():
|
||||
assert parse_ssh_version_from_files('SSH_MONITOR_VERSION="2.1.0-SAC"\n', None) == "2.1.0-SAC"
|
||||
assert parse_ssh_version_from_files(None, "2.0.6-SAC") == "2.0.6-SAC"
|
||||
|
||||
|
||||
def test_parse_product_version_from_dir(tmp_path: Path):
|
||||
(tmp_path / "version.txt").write_text("2.1.2-SAC\n", encoding="utf-8")
|
||||
assert parse_product_version_from_dir(tmp_path, PRODUCT_RDP) == "2.1.2-SAC"
|
||||
|
||||
ssh_dir = tmp_path / "ssh"
|
||||
ssh_dir.mkdir()
|
||||
(ssh_dir / "ssh-monitor").write_text('SSH_MONITOR_VERSION="2.1.0-SAC"\n', encoding="utf-8")
|
||||
assert parse_product_version_from_dir(ssh_dir, PRODUCT_SSH) == "2.1.0-SAC"
|
||||
|
||||
|
||||
def test_recommended_from_git_prefers_git():
|
||||
cfg = AgentUpdateConfig(
|
||||
mode="sac",
|
||||
fallback_enabled=True,
|
||||
fallback_after_minutes=15,
|
||||
recommended_rdp_version="2.0.0-SAC",
|
||||
recommended_ssh_version="",
|
||||
min_rdp_version="",
|
||||
min_ssh_version="",
|
||||
win_agent_update_script="",
|
||||
rdp_git_repo_url="https://git.example/rdp.git",
|
||||
ssh_git_repo_url="https://git.example/ssh.git",
|
||||
git_branch="main",
|
||||
source="env",
|
||||
)
|
||||
git_versions = {PRODUCT_SSH: "2.1.0-SAC"}
|
||||
assert recommended_from_git(cfg, git_versions, PRODUCT_SSH) == "2.1.0-SAC"
|
||||
assert recommended_from_git(cfg, git_versions, PRODUCT_RDP) == "2.0.0-SAC"
|
||||
|
||||
|
||||
def test_reference_agent_versions_uses_git():
|
||||
cfg = AgentUpdateConfig(
|
||||
mode="gpo",
|
||||
fallback_enabled=True,
|
||||
fallback_after_minutes=15,
|
||||
recommended_rdp_version="",
|
||||
recommended_ssh_version="",
|
||||
min_rdp_version="",
|
||||
min_ssh_version="",
|
||||
win_agent_update_script="",
|
||||
rdp_git_repo_url="",
|
||||
ssh_git_repo_url="",
|
||||
git_branch="main",
|
||||
source="env",
|
||||
)
|
||||
refs = reference_agent_versions_by_product(
|
||||
cfg,
|
||||
{"ssh-monitor": "2.0.6-SAC"},
|
||||
git_versions={"ssh-monitor": "2.1.0-SAC"},
|
||||
)
|
||||
assert refs["ssh-monitor"] == "2.1.0-SAC"
|
||||
@@ -1,6 +1,12 @@
|
||||
"""Agent version parse/compare for outdated highlighting."""
|
||||
|
||||
from app.services.agent_version import is_agent_version_outdated, latest_agent_versions_by_product, parse_agent_version
|
||||
from app.services.agent_version import (
|
||||
effective_reference_version,
|
||||
host_version_outdated,
|
||||
is_agent_version_outdated,
|
||||
latest_agent_versions_by_product,
|
||||
parse_agent_version,
|
||||
)
|
||||
from app.models import Host
|
||||
from datetime import datetime, timezone
|
||||
|
||||
@@ -27,6 +33,61 @@ def test_outdated_different_minor_or_major():
|
||||
assert is_agent_version_outdated("2.1.0-SAC", latest) is False
|
||||
|
||||
|
||||
def test_effective_reference_version_picks_max():
|
||||
assert (
|
||||
effective_reference_version(
|
||||
recommended="2.1.0-SAC",
|
||||
fleet_latest="2.0.6-SAC",
|
||||
min_version="",
|
||||
)
|
||||
== "2.1.0-SAC"
|
||||
)
|
||||
assert (
|
||||
effective_reference_version(
|
||||
recommended="",
|
||||
fleet_latest="2.0.6-SAC",
|
||||
min_version="2.1.0-SAC",
|
||||
)
|
||||
== "2.1.0-SAC"
|
||||
)
|
||||
assert (
|
||||
effective_reference_version(
|
||||
recommended="",
|
||||
fleet_latest="2.0.35-SAC",
|
||||
min_version="",
|
||||
)
|
||||
== "2.0.35-SAC"
|
||||
)
|
||||
|
||||
|
||||
def test_host_version_outdated_ssh_vs_git():
|
||||
assert (
|
||||
host_version_outdated(
|
||||
"2.0.6-SAC",
|
||||
recommended="2.1.0-SAC",
|
||||
fleet_latest="2.0.6-SAC",
|
||||
)
|
||||
is True
|
||||
)
|
||||
assert (
|
||||
host_version_outdated(
|
||||
"2.0.6-SAC",
|
||||
recommended="",
|
||||
fleet_latest="2.0.6-SAC",
|
||||
)
|
||||
is False
|
||||
)
|
||||
assert (
|
||||
host_version_outdated(
|
||||
"2.0.6-SAC",
|
||||
recommended="",
|
||||
fleet_latest="2.0.6-SAC",
|
||||
min_version="2.1.0-SAC",
|
||||
)
|
||||
is True
|
||||
)
|
||||
|
||||
|
||||
def test_latest_agent_versions_by_product(db_session):
|
||||
now = datetime.now(timezone.utc)
|
||||
db_session.add_all(
|
||||
|
||||
@@ -4,6 +4,6 @@ from app.version import APP_NAME, APP_VERSION, APP_VERSION_LABEL
|
||||
|
||||
|
||||
def test_version_constants():
|
||||
assert APP_VERSION == "0.12.1"
|
||||
assert APP_VERSION == "0.20.0"
|
||||
assert APP_NAME == "Security Alert Center"
|
||||
assert APP_VERSION_LABEL == "Security Alert Center v.0.12.1"
|
||||
assert APP_VERSION_LABEL == "Security Alert Center v.0.20.0"
|
||||
|
||||
Reference in New Issue
Block a user