mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-02-18 00:17:39 +01:00
5.8 KiB
5.8 KiB
Pulse Temperature Proxy – Control Plane Sync
Goals
- Make
pulse-sensor-proxytrust Pulse itself instead of scrapingpvecm/editing/etc/pve. - Ensure host installers always create a pulse-proxy registration, regardless of socket vs HTTP mode.
- Keep backwards compatibility: existing
allowed_nodesentries remain a fallback cache, but the runtime source of truth is Pulse.
Overview
┌─────────────────────┐ HTTPS / Unix socket ┌─────────────────────┐
│ Pulse server (LXC) │ <═════════════════════════════> │ pulse-sensor-proxy │
│ │ /api/... │ (Proxmox host) │
│ - Stores nodes │ │ - Collects temps │
│ - Issues proxy token│ │ - Validates node │
└─────────────────────┘ │ via synced list │
└─────────────────────┘
- Installer registers the proxy using
/api/temperature-proxy/register.- Response now includes
ctrl_token,instance_id, andallowed_nodes. - Pulse persists
{instance_id, ctrl_token, last_seen, allowed_nodes_cache}.
- Response now includes
- Proxy writes:
pulse_control_plane: url: https://pulse.example.com:7655 token_file: /etc/pulse-sensor-proxy/.pulse-control-token refresh_interval: 60s - Proxy boot sequence:
- Load cached
allowed_nodesfrom YAML (fallback only). - If
pulse_control_planeconfigured, fetch/api/temperature-proxy/authorized-nodes. - Replace in-memory allowlist atomically, log version/hash.
- Retry based on exponential backoff; stay on cached list if control plane unreachable.
- Load cached
API Changes (Pulse)
- Extend existing registration endpoint
- Request:
{hostname, proxy_url, kind}(kind=socketorhttp). - Response:
{success, token, ctrl_token, pve_instance, allowed_nodes, refresh_interval}. - Persist
ctrl_token(or reuseTemperatureProxyTokenfield ifproxy_urlempty).
- Request:
- New endpoint
/api/temperature-proxy/authorized-nodes- Auth:
X-Proxy-Token: <ctrl_token>orAuthorization: Bearer. - Response:
{ "nodes": [ {"name": "delly", "ip": "192.168.0.5"}, {"name": "minipc", "ip": "192.168.0.134"} ], "hash": "sha256:...", "refresh_interval": 60, "updated_at": "2025-11-15T20:47:00Z" } - Uses Pulse config (
nodes.enc+ cluster endpoints) to build list. - Derives
ipfrom cluster endpoints or stored host value; duplicates removed. - Logs when proxies pull list (metrics + last_seen).
- Auth:
- Persistence
config.PVEInstancealready hasTemperatureProxyURL/Token. AddTemperatureProxyControlTokenor reuse existing field when URL empty.- Add
LastProxyPull,LastAllowlistHash.
- Access control
- Router should treat
/api/temperature-proxy/authorized-nodesas public but requiring proxy token (bypasses user auth). - Rate limit per proxy (maybe 12/min).
- Router should treat
Proxy Changes
- Config additions
pulse_control_plane: url: https://pulse.lan:7655 token_file: /etc/pulse-sensor-proxy/.pulse-control-token refresh_interval: 60s # default insecure_skip_verify: false - Startup
- Read token from
token_file. - Launch goroutine:
syncAllowlist(ctx)loops:- GET
/api/temperature-proxy/authorized-nodes. - Validate response (non-empty, verify hash changes).
- Replace
nodeValidatorallowlist in thread-safe way. - Write new snapshot to
allowed_nodes_cache(optional). - Sleep
refresh_interval(server-provided).
- GET
- If call fails: log warning, keep last known list, use fallback allowlist when empty.
- Read token from
- NodeValidator
- Keep ability to parse static
allowed_nodes. - Add
SetAuthorizedNodes([]string)to update hosts + CIDRs. - When
hasAllowlist == falsebut control-plane sync enabled, we never fall back to cluster detection. - Provide metrics: last sync success timestamp, number of nodes, etc.
- Keep ability to parse static
Installer Changes
- Host install path (
install.shinvokinginstall-sensor-proxy.sh)- Always pass
--pulse-server http://<container-ip>:<port>. - If
--pulse-servernot supplied manually,install-sensor-proxy.shfetches fromPULSE_SERVERenv.
- Always pass
install-sensor-proxy.sh- After downloading binary, run registration:
ctrl_token=$(register_with_pulse "$PULSE_SERVER" "$SHORT_HOSTNAME" "$PROXY_URL" "$MODE") echo "$ctrl_token" > /etc/pulse-sensor-proxy/.pulse-control-token - Append control-plane block to config if not present.
- After install, call new authorized-nodes endpoint once to prime the cache.
- Continue merging
allowed_nodesfor fallback, but treat as# Legacy fallback.
- After downloading binary, run registration:
- Provide migration flag
--legacy-allowlistto skip control plane (for air-gapped hosts).
Migration Plan
- Ship allowlist merge fix (already done locally) so reruns stop causing YAML errors.
- Release intermediate version where installer accepts
--pulse-serverand registers proxies; proxy ignores new config fields until next release. - Release proxy with control-plane sync; ensure it tolerates missing control block (for older installs).
- Update docs + UI to show last proxy sync state (diagnostics tab).
Open Questions / TODO
- Decide whether ctrl_token reuses
TemperatureProxyToken(rename field) or is separate. - How to handle multiple Pulse servers controlling the same host (future?). For now, one ctrl token per PVE instance.
- Should HTTP-mode proxies reuse the same sync endpoint (yes).