From f21ab14690ac00567281e3c4158f472cbe363228 Mon Sep 17 00:00:00 2001 From: Florian Apolloner Date: Fri, 26 Mar 2021 18:16:19 +0100 Subject: [PATCH] Automatically populate `CONSUL_HTTP_ADDR` for connect native tasks in host networking mode. Fixes #10239 --- CHANGELOG.md | 1 + .../taskrunner/connect_native_hook.go | 20 +++++++ .../taskrunner/connect_native_hook_test.go | 53 +++++++++++++++- .../content/docs/upgrade/upgrade-specific.mdx | 6 ++ website/content/partials/envvars.mdx | 60 +++++++++++++++++++ 5 files changed, 138 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9022841bcc1..447f4ed949b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ BUG FIXES: IMPROVEMENTS: * cli: Update defaults for `nomad operator debug` flags `-interval` and `-server-id` to match common usage. [[GH-10121](https://github.com/hashicorp/nomad/issues/10121)] * consul/connect: Enable setting `local_bind_address` field on connect upstreams [[GH-6248](https://github.com/hashicorp/nomad/issues/6248)] + * consul/connect: Automatically populate `CONSUL_HTTP_ADDR` for connect native tasks in host networking mode. [[GH-10239](https://github.com/hashicorp/nomad/issues/10239)] * csi: Added support for jobs to request a unique volume ID per allocation. [[GH-10136](https://github.com/hashicorp/nomad/issues/10136)] * driver/docker: Added support for optional extra container labels. [[GH-9885](https://github.com/hashicorp/nomad/issues/9885)] * driver/docker: Added support for configuring default logger behavior in the client configuration. [[GH-10156](https://github.com/hashicorp/nomad/issues/10156)] diff --git a/client/allocrunner/taskrunner/connect_native_hook.go b/client/allocrunner/taskrunner/connect_native_hook.go index 4ebd2c50430..23243809bab 100644 --- a/client/allocrunner/taskrunner/connect_native_hook.go +++ b/client/allocrunner/taskrunner/connect_native_hook.go @@ -115,6 +115,7 @@ func (h *connectNativeHook) Prestart( } merge(environment, h.bridgeEnv(request.TaskEnv.EnvMap)) + merge(environment, h.hostEnv(request.TaskEnv.EnvMap)) // tls/acl setup for native task done response.Done = true @@ -225,6 +226,25 @@ func (h *connectNativeHook) bridgeEnv(env map[string]string) map[string]string { return nil } +// hostEnv creates a set of additional environment variables to be used when launching +// the connect native task. This will enable the task to communicate with Consul +// if the task is running in host network mode. +// +// Sets CONSUL_HTTP_ADDR if not already set. +func (h *connectNativeHook) hostEnv(env map[string]string) map[string]string { + if h.alloc.AllocatedResources.Shared.Networks[0].Mode != "host" { + return nil + } + + if _, exists := env["CONSUL_HTTP_ADDR"]; !exists { + return map[string]string{ + "CONSUL_HTTP_ADDR": h.consulConfig.HTTPAddr, + } + } + + return nil +} + // maybeSetSITokenEnv will set the CONSUL_HTTP_TOKEN environment variable in // the given env map, if the token is found to exist in the task's secrets // directory AND the CONSUL_HTTP_TOKEN environment variable is not already set. diff --git a/client/allocrunner/taskrunner/connect_native_hook_test.go b/client/allocrunner/taskrunner/connect_native_hook_test.go index b4e420f6a4e..6b722dee6f9 100644 --- a/client/allocrunner/taskrunner/connect_native_hook_test.go +++ b/client/allocrunner/taskrunner/connect_native_hook_test.go @@ -202,6 +202,48 @@ func TestConnectNativeHook_bridgeEnv_host(t *testing.T) { }) } +func TestConnectNativeHook_hostEnv_host(t *testing.T) { + t.Parallel() + + hook := new(connectNativeHook) + hook.alloc = mock.ConnectNativeAlloc("host") + hook.consulConfig.HTTPAddr = "http://1.2.3.4:9999" + + t.Run("consul address env not preconfigured", func(t *testing.T) { + result := hook.hostEnv(nil) + require.Equal(t, map[string]string{ + "CONSUL_HTTP_ADDR": "http://1.2.3.4:9999", + }, result) + }) + + t.Run("consul address env is preconfigured", func(t *testing.T) { + result := hook.hostEnv(map[string]string{ + "CONSUL_HTTP_ADDR": "10.1.1.1", + }) + require.Empty(t, result) + }) +} + +func TestConnectNativeHook_hostEnv_bridge(t *testing.T) { + t.Parallel() + + hook := new(connectNativeHook) + hook.alloc = mock.ConnectNativeAlloc("bridge") + hook.consulConfig.HTTPAddr = "http://1.2.3.4:9999" + + t.Run("consul address env not preconfigured", func(t *testing.T) { + result := hook.hostEnv(nil) + require.Empty(t, result) + }) + + t.Run("consul address env is preconfigured", func(t *testing.T) { + result := hook.hostEnv(map[string]string{ + "CONSUL_HTTP_ADDR": "10.1.1.1", + }) + require.Empty(t, result) + }) +} + func TestTaskRunner_ConnectNativeHook_Noop(t *testing.T) { t.Parallel() logger := testlog.HCLogger(t) @@ -231,6 +273,9 @@ func TestTaskRunner_ConnectNativeHook_Noop(t *testing.T) { // Assert the hook is Done require.True(t, response.Done) + // Assert no environment variables configured to be set + require.Empty(t, response.Env) + // Assert secrets dir is empty (no TLS config set) checkFilesInDir(t, request.TaskDir.SecretsDir, nil, @@ -292,8 +337,8 @@ func TestTaskRunner_ConnectNativeHook_Ok(t *testing.T) { // Assert the hook is Done require.True(t, response.Done) - // Assert no environment variables configured to be set - require.Empty(t, response.Env) + // Assert only CONSUL_HTTP_ADDR env variable is set + require.Equal(t, map[string]string{"CONSUL_HTTP_ADDR": testConsul.HTTPAddr}, response.Env) // Assert no secrets were written checkFilesInDir(t, request.TaskDir.SecretsDir, @@ -443,6 +488,9 @@ func TestTaskRunner_ConnectNativeHook_shareTLS(t *testing.T) { // Assert the hook is Done require.True(t, response.Done) + // Remove variables we are not interested in + delete(response.Env, "CONSUL_HTTP_ADDR") + // Assert environment variable for token is set require.NotEmpty(t, response.Env) require.Equal(t, map[string]string{ @@ -550,6 +598,7 @@ func TestTaskRunner_ConnectNativeHook_shareTLS_override(t *testing.T) { "CONSUL_CLIENT_KEY": "/foo/key.pem", "CONSUL_HTTP_AUTH": "foo:bar", "CONSUL_HTTP_SSL_VERIFY": "false", + "CONSUL_HTTP_ADDR": "localhost:8500", // CONSUL_HTTP_SSL (check the default value is assumed from client config) } diff --git a/website/content/docs/upgrade/upgrade-specific.mdx b/website/content/docs/upgrade/upgrade-specific.mdx index fee5a538a01..c6df2edc960 100644 --- a/website/content/docs/upgrade/upgrade-specific.mdx +++ b/website/content/docs/upgrade/upgrade-specific.mdx @@ -23,6 +23,12 @@ The Nomad agent metrics API now respects the configuration value. If this value is set to `false`, which is the default value, calling `/v1/metrics?format=prometheus` will now result in a response error. +#### Connect native tasks + +Connect native tasks running in host networking mode will now have `CONSUL_HTTP_ADDR` +set automatically. Before this was only the case for bridge networking. If an operator +already explicitly set `CONSUL_HTTP_ADDR` then it will not get overriden. + ## Nomad 1.0.3, 0.12.10 Nomad versions 1.0.3 and 0.12.10 change the behavior of the `exec` and `java` drivers so that diff --git a/website/content/partials/envvars.mdx b/website/content/partials/envvars.mdx index 83c3c44a529..6ef8efe9951 100644 --- a/website/content/partials/envvars.mdx +++ b/website/content/partials/envvars.mdx @@ -260,5 +260,65 @@ Consul Connect enabled service. + + Consul-related Variables (only set for connect native tasks) + + + + CONSUL_HTTP_ADDR + + + Specifies the address to the local Consul agent, will be a unix domain + socket in bridge mode and a tcp address in host networking. + + + + + CONSUL_HTTP_TOKEN + + + The token to authenticate against consul. + + + + + CONSUL_HTTP_SSL + + + Specifies whether HTTPS should be used when communicating with consul. + + + + + CONSUL_HTTP_SSL_VERIFY + + + Specifies whether the HTTPS connection should be verified. + + + + + CONSUL_CACERT + + + Specifies the path to the CA certificate used for Consul communication. + + + + + CONSUL_CLIENT_CERT + + + The client certificate to use when communicating with Consul. + + + + + CONSUL_CLIENT_KEY + + + The client key to use when communicating with Consul. + +