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 }