Changes host-based node IDs from opt-out to opt-in. (#3187)

This commit is contained in:
James Phillips 2017-06-24 09:36:53 -07:00 committed by GitHub
parent 42f60b04bb
commit 380c8b957d
7 changed files with 75 additions and 13 deletions

View File

@ -940,7 +940,7 @@ func (a *Agent) makeRandomID() (string, error) {
// gopsutil change implementations without affecting in-place upgrades of nodes. // gopsutil change implementations without affecting in-place upgrades of nodes.
func (a *Agent) makeNodeID() (string, error) { func (a *Agent) makeNodeID() (string, error) {
// If they've disabled host-based IDs then just make a random one. // If they've disabled host-based IDs then just make a random one.
if a.config.DisableHostNodeID { if *a.config.DisableHostNodeID {
return a.makeRandomID() return a.makeRandomID()
} }

View File

@ -306,24 +306,34 @@ func TestAgent_makeNodeID(t *testing.T) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Calling again should yield the same ID since it's host-based. // Calling again should yield a random ID by default.
another, err := a.makeNodeID() another, err := a.makeNodeID()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
if id != another { if id == another {
t.Fatalf("bad: %s vs %s", id, another) t.Fatalf("bad: %s vs %s", id, another)
} }
// Turn off host-based IDs and try again. We should get a random ID. // Turn on host-based IDs and try again. We should get the same ID
a.Config.DisableHostNodeID = true // each time (and a different one from the random one above).
another, err = a.makeNodeID() a.Config.DisableHostNodeID = Bool(false)
id, err = a.makeNodeID()
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
if id == another { if id == another {
t.Fatalf("bad: %s vs %s", id, another) t.Fatalf("bad: %s vs %s", id, another)
} }
// Calling again should yield the host-based ID.
another, err = a.makeNodeID()
if err != nil {
t.Fatalf("err: %v", err)
}
if id != another {
t.Fatalf("bad: %s vs %s", id, another)
}
} }
func TestAgent_AddService(t *testing.T) { func TestAgent_AddService(t *testing.T) {

View File

@ -402,7 +402,7 @@ type Config struct {
// DisableHostNodeID will prevent Consul from using information from the // DisableHostNodeID will prevent Consul from using information from the
// host to generate a node ID, and will cause Consul to generate a // host to generate a node ID, and will cause Consul to generate a
// random ID instead. // random ID instead.
DisableHostNodeID bool `mapstructure:"disable_host_node_id"` DisableHostNodeID *bool `mapstructure:"disable_host_node_id"`
// Node name is the name we use to advertise. Defaults to hostname. // Node name is the name we use to advertise. Defaults to hostname.
NodeName string `mapstructure:"node_name"` NodeName string `mapstructure:"node_name"`
@ -959,6 +959,8 @@ func DefaultConfig() *Config {
EncryptVerifyIncoming: Bool(true), EncryptVerifyIncoming: Bool(true),
EncryptVerifyOutgoing: Bool(true), EncryptVerifyOutgoing: Bool(true),
DisableHostNodeID: Bool(true),
} }
} }
@ -1616,7 +1618,7 @@ func MergeConfig(a, b *Config) *Config {
if b.NodeID != "" { if b.NodeID != "" {
result.NodeID = b.NodeID result.NodeID = b.NodeID
} }
if b.DisableHostNodeID == true { if b.DisableHostNodeID != nil {
result.DisableHostNodeID = b.DisableHostNodeID result.DisableHostNodeID = b.DisableHostNodeID
} }
if b.NodeName != "" { if b.NodeName != "" {

View File

@ -242,8 +242,8 @@ func TestDecodeConfig(t *testing.T) {
c: &Config{DisableCoordinates: true}, c: &Config{DisableCoordinates: true},
}, },
{ {
in: `{"disable_host_node_id":true}`, in: `{"disable_host_node_id":false}`,
c: &Config{DisableHostNodeID: true}, c: &Config{DisableHostNodeID: Bool(false)},
}, },
{ {
in: `{"dns_config":{"allow_stale":true}}`, in: `{"dns_config":{"allow_stale":true}}`,
@ -1305,7 +1305,7 @@ func TestMergeConfig(t *testing.T) {
Domain: "other", Domain: "other",
LogLevel: "info", LogLevel: "info",
NodeID: "bar", NodeID: "bar",
DisableHostNodeID: true, DisableHostNodeID: Bool(false),
NodeName: "baz", NodeName: "baz",
ClientAddr: "127.0.0.2", ClientAddr: "127.0.0.2",
BindAddr: "127.0.0.2", BindAddr: "127.0.0.2",

View File

@ -79,10 +79,13 @@ func (cmd *AgentCommand) readConfig() *agent.Config {
f.StringVar((*string)(&cmdCfg.NodeID), "node-id", "", f.StringVar((*string)(&cmdCfg.NodeID), "node-id", "",
"A unique ID for this node across space and time. Defaults to a randomly-generated ID"+ "A unique ID for this node across space and time. Defaults to a randomly-generated ID"+
" that persists in the data-dir.") " that persists in the data-dir.")
f.BoolVar(&cmdCfg.DisableHostNodeID, "disable-host-node-id", false,
var disableHostNodeID configutil.BoolValue
f.Var(&disableHostNodeID, "disable-host-node-id",
"Setting this to true will prevent Consul from using information from the"+ "Setting this to true will prevent Consul from using information from the"+
" host to generate a node ID, and will cause Consul to generate a"+ " host to generate a node ID, and will cause Consul to generate a"+
" random node ID instead.") " random node ID instead.")
f.StringVar(&cmdCfg.Datacenter, "datacenter", "", "Datacenter of the agent.") f.StringVar(&cmdCfg.Datacenter, "datacenter", "", "Datacenter of the agent.")
f.StringVar(&cmdCfg.DataDir, "data-dir", "", "Path to a data directory to store agent state.") f.StringVar(&cmdCfg.DataDir, "data-dir", "", "Path to a data directory to store agent state.")
f.BoolVar(&cmdCfg.EnableUI, "ui", false, "Enables the built-in static web UI server.") f.BoolVar(&cmdCfg.EnableUI, "ui", false, "Enables the built-in static web UI server.")
@ -238,6 +241,7 @@ func (cmd *AgentCommand) readConfig() *agent.Config {
cmdCfg.DNSRecursors = append(cmdCfg.DNSRecursors, dnsRecursors...) cmdCfg.DNSRecursors = append(cmdCfg.DNSRecursors, dnsRecursors...)
cfg = agent.MergeConfig(cfg, &cmdCfg) cfg = agent.MergeConfig(cfg, &cmdCfg)
disableHostNodeID.Merge(cfg.DisableHostNodeID)
if cfg.NodeName == "" { if cfg.NodeName == "" {
hostname, err := os.Hostname() hostname, err := os.Hostname()

View File

@ -291,6 +291,48 @@ func TestReadCliConfig(t *testing.T) {
} }
} }
func TestAgent_HostBasedIDs(t *testing.T) {
t.Parallel()
tmpDir := testutil.TempDir(t, "consul")
defer os.RemoveAll(tmpDir)
shutdownCh := make(chan struct{})
defer close(shutdownCh)
// Host-based IDs are disabled by default.
{
cmd := &AgentCommand{
args: []string{
"-data-dir", tmpDir,
},
ShutdownCh: shutdownCh,
BaseCommand: baseCommand(cli.NewMockUi()),
}
config := cmd.readConfig()
if *config.DisableHostNodeID != true {
t.Fatalf("expected host-based node IDs to be disabled")
}
}
// Try enabling host-based IDs.
{
cmd := &AgentCommand{
args: []string{
"-data-dir", tmpDir,
"-disable-host-node-id=false",
},
ShutdownCh: shutdownCh,
BaseCommand: baseCommand(cli.NewMockUi()),
}
config := cmd.readConfig()
if *config.DisableHostNodeID != false {
t.Fatalf("expected host-based node IDs to be enabled")
}
}
}
func TestRetryJoinFail(t *testing.T) { func TestRetryJoinFail(t *testing.T) {
t.Skip("fs: skipping tests that use cmd.Run until signal handling is fixed") t.Skip("fs: skipping tests that use cmd.Run until signal handling is fixed")
t.Parallel() t.Parallel()

View File

@ -141,7 +141,11 @@ will exit with an error at startup.
* <a name="_disable_host_node_id"></a><a href="#_disable_host_node_id">`-disable-host-node-id`</a> - Setting * <a name="_disable_host_node_id"></a><a href="#_disable_host_node_id">`-disable-host-node-id`</a> - Setting
this to true will prevent Consul from using information from the host to generate a deterministic node ID, this to true will prevent Consul from using information from the host to generate a deterministic node ID,
and will instead generate a random node ID which will be persisted in the data directory. This is useful and will instead generate a random node ID which will be persisted in the data directory. This is useful
when running multiple Consul agents on the same host for testing. This defaults to false. when running multiple Consul agents on the same host for testing. This defaults to false in Consul prior
to version 0.8.5 and in 0.8.5 and later defaults to true, so you must opt-in for host-based IDs. Host-based
IDs are generated using https://github.com/shirou/gopsutil/tree/master/host, which is shared with HashiCorp's
[Nomad](https://www.nomadproject.io/), so if you opt-in to host-based IDs then Consul and Nomad will use
information on the host to automatically assign the same ID in both systems.
* <a name="_dns_port"></a><a href="#_dns_port">`-dns-port`</a> - the DNS port to listen on. * <a name="_dns_port"></a><a href="#_dns_port">`-dns-port`</a> - the DNS port to listen on.
This overrides the default port 8600. This is available in Consul 0.7 and later. This overrides the default port 8600. This is available in Consul 0.7 and later.