github.com/smithx10/nomad@v0.9.1-rc1/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 }