105 lines
2.9 KiB
Python
105 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
import platform
|
|
import socket
|
|
import subprocess
|
|
import uuid
|
|
from typing import Any
|
|
|
|
|
|
VM_MARKERS = (
|
|
"virtual",
|
|
"vmware",
|
|
"hyper-v",
|
|
"hyperv",
|
|
"kvm",
|
|
"qemu",
|
|
"xen",
|
|
"virtualbox",
|
|
"parallels",
|
|
"bochs",
|
|
)
|
|
|
|
|
|
def host_name() -> str:
|
|
return socket.gethostname()
|
|
|
|
|
|
def machine_fingerprint() -> str:
|
|
material = {
|
|
"host": host_name(),
|
|
"platform": platform.platform(),
|
|
"machine": platform.machine(),
|
|
"mac": f"{uuid.getnode():012x}",
|
|
}
|
|
encoded = json.dumps(material, sort_keys=True).encode("utf-8")
|
|
return hashlib.sha256(encoded).hexdigest()
|
|
|
|
|
|
def public_id() -> str:
|
|
return f"agent-{machine_fingerprint()[:16]}"
|
|
|
|
|
|
def _read_windows_computer_system() -> dict[str, Any]:
|
|
command = [
|
|
"powershell",
|
|
"-NoProfile",
|
|
"-Command",
|
|
"Get-CimInstance Win32_ComputerSystem | "
|
|
"Select-Object Manufacturer,Model,HypervisorPresent | ConvertTo-Json -Compress",
|
|
]
|
|
try:
|
|
completed = subprocess.run(
|
|
command,
|
|
check=True,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=3,
|
|
)
|
|
except (OSError, subprocess.SubprocessError):
|
|
return {}
|
|
try:
|
|
data = json.loads(completed.stdout.strip() or "{}")
|
|
except json.JSONDecodeError:
|
|
return {}
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
|
|
def deployment_info(override: str) -> dict[str, Any]:
|
|
normalized = (override or "auto").strip().lower()
|
|
aliases = {
|
|
"physical": "physical_machine",
|
|
"physical_machine": "physical_machine",
|
|
"box_physical": "physical_machine",
|
|
"virtual": "virtual_machine",
|
|
"vm": "virtual_machine",
|
|
"virtual_machine": "virtual_machine",
|
|
"box_virtual": "virtual_machine",
|
|
}
|
|
if normalized in aliases:
|
|
return {
|
|
"deployment_type": aliases[normalized],
|
|
"detection_reason": f"env:{override}",
|
|
"system": {},
|
|
}
|
|
|
|
system_data = _read_windows_computer_system() if platform.system().lower() == "windows" else {}
|
|
manufacturer = str(system_data.get("Manufacturer") or "")
|
|
model = str(system_data.get("Model") or "")
|
|
hypervisor_present = bool(system_data.get("HypervisorPresent"))
|
|
probe_text = f"{manufacturer} {model} {platform.platform()}".lower()
|
|
is_virtual = hypervisor_present or any(marker in probe_text for marker in VM_MARKERS)
|
|
return {
|
|
"deployment_type": "virtual_machine" if is_virtual else "physical_machine",
|
|
"detection_reason": "auto:virtualization-marker" if is_virtual else "auto:no-virtualization-marker",
|
|
"system": {
|
|
"manufacturer": manufacturer,
|
|
"model": model,
|
|
"hypervisor_present": hypervisor_present,
|
|
"platform": platform.platform(),
|
|
"machine": platform.machine(),
|
|
},
|
|
}
|