diff --git a/vendor/github.com/hashicorp/go-checkpoint/README.md b/vendor/github.com/hashicorp/go-checkpoint/README.md index ab8ebc0d3..e717b6ad3 100644 --- a/vendor/github.com/hashicorp/go-checkpoint/README.md +++ b/vendor/github.com/hashicorp/go-checkpoint/README.md @@ -1,7 +1,7 @@ # Go Checkpoint Client [Checkpoint](http://checkpoint.hashicorp.com) is an internal service at -Hashicorp that we use to check version information, broadcoast security +Hashicorp that we use to check version information, broadcast security bulletins, etc. We understand that software making remote calls over the internet @@ -10,7 +10,7 @@ disabled in all of our software that includes it. You can view the source of this client to see that we're not sending any private information. Each Hashicorp application has it's specific configuration option -to disable chekpoint calls, but the `CHECKPOINT_DISABLE` makes +to disable checkpoint calls, but the `CHECKPOINT_DISABLE` makes the underlying checkpoint component itself disabled. For example in the case of packer: ``` diff --git a/vendor/github.com/hashicorp/go-checkpoint/checkpoint.go b/vendor/github.com/hashicorp/go-checkpoint/checkpoint.go index abea934bf..36e572999 100644 --- a/vendor/github.com/hashicorp/go-checkpoint/checkpoint.go +++ b/vendor/github.com/hashicorp/go-checkpoint/checkpoint.go @@ -3,6 +3,8 @@ package checkpoint import ( + "bytes" + "context" "crypto/rand" "encoding/binary" "encoding/json" @@ -16,14 +18,118 @@ import ( "path/filepath" "reflect" "runtime" + "strconv" "strings" "time" "github.com/hashicorp/go-cleanhttp" + uuid "github.com/hashicorp/go-uuid" ) var magicBytes [4]byte = [4]byte{0x35, 0x77, 0x69, 0xFB} +// ReportParams are the parameters for configuring a telemetry report. +type ReportParams struct { + // Signature is some random signature that should be stored and used + // as a cookie-like value. This ensures that alerts aren't repeated. + // If the signature is changed, repeat alerts may be sent down. The + // signature should NOT be anything identifiable to a user (such as + // a MAC address). It should be random. + // + // If SignatureFile is given, then the signature will be read from this + // file. If the file doesn't exist, then a random signature will + // automatically be generated and stored here. SignatureFile will be + // ignored if Signature is given. + Signature string `json:"signature"` + SignatureFile string `json:"-"` + + StartTime time.Time `json:"start_time"` + EndTime time.Time `json:"end_time"` + Arch string `json:"arch"` + OS string `json:"os"` + Payload interface{} `json:"payload,omitempty"` + Product string `json:"product"` + RunID string `json:"run_id"` + SchemaVersion string `json:"schema_version"` + Version string `json:"version"` +} + +func (i *ReportParams) signature() string { + signature := i.Signature + if i.Signature == "" && i.SignatureFile != "" { + var err error + signature, err = checkSignature(i.SignatureFile) + if err != nil { + return "" + } + } + return signature +} + +// Report sends telemetry information to checkpoint +func Report(ctx context.Context, r *ReportParams) error { + if disabled := os.Getenv("CHECKPOINT_DISABLE"); disabled != "" { + return nil + } + + req, err := ReportRequest(r) + if err != nil { + return err + } + + client := cleanhttp.DefaultClient() + resp, err := client.Do(req.WithContext(ctx)) + if err != nil { + return err + } + if resp.StatusCode != 201 { + return fmt.Errorf("Unknown status: %d", resp.StatusCode) + } + + return nil +} + +// ReportRequest creates a request object for making a report +func ReportRequest(r *ReportParams) (*http.Request, error) { + // Populate some fields automatically if we can + if r.RunID == "" { + uuid, err := uuid.GenerateUUID() + if err != nil { + return nil, err + } + r.RunID = uuid + } + if r.Arch == "" { + r.Arch = runtime.GOARCH + } + if r.OS == "" { + r.OS = runtime.GOOS + } + if r.Signature == "" { + r.Signature = r.signature() + } + + b, err := json.Marshal(r) + if err != nil { + return nil, err + } + + u := &url.URL{ + Scheme: "https", + Host: "checkpoint-api.hashicorp.com", + Path: fmt.Sprintf("/v1/telemetry/%s", r.Product), + } + + req, err := http.NewRequest("POST", u.String(), bytes.NewReader(b)) + if err != nil { + return nil, err + } + req.Header.Add("Accept", "application/json") + req.Header.Add("User-Agent", "HashiCorp/go-checkpoint") + + return req, nil +} + // CheckParams are the parameters for configuring a check request. type CheckParams struct { // Product and version are used to lookup the correct product and @@ -99,6 +205,12 @@ func Check(p *CheckParams) (*CheckResponse, error) { return &CheckResponse{}, nil } + // set a default timeout of 3 sec for the check request (in milliseconds) + timeout := 3000 + if _, err := strconv.Atoi(os.Getenv("CHECKPOINT_TIMEOUT")); err == nil { + timeout, _ = strconv.Atoi(os.Getenv("CHECKPOINT_TIMEOUT")) + } + // If we have a cached result, then use that if r, err := checkCache(p.Version, p.CacheFile, p.CacheDuration); err != nil { return nil, err @@ -145,6 +257,11 @@ func Check(p *CheckParams) (*CheckResponse, error) { req.Header.Add("User-Agent", "HashiCorp/go-checkpoint") client := cleanhttp.DefaultClient() + + // We use a short timeout since checking for new versions is not critical + // enough to block on if checkpoint is broken/slow. + client.Timeout = time.Duration(timeout) * time.Millisecond + resp, err := client.Do(req) if err != nil { return nil, err diff --git a/vendor/vendor.json b/vendor/vendor.json index da4ba5d10..0f2af1b43 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1421,9 +1421,10 @@ "revision": "7554cd9344cec97297fa6649b055a8c98c2a1e55" }, { - "checksumSHA1": "nd3S1qkFv7zZxA9be0bw4nT0pe0=", + "checksumSHA1": "D267IUMW2rcb+vNe3QU+xhfSrgY=", "path": "github.com/hashicorp/go-checkpoint", - "revision": "e4b2dc34c0f698ee04750bf2035d8b9384233e1b" + "revision": "1545e56e46dec3bba264e41fde2c1e2aa65b5dd4", + "revisionTime": "2017-10-09T17:35:28Z" }, { "checksumSHA1": "b8F628srIitj5p7Y130xc9k0QWs=",