diff options
Diffstat (limited to 'vendor/github.com/hashicorp/vault/api/client.go')
-rw-r--r-- | vendor/github.com/hashicorp/vault/api/client.go | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/vendor/github.com/hashicorp/vault/api/client.go b/vendor/github.com/hashicorp/vault/api/client.go index 5f8a6f6..0204cec 100644 --- a/vendor/github.com/hashicorp/vault/api/client.go +++ b/vendor/github.com/hashicorp/vault/api/client.go @@ -3,9 +3,11 @@ package api import ( "crypto/tls" "fmt" + "net" "net/http" "net/url" "os" + "path" "strconv" "strings" "sync" @@ -15,6 +17,7 @@ import ( "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-rootcerts" + "github.com/hashicorp/vault/helper/parseutil" "github.com/sethgrid/pester" ) @@ -23,6 +26,7 @@ const EnvVaultCACert = "VAULT_CACERT" const EnvVaultCAPath = "VAULT_CAPATH" const EnvVaultClientCert = "VAULT_CLIENT_CERT" const EnvVaultClientKey = "VAULT_CLIENT_KEY" +const EnvVaultClientTimeout = "VAULT_CLIENT_TIMEOUT" const EnvVaultInsecure = "VAULT_SKIP_VERIFY" const EnvVaultTLSServerName = "VAULT_TLS_SERVER_NAME" const EnvVaultWrapTTL = "VAULT_WRAP_TTL" @@ -53,6 +57,9 @@ type Config struct { // MaxRetries controls the maximum number of times to retry when a 5xx error // occurs. Set to 0 or less to disable retrying. Defaults to 0. MaxRetries int + + // Timeout is for setting custom timeout parameter in the HttpClient + Timeout time.Duration } // TLSConfig contains the parameters needed to configure TLS on the HTTP client @@ -155,6 +162,7 @@ func (c *Config) ReadEnvironment() error { var envCAPath string var envClientCert string var envClientKey string + var envClientTimeout time.Duration var envInsecure bool var envTLSServerName string var envMaxRetries *uint64 @@ -182,6 +190,13 @@ func (c *Config) ReadEnvironment() error { if v := os.Getenv(EnvVaultClientKey); v != "" { envClientKey = v } + if t := os.Getenv(EnvVaultClientTimeout); t != "" { + clientTimeout, err := parseutil.ParseDurationSecond(t) + if err != nil { + return fmt.Errorf("Could not parse %s", EnvVaultClientTimeout) + } + envClientTimeout = clientTimeout + } if v := os.Getenv(EnvVaultInsecure); v != "" { var err error envInsecure, err = strconv.ParseBool(v) @@ -214,6 +229,10 @@ func (c *Config) ReadEnvironment() error { c.MaxRetries = int(*envMaxRetries) + 1 } + if envClientTimeout != 0 { + c.Timeout = envClientTimeout + } + return nil } @@ -223,6 +242,7 @@ type Client struct { addr *url.URL config *Config token string + headers http.Header wrappingLookupFunc WrappingLookupFunc } @@ -247,10 +267,14 @@ func NewClient(c *Config) (*Client, error) { if c.HttpClient == nil { c.HttpClient = DefaultConfig().HttpClient } + if c.HttpClient.Transport == nil { + c.HttpClient.Transport = cleanhttp.DefaultTransport() + } - tp := c.HttpClient.Transport.(*http.Transport) - if err := http2.ConfigureTransport(tp); err != nil { - return nil, err + if tp, ok := c.HttpClient.Transport.(*http.Transport); ok { + if err := http2.ConfigureTransport(tp); err != nil { + return nil, err + } } redirFunc := func() { @@ -303,6 +327,11 @@ func (c *Client) SetMaxRetries(retries int) { c.config.MaxRetries = retries } +// SetClientTimeout sets the client request timeout +func (c *Client) SetClientTimeout(timeout time.Duration) { + c.config.Timeout = timeout +} + // SetWrappingLookupFunc sets a lookup function that returns desired wrap TTLs // for a given operation and path func (c *Client) SetWrappingLookupFunc(lookupFunc WrappingLookupFunc) { @@ -326,17 +355,38 @@ func (c *Client) ClearToken() { c.token = "" } +// SetHeaders sets the headers to be used for future requests. +func (c *Client) SetHeaders(headers http.Header) { + c.headers = headers +} + +// Clone creates a copy of this client. +func (c *Client) Clone() (*Client, error) { + return NewClient(c.config) +} + // NewRequest creates a new raw request object to query the Vault server // configured for this client. This is an advanced method and generally // doesn't need to be called externally. -func (c *Client) NewRequest(method, path string) *Request { +func (c *Client) NewRequest(method, requestPath string) *Request { + // if SRV records exist (see https://tools.ietf.org/html/draft-andrews-http-srv-02), lookup the SRV + // record and take the highest match; this is not designed for high-availability, just discovery + var host string = c.addr.Host + if c.addr.Port() == "" { + // Internet Draft specifies that the SRV record is ignored if a port is given + _, addrs, err := net.LookupSRV("http", "tcp", c.addr.Hostname()) + if err == nil && len(addrs) > 0 { + host = fmt.Sprintf("%s:%d", addrs[0].Target, addrs[0].Port) + } + } + req := &Request{ Method: method, URL: &url.URL{ User: c.addr.User, Scheme: c.addr.Scheme, - Host: c.addr.Host, - Path: path, + Host: host, + Path: path.Join(c.addr.Path, requestPath), }, ClientToken: c.token, Params: make(map[string][]string), @@ -344,18 +394,24 @@ func (c *Client) NewRequest(method, path string) *Request { var lookupPath string switch { - case strings.HasPrefix(path, "/v1/"): - lookupPath = strings.TrimPrefix(path, "/v1/") - case strings.HasPrefix(path, "v1/"): - lookupPath = strings.TrimPrefix(path, "v1/") + case strings.HasPrefix(requestPath, "/v1/"): + lookupPath = strings.TrimPrefix(requestPath, "/v1/") + case strings.HasPrefix(requestPath, "v1/"): + lookupPath = strings.TrimPrefix(requestPath, "v1/") default: - lookupPath = path + lookupPath = requestPath } if c.wrappingLookupFunc != nil { req.WrapTTL = c.wrappingLookupFunc(method, lookupPath) } else { req.WrapTTL = DefaultWrappingLookupFunc(method, lookupPath) } + if c.config.Timeout != 0 { + c.config.HttpClient.Timeout = c.config.Timeout + } + if c.headers != nil { + req.Headers = c.headers + } return req } |