summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/modules/storcli/collect_controllers.go
blob: d1302aea014322a2b0e33f40d17e2bbd98046c98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// SPDX-License-Identifier: GPL-3.0-or-later

package storcli

import (
	"encoding/json"
	"errors"
	"fmt"
	"strconv"
	"strings"
)

type (
	controllersInfoResponse struct {
		Controllers []struct {
			CommandStatus struct {
				Controller int    `json:"Controller"`
				Status     string `json:"Status"`
			} `json:"Command Status"`
			ResponseData controllerInfo `json:"Response Data"`
		} `json:"Controllers"`
	}
	controllerInfo struct {
		Basics struct {
			Controller   int    `json:"Controller"`
			Model        string `json:"Model"`
			SerialNumber string `json:"Serial Number"`
		} `json:"Basics"`
		Version struct {
			DriverName string `json:"Driver Name"`
		} `json:"Version"`
		Status struct {
			ControllerStatus string     `json:"Controller Status"`
			BBUStatus        storNumber `json:"BBU Status"`
		} `json:"Status"`
		BBUInfo []struct {
			Model string `json:"Model"`
			State string `json:"State"`
			Temp  string `json:"Temp"`
		} `json:"BBU_Info"`
		PDList []struct {
		} `json:"PD LIST"`
	}
)

func (s *StorCli) collectControllersInfo(mx map[string]int64, resp *controllersInfoResponse) error {
	for _, v := range resp.Controllers {
		cntrl := v.ResponseData

		cntrlNum := strconv.Itoa(cntrl.Basics.Controller)

		if !s.controllers[cntrlNum] {
			s.controllers[cntrlNum] = true
			s.addControllerCharts(cntrl)
		}

		px := fmt.Sprintf("cntrl_%s_", cntrlNum)

		for _, st := range []string{"optimal", "degraded", "partially_degraded", "failed"} {
			mx[px+"status_"+st] = 0
		}
		mx[px+"status_"+strings.ToLower(cntrl.Status.ControllerStatus)] = 1

		for _, st := range []string{"healthy", "unhealthy", "na"} {
			mx[px+"bbu_status_"+st] = 0
		}
		// https://github.com/prometheus-community/node-exporter-textfile-collector-scripts/issues/27
		switch cntrl.Status.BBUStatus {
		case "0", "8", "4096": // 0 good, 8 charging
			mx[px+"bbu_status_healthy"] = 1
		case "NA", "N/A":
			mx[px+"bbu_status_na"] = 1
		default:
			mx[px+"bbu_status_unhealthy"] = 1
		}

		for i, bbu := range cntrl.BBUInfo {
			bbuNum := strconv.Itoa(i)
			if k := cntrlNum + bbuNum; !s.bbu[k] {
				s.bbu[k] = true
				s.addBBUCharts(cntrlNum, bbuNum, bbu.Model)
			}

			px := fmt.Sprintf("bbu_%s_cntrl_%s_", bbuNum, cntrlNum)

			if v, ok := parseInt(getTemperature(bbu.Temp)); ok {
				mx[px+"temperature"] = v
			}
		}
	}

	return nil
}

func (s *StorCli) queryControllersInfo() (*controllersInfoResponse, error) {
	bs, err := s.exec.controllersInfo()
	if err != nil {
		return nil, err
	}

	if len(bs) == 0 {
		return nil, errors.New("empty response")
	}

	var resp controllersInfoResponse
	if err := json.Unmarshal(bs, &resp); err != nil {
		return nil, err
	}
	if len(resp.Controllers) == 0 {
		return nil, errors.New("no controllers found")
	}
	if st := resp.Controllers[0].CommandStatus.Status; st != "Success" {
		return nil, fmt.Errorf("command status error: %s", st)
	}

	return &resp, nil
}