Files
homelable/backend/app/schemas/proxmox.py
T
Pouzor 9437a74147 feat: manual Proxmox re-sync button + make connection config env-only
Add a 'Re-sync now' button to the Proxmox auto-sync settings section that
triggers an immediate inventory import (POST /proxmox/sync-now) using the
server env config — the manual counterpart to scheduled auto-sync.

Also fix a dual-source-of-truth bug: Proxmox connection config (host, port,
token, verify_tls) is now env-only and never persisted to scan_config.json.
Previously save_overrides() dumped host/port/verify alongside scan settings,
so saving an unrelated setting wrote an empty proxmox_host that load_overrides
then clobbered PROXMOX_HOST with on every boot. Only the auto-sync activation
(sync_enabled + sync_interval) stays user-editable and persisted.

ha-relevant: no
2026-07-07 21:20:13 +02:00

88 lines
2.6 KiB
Python

"""Pydantic v2 schemas for Proxmox VE import.
Token fields are accepted on requests only and are optional — when omitted the
backend falls back to the server-configured token (env). No response schema ever
carries a token; secrets are kept out of responses by structural omission.
"""
from pydantic import BaseModel, Field
class ProxmoxConnectionRequest(BaseModel):
host: str = Field(..., description="Proxmox VE host or IP")
port: int = Field(8006, ge=1, le=65535, description="Proxmox API port")
token_id: str | None = Field(
None, description="API token id 'user@realm!tokenname' (falls back to server env)"
)
token_secret: str | None = Field(
None, description="API token secret (falls back to server env)"
)
verify_tls: bool = Field(True, description="Verify the Proxmox TLS certificate")
class ProxmoxTestConnectionResponse(BaseModel):
connected: bool
message: str
class ProxmoxNodeOut(BaseModel):
"""A homelable-ready node representation of a Proxmox host / VM / LXC."""
id: str
label: str
type: str # proxmox | vm | lxc
ieee_address: str
hostname: str | None = None
ip: str | None = None
status: str
cpu_count: int | None = None
ram_gb: float | None = None
disk_gb: float | None = None
vendor: str | None = None
model: str | None = None
parent_ieee: str | None = None
class ProxmoxEdgeOut(BaseModel):
source: str
target: str
class ProxmoxImportResponse(BaseModel):
nodes: list[ProxmoxNodeOut]
edges: list[ProxmoxEdgeOut]
device_count: int
class ProxmoxImportPendingResponse(BaseModel):
"""Result of importing a Proxmox inventory into the pending section."""
pending_created: int
pending_updated: int
links_recorded: int
device_count: int
class ProxmoxConfig(BaseModel):
"""Non-secret Proxmox connection + auto-sync config (GET response).
Connection fields (host/port/verify_tls) are env-only and read-only here —
surfaced for display. ``token_configured`` reflects whether a server-side
token is present. Never carries the token itself."""
host: str = ""
port: int = Field(8006, ge=1, le=65535)
verify_tls: bool = True
sync_enabled: bool = False
sync_interval: int = Field(3600, ge=300)
token_configured: bool = False
class ProxmoxSyncConfig(BaseModel):
"""User-editable auto-sync config (POST body). The ONLY persisted Proxmox
settings. Connection fields (host/port/token/verify_tls) are env-only and
are deliberately not accepted here."""
sync_enabled: bool = False
sync_interval: int = Field(3600, ge=300)