go.d hpssa (#17637)
Ilya Mashchenko committed
May 14, 2024 at 10:59 UTC
e8618460d1ac4c26592b983f2c88628aea0d82b1
18 files changed
+3129
src/go/collectors/go.d.plugin/README.md
+1
@@ -79,6 +79,7 @@ see the appropriate collector readme.
79
| [haproxy](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/haproxy) | HAProxy |
80
| [hddtemp](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/hddtemp) | Disks temperature |
81
| [hdfs](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/hdfs) | HDFS |
82
+| [hpssa](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/hpssa) | HPE Smart Array |
83
| [httpcheck](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/httpcheck) | Any HTTP Endpoint |
84
| [intelgpu](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/intelgpu) | Intel integrated GPU |
85
| [isc_dhcpd](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/isc_dhcpd) | ISC DHCP |
src/go/collectors/go.d.plugin/config/go.d.conf
+1
@@ -42,6 +42,7 @@ modules:
42
# haproxy: yes
43
# hddtemp: yes
44
# hdfs: yes
45
+# hpssa: yes
46
# httpcheck: yes
47
# intelgpu: yes
48
# isc_dhcpd: yes
src/go/collectors/go.d.plugin/config/go.d/hpssa.conf
new
+5
@@ -0,0 +1,5 @@
1
+## All available configuration options, their descriptions and default values:
2
+## https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/hpssa#readme
3
+
4
+jobs:
5
+ - name: hpssa
src/go/collectors/go.d.plugin/modules/hpssa/charts.go
new
+403
@@ -0,0 +1,403 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+package hpssa
4
+
5
+import (
6
+ "fmt"
7
+ "strings"
8
+
9
+ "github.com/netdata/netdata/go/go.d.plugin/agent/module"
10
+)
11
+
12
+const (
13
+ prioControllerStatus = module.Priority + iota
14
+ prioControllerTemperature
15
+
16
+ prioControllerCacheModulePresenceStatus
17
+ prioControllerCacheModuleStatus
18
+ prioControllerCacheModuleTemperature
19
+ prioControllerCacheModuleBatteryStatus
20
+
21
+ prioArrayStatus
22
+
23
+ prioLogicalDriveStatus
24
+
25
+ prioPhysicalDriveStatus
26
+ prioPhysicalDriveTemperature
27
+)
28
+
29
+var controllerChartsTmpl = module.Charts{
30
+ controllerStatusChartTmpl.Copy(),
31
+ controllerTemperatureChartTmpl.Copy(),
32
+
33
+ controllerCacheModulePresenceStatusChartTmpl.Copy(),
34
+ controllerCacheModuleStatusChartTmpl.Copy(),
35
+ controllerCacheModuleTemperatureChartTmpl.Copy(),
36
+ controllerCacheModuleBatteryStatusChartTmpl.Copy(),
37
+}
38
+
39
+var (
40
+ controllerStatusChartTmpl = module.Chart{
41
+ ID: "cntrl_%s_slot_%s_status",
42
+ Title: "Controller status",
43
+ Units: "status",
44
+ Fam: "controllers",
45
+ Ctx: "hpssa.controller_status",
46
+ Type: module.Line,
47
+ Priority: prioControllerStatus,
48
+ Dims: module.Dims{
49
+ {ID: "cntrl_%s_slot_%s_status_ok", Name: "ok"},
50
+ {ID: "cntrl_%s_slot_%s_status_nok", Name: "nok"},
51
+ },
52
+ }
53
+ controllerTemperatureChartTmpl = module.Chart{
54
+ ID: "cntrl_%s_slot_%s_temperature",
55
+ Title: "Controller temperature",
56
+ Units: "Celsius",
57
+ Fam: "controllers",
58
+ Ctx: "hpssa.controller_temperature",
59
+ Type: module.Line,
60
+ Priority: prioControllerTemperature,
61
+ Dims: module.Dims{
62
+ {ID: "cntrl_%s_slot_%s_temperature", Name: "temperature"},
63
+ },
64
+ }
65
+
66
+ controllerCacheModulePresenceStatusChartTmpl = module.Chart{
67
+ ID: "cntrl_%s_slot_%s_cache_presence_status",
68
+ Title: "Controller cache module presence",
69
+ Units: "status",
70
+ Fam: "cache",
71
+ Ctx: "hpssa.controller_cache_module_presence_status",
72
+ Type: module.Line,
73
+ Priority: prioControllerCacheModulePresenceStatus,
74
+ Dims: module.Dims{
75
+ {ID: "cntrl_%s_slot_%s_cache_presence_status_present", Name: "present"},
76
+ {ID: "cntrl_%s_slot_%s_cache_presence_status_not_present", Name: "not_present"},
77
+ },
78
+ }
79
+ controllerCacheModuleStatusChartTmpl = module.Chart{
80
+ ID: "cntrl_%s_slot_%s_cache_status",
81
+ Title: "Controller cache module status",
82
+ Units: "status",
83
+ Fam: "cache",
84
+ Ctx: "hpssa.controller_cache_module_status",
85
+ Type: module.Line,
86
+ Priority: prioControllerCacheModuleStatus,
87
+ Dims: module.Dims{
88
+ {ID: "cntrl_%s_slot_%s_cache_status_ok", Name: "ok"},
89
+ {ID: "cntrl_%s_slot_%s_cache_status_nok", Name: "nok"},
90
+ },
91
+ }
92
+ controllerCacheModuleTemperatureChartTmpl = module.Chart{
93
+ ID: "cntrl_%s_slot_%s_cache_temperature",
94
+ Title: "Controller cache module temperature",
95
+ Units: "Celsius",
96
+ Fam: "cache",
97
+ Ctx: "hpssa.controller_cache_module_temperature",
98
+ Type: module.Line,
99
+ Priority: prioControllerCacheModuleTemperature,
100
+ Dims: module.Dims{
101
+ {ID: "cntrl_%s_slot_%s_cache_temperature", Name: "temperature"},
102
+ },
103
+ }
104
+ controllerCacheModuleBatteryStatusChartTmpl = module.Chart{
105
+ ID: "cntrl_%s_slot_%s_cache_battery_status",
106
+ Title: "Controller cache module battery status",
107
+ Units: "status",
108
+ Fam: "cache",
109
+ Ctx: "hpssa.controller_cache_module_battery status",
110
+ Type: module.Line,
111
+ Priority: prioControllerCacheModuleBatteryStatus,
112
+ Dims: module.Dims{
113
+ {ID: "cntrl_%s_slot_%s_cache_battery_status_ok", Name: "ok"},
114
+ {ID: "cntrl_%s_slot_%s_cache_battery_status_nok", Name: "nok"},
115
+ },
116
+ }
117
+)
118
+
119
+var arrayChartsTmpl = module.Charts{
120
+ arrayStatusChartTmpl.Copy(),
121
+}
122
+
123
+var (
124
+ arrayStatusChartTmpl = module.Chart{
125
+ ID: "array_%s_cntrl_%s_slot_%s_status",
126
+ Title: "Array status",
127
+ Units: "status",
128
+ Fam: "arrays",
129
+ Ctx: "hpssa.array_status",
130
+ Type: module.Line,
131
+ Priority: prioArrayStatus,
132
+ Dims: module.Dims{
133
+ {ID: "array_%s_cntrl_%s_slot_%s_status_ok", Name: "ok"},
134
+ {ID: "array_%s_cntrl_%s_slot_%s_status_nok", Name: "nok"},
135
+ },
136
+ }
137
+)
138
+
139
+var logicalDriveChartsTmpl = module.Charts{
140
+ logicalDriveStatusChartTmpl.Copy(),
141
+}
142
+
143
+var (
144
+ logicalDriveStatusChartTmpl = module.Chart{
145
+ ID: "ld_%s_array_%s_cntrl_%s_slot_%s_status",
146
+ Title: "Logical Drive status",
147
+ Units: "status",
148
+ Fam: "logical drives",
149
+ Ctx: "hpssa.logical_drive_status",
150
+ Type: module.Line,
151
+ Priority: prioLogicalDriveStatus,
152
+ Dims: module.Dims{
153
+ {ID: "ld_%s_array_%s_cntrl_%s_slot_%s_status_ok", Name: "ok"},
154
+ {ID: "ld_%s_array_%s_cntrl_%s_slot_%s_status_nok", Name: "nok"},
155
+ },
156
+ }
157
+)
158
+
159
+var physicalDriveChartsTmpl = module.Charts{
160
+ physicalDriveStatusChartTmpl.Copy(),
161
+ physicalDriveTemperatureChartTmpl.Copy(),
162
+}
163
+
164
+var (
165
+ physicalDriveStatusChartTmpl = module.Chart{
166
+ ID: "pd_%s_ld_%s_array_%s_cntrl_%s_slot_%s_status",
167
+ Title: "Physical Drive status",
168
+ Units: "status",
169
+ Fam: "physical drives",
170
+ Ctx: "hpssa.physical_drive_status",
171
+ Type: module.Line,
172
+ Priority: prioPhysicalDriveStatus,
173
+ Dims: module.Dims{
174
+ {ID: "pd_%s_ld_%s_array_%s_cntrl_%s_slot_%s_status_ok", Name: "ok"},
175
+ {ID: "pd_%s_ld_%s_array_%s_cntrl_%s_slot_%s_status_nok", Name: "nok"},
176
+ },
177
+ }
178
+ physicalDriveTemperatureChartTmpl = module.Chart{
179
+ ID: "pd_%s_ld_%s_array_%s_cntrl_%s_slot_%s_temperature",
180
+ Title: "Physical Drive temperature",
181
+ Units: "Celsius",
182
+ Fam: "physical drives",
183
+ Ctx: "hpssa.physical_drive_temperature",
184
+ Type: module.Line,
185
+ Priority: prioPhysicalDriveTemperature,
186
+ Dims: module.Dims{
187
+ {ID: "pd_%s_ld_%s_array_%s_cntrl_%s_slot_%s_temperature", Name: "temperature"},
188
+ },
189
+ }
190
+)
191
+
192
+func (h *Hpssa) updateCharts(controllers map[string]*hpssaController) {
193
+ seenControllers := make(map[string]bool)
194
+ seenArrays := make(map[string]bool)
195
+ seenLDrives := make(map[string]bool)
196
+ seenPDrives := make(map[string]bool)
197
+
198
+ for _, cntrl := range controllers {
199
+ key := cntrl.uniqueKey()
200
+ seenControllers[key] = true
201
+ if _, ok := h.seenControllers[key]; !ok {
202
+ h.seenControllers[key] = cntrl
203
+ h.addControllerCharts(cntrl)
204
+ }
205
+
206
+ for _, pd := range cntrl.unassignedDrives {
207
+ key := pd.uniqueKey()
208
+ seenPDrives[key] = true
209
+ if _, ok := h.seenPDrives[key]; !ok {
210
+ h.seenPDrives[key] = pd
211
+ h.addPhysicalDriveCharts(pd)
212
+ }
213
+ }
214
+
215
+ for _, arr := range cntrl.arrays {
216
+ key := arr.uniqueKey()
217
+ seenArrays[key] = true
218
+ if _, ok := h.seenArrays[key]; !ok {
219
+ h.seenArrays[key] = arr
220
+ h.addArrayCharts(arr)
221
+ }
222
+
223
+ for _, ld := range arr.logicalDrives {
224
+ key := ld.uniqueKey()
225
+ seenLDrives[key] = true
226
+ if _, ok := h.seenLDrives[key]; !ok {
227
+ h.seenLDrives[key] = ld
228
+ h.addLogicalDriveCharts(ld)
229
+ }
230
+
231
+ for _, pd := range ld.physicalDrives {
232
+ key := pd.uniqueKey()
233
+ seenPDrives[key] = true
234
+ if _, ok := h.seenPDrives[key]; !ok {
235
+ h.seenPDrives[key] = pd
236
+ h.addPhysicalDriveCharts(pd)
237
+ }
238
+ }
239
+ }
240
+ }
241
+ }
242
+
243
+ for k, cntrl := range h.seenControllers {
244
+ if !seenControllers[k] {
245
+ delete(h.seenControllers, k)
246
+ h.removeControllerCharts(cntrl)
247
+ }
248
+ }
249
+ for k, arr := range h.seenArrays {
250
+ if !seenArrays[k] {
251
+ delete(h.seenArrays, k)
252
+ h.removeArrayCharts(arr)
253
+ }
254
+ }
255
+ for k, ld := range h.seenLDrives {
256
+ if !seenLDrives[k] {
257
+ delete(h.seenLDrives, k)
258
+ h.removeLogicalDriveCharts(ld)
259
+ }
260
+ }
261
+ for k, pd := range h.seenPDrives {
262
+ if !seenPDrives[k] {
263
+ delete(h.seenPDrives, k)
264
+ h.removePhysicalDriveCharts(pd)
265
+ }
266
+ }
267
+}
268
+
269
+func (h *Hpssa) addControllerCharts(cntrl *hpssaController) {
270
+ charts := controllerChartsTmpl.Copy()
271
+
272
+ if cntrl.controllerTemperatureC == "" {
273
+ _ = charts.Remove(controllerTemperatureChartTmpl.ID)
274
+ }
275
+
276
+ if cntrl.cacheBoardPresent != "True" {
277
+ _ = charts.Remove(controllerCacheModuleStatusChartTmpl.ID)
278
+ _ = charts.Remove(controllerCacheModuleTemperatureChartTmpl.ID)
279
+ _ = charts.Remove(controllerCacheModuleBatteryStatusChartTmpl.ID)
280
+ }
281
+ if cntrl.cacheModuleTemperatureC == "" {
282
+ _ = charts.Remove(controllerCacheModuleTemperatureChartTmpl.ID)
283
+ }
284
+ if cntrl.batteryCapacitorStatus == "" {
285
+ _ = charts.Remove(controllerCacheModuleBatteryStatusChartTmpl.ID)
286
+ }
287
+
288
+ for _, chart := range *charts {
289
+ chart.ID = fmt.Sprintf(chart.ID, strings.ToLower(cntrl.model), cntrl.slot)
290
+ chart.Labels = []module.Label{
291
+ {Key: "slot", Value: cntrl.slot},
292
+ {Key: "model", Value: cntrl.model},
293
+ }
294
+ for _, dim := range chart.Dims {
295
+ dim.ID = fmt.Sprintf(dim.ID, cntrl.model, cntrl.slot)
296
+ }
297
+ }
298
+
299
+ if err := h.Charts().Add(*charts...); err != nil {
300
+ h.Warning(err)
301
+ }
302
+}
303
+
304
+func (h *Hpssa) removeControllerCharts(cntrl *hpssaController) {
305
+ px := fmt.Sprintf("cntrl_%s_slot_%s_", strings.ToLower(cntrl.model), cntrl.slot)
306
+ h.removeCharts(px)
307
+}
308
+
309
+func (h *Hpssa) addArrayCharts(arr *hpssaArray) {
310
+ charts := arrayChartsTmpl.Copy()
311
+
312
+ for _, chart := range *charts {
313
+ chart.ID = fmt.Sprintf(chart.ID, arr.id, strings.ToLower(arr.cntrl.model), arr.cntrl.slot)
314
+ chart.Labels = []module.Label{
315
+ {Key: "slot", Value: arr.cntrl.slot},
316
+ {Key: "array_id", Value: arr.id},
317
+ {Key: "interface_type", Value: arr.interfaceType},
318
+ {Key: "array_type", Value: arr.arrayType},
319
+ }
320
+ for _, dim := range chart.Dims {
321
+ dim.ID = fmt.Sprintf(dim.ID, arr.id, arr.cntrl.model, arr.cntrl.slot)
322
+ }
323
+ }
324
+
325
+ if err := h.Charts().Add(*charts...); err != nil {
326
+ h.Warning(err)
327
+ }
328
+}
329
+
330
+func (h *Hpssa) removeArrayCharts(arr *hpssaArray) {
331
+ px := fmt.Sprintf("array_%s_cntrl_%s_slot_%s_", arr.id, strings.ToLower(arr.cntrl.model), arr.cntrl.slot)
332
+ h.removeCharts(px)
333
+}
334
+
335
+func (h *Hpssa) addLogicalDriveCharts(ld *hpssaLogicalDrive) {
336
+ charts := logicalDriveChartsTmpl.Copy()
337
+
338
+ for _, chart := range *charts {
339
+ chart.ID = fmt.Sprintf(chart.ID, ld.id, ld.arr.id, strings.ToLower(ld.cntrl.model), ld.cntrl.slot)
340
+ chart.Labels = []module.Label{
341
+ {Key: "slot", Value: ld.cntrl.slot},
342
+ {Key: "array_id", Value: ld.arr.id},
343
+ {Key: "logical_drive_id", Value: ld.id},
344
+ {Key: "disk_name", Value: ld.diskName},
345
+ {Key: "drive_type", Value: ld.driveType},
346
+ }
347
+ for _, dim := range chart.Dims {
348
+ dim.ID = fmt.Sprintf(dim.ID, ld.id, ld.arr.id, ld.cntrl.model, ld.cntrl.slot)
349
+ }
350
+ }
351
+
352
+ if err := h.Charts().Add(*charts...); err != nil {
353
+ h.Warning(err)
354
+ }
355
+}
356
+
357
+func (h *Hpssa) removeLogicalDriveCharts(ld *hpssaLogicalDrive) {
358
+ px := fmt.Sprintf("ld_%s_array_%s_cntrl_%s_slot_%s_", ld.id, ld.arr.id, strings.ToLower(ld.cntrl.model), ld.cntrl.slot)
359
+ h.removeCharts(px)
360
+}
361
+
362
+func (h *Hpssa) addPhysicalDriveCharts(pd *hpssaPhysicalDrive) {
363
+ charts := physicalDriveChartsTmpl.Copy()
364
+
365
+ if pd.currentTemperatureC == "" {
366
+ _ = charts.Remove(physicalDriveTemperatureChartTmpl.ID)
367
+ }
368
+
369
+ for _, chart := range *charts {
370
+ chart.ID = fmt.Sprintf(chart.ID, pd.location, pd.ldId(), pd.arrId(), strings.ToLower(pd.cntrl.model), pd.cntrl.slot)
371
+ chart.Labels = []module.Label{
372
+ {Key: "slot", Value: pd.cntrl.slot},
373
+ {Key: "array_id", Value: pd.arrId()},
374
+ {Key: "logical_drive_id", Value: pd.ldId()},
375
+ {Key: "location", Value: pd.location},
376
+ {Key: "interface_type", Value: pd.interfaceType},
377
+ {Key: "drive_type", Value: pd.driveType},
378
+ {Key: "model", Value: pd.model},
379
+ }
380
+ for _, dim := range chart.Dims {
381
+ dim.ID = fmt.Sprintf(dim.ID, pd.location, pd.ldId(), pd.arrId(), pd.cntrl.model, pd.cntrl.slot)
382
+ }
383
+ }
384
+
385
+ if err := h.Charts().Add(*charts...); err != nil {
386
+ h.Warning(err)
387
+ }
388
+}
389
+
390
+func (h *Hpssa) removePhysicalDriveCharts(pd *hpssaPhysicalDrive) {
391
+ px := fmt.Sprintf("pd_%s_ld_%s_array_%s_cntrl_%s_slot_%s_",
392
+ pd.location, pd.ldId(), pd.arrId(), strings.ToLower(pd.cntrl.model), pd.cntrl.slot)
393
+ h.removeCharts(px)
394
+}
395
+
396
+func (h *Hpssa) removeCharts(prefix string) {
397
+ for _, chart := range *h.Charts() {
398
+ if strings.HasPrefix(chart.ID, prefix) {
399
+ chart.MarkRemove()
400
+ chart.MarkNotCreated()
401
+ }
402
+ }
403
+}
src/go/collectors/go.d.plugin/modules/hpssa/collect.go
new
+139
@@ -0,0 +1,139 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+package hpssa
4
+
5
+import (
6
+ "fmt"
7
+ "strconv"
8
+ "strings"
9
+)
10
+
11
+func (h *Hpssa) collect() (map[string]int64, error) {
12
+ data, err := h.exec.controllersInfo()
13
+ if err != nil {
14
+ return nil, err
15
+ }
16
+
17
+ controllers, err := parseSsacliControllersInfo(data)
18
+ if err != nil {
19
+ return nil, err
20
+ }
21
+
22
+ mx := make(map[string]int64)
23
+
24
+ h.collectControllers(mx, controllers)
25
+ h.updateCharts(controllers)
26
+
27
+ return mx, nil
28
+}
29
+
30
+func (h *Hpssa) collectControllers(mx map[string]int64, controllers map[string]*hpssaController) {
31
+ for _, cntrl := range controllers {
32
+ h.collectController(mx, cntrl)
33
+
34
+ for _, pd := range cntrl.unassignedDrives {
35
+ h.collectPhysicalDrive(mx, pd)
36
+ }
37
+
38
+ for _, arr := range cntrl.arrays {
39
+ h.collectArray(mx, arr)
40
+
41
+ for _, ld := range arr.logicalDrives {
42
+ h.collectLogicalDrive(mx, ld)
43
+
44
+ for _, pd := range ld.physicalDrives {
45
+ h.collectPhysicalDrive(mx, pd)
46
+ }
47
+ }
48
+ }
49
+ }
50
+}
51
+
52
+func (h *Hpssa) collectController(mx map[string]int64, cntrl *hpssaController) {
53
+ px := fmt.Sprintf("cntrl_%s_slot_%s_", cntrl.model, cntrl.slot)
54
+
55
+ writeStatusOkNok(mx, px, cntrl.controllerStatus)
56
+
57
+ if v, ok := parseNumber(cntrl.controllerTemperatureC); ok {
58
+ mx[px+"temperature"] = v
59
+ }
60
+
61
+ mx[px+"cache_presence_status_present"] = 0
62
+ mx[px+"cache_presence_status_not_present"] = 0
63
+ if cntrl.cacheBoardPresent != "True" {
64
+ mx[px+"cache_presence_status_not_present"] = 1
65
+ return
66
+ }
67
+
68
+ mx[px+"cache_presence_status_present"] = 1
69
+
70
+ writeStatusOkNok(mx, px+"cache_", cntrl.cacheStatus)
71
+
72
+ if v, ok := parseNumber(cntrl.cacheModuleTemperatureC); ok {
73
+ mx[px+"cache_temperature"] = v
74
+ }
75
+
76
+ writeStatusOkNok(mx, px+"cache_battery_", cntrl.batteryCapacitorStatus)
77
+}
78
+
79
+func (h *Hpssa) collectArray(mx map[string]int64, arr *hpssaArray) {
80
+ if arr.cntrl == nil {
81
+ return
82
+ }
83
+
84
+ px := fmt.Sprintf("array_%s_cntrl_%s_slot_%s_",
85
+ arr.id, arr.cntrl.model, arr.cntrl.slot)
86
+
87
+ writeStatusOkNok(mx, px, arr.status)
88
+}
89
+
90
+func (h *Hpssa) collectLogicalDrive(mx map[string]int64, ld *hpssaLogicalDrive) {
91
+ if ld.cntrl == nil || ld.arr == nil {
92
+ return
93
+ }
94
+
95
+ px := fmt.Sprintf("ld_%s_array_%s_cntrl_%s_slot_%s_",
96
+ ld.id, ld.arr.id, ld.cntrl.model, ld.cntrl.slot)
97
+
98
+ writeStatusOkNok(mx, px, ld.status)
99
+}
100
+
101
+func (h *Hpssa) collectPhysicalDrive(mx map[string]int64, pd *hpssaPhysicalDrive) {
102
+ if pd.cntrl == nil {
103
+ return
104
+ }
105
+
106
+ px := fmt.Sprintf("pd_%s_ld_%s_array_%s_cntrl_%s_slot_%s_",
107
+ pd.location, pd.ldId(), pd.arrId(), pd.cntrl.model, pd.cntrl.slot)
108
+
109
+ writeStatusOkNok(mx, px, pd.status)
110
+
111
+ if v, ok := parseNumber(pd.currentTemperatureC); ok {
112
+ mx[px+"temperature"] = v
113
+ }
114
+}
115
+
116
+func parseNumber(s string) (int64, bool) {
117
+ v, err := strconv.ParseFloat(s, 64)
118
+ if err != nil {
119
+ return 0, false
120
+ }
121
+ return int64(v), true
122
+}
123
+
124
+func writeStatusOkNok(mx map[string]int64, prefix, status string) {
125
+ if !strings.HasSuffix(prefix, "_") {
126
+ prefix += "_"
127
+ }
128
+
129
+ mx[prefix+"status_ok"] = 0
130
+ mx[prefix+"status_nok"] = 0
131
+
132
+ switch status {
133
+ case "":
134
+ case "OK":
135
+ mx[prefix+"status_ok"] = 1
136
+ default:
137
+ mx[prefix+"status_nok"] = 1
138
+ }
139
+}
src/go/collectors/go.d.plugin/modules/hpssa/config_schema.json
new
+35
@@ -0,0 +1,35 @@
1
+{
2
+ "jsonSchema": {
3
+ "$schema": "http://json-schema.org/draft-07/schema#",
4
+ "title": "HPSSA collector configuration.",
5
+ "type": "object",
6
+ "properties": {
7
+ "update_every": {
8
+ "title": "Update every",
9
+ "description": "Data collection interval, measured in seconds.",
10
+ "type": "integer",
11
+ "minimum": 1,
12
+ "default": 10
13
+ },
14
+ "timeout": {
15
+ "title": "Timeout",
16
+ "description": "Timeout for executing the `ssacli` binary, specified in seconds.",
17
+ "type": "number",
18
+ "minimum": 0.5,
19
+ "default": 2
20
+ }
21
+ },
22
+ "additionalProperties": false,
23
+ "patternProperties": {
24
+ "^name$": {}
25
+ }
26
+ },
27
+ "uiSchema": {
28
+ "uiOptions": {
29
+ "fullPage": true
30
+ },
31
+ "timeout": {
32
+ "ui:help": "Accepts decimals for precise control (e.g., type 1.5 for 1.5 seconds)."
33
+ }
34
+ }
35
+}
src/go/collectors/go.d.plugin/modules/hpssa/exec.go
new
+46
@@ -0,0 +1,46 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+package hpssa
4
+
5
+import (
6
+ "context"
7
+ "fmt"
8
+ "os/exec"
9
+ "time"
10
+
11
+ "github.com/netdata/netdata/go/go.d.plugin/logger"
12
+)
13
+
14
+func newSsacliExec(ndsudoPath string, timeout time.Duration, log *logger.Logger) *ssacliExec {
15
+ return &ssacliExec{
16
+ Logger: log,
17
+ ndsudoPath: ndsudoPath,
18
+ timeout: timeout,
19
+ }
20
+}
21
+
22
+type ssacliExec struct {
23
+ *logger.Logger
24
+
25
+ ndsudoPath string
26
+ timeout time.Duration
27
+}
28
+
29
+func (e *ssacliExec) controllersInfo() ([]byte, error) {
30
+ return e.execute("ssacli-controllers-info")
31
+}
32
+
33
+func (e *ssacliExec) execute(args ...string) ([]byte, error) {
34
+ ctx, cancel := context.WithTimeout(context.Background(), e.timeout)
35
+ defer cancel()
36
+
37
+ cmd := exec.CommandContext(ctx, e.ndsudoPath, args...)
38
+ e.Debugf("executing '%s'", cmd)
39
+
40
+ bs, err := cmd.Output()
41
+ if err != nil {
42
+ return nil, fmt.Errorf("error on '%s': %v", cmd, err)
43
+ }
44
+
45
+ return bs, nil
46
+}
src/go/collectors/go.d.plugin/modules/hpssa/hpssa.go
new
+110
@@ -0,0 +1,110 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+package hpssa
4
+
5
+import (
6
+ _ "embed"
7
+ "errors"
8
+ "time"
9
+
10
+ "github.com/netdata/netdata/go/go.d.plugin/agent/module"
11
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/web"
12
+)
13
+
14
+//go:embed "config_schema.json"
15
+var configSchema string
16
+
17
+func init() {
18
+ module.Register("hpssa", module.Creator{
19
+ JobConfigSchema: configSchema,
20
+ Defaults: module.Defaults{
21
+ UpdateEvery: 10,
22
+ },
23
+ Create: func() module.Module { return New() },
24
+ })
25
+}
26
+
27
+func New() *Hpssa {
28
+ return &Hpssa{
29
+ Config: Config{
30
+ Timeout: web.Duration(time.Second * 2),
31
+ },
32
+ charts: &module.Charts{},
33
+ seenControllers: make(map[string]*hpssaController),
34
+ seenArrays: make(map[string]*hpssaArray),
35
+ seenLDrives: make(map[string]*hpssaLogicalDrive),
36
+ seenPDrives: make(map[string]*hpssaPhysicalDrive),
37
+ }
38
+}
39
+
40
+type Config struct {
41
+ UpdateEvery int `yaml:"update_every" json:"update_every"`
42
+ Timeout web.Duration `yaml:"timeout" json:"timeout"`
43
+}
44
+
45
+type (
46
+ Hpssa struct {
47
+ module.Base
48
+ Config `yaml:",inline" json:""`
49
+
50
+ charts *module.Charts
51
+
52
+ exec ssacli
53
+
54
+ seenControllers map[string]*hpssaController
55
+ seenArrays map[string]*hpssaArray
56
+ seenLDrives map[string]*hpssaLogicalDrive
57
+ seenPDrives map[string]*hpssaPhysicalDrive
58
+ }
59
+ ssacli interface {
60
+ controllersInfo() ([]byte, error)
61
+ }
62
+)
63
+
64
+func (h *Hpssa) Configuration() any {
65
+ return h.Config
66
+}
67
+
68
+func (h *Hpssa) Init() error {
69
+ ssacliExec, err := h.initSsacliExec()
70
+ if err != nil {
71
+ h.Errorf("ssacli exec initialization: %v", err)
72
+ return err
73
+ }
74
+ h.exec = ssacliExec
75
+
76
+ return nil
77
+}
78
+
79
+func (h *Hpssa) Check() error {
80
+ mx, err := h.collect()
81
+ if err != nil {
82
+ h.Error(err)
83
+ return err
84
+ }
85
+
86
+ if len(mx) == 0 {
87
+ return errors.New("no metrics collected")
88
+ }
89
+
90
+ return nil
91
+}
92
+
93
+func (h *Hpssa) Charts() *module.Charts {
94
+ return h.charts
95
+}
96
+
97
+func (h *Hpssa) Collect() map[string]int64 {
98
+ mx, err := h.collect()
99
+ if err != nil {
100
+ h.Error(err)
101
+ }
102
+
103
+ if len(mx) == 0 {
104
+ return nil
105
+ }
106
+
107
+ return mx
108
+}
109
+
110
+func (h *Hpssa) Cleanup() {}
src/go/collectors/go.d.plugin/modules/hpssa/hpssa_test.go
new
+430
@@ -0,0 +1,430 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+package hpssa
4
+
5
+import (
6
+ "errors"
7
+ "os"
8
+ "testing"
9
+
10
+ "github.com/netdata/netdata/go/go.d.plugin/agent/module"
11
+
12
+ "github.com/stretchr/testify/assert"
13
+ "github.com/stretchr/testify/require"
14
+)
15
+
16
+var (
17
+ dataConfigJSON, _ = os.ReadFile("testdata/config.json")
18
+ dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
19
+
20
+ dataP212andP410i, _ = os.ReadFile("testdata/ssacli-P212_P410i.txt")
21
+ dataP400ar, _ = os.ReadFile("testdata/ssacli-P400ar.txt")
22
+ dataP400iUnassigned, _ = os.ReadFile("testdata/ssacli-P400i-unassigned.txt")
23
+)
24
+
25
+func Test_testDataIsValid(t *testing.T) {
26
+ for name, data := range map[string][]byte{
27
+ "dataConfigJSON": dataConfigJSON,
28
+ "dataConfigYAML": dataConfigYAML,
29
+
30
+ "dataP212andP410i": dataP212andP410i,
31
+ "dataP400ar": dataP400ar,
32
+ "dataP400iUnassigned": dataP400iUnassigned,
33
+ } {
34
+ require.NotNil(t, data, name)
35
+ }
36
+}
37
+
38
+func TestHpssa_Init(t *testing.T) {
39
+ tests := map[string]struct {
40
+ config Config
41
+ wantFail bool
42
+ }{
43
+ "fails if 'ndsudo' not found": {
44
+ wantFail: true,
45
+ config: New().Config,
46
+ },
47
+ }
48
+
49
+ for name, test := range tests {
50
+ t.Run(name, func(t *testing.T) {
51
+ hpe := New()
52
+
53
+ if test.wantFail {
54
+ assert.Error(t, hpe.Init())
55
+ } else {
56
+ assert.NoError(t, hpe.Init())
57
+ }
58
+ })
59
+ }
60
+}
61
+
62
+func TestHpssa_Cleanup(t *testing.T) {
63
+ tests := map[string]struct {
64
+ prepare func() *Hpssa
65
+ }{
66
+ "not initialized exec": {
67
+ prepare: func() *Hpssa {
68
+ return New()
69
+ },
70
+ },
71
+ "after check": {
72
+ prepare: func() *Hpssa {
73
+ hpe := New()
74
+ hpe.exec = prepareMockOkP212andP410i()
75
+ _ = hpe.Check()
76
+ return hpe
77
+ },
78
+ },
79
+ "after collect": {
80
+ prepare: func() *Hpssa {
81
+ hpe := New()
82
+ hpe.exec = prepareMockOkP212andP410i()
83
+ _ = hpe.Collect()
84
+ return hpe
85
+ },
86
+ },
87
+ }
88
+
89
+ for name, test := range tests {
90
+ t.Run(name, func(t *testing.T) {
91
+ hpe := test.prepare()
92
+
93
+ assert.NotPanics(t, hpe.Cleanup)
94
+ })
95
+ }
96
+}
97
+
98
+func TestHpssa_Charts(t *testing.T) {
99
+ assert.NotNil(t, New().Charts())
100
+}
101
+
102
+func TestHpssa_Check(t *testing.T) {
103
+ tests := map[string]struct {
104
+ prepareMock func() *mockSsacliExec
105
+ wantFail bool
106
+ }{
107
+ "success P212 and P410i": {
108
+ wantFail: false,
109
+ prepareMock: prepareMockOkP212andP410i,
110
+ },
111
+ "success P400ar": {
112
+ wantFail: false,
113
+ prepareMock: prepareMockOkP400ar,
114
+ },
115
+ "success P400i with Unassigned": {
116
+ wantFail: false,
117
+ prepareMock: prepareMockOkP400iUnassigned,
118
+ },
119
+ "fails if error on controllersInfo()": {
120
+ wantFail: true,
121
+ prepareMock: prepareMockErr,
122
+ },
123
+ "fails if empty response": {
124
+ wantFail: true,
125
+ prepareMock: prepareMockEmptyResponse,
126
+ },
127
+ "fails if unexpected response": {
128
+ wantFail: true,
129
+ prepareMock: prepareMockUnexpectedResponse,
130
+ },
131
+ }
132
+
133
+ for name, test := range tests {
134
+ t.Run(name, func(t *testing.T) {
135
+ hpe := New()
136
+ mock := test.prepareMock()
137
+ hpe.exec = mock
138
+
139
+ if test.wantFail {
140
+ assert.Error(t, hpe.Check())
141
+ } else {
142
+ assert.NoError(t, hpe.Check())
143
+ }
144
+ })
145
+ }
146
+}
147
+
148
+func TestHpssa_Collect(t *testing.T) {
149
+ tests := map[string]struct {
150
+ prepareMock func() *mockSsacliExec
151
+ wantMetrics map[string]int64
152
+ wantCharts int
153
+ }{
154
+ "success P212 and P410i": {
155
+ prepareMock: prepareMockOkP212andP410i,
156
+ wantCharts: (len(controllerChartsTmpl)*2 - 6) +
157
+ len(arrayChartsTmpl)*3 +
158
+ len(logicalDriveChartsTmpl)*3 +
159
+ len(physicalDriveChartsTmpl)*18,
160
+ wantMetrics: map[string]int64{
161
+ "array_A_cntrl_P212_slot_5_status_nok": 0,
162
+ "array_A_cntrl_P212_slot_5_status_ok": 1,
163
+ "array_A_cntrl_P410i_slot_0_status_nok": 0,
164
+ "array_A_cntrl_P410i_slot_0_status_ok": 1,
165
+ "array_B_cntrl_P410i_slot_0_status_nok": 0,
166
+ "array_B_cntrl_P410i_slot_0_status_ok": 1,
167
+ "cntrl_P212_slot_5_cache_battery_status_nok": 0,
168
+ "cntrl_P212_slot_5_cache_battery_status_ok": 0,
169
+ "cntrl_P212_slot_5_cache_presence_status_not_present": 0,
170
+ "cntrl_P212_slot_5_cache_presence_status_present": 1,
171
+ "cntrl_P212_slot_5_cache_status_nok": 0,
172
+ "cntrl_P212_slot_5_cache_status_ok": 1,
173
+ "cntrl_P212_slot_5_status_nok": 0,
174
+ "cntrl_P212_slot_5_status_ok": 1,
175
+ "cntrl_P410i_slot_0_cache_battery_status_nok": 0,
176
+ "cntrl_P410i_slot_0_cache_battery_status_ok": 0,
177
+ "cntrl_P410i_slot_0_cache_presence_status_not_present": 0,
178
+ "cntrl_P410i_slot_0_cache_presence_status_present": 1,
179
+ "cntrl_P410i_slot_0_cache_status_nok": 0,
180
+ "cntrl_P410i_slot_0_cache_status_ok": 1,
181
+ "cntrl_P410i_slot_0_status_nok": 0,
182
+ "cntrl_P410i_slot_0_status_ok": 1,
183
+ "ld_1_array_A_cntrl_P212_slot_5_status_nok": 0,
184
+ "ld_1_array_A_cntrl_P212_slot_5_status_ok": 1,
185
+ "ld_1_array_A_cntrl_P410i_slot_0_status_nok": 0,
186
+ "ld_1_array_A_cntrl_P410i_slot_0_status_ok": 1,
187
+ "ld_2_array_B_cntrl_P410i_slot_0_status_nok": 0,
188
+ "ld_2_array_B_cntrl_P410i_slot_0_status_ok": 1,
189
+ "pd_1I:1:1_ld_2_array_B_cntrl_P410i_slot_0_status_nok": 0,
190
+ "pd_1I:1:1_ld_2_array_B_cntrl_P410i_slot_0_status_ok": 1,
191
+ "pd_1I:1:1_ld_2_array_B_cntrl_P410i_slot_0_temperature": 37,
192
+ "pd_1I:1:2_ld_2_array_B_cntrl_P410i_slot_0_status_nok": 0,
193
+ "pd_1I:1:2_ld_2_array_B_cntrl_P410i_slot_0_status_ok": 1,
194
+ "pd_1I:1:2_ld_2_array_B_cntrl_P410i_slot_0_temperature": 37,
195
+ "pd_1I:1:3_ld_2_array_B_cntrl_P410i_slot_0_status_nok": 0,
196
+ "pd_1I:1:3_ld_2_array_B_cntrl_P410i_slot_0_status_ok": 1,
197
+ "pd_1I:1:3_ld_2_array_B_cntrl_P410i_slot_0_temperature": 43,
198
+ "pd_1I:1:4_ld_2_array_B_cntrl_P410i_slot_0_status_nok": 0,
199
+ "pd_1I:1:4_ld_2_array_B_cntrl_P410i_slot_0_status_ok": 1,
200
+ "pd_1I:1:4_ld_2_array_B_cntrl_P410i_slot_0_temperature": 44,
201
+ "pd_2E:1:10_ld_na_array_na_cntrl_P212_slot_5_status_nok": 0,
202
+ "pd_2E:1:10_ld_na_array_na_cntrl_P212_slot_5_status_ok": 1,
203
+ "pd_2E:1:10_ld_na_array_na_cntrl_P212_slot_5_temperature": 35,
204
+ "pd_2E:1:11_ld_na_array_na_cntrl_P212_slot_5_status_nok": 0,
205
+ "pd_2E:1:11_ld_na_array_na_cntrl_P212_slot_5_status_ok": 1,
206
+ "pd_2E:1:11_ld_na_array_na_cntrl_P212_slot_5_temperature": 34,
207
+ "pd_2E:1:12_ld_na_array_na_cntrl_P212_slot_5_status_nok": 0,
208
+ "pd_2E:1:12_ld_na_array_na_cntrl_P212_slot_5_status_ok": 1,
209
+ "pd_2E:1:12_ld_na_array_na_cntrl_P212_slot_5_temperature": 31,
210
+ "pd_2E:1:1_ld_1_array_A_cntrl_P212_slot_5_status_nok": 0,
211
+ "pd_2E:1:1_ld_1_array_A_cntrl_P212_slot_5_status_ok": 1,
212
+ "pd_2E:1:1_ld_1_array_A_cntrl_P212_slot_5_temperature": 33,
213
+ "pd_2E:1:2_ld_1_array_A_cntrl_P212_slot_5_status_nok": 0,
214
+ "pd_2E:1:2_ld_1_array_A_cntrl_P212_slot_5_status_ok": 1,
215
+ "pd_2E:1:2_ld_1_array_A_cntrl_P212_slot_5_temperature": 34,
216
+ "pd_2E:1:3_ld_1_array_A_cntrl_P212_slot_5_status_nok": 0,
217
+ "pd_2E:1:3_ld_1_array_A_cntrl_P212_slot_5_status_ok": 1,
218
+ "pd_2E:1:3_ld_1_array_A_cntrl_P212_slot_5_temperature": 35,
219
+ "pd_2E:1:4_ld_1_array_A_cntrl_P212_slot_5_status_nok": 0,
220
+ "pd_2E:1:4_ld_1_array_A_cntrl_P212_slot_5_status_ok": 1,
221
+ "pd_2E:1:4_ld_1_array_A_cntrl_P212_slot_5_temperature": 35,
222
+ "pd_2E:1:5_ld_1_array_A_cntrl_P212_slot_5_status_nok": 0,
223
+ "pd_2E:1:5_ld_1_array_A_cntrl_P212_slot_5_status_ok": 1,
224
+ "pd_2E:1:5_ld_1_array_A_cntrl_P212_slot_5_temperature": 34,
225
+ "pd_2E:1:6_ld_1_array_A_cntrl_P212_slot_5_status_nok": 0,
226
+ "pd_2E:1:6_ld_1_array_A_cntrl_P212_slot_5_status_ok": 1,
227
+ "pd_2E:1:6_ld_1_array_A_cntrl_P212_slot_5_temperature": 33,
228
+ "pd_2E:1:7_ld_na_array_na_cntrl_P212_slot_5_status_nok": 0,
229
+ "pd_2E:1:7_ld_na_array_na_cntrl_P212_slot_5_status_ok": 1,
230
+ "pd_2E:1:7_ld_na_array_na_cntrl_P212_slot_5_temperature": 30,
231
+ "pd_2E:1:8_ld_na_array_na_cntrl_P212_slot_5_status_nok": 0,
232
+ "pd_2E:1:8_ld_na_array_na_cntrl_P212_slot_5_status_ok": 1,
233
+ "pd_2E:1:8_ld_na_array_na_cntrl_P212_slot_5_temperature": 33,
234
+ "pd_2E:1:9_ld_na_array_na_cntrl_P212_slot_5_status_nok": 0,
235
+ "pd_2E:1:9_ld_na_array_na_cntrl_P212_slot_5_status_ok": 1,
236
+ "pd_2E:1:9_ld_na_array_na_cntrl_P212_slot_5_temperature": 30,
237
+ "pd_2I:1:5_ld_1_array_A_cntrl_P410i_slot_0_status_nok": 0,
238
+ "pd_2I:1:5_ld_1_array_A_cntrl_P410i_slot_0_status_ok": 1,
239
+ "pd_2I:1:5_ld_1_array_A_cntrl_P410i_slot_0_temperature": 38,
240
+ "pd_2I:1:6_ld_1_array_A_cntrl_P410i_slot_0_status_nok": 0,
241
+ "pd_2I:1:6_ld_1_array_A_cntrl_P410i_slot_0_status_ok": 1,
242
+ "pd_2I:1:6_ld_1_array_A_cntrl_P410i_slot_0_temperature": 36,
243
+ },
244
+ },
245
+ "success P400ar": {
246
+ prepareMock: prepareMockOkP400ar,
247
+ wantCharts: len(controllerChartsTmpl)*1 +
248
+ len(arrayChartsTmpl)*2 +
249
+ len(logicalDriveChartsTmpl)*2 +
250
+ len(physicalDriveChartsTmpl)*8,
251
+ wantMetrics: map[string]int64{
252
+ "array_A_cntrl_P440ar_slot_0_status_nok": 0,
253
+ "array_A_cntrl_P440ar_slot_0_status_ok": 1,
254
+ "array_B_cntrl_P440ar_slot_0_status_nok": 0,
255
+ "array_B_cntrl_P440ar_slot_0_status_ok": 1,
256
+ "cntrl_P440ar_slot_0_cache_battery_status_nok": 0,
257
+ "cntrl_P440ar_slot_0_cache_battery_status_ok": 1,
258
+ "cntrl_P440ar_slot_0_cache_presence_status_not_present": 0,
259
+ "cntrl_P440ar_slot_0_cache_presence_status_present": 1,
260
+ "cntrl_P440ar_slot_0_cache_status_nok": 0,
261
+ "cntrl_P440ar_slot_0_cache_status_ok": 1,
262
+ "cntrl_P440ar_slot_0_cache_temperature": 41,
263
+ "cntrl_P440ar_slot_0_status_nok": 0,
264
+ "cntrl_P440ar_slot_0_status_ok": 1,
265
+ "cntrl_P440ar_slot_0_temperature": 47,
266
+ "ld_1_array_A_cntrl_P440ar_slot_0_status_nok": 0,
267
+ "ld_1_array_A_cntrl_P440ar_slot_0_status_ok": 1,
268
+ "ld_2_array_B_cntrl_P440ar_slot_0_status_nok": 0,
269
+ "ld_2_array_B_cntrl_P440ar_slot_0_status_ok": 1,
270
+ "pd_1I:1:1_ld_1_array_A_cntrl_P440ar_slot_0_status_nok": 0,
271
+ "pd_1I:1:1_ld_1_array_A_cntrl_P440ar_slot_0_status_ok": 1,
272
+ "pd_1I:1:1_ld_1_array_A_cntrl_P440ar_slot_0_temperature": 27,
273
+ "pd_1I:1:2_ld_1_array_A_cntrl_P440ar_slot_0_status_nok": 0,
274
+ "pd_1I:1:2_ld_1_array_A_cntrl_P440ar_slot_0_status_ok": 1,
275
+ "pd_1I:1:2_ld_1_array_A_cntrl_P440ar_slot_0_temperature": 28,
276
+ "pd_1I:1:3_ld_1_array_A_cntrl_P440ar_slot_0_status_nok": 0,
277
+ "pd_1I:1:3_ld_1_array_A_cntrl_P440ar_slot_0_status_ok": 1,
278
+ "pd_1I:1:3_ld_1_array_A_cntrl_P440ar_slot_0_temperature": 27,
279
+ "pd_1I:1:4_ld_2_array_B_cntrl_P440ar_slot_0_status_nok": 0,
280
+ "pd_1I:1:4_ld_2_array_B_cntrl_P440ar_slot_0_status_ok": 1,
281
+ "pd_1I:1:4_ld_2_array_B_cntrl_P440ar_slot_0_temperature": 30,
282
+ "pd_2I:1:5_ld_1_array_A_cntrl_P440ar_slot_0_status_nok": 0,
283
+ "pd_2I:1:5_ld_1_array_A_cntrl_P440ar_slot_0_status_ok": 1,
284
+ "pd_2I:1:5_ld_1_array_A_cntrl_P440ar_slot_0_temperature": 26,
285
+ "pd_2I:1:6_ld_1_array_A_cntrl_P440ar_slot_0_status_nok": 0,
286
+ "pd_2I:1:6_ld_1_array_A_cntrl_P440ar_slot_0_status_ok": 1,
287
+ "pd_2I:1:6_ld_1_array_A_cntrl_P440ar_slot_0_temperature": 28,
288
+ "pd_2I:1:7_ld_1_array_A_cntrl_P440ar_slot_0_status_nok": 0,
289
+ "pd_2I:1:7_ld_1_array_A_cntrl_P440ar_slot_0_status_ok": 1,
290
+ "pd_2I:1:7_ld_1_array_A_cntrl_P440ar_slot_0_temperature": 27,
291
+ "pd_2I:1:8_ld_2_array_B_cntrl_P440ar_slot_0_status_nok": 0,
292
+ "pd_2I:1:8_ld_2_array_B_cntrl_P440ar_slot_0_status_ok": 1,
293
+ "pd_2I:1:8_ld_2_array_B_cntrl_P440ar_slot_0_temperature": 29,
294
+ },
295
+ },
296
+ "success P400i with Unassigned": {
297
+ prepareMock: prepareMockOkP400iUnassigned,
298
+ wantCharts: (len(controllerChartsTmpl)*1 - 2) +
299
+ len(arrayChartsTmpl)*1 +
300
+ len(logicalDriveChartsTmpl)*1 +
301
+ len(physicalDriveChartsTmpl)*4,
302
+ wantMetrics: map[string]int64{
303
+ "array_A_cntrl_P400i_slot_0_status_nok": 0,
304
+ "array_A_cntrl_P400i_slot_0_status_ok": 1,
305
+ "cntrl_P400i_slot_0_cache_battery_status_nok": 1,
306
+ "cntrl_P400i_slot_0_cache_battery_status_ok": 0,
307
+ "cntrl_P400i_slot_0_cache_presence_status_not_present": 0,
308
+ "cntrl_P400i_slot_0_cache_presence_status_present": 1,
309
+ "cntrl_P400i_slot_0_cache_status_nok": 1,
310
+ "cntrl_P400i_slot_0_cache_status_ok": 0,
311
+ "cntrl_P400i_slot_0_status_nok": 0,
312
+ "cntrl_P400i_slot_0_status_ok": 1,
313
+ "ld_1_array_A_cntrl_P400i_slot_0_status_nok": 0,
314
+ "ld_1_array_A_cntrl_P400i_slot_0_status_ok": 1,
315
+ "pd_1I:1:1_ld_na_array_na_cntrl_P400i_slot_0_status_nok": 0,
316
+ "pd_1I:1:1_ld_na_array_na_cntrl_P400i_slot_0_status_ok": 1,
317
+ "pd_1I:1:1_ld_na_array_na_cntrl_P400i_slot_0_temperature": 28,
318
+ "pd_1I:1:2_ld_na_array_na_cntrl_P400i_slot_0_status_nok": 0,
319
+ "pd_1I:1:2_ld_na_array_na_cntrl_P400i_slot_0_status_ok": 1,
320
+ "pd_1I:1:2_ld_na_array_na_cntrl_P400i_slot_0_temperature": 28,
321
+ "pd_1I:1:3_ld_1_array_A_cntrl_P400i_slot_0_status_nok": 0,
322
+ "pd_1I:1:3_ld_1_array_A_cntrl_P400i_slot_0_status_ok": 1,
323
+ "pd_1I:1:3_ld_1_array_A_cntrl_P400i_slot_0_temperature": 23,
324
+ "pd_1I:1:4_ld_1_array_A_cntrl_P400i_slot_0_status_nok": 0,
325
+ "pd_1I:1:4_ld_1_array_A_cntrl_P400i_slot_0_status_ok": 1,
326
+ "pd_1I:1:4_ld_1_array_A_cntrl_P400i_slot_0_temperature": 23,
327
+ },
328
+ },
329
+ "fails if error on controllersInfo()": {
330
+ prepareMock: prepareMockErr,
331
+ wantMetrics: nil,
332
+ wantCharts: 0,
333
+ },
334
+ "fails if empty response": {
335
+ prepareMock: prepareMockEmptyResponse,
336
+ wantMetrics: nil,
337
+ wantCharts: 0,
338
+ },
339
+ "fails if unexpected response": {
340
+ prepareMock: prepareMockUnexpectedResponse,
341
+ wantMetrics: nil,
342
+ wantCharts: 0,
343
+ },
344
+ }
345
+
346
+ for name, test := range tests {
347
+ t.Run(name, func(t *testing.T) {
348
+ hpe := New()
349
+ mock := test.prepareMock()
350
+ hpe.exec = mock
351
+
352
+ mx := hpe.Collect()
353
+
354
+ assert.Equal(t, test.wantMetrics, mx)
355
+ assert.Len(t, *hpe.Charts(), test.wantCharts)
356
+ testMetricsHasAllChartsDims(t, hpe, mx)
357
+ })
358
+ }
359
+}
360
+
361
+func TestHpssa_ConfigurationSerialize(t *testing.T) {
362
+ module.TestConfigurationSerialize(t, &Hpssa{}, dataConfigJSON, dataConfigYAML)
363
+}
364
+
365
+func prepareMockOkP212andP410i() *mockSsacliExec {
366
+ return &mockSsacliExec{
367
+ infoData: dataP212andP410i,
368
+ }
369
+}
370
+
371
+func prepareMockOkP400ar() *mockSsacliExec {
372
+ return &mockSsacliExec{
373
+ infoData: dataP400ar,
374
+ }
375
+}
376
+
377
+func prepareMockOkP400iUnassigned() *mockSsacliExec {
378
+ return &mockSsacliExec{
379
+ infoData: dataP400iUnassigned,
380
+ }
381
+}
382
+
383
+func prepareMockErr() *mockSsacliExec {
384
+ return &mockSsacliExec{
385
+ errOnInfo: true,
386
+ }
387
+}
388
+
389
+func prepareMockEmptyResponse() *mockSsacliExec {
390
+ return &mockSsacliExec{}
391
+}
392
+
393
+func prepareMockUnexpectedResponse() *mockSsacliExec {
394
+ resp := []byte(`
395
+Lorem ipsum dolor sit amet, consectetur adipiscing elit.
396
+Nulla malesuada erat id magna mattis, eu viverra tellus rhoncus.
397
+Fusce et felis pulvinar, posuere sem non, porttitor eros.
398
+`)
399
+ return &mockSsacliExec{
400
+ infoData: resp,
401
+ }
402
+}
403
+
404
+type mockSsacliExec struct {
405
+ errOnInfo bool
406
+ infoData []byte
407
+}
408
+
409
+func (m *mockSsacliExec) controllersInfo() ([]byte, error) {
410
+ if m.errOnInfo {
411
+ return nil, errors.New("mock.controllersInfo() error")
412
+ }
413
+ return m.infoData, nil
414
+}
415
+
416
+func testMetricsHasAllChartsDims(t *testing.T, hpe *Hpssa, mx map[string]int64) {
417
+ for _, chart := range *hpe.Charts() {
418
+ if chart.Obsolete {
419
+ continue
420
+ }
421
+ for _, dim := range chart.Dims {
422
+ _, ok := mx[dim.ID]
423
+ assert.Truef(t, ok, "collected metrics has no data for dim '%s' chart '%s'", dim.ID, chart.ID)
424
+ }
425
+ for _, v := range chart.Vars {
426
+ _, ok := mx[v.ID]
427
+ assert.Truef(t, ok, "collected metrics has no data for var '%s' chart '%s'", v.ID, chart.ID)
428
+ }
429
+ }
430
+}
src/go/collectors/go.d.plugin/modules/hpssa/init.go
new
+23
@@ -0,0 +1,23 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+package hpssa
4
+
5
+import (
6
+ "fmt"
7
+ "os"
8
+ "path/filepath"
9
+
10
+ "github.com/netdata/netdata/go/go.d.plugin/agent/executable"
11
+)
12
+
13
+func (h *Hpssa) initSsacliExec() (ssacli, error) {
14
+ ndsudoPath := filepath.Join(executable.Directory, "ndsudo")
15
+
16
+ if _, err := os.Stat(ndsudoPath); err != nil {
17
+ return nil, fmt.Errorf("ndsudo executable not found: %v", err)
18
+ }
19
+
20
+ ssacliExec := newSsacliExec(ndsudoPath, h.Timeout.Duration(), h.Logger)
21
+
22
+ return ssacliExec, nil
23
+}
src/go/collectors/go.d.plugin/modules/hpssa/metadata.yaml
new
+213
@@ -0,0 +1,213 @@
1
+plugin_name: go.d.plugin
2
+modules:
3
+ - meta:
4
+ id: collector-go.d.plugin-hpssa
5
+ plugin_name: go.d.plugin
6
+ module_name: hpssa
7
+ monitored_instance:
8
+ name: HPE Smart Arrays
9
+ link: "https://buy.hpe.com/us/en/options/controller-controller-options/smart-array-controllers-smart-host-bus-adapters/c/7109730"
10
+ icon_filename: "hp.svg"
11
+ categories:
12
+ - data-collection.storage-mount-points-and-filesystems
13
+ keywords:
14
+ - storage
15
+ - raid-controller
16
+ - hp
17
+ - hpssa
18
+ - array
19
+ related_resources:
20
+ integrations:
21
+ list: []
22
+ info_provided_to_referring_integrations:
23
+ description: ""
24
+ most_popular: false
25
+ overview:
26
+ data_collection:
27
+ metrics_description: |
28
+ Monitors the health of HPE Smart Arrays by tracking the status of controllers, arrays, logical and physical drives in your storage system.
29
+ It relies on the `ssacli` CLI tool but avoids directly executing the binary.
30
+ Instead, it utilizes `ndsudo`, a Netdata helper specifically designed to run privileged commands securely within the Netdata environment.
31
+ This approach eliminates the need to use `sudo`, improving security and potentially simplifying permission management.
32
+
33
+ Executed commands:
34
+ - `ssacli ctrl all show config detail`
35
+ method_description: ""
36
+ supported_platforms:
37
+ include: []
38
+ exclude: []
39
+ multi_instance: false
40
+ additional_permissions:
41
+ description: ""
42
+ default_behavior:
43
+ auto_detection:
44
+ description: ""
45
+ limits:
46
+ description: ""
47
+ performance_impact:
48
+ description: ""
49
+ setup:
50
+ prerequisites:
51
+ list:
52
+ - title: Install ssacli
53
+ description: |
54
+ See [official installation instructions](https://support.hpe.com/connect/s/softwaredetails?language=en_US&collectionId=MTX-0cb3f808e2514d3d).
55
+ configuration:
56
+ file:
57
+ name: go.d/ssacli.conf
58
+ options:
59
+ description: |
60
+ The following options can be defined globally: update_every.
61
+ folding:
62
+ title: Config options
63
+ enabled: true
64
+ list:
65
+ - name: update_every
66
+ description: Data collection frequency.
67
+ default_value: 10
68
+ required: false
69
+ - name: timeout
70
+ description: ssacli binary execution timeout.
71
+ default_value: 2
72
+ required: false
73
+ examples:
74
+ folding:
75
+ title: Config
76
+ enabled: true
77
+ list:
78
+ - name: Custom update_every
79
+ description: Allows you to override the default data collection interval.
80
+ config: |
81
+ jobs:
82
+ - name: hpssa
83
+ update_every: 5 # Collect HPE Smart Array statistics every 5 seconds
84
+ troubleshooting:
85
+ problems:
86
+ list: []
87
+ alerts: []
88
+ metrics:
89
+ folding:
90
+ title: Metrics
91
+ enabled: false
92
+ description: ""
93
+ availability: []
94
+ scopes:
95
+ - name: controller
96
+ description: These metrics refer to the Controller.
97
+ labels:
98
+ - name: slot
99
+ description: Slot number
100
+ - name: model
101
+ description: Controller model
102
+ metrics:
103
+ - name: hpssa.controller_status
104
+ description: Controller status
105
+ unit: status
106
+ chart_type: line
107
+ dimensions:
108
+ - name: ok
109
+ - name: nok
110
+ - name: hpssa.controller_temperature
111
+ description: Controller temperature
112
+ unit: Celsius
113
+ chart_type: line
114
+ dimensions:
115
+ - name: temperature
116
+ - name: hpssa.controller_cache_module_presence_status
117
+ description: Controller cache module presence
118
+ unit: status
119
+ chart_type: line
120
+ dimensions:
121
+ - name: present
122
+ - name: not_present
123
+ - name: hpssa.controller_cache_module_status
124
+ description: Controller cache module status
125
+ unit: status
126
+ chart_type: line
127
+ dimensions:
128
+ - name: ok
129
+ - name: nok
130
+ - name: hpssa.controller_cache_module_temperature
131
+ description: Controller cache module temperature
132
+ unit: Celsius
133
+ chart_type: line
134
+ dimensions:
135
+ - name: temperature
136
+ - name: hpssa.controller_cache_module_battery status
137
+ description: Controller cache module battery status
138
+ unit: status
139
+ chart_type: line
140
+ dimensions:
141
+ - name: ok
142
+ - name: nok
143
+ - name: array
144
+ description: These metrics refer to the Array.
145
+ labels:
146
+ - name: slot
147
+ description: Slot number
148
+ - name: array_id
149
+ description: Array id
150
+ - name: interface_type
151
+ description: Array interface type (e.g. SATA)
152
+ - name: array_type
153
+ description: Array type (e.g. Data)
154
+ metrics:
155
+ - name: hpssa.array_status
156
+ description: Array status
157
+ unit: status
158
+ chart_type: line
159
+ dimensions:
160
+ - name: ok
161
+ - name: nok
162
+ - name: logical drive
163
+ description: These metrics refer to the Logical Drive.
164
+ labels:
165
+ - name: slot
166
+ description: Slot number
167
+ - name: array_id
168
+ description: Array id
169
+ - name: logical_drive_id
170
+ description: Logical Drive id (number)
171
+ - name: disk_name
172
+ description: Disk name (e.g. /dev/sda)
173
+ - name: drive_type
174
+ description: Drive type (e.g. Data)
175
+ metrics:
176
+ - name: hpssa.logical_drive_status
177
+ description: Logical Drive status
178
+ unit: status
179
+ chart_type: line
180
+ dimensions:
181
+ - name: ok
182
+ - name: nok
183
+ - name: physical drive
184
+ description: These metrics refer to the Physical Drive.
185
+ labels:
186
+ - name: slot
187
+ description: Slot number
188
+ - name: array_id
189
+ description: Array id or "na" if unassigned
190
+ - name: logical_drive_id
191
+ description: Logical Drive id or "na" if unassigned
192
+ - name: location
193
+ description: Drive location in port:box:bay format (e.g. 1I:1:1)
194
+ - name: interface_type
195
+ description: Drive interface type (e.g. SATA)
196
+ - name: drive_type
197
+ description: Drive type (e.g. Data Drive, Unassigned Drive)
198
+ - name: model
199
+ description: Drive model
200
+ metrics:
201
+ - name: hpssa.physical_drive_status
202
+ description: Physical Drive status
203
+ unit: status
204
+ chart_type: line
205
+ dimensions:
206
+ - name: ok
207
+ - name: nok
208
+ - name: hpssa.physical_drive_temperature
209
+ description: Physical Drive temperature
210
+ unit: status
211
+ chart_type: line
212
+ dimensions:
213
+ - name: temperature
src/go/collectors/go.d.plugin/modules/hpssa/parse.go
new
+364
@@ -0,0 +1,364 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+package hpssa
4
+
5
+import (
6
+ "bufio"
7
+ "bytes"
8
+ "fmt"
9
+ "strings"
10
+)
11
+
12
+type hpssaController struct {
13
+ model string
14
+ slot string
15
+ serialNumber string
16
+ controllerStatus string
17
+ cacheBoardPresent string
18
+ cacheStatus string
19
+ cacheRatio string
20
+ batteryCapacitorCount string
21
+ batteryCapacitorStatus string
22
+ controllerTemperatureC string
23
+ cacheModuleTemperatureC string
24
+ numberOfPorts string
25
+ driverName string
26
+ arrays map[string]*hpssaArray
27
+ unassignedDrives map[string]*hpssaPhysicalDrive
28
+}
29
+
30
+func (c *hpssaController) uniqueKey() string {
31
+ return fmt.Sprintf("%s/%s", c.model, c.slot)
32
+}
33
+
34
+type hpssaArray struct {
35
+ cntrl *hpssaController
36
+
37
+ id string
38
+ interfaceType string
39
+ unusedSpace string
40
+ usedSpace string
41
+ status string
42
+ arrayType string
43
+ logicalDrives map[string]*hpssaLogicalDrive
44
+}
45
+
46
+func (a *hpssaArray) uniqueKey() string {
47
+ return fmt.Sprintf("%s/%s/%s", a.cntrl.model, a.cntrl.slot, a.id)
48
+}
49
+
50
+type hpssaLogicalDrive struct {
51
+ cntrl *hpssaController
52
+ arr *hpssaArray
53
+
54
+ id string
55
+ size string
56
+ status string
57
+ diskName string
58
+ uniqueIdentifier string
59
+ logicalDriveLabel string
60
+ driveType string
61
+ physicalDrives map[string]*hpssaPhysicalDrive
62
+}
63
+
64
+func (ld *hpssaLogicalDrive) uniqueKey() string {
65
+ return fmt.Sprintf("%s/%s/%s/%s", ld.cntrl.model, ld.cntrl.slot, ld.arr.id, ld.id)
66
+}
67
+
68
+type hpssaPhysicalDrive struct {
69
+ cntrl *hpssaController
70
+ arr *hpssaArray
71
+ ld *hpssaLogicalDrive
72
+
73
+ location string // port:box:bay
74
+ status string
75
+ driveType string
76
+ interfaceType string
77
+ size string
78
+ serialNumber string
79
+ wwid string
80
+ model string
81
+ currentTemperatureC string
82
+}
83
+
84
+func (pd *hpssaPhysicalDrive) uniqueKey() string {
85
+ return fmt.Sprintf("%s/%s/%s/%s/%s", pd.cntrl.model, pd.cntrl.slot, pd.arrId(), pd.ldId(), pd.location)
86
+}
87
+
88
+func (pd *hpssaPhysicalDrive) arrId() string {
89
+ if pd.arr == nil {
90
+ return "na"
91
+ }
92
+ return pd.arr.id
93
+}
94
+
95
+func (pd *hpssaPhysicalDrive) ldId() string {
96
+ if pd.ld == nil {
97
+ return "na"
98
+ }
99
+ return pd.ld.id
100
+}
101
+
102
+func parseSsacliControllersInfo(data []byte) (map[string]*hpssaController, error) {
103
+ var (
104
+ cntrl *hpssaController
105
+ arr *hpssaArray
106
+ ld *hpssaLogicalDrive
107
+ pd *hpssaPhysicalDrive
108
+
109
+ line string
110
+ prevLine string
111
+ section string
112
+ unassigned bool
113
+ )
114
+
115
+ controllers := make(map[string]*hpssaController)
116
+
117
+ sc := bufio.NewScanner(bytes.NewReader(data))
118
+
119
+ for sc.Scan() {
120
+ prevLine = line
121
+ line = sc.Text()
122
+
123
+ switch {
124
+ case line == "":
125
+ section = ""
126
+ continue
127
+ case strings.HasPrefix(line, "Smart Array"):
128
+ section = "controller"
129
+
130
+ v, err := parseControllerLine(line)
131
+ if err != nil {
132
+ return nil, err
133
+ }
134
+
135
+ cntrl = v
136
+ controllers[cntrl.slot] = cntrl
137
+
138
+ continue
139
+ case strings.HasPrefix(line, " Array:") && cntrl != nil:
140
+ section = "array"
141
+ unassigned = false
142
+
143
+ arr = parseArrayLine(line)
144
+ cntrl.arrays[arr.id] = arr
145
+
146
+ continue
147
+ case strings.HasPrefix(line, " Logical Drive:") && cntrl != nil && arr != nil:
148
+ section = "logical drive"
149
+
150
+ ld = parseLogicalDriveLine(line)
151
+ arr.logicalDrives[arr.id] = ld
152
+
153
+ continue
154
+ case strings.HasPrefix(line, " physicaldrive") && prevLine == "":
155
+ section = "physical drive"
156
+
157
+ if unassigned && cntrl == nil {
158
+ return nil, fmt.Errorf("unassigned drive but controller is nil (line '%s')", line)
159
+ }
160
+ if !unassigned && ld == nil {
161
+ return nil, fmt.Errorf("assigned drive but logical device is nil (line '%s')", line)
162
+ }
163
+
164
+ v, err := parsePhysicalDriveLine(line)
165
+ if err != nil {
166
+ return nil, err
167
+ }
168
+
169
+ pd = v
170
+ if unassigned {
171
+ cntrl.unassignedDrives[pd.location] = pd
172
+ } else {
173
+ ld.physicalDrives[pd.location] = pd
174
+ }
175
+
176
+ continue
177
+ case strings.HasPrefix(line, " Unassigned"):
178
+ unassigned = true
179
+ continue
180
+ }
181
+
182
+ switch section {
183
+ case "controller":
184
+ parseControllerSectionLine(line, cntrl)
185
+ case "array":
186
+ parseArraySectionLine(line, arr)
187
+ case "logical drive":
188
+ parseLogicalDriveSectionLine(line, ld)
189
+ case "physical drive":
190
+ parsePhysicalDriveSectionLine(line, pd)
191
+ }
192
+ }
193
+
194
+ if len(controllers) == 0 {
195
+ return nil, fmt.Errorf("no controllers found")
196
+ }
197
+
198
+ updateHpssaHierarchy(controllers)
199
+
200
+ return controllers, nil
201
+}
202
+
203
+func updateHpssaHierarchy(controllers map[string]*hpssaController) {
204
+ for _, cntrl := range controllers {
205
+ for _, pd := range cntrl.unassignedDrives {
206
+ pd.cntrl = cntrl
207
+ }
208
+ for _, arr := range cntrl.arrays {
209
+ arr.cntrl = cntrl
210
+ for _, ld := range arr.logicalDrives {
211
+ ld.cntrl = cntrl
212
+ ld.arr = arr
213
+ for _, pd := range ld.physicalDrives {
214
+ pd.cntrl = cntrl
215
+ pd.arr = arr
216
+ pd.ld = ld
217
+ }
218
+ }
219
+ }
220
+ }
221
+}
222
+
223
+func parseControllerLine(line string) (*hpssaController, error) {
224
+ parts := strings.Fields(strings.TrimPrefix(line, "Smart Array "))
225
+ if len(parts) < 4 {
226
+ return nil, fmt.Errorf("malformed Smart Array line: '%s'", line)
227
+ }
228
+
229
+ cntrl := &hpssaController{
230
+ model: parts[0],
231
+ slot: parts[3],
232
+ arrays: make(map[string]*hpssaArray),
233
+ unassignedDrives: make(map[string]*hpssaPhysicalDrive),
234
+ }
235
+
236
+ return cntrl, nil
237
+}
238
+
239
+func parseArrayLine(line string) *hpssaArray {
240
+ arr := &hpssaArray{
241
+ id: getColonSepValue(line),
242
+ logicalDrives: make(map[string]*hpssaLogicalDrive),
243
+ }
244
+
245
+ return arr
246
+}
247
+
248
+func parseLogicalDriveLine(line string) *hpssaLogicalDrive {
249
+ ld := &hpssaLogicalDrive{
250
+ id: getColonSepValue(line),
251
+ physicalDrives: make(map[string]*hpssaPhysicalDrive),
252
+ }
253
+
254
+ return ld
255
+}
256
+
257
+func parsePhysicalDriveLine(line string) (*hpssaPhysicalDrive, error) {
258
+ parts := strings.Fields(strings.TrimSpace(line))
259
+ if len(parts) != 2 {
260
+ return nil, fmt.Errorf("malformed physicaldrive line: '%s'", line)
261
+ }
262
+
263
+ pd := &hpssaPhysicalDrive{
264
+ location: parts[1],
265
+ }
266
+
267
+ return pd, nil
268
+}
269
+
270
+func parseControllerSectionLine(line string, cntrl *hpssaController) {
271
+ indent := strings.Repeat(" ", 3)
272
+
273
+ switch {
274
+ case strings.HasPrefix(line, indent+"Serial Number:"):
275
+ cntrl.serialNumber = getColonSepValue(line)
276
+ case strings.HasPrefix(line, indent+"Controller Status:"):
277
+ cntrl.controllerStatus = getColonSepValue(line)
278
+ case strings.HasPrefix(line, indent+"Cache Board Present:"):
279
+ cntrl.cacheBoardPresent = getColonSepValue(line)
280
+ case strings.HasPrefix(line, indent+"Cache Status:"):
281
+ cntrl.cacheStatus = getColonSepValue(line)
282
+ case strings.HasPrefix(line, indent+"Cache Ratio:"):
283
+ cntrl.cacheRatio = getColonSepValue(line)
284
+ case strings.HasPrefix(line, indent+"Controller Temperature (C):"):
285
+ cntrl.controllerTemperatureC = getColonSepValue(line)
286
+ case strings.HasPrefix(line, indent+"Cache Module Temperature (C):"):
287
+ cntrl.cacheModuleTemperatureC = getColonSepValue(line)
288
+ case strings.HasPrefix(line, indent+"Number of Ports:"):
289
+ cntrl.numberOfPorts = getColonSepValue(line)
290
+ case strings.HasPrefix(line, indent+"Driver Name:"):
291
+ cntrl.driverName = getColonSepValue(line)
292
+ case strings.HasPrefix(line, indent+"Battery/Capacitor Count:"):
293
+ cntrl.batteryCapacitorCount = getColonSepValue(line)
294
+ case strings.HasPrefix(line, indent+"Battery/Capacitor Status:"):
295
+ cntrl.batteryCapacitorStatus = getColonSepValue(line)
296
+ }
297
+}
298
+
299
+func parseArraySectionLine(line string, arr *hpssaArray) {
300
+ indent := strings.Repeat(" ", 6)
301
+
302
+ switch {
303
+ case strings.HasPrefix(line, indent+"Interface Type:"):
304
+ arr.interfaceType = getColonSepValue(line)
305
+ case strings.HasPrefix(line, indent+"Unused Space:"):
306
+ arr.unusedSpace = getColonSepValue(line)
307
+ case strings.HasPrefix(line, indent+"Used Space:"):
308
+ arr.usedSpace = getColonSepValue(line)
309
+ case strings.HasPrefix(line, indent+"Status:"):
310
+ arr.status = getColonSepValue(line)
311
+ case strings.HasPrefix(line, indent+"Array Type:"):
312
+ arr.arrayType = getColonSepValue(line)
313
+ }
314
+}
315
+
316
+func parseLogicalDriveSectionLine(line string, ld *hpssaLogicalDrive) {
317
+ indent := strings.Repeat(" ", 9)
318
+
319
+ switch {
320
+ case strings.HasPrefix(line, indent+"Size:"):
321
+ ld.size = getColonSepValue(line)
322
+ case strings.HasPrefix(line, indent+"Status:"):
323
+ ld.status = getColonSepValue(line)
324
+ case strings.HasPrefix(line, indent+"Disk Name:"):
325
+ ld.diskName = getColonSepValue(line)
326
+ case strings.HasPrefix(line, indent+"Unique Identifier:"):
327
+ ld.uniqueIdentifier = getColonSepValue(line)
328
+ case strings.HasPrefix(line, indent+"Logical Drive Label:"):
329
+ ld.logicalDriveLabel = getColonSepValue(line)
330
+ case strings.HasPrefix(line, indent+"Drive Type:"):
331
+ ld.driveType = getColonSepValue(line)
332
+ }
333
+}
334
+
335
+func parsePhysicalDriveSectionLine(line string, pd *hpssaPhysicalDrive) {
336
+ indent := strings.Repeat(" ", 9)
337
+
338
+ switch {
339
+ case strings.HasPrefix(line, indent+"Status:"):
340
+ pd.status = getColonSepValue(line)
341
+ case strings.HasPrefix(line, indent+"Drive Type:"):
342
+ pd.driveType = getColonSepValue(line)
343
+ case strings.HasPrefix(line, indent+"Interface Type:"):
344
+ pd.interfaceType = getColonSepValue(line)
345
+ case strings.HasPrefix(line, indent+"Size:"):
346
+ pd.size = getColonSepValue(line)
347
+ case strings.HasPrefix(line, indent+"Serial Number:"):
348
+ pd.serialNumber = getColonSepValue(line)
349
+ case strings.HasPrefix(line, indent+"WWID:"):
350
+ pd.wwid = getColonSepValue(line)
351
+ case strings.HasPrefix(line, indent+"Model:"):
352
+ pd.model = getColonSepValue(line)
353
+ case strings.HasPrefix(line, indent+"Current Temperature (C):"):
354
+ pd.currentTemperatureC = getColonSepValue(line)
355
+ }
356
+}
357
+
358
+func getColonSepValue(line string) string {
359
+ i := strings.IndexByte(line, ':')
360
+ if i == -1 {
361
+ return ""
362
+ }
363
+ return strings.TrimSpace(line[i+1:])
364
+}
src/go/collectors/go.d.plugin/modules/hpssa/testdata/config.json
new
+4
@@ -0,0 +1,4 @@
1
+{
2
+ "update_every": 123,
3
+ "timeout": 123.123
4
+}
src/go/collectors/go.d.plugin/modules/hpssa/testdata/config.yaml
new
+2
@@ -0,0 +1,2 @@
1
+update_every: 123
2
+timeout: 123.123
src/go/collectors/go.d.plugin/modules/hpssa/testdata/ssacli-P212_P410i.txt
new
+748
@@ -0,0 +1,748 @@
1
+Smart Array P212 in Slot 5
2
+ Bus Interface: PCI
3
+ Slot: 5
4
+ Serial Number: REDACTED
5
+ Cache Serial Number: REDACTED
6
+ Controller Status: OK
7
+ Hardware Revision: C
8
+ Firmware Version: 6.60-0
9
+ Rebuild Priority: Medium
10
+ Expand Priority: Medium
11
+ Surface Scan Delay: 15 secs
12
+ Surface Scan Mode: Idle
13
+ Parallel Surface Scan Supported: No
14
+ Queue Depth: Automatic
15
+ Monitor and Performance Delay: 60 min
16
+ Elevator Sort: Enabled
17
+ Degraded Performance Optimization: Disabled
18
+ Wait for Cache Room: Disabled
19
+ Surface Analysis Inconsistency Notification: Disabled
20
+ Post Prompt Timeout: 0 secs
21
+ Cache Board Present: True
22
+ Cache Status: OK
23
+ Cache Ratio: 100% Read / 0% Write
24
+ Drive Write Cache: Disabled
25
+ Total Cache Size: 0.2
26
+ Total Cache Memory Available: 0.1
27
+ No-Battery Write Cache: Disabled
28
+ SATA NCQ Supported: True
29
+ Number of Ports: 2 (1 Internal / 1 External )
30
+ Encryption: Not Set
31
+ Driver Name: hpsa
32
+ Driver Version: 3.4.20
33
+ Driver Supports SSD Smart Path: True
34
+ PCI Address (Domain:Bus:Device.Function): 0000:14:00.0
35
+ Port Max Phy Rate Limiting Supported: False
36
+ Host Serial Number: REDACTED
37
+ Sanitize Erase Supported: False
38
+ Primary Boot Volume: None
39
+ Secondary Boot Volume: None
40
+
41
+
42
+ Port Name: 1I
43
+ Port ID: 0
44
+ Port Connection Number: 0
45
+ SAS Address: 5001438014623D00
46
+ Port Location: Internal
47
+
48
+ Port Name: 2E
49
+ Port ID: 1
50
+ Port Connection Number: 1
51
+ SAS Address: 5001438014623D04
52
+ Port Location: External
53
+
54
+
55
+ StorageWorks MSA 60 at Port 2E, Box 1, OK
56
+
57
+ Fan Status: OK
58
+ Temperature Status: OK
59
+ Power Supply Status: Redundant
60
+ Vendor ID: HP
61
+ Serial Number:
62
+ Firmware Version: 2.16
63
+ Drive Bays: 12
64
+ Port: 2E
65
+ Box: 1
66
+ Location: External
67
+
68
+ Expander 249
69
+ Device Number: 249
70
+ Firmware Version: 2.16
71
+ WWID: REDACTED
72
+ Port: 2E
73
+ Box: 1
74
+ Vendor ID: HP
75
+
76
+ Enclosure SEP (Vendor ID HP, Model MSA60) 248
77
+ Device Number: 248
78
+ Firmware Version: 2.16
79
+ WWID: REDACTED
80
+ Port: 2E
81
+ Box: 1
82
+ Vendor ID: HP
83
+ Model: MSA60
84
+ SEP: (1) 2.16
85
+ Backplane Module (BPM): (1) 2.06, (2) 2.06
86
+ Fan Control Module (FCM): (1) 1.08, (2) 1.08
87
+ Health Monitor Module (HMM): (1) 1.10, (2) 1.10
88
+ Seven Segment LED Display: (1) 0.10
89
+
90
+ Physical Drives
91
+ physicaldrive 2E:1:1 (port 2E:box 1:bay 1, SATA HDD, 1 TB, OK)
92
+ physicaldrive 2E:1:2 (port 2E:box 1:bay 2, SATA HDD, 1 TB, OK)
93
+ physicaldrive 2E:1:3 (port 2E:box 1:bay 3, SATA HDD, 1 TB, OK)
94
+ physicaldrive 2E:1:4 (port 2E:box 1:bay 4, SATA HDD, 1 TB, OK)
95
+ physicaldrive 2E:1:5 (port 2E:box 1:bay 5, SATA HDD, 1 TB, OK)
96
+ physicaldrive 2E:1:6 (port 2E:box 1:bay 6, SATA HDD, 1 TB, OK)
97
+ physicaldrive 2E:1:7 (port 2E:box 1:bay 7, SATA HDD, 1 TB, OK)
98
+ physicaldrive 2E:1:8 (port 2E:box 1:bay 8, SATA HDD, 1 TB, OK)
99
+ physicaldrive 2E:1:9 (port 2E:box 1:bay 9, SATA HDD, 1 TB, OK)
100
+ physicaldrive 2E:1:10 (port 2E:box 1:bay 10, SATA HDD, 1 TB, OK)
101
+ physicaldrive 2E:1:11 (port 2E:box 1:bay 11, SATA HDD, 1 TB, OK)
102
+ physicaldrive 2E:1:12 (port 2E:box 1:bay 12, SATA HDD, 1 TB, OK)
103
+
104
+
105
+ Array: A
106
+ Interface Type: SATA
107
+ Unused Space: 0 MB (0.00%)
108
+ Used Space: 5.46 TB (100.00%)
109
+ Status: OK
110
+ Array Type: Data
111
+ Smart Path: disable
112
+
113
+
114
+ Logical Drive: 1
115
+ Size: 4.55 TB
116
+ Fault Tolerance: 5
117
+ Heads: 255
118
+ Sectors Per Track: 32
119
+ Cylinders: 65535
120
+ Strip Size: 256 KB
121
+ Full Stripe Size: 1280 KB
122
+ Status: OK
123
+ Unrecoverable Media Errors: None
124
+ Caching: Enabled
125
+ Parity Initialization Status: Initialization Completed
126
+ Unique Identifier: 600508B1001C48AFDD414EB0F3004830
127
+ Disk Name: /dev/sdc
128
+ Mount Points: /srv/mnt2 4.5 TB Partition Number 1
129
+ OS Status: LOCKED
130
+ Logical Drive Label: A4A06DEEPACCPID11170BVJE8DB
131
+ Drive Type: Data
132
+ LD Acceleration Method: Controller Cache
133
+
134
+
135
+ physicaldrive 2E:1:1
136
+ Port: 2E
137
+ Box: 1
138
+ Bay: 1
139
+ Status: OK
140
+ Drive Type: Data Drive
141
+ Interface Type: SATA
142
+ Size: 1 TB
143
+ Drive exposed to OS: False
144
+ Logical/Physical Block Size: 512/512
145
+ Rotational Speed: 7200
146
+ Firmware Revision: HPG2
147
+ Serial Number: REDACTED
148
+ WWID: REDACTED
149
+ Model: ATA MB1000EBZQB
150
+ SATA NCQ Capable: True
151
+ SATA NCQ Enabled: True
152
+ Current Temperature (C): 33
153
+ Maximum Temperature (C): 51
154
+ PHY Count: 1
155
+ PHY Transfer Rate: 1.5Gbps
156
+ Sanitize Erase Supported: False
157
+ Shingled Magnetic Recording Support: None
158
+
159
+ physicaldrive 2E:1:2
160
+ Port: 2E
161
+ Box: 1
162
+ Bay: 2
163
+ Status: OK
164
+ Drive Type: Data Drive
165
+ Interface Type: SATA
166
+ Size: 1 TB
167
+ Drive exposed to OS: False
168
+ Logical/Physical Block Size: 512/512
169
+ Rotational Speed: 7200
170
+ Firmware Revision: HPG3
171
+ Serial Number: REDACTED
172
+ WWID: REDACTED
173
+ Model: ATA MB1000EAMZE
174
+ SATA NCQ Capable: True
175
+ SATA NCQ Enabled: True
176
+ Current Temperature (C): 34
177
+ Maximum Temperature (C): 39
178
+ PHY Count: 1
179
+ PHY Transfer Rate: 1.5Gbps
180
+ Sanitize Erase Supported: False
181
+ Shingled Magnetic Recording Support: None
182
+
183
+ physicaldrive 2E:1:3
184
+ Port: 2E
185
+ Box: 1
186
+ Bay: 3
187
+ Status: OK
188
+ Drive Type: Data Drive
189
+ Interface Type: SATA
190
+ Size: 1 TB
191
+ Drive exposed to OS: False
192
+ Logical/Physical Block Size: 512/512
193
+ Rotational Speed: 7200
194
+ Firmware Revision: HPG1
195
+ Serial Number: REDACTED
196
+ WWID: REDACTED
197
+ Model: ATA MB1000ECWCQ
198
+ SATA NCQ Capable: True
199
+ SATA NCQ Enabled: True
200
+ Current Temperature (C): 35
201
+ Maximum Temperature (C): 41
202
+ PHY Count: 1
203
+ PHY Transfer Rate: 1.5Gbps
204
+ Sanitize Erase Supported: False
205
+ Shingled Magnetic Recording Support: None
206
+
207
+ physicaldrive 2E:1:4
208
+ Port: 2E
209
+ Box: 1
210
+ Bay: 4
211
+ Status: OK
212
+ Drive Type: Data Drive
213
+ Interface Type: SATA
214
+ Size: 1 TB
215
+ Drive exposed to OS: False
216
+ Logical/Physical Block Size: 512/512
217
+ Rotational Speed: 7200
218
+ Firmware Revision: HPG4
219
+ Serial Number: REDACTED
220
+ WWID: REDACTED
221
+ Model: ATA MB1000EAMZE
222
+ SATA NCQ Capable: True
223
+ SATA NCQ Enabled: True
224
+ Current Temperature (C): 35
225
+ Maximum Temperature (C): 44
226
+ PHY Count: 1
227
+ PHY Transfer Rate: 1.5Gbps
228
+ Sanitize Erase Supported: False
229
+ Shingled Magnetic Recording Support: None
230
+
231
+ physicaldrive 2E:1:5
232
+ Port: 2E
233
+ Box: 1
234
+ Bay: 5
235
+ Status: OK
236
+ Drive Type: Data Drive
237
+ Interface Type: SATA
238
+ Size: 1 TB
239
+ Drive exposed to OS: False
240
+ Logical/Physical Block Size: 512/512
241
+ Rotational Speed: 7200
242
+ Firmware Revision: HPG1
243
+ Serial Number: REDACTED
244
+ WWID: REDACTED
245
+ Model: ATA MB1000EBZQB
246
+ SATA NCQ Capable: True
247
+ SATA NCQ Enabled: True
248
+ Current Temperature (C): 34
249
+ Maximum Temperature (C): 51
250
+ PHY Count: 1
251
+ PHY Transfer Rate: 1.5Gbps
252
+ Sanitize Erase Supported: False
253
+ Shingled Magnetic Recording Support: None
254
+
255
+ physicaldrive 2E:1:6
256
+ Port: 2E
257
+ Box: 1
258
+ Bay: 6
259
+ Status: OK
260
+ Drive Type: Data Drive
261
+ Interface Type: SATA
262
+ Size: 1 TB
263
+ Drive exposed to OS: False
264
+ Logical/Physical Block Size: 512/512
265
+ Rotational Speed: 7200
266
+ Firmware Revision: HPG1
267
+ Serial Number: REDACTED
268
+ WWID: REDACTED
269
+ Model: ATA MB1000EBZQB
270
+ SATA NCQ Capable: True
271
+ SATA NCQ Enabled: True
272
+ Current Temperature (C): 33
273
+ Maximum Temperature (C): 50
274
+ PHY Count: 1
275
+ PHY Transfer Rate: 1.5Gbps
276
+ Sanitize Erase Supported: False
277
+ Shingled Magnetic Recording Support: None
278
+
279
+
280
+ Unassigned
281
+
282
+ physicaldrive 2E:1:7
283
+ Port: 2E
284
+ Box: 1
285
+ Bay: 7
286
+ Status: OK
287
+ Drive Type: Unassigned Drive
288
+ Interface Type: SATA
289
+ Size: 1 TB
290
+ Drive exposed to OS: False
291
+ Logical/Physical Block Size: 512/512
292
+ Rotational Speed: 7200
293
+ Firmware Revision: HPG2
294
+ Serial Number: REDACTED
295
+ WWID: REDACTED
296
+ Model: ATA MB1000EBZQB
297
+ SATA NCQ Capable: True
298
+ SATA NCQ Enabled: True
299
+ Current Temperature (C): 30
300
+ Maximum Temperature (C): 50
301
+ PHY Count: 1
302
+ PHY Transfer Rate: 1.5Gbps
303
+ Sanitize Erase Supported: False
304
+ Shingled Magnetic Recording Support: None
305
+
306
+ physicaldrive 2E:1:8
307
+ Port: 2E
308
+ Box: 1
309
+ Bay: 8
310
+ Status: OK
311
+ Drive Type: Unassigned Drive
312
+ Interface Type: SATA
313
+ Size: 1 TB
314
+ Drive exposed to OS: False
315
+ Logical/Physical Block Size: 512/512
316
+ Rotational Speed: 7200
317
+ Firmware Revision: HPG1
318
+ Serial Number: REDACTED
319
+ WWID: REDACTED
320
+ Model: ATA MB1000EAMZE
321
+ SATA NCQ Capable: True
322
+ SATA NCQ Enabled: True
323
+ Current Temperature (C): 33
324
+ Maximum Temperature (C): 41
325
+ PHY Count: 1
326
+ PHY Transfer Rate: 1.5Gbps
327
+ Sanitize Erase Supported: False
328
+ Shingled Magnetic Recording Support: None
329
+
330
+ physicaldrive 2E:1:9
331
+ Port: 2E
332
+ Box: 1
333
+ Bay: 9
334
+ Status: OK
335
+ Drive Type: Unassigned Drive
336
+ Interface Type: SATA
337
+ Size: 1 TB
338
+ Drive exposed to OS: False
339
+ Logical/Physical Block Size: 512/512
340
+ Rotational Speed: 7200
341
+ Firmware Revision: HPG1
342
+ Serial Number: REDACTED
343
+ WWID: REDACTED
344
+ Model: ATA MB1000EBZQB
345
+ SATA NCQ Capable: True
346
+ SATA NCQ Enabled: True
347
+ Current Temperature (C): 30
348
+ Maximum Temperature (C): 50
349
+ PHY Count: 1
350
+ PHY Transfer Rate: 1.5Gbps
351
+ Sanitize Erase Supported: False
352
+ Shingled Magnetic Recording Support: None
353
+
354
+ physicaldrive 2E:1:10
355
+ Port: 2E
356
+ Box: 1
357
+ Bay: 10
358
+ Status: OK
359
+ Drive Type: Unassigned Drive
360
+ Interface Type: SATA
361
+ Size: 1 TB
362
+ Drive exposed to OS: False
363
+ Logical/Physical Block Size: 512/512
364
+ Rotational Speed: 7200
365
+ Firmware Revision: HPG2
366
+ Serial Number: REDACTED
367
+ WWID: REDACTED
368
+ Model: ATA MB1000EBNCF
369
+ SATA NCQ Capable: True
370
+ SATA NCQ Enabled: True
371
+ Current Temperature (C): 35
372
+ Maximum Temperature (C): 41
373
+ PHY Count: 1
374
+ PHY Transfer Rate: 1.5Gbps
375
+ Sanitize Erase Supported: False
376
+ Shingled Magnetic Recording Support: None
377
+
378
+ physicaldrive 2E:1:11
379
+ Port: 2E
380
+ Box: 1
381
+ Bay: 11
382
+ Status: OK
383
+ Drive Type: Unassigned Drive
384
+ Interface Type: SATA
385
+ Size: 1 TB
386
+ Drive exposed to OS: False
387
+ Logical/Physical Block Size: 512/512
388
+ Rotational Speed: 7200
389
+ Firmware Revision: HPG1
390
+ Serial Number: REDACTED
391
+ WWID: REDACTED
392
+ Model: ATA ST31000524NS
393
+ SATA NCQ Capable: True
394
+ SATA NCQ Enabled: True
395
+ Current Temperature (C): 34
396
+ Maximum Temperature (C): 42
397
+ PHY Count: 1
398
+ PHY Transfer Rate: 1.5Gbps
399
+ Sanitize Erase Supported: False
400
+ Shingled Magnetic Recording Support: None
401
+
402
+ physicaldrive 2E:1:12
403
+ Port: 2E
404
+ Box: 1
405
+ Bay: 12
406
+ Status: OK
407
+ Drive Type: Unassigned Drive
408
+ Interface Type: SATA
409
+ Size: 1 TB
410
+ Drive exposed to OS: False
411
+ Logical/Physical Block Size: 512/512
412
+ Rotational Speed: 7200
413
+ Firmware Revision: HPG1
414
+ Serial Number: REDACTED
415
+ WWID: REDACTED
416
+ Model: ATA MB1000EBZQB
417
+ SATA NCQ Capable: True
418
+ SATA NCQ Enabled: True
419
+ Current Temperature (C): 31
420
+ Maximum Temperature (C): 50
421
+ PHY Count: 1
422
+ PHY Transfer Rate: 1.5Gbps
423
+ Sanitize Erase Supported: False
424
+ Shingled Magnetic Recording Support: None
425
+
426
+
427
+ Enclosure SEP (Vendor ID HP, Model MSA60) 248
428
+ Device Number: 248
429
+ Firmware Version: 2.16
430
+ WWID: REDACTED
431
+ Port: 2E
432
+ Box: 1
433
+ Vendor ID: HP
434
+ Model: MSA60
435
+ SEP: (1) 2.16
436
+ Backplane Module (BPM): (1) 2.06, (2) 2.06
437
+ Fan Control Module (FCM): (1) 1.08, (2) 1.08
438
+ Health Monitor Module (HMM): (1) 1.10, (2) 1.10
439
+ Seven Segment LED Display: (1) 0.10
440
+
441
+ Expander 249
442
+ Device Number: 249
443
+ Firmware Version: 2.16
444
+ WWID: REDACTED
445
+ Port: 2E
446
+ Box: 1
447
+ Vendor ID: HP
448
+
449
+ SEP (Vendor ID PMCSIERA, Model SRC 8x6G) 250
450
+ Device Number: 250
451
+ Firmware Version: RevC
452
+ WWID: REDACTED
453
+ Vendor ID: PMCSIERA
454
+ Model: SRC 8x6G
455
+
456
+
457
+Smart Array P410i in Slot 0 (Embedded)
458
+ Bus Interface: PCI
459
+ Slot: 0
460
+ Serial Number: REDACTED
461
+ Cache Serial Number: REDACTED
462
+ Controller Status: OK
463
+ Hardware Revision: C
464
+ Firmware Version: 6.40-0
465
+ Rebuild Priority: Medium
466
+ Expand Priority: Medium
467
+ Surface Scan Delay: 15 secs
468
+ Surface Scan Mode: Idle
469
+ Parallel Surface Scan Supported: No
470
+ Queue Depth: Automatic
471
+ Monitor and Performance Delay: 60 min
472
+ Elevator Sort: Enabled
473
+ Degraded Performance Optimization: Disabled
474
+ Wait for Cache Room: Disabled
475
+ Surface Analysis Inconsistency Notification: Disabled
476
+ Post Prompt Timeout: 0 secs
477
+ Cache Board Present: True
478
+ Cache Status: OK
479
+ Cache Ratio: 100% Read / 0% Write
480
+ Drive Write Cache: Disabled
481
+ Total Cache Size: 0.2
482
+ Total Cache Memory Available: 0.1
483
+ No-Battery Write Cache: Disabled
484
+ SATA NCQ Supported: True
485
+ Number of Ports: 2 Internal only
486
+ Encryption: Not Set
487
+ Driver Name: hpsa
488
+ Driver Version: 3.4.20
489
+ Driver Supports SSD Smart Path: True
490
+ PCI Address (Domain:Bus:Device.Function): 0000:04:00.0
491
+ Port Max Phy Rate Limiting Supported: False
492
+ Host Serial Number: REDACTED
493
+ Sanitize Erase Supported: False
494
+ Primary Boot Volume: logicaldrive 1 (600508B1001C8CBE468FB9524F39E535)
495
+ Secondary Boot Volume: None
496
+
497
+
498
+
499
+ Internal Drive Cage at Port 1I, Box 1, OK
500
+
501
+ Power Supply Status: Not Redundant
502
+ Drive Bays: 4
503
+ Port: 1I
504
+ Box: 1
505
+ Location: Internal
506
+
507
+ Physical Drives
508
+ physicaldrive 1I:1:1 (port 1I:box 1:bay 1, SAS HDD, 146 GB, OK)
509
+ physicaldrive 1I:1:2 (port 1I:box 1:bay 2, SAS HDD, 146 GB, OK)
510
+ physicaldrive 1I:1:3 (port 1I:box 1:bay 3, SAS HDD, 146 GB, OK)
511
+ physicaldrive 1I:1:4 (port 1I:box 1:bay 4, SAS HDD, 146 GB, OK)
512
+
513
+
514
+
515
+ Internal Drive Cage at Port 2I, Box 1, OK
516
+
517
+ Power Supply Status: Not Redundant
518
+ Drive Bays: 4
519
+ Port: 2I
520
+ Box: 1
521
+ Location: Internal
522
+
523
+ Physical Drives
524
+ physicaldrive 2I:1:5 (port 2I:box 1:bay 5, SAS HDD, 146 GB, OK)
525
+ physicaldrive 2I:1:6 (port 2I:box 1:bay 6, SAS HDD, 146 GB, OK)
526
+
527
+
528
+ Port Name: 1I
529
+ Port ID: 0
530
+ Port Connection Number: 0
531
+ SAS Address: 50123456789ABCDE
532
+ Port Location: Internal
533
+
534
+ Port Name: 2I
535
+ Port ID: 1
536
+ Port Connection Number: 1
537
+ SAS Address: 50123456789ABCE2
538
+ Port Location: Internal
539
+
540
+ Array: A
541
+ Interface Type: SAS
542
+ Unused Space: 6 MB (0.00%)
543
+ Used Space: 273.40 GB (100.00%)
544
+ Status: OK
545
+ Array Type: Data
546
+ Smart Path: disable
547
+
548
+
549
+ Logical Drive: 1
550
+ Size: 136.70 GB
551
+ Fault Tolerance: 1
552
+ Heads: 255
553
+ Sectors Per Track: 32
554
+ Cylinders: 35132
555
+ Strip Size: 256 KB
556
+ Full Stripe Size: 256 KB
557
+ Status: OK
558
+ Unrecoverable Media Errors: None
559
+ Caching: Enabled
560
+ Unique Identifier: 600508B1001C8CBE468FB9524F39E535
561
+ Disk Name: /dev/sda
562
+ Mount Points: /boot 243 MB Partition Number 1
563
+ OS Status: LOCKED
564
+ Boot Volume: Primary
565
+ Logical Drive Label: ADF758B150123456789ABCDEDC07
566
+ Mirror Group 1:
567
+ physicaldrive 2I:1:5 (port 2I:box 1:bay 5, SAS HDD, 146 GB, OK)
568
+ Mirror Group 2:
569
+ physicaldrive 2I:1:6 (port 2I:box 1:bay 6, SAS HDD, 146 GB, OK)
570
+ Drive Type: Data
571
+ LD Acceleration Method: Controller Cache
572
+
573
+
574
+ physicaldrive 2I:1:5
575
+ Port: 2I
576
+ Box: 1
577
+ Bay: 5
578
+ Status: OK
579
+ Drive Type: Data Drive
580
+ Interface Type: SAS
581
+ Size: 146 GB
582
+ Drive exposed to OS: False
583
+ Logical/Physical Block Size: 512/512
584
+ Rotational Speed: 15000
585
+ Firmware Revision: HPD5 (FW update is recommended to minimum version: HPDA)
586
+ Serial Number: REDACTED
587
+ WWID: REDACTED
588
+ Model: HP EH0146FARWD
589
+ Current Temperature (C): 38
590
+ Maximum Temperature (C): 38
591
+ PHY Count: 2
592
+ PHY Transfer Rate: 6.0Gbps, Unknown
593
+ Sanitize Erase Supported: False
594
+ Shingled Magnetic Recording Support: None
595
+
596
+ physicaldrive 2I:1:6
597
+ Port: 2I
598
+ Box: 1
599
+ Bay: 6
600
+ Status: OK
601
+ Drive Type: Data Drive
602
+ Interface Type: SAS
603
+ Size: 146 GB
604
+ Drive exposed to OS: False
605
+ Logical/Physical Block Size: 512/512
606
+ Rotational Speed: 15000
607
+ Firmware Revision: HPDF
608
+ Serial Number: REDACTED
609
+ WWID: REDACTED
610
+ Model: HP EH0146FAWJB
611
+ Current Temperature (C): 36
612
+ Maximum Temperature (C): 43
613
+ PHY Count: 2
614
+ PHY Transfer Rate: 6.0Gbps, Unknown
615
+ Sanitize Erase Supported: False
616
+ Shingled Magnetic Recording Support: None
617
+
618
+
619
+
620
+ Array: B
621
+ Interface Type: SAS
622
+ Unused Space: 0 MB (0.00%)
623
+ Used Space: 546.81 GB (100.00%)
624
+ Status: OK
625
+ Array Type: Data
626
+ Smart Path: disable
627
+
628
+
629
+ Logical Drive: 2
630
+ Size: 273.40 GB
631
+ Fault Tolerance: 1+0
632
+ Heads: 255
633
+ Sectors Per Track: 32
634
+ Cylinders: 65535
635
+ Strip Size: 256 KB
636
+ Full Stripe Size: 512 KB
637
+ Status: OK
638
+ Unrecoverable Media Errors: None
639
+ Caching: Enabled
640
+ Unique Identifier: 600508B1001CE15640A74343E4DD1E18
641
+ Disk Name: /dev/sdb
642
+ Mount Points: /srv/mnt1 262.3 GB Partition Number 1
643
+ OS Status: LOCKED
644
+ Mirror Group 1:
645
+ physicaldrive 1I:1:1 (port 1I:box 1:bay 1, SAS HDD, 146 GB, OK)
646
+ physicaldrive 1I:1:2 (port 1I:box 1:bay 2, SAS HDD, 146 GB, OK)
647
+ Mirror Group 2:
648
+ physicaldrive 1I:1:3 (port 1I:box 1:bay 3, SAS HDD, 146 GB, OK)
649
+ physicaldrive 1I:1:4 (port 1I:box 1:bay 4, SAS HDD, 146 GB, OK)
650
+ Drive Type: Data
651
+ LD Acceleration Method: Controller Cache
652
+
653
+
654
+ physicaldrive 1I:1:1
655
+ Port: 1I
656
+ Box: 1
657
+ Bay: 1
658
+ Status: OK
659
+ Drive Type: Data Drive
660
+ Interface Type: SAS
661
+ Size: 146 GB
662
+ Drive exposed to OS: False
663
+ Logical/Physical Block Size: 512/512
664
+ Rotational Speed: 10000
665
+ Firmware Revision: HPDD
666
+ Serial Number: REDACTED
667
+ WWID: REDACTED
668
+ Model: HP EG0146FAWHU
669
+ Current Temperature (C): 37
670
+ Maximum Temperature (C): 43
671
+ PHY Count: 2
672
+ PHY Transfer Rate: 6.0Gbps, Unknown
673
+ Sanitize Erase Supported: False
674
+ Shingled Magnetic Recording Support: None
675
+
676
+ physicaldrive 1I:1:2
677
+ Port: 1I
678
+ Box: 1
679
+ Bay: 2
680
+ Status: OK
681
+ Drive Type: Data Drive
682
+ Interface Type: SAS
683
+ Size: 146 GB
684
+ Drive exposed to OS: False
685
+ Logical/Physical Block Size: 512/512
686
+ Rotational Speed: 10000
687
+ Firmware Revision: HPDD
688
+ Serial Number: REDACTED
689
+ WWID: REDACTED
690
+ Model: HP EG0146FAWHU
691
+ Current Temperature (C): 37
692
+ Maximum Temperature (C): 44
693
+ PHY Count: 2
694
+ PHY Transfer Rate: 6.0Gbps, Unknown
695
+ Sanitize Erase Supported: False
696
+ Shingled Magnetic Recording Support: None
697
+
698
+ physicaldrive 1I:1:3
699
+ Port: 1I
700
+ Box: 1
701
+ Bay: 3
702
+ Status: OK
703
+ Drive Type: Data Drive
704
+ Interface Type: SAS
705
+ Size: 146 GB
706
+ Drive exposed to OS: False
707
+ Logical/Physical Block Size: 512/512
708
+ Rotational Speed: 10000
709
+ Firmware Revision: HPDB
710
+ Serial Number: REDACTED
711
+ WWID: REDACTED
712
+ Model: HP DG146BAAJB
713
+ Current Temperature (C): 43
714
+ Maximum Temperature (C): 52
715
+ PHY Count: 2
716
+ PHY Transfer Rate: 3.0Gbps, Unknown
717
+ Sanitize Erase Supported: False
718
+ Shingled Magnetic Recording Support: None
719
+
720
+ physicaldrive 1I:1:4
721
+ Port: 1I
722
+ Box: 1
723
+ Bay: 4
724
+ Status: OK
725
+ Drive Type: Data Drive
726
+ Interface Type: SAS
727
+ Size: 146 GB
728
+ Drive exposed to OS: False
729
+ Logical/Physical Block Size: 512/512
730
+ Rotational Speed: 10000
731
+ Firmware Revision: HPDB
732
+ Serial Number: REDACTED
733
+ WWID: REDACTED
734
+ Model: HP DG146BAAJB
735
+ Current Temperature (C): 44
736
+ Maximum Temperature (C): 55
737
+ PHY Count: 2
738
+ PHY Transfer Rate: 3.0Gbps, Unknown
739
+ Sanitize Erase Supported: False
740
+ Shingled Magnetic Recording Support: None
741
+
742
+
743
+ SEP (Vendor ID PMCSIERA, Model SRC 8x6G) 250
744
+ Device Number: 250
745
+ Firmware Version: RevC
746
+ WWID: REDACTED
747
+ Vendor ID: PMCSIERA
748
+ Model: SRC 8x6G
src/go/collectors/go.d.plugin/modules/hpssa/testdata/ssacli-P400ar.txt
new
+397
@@ -0,0 +1,397 @@
1
+Smart Array P440ar in Slot 0 (Embedded)
2
+ Bus Interface: PCI
3
+ Slot: 0
4
+ Serial Number: REDACTED
5
+ Cache Serial Number: REDACTED
6
+ RAID 6 (ADG) Status: Enabled
7
+ Controller Status: OK
8
+ Hardware Revision: B
9
+ Firmware Version: 3.56-0
10
+ Rebuild Priority: Low
11
+ Expand Priority: Medium
12
+ Surface Scan Delay: 15 secs
13
+ Surface Scan Mode: Idle
14
+ Parallel Surface Scan Supported: Yes
15
+ Current Parallel Surface Scan Count: 4
16
+ Max Parallel Surface Scan Count: 16
17
+ Queue Depth: Automatic
18
+ Monitor and Performance Delay: 60 min
19
+ Elevator Sort: Enabled
20
+ Degraded Performance Optimization: Disabled
21
+ Inconsistency Repair Policy: Disabled
22
+ Wait for Cache Room: Disabled
23
+ Surface Analysis Inconsistency Notification: Disabled
24
+ Post Prompt Timeout: 0 secs
25
+ Cache Board Present: True
26
+ Cache Status: OK
27
+ Cache Ratio: 10% Read / 90% Write
28
+ Drive Write Cache: Enabled
29
+ Total Cache Size: 2.0 GB
30
+ Total Cache Memory Available: 1.8 GB
31
+ No-Battery Write Cache: Enabled
32
+ SSD Caching RAID5 WriteBack Enabled: True
33
+ SSD Caching Version: 2
34
+ Cache Backup Power Source: Batteries
35
+ Battery/Capacitor Count: 1
36
+ Battery/Capacitor Status: OK
37
+ SATA NCQ Supported: True
38
+ Spare Activation Mode: Activate on physical drive failure (default)
39
+ Controller Temperature (C): 47
40
+ Cache Module Temperature (C): 41
41
+ Number of Ports: 2 Internal only
42
+ Encryption: Disabled
43
+ Express Local Encryption: False
44
+ Driver Name: hpsa
45
+ Driver Version: 3.4.4
46
+ Driver Supports SSD Smart Path: True
47
+ PCI Address (Domain:Bus:Device.Function): 0000:03:00.0
48
+ Negotiated PCIe Data Rate: PCIe 3.0 x8 (7880 MB/s)
49
+ Controller Mode: RAID
50
+ Pending Controller Mode: RAID
51
+ Port Max Phy Rate Limiting Supported: False
52
+ Latency Scheduler Setting: Disabled
53
+ Current Power Mode: MaxPerformance
54
+ Survival Mode: Enabled
55
+ Host Serial Number: REDACTED
56
+ Sanitize Erase Supported: False
57
+ Primary Boot Volume: logicaldrive 1 (600508B1001C158B69C0104DA29E6FF7)
58
+ Secondary Boot Volume: logicaldrive 2 (600508B1001C6BBD22BCA12CEDF36CB0)
59
+
60
+
61
+ Port Name: 1I
62
+ Port ID: 0
63
+ Port Connection Number: 0
64
+ SAS Address: 5001438037D24990
65
+ Port Location: Internal
66
+ Managed Cable Connected: False
67
+
68
+ Port Name: 2I
69
+ Port ID: 1
70
+ Port Connection Number: 1
71
+ SAS Address: 5001438037D24994
72
+ Port Location: Internal
73
+ Managed Cable Connected: False
74
+
75
+
76
+ Internal Drive Cage at Port 1I, Box 1, OK
77
+
78
+ Power Supply Status: Not Redundant
79
+ Drive Bays: 4
80
+ Port: 1I
81
+ Box: 1
82
+ Location: Internal
83
+
84
+ Physical Drives
85
+ physicaldrive 1I:1:1 (port 1I:box 1:bay 1, SATA SSD, 1.9 TB, OK)
86
+ physicaldrive 1I:1:2 (port 1I:box 1:bay 2, SATA SSD, 1.9 TB, OK)
87
+ physicaldrive 1I:1:3 (port 1I:box 1:bay 3, SATA SSD, 1.9 TB, OK)
88
+ physicaldrive 1I:1:4 (port 1I:box 1:bay 4, SATA HDD, 1 TB, OK)
89
+
90
+
91
+
92
+ Internal Drive Cage at Port 2I, Box 1, OK
93
+
94
+ Power Supply Status: Not Redundant
95
+ Drive Bays: 4
96
+ Port: 2I
97
+ Box: 1
98
+ Location: Internal
99
+
100
+ Physical Drives
101
+ physicaldrive 2I:1:5 (port 2I:box 1:bay 5, SATA SSD, 1.9 TB, OK)
102
+ physicaldrive 2I:1:6 (port 2I:box 1:bay 6, SATA SSD, 1.9 TB, OK)
103
+ physicaldrive 2I:1:7 (port 2I:box 1:bay 7, SATA SSD, 1.9 TB, OK)
104
+ physicaldrive 2I:1:8 (port 2I:box 1:bay 8, SATA HDD, 1 TB, OK)
105
+
106
+
107
+ Array: A
108
+ Interface Type: Solid State SATA
109
+ Unused Space: 0 MB (0.0%)
110
+ Used Space: 10.5 TB (100.0%)
111
+ Status: OK
112
+ MultiDomain Status: OK
113
+ Array Type: Data
114
+ Smart Path: disable
115
+
116
+
117
+ Logical Drive: 1
118
+ Size: 5.2 TB
119
+ Fault Tolerance: 1+0
120
+ Heads: 255
121
+ Sectors Per Track: 32
122
+ Cylinders: 65535
123
+ Strip Size: 256 KB
124
+ Full Stripe Size: 768 KB
125
+ Status: OK
126
+ MultiDomain Status: OK
127
+ Caching: Enabled
128
+ Unique Identifier: 600508B1001C158B69C0104DA29E6FF7
129
+ Disk Name: /dev/sda
130
+ Mount Points: / 18.6 GB Partition Number 2, /data 5.2 TB Partition Number 4
131
+ OS Status: LOCKED
132
+ Boot Volume: primary
133
+ Logical Drive Label: A9255E2C50123456789ABCDE7239
134
+ Mirror Group 1:
135
+ physicaldrive 1I:1:1 (port 1I:box 1:bay 1, SATA SSD, 1.9 TB, OK)
136
+ physicaldrive 1I:1:2 (port 1I:box 1:bay 2, SATA SSD, 1.9 TB, OK)
137
+ physicaldrive 1I:1:3 (port 1I:box 1:bay 3, SATA SSD, 1.9 TB, OK)
138
+ Mirror Group 2:
139
+ physicaldrive 2I:1:5 (port 2I:box 1:bay 5, SATA SSD, 1.9 TB, OK)
140
+ physicaldrive 2I:1:6 (port 2I:box 1:bay 6, SATA SSD, 1.9 TB, OK)
141
+ physicaldrive 2I:1:7 (port 2I:box 1:bay 7, SATA SSD, 1.9 TB, OK)
142
+ Drive Type: Data
143
+ LD Acceleration Method: Controller Cache
144
+
145
+
146
+ physicaldrive 1I:1:1
147
+ Port: 1I
148
+ Box: 1
149
+ Bay: 1
150
+ Status: OK
151
+ Drive Type: Data Drive
152
+ Interface Type: Solid State SATA
153
+ Size: 1.9 TB
154
+ Drive exposed to OS: False
155
+ Logical/Physical Block Size: 512/4096
156
+ Firmware Revision: XCV10110
157
+ Serial Number:REDACTED
158
+ WWID: REDACTED
159
+ Model: ATA INTEL SSDSC2KB01
160
+ SATA NCQ Capable: True
161
+ SATA NCQ En physicaldriveabled: True
162
+ Current Temperature (C): 27
163
+ Maximum Temperature (C): 33
164
+ SSD Smart Trip Wearout: Not Supported
165
+ PHY Count: 1
166
+ PHY Transfer Rate: 6.0Gbps
167
+ Drive Authentication Status: OK
168
+ Carrier Application Version: 11
169
+ Carrier Bootloader Version: 6
170
+ Sanitize Erase Supported: False
171
+ Shingled Magnetic Recording Support: None
172
+
173
+ physicaldrive 1I:1:2
174
+ Port: 1I
175
+ Box: 1
176
+ Bay: 2
177
+ Status: OK
178
+ Drive Type: Data Drive
179
+ Interface Type: Solid State SATA
180
+ Size: 1.9 TB
181
+ Drive exposed to OS: False
182
+ Logical/Physical Block Size: 512/4096
183
+ Firmware Revision: XCV10110
184
+ Serial Number: REDACTED
185
+ WWID: REDACTED
186
+ Model: ATA INTEL SSDSC2KB01
187
+ SATA NCQ Capable: True
188
+ SATA NCQ Enabled: True
189
+ Current Temperature (C): 28
190
+ Maximum Temperature (C): 33
191
+ SSD Smart Trip Wearout: Not Supported
192
+ PHY Count: 1
193
+ PHY Transfer Rate: 6.0Gbps
194
+ Drive Authentication Status: OK
195
+ Carrier Application Version: 11
196
+ Carrier Bootloader Version: 6
197
+ Sanitize Erase Supported: False
198
+ Shingled Magnetic Recording Support: None
199
+
200
+ physicaldrive 1I:1:3
201
+ Port: 1I
202
+ Box: 1
203
+ Bay: 3
204
+ Status: OK
205
+ Drive Type: Data Drive
206
+ Interface Type: Solid State SATA
207
+ Size: 1.9 TB
208
+ Drive exposed to OS: False
209
+ Logical/Physical Block Size: 512/4096
210
+ Firmware Revision: XCV10110
211
+ Serial Number: REDACTED
212
+ WWID: REDACTED
213
+ Model: ATA INTEL SSDSC2KB01
214
+ SATA NCQ Capable: True
215
+ SATA NCQ Enabled: True
216
+ Current Temperature (C): 27
217
+ Maximum Temperature (C): 30
218
+ SSD Smart Trip Wearout: Not Supported
219
+ PHY Count: 1
220
+ PHY Transfer Rate: 6.0Gbps
221
+ Drive Authentication Status: OK
222
+ Carrier Application Version: 11
223
+ Carrier Bootloader Version: 6
224
+ Sanitize Erase Supported: False
225
+ Shingled Magnetic Recording Support: None
226
+
227
+ physicaldrive 2I:1:5
228
+ Port: 2I
229
+ Box: 1
230
+ Bay: 5
231
+ Status: OK
232
+ Drive Type: Data Drive
233
+ Interface Type: Solid State SATA
234
+ Size: 1.9 TB
235
+ Drive exposed to OS: False
236
+ Logical/Physical Block Size: 512/4096
237
+ Firmware Revision: XCV10110
238
+ Serial Number: REDACTED
239
+ WWID: REDACTED
240
+ Model: ATA INTEL SSDSC2KB01
241
+ SATA NCQ Capable: True
242
+ SATA NCQ Enabled: True
243
+ Current Temperature (C): 26
244
+ Maximum Temperature (C): 29
245
+ SSD Smart Trip Wearout: Not Supported
246
+ PHY Count: 1
247
+ PHY Transfer Rate: 6.0Gbps
248
+ Drive Authentication Status: OK
249
+ Carrier Application Version: 11
250
+ Carrier Bootloader Version: 6
251
+ Sanitize Erase Supported: False
252
+ Shingled Magnetic Recording Support: None
253
+
254
+ physicaldrive 2I:1:6
255
+ Port: 2I
256
+ Box: 1
257
+ Bay: 6
258
+ Status: OK
259
+ Drive Type: Data Drive
260
+ Interface Type: Solid State SATA
261
+ Size: 1.9 TB
262
+ Drive exposed to OS: False
263
+ Logical/Physical Block Size: 512/4096
264
+ Firmware Revision: XCV10110
265
+ Serial Number: REDACTED
266
+ WWID: REDACTED
267
+ Model: ATA INTEL SSDSC2KB01
268
+ SATA NCQ Capable: True
269
+ SATA NCQ Enabled: True
270
+ Current Temperature (C): 28
271
+ Maximum Temperature (C): 32
272
+ SSD Smart Trip Wearout: Not Supported
273
+ PHY Count: 1
274
+ PHY Transfer Rate: 6.0Gbps
275
+ Drive Authentication Status: OK
276
+ Carrier Application Version: 11
277
+ Carrier Bootloader Version: 6
278
+ Sanitize Erase Supported: False
279
+ Shingled Magnetic Recording Support: None
280
+
281
+ physicaldrive 2I:1:7
282
+ Port: 2I
283
+ Box: 1
284
+ Bay: 7
285
+ Status: OK
286
+ Drive Type: Data Drive
287
+ Interface Type: Solid State SATA
288
+ Size: 1.9 TB
289
+ Drive exposed to OS: False
290
+ Logical/Physical Block Size: 512/4096
291
+ Firmware Revision: XCV10110
292
+ Serial Number: REDACTED
293
+ WWID: REDACTED
294
+ Model: ATA INTEL SSDSC2KB01
295
+ SATA NCQ Capable: True
296
+ SATA NCQ Enabled: True
297
+ Current Temperature (C): 27
298
+ Maximum Temperature (C): 32
299
+ SSD Smart Trip Wearout: Not Supported
300
+ PHY Count: 1
301
+ PHY Transfer Rate: 6.0Gbps
302
+ Drive Authentication Status: OK
303
+ Carrier Application Version: 11
304
+ Carrier Bootloader Version: 6
305
+ Sanitize Erase Supported: False
306
+ Shingled Magnetic Recording Support: None
307
+
308
+
309
+
310
+ Array: B
311
+ Interface Type: SATA
312
+ Unused Space: 0 MB (0.0%)
313
+ Used Space: 1.8 TB (100.0%)
314
+ Status: OK
315
+ MultiDomain Status: OK
316
+ Array Type: Data
317
+ Smart Path: disable
318
+
319
+
320
+ Logical Drive: 2
321
+ Size: 931.5 GB
322
+ Fault Tolerance: 1
323
+ Heads: 255
324
+ Sectors Per Track: 32
325
+ Cylinders: 65535
326
+ Strip Size: 256 KB
327
+ Full Stripe Size: 256 KB
328
+ Status: OK
329
+ MultiDomain Status: OK
330
+ Caching: Enabled
331
+ Unique Identifier: 600508B1001C6BBD22BCA12CEDF36CB0
332
+ Disk Name: /dev/sdb
333
+ Mount Points: /data/pgsql/spaces/big 931.5 GB Partition Number 1
334
+ OS Status: LOCKED
335
+ Boot Volume: secondary
336
+ Logical Drive Label: A9254E3850123456789ABCDE368D
337
+ Mirror Group 1:
338
+ physicaldrive 1I:1:4 (port 1I:box 1:bay 4, SATA HDD, 1 TB, OK)
339
+ Mirror Group 2:
340
+ physicaldrive 2I:1:8 (port 2I:box 1:bay 8, SATA HDD, 1 TB, OK)
341
+ Drive Type: Data
342
+ LD Acceleration Method: Controller Cache
343
+
344
+
345
+ physicaldrive 1I:1:4
346
+ Port: 1I
347
+ Box: 1
348
+ Bay: 4
349
+ Status: OK
350
+ Drive Type: Data Drive
351
+ Interface Type: SATA
352
+ Size: 1 TB
353
+ Drive exposed to OS: False
354
+ Logical/Physical Block Size: 512/4096
355
+ Rotational Speed: 5400
356
+ Firmware Revision: 2BA30001
357
+ Serial Number: REDACTED
358
+ WWID: REDACTED
359
+ Model: ATA ST1000LM024 HN-M
360
+ SATA NCQ Capable: True
361
+ SATA NCQ Enabled: True
362
+ Current Temperature (C): 30
363
+ Maximum Temperature (C): 35
364
+ PHY Count: 1
365
+ PHY Transfer Rate: 6.0Gbps
366
+ Drive Authentication Status: OK
367
+ Carrier Application Version: 11
368
+ Carrier Bootloader Version: 6
369
+ Sanitize Erase Supported: False
370
+ Shingled Magnetic Recording Support: None
371
+
372
+ physicaldrive 2I:1:8
373
+ Port: 2I
374
+ Box: 1
375
+ Bay: 8
376
+ Status: OK
377
+ Drive Type: Data Drive
378
+ Interface Type: SATA
379
+ Size: 1 TB
380
+ Drive exposed to OS: False
381
+ Logical/Physical Block Size: 512/4096
382
+ Rotational Speed: 5400
383
+ Firmware Revision: 2BA30001
384
+ Serial Number: REDACTED
385
+ WWID: REDACTED
386
+ Model: ATA ST1000LM024 HN-M
387
+ SATA NCQ Capable: True
388
+ SATA NCQ Enabled: True
389
+ Current Temperature (C): 29
390
+ Maximum Temperature (C): 34
391
+ PHY Count: 1
392
+ PHY Transfer Rate: 6.0Gbps
393
+ Drive Authentication Status: OK
394
+ Carrier Application Version: 11
395
+ Carrier Bootloader Version: 6
396
+ Sanitize Erase Supported: False
397
+ Shingled Magnetic Recording Support: None
src/go/collectors/go.d.plugin/modules/hpssa/testdata/ssacli-P400i-unassigned.txt
new
+207
@@ -0,0 +1,207 @@
1
+Smart Array P400i in Slot 0 (Embedded)
2
+ Bus Interface: PCI
3
+ Slot: 0
4
+ Serial Number: REDACTED
5
+ Cache Serial Number: REDACTED
6
+ RAID 6 (ADG) Status: Enabled
7
+ Controller Status: OK
8
+ Hardware Revision: E
9
+ Firmware Version: 7.24-0
10
+ Rebuild Priority: Medium
11
+ Expand Priority: Medium
12
+ Surface Scan Delay: 15 secs
13
+ Surface Scan Mode: Idle
14
+ Parallel Surface Scan Supported: No
15
+ Elevator Sort: Enabled
16
+ Wait for Cache Room: Disabled
17
+ Surface Analysis Inconsistency Notification: Disabled
18
+ Post Prompt Timeout: 0 secs
19
+ Cache Board Present: True
20
+ Cache Status: Temporarily Disabled
21
+ Cache Status Details: Cache disabled; low batteries.
22
+ Cache Ratio: 25% Read / 75% Write
23
+ Drive Write Cache: Disabled
24
+ Total Cache Size: 256 MB
25
+ Total Cache Memory Available: 208 MB
26
+ No-Battery Write Cache: Disabled
27
+ Cache Backup Power Source: Batteries
28
+ Battery/Capacitor Count: 1
29
+ Battery/Capacitor Status: Failed (Replace Batteries)
30
+ SATA NCQ Supported: True
31
+ Number of Ports: 2 Internal only
32
+ Driver Name: cciss
33
+ Driver Version: 3.6.26
34
+ PCI Address (Domain:Bus:Device.Function): 0000:06:00.0
35
+ Port Max Phy Rate Limiting Supported: False
36
+ Host Serial Number: REDACTED
37
+ Sanitize Erase Supported: False
38
+ Primary Boot Volume: None
39
+ Secondary Boot Volume: None
40
+
41
+
42
+ Port Name: 1I
43
+ Port ID: 0
44
+ Port Connection Number: 0
45
+ SAS Address: 0000000000000000
46
+ Port Location: Internal
47
+
48
+ Port Name: 2I
49
+ Port ID: 1
50
+ Port Connection Number: 1
51
+ SAS Address: 0000000000000000
52
+ Port Location: Internal
53
+
54
+
55
+ Internal Drive Cage at Port 1I, Box 1, OK
56
+
57
+ Power Supply Status: Not Redundant
58
+ Drive Bays: 4
59
+ Port: 1I
60
+ Box: 1
61
+ Location: Internal
62
+
63
+ Physical Drives
64
+ physicaldrive 1I:1:1 (port 1I:box 1:bay 1, SATA HDD, 250 GB, OK)
65
+ physicaldrive 1I:1:2 (port 1I:box 1:bay 2, SATA HDD, 250 GB, OK)
66
+ physicaldrive 1I:1:3 (port 1I:box 1:bay 3, SATA HDD, 100 GB, OK)
67
+ physicaldrive 1I:1:4 (port 1I:box 1:bay 4, SATA HDD, 100 GB, OK)
68
+
69
+
70
+
71
+ Internal Drive Cage at Port 2I, Box 1, OK
72
+
73
+ Power Supply Status: Not Redundant
74
+ Drive Bays: 2
75
+ Port: 2I
76
+ Box: 1
77
+ Location: Internal
78
+
79
+ Physical Drives
80
+ None attached
81
+
82
+
83
+ Array: A
84
+ Interface Type: SATA
85
+ Unused Space: 0 MB (0.0%)
86
+ Used Space: 186.3 GB (100.0%)
87
+ Status: OK
88
+ Array Type: Data
89
+
90
+
91
+ Logical Drive: 1
92
+ Size: 93.1 GB
93
+ Fault Tolerance: 1
94
+ Heads: 255
95
+ Sectors Per Track: 32
96
+ Cylinders: 23934
97
+ Strip Size: 128 KB
98
+ Full Stripe Size: 128 KB
99
+ Status: OK
100
+ Caching: Enabled
101
+ Unique Identifier: 600508B1001038333220202020200004
102
+ Disk Name: /dev/cciss/c0d0
103
+ Mount Points: /boot 94 MB Partition Number 1, / 91.2 GB Partition Number 3
104
+ OS Status: LOCKED
105
+ Logical Drive Label: A00AD958PH89MQ7832 7E6D
106
+ Mirror Group 1:
107
+ physicaldrive 1I:1:3 (port 1I:box 1:bay 3, SATA HDD, 100 GB, OK)
108
+ Mirror Group 2:
109
+ physicaldrive 1I:1:4 (port 1I:box 1:bay 4, SATA HDD, 100 GB, OK)
110
+ Drive Type: Data
111
+ LD Acceleration Method: Controller Cache
112
+
113
+
114
+ physicaldrive 1I:1:3
115
+ Port: 1I
116
+ Box: 1
117
+ Bay: 3
118
+ Status: OK
119
+ Drive Type: Data Drive
120
+ Interface Type: SATA
121
+ Size: 100 GB
122
+ Drive exposed to OS: False
123
+ Logical/Physical Block Size: 512/512
124
+ Firmware Revision: 6PB10362
125
+ Serial Number: REDACTED
126
+ WWID: REDACTED
127
+ Model: ATA INTEL SSDSA2BZ10
128
+ SATA NCQ Capable: True
129
+ SATA NCQ Enabled: True
130
+ Current Temperature (C): 23
131
+ Maximum Temperature (C): 32
132
+ PHY Count: 1
133
+ PHY Transfer Rate: 1.5Gbps
134
+ Sanitize Erase Supported: False
135
+ Shingled Magnetic Recording Support: None
136
+
137
+ physicaldrive 1I:1:4
138
+ Port: 1I
139
+ Box: 1
140
+ Bay: 4
141
+ Status: OK
142
+ Drive Type: Data Drive
143
+ Interface Type: SATA
144
+ Size: 100 GB
145
+ Drive exposed to OS: False
146
+ Logical/Physical Block Size: 512/512
147
+ Firmware Revision: 6PB10362
148
+ Serial Number: REDACTED
149
+ WWID: REDACTED
150
+ Model: ATA INTEL SSDSA2BZ10
151
+ SATA NCQ Capable: True
152
+ SATA NCQ Enabled: True
153
+ Current Temperature (C): 23
154
+ Maximum Temperature (C): 33
155
+ PHY Count: 1
156
+ PHY Transfer Rate: 1.5Gbps
157
+ Sanitize Erase Supported: False
158
+ Shingled Magnetic Recording Support: None
159
+
160
+
161
+ Unassigned
162
+
163
+ physicaldrive 1I:1:1
164
+ Port: 1I
165
+ Box: 1
166
+ Bay: 1
167
+ Status: OK
168
+ Drive Type: Unassigned Drive
169
+ Interface Type: SATA
170
+ Size: 250 GB
171
+ Drive exposed to OS: False
172
+ Logical/Physical Block Size: 512/512
173
+ Firmware Revision: 0001EXM1
174
+ Serial Number: REDACTED
175
+ WWID: REDACTED
176
+ Model: ATA ST250LT021-1AF14
177
+ SATA NCQ Capable: True
178
+ SATA NCQ Enabled: True
179
+ Current Temperature (C): 28
180
+ Maximum Temperature (C): 36
181
+ PHY Count: 1
182
+ PHY Transfer Rate: 1.5Gbps
183
+ Sanitize Erase Supported: False
184
+ Shingled Magnetic Recording Support: None
185
+
186
+ physicaldrive 1I:1:2
187
+ Port: 1I
188
+ Box: 1
189
+ Bay: 2
190
+ Status: OK
191
+ Drive Type: Unassigned Drive
192
+ Interface Type: SATA
193
+ Size: 250 GB
194
+ Drive exposed to OS: False
195
+ Logical/Physical Block Size: 512/512
196
+ Firmware Revision: 0001EXM1
197
+ Serial Number: REDACTED
198
+ WWID: REDACTED
199
+ Model: ATA ST250LT021-1AF14
200
+ SATA NCQ Capable: True
201
+ SATA NCQ Enabled: True
202
+ Current Temperature (C): 28
203
+ Maximum Temperature (C): 36
204
+ PHY Count: 1
205
+ PHY Transfer Rate: 1.5Gbps
206
+ Sanitize Erase Supported: False
207
+ Shingled Magnetic Recording Support: None
src/go/collectors/go.d.plugin/modules/init.go
+1
@@ -32,6 +32,7 @@ import (
32
_ "github.com/netdata/netdata/go/go.d.plugin/modules/haproxy"
33
_ "github.com/netdata/netdata/go/go.d.plugin/modules/hddtemp"
34
_ "github.com/netdata/netdata/go/go.d.plugin/modules/hdfs"
35
+ _ "github.com/netdata/netdata/go/go.d.plugin/modules/hpssa"
36
_ "github.com/netdata/netdata/go/go.d.plugin/modules/httpcheck"
37
_ "github.com/netdata/netdata/go/go.d.plugin/modules/intelgpu"
38
_ "github.com/netdata/netdata/go/go.d.plugin/modules/isc_dhcpd"