diff --git a/api/api.go b/api/api.go index 76acad1b65..8fe2ead048 100644 --- a/api/api.go +++ b/api/api.go @@ -2,9 +2,11 @@ package api import ( "bytes" + "crypto/tls" "encoding/json" "fmt" "io" + "log" "net" "net/http" "net/url" @@ -124,6 +126,52 @@ func DefaultConfig() *Config { config.Address = addr } + if token := os.Getenv("CONSUL_HTTP_TOKEN"); token != "" { + config.Token = token + } + + if auth := os.Getenv("CONSUL_HTTP_AUTH"); auth != "" { + var username, password string + if strings.Contains(auth, ":") { + split := strings.SplitN(auth, ":", 2) + username = split[0] + password = split[1] + } else { + username = auth + } + + config.HttpAuth = &HttpBasicAuth{ + Username: username, + Password: password, + } + } + + if ssl := os.Getenv("CONSUL_HTTP_SSL"); ssl != "" { + enabled, err := strconv.ParseBool(ssl) + if err != nil { + log.Printf("[WARN] client: could not parse CONSUL_HTTP_SSL: %s", err) + } + + if enabled { + config.Scheme = "https" + } + } + + if verify := os.Getenv("CONSUL_HTTP_SSL_VERIFY"); verify != "" { + doVerify, err := strconv.ParseBool(verify) + if err != nil { + log.Printf("[WARN] client: could not parse CONSUL_HTTP_SSL_VERIFY: %s", err) + } + + if !doVerify { + config.HttpClient.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + } + } + return config } diff --git a/api/api_test.go b/api/api_test.go index dc25f8b5a4..f0de0b6b97 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -190,6 +190,51 @@ func testKey() string { buf[10:16]) } +func TestDefaultConfig_env(t *testing.T) { + addr := "1.2.3.4:5678" + token := "abcd1234" + auth := "username:password" + + os.Setenv("CONSUL_HTTP_ADDR", addr) + defer os.Setenv("CONSUL_HTTP_ADDR", "") + os.Setenv("CONSUL_HTTP_TOKEN", token) + defer os.Setenv("CONSUL_HTTP_TOKEN", "") + os.Setenv("CONSUL_HTTP_AUTH", auth) + defer os.Setenv("CONSUL_HTTP_AUTH", "") + os.Setenv("CONSUL_HTTP_SSL", "1") + defer os.Setenv("CONSUL_HTTP_SSL", "") + os.Setenv("CONSUL_HTTP_SSL_VERIFY", "0") + defer os.Setenv("CONSUL_HTTP_SSL_VERIFY", "") + + config := DefaultConfig() + + if config.Address != addr { + t.Errorf("expected %q to be %q", config.Address, addr) + } + + if config.Token != token { + t.Errorf("expected %q to be %q", config.Token, token) + } + + if config.HttpAuth == nil { + t.Fatalf("expected HttpAuth to be enabled") + } + if config.HttpAuth.Username != "username" { + t.Errorf("expected %q to be %q", config.HttpAuth.Username, "username") + } + if config.HttpAuth.Password != "password" { + t.Errorf("expected %q to be %q", config.HttpAuth.Password, "password") + } + + if config.Scheme != "https" { + t.Errorf("expected %q to be %q", config.Scheme, "https") + } + + if !config.HttpClient.Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify { + t.Errorf("expected SSL verification to be off") + } +} + func TestSetQueryOptions(t *testing.T) { c, s := makeClient(t) defer s.stop() diff --git a/website/source/docs/agent/options.html.markdown b/website/source/docs/agent/options.html.markdown index 585d1ffb5a..d9729d4add 100644 --- a/website/source/docs/agent/options.html.markdown +++ b/website/source/docs/agent/options.html.markdown @@ -302,6 +302,7 @@ definitions support being updated during a reload. The following keys are valid: * `dns` - The DNS server. Defaults to `client_addr` * `http` - The HTTP API. Defaults to `client_addr` + * `https` - The HTTPS API. Defaults to `client_addr` * `rpc` - The RPC endpoint. Defaults to `client_addr` * `advertise_addr` Equivalent to @@ -546,7 +547,7 @@ definitions support being updated during a reload. connections make use of TLS and that the client provides a certificate signed by the Certificate Authority from the [`ca_file`](#ca_file). By default, this is false, and Consul will not enforce the use of TLS or verify a client's authenticity. This - only applies to Consul servers since a client never has an incoming connection. + applies to both server RPC and to the HTTPS API. * `verify_outgoing` - If set to true, Consul requires that all outgoing connections