hub: S1 wgsync (pinned-SSH push + declarative reconciler) + /admin/wg API + env wiring
internal/wgsync: x/crypto/ssh client with ssh.FixedHostKey pin (no insecure fallback), forced-command exec, ok/applied response contract; Reconciler pushes the FULL peer list on Trigger or 5-min tick (drift repair by construction). internal/api/wg.go: PUT/GET /admin/wg/endpoint + POST/DELETE/GET /admin/wg/peers, global-key-only, pubkey in body (base64 vs URL), sync ok|deferred|disabled. main.go: WG_ENDPOINT_SSH_* env wiring, disabled-with-INFO when unconfigured. Groups B/C/D tests incl. in-process SSH server; red-proofs b/c/d run + reverted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -49,6 +49,10 @@ type Handler struct {
|
||||
mailSender mailrelay.Sender
|
||||
mailLimiter *mailRateLimiter
|
||||
mailFromAllow map[string]bool
|
||||
|
||||
// S1 offsite connectivity: the wgsync reconciler seam (internal/api/wg.go). nil = peer-sync
|
||||
// disabled — mutations still persist, responses carry sync:"disabled".
|
||||
wgSyncer WGSyncer
|
||||
}
|
||||
|
||||
// SetLatestVersionProvider wires the registry version checker so the controller report ACK can
|
||||
@@ -187,6 +191,18 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case r.Method == http.MethodPost && strings.HasPrefix(path, "/admin/hosts/") && strings.HasSuffix(path, "/jobs"):
|
||||
hostID := strings.TrimSuffix(strings.TrimPrefix(path, "/admin/hosts/"), "/jobs")
|
||||
h.handleAdminEnqueueJob(w, r, hostID)
|
||||
// S1 offsite connectivity — WG endpoint record + peer registry (global key only, api/wg.go).
|
||||
// DELETE carries the pubkey in the body: base64 '/'+'+' keep pubkeys out of URL paths.
|
||||
case r.Method == http.MethodPut && path == "/admin/wg/endpoint":
|
||||
h.handleAdminSetWGEndpoint(w, r)
|
||||
case r.Method == http.MethodGet && path == "/admin/wg/endpoint":
|
||||
h.handleAdminGetWGEndpoint(w, r)
|
||||
case r.Method == http.MethodPost && path == "/admin/wg/peers":
|
||||
h.handleAdminAddWGPeer(w, r)
|
||||
case r.Method == http.MethodDelete && path == "/admin/wg/peers":
|
||||
h.handleAdminDeleteWGPeer(w, r)
|
||||
case r.Method == http.MethodGet && path == "/admin/wg/peers":
|
||||
h.handleAdminListWGPeers(w, r)
|
||||
case r.Method == http.MethodPost && path == "/event":
|
||||
h.handleEvent(w, r)
|
||||
case r.Method == http.MethodPost && path == "/mail":
|
||||
|
||||
Reference in New Issue
Block a user