Skip to content

Commit

Permalink
Added support for VAULT_PROXY_ADDR + Updated docs (#15377)
Browse files Browse the repository at this point in the history
Updated documentation to describe the behavior when supplying `VAULT_HTTP_PROXY`. Also added support for `VAULT_PROXY_ADDR` as a 'better name' for `VAULT_HTTP_PROXY`.
  • Loading branch information
peteski22 authored May 24, 2022
1 parent 88b327c commit 338fbea
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 9 deletions.
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.
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.
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

0 comments on commit 338fbea

Please sign in to comment.