Adds node ID integrity checking for the catalog.

This commit is contained in:
James Phillips 2017-03-27 00:15:21 -07:00
parent 32beea5cb8
commit 7340b5b7ad
No known key found for this signature in database
GPG Key ID: 77183E682AC5FC11
3 changed files with 53 additions and 10 deletions

View File

@ -90,11 +90,13 @@ func (c *Catalog) Register(args *structs.RegisterRequest, reply *struct{}) error
}
}
_, err = c.srv.raftApply(structs.RegisterRequestType, args)
resp, err := c.srv.raftApply(structs.RegisterRequestType, args)
if err != nil {
return err
}
if respErr, ok := resp.(error); ok {
return respErr
}
return nil
}

View File

@ -165,22 +165,45 @@ func (s *StateStore) EnsureNode(idx uint64, node *structs.Node) error {
// registration or modify an existing one in the state store. It allows
// passing in a memdb transaction so it may be part of a larger txn.
func (s *StateStore) ensureNodeTxn(tx *memdb.Txn, idx uint64, node *structs.Node) error {
// Check for an existing node
existing, err := tx.First("nodes", "id", node.Node)
if err != nil {
return fmt.Errorf("node name lookup failed: %s", err)
// See if there's an existing node with this UUID, and make sure the
// name is the same.
var n *structs.Node
if node.ID != "" {
existing, err := tx.First("nodes", "uuid", string(node.ID))
if err != nil {
return fmt.Errorf("node lookup failed: %s", err)
}
if existing != nil {
n = existing.(*structs.Node)
fmt.Printf("XXX %#v\n", *n)
if n.Node != node.Node {
return fmt.Errorf("node ID %q for node %q aliases existing node %q",
node.ID, node.Node, n.Node)
}
}
}
// Get the indexes
if existing != nil {
node.CreateIndex = existing.(*structs.Node).CreateIndex
// Check for an existing node by name to support nodes with no IDs.
if n == nil {
existing, err := tx.First("nodes", "id", node.Node)
if err != nil {
return fmt.Errorf("node name lookup failed: %s", err)
}
if existing != nil {
n = existing.(*structs.Node)
}
}
// Get the indexes.
if n != nil {
node.CreateIndex = n.CreateIndex
node.ModifyIndex = idx
} else {
node.CreateIndex = idx
node.ModifyIndex = idx
}
// Insert the node and update the index
// Insert the node and update the index.
if err := tx.Insert("nodes", node); err != nil {
return fmt.Errorf("failed inserting node: %s", err)
}

View File

@ -4,6 +4,7 @@ import (
"fmt"
"reflect"
"sort"
"strings"
"testing"
"github.com/hashicorp/consul/consul/structs"
@ -419,6 +420,23 @@ func TestStateStore_EnsureNode(t *testing.T) {
if idx != 3 {
t.Fatalf("bad index: %d", idx)
}
// Add an ID to the node
in.ID = types.NodeID("cda916bc-a357-4a19-b886-59419fcee50c")
if err := s.EnsureNode(4, in); err != nil {
t.Fatalf("err: %v", err)
}
// Now try to add another node with the same ID
in = &structs.Node{
Node: "nope",
ID: types.NodeID("cda916bc-a357-4a19-b886-59419fcee50c"),
Address: "1.2.3.4",
}
err = s.EnsureNode(5, in)
if err == nil || !strings.Contains(err.Error(), "aliases existing node") {
t.Fatalf("err: %v", err)
}
}
func TestStateStore_GetNodes(t *testing.T) {