refactor into multiple fingerprints
This commit is contained in:
parent
8ab31da8b0
commit
9a92383b69
10
client/fingerprint/common_test.go
Normal file
10
client/fingerprint/common_test.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package fingerprint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testLogger() *log.Logger {
|
||||||
|
return log.New(os.Stderr, "", log.LstdFlags)
|
||||||
|
}
|
51
client/fingerprint/cpu.go
Normal file
51
client/fingerprint/cpu.go
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package fingerprint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/hashicorp/nomad/client/config"
|
||||||
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
|
"github.com/shirou/gopsutil/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CPUFingerprint is used to fingerprint the CPU
|
||||||
|
type CPUFingerprint struct {
|
||||||
|
logger *log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCPUFingerprint is used to create a CPU fingerprint
|
||||||
|
func NewCPUFingerprint(logger *log.Logger) Fingerprint {
|
||||||
|
f := &CPUFingerprint{logger}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *CPUFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
|
||||||
|
cpuInfo, err := cpu.CPUInfo()
|
||||||
|
if err != nil {
|
||||||
|
f.logger.Println("[WARN] Error reading CPU information:", err)
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var numCores int32
|
||||||
|
numCores = 0
|
||||||
|
var modelName string
|
||||||
|
// Assume all CPUs found have same Model. Log if not.
|
||||||
|
// If CPUInfo() returns nil above, this loop is still safe
|
||||||
|
for i, c := range cpuInfo {
|
||||||
|
f.logger.Printf("(%d) Vendor: %s", i, c.VendorID)
|
||||||
|
numCores += c.Cores
|
||||||
|
if modelName != "" && modelName != c.ModelName {
|
||||||
|
f.logger.Println("[WARN] Found different model names in the same CPU information. Recording last found")
|
||||||
|
}
|
||||||
|
modelName = c.ModelName
|
||||||
|
}
|
||||||
|
if numCores > 0 {
|
||||||
|
node.Attributes["cpu.numcores"] = strconv.FormatInt(int64(numCores), 10)
|
||||||
|
}
|
||||||
|
if modelName != "" {
|
||||||
|
node.Attributes["cpu.modelname"] = modelName
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
31
client/fingerprint/cpu_test.go
Normal file
31
client/fingerprint/cpu_test.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package fingerprint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/nomad/client/config"
|
||||||
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCPUFingerprint(t *testing.T) {
|
||||||
|
f := NewCPUFingerprint(testLogger())
|
||||||
|
node := &structs.Node{
|
||||||
|
Attributes: make(map[string]string),
|
||||||
|
}
|
||||||
|
ok, err := f.Fingerprint(&config.Config{}, node)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("should apply")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CPU info
|
||||||
|
if node.Attributes["cpu.numcores"] == "" {
|
||||||
|
t.Fatalf("Missing Num Cores")
|
||||||
|
}
|
||||||
|
if node.Attributes["cpu.modelname"] == "" {
|
||||||
|
t.Fatalf("Missing Model Name")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,8 +11,10 @@ import (
|
||||||
// BuiltinFingerprints contains the built in registered fingerprints
|
// BuiltinFingerprints contains the built in registered fingerprints
|
||||||
// which are available
|
// which are available
|
||||||
var BuiltinFingerprints = map[string]Factory{
|
var BuiltinFingerprints = map[string]Factory{
|
||||||
"os": NewOSFingerprint,
|
|
||||||
"arch": NewArchFingerprint,
|
"arch": NewArchFingerprint,
|
||||||
|
"cpu": NewCPUFingerprint,
|
||||||
|
"host": NewHostFingerprint,
|
||||||
|
"os": NewOSFingerprint,
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFingerprint is used to instantiate and return a new fingerprint
|
// NewFingerprint is used to instantiate and return a new fingerprint
|
||||||
|
|
35
client/fingerprint/host.go
Normal file
35
client/fingerprint/host.go
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package fingerprint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/hashicorp/nomad/client/config"
|
||||||
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
|
"github.com/shirou/gopsutil/host"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HostFingerprint is used to fingerprint the host
|
||||||
|
type HostFingerprint struct {
|
||||||
|
logger *log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHostFingerprint is used to create a Host fingerprint
|
||||||
|
func NewHostFingerprint(logger *log.Logger) Fingerprint {
|
||||||
|
f := &HostFingerprint{logger}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *HostFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
|
||||||
|
hostInfo, err := host.HostInfo()
|
||||||
|
if err != nil {
|
||||||
|
f.logger.Println("[WARN] Error retrieving host information: ", err)
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
node.Attributes["os.name"] = hostInfo.Platform
|
||||||
|
node.Attributes["os.version"] = hostInfo.PlatformVersion
|
||||||
|
node.Attributes["hostname"] = hostInfo.Hostname
|
||||||
|
node.Attributes["kernel.name"] = hostInfo.OS
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
29
client/fingerprint/host_test.go
Normal file
29
client/fingerprint/host_test.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package fingerprint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/nomad/client/config"
|
||||||
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHostFingerprint(t *testing.T) {
|
||||||
|
f := NewHostFingerprint(testLogger())
|
||||||
|
node := &structs.Node{
|
||||||
|
Attributes: make(map[string]string),
|
||||||
|
}
|
||||||
|
ok, err := f.Fingerprint(&config.Config{}, node)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("should apply")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Host info
|
||||||
|
for _, key := range []string{"os.name", "os.version", "hostname", "kernel.name"} {
|
||||||
|
if node.Attributes[key] == "" {
|
||||||
|
t.Fatalf("Missing (%s) in Host Info attribute check", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,12 +3,9 @@ package fingerprint
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/hashicorp/nomad/client/config"
|
"github.com/hashicorp/nomad/client/config"
|
||||||
"github.com/hashicorp/nomad/nomad/structs"
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
"github.com/shirou/gopsutil/cpu"
|
|
||||||
"github.com/shirou/gopsutil/host"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// OSFingerprint is used to fingerprint the operating system
|
// OSFingerprint is used to fingerprint the operating system
|
||||||
|
@ -26,42 +23,5 @@ func (f *OSFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) (boo
|
||||||
node.Attributes["os"] = runtime.GOOS
|
node.Attributes["os"] = runtime.GOOS
|
||||||
f.logger.Printf("[DEBUG] fingerprint.os: detected '%s'", runtime.GOOS)
|
f.logger.Printf("[DEBUG] fingerprint.os: detected '%s'", runtime.GOOS)
|
||||||
|
|
||||||
cpuInfo, err := cpu.CPUInfo()
|
|
||||||
if err != nil {
|
|
||||||
f.logger.Println("[WARN] Error reading CPU information:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var numCores int32
|
|
||||||
numCores = 0
|
|
||||||
var modelName string
|
|
||||||
// Assume all CPUs found have same Model. Log if not.
|
|
||||||
// If CPUInfo() returns err above, this loop is still safe
|
|
||||||
for i, c := range cpuInfo {
|
|
||||||
f.logger.Printf("(%d) Vendor: %s", i, c.VendorID)
|
|
||||||
numCores += c.Cores
|
|
||||||
if modelName != "" && modelName != c.ModelName {
|
|
||||||
f.logger.Println("[WARN] Found different model names in the same CPU information. Recording last found")
|
|
||||||
}
|
|
||||||
modelName = c.ModelName
|
|
||||||
}
|
|
||||||
if numCores > 0 {
|
|
||||||
node.Attributes["cpu.numcores"] = strconv.FormatInt(int64(numCores), 10)
|
|
||||||
}
|
|
||||||
if modelName != "" {
|
|
||||||
node.Attributes["cpu.modelname"] = modelName
|
|
||||||
}
|
|
||||||
|
|
||||||
hostInfo, err := host.HostInfo()
|
|
||||||
if err != nil {
|
|
||||||
f.logger.Println("[WARN] Error retrieving host information: ", err)
|
|
||||||
} else {
|
|
||||||
node.Attributes["os.name"] = hostInfo.Platform
|
|
||||||
node.Attributes["os.version"] = hostInfo.PlatformVersion
|
|
||||||
node.Attributes["hostname"] = hostInfo.Hostname
|
|
||||||
node.Attributes["kernel.name"] = hostInfo.OS
|
|
||||||
}
|
|
||||||
|
|
||||||
f.logger.Printf("Node: %s", node)
|
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,12 @@
|
||||||
package fingerprint
|
package fingerprint
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/nomad/client/config"
|
"github.com/hashicorp/nomad/client/config"
|
||||||
"github.com/hashicorp/nomad/nomad/structs"
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testLogger() *log.Logger {
|
|
||||||
return log.New(os.Stderr, "", log.LstdFlags)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOSFingerprint(t *testing.T) {
|
func TestOSFingerprint(t *testing.T) {
|
||||||
f := NewOSFingerprint(testLogger())
|
f := NewOSFingerprint(testLogger())
|
||||||
node := &structs.Node{
|
node := &structs.Node{
|
||||||
|
@ -31,18 +25,4 @@ func TestOSFingerprint(t *testing.T) {
|
||||||
t.Fatalf("missing OS")
|
t.Fatalf("missing OS")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CPU info
|
|
||||||
if node.Attributes["cpu.numcores"] == "" {
|
|
||||||
t.Fatalf("Missing Num Cores")
|
|
||||||
}
|
|
||||||
if node.Attributes["cpu.modelname"] == "" {
|
|
||||||
t.Fatalf("Missing Model Name")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Host info
|
|
||||||
for _, key := range []string{"os.name", "os.version", "hostname", "kernel.name"} {
|
|
||||||
if node.Attributes[key] == "" {
|
|
||||||
t.Fatalf("Missing (%s) in Host Info attribute check", key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue