-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfirmware.go
101 lines (80 loc) · 2.6 KB
/
firmware.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package ilo
import (
"fmt"
"github.com/NETWAYS/check_hp_firmware/hp/mib"
"github.com/NETWAYS/go-check"
"github.com/gosnmp/gosnmp"
"github.com/hashicorp/go-version"
)
type Ilo struct {
ModelID int
Model string
RomRevision string
}
// GetIloInformation retrieves the iLO's Model and Rom Revision via SNMP
// and returns an Ilo struct.
func GetIloInformation(client gosnmp.Handler) (ilo *Ilo, err error) {
oids := []string{
mib.CpqSm2CntlrModel + ".0",
mib.CpqSm2CntlrRomRevision + ".0",
}
ilo = &Ilo{}
iloVariables, err := client.Get(oids)
if err != nil {
err = fmt.Errorf("could not get SNMP data for iLO: %w", err)
return
}
// Since we only have two variable of different type we don't need to check their names
for _, v := range iloVariables.Variables {
switch v.Type {
case gosnmp.OctetString: // CpqSm2CntlrRomRevision
// Using Sprintf makes this work for (string) and ([]byte)
ilo.RomRevision = fmt.Sprintf("%s", v.Value)
case gosnmp.Integer: // CpqSm2CntlrModel
modelID := v.Value.(int)
ilo.ModelID = modelID
if model, ok := mib.CpqSm2CntlrModelMap[modelID]; ok {
ilo.Model = model
}
}
}
return
}
// GetNagiosStatus validates the iLO's data against the known models
// in this plugin.
func (ilo *Ilo) GetNagiosStatus(returnStateforPatch int) (state int, output string) {
// nolint: ineffassign
state = check.Unknown
// Check if the SNMP id is an older model, then alert
if ilo.ModelID <= OlderModels {
state = check.Critical
output = fmt.Sprintf("ILO model %s (%d) is pretty old and likely unsafe", ilo.Model, ilo.ModelID)
return
}
// Check if we know fixed versions for the generation, other models are only reported
modelInfo, found := FixedVersionMap[ilo.Model]
if !found {
state = check.OK
output = fmt.Sprintf("Integrated Lights-Out model %s (%d) revision %s not known for any issues",
ilo.Model, ilo.ModelID, ilo.RomRevision)
return
}
output = fmt.Sprintf("Integrated Lights-Out %s revision %s ", modelInfo.Name, ilo.RomRevision)
if !isNewerVersion(modelInfo.FixedRelease, ilo.RomRevision) {
state = returnStateforPatch
output += "- Patch available, should be at least " + modelInfo.FixedRelease
} else {
state = check.OK
output += "- version newer than affected"
}
return
}
// isNewerVersion compares the current version against the required version
func isNewerVersion(required, current string) bool {
currentVersion, cErr := version.NewVersion(current)
requiredVersion, rErr := version.NewVersion(required)
if cErr != nil || rErr != nil {
return false
}
return currentVersion.GreaterThanOrEqual(requiredVersion)
}