Skip to content
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

SetBiosConfiguration(ctx, biosConfig) & ResetBiosConfiguration(ctx) for dell #385

Merged
merged 11 commits into from
Apr 16, 2024
126 changes: 126 additions & 0 deletions bmc/bios.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@
BiosConfigurationGetter
}

type BiosConfigurationSetter interface {
SetBiosConfiguration(ctx context.Context, biosConfig map[string]string) (err error)
}

type biosConfigurationSetterProvider struct {
name string
BiosConfigurationSetter
}

type BiosConfigurationResetter interface {
ResetBiosConfiguration(ctx context.Context) (err error)
}

type biosConfigurationResetterProvider struct {
name string
BiosConfigurationResetter
}

func biosConfiguration(ctx context.Context, generic []biosConfigurationGetterProvider) (biosConfig map[string]string, metadata Metadata, err error) {
var metadataLocal Metadata
Loop:
Expand All @@ -27,14 +45,14 @@
}
select {
case <-ctx.Done():
err = multierror.Append(err, ctx.Err())

Check failure on line 48 in bmc/bios.go

View workflow job for this annotation

GitHub Actions / lint

undefined: multierror (typecheck)

Check failure on line 48 in bmc/bios.go

View workflow job for this annotation

GitHub Actions / lint

undefined: multierror (typecheck)
break Loop
default:
metadataLocal.ProvidersAttempted = append(metadataLocal.ProvidersAttempted, elem.name)
biosConfig, vErr := elem.GetBiosConfiguration(ctx)
if vErr != nil {
err = multierror.Append(err, errors.WithMessagef(vErr, "provider: %v", elem.name))

Check failure on line 54 in bmc/bios.go

View workflow job for this annotation

GitHub Actions / lint

undefined: multierror (typecheck)

Check failure on line 54 in bmc/bios.go

View workflow job for this annotation

GitHub Actions / lint

undefined: multierror (typecheck)
err = multierror.Append(err, vErr)

Check failure on line 55 in bmc/bios.go

View workflow job for this annotation

GitHub Actions / lint

undefined: multierror (typecheck)

Check failure on line 55 in bmc/bios.go

View workflow job for this annotation

GitHub Actions / lint

undefined: multierror (typecheck)
continue

}
Expand All @@ -46,6 +64,62 @@
return biosConfig, metadataLocal, multierror.Append(err, errors.New("failure to get bios configuration"))
}

func setBiosConfiguration(ctx context.Context, generic []biosConfigurationSetterProvider, biosConfig map[string]string) (metadata Metadata, err error) {
var metadataLocal Metadata
splaspood marked this conversation as resolved.
Show resolved Hide resolved
Loop:
for _, elem := range generic {
if elem.BiosConfigurationSetter == nil {
continue
}
select {
case <-ctx.Done():
err = multierror.Append(err, ctx.Err())
break Loop
default:
metadataLocal.ProvidersAttempted = append(metadataLocal.ProvidersAttempted, elem.name)
vErr := elem.SetBiosConfiguration(ctx, biosConfig)
if vErr != nil {
err = multierror.Append(err, errors.WithMessagef(vErr, "provider: %v", elem.name))
err = multierror.Append(err, vErr)
continue

}
metadataLocal.SuccessfulProvider = elem.name
return metadataLocal, nil
}
}

return metadataLocal, multierror.Append(err, errors.New("failure to set bios configuration"))
}

func resetBiosConfiguration(ctx context.Context, generic []biosConfigurationResetterProvider) (metadata Metadata, err error) {
var metadataLocal Metadata
Loop:
for _, elem := range generic {
if elem.BiosConfigurationResetter == nil {
continue
}
select {
case <-ctx.Done():
err = multierror.Append(err, ctx.Err())
break Loop
default:
metadataLocal.ProvidersAttempted = append(metadataLocal.ProvidersAttempted, elem.name)
vErr := elem.ResetBiosConfiguration(ctx)
if vErr != nil {
err = multierror.Append(err, errors.WithMessagef(vErr, "provider: %v", elem.name))
err = multierror.Append(err, vErr)
continue

}
metadataLocal.SuccessfulProvider = elem.name
return metadataLocal, nil
}
}

return metadataLocal, multierror.Append(err, errors.New("failure to reset bios configuration"))
}

func GetBiosConfigurationInterfaces(ctx context.Context, generic []interface{}) (biosConfig map[string]string, metadata Metadata, err error) {
implementations := make([]biosConfigurationGetterProvider, 0)
for _, elem := range generic {
Expand All @@ -71,3 +145,55 @@

return biosConfiguration(ctx, implementations)
}

func SetBiosConfigurationInterfaces(ctx context.Context, generic []interface{}, biosConfig map[string]string) (metadata Metadata, err error) {
implementations := make([]biosConfigurationSetterProvider, 0)
for _, elem := range generic {
temp := biosConfigurationSetterProvider{name: getProviderName(elem)}
switch p := elem.(type) {
case BiosConfigurationSetter:
temp.BiosConfigurationSetter = p
implementations = append(implementations, temp)
default:
e := fmt.Sprintf("not a BiosConfigurationSetter implementation: %T", p)
err = multierror.Append(err, errors.New(e))
}
}
if len(implementations) == 0 {
return metadata, multierror.Append(
err,
errors.Wrap(
bmclibErrs.ErrProviderImplementation,
("no BiosConfigurationSetter implementations found"),
),
)
}

return setBiosConfiguration(ctx, implementations, biosConfig)
}

func ResetBiosConfigurationInterfaces(ctx context.Context, generic []interface{}) (metadata Metadata, err error) {
implementations := make([]biosConfigurationResetterProvider, 0)
for _, elem := range generic {
temp := biosConfigurationResetterProvider{name: getProviderName(elem)}
switch p := elem.(type) {
case BiosConfigurationResetter:
temp.BiosConfigurationResetter = p
implementations = append(implementations, temp)
default:
e := fmt.Sprintf("not a BiosConfigurationResetter implementation: %T", p)
err = multierror.Append(err, errors.New(e))
}
}
if len(implementations) == 0 {
return metadata, multierror.Append(
err,
errors.Wrap(
bmclibErrs.ErrProviderImplementation,
("no BiosConfigurationResetter implementations found"),
),
)
}

return resetBiosConfiguration(ctx, implementations)
}
25 changes: 23 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"github.com/go-logr/logr"
"github.com/jacobweinstock/registrar"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
oteltrace "go.opentelemetry.io/otel/trace"
tracenoop "go.opentelemetry.io/otel/trace/noop"
)
Expand Down Expand Up @@ -319,7 +318,7 @@ func (c *Client) registry() *registrar.Registry {
return c.Registry
}

func (c *Client) RegisterSpanAttributes(m bmc.Metadata, span trace.Span) {
func (c *Client) RegisterSpanAttributes(m bmc.Metadata, span oteltrace.Span) {
span.SetAttributes(attribute.String("host", c.Auth.Host))

span.SetAttributes(attribute.String("successful-provider", m.SuccessfulProvider))
Expand Down Expand Up @@ -556,6 +555,28 @@ func (c *Client) GetBiosConfiguration(ctx context.Context) (biosConfig map[strin
return biosConfig, err
}

func (c *Client) SetBiosConfiguration(ctx context.Context, biosConfig map[string]string) (err error) {
coffeefreak101 marked this conversation as resolved.
Show resolved Hide resolved
ctx, span := c.traceprovider.Tracer(pkgName).Start(ctx, "SetBiosConfiguration")
defer span.End()

metadata, err := bmc.SetBiosConfigurationInterfaces(ctx, c.registry().GetDriverInterfaces(), biosConfig)
c.setMetadata(metadata)
metadata.RegisterSpanAttributes(c.Auth.Host, span)

return err
}

func (c *Client) ResetBiosConfiguration(ctx context.Context) (err error) {
ctx, span := c.traceprovider.Tracer(pkgName).Start(ctx, "ResetBiosConfiguration")
defer span.End()

metadata, err := bmc.ResetBiosConfigurationInterfaces(ctx, c.registry().GetDriverInterfaces())
c.setMetadata(metadata)
metadata.RegisterSpanAttributes(c.Auth.Host, span)

return err
}

// FirmwareInstall pass through library function to upload firmware and install firmware
func (c *Client) FirmwareInstall(ctx context.Context, component string, operationApplyTime string, forceInstall bool, reader io.Reader) (taskID string, err error) {
ctx, span := c.traceprovider.Tracer(pkgName).Start(ctx, "FirmwareInstall")
Expand Down
85 changes: 70 additions & 15 deletions examples/bios/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,97 @@ package main

import (
"context"
"encoding/json"
"flag"
"fmt"
"io"
"os"
"strings"
"time"

bmclib "github.com/bmc-toolbox/bmclib/v2"
"github.com/bmc-toolbox/bmclib/v2/providers"
logrusr "github.com/bombsimon/logrusr/v2"

"github.com/sirupsen/logrus"
)

func main() {
// setup logger
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()

// Command line option flag parsing
user := flag.String("user", "", "Username to login with")
pass := flag.String("password", "", "Username to login with")
host := flag.String("host", "", "BMC hostname to connect to")
mode := flag.String("mode", "get", "Mode [get,set,reset]")
dfile := flag.String("file", "", "Read data from file")

flag.Parse()

// Logger configuration
l := logrus.New()
l.Level = logrus.TraceLevel
l.Level = logrus.DebugLevel
logger := logrusr.New(l)

// bmclib client abstraction
clientOpts := []bmclib.Option{bmclib.WithLogger(logger)}

host := os.Getenv("BMC_HOST")
bmcPass := os.Getenv("BMC_PASSWORD")
bmcUser := os.Getenv("BMC_USERNAME")
// init client
client := bmclib.NewClient(host, bmcUser, bmcPass, clientOpts...)
client := bmclib.NewClient(*host, *user, *pass, clientOpts...)
client.Registry.Drivers = client.Registry.Supports(providers.FeatureGetBiosConfiguration, providers.FeatureSetBiosConfiguration, providers.FeatureResetBiosConfiguration)

ctx := context.TODO()
// open BMC session
err := client.Open(ctx)
if err != nil {
l.Fatal(err, "bmc login failed")
}

defer client.Close(ctx)

// retrieve bios configuration
biosConfig, err := client.GetBiosConfiguration(ctx)
if err != nil {
l.Error(err)
}
// Operating mode selection
switch strings.ToLower(*mode) {
case "get":
// retrieve bios configuration
biosConfig, err := client.GetBiosConfiguration(ctx)
if err != nil {
l.Fatal(err)
}

fmt.Printf("biosConfig: %+v\n", biosConfig)
case "set":
exampleConfig := make(map[string]string)

fmt.Println(biosConfig)
if *dfile != "" {
jsonFile, err := os.Open(*dfile)
if err != nil {
l.Fatal(err)
}

defer jsonFile.Close()

jsonData, _ := io.ReadAll(jsonFile)

err = json.Unmarshal(jsonData, &exampleConfig)
if err != nil {
l.Fatal(err)
}
} else {
exampleConfig["TpmSecurity"] = "Off"
}

fmt.Println("Attempting to set BIOS configuration:")
fmt.Printf("exampleConfig: %+v\n", exampleConfig)

err := client.SetBiosConfiguration(ctx, exampleConfig)
if err != nil {
l.Error(err)
}
case "reset":
err := client.ResetBiosConfiguration(ctx)
if err != nil {
l.Error(err)
}
default:
l.Fatal("Unknown mode: " + *mode)

}
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/stmcginnis/gofish v0.15.1-0.20231121142100-22a60a77be91
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/otel v1.25.0
go.opentelemetry.io/otel/trace v1.25.0
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/trace v1.24.0
go.uber.org/goleak v1.2.1
golang.org/x/crypto v0.22.0
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8
Expand Down
29 changes: 6 additions & 23 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ github.com/VictorLowther/simplexml v0.0.0-20180716164440-0bff93621230 h1:t95Grn2
github.com/VictorLowther/simplexml v0.0.0-20180716164440-0bff93621230/go.mod h1:t2EzW1qybnPDQ3LR/GgeF0GOzHUXT5IVMLP2gkW1cmc=
github.com/VictorLowther/soap v0.0.0-20150314151524-8e36fca84b22 h1:a0MBqYm44o0NcthLKCljZHe1mxlN6oahCQHHThnSwB4=
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-20230717121556-5eb9915a8a5a h1:SjtoU9dE3bYfYnPXODCunMztjoDgnE3DVJCPLBqwz6Q=
github.com/bmc-toolbox/common v0.0.0-20230717121556-5eb9915a8a5a/go.mod h1:SY//n1PJjZfbFbmAsB6GvEKbc7UXz3d30s3kWxfJQ/c=
github.com/bmc-toolbox/common v0.0.0-20231204194243-7bcbccab7116 h1:gqWn/cMjryKoUfITx2vRHrRHTvd9fQ+zKPwWsmMIrK4=
github.com/bmc-toolbox/common v0.0.0-20231204194243-7bcbccab7116/go.mod h1:SY//n1PJjZfbFbmAsB6GvEKbc7UXz3d30s3kWxfJQ/c=
github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM=
Expand All @@ -20,8 +18,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zerologr v1.2.3 h1:up5N9vcH9Xck3jJkXzgyOxozT14R47IyDODz8LM1KSs=
Expand Down Expand Up @@ -69,30 +65,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc=
go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs=
go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k=
go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg=
go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ=
go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU=
go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM=
go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I=
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc=
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -101,11 +85,10 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
Expand Down
Loading
Loading