chore(home): mirror from kalinamall (9883e6a) with papatramp URLs
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
"""Host inventory ingest and API."""
|
||||
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from sqlalchemy import select
|
||||
|
||||
from app.models import Event, Host
|
||||
from app.services.host_inventory import diff_hardware, hardware_snapshot, inventory_fingerprint
|
||||
|
||||
|
||||
def test_hardware_diff_detects_memory_change():
|
||||
old = {"memory_gb": 16.0, "processor": [{"name": "CPU A", "cores": 4, "logical_processors": 8}]}
|
||||
new = {"memory_gb": 32.0, "processor": [{"name": "CPU A", "cores": 4, "logical_processors": 8}]}
|
||||
changes = diff_hardware(old, new)
|
||||
assert len(changes) == 1
|
||||
assert changes[0]["field"] == "memory_gb"
|
||||
|
||||
|
||||
def test_hardware_diff_ignores_first_snapshot():
|
||||
new = {"memory_gb": 16.0}
|
||||
assert diff_hardware(None, new) == []
|
||||
|
||||
|
||||
def test_ingest_inventory_stores_host_and_info(client, auth_headers, db_session):
|
||||
event_id = str(uuid.uuid4())
|
||||
payload = {
|
||||
"schema_version": "1.0",
|
||||
"event_id": event_id,
|
||||
"occurred_at": "2026-06-04T10:00:00+03:00",
|
||||
"source": {"product": "rdp-login-monitor", "product_version": "2.0.21-SAC"},
|
||||
"host": {"hostname": "inv-pc", "os_family": "windows"},
|
||||
"category": "agent",
|
||||
"type": "agent.inventory",
|
||||
"severity": "info",
|
||||
"title": "Host inventory",
|
||||
"summary": "Inventory snapshot",
|
||||
"details": {
|
||||
"inventory": {
|
||||
"schema_version": 1,
|
||||
"computer_name": "INV-PC",
|
||||
"memory_gb": 32.0,
|
||||
"processor": [{"name": "Intel Xeon", "cores": 8, "logical_processors": 16}],
|
||||
"windows": {"product_name": "Windows Server 2019", "version": "1809"},
|
||||
}
|
||||
},
|
||||
}
|
||||
r = client.post("/api/v1/events", json=payload, headers=auth_headers)
|
||||
assert r.status_code == 201
|
||||
|
||||
host = db_session.scalar(select(Host).where(Host.hostname == "inv-pc"))
|
||||
assert host is not None
|
||||
assert host.inventory is not None
|
||||
assert host.inventory["memory_gb"] == 32.0
|
||||
assert host.inventory_updated_at is not None
|
||||
assert host.os_version == "Windows Server 2019 (1809)"
|
||||
|
||||
|
||||
def test_ingest_inventory_hardware_change_warning(client, auth_headers, db_session):
|
||||
base = {
|
||||
"schema_version": "1.0",
|
||||
"occurred_at": "2026-06-04T10:00:00+03:00",
|
||||
"source": {"product": "rdp-login-monitor", "product_version": "2.0.21-SAC"},
|
||||
"host": {"hostname": "inv-change", "os_family": "windows"},
|
||||
"category": "agent",
|
||||
"type": "agent.inventory",
|
||||
"severity": "info",
|
||||
"title": "Host inventory",
|
||||
"summary": "Inventory snapshot",
|
||||
}
|
||||
inv_v1 = {
|
||||
"inventory": {
|
||||
"memory_gb": 16.0,
|
||||
"processor": [{"name": "CPU A", "cores": 4, "logical_processors": 8}],
|
||||
"disks": [{"friendly_name": "Disk0", "media_type": "SSD", "size_gb": 500.0}],
|
||||
}
|
||||
}
|
||||
assert (
|
||||
client.post(
|
||||
"/api/v1/events",
|
||||
json={**base, "event_id": str(uuid.uuid4()), "details": inv_v1},
|
||||
headers=auth_headers,
|
||||
).status_code
|
||||
== 201
|
||||
)
|
||||
|
||||
inv_v2 = {
|
||||
"inventory": {
|
||||
"memory_gb": 32.0,
|
||||
"processor": [{"name": "CPU A", "cores": 4, "logical_processors": 8}],
|
||||
"disks": [{"friendly_name": "Disk0", "media_type": "SSD", "size_gb": 500.0}],
|
||||
}
|
||||
}
|
||||
r = client.post(
|
||||
"/api/v1/events",
|
||||
json={**base, "event_id": str(uuid.uuid4()), "details": inv_v2},
|
||||
headers=auth_headers,
|
||||
)
|
||||
assert r.status_code == 201
|
||||
|
||||
ev = db_session.scalar(select(Event).order_by(Event.id.desc()))
|
||||
assert ev is not None
|
||||
assert ev.severity == "warning"
|
||||
assert ev.details.get("hardware_changes")
|
||||
|
||||
|
||||
def test_get_host_detail(client, db_session, jwt_headers):
|
||||
h = Host(
|
||||
hostname="detail-host",
|
||||
display_name="Detail Host",
|
||||
os_family="windows",
|
||||
product="rdp-login-monitor",
|
||||
product_version="2.0.21-SAC",
|
||||
inventory={"memory_gb": 64.0},
|
||||
inventory_updated_at=datetime.now(timezone.utc),
|
||||
last_seen_at=datetime.now(timezone.utc),
|
||||
)
|
||||
db_session.add(h)
|
||||
db_session.commit()
|
||||
|
||||
r = client.get(f"/api/v1/hosts/{h.id}", headers=jwt_headers)
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert body["hostname"] == "detail-host"
|
||||
assert body["inventory"]["memory_gb"] == 64.0
|
||||
assert body["last_inventory_at"] is not None
|
||||
|
||||
|
||||
def test_inventory_fingerprint_stable():
|
||||
inv = {"memory_gb": 16.0, "processor": [{"name": "X", "cores": 2, "logical_processors": 4}]}
|
||||
assert inventory_fingerprint(inv) == inventory_fingerprint(inv)
|
||||
assert hardware_snapshot(inv)["memory_gb"] == 16.0
|
||||
Reference in New Issue
Block a user