ab36ba6f81
Add a Proxmox VE importer that reads the /api2/json REST API with a read-only
API token and drops hosts (proxmox), VMs (vm) and LXC containers (lxc) onto the
canvas as typed nodes with run state and hardware specs (vCPU/RAM/disk).
- Backend: proxmox_service (httpx) + proxmox routes (test-connection, import,
import-pending, config). Two-tier dedupe — merge onto an existing scanned node
by IP, else synthetic pve-{host}-{vmid} identity. Update-in-place, never
deletes. Host->guest rendered as a 'virtual' edge via the pending-link flow.
- Security: token is env-only (PROXMOX_TOKEN_*), never written to disk by the
app, never returned by any endpoint; errors are credential-sanitized.
- Auto-sync: optional scheduled re-import into pending (APScheduler job).
- PendingDevice.properties carries specs through approve (+ migration).
- Frontend: ProxmoxImportModal, sidebar entry, pending inventory source filter,
Settings auto-sync section, proxmoxApi client.
- Docs: docs/proxmox-import.md, README + FEATURES sections, .env.example keys.
- Tests: backend service/router/scheduler, frontend modal/client/pending.
ha-relevant: maybe
61 lines
2.9 KiB
Bash
61 lines
2.9 KiB
Bash
# Backend - server-side only (NEVER commit .env)
|
||
SECRET_KEY=change_me_in_production
|
||
SQLITE_PATH=./data/homelab.db
|
||
# Uploaded media (floor plans) folder. Optional — defaults to <SQLITE_PATH dir>/uploads,
|
||
# which sits on the same persistent volume as the DB.
|
||
# UPLOAD_DIR=./data/uploads
|
||
# Set this to the URL(s) you use to access Homelable in your browser.
|
||
CORS_ORIGINS=["http://localhost:5173","http://localhost:3000"]
|
||
|
||
# Auth — default credentials: admin / admin
|
||
# ⚠️ Change before exposing on a network.
|
||
# Generate a new hash: python3 -c "from passlib.context import CryptContext; print(CryptContext(schemes=['bcrypt']).hash('yourpassword'))"
|
||
# ⚠️ Keep the single quotes around the hash — bcrypt hashes contain \$ which Docker misinterprets without them.
|
||
AUTH_USERNAME=admin
|
||
AUTH_PASSWORD_HASH='$2b$12$RtMbyw17l4N5UGzeXMNAWuzCaVV.XFBY7ZetWheQhxcBDcxahapkG'
|
||
|
||
# Scanner — JSON array of CIDR ranges to scan
|
||
SCANNER_RANGES=["192.168.1.0/24"]
|
||
|
||
# Deep scan (optional) — extra nmap port ranges + HTTP probe for service ID on
|
||
# custom ports. Defaults below are overridable per-scan from the scan dialog.
|
||
# SCANNER_HTTP_RANGES: JSON array of port specs, each a single port "N" or an
|
||
# inclusive range "N-M" (1–65535, N <= M). Not CIDRs, not bare ints.
|
||
# Example: SCANNER_HTTP_RANGES=["8080","9000-9100"]
|
||
SCANNER_HTTP_RANGES=[]
|
||
SCANNER_HTTP_PROBE_ENABLED=false
|
||
SCANNER_HTTP_VERIFY_TLS=false
|
||
|
||
# Status checker interval in seconds
|
||
STATUS_CHECKER_INTERVAL=60
|
||
|
||
# MCP server — used by the mcp service (port 8001)
|
||
# MCP_API_KEY: authenticates AI clients (Claude Code, etc.) → MCP server
|
||
# MCP_SERVICE_KEY: authenticates MCP server → backend (never exposed externally)
|
||
# Generate keys: python3 -c "import secrets; print(secrets.token_hex(32))"
|
||
MCP_API_KEY=mcp_sk_changeme
|
||
MCP_SERVICE_KEY=svc_changeme
|
||
|
||
# Live view — read-only public canvas at /view?key=<value>
|
||
# Off by default. Set to a random secret to enable.
|
||
# Generate: python3 -c "import secrets; print(secrets.token_urlsafe(32))"
|
||
# LIVEVIEW_KEY=
|
||
|
||
# Gethomepage widget — read-only stats at /api/v1/stats/summary
|
||
# Off by default. Set to a random secret to enable; clients must send
|
||
# the same value in the `X-API-Key` header.
|
||
# Generate: python3 -c "import secrets; print(secrets.token_urlsafe(32))"
|
||
# HOMEPAGE_API_KEY=
|
||
|
||
# Proxmox VE import — pull hosts/VMs/LXC from the Proxmox REST API.
|
||
# The token is a credential: kept in memory only, never written to disk by the
|
||
# app, never returned by any API. Create it under Datacenter → Permissions →
|
||
# API Tokens and grant the read-only PVEAuditor role at path "/".
|
||
# Token id format: user@realm!tokenname (e.g. root@pam!homelable).
|
||
# Required only for auto-sync; one-off imports can pass the token in the dialog.
|
||
# PROXMOX_TOKEN_ID=root@pam!homelable
|
||
# PROXMOX_TOKEN_SECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||
# PROXMOX_HOST=192.168.1.10
|
||
# PROXMOX_PORT=8006
|
||
# PROXMOX_VERIFY_TLS=true # set false only for self-signed certs
|