github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/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, // networks 35 "cpu": NewCPUFingerprint, 36 "host": NewHostFingerprint, 37 "landlock": NewLandlockFingerprint, 38 "memory": NewMemoryFingerprint, 39 "network": NewNetworkFingerprint, 40 "nomad": NewNomadFingerprint, 41 "plugins_cni": NewPluginsCNIFingerprint, 42 "signal": NewSignalFingerprint, 43 "storage": NewStorageFingerprint, 44 "vault": NewVaultFingerprint, 45 } 46 47 // envFingerprinters contains the fingerprints that are environment specific. 48 // This should run after the host fingerprinters as they may override specific 49 // node resources with more detailed information. 50 envFingerprinters = map[string]Factory{ 51 "env_aws": NewEnvAWSFingerprint, 52 "env_gce": NewEnvGCEFingerprint, 53 "env_azure": NewEnvAzureFingerprint, 54 "env_digitalocean": NewEnvDigitalOceanFingerprint, 55 } 56 ) 57 58 // BuiltinFingerprints is a slice containing the key names of all registered 59 // fingerprints available. The order of this slice should be preserved when 60 // fingerprinting. 61 func BuiltinFingerprints() []string { 62 fingerprints := make([]string, 0, len(hostFingerprinters)) 63 for k := range hostFingerprinters { 64 fingerprints = append(fingerprints, k) 65 } 66 sort.Strings(fingerprints) 67 for k := range envFingerprinters { 68 fingerprints = append(fingerprints, k) 69 } 70 return fingerprints 71 } 72 73 // NewFingerprint is used to instantiate and return a new fingerprint 74 // given the name and a logger 75 func NewFingerprint(name string, logger log.Logger) (Fingerprint, error) { 76 // Lookup the factory function 77 factory, ok := hostFingerprinters[name] 78 if !ok { 79 factory, ok = envFingerprinters[name] 80 if !ok { 81 return nil, fmt.Errorf("unknown fingerprint '%s'", name) 82 } 83 } 84 85 // Instantiate the fingerprint 86 f := factory(logger) 87 return f, nil 88 } 89 90 // Factory is used to instantiate a new Fingerprint 91 type Factory func(log.Logger) Fingerprint 92 93 // HealthCheck is used for doing periodic health checks. On a given time 94 // interfal, a health check will be called by the fingerprint manager of the 95 // node. 96 type HealthCheck interface { 97 // Check is used to update properties of the node on the status of the health 98 // check 99 HealthCheck(*cstructs.HealthCheckRequest, *cstructs.HealthCheckResponse) error 100 101 // GetHealthCheckInterval is a mechanism for the health checker to indicate that 102 // it should be run periodically. The return value is a boolean indicating 103 // whether it should be done periodically, and the time interval at which 104 // this check should happen. 105 GetHealthCheckInterval(*cstructs.HealthCheckIntervalRequest, *cstructs.HealthCheckIntervalResponse) error 106 } 107 108 // Fingerprint is used for doing "fingerprinting" of the 109 // host to automatically determine attributes, resources, 110 // and metadata about it. Each of these is a heuristic, and 111 // many of them can be applied on a particular host. 112 type Fingerprint interface { 113 // Fingerprint is used to update properties of the Node, 114 // and returns a diff of updated node attributes and a potential error. 115 Fingerprint(*FingerprintRequest, *FingerprintResponse) error 116 117 // Periodic is a mechanism for the fingerprinter to indicate that it should 118 // be run periodically. The return value is a boolean indicating if it 119 // should be periodic, and if true, a duration. 120 Periodic() (bool, time.Duration) 121 } 122 123 // ReloadableFingerprint can be implemented if the fingerprinter needs to be run during client reload. 124 // If implemented, the client will call Reload during client reload then immediately Fingerprint 125 type ReloadableFingerprint interface { 126 Fingerprint 127 Reload() 128 } 129 130 // StaticFingerprinter can be embedded in a struct that has a Fingerprint method 131 // to make it non-periodic. 132 type StaticFingerprinter struct{} 133 134 func (s *StaticFingerprinter) Periodic() (bool, time.Duration) { 135 return false, EmptyDuration 136 }