From 105a48afd7cf957b346e065f9953f4402ba59465 Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Sun, 12 Jan 2025 20:52:10 +0100 Subject: [PATCH] supermicro: fallback to identifying model number from the board ID for when neither the XML or Redfish APIs indicate the device model number --- go.mod | 2 +- go.sum | 2 ++ providers/supermicro/errors.go | 1 + providers/supermicro/x11.go | 56 ++++++++++++++++++++++++++++++++-- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 6c2601fc..901f6a31 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( dario.cat/mergo v1.0.1 github.com/Jeffail/gabs/v2 v2.7.0 - github.com/bmc-toolbox/common v0.0.0-20241031162543-6b96e5981a0d + github.com/bmc-toolbox/common v0.0.0-20250112191656-b6de52e8303d github.com/bombsimon/logrusr/v2 v2.0.1 github.com/ghodss/yaml v1.0.0 github.com/go-logr/logr v1.4.2 diff --git a/go.sum b/go.sum index df0e4d53..35135fbf 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/VictorLowther/soap v0.0.0-20150314151524-8e36fca84b22 h1:a0MBqYm44o0N github.com/VictorLowther/soap v0.0.0-20150314151524-8e36fca84b22/go.mod h1:/B7V22rcz4860iDqstGvia/2+IYWXf3/JdQCVd/1D2A= github.com/bmc-toolbox/common v0.0.0-20241031162543-6b96e5981a0d h1:dMmFDAAEpXizInaNwPSa5LM6tX/xDIPKjL6v9jYfMxo= github.com/bmc-toolbox/common v0.0.0-20241031162543-6b96e5981a0d/go.mod h1:Cdnkm+edb6C0pVkyCrwh3JTXAe0iUF9diDG/DztPI9I= +github.com/bmc-toolbox/common v0.0.0-20250112191656-b6de52e8303d h1:5c0jhS9jNLm1t3GVEESsWv+p6recFRLGW90zp8HDIDs= +github.com/bmc-toolbox/common v0.0.0-20250112191656-b6de52e8303d/go.mod h1:Cdnkm+edb6C0pVkyCrwh3JTXAe0iUF9diDG/DztPI9I= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/providers/supermicro/errors.go b/providers/supermicro/errors.go index 6587df02..7f10f01f 100644 --- a/providers/supermicro/errors.go +++ b/providers/supermicro/errors.go @@ -12,6 +12,7 @@ var ( ErrXMLAPIUnsupported = errors.New("XML API is unsupported") ErrModelUnknown = errors.New("Model number unknown") ErrModelUnsupported = errors.New("Model not supported") + ErrBoardIDUnknown = errors.New("BoardID could not be identified") ErrUnexpectedResponse = errors.New("Unexpected response content") ErrUnexpectedStatusCode = errors.New("Unexpected status code") ) diff --git a/providers/supermicro/x11.go b/providers/supermicro/x11.go index 761da9ab..d37af411 100644 --- a/providers/supermicro/x11.go +++ b/providers/supermicro/x11.go @@ -15,6 +15,7 @@ import ( "github.com/bmc-toolbox/common" "github.com/go-logr/logr" "github.com/pkg/errors" + "github.com/stmcginnis/gofish/oem/smc" "github.com/stmcginnis/gofish/redfish" ) @@ -36,6 +37,23 @@ func (c *x11) deviceModel() string { } func (c *x11) queryDeviceModel(ctx context.Context) (string, error) { + model, err := c.deviceModelFromFruInfo(ctx) + if err != nil { + // Identify BoardID from Redfish since fru info failed to return the information + model, err2 := c.deviceModelFromBoardID(ctx) + if err2 != nil { + return "", errors.Wrap(err, err2.Error()) + } + + c.model = model + return model, nil + } + + c.model = model + return model, nil +} + +func (c *x11) deviceModelFromFruInfo(ctx context.Context) (string, error) { errBoardPartNumUnknown := errors.New("baseboard part number unknown") data, err := c.fruInfo(ctx) if err != nil { @@ -47,14 +65,46 @@ func (c *x11) queryDeviceModel(ctx context.Context) (string, error) { } partNum := strings.TrimSpace(data.Board.PartNum) - if data.Board == nil || partNum == "" { return "", errors.Wrap(errBoardPartNumUnknown, "baseboard part number empty") } - c.model = common.FormatProductName(partNum) + return common.FormatProductName(partNum), nil +} + +func (c *x11) deviceModelFromBoardID(ctx context.Context) (string, error) { + if err := c.redfishSession(ctx); err != nil { + return "", err + } + + chassis, err := c.redfish.Chassis(ctx) + if err != nil { + return "", err + } + + var boardID string + for _, ch := range chassis { + smcChassis, err := smc.FromChassis(ch) + if err != nil { + return "", errors.Wrap(ErrBoardIDUnknown, err.Error()) + } + + if smcChassis.BoardID != "" { + boardID = smcChassis.BoardID + break + } + } + + if boardID == "" { + return "", ErrBoardIDUnknown + } + + model := common.SupermicroModelFromBoardID(boardID) + if model == "" { + return "", errors.Wrap(ErrModelUnknown, "unable to identify model from board ID: "+boardID) + } - return c.model, nil + return model, nil } func (c *x11) fruInfo(ctx context.Context) (*FruInfo, error) {