github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/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  		"cni":     NewCNIFingerprint,
    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  		"env_azure": NewEnvAzureFingerprint,
    52  	}
    53  )
    54  
    55  // BuiltinFingerprints is a slice containing the key names of all registered
    56  // fingerprints available. The order of this slice should be preserved when
    57  // fingerprinting.
    58  func BuiltinFingerprints() []string {
    59  	fingerprints := make([]string, 0, len(hostFingerprinters))
    60  	for k := range hostFingerprinters {
    61  		fingerprints = append(fingerprints, k)
    62  	}
    63  	sort.Strings(fingerprints)
    64  	for k := range envFingerprinters {
    65  		fingerprints = append(fingerprints, k)
    66  	}
    67  	return fingerprints
    68  }
    69  
    70  // NewFingerprint is used to instantiate and return a new fingerprint
    71  // given the name and a logger
    72  func NewFingerprint(name string, logger log.Logger) (Fingerprint, error) {
    73  	// Lookup the factory function
    74  	factory, ok := hostFingerprinters[name]
    75  	if !ok {
    76  		factory, ok = envFingerprinters[name]
    77  		if !ok {
    78  			return nil, fmt.Errorf("unknown fingerprint '%s'", name)
    79  		}
    80  	}
    81  
    82  	// Instantiate the fingerprint
    83  	f := factory(logger)
    84  	return f, nil
    85  }
    86  
    87  // Factory is used to instantiate a new Fingerprint
    88  type Factory func(log.Logger) Fingerprint
    89  
    90  // HealthCheck is used for doing periodic health checks. On a given time
    91  // interfal, a health check will be called by the fingerprint manager of the
    92  // node.
    93  type HealthCheck interface {
    94  	// Check is used to update properties of the node on the status of the health
    95  	// check
    96  	HealthCheck(*cstructs.HealthCheckRequest, *cstructs.HealthCheckResponse) error
    97  
    98  	// GetHealthCheckInterval is a mechanism for the health checker to indicate that
    99  	// it should be run periodically. The return value is a boolean indicating
   100  	// whether it should be done periodically, and the time interval at which
   101  	// this check should happen.
   102  	GetHealthCheckInterval(*cstructs.HealthCheckIntervalRequest, *cstructs.HealthCheckIntervalResponse) error
   103  }
   104  
   105  // Fingerprint is used for doing "fingerprinting" of the
   106  // host to automatically determine attributes, resources,
   107  // and metadata about it. Each of these is a heuristic, and
   108  // many of them can be applied on a particular host.
   109  type Fingerprint interface {
   110  	// Fingerprint is used to update properties of the Node,
   111  	// and returns a diff of updated node attributes and a potential error.
   112  	Fingerprint(*FingerprintRequest, *FingerprintResponse) error
   113  
   114  	// Periodic is a mechanism for the fingerprinter to indicate that it should
   115  	// be run periodically. The return value is a boolean indicating if it
   116  	// should be periodic, and if true, a duration.
   117  	Periodic() (bool, time.Duration)
   118  }
   119  
   120  // ReloadableFingerprint can be implemented if the fingerprinter needs to be run during client reload.
   121  // If implemented, the client will call Reload during client reload then immediately Fingerprint
   122  type ReloadableFingerprint interface {
   123  	Fingerprint
   124  	Reload()
   125  }
   126  
   127  // StaticFingerprinter can be embedded in a struct that has a Fingerprint method
   128  // to make it non-periodic.
   129  type StaticFingerprinter struct{}
   130  
   131  func (s *StaticFingerprinter) Periodic() (bool, time.Duration) {
   132  	return false, EmptyDuration
   133  }