Add datacenter to catalog node API (#2917)

This patch stores the datacenter of a node in memdb
and exposes it via the API in all places where a Node
structure is returned.

 * /catalog/nodes
 * /catalog/node/:node
 * /catalog/service/:service
 * /health/service/:service
 * /query/:uuid/execute
This commit is contained in:
Frank Schröder 2017-04-18 05:02:24 -07:00 committed by GitHub
parent c7831a188e
commit 892fa89399
10 changed files with 57 additions and 5 deletions

View File

@ -4,6 +4,7 @@ type Node struct {
ID string ID string
Node string Node string
Address string Address string
Datacenter string
TaggedAddresses map[string]string TaggedAddresses map[string]string
Meta map[string]string Meta map[string]string
CreateIndex uint64 CreateIndex uint64
@ -14,6 +15,7 @@ type CatalogService struct {
ID string ID string
Node string Node string
Address string Address string
Datacenter string
TaggedAddresses map[string]string TaggedAddresses map[string]string
NodeMeta map[string]string NodeMeta map[string]string
ServiceID string ServiceID string

View File

@ -54,6 +54,10 @@ func TestCatalog_Nodes(t *testing.T) {
return false, fmt.Errorf("Bad: %v", nodes[0]) return false, fmt.Errorf("Bad: %v", nodes[0])
} }
if nodes[0].Datacenter != "dc1" {
return false, fmt.Errorf("Bad datacenter: %v", nodes[0])
}
return true, nil return true, nil
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
@ -92,6 +96,10 @@ func TestCatalog_Nodes_MetaFilter(t *testing.T) {
return false, fmt.Errorf("Bad: %v", nodes[0].Meta) return false, fmt.Errorf("Bad: %v", nodes[0].Meta)
} }
if nodes[0].Datacenter != "dc1" {
return false, fmt.Errorf("Bad datacenter: %v", nodes[0])
}
return true, nil return true, nil
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
@ -216,6 +224,10 @@ func TestCatalog_Service(t *testing.T) {
return false, fmt.Errorf("Bad: %v", services) return false, fmt.Errorf("Bad: %v", services)
} }
if services[0].Datacenter != "dc1" {
return false, fmt.Errorf("Bad datacenter: %v", services[0])
}
return true, nil return true, nil
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
@ -246,6 +258,10 @@ func TestCatalog_Service_NodeMetaFilter(t *testing.T) {
return false, fmt.Errorf("Bad: %v", services) return false, fmt.Errorf("Bad: %v", services)
} }
if services[0].Datacenter != "dc1" {
return false, fmt.Errorf("Bad datacenter: %v", services[0])
}
return true, nil return true, nil
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
@ -278,6 +294,10 @@ func TestCatalog_Node(t *testing.T) {
return false, fmt.Errorf("Bad: %v", info) return false, fmt.Errorf("Bad: %v", info)
} }
if info.Node.Datacenter != "dc1" {
return false, fmt.Errorf("Bad datacenter: %v", info)
}
return true, nil return true, nil
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -269,6 +269,9 @@ func TestHealth_Service(t *testing.T) {
if _, ok := checks[0].Node.TaggedAddresses["wan"]; !ok { if _, ok := checks[0].Node.TaggedAddresses["wan"]; !ok {
return false, fmt.Errorf("Bad: %v", checks[0].Node) return false, fmt.Errorf("Bad: %v", checks[0].Node)
} }
if checks[0].Node.Datacenter != "dc1" {
return false, fmt.Errorf("Bad datacenter: %v", checks[0].Node)
}
return true, nil return true, nil
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
@ -299,6 +302,9 @@ func TestHealth_Service_NodeMetaFilter(t *testing.T) {
if _, ok := checks[0].Node.TaggedAddresses["wan"]; !ok { if _, ok := checks[0].Node.TaggedAddresses["wan"]; !ok {
return false, fmt.Errorf("Bad: %v", checks[0].Node) return false, fmt.Errorf("Bad: %v", checks[0].Node)
} }
if checks[0].Node.Datacenter != "dc1" {
return false, fmt.Errorf("Bad datacenter: %v", checks[0].Node)
}
return true, nil return true, nil
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -117,6 +117,9 @@ func TestPreparedQuery(t *testing.T) {
if wan, ok := results.Nodes[0].Node.TaggedAddresses["wan"]; !ok || wan != "127.0.0.1" { if wan, ok := results.Nodes[0].Node.TaggedAddresses["wan"]; !ok || wan != "127.0.0.1" {
t.Fatalf("bad: %v", results) t.Fatalf("bad: %v", results)
} }
if results.Nodes[0].Node.Datacenter != "dc1" {
t.Fatalf("bad datacenter: %v", results)
}
// Delete it. // Delete it.
_, err = query.Delete(def.ID, nil) _, err = query.Delete(def.ID, nil)

View File

@ -89,6 +89,7 @@ func (s *StateStore) ensureRegistrationTxn(tx *memdb.Txn, idx uint64, req *struc
ID: req.ID, ID: req.ID,
Node: req.Node, Node: req.Node,
Address: req.Address, Address: req.Address,
Datacenter: req.Datacenter,
TaggedAddresses: req.TaggedAddresses, TaggedAddresses: req.TaggedAddresses,
Meta: req.NodeMeta, Meta: req.NodeMeta,
} }
@ -684,6 +685,7 @@ func (s *StateStore) parseServiceNodes(tx *memdb.Txn, ws memdb.WatchSet, service
node := n.(*structs.Node) node := n.(*structs.Node)
s.ID = node.ID s.ID = node.ID
s.Address = node.Address s.Address = node.Address
s.Datacenter = node.Datacenter
s.TaggedAddresses = node.TaggedAddresses s.TaggedAddresses = node.TaggedAddresses
s.NodeMeta = node.Meta s.NodeMeta = node.Meta

View File

@ -5,14 +5,14 @@ import (
"fmt" "fmt"
"math/rand" "math/rand"
"reflect" "reflect"
"regexp"
"strings"
"time" "time"
"github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/types" "github.com/hashicorp/consul/types"
"github.com/hashicorp/go-msgpack/codec" "github.com/hashicorp/go-msgpack/codec"
"github.com/hashicorp/serf/coordinate" "github.com/hashicorp/serf/coordinate"
"regexp"
"strings"
) )
var ( var (
@ -235,6 +235,7 @@ func (r *RegisterRequest) ChangesNode(node *Node) bool {
if r.ID != node.ID || if r.ID != node.ID ||
r.Node != node.Node || r.Node != node.Node ||
r.Address != node.Address || r.Address != node.Address ||
r.Datacenter != node.Datacenter ||
!reflect.DeepEqual(r.TaggedAddresses, node.TaggedAddresses) || !reflect.DeepEqual(r.TaggedAddresses, node.TaggedAddresses) ||
!reflect.DeepEqual(r.NodeMeta, node.Meta) { !reflect.DeepEqual(r.NodeMeta, node.Meta) {
return true return true
@ -322,6 +323,7 @@ type Node struct {
ID types.NodeID ID types.NodeID
Node string Node string
Address string Address string
Datacenter string
TaggedAddresses map[string]string TaggedAddresses map[string]string
Meta map[string]string Meta map[string]string
@ -387,6 +389,7 @@ type ServiceNode struct {
ID types.NodeID ID types.NodeID
Node string Node string
Address string Address string
Datacenter string
TaggedAddresses map[string]string TaggedAddresses map[string]string
NodeMeta map[string]string NodeMeta map[string]string
ServiceID string ServiceID string

View File

@ -110,6 +110,7 @@ func TestStructs_RegisterRequest_ChangesNode(t *testing.T) {
ID: types.NodeID("40e4a748-2192-161a-0510-9bf59fe950b5"), ID: types.NodeID("40e4a748-2192-161a-0510-9bf59fe950b5"),
Node: "test", Node: "test",
Address: "127.0.0.1", Address: "127.0.0.1",
Datacenter: "dc1",
TaggedAddresses: make(map[string]string), TaggedAddresses: make(map[string]string),
NodeMeta: map[string]string{ NodeMeta: map[string]string{
"role": "server", "role": "server",
@ -120,6 +121,7 @@ func TestStructs_RegisterRequest_ChangesNode(t *testing.T) {
ID: types.NodeID("40e4a748-2192-161a-0510-9bf59fe950b5"), ID: types.NodeID("40e4a748-2192-161a-0510-9bf59fe950b5"),
Node: "test", Node: "test",
Address: "127.0.0.1", Address: "127.0.0.1",
Datacenter: "dc1",
TaggedAddresses: make(map[string]string), TaggedAddresses: make(map[string]string),
Meta: map[string]string{ Meta: map[string]string{
"role": "server", "role": "server",
@ -155,6 +157,7 @@ func TestStructs_RegisterRequest_ChangesNode(t *testing.T) {
check(func() { req.ID = "nope" }, func() { req.ID = types.NodeID("40e4a748-2192-161a-0510-9bf59fe950b5") }) check(func() { req.ID = "nope" }, func() { req.ID = types.NodeID("40e4a748-2192-161a-0510-9bf59fe950b5") })
check(func() { req.Node = "nope" }, func() { req.Node = "test" }) check(func() { req.Node = "nope" }, func() { req.Node = "test" })
check(func() { req.Address = "127.0.0.2" }, func() { req.Address = "127.0.0.1" }) check(func() { req.Address = "127.0.0.2" }, func() { req.Address = "127.0.0.1" })
check(func() { req.Datacenter = "dc2" }, func() { req.Datacenter = "dc1" })
check(func() { req.TaggedAddresses["wan"] = "nope" }, func() { delete(req.TaggedAddresses, "wan") }) check(func() { req.TaggedAddresses["wan"] = "nope" }, func() { delete(req.TaggedAddresses, "wan") })
check(func() { req.NodeMeta["invalid"] = "nope" }, func() { delete(req.NodeMeta, "invalid") }) check(func() { req.NodeMeta["invalid"] = "nope" }, func() { delete(req.NodeMeta, "invalid") })
@ -169,6 +172,7 @@ func testServiceNode() *ServiceNode {
ID: types.NodeID("40e4a748-2192-161a-0510-9bf59fe950b5"), ID: types.NodeID("40e4a748-2192-161a-0510-9bf59fe950b5"),
Node: "node1", Node: "node1",
Address: "127.0.0.1", Address: "127.0.0.1",
Datacenter: "dc1",
TaggedAddresses: map[string]string{ TaggedAddresses: map[string]string{
"hello": "world", "hello": "world",
}, },
@ -198,6 +202,7 @@ func TestStructs_ServiceNode_PartialClone(t *testing.T) {
// the rest of the contents. // the rest of the contents.
if clone.ID != "" || if clone.ID != "" ||
clone.Address != "" || clone.Address != "" ||
clone.Datacenter != "" ||
len(clone.TaggedAddresses) != 0 || len(clone.TaggedAddresses) != 0 ||
len(clone.NodeMeta) != 0 { len(clone.NodeMeta) != 0 {
t.Fatalf("bad: %v", clone) t.Fatalf("bad: %v", clone)
@ -205,6 +210,7 @@ func TestStructs_ServiceNode_PartialClone(t *testing.T) {
sn.ID = "" sn.ID = ""
sn.Address = "" sn.Address = ""
sn.Datacenter = ""
sn.TaggedAddresses = nil sn.TaggedAddresses = nil
sn.NodeMeta = nil sn.NodeMeta = nil
if !reflect.DeepEqual(sn, clone) { if !reflect.DeepEqual(sn, clone) {
@ -226,6 +232,7 @@ func TestStructs_ServiceNode_Conversions(t *testing.T) {
// them out before we do the compare. // them out before we do the compare.
sn.ID = "" sn.ID = ""
sn.Address = "" sn.Address = ""
sn.Datacenter = ""
sn.TaggedAddresses = nil sn.TaggedAddresses = nil
sn.NodeMeta = nil sn.NodeMeta = nil
if !reflect.DeepEqual(sn, sn2) { if !reflect.DeepEqual(sn, sn2) {

View File

@ -274,6 +274,7 @@ $ curl \
"ID": "40e4a748-2192-161a-0510-9bf59fe950b5", "ID": "40e4a748-2192-161a-0510-9bf59fe950b5",
"Node": "baz", "Node": "baz",
"Address": "10.1.10.11", "Address": "10.1.10.11",
"Datacenter": "dc1",
"TaggedAddresses": { "TaggedAddresses": {
"lan": "10.1.10.11", "lan": "10.1.10.11",
"wan": "10.1.10.11" "wan": "10.1.10.11"
@ -286,6 +287,7 @@ $ curl \
"ID": "8f246b77-f3e1-ff88-5b48-8ec93abf3e05", "ID": "8f246b77-f3e1-ff88-5b48-8ec93abf3e05",
"Node": "foobar", "Node": "foobar",
"Address": "10.1.10.12", "Address": "10.1.10.12",
"Datacenter": "dc2",
"TaggedAddresses": { "TaggedAddresses": {
"lan": "10.1.10.11", "lan": "10.1.10.11",
"wan": "10.1.10.12" "wan": "10.1.10.12"
@ -401,6 +403,7 @@ $ curl \
"ID": "40e4a748-2192-161a-0510-9bf59fe950b5", "ID": "40e4a748-2192-161a-0510-9bf59fe950b5",
"Node": "foobar", "Node": "foobar",
"Address": "192.168.10.10", "Address": "192.168.10.10",
"Datacenter": "dc1",
"TaggedAddresses": { "TaggedAddresses": {
"lan": "192.168.10.10", "lan": "192.168.10.10",
"wan": "10.0.10.10" "wan": "10.0.10.10"
@ -425,6 +428,9 @@ $ curl \
- `Address` is the IP address of the Consul node on which the service is - `Address` is the IP address of the Consul node on which the service is
registered. registered.
- `Datacenter` is the data center of the Consul node on which the service is
registered.
- `TaggedAddresses` is the list of explicit LAN and WAN IP addresses for the - `TaggedAddresses` is the list of explicit LAN and WAN IP addresses for the
agent agent
@ -495,6 +501,7 @@ $ curl \
"ID": "40e4a748-2192-161a-0510-9bf59fe950b5", "ID": "40e4a748-2192-161a-0510-9bf59fe950b5",
"Node": "foobar", "Node": "foobar",
"Address": "10.1.10.12", "Address": "10.1.10.12",
"Datacenter": "dc1",
"TaggedAddresses": { "TaggedAddresses": {
"lan": "10.1.10.12", "lan": "10.1.10.12",
"wan": "10.1.10.12" "wan": "10.1.10.12"

View File

@ -199,6 +199,7 @@ $ curl \
"ID": "40e4a748-2192-161a-0510-9bf59fe950b5", "ID": "40e4a748-2192-161a-0510-9bf59fe950b5",
"Node": "foobar", "Node": "foobar",
"Address": "10.1.10.12", "Address": "10.1.10.12",
"Datacenter": "dc1",
"TaggedAddresses": { "TaggedAddresses": {
"lan": "10.1.10.12", "lan": "10.1.10.12",
"wan": "10.1.10.12" "wan": "10.1.10.12"

View File

@ -470,6 +470,7 @@ $ curl \
"ID": "40e4a748-2192-161a-0510-9bf59fe950b5", "ID": "40e4a748-2192-161a-0510-9bf59fe950b5",
"Node": "foobar", "Node": "foobar",
"Address": "10.1.10.12", "Address": "10.1.10.12",
"Datacenter": "dc1",
"TaggedAddresses": { "TaggedAddresses": {
"lan": "10.1.10.12", "lan": "10.1.10.12",
"wan": "10.1.10.12" "wan": "10.1.10.12"