cd2f27792d
Add agent update settings, pending self-update via poll, desired config per host, and automatic or manual SSH/WinRM fallback when agents do not report agent.update events.
75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
"""Desired agent config per host (poll delivery)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from sqlalchemy.orm import Session
|
|
from sqlalchemy.orm.attributes import flag_modified
|
|
|
|
from app.models import Host
|
|
from app.services.agent_update_settings import PRODUCT_RDP, PRODUCT_SSH
|
|
|
|
RDP_CONFIG_KEYS = frozenset(
|
|
{
|
|
"ServerDisplayName",
|
|
"EnableRcmShadowControlMonitoring",
|
|
"EnableWinRmInboundMonitoring",
|
|
"EnableAdminShareMonitoring",
|
|
"GetInventory",
|
|
"SacCommandPollIntervalSec",
|
|
}
|
|
)
|
|
SSH_CONFIG_KEYS = frozenset(
|
|
{
|
|
"SERVER_DISPLAY_NAME",
|
|
"HEARTBEAT_INTERVAL",
|
|
"DAILY_REPORT_ENABLED",
|
|
"UseSAC",
|
|
}
|
|
)
|
|
|
|
|
|
def _allowed_keys(host: Host) -> frozenset[str]:
|
|
product = (host.product or "").strip()
|
|
if product == PRODUCT_RDP or (host.os_family or "").strip().lower() == "windows":
|
|
return RDP_CONFIG_KEYS
|
|
if product == PRODUCT_SSH or (host.os_family or "").strip().lower() == "linux":
|
|
return SSH_CONFIG_KEYS
|
|
return frozenset()
|
|
|
|
|
|
def get_host_agent_settings(host: Host) -> dict:
|
|
raw = host.agent_config if isinstance(host.agent_config, dict) else {}
|
|
allowed = _allowed_keys(host)
|
|
if not allowed:
|
|
return {}
|
|
return {k: v for k, v in raw.items() if k in allowed}
|
|
|
|
|
|
def build_agent_config_payload(host: Host) -> dict:
|
|
settings = get_host_agent_settings(host)
|
|
if not settings:
|
|
return {}
|
|
return {"settings": settings}
|
|
|
|
|
|
def update_host_agent_config(db: Session, host: Host, settings: dict) -> Host:
|
|
allowed = _allowed_keys(host)
|
|
if not allowed:
|
|
raise ValueError("Host product does not support desired agent config")
|
|
|
|
current = host.agent_config if isinstance(host.agent_config, dict) else {}
|
|
merged = dict(current)
|
|
for key, value in settings.items():
|
|
if key not in allowed:
|
|
raise ValueError(f"Unsupported config key: {key}")
|
|
if value is None:
|
|
merged.pop(key, None)
|
|
else:
|
|
merged[key] = value
|
|
|
|
host.agent_config = merged
|
|
host.agent_config_revision = int(host.agent_config_revision or 0) + 1
|
|
flag_modified(host, "agent_config")
|
|
db.flush()
|
|
return host
|