consul/state: add function for returning all nodes

This commit is contained in:
Ryan Uber 2015-08-24 18:10:23 -07:00 committed by James Phillips
parent 8fea5f8dc5
commit 766c367ef4
3 changed files with 69 additions and 9 deletions

View file

@ -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

View file

@ -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)

View file

@ -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