package consul import ( "context" "strings" "time" log "github.com/hashicorp/go-hclog" version "github.com/hashicorp/go-version" "github.com/hashicorp/nomad/helper" ) // checkConsulTLSSkipVerify logs if Consul does not support TLSSkipVerify on // checks and is intended to be run in a goroutine. func checkConsulTLSSkipVerify(ctx context.Context, logger log.Logger, client AgentAPI, done chan struct{}) { const ( baseline = time.Second limit = 20 * time.Second ) defer close(done) i := uint64(0) timer, stop := helper.NewSafeTimer(limit) defer stop() for { self, err := client.Self() if err == nil { if supportsTLSSkipVerify(self) { logger.Trace("Consul supports TLSSkipVerify") } else { logger.Warn("Consul does NOT support TLSSkipVerify; please upgrade Consul", "min_version", consulTLSSkipVerifyMinVersion) } return } backoff := (1 << (2 * i)) * baseline if backoff > limit { backoff = limit } else { i++ } timer.Reset(backoff) select { case <-ctx.Done(): return case <-timer.C: } } } var consulTLSSkipVerifyMinVersion = version.Must(version.NewVersion("0.7.2")) // supportsTLSSkipVerify returns true if Consul supports TLSSkipVerify. func supportsTLSSkipVerify(self map[string]map[string]interface{}) bool { member, ok := self["Member"] if !ok { return false } tagsI, ok := member["Tags"] if !ok { return false } tags, ok := tagsI.(map[string]interface{}) if !ok { return false } buildI, ok := tags["build"] if !ok { return false } build, ok := buildI.(string) if !ok { return false } parts := strings.SplitN(build, ":", 2) if len(parts) != 2 { return false } v, err := version.NewVersion(parts[0]) if err != nil { return false } if v.LessThan(consulTLSSkipVerifyMinVersion) { return false } return true }