From 4ac6dda6333f603b1fa2ea5023df9367d60185f8 Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Tue, 3 May 2016 08:44:35 -0500 Subject: [PATCH] state/remote/atlas: Use go-rootcerts for certificate loading Allows CA certs to be configured via `ATLAS_CAFILE` and `ATLAS_CAPATH` env vars, and works around https://github.com/golang/go/issues/14514 on OS X. --- state/remote/atlas.go | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/state/remote/atlas.go b/state/remote/atlas.go index e3988e02c..6a48c21bc 100644 --- a/state/remote/atlas.go +++ b/state/remote/atlas.go @@ -3,6 +3,7 @@ package remote import ( "bytes" "crypto/md5" + "crypto/tls" "encoding/base64" "fmt" "io" @@ -13,7 +14,9 @@ import ( "path" "strings" + "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-retryablehttp" + "github.com/hashicorp/go-rootcerts" "github.com/hashicorp/terraform/terraform" ) @@ -90,7 +93,10 @@ func (c *AtlasClient) Get() (*Payload, error) { } // Request the url - client := c.http() + client, err := c.http() + if err != nil { + return nil, err + } resp, err := client.Do(req) if err != nil { return nil, err @@ -169,7 +175,10 @@ func (c *AtlasClient) Put(state []byte) error { req.ContentLength = int64(len(state)) // Make the request - client := c.http() + client, err := c.http() + if err != nil { + return err + } resp, err := client.Do(req) if err != nil { return fmt.Errorf("Failed to upload state: %v", err) @@ -197,7 +206,10 @@ func (c *AtlasClient) Delete() error { } // Make the request - client := c.http() + client, err := c.http() + if err != nil { + return err + } resp, err := client.Do(req) if err != nil { return fmt.Errorf("Failed to delete state: %v", err) @@ -247,11 +259,23 @@ func (c *AtlasClient) url() *url.URL { } } -func (c *AtlasClient) http() *retryablehttp.Client { +func (c *AtlasClient) http() (*retryablehttp.Client, error) { if c.HTTPClient != nil { - return c.HTTPClient + return c.HTTPClient, nil } - return retryablehttp.NewClient() + tlsConfig := &tls.Config{} + err := rootcerts.ConfigureTLS(tlsConfig, &rootcerts.Config{ + CAFile: os.Getenv("ATLAS_CAFILE"), + CAPath: os.Getenv("ATLAS_CAPATH"), + }) + if err != nil { + return nil, err + } + rc := retryablehttp.NewClient() + t := cleanhttp.DefaultTransport() + t.TLSClientConfig = tlsConfig + rc.HTTPClient.Transport = t + return rc, nil } // Atlas returns an HTTP 409 - Conflict if the pushed state reports the same