func (c *Client) Token() string {
	return c.token
}
Token returns the access token being used by this client. It will
return the empty string if there is no token set.
package api
import (
	"crypto/tls"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"
	"github.com/hashicorp/go-cleanhttp"
	"github.com/hashicorp/go-rootcerts"
	"github.com/sethgrid/pester"
)
const EnvVaultAddress = "VAULT_ADDR"
const EnvVaultCACert = "VAULT_CACERT"
const EnvVaultCAPath = "VAULT_CAPATH"
const EnvVaultClientCert = "VAULT_CLIENT_CERT"
const EnvVaultClientKey = "VAULT_CLIENT_KEY"
const EnvVaultInsecure = "VAULT_SKIP_VERIFY"
const EnvVaultTLSServerName = "VAULT_TLS_SERVER_NAME"
const EnvVaultWrapTTL = "VAULT_WRAP_TTL"
const EnvVaultMaxRetries = "VAULT_MAX_RETRIES"
type WrappingLookupFunc func(operation, path string) string
type Config struct {
	Address string
	HttpClient *http.Client
	redirectSetup sync.Once
	MaxRetries int
}
type TLSConfig struct {
	CACert string
	CAPath string
	ClientCert string
	ClientKey string
	TLSServerName string
	Insecure bool
}
func DefaultConfig() *Config {
	config := &Config{
		Address: "https://127.0.0.1:8200",
		HttpClient: cleanhttp.DefaultClient(),
	}
	config.HttpClient.Timeout = time.Second * 60
	transport := config.HttpClient.Transport.(*http.Transport)
	transport.TLSHandshakeTimeout = 10 * time.Second
	transport.TLSClientConfig = &tls.Config{
		MinVersion: tls.VersionTLS12,
	}
	if v := os.Getenv(EnvVaultAddress); v != "" {
		config.Address = v
	}
	return config
}
func (c *Config) ConfigureTLS(t *TLSConfig) error {
	if c.HttpClient == nil {
		return fmt.Errorf("config HTTP Client must be set")
	}
	var clientCert tls.Certificate
	foundClientCert := false
	if t.CACert != "" || t.CAPath != "" || t.ClientCert != "" || t.ClientKey != "" || t.Insecure {
		if t.ClientCert != "" && t.ClientKey != "" {
			var err error
			clientCert, err = tls.LoadX509KeyPair(t.ClientCert, t.ClientKey)
			if err != nil {
				return err
			}
			foundClientCert = true
		} else if t.ClientCert != "" || t.ClientKey != "" {
			return fmt.Errorf("Both client cert and client key must be provided")
		}
	}
	clientTLSConfig := c.HttpClient.Transport.(*http.Transport).TLSClientConfig
	rootConfig := &rootcerts.Config{
		CAFile: t.CACert,
		CAPath: t.CAPath,
	}
	if err := rootcerts.ConfigureTLS(clientTLSConfig, rootConfig); err != nil {
		return err
	}
	clientTLSConfig.InsecureSkipVerify = t.Insecure
	if foundClientCert {
		clientTLSConfig.Certificates = []tls.Certificate{clientCert}
	}
	if t.TLSServerName != "" {
		clientTLSConfig.ServerName = t.TLSServerName
	}
	return nil
}
func (c *Config) ReadEnvironment() error {
	var envAddress string
	var envCACert string
	var envCAPath string
	var envClientCert string
	var envClientKey string
	var envInsecure bool
	var envTLSServerName string
	var envMaxRetries *uint64
	if v := os.Getenv(EnvVaultAddress); v != "" {
		envAddress = v
	}
	if v := os.Getenv(EnvVaultMaxRetries); v != "" {
		maxRetries, err := strconv.ParseUint(v, 10, 32)
		if err != nil {
			return err
		}
		envMaxRetries = &maxRetries
	}
	if v := os.Getenv(EnvVaultCACert); v != "" {
		envCACert = v
	}
	if v := os.Getenv(EnvVaultCAPath); v != "" {
		envCAPath = v
	}
	if v := os.Getenv(EnvVaultClientCert); v != "" {
		envClientCert = v
	}
	if v := os.Getenv(EnvVaultClientKey); v != "" {
		envClientKey = v
	}
	if v := os.Getenv(EnvVaultInsecure); v != "" {
		var err error
		envInsecure, err = strconv.ParseBool(v)
		if err != nil {
			return fmt.Errorf("Could not parse VAULT_SKIP_VERIFY")
		}
	}
	if v := os.Getenv(EnvVaultTLSServerName); v != "" {
		envTLSServerName = v
	}
	t := &TLSConfig{
		CACert:        envCACert,
		CAPath:        envCAPath,
		ClientCert:    envClientCert,
		ClientKey:     envClientKey,
		TLSServerName: envTLSServerName,
		Insecure:      envInsecure,
	}
	if err := c.ConfigureTLS(t); err != nil {
		return err
	}
	if envAddress != "" {
		c.Address = envAddress
	}
	if envMaxRetries != nil {
		c.MaxRetries = int(*envMaxRetries) + 1
	}
	return nil
}
type Client struct {
	addr               *url.URL
	config             *Config
	token              string
	wrappingLookupFunc WrappingLookupFunc
}
func NewClient(c *Config) (*Client, error) {
	if c == nil {
		c = DefaultConfig()
		if err := c.ReadEnvironment(); err != nil {
			return nil, fmt.Errorf("error reading environment: %v", err)
		}
	}
	u, err := url.Parse(c.Address)
	if err != nil {
		return nil, err
	}
	if c.HttpClient == nil {
		c.HttpClient = DefaultConfig().HttpClient
	}
	redirFunc := func() {
		c.HttpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
			return http.ErrUseLastResponse
		}
	}
	c.redirectSetup.Do(redirFunc)
	client := &Client{
		addr:   u,
		config: c,
	}
	if token := os.Getenv("VAULT_TOKEN"); token != "" {
		client.SetToken(token)
	}
	return client, nil
}
func (c *Client) SetAddress(addr string) error {
	var err error
	if c.addr, err = url.Parse(addr); err != nil {
		return fmt.Errorf("failed to set address: %v", err)
	}
	return nil
}
func (c *Client) Address() string {
	return c.addr.String()
}
func (c *Client) SetWrappingLookupFunc(lookupFunc WrappingLookupFunc) {
	c.wrappingLookupFunc = lookupFunc
}