diff --git a/command/agent/agent.go b/command/agent/agent.go
index d1d9e9291..449b03c47 100644
--- a/command/agent/agent.go
+++ b/command/agent/agent.go
@@ -246,6 +246,17 @@ func (a *Agent) consulConfig() *consul.Config {
Port: a.config.Ports.Server,
}
}
+ if a.config.AdvertiseAddrs.SerfLan != nil {
+ base.SerfLANConfig.MemberlistConfig.AdvertiseAddr = a.config.AdvertiseAddrs.SerfLan.IP.String()
+ base.SerfLANConfig.MemberlistConfig.AdvertisePort = a.config.AdvertiseAddrs.SerfLan.Port
+ }
+ if a.config.AdvertiseAddrs.SerfWan != nil {
+ base.SerfWANConfig.MemberlistConfig.AdvertiseAddr = a.config.AdvertiseAddrs.SerfWan.IP.String()
+ base.SerfWANConfig.MemberlistConfig.AdvertisePort = a.config.AdvertiseAddrs.SerfWan.Port
+ }
+ if a.config.AdvertiseAddrs.RPC != nil {
+ base.RPCAdvertise = a.config.AdvertiseAddrs.RPC
+ }
if a.config.Bootstrap {
base.Bootstrap = true
}
diff --git a/command/agent/agent_test.go b/command/agent/agent_test.go
index b36a8a274..5b8986eba 100644
--- a/command/agent/agent_test.go
+++ b/command/agent/agent_test.go
@@ -6,6 +6,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "net"
"os"
"path/filepath"
"reflect"
@@ -134,6 +135,37 @@ func TestAgent_RPCPing(t *testing.T) {
}
}
+func TestAgent_CheckAdvertiseAddrsSettings(t *testing.T) {
+ c := nextConfig()
+ c.AdvertiseAddrs.SerfLan, _ = net.ResolveTCPAddr("tcp", "127.0.0.42:1233")
+ c.AdvertiseAddrs.SerfWan, _ = net.ResolveTCPAddr("tcp", "127.0.0.43:1234")
+ c.AdvertiseAddrs.RPC, _ = net.ResolveTCPAddr("tcp", "127.0.0.44:1235")
+ dir, agent := makeAgent(t, c)
+ defer os.RemoveAll(dir)
+ defer agent.Shutdown()
+
+ serfLanAddr := agent.consulConfig().SerfLANConfig.MemberlistConfig.AdvertiseAddr
+ if serfLanAddr != "127.0.0.42" {
+ t.Fatalf("SerfLan is not properly set to '127.0.0.42': %s", serfLanAddr)
+ }
+ serfLanPort := agent.consulConfig().SerfLANConfig.MemberlistConfig.AdvertisePort
+ if serfLanPort != 1233 {
+ t.Fatalf("SerfLan is not properly set to '1233': %s", serfLanPort)
+ }
+ serfWanAddr := agent.consulConfig().SerfWANConfig.MemberlistConfig.AdvertiseAddr
+ if serfWanAddr != "127.0.0.43" {
+ t.Fatalf("SerfWan is not properly set to '127.0.0.43': %s", serfWanAddr)
+ }
+ serfWanPort := agent.consulConfig().SerfWANConfig.MemberlistConfig.AdvertisePort
+ if serfWanPort != 1234 {
+ t.Fatalf("SerfWan is not properly set to '1234': %s", serfWanPort)
+ }
+ rpc := agent.consulConfig().RPCAdvertise
+ if rpc != c.AdvertiseAddrs.RPC {
+ t.Fatalf("RPC is not properly set to %v: %s", c.AdvertiseAddrs.RPC, rpc)
+ }
+}
+
func TestAgent_AddService(t *testing.T) {
dir, agent := makeAgent(t, nextConfig())
defer os.RemoveAll(dir)
diff --git a/command/agent/config.go b/command/agent/config.go
index ce6511107..5b3357a34 100644
--- a/command/agent/config.go
+++ b/command/agent/config.go
@@ -40,6 +40,15 @@ type AddressConfig struct {
RPC string // CLI RPC
}
+type AdvertiseAddrsConfig struct {
+ SerfLan *net.TCPAddr `mapstructure:"-"`
+ SerfLanRaw string `mapstructure:"serf_lan"`
+ SerfWan *net.TCPAddr `mapstructure:"-"`
+ SerfWanRaw string `mapstructure:"serf_wan"`
+ RPC *net.TCPAddr `mapstructure:"-"`
+ RPCRaw string `mapstructure:"rpc"`
+}
+
// DNSConfig is used to fine tune the DNS sub-system.
// It can be used to control cache values, and stale
// reads
@@ -142,6 +151,9 @@ type Config struct {
// and Consul RPC IP. If not specified, bind address is used.
AdvertiseAddr string `mapstructure:"advertise_addr"`
+ // AdvertiseAddrs configuration
+ AdvertiseAddrs AdvertiseAddrsConfig `mapstructure:"advertise_addrs"`
+
// AdvertiseAddrWan is the address we use for advertising our
// Serf WAN IP. If not specified, the general advertise address is used.
AdvertiseAddrWan string `mapstructure:"advertise_addr_wan"`
@@ -638,6 +650,30 @@ func DecodeConfig(r io.Reader) (*Config, error) {
result.SessionTTLMin = dur
}
+ if result.AdvertiseAddrs.SerfLanRaw != "" {
+ addr, err := net.ResolveTCPAddr("tcp", result.AdvertiseAddrs.SerfLanRaw)
+ if err != nil {
+ return nil, fmt.Errorf("AdvertiseAddrs.SerfLan is invalid: %v", err)
+ }
+ result.AdvertiseAddrs.SerfLan = addr
+ }
+
+ if result.AdvertiseAddrs.SerfWanRaw != "" {
+ addr, err := net.ResolveTCPAddr("tcp", result.AdvertiseAddrs.SerfWanRaw)
+ if err != nil {
+ return nil, fmt.Errorf("AdvertiseAddrs.SerfWan is invalid: %v", err)
+ }
+ result.AdvertiseAddrs.SerfWan = addr
+ }
+
+ if result.AdvertiseAddrs.RPCRaw != "" {
+ addr, err := net.ResolveTCPAddr("tcp", result.AdvertiseAddrs.RPCRaw)
+ if err != nil {
+ return nil, fmt.Errorf("AdvertiseAddrs.RPC is invalid: %v", err)
+ }
+ result.AdvertiseAddrs.RPC = addr
+ }
+
return &result, nil
}
@@ -819,6 +855,18 @@ func MergeConfig(a, b *Config) *Config {
if b.AdvertiseAddrWan != "" {
result.AdvertiseAddrWan = b.AdvertiseAddrWan
}
+ if b.AdvertiseAddrs.SerfLan != nil {
+ result.AdvertiseAddrs.SerfLan = b.AdvertiseAddrs.SerfLan
+ result.AdvertiseAddrs.SerfLanRaw = b.AdvertiseAddrs.SerfLanRaw
+ }
+ if b.AdvertiseAddrs.SerfWan != nil {
+ result.AdvertiseAddrs.SerfWan = b.AdvertiseAddrs.SerfWan
+ result.AdvertiseAddrs.SerfWanRaw = b.AdvertiseAddrs.SerfWanRaw
+ }
+ if b.AdvertiseAddrs.RPC != nil {
+ result.AdvertiseAddrs.RPC = b.AdvertiseAddrs.RPC
+ result.AdvertiseAddrs.RPCRaw = b.AdvertiseAddrs.RPCRaw
+ }
if b.Server == true {
result.Server = b.Server
}
diff --git a/command/agent/config_test.go b/command/agent/config_test.go
index ac22af300..ed2a2921e 100644
--- a/command/agent/config_test.go
+++ b/command/agent/config_test.go
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/base64"
"io/ioutil"
+ "net"
"os"
"path/filepath"
"reflect"
@@ -211,6 +212,45 @@ func TestDecodeConfig(t *testing.T) {
t.Fatalf("bad: %#v", config)
}
+ // Advertise addresses for serflan
+ input = `{"advertise_addrs": {"serf_lan": "127.0.0.5:1234"}}`
+ config, err = DecodeConfig(bytes.NewReader([]byte(input)))
+ if err != nil {
+ t.Fatalf("err: %s", err)
+ }
+ if config.AdvertiseAddrs.SerfLanRaw != "127.0.0.5:1234" {
+ t.Fatalf("bad: %#v", config)
+ }
+ if config.AdvertiseAddrs.SerfLan.String() != "127.0.0.5:1234" {
+ t.Fatalf("bad: %#v", config)
+ }
+
+ // Advertise addresses for serfwan
+ input = `{"advertise_addrs": {"serf_wan": "127.0.0.5:1234"}}`
+ config, err = DecodeConfig(bytes.NewReader([]byte(input)))
+ if err != nil {
+ t.Fatalf("err: %s", err)
+ }
+ if config.AdvertiseAddrs.SerfWanRaw != "127.0.0.5:1234" {
+ t.Fatalf("bad: %#v", config)
+ }
+ if config.AdvertiseAddrs.SerfWan.String() != "127.0.0.5:1234" {
+ t.Fatalf("bad: %#v", config)
+ }
+
+ // Advertise addresses for rpc
+ input = `{"advertise_addrs": {"rpc": "127.0.0.5:1234"}}`
+ config, err = DecodeConfig(bytes.NewReader([]byte(input)))
+ if err != nil {
+ t.Fatalf("err: %s", err)
+ }
+ if config.AdvertiseAddrs.RPCRaw != "127.0.0.5:1234" {
+ t.Fatalf("bad: %#v", config)
+ }
+ if config.AdvertiseAddrs.RPC.String() != "127.0.0.5:1234" {
+ t.Fatalf("bad: %#v", config)
+ }
+
// leave_on_terminate
input = `{"leave_on_terminate": true}`
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
@@ -1166,6 +1206,14 @@ func TestMergeConfig(t *testing.T) {
AtlasJoin: true,
SessionTTLMinRaw: "1000s",
SessionTTLMin: 1000 * time.Second,
+ AdvertiseAddrs: AdvertiseAddrsConfig{
+ SerfLan: &net.TCPAddr{},
+ SerfLanRaw: "127.0.0.5:1231",
+ SerfWan: &net.TCPAddr{},
+ SerfWanRaw: "127.0.0.5:1232",
+ RPC: &net.TCPAddr{},
+ RPCRaw: "127.0.0.5:1233",
+ },
}
c := MergeConfig(a, b)
diff --git a/website/source/docs/agent/options.html.markdown b/website/source/docs/agent/options.html.markdown
index 7e8cdda1f..ac579974d 100644
--- a/website/source/docs/agent/options.html.markdown
+++ b/website/source/docs/agent/options.html.markdown
@@ -322,6 +322,16 @@ definitions support being updated during a reload.
* `advertise_addr` Equivalent to
the [`-advertise` command-line flag](#_advertise).
+* `advertise_addrs` Allows to set
+ the advertised addresses for SerfLan, SerfWan and RPC together with the port. This gives
+ you more control than (#_advertise) or (#_advertise-wan) while it serves the same purpose.
+ These settings might override (#_advertise) and (#_advertise-wan).
+
+ This is a nested setting that allows the following keys:
+ * `serf_lan` - The SerfLan address. Accepts values in the form of "host:port" like "10.23.31.101:8301".
+ * `serf_wan` - The SerfWan address. Accepts values in the form of "host:port" like "10.23.31.101:8302".
+ * `rpc` - The RPC address. Accepts values in the form of "host:port" like "10.23.31.101:8400".
+
* `advertise_addr_wan` Equivalent to
the [`-advertise-wan` command-line flag](#_advertise-wan).