Merge pull request #1910 from hashicorp/f-detect-dupe-addrs
Print a helpful message re: duplicate addresses
This commit is contained in:
commit
af0f87ed90
|
@ -192,6 +192,12 @@ func (c *Command) readConfig() *Config {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Ensure all endpoints are unique
|
||||
if err := config.verifyUniqueListeners(); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("All listening endpoints must be unique: %s", err))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check the data dir for signs of an un-migrated Consul 0.5.x or older
|
||||
// server. Consul refuses to start if this is present to protect a server
|
||||
// with existing data from starting on a fresh data set.
|
||||
|
@ -301,6 +307,67 @@ func (c *Command) readConfig() *Config {
|
|||
return config
|
||||
}
|
||||
|
||||
// verifyUniqueListeners checks to see if an address was used more than once in
|
||||
// the config
|
||||
func (config *Config) verifyUniqueListeners() error {
|
||||
type key struct {
|
||||
host string
|
||||
port int
|
||||
}
|
||||
const numUniqueAddrs = 7
|
||||
m := make(map[key]string, numUniqueAddrs)
|
||||
|
||||
testFunc := func(k key, descr string) error {
|
||||
if k.host == "" {
|
||||
k.host = "0.0.0.0"
|
||||
} else if strings.HasPrefix(k.host, "unix") {
|
||||
// Don't compare ports on unix sockets
|
||||
k.port = 0
|
||||
}
|
||||
if k.host == "0.0.0.0" && k.port <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
v, ok := m[k]
|
||||
if ok {
|
||||
return fmt.Errorf("%s address already configured for %s", descr, v)
|
||||
}
|
||||
m[k] = descr
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := testFunc(key{config.Addresses.RPC, config.Ports.RPC}, "RPC"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := testFunc(key{config.Addresses.DNS, config.Ports.DNS}, "DNS"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := testFunc(key{config.Addresses.HTTP, config.Ports.HTTP}, "HTTP"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := testFunc(key{config.Addresses.HTTPS, config.Ports.HTTPS}, "HTTPS"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := testFunc(key{config.AdvertiseAddr, config.Ports.Server}, "Server RPC"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := testFunc(key{config.AdvertiseAddr, config.Ports.SerfLan}, "Serf LAN"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := testFunc(key{config.AdvertiseAddr, config.Ports.SerfWan}, "Serf WAN"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// setupLoggers is used to setup the logGate, logWriter, and our logOutput
|
||||
func (c *Command) setupLoggers(config *Config) (*GatedWriter, *logWriter, io.Writer) {
|
||||
// Setup logging. First create the gated log writer, which will
|
||||
|
|
|
@ -989,6 +989,42 @@ func TestDecodeConfig_Services(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDecodeConfig_verifyUniqueListeners(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cfg string
|
||||
pass bool
|
||||
}{
|
||||
{
|
||||
"http_rpc1",
|
||||
`{"addresses": {"http": "0.0.0.0", "rpc": "127.0.0.1"}, "ports": {"rpc": 8000, "dns": 8000}}`,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"http_rpc IP identical",
|
||||
`{"addresses": {"http": "0.0.0.0", "rpc": "0.0.0.0"}, "ports": {"rpc": 8000, "dns": 8000}}`,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"http_rpc unix identical (diff ports)",
|
||||
`{"addresses": {"http": "unix:///tmp/.consul.sock", "rpc": "unix:///tmp/.consul.sock"}, "ports": {"rpc": 8000, "dns": 8001}}`,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
config, err := DecodeConfig(bytes.NewReader([]byte(test.cfg)))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s %s", test.name, err)
|
||||
}
|
||||
|
||||
err = config.verifyUniqueListeners()
|
||||
if (err != nil && test.pass) || (err == nil && !test.pass) {
|
||||
t.Errorf("err: %s should have %v: %v: %v", test.name, test.pass, test.cfg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeConfig_Checks(t *testing.T) {
|
||||
input := `{
|
||||
"checks": [
|
||||
|
|
Loading…
Reference in New Issue