diff --git a/agent/consul/state/catalog.go b/agent/consul/state/catalog.go index 38d59e8109..8196934845 100644 --- a/agent/consul/state/catalog.go +++ b/agent/consul/state/catalog.go @@ -355,9 +355,18 @@ func (s *Store) ensureNodeTxn(tx *memdb.Txn, idx uint64, node *structs.Node) err if existing != nil { n = existing.(*structs.Node) if n.Node != node.Node { - return fmt.Errorf("node ID %q for node %q aliases existing node %q", - node.ID, node.Node, n.Node) + if n.Address != node.Address { + return fmt.Errorf("node ID %q for node %q (%s) aliases existing node %q (%s)", + node.ID, node.Node, node.Address, n.Node, n.Address) + } + fmt.Printf("Node renaming: %s VS %s -- idx=%d\n", node.Node, n.Node, idx) + err := s.deleteNodeTxn(tx, idx, n.Node) + if err != nil { + return fmt.Errorf("Error while renaming Node ID: %q from %s to %s", + node.ID, n.Node, node.Node) + } } + } } diff --git a/agent/consul/state/catalog_test.go b/agent/consul/state/catalog_test.go index 39cd81d60c..03e0f1f485 100644 --- a/agent/consul/state/catalog_test.go +++ b/agent/consul/state/catalog_test.go @@ -476,6 +476,35 @@ func TestStateStore_EnsureNode(t *testing.T) { if err == nil || !strings.Contains(err.Error(), "aliases existing node") { t.Fatalf("err: %v", err) } + + // Renaming a node should work as long as IP did not change + in = &structs.Node{ + Node: "node1-renamed", + ID: types.NodeID("cda916bc-a357-4a19-b886-59419fcee50c"), + Address: "1.1.1.2", + } + if err := s.EnsureNode(6, in); err != nil { + t.Fatalf("err: %s", err) + } + + // Retrieve the node + idx, out, err = s.GetNode("node1") + if out != nil { + t.Fatalf("Node should not exist anymore: %q", out) + } + + idx, out, err = s.GetNode("node1-renamed") + if err != nil { + t.Fatalf("err: %s", err) + } + + // Node and indexes were updated + if out.CreateIndex != 1 || out.ModifyIndex != 6 || out.Address != "1.1.1.2" || out.Node != "node1-renamed" { + t.Fatalf("bad: %#v", out) + } + if idx != 6 { + t.Fatalf("bad index: %d", idx) + } } func TestStateStore_GetNodes(t *testing.T) {