github.com/bigcommerce/nomad@v0.9.3-bc/client/fingerprint/fingerprint.go (about)

     1  package fingerprint
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"time"
     7  
     8  	log "github.com/hashicorp/go-hclog"
     9  	cstructs "github.com/hashicorp/nomad/client/structs"
    10  )
    11  
    12  // EmptyDuration is to be used by fingerprinters that are not periodic.
    13  const (
    14  	EmptyDuration = time.Duration(0)
    15  
    16  	// TightenNetworkTimeoutsConfig is a config key that can be used during
    17  	// tests to tighten the timeouts for fingerprinters that make network calls.
    18  	TightenNetworkTimeoutsConfig = "test.tighten_network_timeouts"
    19  )
    20  
    21  func init() {
    22  
    23  	// Initialize the list of available fingerprinters per platform.  Each
    24  	// platform defines its own list of available fingerprinters.
    25  	initPlatformFingerprints(hostFingerprinters)
    26  }
    27  
    28  var (
    29  	// hostFingerprinters contains the host fingerprints which are available for a
    30  	// given platform.
    31  	hostFingerprinters = map[string]Factory{
    32  		"arch":    NewArchFingerprint,
    33  		"consul":  NewConsulFingerprint,
    34  		"cpu":     NewCPUFingerprint,
    35  		"host":    NewHostFingerprint,
    36  		"memory":  NewMemoryFingerprint,
    37  		"network": NewNetworkFingerprint,
    38  		"nomad":   NewNomadFingerprint,
    39  		"signal":  NewSignalFingerprint,
    40  		"storage": NewStorageFingerprint,
    41  		"vault":   NewVaultFingerprint,
    42  	}
    43  
    44  	// envFingerprinters contains the fingerprints that are environment specific.
    45  	// This should run after the host fingerprinters as they may override specific
    46  	// node resources with more detailed information.
    47  	envFingerprinters = map[string]Factory{
    48  		"env_aws": NewEnvAWSFingerprint,
    49  		"env_gce": NewEnvGCEFingerprint,
    50  	}
    51  )
    52  
    53  // BuiltinFingerprints is a slice containing the key names of all registered
    54  // fingerprints available. The order of this slice should be preserved when
    55  // fingerprinting.
    56  func BuiltinFingerprints() []string {
    57  	fingerprints := make([]string, 0, len(hostFingerprinters))
    58  	for k := range hostFingerprinters {
    59  		fingerprints = append(fingerprints, k)
    60  	}
    61  	sort.Strings(fingerprints)
    62  	for k := range envFingerprinters {
    63  		fingerprints = append(fingerprints, k)
    64  	}
    65  	return fingerprints
    66  }
    67  
    68  // NewFingerprint is used to instantiate and return a new fingerprint
    69  // given the name and a logger
    70  func NewFingerprint(name string, logger log.Logger) (Fingerprint, error) {
    71  	// Lookup the factory function
    72  	factory, ok := hostFingerprinters[name]
    73  	if !ok {
    74  		factory, ok = envFingerprinters[name]
    75  		if !ok {
    76  			return nil, fmt.Errorf("unknown fingerprint '%s'", name)
    77  		}
    78  	}
    79  
    80  	// Instantiate the fingerprint
    81  	f := factory(logger)
    82  	return f, nil
    83  }
    84  
    85  // Factory is used to instantiate a new Fingerprint
    86  type Factory func(log.Logger) Fingerprint
    87  
    88  // HealthCheck is used for doing periodic health checks. On a given time
    89  // interfal, a health check will be called by the fingerprint manager of the
    90  // node.
    91  type HealthCheck interface {
    92  	// Check is used to update properties of the node on the status of the health
    93  	// check
    94  	HealthCheck(*cstructs.HealthCheckRequest, *cstructs.HealthCheckResponse) error
    95  
    96  	// GetHealthCheckInterval is a mechanism for the health checker to indicate that
    97  	// it should be run periodically. The return value is a boolean indicating
    98  	// whether it should be done periodically, and the time interval at which
    99  	// this check should happen.
   100  	GetHealthCheckInterval(*cstructs.HealthCheckIntervalRequest, *cstructs.HealthCheckIntervalResponse) error
   101  }
   102  
   103  // Fingerprint is used for doing "fingerprinting" of the
   104  // host to automatically determine attributes, resources,
   105  // and metadata about it. Each of these is a heuristic, and
   106  // many of them can be applied on a particular host.
   107  type Fingerprint interface {
   108  	// Fingerprint is used to update properties of the Node,
   109  	// and returns a diff of updated node attributes and a potential error.
   110  	Fingerprint(*FingerprintRequest, *FingerprintResponse) error
   111  
   112  	// Periodic is a mechanism for the fingerprinter to indicate that it should
   113  	// be run periodically. The return value is a boolean indicating if it
   114  	// should be periodic, and if true, a duration.
   115  	Periodic() (bool, time.Duration)
   116  }
   117  
   118  // StaticFingerprinter can be embedded in a struct that has a Fingerprint method
   119  // to make it non-periodic.
   120  type StaticFingerprinter struct{}
   121  
   122  func (s *StaticFingerprinter) Periodic() (bool, time.Duration) {
   123  	return false, EmptyDuration
   124  }