chore(home): mirror from kalinamall (9883e6a) with papatramp URLs
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models import Event, Host
|
||||
from app.services.agent_update import process_agent_update_ingest
|
||||
from app.services.daily_report_format import normalize_daily_report_details
|
||||
from app.services.event_severity_overrides import apply_severity_override
|
||||
from app.services.host_inventory import INVENTORY_EVENT_TYPE, process_inventory_ingest
|
||||
from app.services.rdp_session_logoff import close_workstation_session_for_rdp_logoff
|
||||
from app.services.rdg_workstation_session import close_workstation_session_for_rdg_end
|
||||
|
||||
DAILY_REPORT_TYPES = frozenset({"report.daily.ssh", "report.daily.rdp"})
|
||||
|
||||
|
||||
def _parse_dt(value: str) -> datetime:
|
||||
dt = datetime.fromisoformat(value.replace("Z", "+00:00"))
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=timezone.utc)
|
||||
return dt
|
||||
|
||||
|
||||
def upsert_host(db: Session, payload: dict) -> Host:
|
||||
source = payload.get("source") or {}
|
||||
host_data = payload.get("host") or {}
|
||||
agent_id = source.get("agent_instance_id")
|
||||
hostname = host_data.get("hostname") or "unknown"
|
||||
product = source.get("product") or "unknown"
|
||||
|
||||
host: Host | None = None
|
||||
if agent_id:
|
||||
host = db.scalar(select(Host).where(Host.agent_instance_id == agent_id))
|
||||
|
||||
if host is None:
|
||||
host = db.scalar(
|
||||
select(Host).where(Host.hostname == hostname, Host.product == product).limit(1)
|
||||
)
|
||||
|
||||
if host is None:
|
||||
host = Host(
|
||||
agent_instance_id=agent_id,
|
||||
hostname=hostname,
|
||||
display_name=host_data.get("display_name"),
|
||||
os_family=host_data.get("os_family", "linux"),
|
||||
os_version=host_data.get("os_version"),
|
||||
product=product,
|
||||
product_version=source.get("product_version"),
|
||||
ipv4=host_data.get("ipv4"),
|
||||
ipv6=host_data.get("ipv6"),
|
||||
tags=payload.get("tags") or [],
|
||||
)
|
||||
db.add(host)
|
||||
else:
|
||||
host.hostname = hostname
|
||||
dn = host_data.get("display_name")
|
||||
if isinstance(dn, str) and dn.strip():
|
||||
host.display_name = dn.strip()
|
||||
host.os_version = host_data.get("os_version") or host.os_version
|
||||
host.product_version = source.get("product_version") or host.product_version
|
||||
host.ipv4 = host_data.get("ipv4") or host.ipv4
|
||||
host.ipv6 = host_data.get("ipv6") or host.ipv6
|
||||
if agent_id and not host.agent_instance_id:
|
||||
host.agent_instance_id = agent_id
|
||||
|
||||
host.last_seen_at = datetime.now(timezone.utc)
|
||||
db.flush()
|
||||
return host
|
||||
|
||||
|
||||
def ingest_event(db: Session, payload: dict) -> tuple[Event, bool]:
|
||||
"""
|
||||
Returns (event, created).
|
||||
created=False if event_id already exists (idempotent).
|
||||
"""
|
||||
event_id = payload["event_id"]
|
||||
existing = db.scalar(select(Event).where(Event.event_id == event_id))
|
||||
if existing:
|
||||
return existing, False
|
||||
|
||||
host = upsert_host(db, payload)
|
||||
payload = apply_severity_override(payload, db)
|
||||
details = payload.get("details")
|
||||
if payload.get("type") in DAILY_REPORT_TYPES:
|
||||
details = normalize_daily_report_details(details, host, payload["type"])
|
||||
|
||||
severity = payload["severity"]
|
||||
title = payload["title"]
|
||||
summary = payload["summary"]
|
||||
if payload.get("type") == INVENTORY_EVENT_TYPE:
|
||||
inv_severity, hw_changes, inv_patch = process_inventory_ingest(host, details)
|
||||
severity = inv_severity
|
||||
if inv_patch:
|
||||
merged = dict(details) if isinstance(details, dict) else {}
|
||||
merged.update(inv_patch)
|
||||
details = merged
|
||||
if hw_changes:
|
||||
change_fields = ", ".join(c["field"] for c in hw_changes)
|
||||
title = f"Hardware inventory changed on {host.hostname}"
|
||||
summary = (
|
||||
f"Изменилось железо на {host.display_name or host.hostname}: {change_fields}"
|
||||
)
|
||||
|
||||
event = Event(
|
||||
event_id=event_id,
|
||||
host_id=host.id,
|
||||
occurred_at=_parse_dt(payload["occurred_at"]),
|
||||
category=payload["category"],
|
||||
type=payload["type"],
|
||||
severity=severity,
|
||||
title=title,
|
||||
summary=summary,
|
||||
details=details,
|
||||
raw=payload.get("raw"),
|
||||
dedup_key=payload.get("dedup_key"),
|
||||
correlation_id=payload.get("correlation_id"),
|
||||
payload=payload,
|
||||
)
|
||||
db.add(event)
|
||||
try:
|
||||
db.flush()
|
||||
except IntegrityError:
|
||||
db.rollback()
|
||||
raced = db.scalar(select(Event).where(Event.event_id == event_id))
|
||||
if raced is not None:
|
||||
return raced, False
|
||||
raise
|
||||
|
||||
process_agent_update_ingest(db, host, payload.get("type", ""), details)
|
||||
from app.services.rdg_workstation_session import (
|
||||
enrich_empty_login_from_rdg_success,
|
||||
enrich_workstation_login_user_from_rdg,
|
||||
)
|
||||
|
||||
if event.host is None:
|
||||
event.host = host
|
||||
enrich_workstation_login_user_from_rdg(db, event)
|
||||
enrich_empty_login_from_rdg_success(db, event)
|
||||
close_workstation_session_for_rdg_end(db, event)
|
||||
close_workstation_session_for_rdp_logoff(db, event)
|
||||
return event, True
|
||||
Reference in New Issue
Block a user