github.com/hhrutter/nomad@v0.6.0-rc2.0.20170723054333-80c4b03f0705/client/fingerprint/fingerprint.go (about)

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