From c67a0548a0d2b6a804e4043dcc26ad0cb7f1c4a5 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Sternberg" Date: Sun, 11 Feb 2018 21:11:23 -0600 Subject: [PATCH] Support proxy environment variables in the influx client This also adds support for both the v1 and v2 APIs to set the Proxy function on the underlying http.Transport. The functionality for proxy environment variables is provided by the [http.ProxyFromEnvironment](https://godoc.org/net/http#ProxyFromEnvironment). --- client/influxdb.go | 2 ++ client/influxdb_test.go | 31 +++++++++++++++++++++++++++++++ client/v2/client.go | 4 ++++ client/v2/client_test.go | 25 +++++++++++++++++++++++++ cmd/influx/cli/cli.go | 2 ++ man/influx.txt | 13 +++++++++++++ 6 files changed, 77 insertions(+) diff --git a/client/influxdb.go b/client/influxdb.go index aa0292255b5..b09e2fcf37d 100644 --- a/client/influxdb.go +++ b/client/influxdb.go @@ -113,6 +113,7 @@ type Config struct { Precision string WriteConsistency string UnsafeSsl bool + Proxy func(req *http.Request) (*url.URL, error) } // NewConfig will create a config to be used in connecting to the client @@ -154,6 +155,7 @@ func NewClient(c Config) (*Client, error) { } tr := &http.Transport{ + Proxy: c.Proxy, TLSClientConfig: tlsConfig, } diff --git a/client/influxdb_test.go b/client/influxdb_test.go index a65c3b1068b..e78fecf2688 100644 --- a/client/influxdb_test.go +++ b/client/influxdb_test.go @@ -957,3 +957,34 @@ func TestChunkedResponse(t *testing.T) { t.Fatalf("unexpected response. expected %v, actual %v", nil, resp) } } + +func TestClient_Proxy(t *testing.T) { + pinged := false + server := httptest.NewServer(http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + if got, want := req.URL.String(), "http://example.com:8086/ping"; got != want { + t.Errorf("invalid url in request: got=%s want=%s", got, want) + } + resp.WriteHeader(http.StatusNoContent) + pinged = true + })) + defer server.Close() + + proxyURL, _ := url.Parse(server.URL) + c, err := client.NewClient(client.Config{ + URL: url.URL{ + Scheme: "http", + Host: "example.com:8086", + }, + Proxy: http.ProxyURL(proxyURL), + }) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if _, _, err := c.Ping(); err != nil { + t.Fatalf("could not ping server: %s", err) + } + + if !pinged { + t.Fatalf("no http request was received") + } +} diff --git a/client/v2/client.go b/client/v2/client.go index 6c2c56a114a..1696e091902 100644 --- a/client/v2/client.go +++ b/client/v2/client.go @@ -45,6 +45,9 @@ type HTTPConfig struct { // TLSConfig allows the user to set their own TLS config for the HTTP // Client. If set, this option overrides InsecureSkipVerify. TLSConfig *tls.Config + + // Proxy configures the Proxy function on the HTTP client. + Proxy func(req *http.Request) (*url.URL, error) } // BatchPointsConfig is the config data needed to create an instance of the BatchPoints struct. @@ -99,6 +102,7 @@ func NewHTTPClient(conf HTTPConfig) (Client, error) { TLSClientConfig: &tls.Config{ InsecureSkipVerify: conf.InsecureSkipVerify, }, + Proxy: conf.Proxy, } if conf.TLSConfig != nil { tr.TLSClientConfig = conf.TLSConfig diff --git a/client/v2/client_test.go b/client/v2/client_test.go index 8d6ab345394..119f23922a6 100644 --- a/client/v2/client_test.go +++ b/client/v2/client_test.go @@ -859,3 +859,28 @@ func TestClientConcatURLPath(t *testing.T) { t.Errorf("unexpected error. expected %v, actual %v", nil, err) } } + +func TestClientProxy(t *testing.T) { + pinged := false + ts := httptest.NewServer(http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + if got, want := req.URL.String(), "http://example.com:8086/ping"; got != want { + t.Errorf("invalid url in request: got=%s want=%s", got, want) + } + resp.WriteHeader(http.StatusNoContent) + pinged = true + })) + defer ts.Close() + + proxyURL, _ := url.Parse(ts.URL) + c, _ := NewHTTPClient(HTTPConfig{ + Addr: "http://example.com:8086", + Proxy: http.ProxyURL(proxyURL), + }) + if _, _, err := c.Ping(0); err != nil { + t.Fatalf("could not ping server: %s", err) + } + + if !pinged { + t.Fatalf("no http request was received") + } +} diff --git a/cmd/influx/cli/cli.go b/cmd/influx/cli/cli.go index 7d444f118ee..b0026efeca0 100644 --- a/cmd/influx/cli/cli.go +++ b/cmd/influx/cli/cli.go @@ -11,6 +11,7 @@ import ( "io" "io/ioutil" "net" + "net/http" "os" "os/signal" "path/filepath" @@ -333,6 +334,7 @@ func (c *CommandLine) Connect(cmd string) error { ClientConfig := c.ClientConfig ClientConfig.UserAgent = "InfluxDBShell/" + c.ClientVersion ClientConfig.URL = URL + ClientConfig.Proxy = http.ProxyFromEnvironment client, err := client.NewClient(ClientConfig) if err != nil { diff --git a/man/influx.txt b/man/influx.txt index 3a0bb629710..66e556d736d 100644 --- a/man/influx.txt +++ b/man/influx.txt @@ -81,4 +81,17 @@ OPTIONS -version:: Outputs the version of the influx client. +ENVIRONMENT +----------- +The environment variables can be specified in lower case or upper case. The upper case version has precedence. + +HTTP_PROXY [protocol://][:port]:: + Sets the proxy server to use for HTTP. + +HTTPS_PROXY [protocol://][:port]:: + Sets the proxy server to use for HTTPS. Takes precedence over HTTP_PROXY for HTTPS. + +NO_PROXY :: + List of host names that shouldn't go through any proxy. If set to an asterisk \'*' only, it matches all hosts. + include::footer.txt[]