Skip to content

Commit 0d7bc0e

Browse files
Fix computersystems field (#70)
* fix graceful shutdown logic in main func, improve unmarshalling logic for different possible json responses * update CHANGELOG and README
1 parent c928ebf commit 0d7bc0e

File tree

8 files changed

+119
-78
lines changed

8 files changed

+119
-78
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ log is based on the [Keep a CHANGELOG](http://keepachangelog.com/) project.
2525
- Thermal Summary, Power total consumed for Cisco servers and Chassis, memory metrics for Gen9 server models [#53](https://github.com/Comcast/fishymetrics/issues/53)
2626
- Firmware gathering endpoint update and add device info to other HP models [#55](https://github.com/Comcast/fishymetrics/issues/55)
2727
- C220 drive metrics on hosts with fw < 4.0, psu metrics result and label values [#57](https://github.com/Comcast/fishymetrics/issues/57)
28+
- Chassis ComputerSystems field is handled improperly [#68](https://github.com/Comcast/fishymetrics/issues/68)
2829

2930
## Updated
3031

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This app can support any chassis that has the redfish API available. If one need
99

1010
To run it:
1111

12-
```bash
12+
```
1313
$ ./fishymetrics --help
1414
usage: fishymetrics [<flags>]
1515
@@ -57,7 +57,7 @@ Flags:
5757

5858
Or set the following ENV Variables:
5959

60-
```bash
60+
```
6161
BMC_USERNAME=<string>
6262
BMC_PASSWORD=<string>
6363
BMC_TIMEOUT=<duration> (Default: 15s)

cmd/fishymetrics/main.go

+20-11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"html/template"
2424
"io"
2525
logg "log"
26+
"net"
2627
"net/http"
2728
"os"
2829
"os/signal"
@@ -319,17 +320,27 @@ func main() {
319320
Handler: loggingHandler(mux),
320321
}
321322

322-
wg.Add(1)
323-
go func() {
324-
defer wg.Done()
325-
326-
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
327-
log.Error("starting "+app+" service failed", zap.Error(err))
328-
}
329-
}()
330-
331323
signals := make(chan os.Signal, 1)
332324
signal.Notify(signals, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
325+
326+
listener, err := net.Listen("tcp4", ":"+*exporterPort)
327+
if err != nil {
328+
log.Error("starting "+app+" service failed", zap.Error(err))
329+
signals <- syscall.SIGTERM
330+
} else {
331+
wg.Add(1)
332+
go func() {
333+
defer wg.Done()
334+
335+
if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {
336+
log.Error("http server received an error", zap.Error(err))
337+
signals <- syscall.SIGTERM
338+
}
339+
}()
340+
341+
log.Info("started " + app + " service")
342+
}
343+
333344
wg.Add(1)
334345
go func() {
335346
defer wg.Done()
@@ -346,8 +357,6 @@ func main() {
346357
doneRenew <- true
347358
}()
348359

349-
log.Info("started " + app + " service")
350-
351360
wg.Wait()
352361
}
353362

oem/chassis.go

+22-12
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package oem
1818

1919
import (
20-
"bytes"
2120
"encoding/json"
2221
)
2322

@@ -62,25 +61,36 @@ type LinksWrapper struct {
6261

6362
func (w *LinksWrapper) UnmarshalJSON(data []byte) error {
6463
// because of a change in output between firmware versions we need to account for this
65-
if bytes.Compare([]byte("[{"), data[0:2]) == 0 {
66-
var linksTmp []struct {
67-
URL string `json:"@odata.id,omitempty"`
68-
HRef string `json:"href,omitempty"`
69-
}
70-
err := json.Unmarshal(data, &linksTmp)
71-
if len(linksTmp) > 0 {
72-
for _, l := range linksTmp {
64+
// try to unmarshal as a slice of structs
65+
// [
66+
// {
67+
// "@odata.id": "/redfish/v1/Systems/XXXX"
68+
// }
69+
// ]
70+
var links []struct {
71+
URL string `json:"@odata.id,omitempty"`
72+
HRef string `json:"href,omitempty"`
73+
}
74+
err := json.Unmarshal(data, &links)
75+
if err == nil {
76+
if len(links) > 0 {
77+
for _, l := range links {
7378
if l.URL != "" {
7479
w.LinksURLSlice = append(w.LinksURLSlice, l.URL)
7580
} else {
7681
w.LinksURLSlice = append(w.LinksURLSlice, l.HRef)
7782
}
7883
}
79-
return nil
8084
}
81-
return err
85+
} else {
86+
// try to unmarshal as a slice of strings
87+
// [
88+
// "/redfish/v1/Systems/XXXX"
89+
// ]
90+
return json.Unmarshal(data, &w.LinksURLSlice)
8291
}
83-
return json.Unmarshal(data, &w.LinksURLSlice)
92+
93+
return nil
8494
}
8595

8696
type ChassisStorageBattery struct {

oem/drive.go

+24-11
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package oem
1818

1919
import (
20-
"bytes"
2120
"encoding/json"
2221
)
2322

@@ -81,22 +80,36 @@ type LocationWrapper struct {
8180

8281
func (w *LocationWrapper) UnmarshalJSON(data []byte) error {
8382
// because of a change in output between firmware versions we need to account for this
84-
if bytes.Compare([]byte("[{"), data[0:2]) == 0 {
85-
var locTmp []struct {
86-
Loc string `json:"Info,omitempty"`
87-
}
88-
err := json.Unmarshal(data, &locTmp)
89-
if len(locTmp) > 0 {
90-
for _, l := range locTmp {
83+
// try to unmarshal as a slice of structs
84+
// [
85+
// {
86+
// "Info": "location data"
87+
// }
88+
// ]
89+
var loc []struct {
90+
Loc string `json:"Info,omitempty"`
91+
}
92+
err := json.Unmarshal(data, &loc)
93+
if err == nil {
94+
if len(loc) > 0 {
95+
for _, l := range loc {
9196
if l.Loc != "" {
9297
w.Location = l.Loc
9398
}
9499
}
95-
return nil
96100
}
97-
return err
101+
} else {
102+
// try to unmarshal as a string
103+
// {
104+
// ...
105+
// "Location": "location data"
106+
// ...
107+
// }
108+
return json.Unmarshal(data, &w.Location)
98109
}
99-
return json.Unmarshal(data, &w.Location)
110+
111+
return nil
112+
100113
}
101114

102115
// GenericDrive is used to iterate over differing drive endpoints

oem/manager.go

+28-18
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package oem
1818

1919
import (
20-
"bytes"
2120
"encoding/json"
2221
)
2322

@@ -45,26 +44,37 @@ type ServerManagerURLWrapper struct {
4544
}
4645

4746
func (w *ServerManagerURLWrapper) UnmarshalJSON(data []byte) error {
48-
// because of a change in output betwen c220 firmware versions we need to account for this
49-
if bytes.Compare([]byte("[{"), data[0:2]) == 0 {
50-
var serMgrTmp []struct {
51-
UrlLinks string `json:"@odata.id,omitempty"`
52-
Urllinks string `json:"href,omitempty"`
53-
}
54-
err := json.Unmarshal(data, &serMgrTmp)
55-
if len(serMgrTmp) > 0 {
56-
s := make([]string, 0)
57-
if serMgrTmp[0].UrlLinks != "" {
58-
s = append(s, serMgrTmp[0].UrlLinks)
59-
} else {
60-
s = append(s, serMgrTmp[0].Urllinks)
47+
// because of a change in output between firmware versions we need to account for this
48+
// try to unmarshal as a slice of structs
49+
// [
50+
// {
51+
// "@odata.id": "/redfish/v1/Systems/XXXX"
52+
// }
53+
// ]
54+
var svrMgr []struct {
55+
URL string `json:"@odata.id,omitempty"`
56+
HRef string `json:"href,omitempty"`
57+
}
58+
err := json.Unmarshal(data, &svrMgr)
59+
if err == nil {
60+
if len(svrMgr) > 0 {
61+
for _, l := range svrMgr {
62+
if l.URL != "" {
63+
w.ServerManagerURLSlice = append(w.ServerManagerURLSlice, l.URL)
64+
} else {
65+
w.ServerManagerURLSlice = append(w.ServerManagerURLSlice, l.HRef)
66+
}
6167
}
62-
w.ServerManagerURLSlice = s
63-
return nil
6468
}
65-
return err
69+
} else {
70+
// try to unmarshal as a slice of strings
71+
// [
72+
// "/redfish/v1/Systems/XXXX"
73+
// ]
74+
return json.Unmarshal(data, &w.ServerManagerURLSlice)
6675
}
67-
return json.Unmarshal(data, &w.ServerManagerURLSlice)
76+
77+
return nil
6878
}
6979

7080
type IloSelfTest struct {

oem/power.go

+10-11
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package oem
1818

1919
import (
20-
"bytes"
2120
"encoding/json"
2221
)
2322

@@ -50,19 +49,19 @@ type PowerControlWrapper struct {
5049
}
5150

5251
func (w *PowerControlWrapper) UnmarshalJSON(data []byte) error {
53-
// because of a change in output betwen firmware versions we need to account for this
54-
if bytes.Compare([]byte("{"), data[0:1]) == 0 {
55-
var powCtlSlice PowerControl
56-
err := json.Unmarshal(data, &powCtlSlice)
57-
if err != nil {
58-
return err
59-
}
52+
// because of a change in output between firmware versions we need to account for this
53+
// PowerControl can either be []PowerControl or a singular PowerControl
54+
var powCtl PowerControl
55+
err := json.Unmarshal(data, &powCtl)
56+
if err == nil {
6057
s := make([]PowerControl, 0)
61-
s = append(s, powCtlSlice)
58+
s = append(s, powCtl)
6259
w.PowerControl = s
63-
return nil
60+
} else {
61+
return json.Unmarshal(data, &w.PowerControl)
6462
}
65-
return json.Unmarshal(data, &w.PowerControl)
63+
64+
return nil
6665
}
6766

6867
// PowerMetric contains avg/min/max power metadata

oem/storage_ctrl.go

+12-13
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package oem
1818

1919
import (
20-
"bytes"
2120
"encoding/json"
2221
)
2322

@@ -48,19 +47,19 @@ type StorageControllerWrapper struct {
4847
}
4948

5049
func (w *StorageControllerWrapper) UnmarshalJSON(data []byte) error {
51-
// because of a change in output betwen c220 firmware versions we need to account for this
52-
if bytes.Compare([]byte("{"), data[0:1]) == 0 {
53-
var storCtlSlice StorageController
54-
err := json.Unmarshal(data, &storCtlSlice)
55-
if err != nil {
56-
return err
57-
}
58-
s := make([]StorageController, 0)
59-
s = append(s, storCtlSlice)
60-
w.StorageController = s
61-
return nil
50+
// because of a change in output between firmware versions we need to account for this
51+
// StorageController can either be []StorageController or a singular StorageController
52+
var storCtl StorageController
53+
err := json.Unmarshal(data, &storCtl)
54+
if err == nil {
55+
sc := make([]StorageController, 0)
56+
sc = append(sc, storCtl)
57+
w.StorageController = sc
58+
} else {
59+
return json.Unmarshal(data, &w.StorageController)
6260
}
63-
return json.Unmarshal(data, &w.StorageController)
61+
62+
return nil
6463
}
6564

6665
type Drive struct {

0 commit comments

Comments
 (0)