master
go 163 lines 4.1 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package storcli
4
5 import (
6 "encoding/json"
7 "errors"
8 "fmt"
9 "strconv"
10 "strings"
11 )
12
13 type (
14 controllersInfoResponse struct {
15 Controllers []struct {
16 CommandStatus struct {
17 Controller int `json:"Controller"`
18 Status string `json:"Status"`
19 } `json:"Command Status"`
20 ResponseData controllerInfo `json:"Response Data"`
21 } `json:"Controllers"`
22 }
23 controllerInfo struct {
24 Basics struct {
25 Controller int `json:"Controller"`
26 Model string `json:"Model"`
27 SerialNumber string `json:"Serial Number"`
28 } `json:"Basics"`
29 Version struct {
30 DriverName string `json:"Driver Name"`
31 } `json:"Version"`
32 Status struct {
33 ControllerStatus string `json:"Controller Status"`
34 BBUStatus *storNumber `json:"BBU Status"`
35 } `json:"Status"`
36 HwCfg struct {
37 TemperatureSensorForROC string `json:"Temperature Sensor for ROC"`
38 ROCTemperatureC int `json:"ROC temperature(Degree Celsius)"`
39 } `json:"HwCfg"`
40 BBUInfo []struct {
41 Model string `json:"Model"`
42 State string `json:"State"`
43 Temp string `json:"Temp"`
44 } `json:"BBU_Info"`
45 PDList []struct {
46 } `json:"PD LIST"`
47 }
48 )
49
50 func (c *Collector) collectMegaraidControllersInfo(mx map[string]int64, resp *controllersInfoResponse) error {
51 for _, v := range resp.Controllers {
52 cntrl := v.ResponseData
53
54 cntrlNum := strconv.Itoa(cntrl.Basics.Controller)
55
56 if !c.controllers[cntrlNum] {
57 c.controllers[cntrlNum] = true
58 c.addControllerCharts(cntrl)
59 }
60
61 px := fmt.Sprintf("cntrl_%s_", cntrlNum)
62
63 for _, st := range []string{"healthy", "unhealthy"} {
64 mx[px+"health_status_"+st] = 0
65 }
66 if strings.ToLower(cntrl.Status.ControllerStatus) == "optimal" {
67 mx[px+"health_status_healthy"] = 1
68 } else {
69 mx[px+"health_status_unhealthy"] = 1
70 }
71
72 for _, st := range []string{"optimal", "degraded", "partially_degraded", "failed"} {
73 mx[px+"status_"+st] = 0
74 }
75 mx[px+"status_"+strings.ToLower(cntrl.Status.ControllerStatus)] = 1
76
77 if cntrl.Status.BBUStatus != nil {
78 for _, st := range []string{"healthy", "unhealthy", "na"} {
79 mx[px+"bbu_status_"+st] = 0
80 }
81 // https://github.com/prometheus-community/node-exporter-textfile-collector-scripts/issues/27
82 switch *cntrl.Status.BBUStatus {
83 case "0", "8", "4096": // 0 good, 8 charging
84 mx[px+"bbu_status_healthy"] = 1
85 case "NA", "N/A":
86 mx[px+"bbu_status_na"] = 1
87 default:
88 mx[px+"bbu_status_unhealthy"] = 1
89 }
90 }
91
92 for i, bbu := range cntrl.BBUInfo {
93 bbuNum := strconv.Itoa(i)
94 if k := cntrlNum + bbuNum; !c.bbu[k] {
95 c.bbu[k] = true
96 c.addBBUCharts(cntrlNum, bbuNum, bbu.Model)
97 }
98
99 px := fmt.Sprintf("bbu_%s_cntrl_%s_", bbuNum, cntrlNum)
100
101 if v, ok := parseInt(getTemperature(bbu.Temp)); ok {
102 mx[px+"temperature"] = v
103 }
104 }
105 }
106
107 return nil
108 }
109
110 func (c *Collector) collectMpt3sasControllersInfo(mx map[string]int64, resp *controllersInfoResponse) error {
111 for _, v := range resp.Controllers {
112 cntrl := v.ResponseData
113
114 cntrlNum := strconv.Itoa(cntrl.Basics.Controller)
115
116 if !c.controllers[cntrlNum] {
117 c.controllers[cntrlNum] = true
118 c.addControllerCharts(cntrl)
119 }
120
121 px := fmt.Sprintf("cntrl_%s_", cntrlNum)
122
123 for _, st := range []string{"healthy", "unhealthy"} {
124 mx[px+"health_status_"+st] = 0
125 }
126
127 if strings.EqualFold(cntrl.Status.ControllerStatus, "ok") {
128 mx[px+"health_status_healthy"] = 1
129 } else {
130 mx[px+"health_status_unhealthy"] = 1
131 }
132
133 if strings.EqualFold(cntrl.HwCfg.TemperatureSensorForROC, "present") {
134 mx[px+"roc_temperature_celsius"] = int64(cntrl.HwCfg.ROCTemperatureC)
135 }
136 }
137
138 return nil
139 }
140
141 func (c *Collector) queryControllersInfo() (*controllersInfoResponse, error) {
142 bs, err := c.exec.controllersInfo()
143 if err != nil {
144 return nil, err
145 }
146
147 if len(bs) == 0 {
148 return nil, errors.New("empty response")
149 }
150
151 var resp controllersInfoResponse
152 if err := json.Unmarshal(bs, &resp); err != nil {
153 return nil, err
154 }
155 if len(resp.Controllers) == 0 {
156 return nil, errors.New("no controllers found")
157 }
158 if st := resp.Controllers[0].CommandStatus.Status; st != "Success" {
159 return nil, fmt.Errorf("command status error: %s", st)
160 }
161
162 return &resp, nil
163 }