-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhpmib.go
275 lines (248 loc) · 9.28 KB
/
hpmib.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
package hpmib
import (
"fmt"
"github.com/soniah/gosnmp"
)
// AuthProtocol is the auth protocol to use for SNMPv3 connections.
type AuthProtocol string
// Auth protocols for SNMPv3 connections.
const (
// AuthProtocolMD5 models the MD5 auth protocol for SNMPv3 connections.
AuthProtocolMD5 AuthProtocol = "MD5"
// AuthProtocolSHA models the SHA auth protocol for SNMPv3 connections.
AuthProtocolSHA AuthProtocol = "SHA"
)
// PrivProtocol is the priv protocol to use for SNMPv3 connections.
type PrivProtocol string
// Priv protocols for SNMPv3 connections.
const (
// PrivProtocolAES models the AES priv protocol for SNMPv3 connections.
PrivProtocolAES PrivProtocol = "AES"
// PrivProtocolDES models the DES priv protocol for SNMPv3 connections.
PrivProtocolDES PrivProtocol = "DES"
)
// SecurityLevel is the security level to use for SNMPv3 connections.
type SecurityLevel string
// Security levels for SNMPv3 connections.
const (
// SecurityLevelAuthPriv models the authPriv security level for SNMPv3 connections.
SecurityLevelAuthPriv SecurityLevel = "authPriv"
// SecurityLevelAuthNoPriv models the authNoPriv security level for SNMPv3 connections.
SecurityLevelAuthNoPriv SecurityLevel = "authNoPriv"
// SecurityLevelNoAuthNoPriv models the noAuthNoPriv securitylevel for SNMPv3 connections.
SecurityLevelNoAuthNoPriv SecurityLevel = "noAuthNoPriv"
)
// SNMPVersion is the protocol version to use for SNMP connections.
type SNMPVersion string
// Versions of SNMP.
const (
// SNMPVersion3 models version 3 of of the SNMP protocol.
SNMPVersion3 SNMPVersion = "3"
// SNMPVersion2c models version 2c of of the SNMP protocol.
SNMPVersion2c SNMPVersion = "2c"
// SNMPVersion1 models version 1 of of the SNMP protocol.
SNMPVersion1 SNMPVersion = "1"
)
// Status describes the state of a device.
type Status int
// Statuses defined by the HP MIB.
const (
// StatusUnknown is used if the status cannot be determined.
StatusUnknown Status = -1
// StatusOther represents the "Other" state defined by the HP MIB.
StatusOther Status = 1
// StatusOK represents the "OK" state defined by the HP MIB.
StatusOK Status = 2
// StatusDegraded represents the "Degraded" state defined by the HP MIB.
StatusDegraded Status = 3
// StatusFailed represents the "Failed" state defined by the HP MIB.
StatusFailed Status = 4
)
// BatteryStatus descibes the state of a battery.
type BatteryStatus int
const (
// BatteryStatusUnknown indicates that the battery status cannot be determined.
BatteryStatusUnknown BatteryStatus = -1
// BatteryStatusOther indicates that the instrument agent does not recognize battery status.
BatteryStatusOther BatteryStatus = 1
// BatteryStatusOK indicates that the battery is fully charged.
BatteryStatusOK BatteryStatus = 2
// BatteryStatusCharging indicates that the battery power is less than 75% and is recharging.
BatteryStatusCharging BatteryStatus = 3
// BatteryStatusFailed indicates that the battery has failed.
BatteryStatusFailed BatteryStatus = 4
// BatteryStatusDegraded indicates that the battery is below the sufficient voltage level and has not been recharged.
BatteryStatusDegraded BatteryStatus = 5
// BatteryStatusNotPresent indicates that there is no battery installed.
BatteryStatusNotPresent BatteryStatus = 6
// BatteryStatusCapacitorFailed indicates that the battery capacitor failed.
BatteryStatusCapacitorFailed BatteryStatus = 7
)
// OID represents an object ID
type OID string
// OIDList represents a list of object IDs
type OIDList []OID
// A StatusChecker queries the HP MIB for device status information.
type StatusChecker interface {
ArrayAccelerators() ([]ArrayAccelerator, error)
ASRStatus() (Status, error)
BackupBatteryStatus() (Status, error)
Controllers() ([]Controller, error)
ControllerStatus() (Status, error)
DriveArrayStatus() (Status, error)
EnclosureStatus() (Status, error)
Fans() ([]Fan, error)
FanStatus() (Status, error)
LogicalDrives() ([]LogicalDrive, error)
MemoryModules() ([]MemoryModule, error)
MemoryStatus() (Status, error)
Model() (string, error)
PhysicalDrives() ([]PhysicalDrive, error)
PowerMeterReading() (int, error)
PowerSupplies() ([]PowerSupply, error)
PowerSupplyStatus() (Status, error)
Processors() ([]Processor, error)
ProcessorStatus() (Status, error)
SerialNumber() (string, error)
TemperatureSensors() ([]TemperatureSensor, error)
TemperatureSensorStatus() (Status, error)
}
// MIB implements StatusChecker.
type MIB struct {
snmpClient *gosnmp.GoSNMP
}
// MIBConfig is used to configure the HP MIB.
type MIBConfig struct {
SNMPConfig `yaml:"snmp"`
}
// AuthConfig is used to configure authentication and authorization for the SNMP connection.
type AuthConfig struct {
// Community specifies the community name to use with the SNMP connection.
Community string `yaml:"community"`
// SecurityLevel specifies the security level to use for SNMPv3 connections. Supported security levels are "authPriv", "authNoPriv", and "noAuthNoPriv".
SecurityLevel SecurityLevel `yaml:"security-level,omitempty"`
// Username specifies the username use for SNMPv3 connections.
Username string `yaml:"username,omitempty"`
// Password specifies the password use for SNMPv3 connections.
Password string `yaml:"password,omitempty"`
// AuthProtocol specifies the auth protocol to use for SNMPv3 connections. Supported auth protocols are "SHA" and "MD5".
AuthProtocol AuthProtocol `yaml:"auth-protocol,omitempty"`
// PrivProtocol specifies the priv protocol to use for SNMPv3 connections. Supported priv protocols are "DES" and "AES".
PrivProtocol PrivProtocol `yaml:"priv-protocol,omitempty"`
// PrivPassword specifies the priv password to use for SNMPv3 connections.
PrivPassword string `yaml:"priv-password,omitempty"`
// ContextName specifies the context name to use for SNMPv3 connections.
ContextName string `yaml:"context-name,omitempty"`
}
// SNMPConfig is used to configure the connection to the SNMP agent.
type SNMPConfig struct {
// Auth contains parameters used for authentication and authorization.
Auth AuthConfig `yaml:"auth"`
// Address specifies the address of the SNMP agent.
Address string `yaml:"address"`
// Port specifies the port that the SNMP agent is listening on.
Port int `yaml:"port"`
// Version specifies the SNMP protocol version to use. Supported versions are "1", "2c", and "3".
Version SNMPVersion `yaml:"version"`
}
// NewMIB returns a new HP MIB.
func NewMIB(cfg *MIBConfig) (*MIB, error) {
c := gosnmp.Default
c.Community = cfg.Auth.Community
c.Target = cfg.Address
c.Port = uint16(cfg.Port)
c.ContextName = cfg.Auth.ContextName
switch cfg.Version {
case SNMPVersion1:
c.Version = gosnmp.Version1
case SNMPVersion2c:
c.Version = gosnmp.Version2c
case SNMPVersion3:
c.Version = gosnmp.Version3
var err error
c, err = configureSNMPClientWithAuth(cfg.Auth, c)
if err != nil {
return nil, err
}
}
if err := c.Connect(); err != nil {
return nil, err
}
return &MIB{
snmpClient: c,
}, nil
}
// Connect creates a new socket to be used by the SNMP client.
func (m *MIB) Connect() error {
return m.snmpClient.Connect()
}
// Close closes the socket used by the SNMP client.
func (m *MIB) Close() error {
return m.snmpClient.Conn.Close()
}
// configureSNMPClientWithAuth configures the SNMPv3 client using the provided authentication configuration.
func configureSNMPClientWithAuth(authCfg AuthConfig, client *gosnmp.GoSNMP) (*gosnmp.GoSNMP, error) {
client.SecurityModel = gosnmp.UserSecurityModel
auth, priv := false, false
switch authCfg.SecurityLevel {
case SecurityLevelAuthPriv:
if authCfg.PrivPassword == "" {
return nil, fmt.Errorf("priv password must be specified when using authPriv")
}
if authCfg.PrivProtocol != PrivProtocolAES && authCfg.PrivProtocol != PrivProtocolDES {
return nil, fmt.Errorf("priv protocol must be AES or DES when using authPriv")
}
client.MsgFlags = gosnmp.AuthPriv
auth = true
priv = true
case SecurityLevelAuthNoPriv:
if authCfg.Password == "" {
return nil, fmt.Errorf("password is required when using authNoPriv")
}
if authCfg.AuthProtocol != AuthProtocolMD5 && authCfg.AuthProtocol != AuthProtocolSHA {
return nil, fmt.Errorf("auth protocol must be SHA or MD5 when using authNoPriv")
}
client.MsgFlags = gosnmp.AuthNoPriv
auth = true
case SecurityLevelNoAuthNoPriv:
if authCfg.Username == "" {
return nil, fmt.Errorf("username is required when using noAuthNoPriv")
}
client.MsgFlags = gosnmp.NoAuthNoPriv
}
securityParams := &gosnmp.UsmSecurityParameters{
UserName: authCfg.Username,
}
if auth {
securityParams.AuthenticationPassphrase = authCfg.Password
switch authCfg.AuthProtocol {
case AuthProtocolSHA:
securityParams.AuthenticationProtocol = gosnmp.SHA
case AuthProtocolMD5:
securityParams.AuthenticationProtocol = gosnmp.MD5
}
}
if priv {
securityParams.PrivacyPassphrase = authCfg.PrivPassword
switch authCfg.PrivProtocol {
case PrivProtocolDES:
securityParams.PrivacyProtocol = gosnmp.DES
case PrivProtocolAES:
securityParams.PrivacyProtocol = gosnmp.AES
}
}
client.SecurityParameters = securityParams
return client, nil
}
// String converts the OID to a string.
func (o *OID) String() string {
return string(*o)
}
// Strings converts the list of OIDs to a list of strings.
func (o *OIDList) Strings() []string {
l := make([]string, 0, len(*o))
for _, id := range *o {
l = append(l, id.String())
}
return l
}