Skip to content

feat(cluster): remote edit of a peer's mapping (v2.6.1)#21

Merged
haliskilic merged 1 commit into
mainfrom
feat-cluster-edit
Jun 11, 2026
Merged

feat(cluster): remote edit of a peer's mapping (v2.6.1)#21
haliskilic merged 1 commit into
mainfrom
feat-cluster-edit

Conversation

@haliskilic

Copy link
Copy Markdown
Owner

Completes the cluster fleet-management story: operators can now edit a remote node's mapping from the unified view, not just start/stop/restart it (the last open item from the v2.6.x list).

How it works

The hard part is that the edit form must carry the browser's own CSRF token and post same-origin, while the data and the save belong to a different node. So:

  1. Peer side (key-guarded): GET /api/cluster/mapping-data returns the mapping's config + that node's serial ports + IP candidates; POST /api/cluster/mapping-save validates + persists + applies on the target. Both are in _CLUSTER_PEER_PATHS (PUBLIC + CSRF-exempt — authed by the shared key).
  2. Controlling node renders the form. GET /api/cluster/peer-form (operator+, allowlist-checked) fetches the peer's data and renders _mapping_form.html in remote mode — the form targets /api/cluster/peer-save and carries the peer routing as hidden scheme/host/port fields. The CSRF token is the browser's, so the same-origin submit passes the normal gate.
  3. Save is proxied. POST /api/cluster/peer-save (operator+, allowlist-checked) strips the routing fields and forwards the rest to the peer's key-guarded mapping-save; on a peer-side validation error it re-renders the form with the message.

Refactors

  • mapping_save now shares _save_mapping_from_form with the peer save (no logic drift).
  • Peer HTTP generalized to get_peer / post_peer (control + edit reuse them).

Security

Same model as remote control: an operator+ session on a cluster node + the shared key is required; the local role gates initiation, the key authorizes the cross-node call, and the known-address allowlist bounds the target (anti-SSRF). Remote edit is start/stop/restart's sibling — the destructive surface is the same one already shipped in v2.6.0.

Tests

tests/test_cluster.py extends the two-node (manual-peer) test: the peer's mapping loads into the form routed to peer-save, the mapping-save key guard returns 403 without the key, and a remote edit changes the peer's mapping (verified via the peer's /api/cluster/local). Full suite 32/32; ruff clean.

Version 2.6.1; README (TR/EN) + ROADMAP updated; screenshots regenerated (remote rows now show Start + Edit).

…(v2.6.1)

Operators can now edit a remote node's mapping from the fleet table, not just
start/stop/restart it.

- Key-guarded peer endpoints: GET /api/cluster/mapping-data (mapping config + the
  peer's serial ports + IP candidates) and POST /api/cluster/mapping-save (validate
  + persist + apply on the target). Both in _CLUSTER_PEER_PATHS (PUBLIC + CSRF-exempt).
- Browser-facing proxies (operator+, allowlist-checked): GET /api/cluster/peer-form
  and POST /api/cluster/peer-save. The edit form is rendered on the CONTROLLING node
  (so the CSRF token belongs to the browser's session), with _mapping_form.html in a
  "remote mode" that targets the proxy and carries the peer routing; the save is then
  forwarded to the peer with the shared key.
- mapping_save refactored to share _save_mapping_from_form; peer HTTP generalized to
  get_peer/post_peer. Edit button on remote rows.
- tests/test_cluster.py: extends the two-node test with a remote edit (form loads
  from the peer + a save changes the peer's mapping) and the mapping-save key guard.
- Version 2.6.1 (single-sourced in app/__init__.py); README/ROADMAP + screenshots.
@haliskilic
haliskilic merged commit c7430c3 into main Jun 11, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant