github.com/hernad/nomad@v1.6.112/command/agent/consul/version_checker.go (about)

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