mirror of https://github.com/status-im/consul.git
Merge pull request #4403 from hashicorp/bugfix/choose-client-address
Fix issue with managed proxies and watches attempting to use a client addr that is 0.0.0.0 or ::
This commit is contained in:
commit
3859291148
|
@ -710,25 +710,14 @@ func (a *Agent) reloadWatches(cfg *config.RuntimeConfig) error {
|
|||
watchPlans = append(watchPlans, wp)
|
||||
}
|
||||
|
||||
// Determine the primary http(s) endpoint.
|
||||
var netaddr net.Addr
|
||||
https := false
|
||||
if len(cfg.HTTPAddrs) > 0 {
|
||||
netaddr = cfg.HTTPAddrs[0]
|
||||
} else {
|
||||
netaddr = cfg.HTTPSAddrs[0]
|
||||
https = true
|
||||
}
|
||||
addr := netaddr.String()
|
||||
if netaddr.Network() == "unix" {
|
||||
addr = "unix://" + addr
|
||||
https = false
|
||||
} else if https {
|
||||
addr = "https://" + addr
|
||||
}
|
||||
|
||||
// Fire off a goroutine for each new watch plan.
|
||||
for _, wp := range watchPlans {
|
||||
config, err := a.config.APIConfig(true)
|
||||
if err != nil {
|
||||
a.logger.Printf("[ERR] agent: Failed to run watch: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
a.watchPlans = append(a.watchPlans, wp)
|
||||
go func(wp *watch.Plan) {
|
||||
if h, ok := wp.Exempt["handler"]; ok {
|
||||
|
@ -741,16 +730,9 @@ func (a *Agent) reloadWatches(cfg *config.RuntimeConfig) error {
|
|||
}
|
||||
wp.LogOutput = a.LogOutput
|
||||
|
||||
config := api.DefaultConfig()
|
||||
if https {
|
||||
if a.config.CAPath != "" {
|
||||
config.TLSConfig.CAPath = a.config.CAPath
|
||||
}
|
||||
if a.config.CAFile != "" {
|
||||
config.TLSConfig.CAFile = a.config.CAFile
|
||||
}
|
||||
// use the original address without the https:// prefix
|
||||
config.TLSConfig.Address = netaddr.String()
|
||||
addr := config.Address
|
||||
if config.Scheme == "https" {
|
||||
addr = "https://" + addr
|
||||
}
|
||||
|
||||
if err := wp.RunWithConfig(addr, config); err != nil {
|
||||
|
|
|
@ -1193,7 +1193,7 @@ func (c *RuntimeConfig) IncomingHTTPSConfig() (*tls.Config, error) {
|
|||
func (c *RuntimeConfig) apiAddresses(maxPerType int) (unixAddrs, httpAddrs, httpsAddrs []string) {
|
||||
if len(c.HTTPSAddrs) > 0 {
|
||||
for i, addr := range c.HTTPSAddrs {
|
||||
if i < maxPerType {
|
||||
if maxPerType < 1 || i < maxPerType {
|
||||
httpsAddrs = append(httpsAddrs, addr.String())
|
||||
} else {
|
||||
break
|
||||
|
@ -1206,12 +1206,12 @@ func (c *RuntimeConfig) apiAddresses(maxPerType int) (unixAddrs, httpAddrs, http
|
|||
for _, addr := range c.HTTPAddrs {
|
||||
switch addr.(type) {
|
||||
case *net.UnixAddr:
|
||||
if unix_count < maxPerType {
|
||||
if maxPerType < 1 || unix_count < maxPerType {
|
||||
unixAddrs = append(unixAddrs, addr.String())
|
||||
unix_count += 1
|
||||
}
|
||||
default:
|
||||
if http_count < maxPerType {
|
||||
if maxPerType < 1 || http_count < maxPerType {
|
||||
httpAddrs = append(httpAddrs, addr.String())
|
||||
http_count += 1
|
||||
}
|
||||
|
@ -1222,28 +1222,95 @@ func (c *RuntimeConfig) apiAddresses(maxPerType int) (unixAddrs, httpAddrs, http
|
|||
return
|
||||
}
|
||||
|
||||
func (c *RuntimeConfig) ClientAddress() (unixAddr, httpAddr, httpsAddr string) {
|
||||
unixAddrs, httpAddrs, httpsAddrs := c.apiAddresses(0)
|
||||
|
||||
if len(unixAddrs) > 0 {
|
||||
unixAddr = "unix://" + unixAddrs[0]
|
||||
}
|
||||
|
||||
http_any := ""
|
||||
if len(httpAddrs) > 0 {
|
||||
for _, addr := range httpAddrs {
|
||||
host, port, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if host == "0.0.0.0" || host == "::" {
|
||||
if http_any == "" {
|
||||
if host == "0.0.0.0" {
|
||||
http_any = net.JoinHostPort("127.0.0.1", port)
|
||||
} else {
|
||||
http_any = net.JoinHostPort("::1", port)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
httpAddr = addr
|
||||
break
|
||||
}
|
||||
|
||||
if httpAddr == "" && http_any != "" {
|
||||
httpAddr = http_any
|
||||
}
|
||||
}
|
||||
|
||||
https_any := ""
|
||||
if len(httpsAddrs) > 0 {
|
||||
for _, addr := range httpsAddrs {
|
||||
host, port, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if host == "0.0.0.0" || host == "::" {
|
||||
if https_any == "" {
|
||||
if host == "0.0.0.0" {
|
||||
https_any = net.JoinHostPort("127.0.0.1", port)
|
||||
} else {
|
||||
https_any = net.JoinHostPort("::1", port)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
httpsAddr = addr
|
||||
break
|
||||
}
|
||||
|
||||
if httpsAddr == "" && https_any != "" {
|
||||
httpsAddr = https_any
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *RuntimeConfig) APIConfig(includeClientCerts bool) (*api.Config, error) {
|
||||
cfg := &api.Config{
|
||||
Datacenter: c.Datacenter,
|
||||
TLSConfig: api.TLSConfig{InsecureSkipVerify: !c.VerifyOutgoing},
|
||||
}
|
||||
|
||||
unixAddrs, httpAddrs, httpsAddrs := c.apiAddresses(1)
|
||||
unixAddr, httpAddr, httpsAddr := c.ClientAddress()
|
||||
|
||||
if len(httpsAddrs) > 0 {
|
||||
cfg.Address = httpsAddrs[0]
|
||||
if httpsAddr != "" {
|
||||
cfg.Address = httpsAddr
|
||||
cfg.Scheme = "https"
|
||||
cfg.TLSConfig.CAFile = c.CAFile
|
||||
cfg.TLSConfig.CAPath = c.CAPath
|
||||
cfg.TLSConfig.Address = httpsAddr
|
||||
if includeClientCerts {
|
||||
cfg.TLSConfig.CertFile = c.CertFile
|
||||
cfg.TLSConfig.KeyFile = c.KeyFile
|
||||
}
|
||||
} else if len(httpAddrs) > 0 {
|
||||
cfg.Address = httpAddrs[0]
|
||||
} else if httpAddr != "" {
|
||||
cfg.Address = httpAddr
|
||||
cfg.Scheme = "http"
|
||||
} else if len(unixAddrs) > 0 {
|
||||
cfg.Address = "unix://" + unixAddrs[0]
|
||||
} else if unixAddr != "" {
|
||||
cfg.Address = unixAddr
|
||||
// this should be ignored - however we are still talking http over a unix socket
|
||||
// so it makes sense to set it like this
|
||||
cfg.Scheme = "http"
|
||||
|
|
|
@ -4608,6 +4608,100 @@ func TestRuntime_APIConfigUNIX(t *testing.T) {
|
|||
require.Equal(t, "", cfg.TLSConfig.KeyFile)
|
||||
}
|
||||
|
||||
func TestRuntime_APIConfigANYAddrV4(t *testing.T) {
|
||||
rt := RuntimeConfig{
|
||||
HTTPAddrs: []net.Addr{
|
||||
&net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 5678},
|
||||
},
|
||||
Datacenter: "dc-test",
|
||||
}
|
||||
|
||||
cfg, err := rt.APIConfig(false)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, rt.Datacenter, cfg.Datacenter)
|
||||
require.Equal(t, "127.0.0.1:5678", cfg.Address)
|
||||
require.Equal(t, "http", cfg.Scheme)
|
||||
require.Equal(t, "", cfg.TLSConfig.CAFile)
|
||||
require.Equal(t, "", cfg.TLSConfig.CAPath)
|
||||
require.Equal(t, "", cfg.TLSConfig.CertFile)
|
||||
require.Equal(t, "", cfg.TLSConfig.KeyFile)
|
||||
}
|
||||
|
||||
func TestRuntime_APIConfigANYAddrV6(t *testing.T) {
|
||||
rt := RuntimeConfig{
|
||||
HTTPAddrs: []net.Addr{
|
||||
&net.TCPAddr{IP: net.ParseIP("::"), Port: 5678},
|
||||
},
|
||||
Datacenter: "dc-test",
|
||||
}
|
||||
|
||||
cfg, err := rt.APIConfig(false)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, rt.Datacenter, cfg.Datacenter)
|
||||
require.Equal(t, "[::1]:5678", cfg.Address)
|
||||
require.Equal(t, "http", cfg.Scheme)
|
||||
require.Equal(t, "", cfg.TLSConfig.CAFile)
|
||||
require.Equal(t, "", cfg.TLSConfig.CAPath)
|
||||
require.Equal(t, "", cfg.TLSConfig.CertFile)
|
||||
require.Equal(t, "", cfg.TLSConfig.KeyFile)
|
||||
}
|
||||
|
||||
func TestRuntime_ClientAddress(t *testing.T) {
|
||||
rt := RuntimeConfig{
|
||||
HTTPAddrs: []net.Addr{
|
||||
&net.TCPAddr{IP: net.ParseIP("::"), Port: 5678},
|
||||
&net.TCPAddr{IP: net.ParseIP("198.18.0.1"), Port: 5679},
|
||||
&net.UnixAddr{Name: "/var/run/foo", Net: "unix"},
|
||||
},
|
||||
HTTPSAddrs: []net.Addr{
|
||||
&net.TCPAddr{IP: net.ParseIP("::"), Port: 5688},
|
||||
&net.TCPAddr{IP: net.ParseIP("198.18.0.1"), Port: 5689},
|
||||
},
|
||||
}
|
||||
|
||||
unix, http, https := rt.ClientAddress()
|
||||
|
||||
require.Equal(t, "unix:///var/run/foo", unix)
|
||||
require.Equal(t, "198.18.0.1:5679", http)
|
||||
require.Equal(t, "198.18.0.1:5689", https)
|
||||
}
|
||||
|
||||
func TestRuntime_ClientAddressAnyV4(t *testing.T) {
|
||||
rt := RuntimeConfig{
|
||||
HTTPAddrs: []net.Addr{
|
||||
&net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 5678},
|
||||
&net.UnixAddr{Name: "/var/run/foo", Net: "unix"},
|
||||
},
|
||||
HTTPSAddrs: []net.Addr{
|
||||
&net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 5688},
|
||||
},
|
||||
}
|
||||
|
||||
unix, http, https := rt.ClientAddress()
|
||||
|
||||
require.Equal(t, "unix:///var/run/foo", unix)
|
||||
require.Equal(t, "127.0.0.1:5678", http)
|
||||
require.Equal(t, "127.0.0.1:5688", https)
|
||||
}
|
||||
|
||||
func TestRuntime_ClientAddressAnyV6(t *testing.T) {
|
||||
rt := RuntimeConfig{
|
||||
HTTPAddrs: []net.Addr{
|
||||
&net.TCPAddr{IP: net.ParseIP("::"), Port: 5678},
|
||||
&net.UnixAddr{Name: "/var/run/foo", Net: "unix"},
|
||||
},
|
||||
HTTPSAddrs: []net.Addr{
|
||||
&net.TCPAddr{IP: net.ParseIP("::"), Port: 5688},
|
||||
},
|
||||
}
|
||||
|
||||
unix, http, https := rt.ClientAddress()
|
||||
|
||||
require.Equal(t, "unix:///var/run/foo", unix)
|
||||
require.Equal(t, "[::1]:5678", http)
|
||||
require.Equal(t, "[::1]:5688", https)
|
||||
}
|
||||
|
||||
func splitIPPort(hostport string) (net.IP, int) {
|
||||
h, p, err := net.SplitHostPort(hostport)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue