Skip to content

[FS-539] Implement out of band bios configuration collection #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/metal-toolbox/alloy
go 1.19

require (
github.com/bmc-toolbox/bmclib/v2 v2.0.1-0.20221219143242-1dbc47057ba3
github.com/bmc-toolbox/common v0.0.0-20221115135648-0b584f504396
github.com/bmc-toolbox/bmclib/v2 v2.0.1-0.20230308154037-6f5089bc74fe
github.com/bmc-toolbox/common v0.0.0-20230220061748-93ff001f4a1d
github.com/bombsimon/logrusr/v2 v2.0.1
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/equinix-labs/otel-init-go v0.0.7
Expand All @@ -14,7 +14,7 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.2
github.com/jacobweinstock/registrar v0.4.6
github.com/jinzhu/copier v0.3.5
github.com/metal-toolbox/ironlib v0.2.5
github.com/metal-toolbox/ironlib v0.2.6-0.20230313083928-82c470aff5e5
github.com/peterbourgon/ff/v3 v3.3.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.14.0
Expand Down Expand Up @@ -125,7 +125,7 @@ require (
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
gocloud.dev v0.27.0 // indirect
golang.org/x/crypto v0.4.0 // indirect
golang.org/x/exp v0.0.0-20230116083435-1de6713980de // indirect
golang.org/x/exp v0.0.0-20230127130021-4ca2cb1a16b7 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/sys v0.6.0 // indirect
Expand Down
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,10 @@ github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmc-toolbox/bmclib/v2 v2.0.1-0.20221219143242-1dbc47057ba3 h1:EQpdvDZgNje9/lvPlB+BLjBkeQ4cI3TrwEW589tztW0=
github.com/bmc-toolbox/bmclib/v2 v2.0.1-0.20221219143242-1dbc47057ba3/go.mod h1:2HUSfpk9cdI69955us3orjKGlVr/SKNZg2DQZuNqsjQ=
github.com/bmc-toolbox/common v0.0.0-20221115135648-0b584f504396 h1:MAIYVFtt/Hnhx0Cth6T9pnLTJnZKppzi7LHue4KpPtg=
github.com/bmc-toolbox/common v0.0.0-20221115135648-0b584f504396/go.mod h1:SY//n1PJjZfbFbmAsB6GvEKbc7UXz3d30s3kWxfJQ/c=
github.com/bmc-toolbox/bmclib/v2 v2.0.1-0.20230308154037-6f5089bc74fe h1:ooZMmSIjEHe5axHJoNBPWj888JiD/EXAQlwGGTgLK7w=
github.com/bmc-toolbox/bmclib/v2 v2.0.1-0.20230308154037-6f5089bc74fe/go.mod h1:ni0GMKsi9uNyrkRH51exh5xCg0Fs+aTtJPbbR73AaYI=
github.com/bmc-toolbox/common v0.0.0-20230220061748-93ff001f4a1d h1:cQ30Wa8mhLzK1TSOG+g3FlneIsXtFgun61mmPwVPmD0=
github.com/bmc-toolbox/common v0.0.0-20230220061748-93ff001f4a1d/go.mod h1:SY//n1PJjZfbFbmAsB6GvEKbc7UXz3d30s3kWxfJQ/c=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM=
github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio=
Expand Down Expand Up @@ -1120,8 +1120,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182aff
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
github.com/metal-toolbox/ironlib v0.2.5 h1:un+QgZWYe5b9lZZbtPMspSyoK2P3a1rw+5daz7pUF7g=
github.com/metal-toolbox/ironlib v0.2.5/go.mod h1:vywoREorRcBGmLTcJzjpPLHYDLTXLe8KazaXtLmVkFc=
github.com/metal-toolbox/ironlib v0.2.6-0.20230313083928-82c470aff5e5 h1:HO1XnamQ2Vgncm5W5nybvVcoaFqkMQaWkDH53ljiTCo=
github.com/metal-toolbox/ironlib v0.2.6-0.20230313083928-82c470aff5e5/go.mod h1:twp0CVQaUAZ7LAx6uZy99bGaH89zIj6b5C+kCrId9p0=
github.com/microsoft/ApplicationInsights-Go v0.4.4/go.mod h1:fKRUseBqkw6bDiXTs3ESTiU/4YTIHsQS4W3fP2ieF4U=
github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
Expand Down Expand Up @@ -1747,8 +1747,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230116083435-1de6713980de h1:DBWn//IJw30uYCgERoxCg84hWtA97F4wMiKOIh00Uf0=
golang.org/x/exp v0.0.0-20230116083435-1de6713980de/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/exp v0.0.0-20230127130021-4ca2cb1a16b7 h1:o7Ps2IYdzLRolS9/nadqeMSHpa9k8pu8u+VKBFUG7cQ=
golang.org/x/exp v0.0.0-20230127130021-4ca2cb1a16b7/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
Expand Down
64 changes: 62 additions & 2 deletions internal/collect/outofband.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ type oobGetter interface {
Open(ctx context.Context) error
Close(ctx context.Context) error
Inventory(ctx context.Context) (*common.Device, error)
GetBiosConfiguration(ctx context.Context) (map[string]string, error)
}

// NewOutOfBandCollector returns a instance of the OutOfBandCollector inventory collector
Expand Down Expand Up @@ -236,7 +237,7 @@ func (o *OutOfBandCollector) taskQueueWait(span trace.Span) {
}
}

// spawn runs the asset inventory collection and writes the collected inventory to the collectorCh
// collect runs the asset inventory collection and writes the collected inventory to the collectorCh
func (o *OutOfBandCollector) collect(ctx context.Context, asset *model.Asset) {
// attach child span
ctx, span := tracer.Start(ctx, "collect()")
Expand Down Expand Up @@ -289,6 +290,17 @@ func (o *OutOfBandCollector) collect(ctx context.Context, asset *model.Asset) {
}).Warn("BMC inventory error")
}

// collect bios configuration
err = o.bmcGetBiosConfiguration(ctx, bmc, asset)
if err != nil {
o.logger.WithFields(
logrus.Fields{
"serverID": asset.ID,
"IP": asset.BMCAddress.String(),
"err": err,
}).Warn("BMC bios configuration collection error")
}

// return if the context has been canceled.
if ctx.Err() != nil {
return
Expand All @@ -297,7 +309,55 @@ func (o *OutOfBandCollector) collect(ctx context.Context, asset *model.Asset) {
o.collectorCh <- asset
}

// bmcInventory collects inventory data from he BMC
// bmcGetBiosConfiguration collects bios configuration data from the BMC
// it updates the asset.BiosConfig attribute with the data collected.
//
// If any errors occurred in the collection, those are included in the asset.Errors attribute.
func (o *OutOfBandCollector) bmcGetBiosConfiguration(ctx context.Context, bmc oobGetter, asset *model.Asset) error {
// measure BMC GetBiosConfiguration query
startTS := time.Now()

// attach child span
ctx, span := tracer.Start(ctx, "GetBiosConfiguration()")
defer span.End()

biosConfig, err := bmc.GetBiosConfiguration(ctx)
if err != nil {
o.logger.WithFields(
logrus.Fields{
"serverID": asset.ID,
"IP": asset.BMCAddress.String(),
"err": err,
}).Warn("error in bmc bios configuration collection")

span.SetStatus(codes.Error, " BMC GetBiosConfiguration(): "+err.Error())

// increment get bios configuration query error count metric
switch {
case strings.Contains(err.Error(), "no compatible System Odata IDs identified"):
asset.IncludeError("GetBiosConfigurationError", "redfish_incompatible: no compatible System Odata IDs identified")
metricIncrementBMCQueryErrorCount(asset.Vendor, asset.Model, "redfish_incompatible")
case strings.Contains(err.Error(), "no BiosConfigurationGetter implementations found"):
// If the asset doesn't implement a BiosConfigurationGetter, skip asset.IncludeError() which allows
// inventory to be published later on
metricIncrementBMCQueryErrorCount(asset.Vendor, asset.Model, "NoBiosConfigurationGetter")
default:
asset.IncludeError("GetBiosConfigurationError", err.Error())
metricIncrementBMCQueryErrorCount(asset.Vendor, asset.Model, "GetBiosConfigurationError")
}

return err
}

// measure BMC GetBiosConfiguration query time
metricObserveBMCQueryTimeSummary(asset.Vendor, asset.Model, "GetBiosConfiguration", startTS)

asset.BiosConfig = biosConfig

return nil
}

// bmcInventory collects inventory data from the BMC
// it updates the asset.Inventory attribute with the data collected.
//
// If any errors occurred in the collection, those are included in the asset.Errors attribute.
Expand Down
5 changes: 5 additions & 0 deletions internal/collect/outofband_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ func Test_OutOfBandInventoryRemote(t *testing.T) {
// test inventory items match expected
assert.Equal(t, len(mockAssets), len(got))

// test asset.BiosConfig is populated
for _, a := range got {
assert.Equal(t, "bar", a.BiosConfig["foo"])
}

// test bmc connection was opened
assert.Equal(t, os.Getenv(fixtures.EnvMockBMCOpen), "true")

Expand Down
7 changes: 7 additions & 0 deletions internal/fixtures/bmclib.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ func (m *MockBmclib) Inventory(ctx context.Context) (*common.Device, error) {
return CopyDevice(E3C246D4INL), nil
}

func (m *MockBmclib) GetBiosConfiguration(ctx context.Context) (biosConfig map[string]string, err error) {
biosConfig = make(map[string]string)
biosConfig["foo"] = "bar"

return biosConfig, nil
}

func NewMockBmclib() *MockBmclib {
return &MockBmclib{}
}
Expand Down
98 changes: 58 additions & 40 deletions internal/fixtures/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,15 @@ var (
Firmware: nil,
Status: nil,
},
ID: "",
Description: "",
SpeedBits: 0,
PhysicalID: "",
BusInfo: "",
MacAddress: "",
ID: "",
NICPorts: []*common.NICPort{
&common.NICPort{
SpeedBits: 0,
PhysicalID: "",
BusInfo: "",
MacAddress: "",
},
},
},
},
Mainboard: &common.Mainboard{
Expand Down Expand Up @@ -170,12 +173,15 @@ var (
"speed": "10Gbit/s",
},
},
ID: "",
Description: "Ethernet interface",
SpeedBits: 10000000000,
PhysicalID: "0",
BusInfo: "pci@0000:01:00.0",
MacAddress: "",
ID: "",
NICPorts: []*common.NICPort{
{
SpeedBits: 10000000000,
PhysicalID: "0",
BusInfo: "pci@0000:01:00.0",
MacAddress: "",
},
},
},
},
Drives: []*common.Drive{
Expand Down Expand Up @@ -624,7 +630,7 @@ var (
&common.NIC{
Common: common.Common{
Oem: false,
Description: "",
Description: "Embedded NIC 1 Port 1 Partition 1",
Vendor: "",
Model: "",
Serial: "",
Expand All @@ -642,17 +648,20 @@ var (
PostCodeStatus: "",
},
},
ID: "NIC.Embedded.1",
Description: "Embedded NIC 1 Port 1 Partition 1",
SpeedBits: 6,
PhysicalID: "",
BusInfo: "",
MacAddress: "",
ID: "NIC.Embedded.1",
NICPorts: []*common.NICPort{
{
SpeedBits: 6,
PhysicalID: "",
BusInfo: "",
MacAddress: "",
},
},
},
&common.NIC{
Common: common.Common{
Oem: false,
Description: "",
Description: "NIC in Slot 3 Port 1 Partition 1",
Vendor: "Intel Corporation",
Model: "Intel(R) 10GbE 2P X710 Adapter",
Serial: "MYFLMIT04P00HQ",
Expand All @@ -673,12 +682,15 @@ var (
PostCodeStatus: "",
},
},
ID: "NIC.Slot.3",
Description: "NIC in Slot 3 Port 1 Partition 1",
SpeedBits: 100006,
PhysicalID: "",
BusInfo: "",
MacAddress: "F8:F2:1E:A0:0D:E0",
ID: "NIC.Slot.3",
NICPorts: []*common.NICPort{
{
SpeedBits: 100006,
PhysicalID: "",
BusInfo: "",
MacAddress: "F8:F2:1E:A0:0D:E0",
},
},
},
},
Drives: []*common.Drive{
Expand Down Expand Up @@ -1456,7 +1468,7 @@ var (
&common.NIC{
Common: common.Common{
Oem: false,
Description: "",
Description: "Embedded NIC 1 Port 1 Partition 1",
Vendor: "",
Model: "",
Serial: "",
Expand All @@ -1474,17 +1486,20 @@ var (
PostCodeStatus: "",
},
},
ID: "NIC.Embedded.1",
Description: "Embedded NIC 1 Port 1 Partition 1",
SpeedBits: 6,
PhysicalID: "",
BusInfo: "",
MacAddress: "",
ID: "NIC.Embedded.1",
NICPorts: []*common.NICPort{
{
SpeedBits: 6,
PhysicalID: "",
BusInfo: "",
MacAddress: "",
},
},
},
&common.NIC{
Common: common.Common{
Oem: false,
Description: "",
Description: "NIC in Slot 3 Port 1 Partition 1",
Vendor: "Intel Corporation",
Model: "Intel(R) 10GbE 2P X710 Adapter",
Serial: "MYFLMIT04P00HQ",
Expand All @@ -1505,12 +1520,15 @@ var (
PostCodeStatus: "",
},
},
ID: "NIC.Slot.3",
Description: "NIC in Slot 3 Port 1 Partition 1",
SpeedBits: 100006,
PhysicalID: "",
BusInfo: "",
MacAddress: "F8:F2:1E:A0:0D:E0",
ID: "NIC.Slot.3",
NICPorts: []*common.NICPort{
{
SpeedBits: 100006,
PhysicalID: "",
BusInfo: "",
MacAddress: "F8:F2:1E:A0:0D:E0",
},
},
},
},
Drives: []*common.Drive{
Expand Down
10 changes: 5 additions & 5 deletions internal/publish/serverservice_attributes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,12 +432,12 @@ func Test_ServerService_CreateUpdateServerComponents_ObjectsAdded(t *testing.T)
device.Inventory.NICs = append(
device.Inventory.NICs,
&common.NIC{
ID: "NEW NIC!",
Description: "Just added!, totally incompatible",
ID: "NEW NIC!",
Common: common.Common{
Vendor: "noname",
Model: "noname",
Serial: fixtureNICSerial,
Vendor: "noname",
Model: "noname",
Serial: fixtureNICSerial,
Description: "Just added!, totally incompatible",
},
},
)
Expand Down
Loading