diff --git a/consul/state/state_store.go b/consul/state/state_store.go index 5fa6e7b2b2..5a25dcb409 100644 --- a/consul/state/state_store.go +++ b/consul/state/state_store.go @@ -173,6 +173,18 @@ func (s *StateStore) deleteNodeTxn(idx uint64, nodeID string, tx *memdb.Txn) err return fmt.Errorf("node lookup failed: %s", err) } + // Delete all services associated with the node + services, err := tx.Get("services", "node", nodeID) + if err != nil { + return fmt.Errorf("failed service lookup: %s", err) + } + for service := services.Next(); service != nil; service = services.Next() { + svc := service.(*structs.ServiceNode) + if err := s.deleteNodeServiceTxn(idx, nodeID, svc.ServiceID, tx); err != nil { + return fmt.Errorf("failed removing node service: %s", err) + } + } + // Delete the node and update the index if err := tx.Delete("nodes", node); err != nil { return fmt.Errorf("failed deleting node: %s", err) diff --git a/consul/state/state_store_test.go b/consul/state/state_store_test.go index 423cd26ba5..8fc09f88d1 100644 --- a/consul/state/state_store_test.go +++ b/consul/state/state_store_test.go @@ -138,17 +138,49 @@ func TestStateStore_DeleteNode(t *testing.T) { t.Fatalf("bad: %#v (%#v)", n, err) } + // Register a service with the node + svc := &structs.NodeService{ + ID: "service1", + Service: "redis", + Address: "1.1.1.1", + Port: 1111, + } + if err := s.EnsureService(2, "node1", svc); err != nil { + t.Fatalf("err: %s", err) + } + + // Service exists + if services, err := s.NodeServices("node1"); err != nil || len(services.Services) != 1 { + t.Fatalf("bad: %#v (err: %s)", services.Services, err) + } + // Delete the node - if err := s.DeleteNode(2, "node1"); err != nil { + if err := s.DeleteNode(3, "node1"); err != nil { t.Fatalf("err: %s", err) } - // The node is now gone and the index was updated + // The node and service are gone and the index was updated if n, err := s.GetNode("node1"); err != nil || n != nil { t.Fatalf("bad: %#v (err: %#v)", node, err) } - if idx := s.maxIndex("nodes"); idx != 2 { - t.Fatalf("bad index: %d", idx) + + // Associated service was removed. Need to query this directly out of + // the DB to make sure it is actually gone. + tx := s.db.Txn(false) + defer tx.Abort() + services, err := tx.Get("services", "id", "node1", "service1") + if err != nil { + t.Fatalf("err: %s", err) + } + if s := services.Next(); s != nil { + t.Fatalf("bad: %#v", s) + } + + // Indexes were updated. + for _, tbl := range []string{"nodes", "services"} { + if idx := s.maxIndex(tbl); idx != 3 { + t.Fatalf("bad index: %d (%s)", idx, tbl) + } } }