github.com/bigcommerce/nomad@v0.9.3-bc/command/agent/consul/version_checker.go (about)

     1  package consul
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  	"time"
     7  
     8  	log "github.com/hashicorp/go-hclog"
     9  	version "github.com/hashicorp/go-version"
    10  )
    11  
    12  // checkConsulTLSSkipVerify logs if Consul does not support TLSSkipVerify on
    13  // checks and is intended to be run in a goroutine.
    14  func checkConsulTLSSkipVerify(ctx context.Context, logger log.Logger, client AgentAPI, done chan struct{}) {
    15  	const (
    16  		baseline = time.Second
    17  		limit    = 20 * time.Second
    18  	)
    19  
    20  	defer close(done)
    21  
    22  	i := uint64(0)
    23  	for {
    24  		self, err := client.Self()
    25  		if err == nil {
    26  			if supportsTLSSkipVerify(self) {
    27  				logger.Trace("Consul supports TLSSkipVerify")
    28  			} else {
    29  				logger.Warn("Consul does NOT support TLSSkipVerify; please upgrade Consul",
    30  					"min_version", consulTLSSkipVerifyMinVersion)
    31  			}
    32  			return
    33  		}
    34  
    35  		backoff := (1 << (2 * i)) * baseline
    36  		if backoff > limit {
    37  			backoff = limit
    38  		} else {
    39  			i++
    40  		}
    41  
    42  		select {
    43  		case <-ctx.Done():
    44  			return
    45  		case <-time.After(backoff):
    46  		}
    47  	}
    48  }
    49  
    50  var consulTLSSkipVerifyMinVersion = version.Must(version.NewVersion("0.7.2"))
    51  
    52  // supportsTLSSkipVerify returns true if Consul supports TLSSkipVerify.
    53  func supportsTLSSkipVerify(self map[string]map[string]interface{}) bool {
    54  	member, ok := self["Member"]
    55  	if !ok {
    56  		return false
    57  	}
    58  	tagsI, ok := member["Tags"]
    59  	if !ok {
    60  		return false
    61  	}
    62  	tags, ok := tagsI.(map[string]interface{})
    63  	if !ok {
    64  		return false
    65  	}
    66  	buildI, ok := tags["build"]
    67  	if !ok {
    68  		return false
    69  	}
    70  	build, ok := buildI.(string)
    71  	if !ok {
    72  		return false
    73  	}
    74  	parts := strings.SplitN(build, ":", 2)
    75  	if len(parts) != 2 {
    76  		return false
    77  	}
    78  	v, err := version.NewVersion(parts[0])
    79  	if err != nil {
    80  		return false
    81  	}
    82  	if v.LessThan(consulTLSSkipVerifyMinVersion) {
    83  		return false
    84  	}
    85  	return true
    86  }