diff --git a/consul/state/state_store.go b/consul/state/state_store.go index 4ef13fc905..b31d521cc4 100644 --- a/consul/state/state_store.go +++ b/consul/state/state_store.go @@ -99,6 +99,26 @@ func (s *StateStore) GetNode(id string) (*structs.Node, error) { return nil, nil } +// Nodes is used to return all of the known nodes. +func (s *StateStore) Nodes() (structs.Nodes, error) { + tx := s.db.Txn(false) + defer tx.Abort() + + // Retrieve all of the nodes + nodes, err := tx.Get("nodes", "id") + if err != nil { + return nil, fmt.Errorf("failed nodes lookup: %s", err) + } + + // Create and return the nodes list. + // TODO: Optimize by returning an iterator. + var results structs.Nodes + for node := nodes.Next(); node != nil; node = nodes.Next() { + results = append(results, node.(*structs.Node)) + } + return results, nil +} + // EnsureService is called to upsert creation of a given NodeService. func (s *StateStore) EnsureService(idx uint64, node string, svc *structs.NodeService) error { tx := s.db.Txn(true) @@ -174,7 +194,7 @@ func (s *StateStore) NodeServices(nodeID string) (*structs.NodeServices, error) // Initialize the node services struct ns := &structs.NodeServices{ - Node: *node, + Node: node, Services: make(map[string]*structs.NodeService), } ns.CreateIndex = node.CreateIndex diff --git a/consul/state/state_store_test.go b/consul/state/state_store_test.go index c133a87db7..29e2b39c48 100644 --- a/consul/state/state_store_test.go +++ b/consul/state/state_store_test.go @@ -1,6 +1,7 @@ package state import ( + "fmt" "os" "reflect" "testing" @@ -84,6 +85,45 @@ func TestStateStore_EnsureNode_GetNode(t *testing.T) { } } +func TestStateStore_GetNodes(t *testing.T) { + s := testStateStore(t) + + // Create some nodes in the state store + nodes := []*structs.Node{ + &structs.Node{Node: "node0", Address: "1.1.1.0"}, + &structs.Node{Node: "node1", Address: "1.1.1.1"}, + &structs.Node{Node: "node2", Address: "1.1.1.2"}, + } + for i, node := range nodes { + if err := s.EnsureNode(uint64(i), node); err != nil { + t.Fatalf("err: %s", err) + } + } + + // Retrieve the nodes + out, err := s.Nodes() + if err != nil { + t.Fatalf("err: %s", err) + } + + // All nodes were returned + if n := len(out); n != 3 { + t.Fatalf("bad node count: %d", n) + } + + // Make sure the nodes match + for i, node := range nodes { + if node.CreateIndex != uint64(i) || node.ModifyIndex != uint64(i) { + t.Fatalf("bad node index: %d, %d", node.CreateIndex, node.ModifyIndex) + } + name := fmt.Sprintf("node%d", i) + addr := fmt.Sprintf("1.1.1.%d", i) + if node.Node != name || node.Address != addr { + t.Fatalf("bad: %#v", node) + } + } +} + func TestStateStore_EnsureService_NodeServices(t *testing.T) { s := testStateStore(t) diff --git a/consul/structs/structs.go b/consul/structs/structs.go index 586aff168b..9b7cab7452 100644 --- a/consul/structs/structs.go +++ b/consul/structs/structs.go @@ -17,9 +17,9 @@ var ( type MessageType uint8 -// Index is used to track the index used while creating +// RaftIndex is used to track the index used while creating // or modifying a given struct type. -type Index struct { +type RaftIndex struct { CreateIndex uint64 ModifyIndex uint64 } @@ -232,9 +232,9 @@ type Node struct { Node string Address string - Index + RaftIndex } -type Nodes []Node +type Nodes []*Node // Used to return information about a provided services. // Maps service name to available tags @@ -250,9 +250,9 @@ type ServiceNode struct { ServiceAddress string ServicePort int - Index + RaftIndex } -type ServiceNodes []ServiceNode +type ServiceNodes []*ServiceNode // NodeService is a service provided by a node type NodeService struct { @@ -267,10 +267,10 @@ type NodeService struct { } type NodeServices struct { - Node Node + Node *Node Services map[string]*NodeService - Index + RaftIndex } // HealthCheck represents a single check on a given node