Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for VAULT_PROXY_ADDR + Updated docs #15377

Merged
merged 11 commits into from
May 24, 2022
16 changes: 11 additions & 5 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const (
EnvVaultMFA = "VAULT_MFA"
EnvRateLimit = "VAULT_RATE_LIMIT"
EnvHTTPProxy = "VAULT_HTTP_PROXY"
EnvVaultProxyAddr = "VAULT_PROXY_ADDR"
HeaderIndex = "X-Vault-Index"
HeaderForward = "X-Vault-Forward"
HeaderInconsistent = "X-Vault-Inconsistent"
Expand Down Expand Up @@ -338,7 +339,7 @@ func (c *Config) ReadEnvironment() error {
var envMaxRetries *uint64
var envSRVLookup bool
var limit *rate.Limiter
var envHTTPProxy string
var envVaultProxy string

// Parse the environment variables
if v := os.Getenv(EnvVaultAddress); v != "" {
Expand Down Expand Up @@ -411,7 +412,12 @@ func (c *Config) ReadEnvironment() error {
}

if v := os.Getenv(EnvHTTPProxy); v != "" {
envHTTPProxy = v
envVaultProxy = v
}

// VAULT_PROXY_ADDR supersedes VAULT_HTTP_PROXY
if v := os.Getenv(EnvVaultProxyAddr); v != "" {
envVaultProxy = v
}

// Configure the HTTP clients TLS configuration.
Expand Down Expand Up @@ -451,14 +457,14 @@ func (c *Config) ReadEnvironment() error {
c.Timeout = envClientTimeout
}

if envHTTPProxy != "" {
url, err := url.Parse(envHTTPProxy)
if envVaultProxy != "" {
u, err := url.Parse(envVaultProxy)
if err != nil {
return err
}

transport := c.HttpClient.Transport.(*http.Transport)
transport.Proxy = http.ProxyURL(url)
transport.Proxy = http.ProxyURL(u)
}

return nil
Expand Down
85 changes: 84 additions & 1 deletion api/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (

"github.com/go-test/deep"
"github.com/hashicorp/go-hclog"

"github.com/hashicorp/vault/sdk/helper/consts"
)

Expand Down Expand Up @@ -1201,3 +1200,87 @@ func TestClientWithNamespace(t *testing.T) {
t.Fatalf("Expected original namespace: \"%s\", got \"%s\"", ogNS, client.Namespace())
}
}

func TestVaultProxy(t *testing.T) {
const NoProxy string = "NO_PROXY"

tests := map[string]struct {
name string
vaultHttpProxy string
vaultProxyAddr string
noProxy string
requestUrl string
expectedResolvedProxyUrl string
}{
"VAULT_HTTP_PROXY used when NO_PROXY env var doesn't include request host": {
vaultHttpProxy: "https://hashicorp.com",
vaultProxyAddr: "",
noProxy: "terraform.io",
requestUrl: "https://vaultproject.io",
},
"VAULT_HTTP_PROXY used when NO_PROXY env var includes request host": {
vaultHttpProxy: "https://hashicorp.com",
vaultProxyAddr: "",
noProxy: "terraform.io,vaultproject.io",
requestUrl: "https://vaultproject.io",
},
"VAULT_PROXY_ADDR used when NO_PROXY env var doesn't include request host": {
vaultHttpProxy: "",
vaultProxyAddr: "https://hashicorp.com",
noProxy: "terraform.io",
requestUrl: "https://vaultproject.io",
},
"VAULT_PROXY_ADDR used when NO_PROXY env var includes request host": {
vaultHttpProxy: "",
vaultProxyAddr: "https://hashicorp.com",
noProxy: "terraform.io,vaultproject.io",
requestUrl: "https://vaultproject.io",
},
"VAULT_PROXY_ADDR used when VAULT_HTTP_PROXY env var also supplied": {
vaultHttpProxy: "https://hashicorp.com",
vaultProxyAddr: "https://terraform.io",
noProxy: "",
requestUrl: "https://vaultproject.io",
expectedResolvedProxyUrl: "https://terraform.io",
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
if tc.vaultHttpProxy != "" {
oldVaultHttpProxy := os.Getenv(EnvHTTPProxy)
os.Setenv(EnvHTTPProxy, tc.vaultHttpProxy)
defer os.Setenv(EnvHTTPProxy, oldVaultHttpProxy)
}

if tc.vaultProxyAddr != "" {
oldVaultProxyAddr := os.Getenv(EnvVaultProxyAddr)
os.Setenv(EnvVaultProxyAddr, tc.vaultProxyAddr)
defer os.Setenv(EnvVaultProxyAddr, oldVaultProxyAddr)
}

if tc.noProxy != "" {
oldNoProxy := os.Getenv(NoProxy)
os.Setenv(NoProxy, tc.noProxy)
defer os.Setenv(NoProxy, oldNoProxy)
}

c := DefaultConfig()
if c.Error != nil {
t.Fatalf("Expected no error reading config, found error %v", c.Error)
}

r, _ := http.NewRequest("GET", tc.requestUrl, nil)
proxyUrl, err := c.HttpClient.Transport.(*http.Transport).Proxy(r)
if err != nil {
t.Fatalf("Expected no error resolving proxy, found error %v", err)
}
if proxyUrl == nil || proxyUrl.String() == "" {
t.Fatalf("Expected proxy to be resolved but no proxy returned")
}
if tc.expectedResolvedProxyUrl != "" && proxyUrl.String() != tc.expectedResolvedProxyUrl {
t.Fatalf("Expected resolved proxy URL to be %v but was %v", tc.expectedResolvedProxyUrl, proxyUrl.String())
}
})
}
}
3 changes: 3 additions & 0 deletions changelog/15377.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
api: Support VAULT_PROXY_ADDR environment variable to allow overriding the Vault client's HTTP proxy.
```
23 changes: 20 additions & 3 deletions website/content/docs/commands/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,26 @@ 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`.
HTTP or HTTPS proxy location which should be used by all requests to access Vault.
peteski22 marked this conversation as resolved.
Show resolved Hide resolved
When present, this overrides the default proxy resolution behavior.
Format should be `http://server:port` or `https://server:port`.

(See `VAULT_PROXY_ADDR` below).

### `VAULT_PROXY_ADDR`

HTTP or HTTPS proxy location which should be used by all requests to access Vault.
peteski22 marked this conversation as resolved.
Show resolved Hide resolved
When present, this overrides the default proxy resolution behavior.
Format should be `http://server:port` or `https://server:port`.

~> Note: When using `VAULT_HTTP_PROXY` or `VAULT_PROXY_ADDR` any of the standard
proxy variables found in the environment will be ignored.
Specifically `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY`.
All requests will resolve the specified proxy; there is no way to exclude
domains from consulting the proxy server.

~> Note: If both `VAULT_HTTP_PROXY` and `VAULT_PROXY_ADDR` environment
variables are supplied, `VAULT_PROXY_ADDR` will be prioritized and preferred.

## Flags

Expand Down