From 357113e7be3503371d378f24c508db8122af4eae Mon Sep 17 00:00:00 2001 From: Debian Date: Fri, 29 May 2026 18:33:50 +0200 Subject: [PATCH] fix(cluster): Alle Placeholder-Rows bei autoRegister bereinigen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AgentRegisterPeer löschte bisher nur den neuen prenode-{fqdn}-Placeholder. Alte pre-{timestamp}-Rows (aus Versionen vor 1.1.158) blieben stehen und zeigten dauerhaft status=joining. Fix: DeletePlaceholdersByFQDN löscht ALLE ha_nodes-Rows mit gleicher FQDN außer der echten Node-ID — unabhängig vom ID-Format. Auch preRegisterByFQDN nutzt jetzt das stabile prenode-{fqdn}-Format. Co-Authored-By: Claude Sonnet 4.6 --- VERSION | 2 +- cmd/edgeguard-api/main.go | 2 +- cmd/edgeguard-ctl/main.go | 2 +- cmd/edgeguard-scheduler/main.go | 2 +- internal/cluster/store.go | 10 ++++++++++ internal/handlers/cluster.go | 11 ++++------- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/VERSION b/VERSION index 87b00c6..fade64b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.158 +1.1.159 diff --git a/cmd/edgeguard-api/main.go b/cmd/edgeguard-api/main.go index 9ebaee0..044a924 100644 --- a/cmd/edgeguard-api/main.go +++ b/cmd/edgeguard-api/main.go @@ -60,7 +60,7 @@ import ( usersvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/users" ) -var version = "1.1.158" +var version = "1.1.159" func main() { addr := os.Getenv("EDGEGUARD_API_ADDR") diff --git a/cmd/edgeguard-ctl/main.go b/cmd/edgeguard-ctl/main.go index 43e544e..97ba854 100644 --- a/cmd/edgeguard-ctl/main.go +++ b/cmd/edgeguard-ctl/main.go @@ -11,7 +11,7 @@ import ( "git.netcell-it.de/projekte/edgeguard-native/internal/services/setup" ) -var version = "1.1.158" +var version = "1.1.159" const usage = `edgeguard-ctl — EdgeGuard CLI diff --git a/cmd/edgeguard-scheduler/main.go b/cmd/edgeguard-scheduler/main.go index 93dd437..a2fedaa 100644 --- a/cmd/edgeguard-scheduler/main.go +++ b/cmd/edgeguard-scheduler/main.go @@ -41,7 +41,7 @@ import ( "git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts" ) -var version = "1.1.158" +var version = "1.1.159" const ( // renewTickInterval — how often we re-evaluate expiring certs. diff --git a/internal/cluster/store.go b/internal/cluster/store.go index f809aff..f288691 100644 --- a/internal/cluster/store.go +++ b/internal/cluster/store.go @@ -115,6 +115,16 @@ func (s *Store) Delete(ctx context.Context, id string) error { return nil } +// DeletePlaceholdersByFQDN removes all ha_nodes rows that share the given +// FQDN but do NOT have the specified keepID. Used to clean up pre-registered +// placeholder rows (both old "pre-{timestamp}" and new "prenode-{fqdn}" +// style) after a real autoRegister arrives via mTLS. +func (s *Store) DeletePlaceholdersByFQDN(ctx context.Context, fqdn, keepID string) error { + _, err := s.Pool.Exec(ctx, + `DELETE FROM ha_nodes WHERE fqdn = $1 AND id != $2`, fqdn, keepID) + return err +} + // EnsureSelfRegistered mints the node-id if needed, builds the row // from setup.json + os.Hostname + node.conf, and upserts it. Called // on edgeguard-api boot AFTER the DB pool is reachable. diff --git a/internal/handlers/cluster.go b/internal/handlers/cluster.go index 4e2eef1..2b51c99 100644 --- a/internal/handlers/cluster.go +++ b/internal/handlers/cluster.go @@ -337,7 +337,7 @@ func (h *ClusterHandler) GenerateJoinToken(c *gin.Context) { func (h *ClusterHandler) preRegisterByFQDN(fqdn string) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - nodeID := fmt.Sprintf("pre-%x", time.Now().UnixNano()) + nodeID := fmt.Sprintf("prenode-%s", strings.ReplaceAll(fqdn, ".", "-")) n := models.HANode{ ID: nodeID, Name: fqdn, @@ -602,12 +602,9 @@ func (h *ClusterHandler) AgentRegisterPeer(c *gin.Context) { return } - // Clean up the prenode-{fqdn} placeholder that preRegisterJoiner - // created during cert issuance — the real row just took its place. - placeholderID := fmt.Sprintf("prenode-%s", strings.ReplaceAll(req.FQDN, ".", "-")) - if placeholderID != req.ID { - _ = h.Store.Delete(c.Request.Context(), placeholderID) - } + // Remove ALL placeholder rows for this FQDN (both legacy "pre-{timestamp}" + // and current "prenode-{fqdn}" style) — the real row just took their place. + _ = h.Store.DeletePlaceholdersByFQDN(c.Request.Context(), req.FQDN, req.ID) // Firewall-Reload damit peer_ipv4-Set die neue IP aufnimmt. Best- // effort: Fehler loggen, Response weiter durchreichen — der Peer