github.com/hspak/nomad@v0.7.2-0.20180309000617-bc4ae22a39a5/client/fingerprint/fingerprint.go (about) 1 package fingerprint 2 3 import ( 4 "fmt" 5 "log" 6 "sort" 7 "time" 8 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 // Fingerprint is used for doing "fingerprinting" of the 89 // host to automatically determine attributes, resources, 90 // and metadata about it. Each of these is a heuristic, and 91 // many of them can be applied on a particular host. 92 type Fingerprint interface { 93 // Fingerprint is used to update properties of the Node, 94 // and returns a diff of updated node attributes and a potential error. 95 Fingerprint(*cstructs.FingerprintRequest, *cstructs.FingerprintResponse) error 96 97 // Periodic is a mechanism for the fingerprinter to indicate that it should 98 // be run periodically. The return value is a boolean indicating if it 99 // should be periodic, and if true, a duration. 100 Periodic() (bool, time.Duration) 101 } 102 103 // StaticFingerprinter can be embedded in a struct that has a Fingerprint method 104 // to make it non-periodic. 105 type StaticFingerprinter struct{} 106 107 func (s *StaticFingerprinter) Periodic() (bool, time.Duration) { 108 return false, EmptyDuration 109 }