From ef0cddce8a8c1e215b9fa7d35e76321ce587778d Mon Sep 17 00:00:00 2001 From: Dave Du Cros Date: Fri, 10 Sep 2021 15:31:02 +0100 Subject: [PATCH 1/6] patch to support VAULT_HTTP_PROXY variable --- api/client.go | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/api/client.go b/api/client.go index 9b7129ceb0832..c835568ec5ed4 100644 --- a/api/client.go +++ b/api/client.go @@ -42,6 +42,7 @@ const ( EnvVaultToken = "VAULT_TOKEN" EnvVaultMFA = "VAULT_MFA" EnvRateLimit = "VAULT_RATE_LIMIT" + EnvHttpProxy = "VAULT_HTTP_PROXY" ) // Deprecated values @@ -79,6 +80,8 @@ type Config struct { // (or http.DefaultClient). HttpClient *http.Client + HttpProxy string + // MinRetryWait controls the minimum time to wait before retrying when a 5xx // error occurs. Defaults to 1000 milliseconds. MinRetryWait time.Duration @@ -173,6 +176,25 @@ func DefaultConfig() *Config { Backoff: retryablehttp.LinearJitterBackoff, } + if err := config.ReadEnvironment(); err != nil { + config.Error = err + return config + } + + if config.HttpProxy != "" { + url, err := url.Parse(config.HttpProxy) + if err != nil { + config.Error = err + return config + } + + proxied_transport := cleanhttp.DefaultPooledTransport() + proxied_transport.Proxy = http.ProxyURL(url) + config.HttpClient = &http.Client{ + Transport: proxied_transport, + } + } + transport := config.HttpClient.Transport.(*http.Transport) transport.TLSHandshakeTimeout = 10 * time.Second transport.TLSClientConfig = &tls.Config{ @@ -183,11 +205,6 @@ func DefaultConfig() *Config { return config } - if err := config.ReadEnvironment(); err != nil { - config.Error = err - return config - } - // Ensure redirects are not automatically followed // Note that this is sane for the API client as it has its own // redirect handling logic (and thus also for command/meta), @@ -271,6 +288,7 @@ func (c *Config) ReadEnvironment() error { var envMaxRetries *uint64 var envSRVLookup bool var limit *rate.Limiter + var envHttpProxy string // Parse the environment variables if v := os.Getenv(EnvVaultAddress); v != "" { @@ -339,6 +357,10 @@ func (c *Config) ReadEnvironment() error { envTLSServerName = v } + if v := os.Getenv(EnvHttpProxy); v != "" { + envHttpProxy = v + } + // Configure the HTTP clients TLS configuration. t := &TLSConfig{ CACert: envCACert, @@ -375,6 +397,10 @@ func (c *Config) ReadEnvironment() error { c.Timeout = envClientTimeout } + if envHttpProxy != "" { + c.HttpProxy = envHttpProxy + } + return nil } From c3215ad832a9abfdca9000802ae2136559a4c77c Mon Sep 17 00:00:00 2001 From: Dave Du Cros Date: Wed, 22 Sep 2021 14:36:19 +0100 Subject: [PATCH 2/6] simplify the proxy replacement --- api/client.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/api/client.go b/api/client.go index c835568ec5ed4..d5318f34bb605 100644 --- a/api/client.go +++ b/api/client.go @@ -80,6 +80,10 @@ type Config struct { // (or http.DefaultClient). HttpClient *http.Client + // HTTP proxy needed to access this Vault server. If present this will + // override any proxy picked up from the HTTP{,S}_PROXY environment + // variables. This should be a complete URL + port such as + // "http://proxy.example.com:99". HttpProxy string // MinRetryWait controls the minimum time to wait before retrying when a 5xx @@ -181,6 +185,8 @@ func DefaultConfig() *Config { return config } + transport := config.HttpClient.Transport.(*http.Transport) + if config.HttpProxy != "" { url, err := url.Parse(config.HttpProxy) if err != nil { @@ -188,14 +194,9 @@ func DefaultConfig() *Config { return config } - proxied_transport := cleanhttp.DefaultPooledTransport() - proxied_transport.Proxy = http.ProxyURL(url) - config.HttpClient = &http.Client{ - Transport: proxied_transport, - } + transport.Proxy = http.ProxyURL(url) } - transport := config.HttpClient.Transport.(*http.Transport) transport.TLSHandshakeTimeout = 10 * time.Second transport.TLSClientConfig = &tls.Config{ MinVersion: tls.VersionTLS12, From fa82635c8ef80481cca3b131613281cd040f4d15 Mon Sep 17 00:00:00 2001 From: Dave Du Cros Date: Thu, 23 Sep 2021 12:32:55 +0100 Subject: [PATCH 3/6] internal code review --- api/client.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api/client.go b/api/client.go index d5318f34bb605..555e95ae9ae31 100644 --- a/api/client.go +++ b/api/client.go @@ -42,7 +42,7 @@ const ( EnvVaultToken = "VAULT_TOKEN" EnvVaultMFA = "VAULT_MFA" EnvRateLimit = "VAULT_RATE_LIMIT" - EnvHttpProxy = "VAULT_HTTP_PROXY" + EnvHTTPSProxy = "VAULT_HTTPS_PROXY" ) // Deprecated values @@ -289,7 +289,7 @@ func (c *Config) ReadEnvironment() error { var envMaxRetries *uint64 var envSRVLookup bool var limit *rate.Limiter - var envHttpProxy string + var envHTTPSProxy string // Parse the environment variables if v := os.Getenv(EnvVaultAddress); v != "" { @@ -358,8 +358,8 @@ func (c *Config) ReadEnvironment() error { envTLSServerName = v } - if v := os.Getenv(EnvHttpProxy); v != "" { - envHttpProxy = v + if v := os.Getenv(EnvHTTPSProxy); v != "" { + envHTTPSProxy = v } // Configure the HTTP clients TLS configuration. @@ -398,8 +398,8 @@ func (c *Config) ReadEnvironment() error { c.Timeout = envClientTimeout } - if envHttpProxy != "" { - c.HttpProxy = envHttpProxy + if envHTTPSProxy != "" { + c.HttpProxy = envHTTPSProxy } return nil From 003d18a0808fe4c0ae29d42a0722b8c95dd0f521 Mon Sep 17 00:00:00 2001 From: Dave Du Cros Date: Tue, 5 Oct 2021 12:50:52 +0100 Subject: [PATCH 4/6] rename to VAULT_HTTP_PROXY, apply within ReadEnvironment --- api/client.go | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/api/client.go b/api/client.go index 555e95ae9ae31..c380919e3065a 100644 --- a/api/client.go +++ b/api/client.go @@ -42,7 +42,7 @@ const ( EnvVaultToken = "VAULT_TOKEN" EnvVaultMFA = "VAULT_MFA" EnvRateLimit = "VAULT_RATE_LIMIT" - EnvHTTPSProxy = "VAULT_HTTPS_PROXY" + EnvHTTPProxy = "VAULT_HTTP_PROXY" ) // Deprecated values @@ -80,12 +80,6 @@ type Config struct { // (or http.DefaultClient). HttpClient *http.Client - // HTTP proxy needed to access this Vault server. If present this will - // override any proxy picked up from the HTTP{,S}_PROXY environment - // variables. This should be a complete URL + port such as - // "http://proxy.example.com:99". - HttpProxy string - // MinRetryWait controls the minimum time to wait before retrying when a 5xx // error occurs. Defaults to 1000 milliseconds. MinRetryWait time.Duration @@ -180,23 +174,8 @@ func DefaultConfig() *Config { Backoff: retryablehttp.LinearJitterBackoff, } - if err := config.ReadEnvironment(); err != nil { - config.Error = err - return config - } - transport := config.HttpClient.Transport.(*http.Transport) - if config.HttpProxy != "" { - url, err := url.Parse(config.HttpProxy) - if err != nil { - config.Error = err - return config - } - - transport.Proxy = http.ProxyURL(url) - } - transport.TLSHandshakeTimeout = 10 * time.Second transport.TLSClientConfig = &tls.Config{ MinVersion: tls.VersionTLS12, @@ -206,6 +185,11 @@ func DefaultConfig() *Config { return config } + if err := config.ReadEnvironment(); err != nil { + config.Error = err + return config + } + // Ensure redirects are not automatically followed // Note that this is sane for the API client as it has its own // redirect handling logic (and thus also for command/meta), @@ -289,7 +273,7 @@ func (c *Config) ReadEnvironment() error { var envMaxRetries *uint64 var envSRVLookup bool var limit *rate.Limiter - var envHTTPSProxy string + var envHTTPProxy string // Parse the environment variables if v := os.Getenv(EnvVaultAddress); v != "" { @@ -358,8 +342,8 @@ func (c *Config) ReadEnvironment() error { envTLSServerName = v } - if v := os.Getenv(EnvHTTPSProxy); v != "" { - envHTTPSProxy = v + if v := os.Getenv(EnvHTTPProxy); v != "" { + envHTTPProxy = v } // Configure the HTTP clients TLS configuration. @@ -398,8 +382,14 @@ func (c *Config) ReadEnvironment() error { c.Timeout = envClientTimeout } - if envHTTPSProxy != "" { - c.HttpProxy = envHTTPSProxy + if envHTTPProxy != "" { + url, err := url.Parse(envHTTPProxy) + if err != nil { + return err + } + + transport := c.HttpClient.Transport.(*http.Transport) + transport.Proxy = http.ProxyURL(url) } return nil From 47a73b7df95d70da668eacfc1144775dcbc811d0 Mon Sep 17 00:00:00 2001 From: Dave Du Cros Date: Tue, 5 Oct 2021 13:04:20 +0100 Subject: [PATCH 5/6] clean up some unintended whitespace changes --- api/client.go | 1 - 1 file changed, 1 deletion(-) diff --git a/api/client.go b/api/client.go index c380919e3065a..df8cfa551bd8c 100644 --- a/api/client.go +++ b/api/client.go @@ -175,7 +175,6 @@ func DefaultConfig() *Config { } transport := config.HttpClient.Transport.(*http.Transport) - transport.TLSHandshakeTimeout = 10 * time.Second transport.TLSClientConfig = &tls.Config{ MinVersion: tls.VersionTLS12, From 7c10fcd590ecff2c837f27b6c5976e8ac8cdbbe2 Mon Sep 17 00:00:00 2001 From: Dave Du Cros Date: Tue, 5 Oct 2021 13:40:26 +0100 Subject: [PATCH 6/6] add docs for the new env variable and a changelog entry --- changelog/12582.txt | 3 +++ website/content/docs/commands/index.mdx | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 changelog/12582.txt diff --git a/changelog/12582.txt b/changelog/12582.txt new file mode 100644 index 0000000000000..6e5c0c916fa59 --- /dev/null +++ b/changelog/12582.txt @@ -0,0 +1,3 @@ +```release-note:improvement +api: Support VAULT_HTTP_PROXY environment variable to allow overriding the Vault client's HTTP proxy +``` diff --git a/website/content/docs/commands/index.mdx b/website/content/docs/commands/index.mdx index 9927152503c8a..cefdeeed82997 100644 --- a/website/content/docs/commands/index.mdx +++ b/website/content/docs/commands/index.mdx @@ -323,6 +323,12 @@ can be supplied. If a MFA method expects multiple credential values, or if there are multiple MFA methods specified on a path, then the CLI flag `-mfa` should be used. +### `VAULT_HTTP_PROXY` + +HTTP proxy location which should be used to access Vault. When present, this +overrides any other proxies found in the environment. Format should be +`http://server:port`. + ## Flags There are different CLI flags that are available depending on subcommands. Some