From bbbd80efd969293baa96d13aff2da95a1b52c9e0 Mon Sep 17 00:00:00 2001 From: Seth Hoenig Date: Tue, 5 Jan 2021 09:27:01 -0600 Subject: [PATCH] consul/connect: avoid NPE from unset connect gateway proxy Submitting a job with an ingress gateway in host networking mode with an absent gateway.proxy block would cause the Nomad client to panic on NPE. The consul registration bits would assume the proxy stanza was not nil, but it could be if the user does not supply any manually configured envoy proxy settings. Check the proxy field is not nil before using it. Fixes #9669 --- command/agent/consul/connect.go | 38 +++++++++++++++------------- command/agent/consul/connect_test.go | 11 ++++++++ nomad/structs/services.go | 1 + 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/command/agent/consul/connect.go b/command/agent/consul/connect.go index 62049241bcf1..1fcf3f568bc5 100644 --- a/command/agent/consul/connect.go +++ b/command/agent/consul/connect.go @@ -45,29 +45,33 @@ func newConnectGateway(serviceName string, connect *structs.ConsulConnect) *api. return nil } - proxy := connect.Gateway.Proxy + var envoyConfig map[string]interface{} - envoyConfig := make(map[string]interface{}) + // Populate the envoy configuration from the gateway.proxy stanza, if + // such configuration is provided. + if proxy := connect.Gateway.Proxy; proxy != nil { + envoyConfig = make(map[string]interface{}) - if len(proxy.EnvoyGatewayBindAddresses) > 0 { - envoyConfig["envoy_gateway_bind_addresses"] = proxy.EnvoyGatewayBindAddresses - } + if len(proxy.EnvoyGatewayBindAddresses) > 0 { + envoyConfig["envoy_gateway_bind_addresses"] = proxy.EnvoyGatewayBindAddresses + } - if proxy.EnvoyGatewayNoDefaultBind { - envoyConfig["envoy_gateway_no_default_bind"] = true - } + if proxy.EnvoyGatewayNoDefaultBind { + envoyConfig["envoy_gateway_no_default_bind"] = true + } - if proxy.EnvoyGatewayBindTaggedAddresses { - envoyConfig["envoy_gateway_bind_tagged_addresses"] = true - } + if proxy.EnvoyGatewayBindTaggedAddresses { + envoyConfig["envoy_gateway_bind_tagged_addresses"] = true + } - if proxy.ConnectTimeout != nil { - envoyConfig["connect_timeout_ms"] = proxy.ConnectTimeout.Milliseconds() - } + if proxy.ConnectTimeout != nil { + envoyConfig["connect_timeout_ms"] = proxy.ConnectTimeout.Milliseconds() + } - if len(proxy.Config) > 0 { - for k, v := range proxy.Config { - envoyConfig[k] = v + if len(proxy.Config) > 0 { + for k, v := range proxy.Config { + envoyConfig[k] = v + } } } diff --git a/command/agent/consul/connect_test.go b/command/agent/consul/connect_test.go index ea1728bda384..e3d08d3e97ab 100644 --- a/command/agent/consul/connect_test.go +++ b/command/agent/consul/connect_test.go @@ -429,6 +429,17 @@ func TestConnect_newConnectGateway(t *testing.T) { }, result) }) + t.Run("proxy undefined", func(t *testing.T) { + result := newConnectGateway("s1", &structs.ConsulConnect{ + Gateway: &structs.ConsulGateway{ + Proxy: nil, + }, + }) + require.Equal(t, &api.AgentServiceConnectProxyConfig{ + Config: nil, + }, result) + }) + t.Run("full", func(t *testing.T) { result := newConnectGateway("s1", &structs.ConsulConnect{ Gateway: &structs.ConsulGateway{ diff --git a/nomad/structs/services.go b/nomad/structs/services.go index 9d7d9152c3e3..2ca1dd81f2d6 100644 --- a/nomad/structs/services.go +++ b/nomad/structs/services.go @@ -733,6 +733,7 @@ func (c *ConsulConnect) IsNative() bool { return c != nil && c.Native } +// IsGateway checks if the service is a Connect gateway. func (c *ConsulConnect) IsGateway() bool { return c != nil && c.Gateway != nil }