Skip to content

Commit

Permalink
Merge pull request #385 from bmc-toolbox/bios-config-0
Browse files Browse the repository at this point in the history
SetBiosConfiguration(ctx, biosConfig) & ResetBiosConfiguration(ctx) for dell
  • Loading branch information
splaspood authored Apr 16, 2024
2 parents 7b6b567 + 27122f0 commit a3d8e72
Show file tree
Hide file tree
Showing 12 changed files with 336 additions and 58 deletions.
136 changes: 131 additions & 5 deletions bmc/bios.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,26 @@ type biosConfigurationGetterProvider struct {
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
metadata = newMetadata()
Loop:
for _, elem := range generic {
if elem.BiosConfigurationGetter == nil {
Expand All @@ -30,20 +48,76 @@ Loop:
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)
break Loop
default:
metadataLocal.ProvidersAttempted = append(metadataLocal.ProvidersAttempted, elem.name)
metadata.ProvidersAttempted = append(metadata.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)
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)
continue

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

return biosConfig, metadata, 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) {
metadata = newMetadata()
Loop:
for _, elem := range generic {
if elem.BiosConfigurationSetter == nil {
continue
}
select {
case <-ctx.Done():
err = multierror.Append(err, ctx.Err())
break Loop
default:
metadata.ProvidersAttempted = append(metadata.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

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

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

func resetBiosConfiguration(ctx context.Context, generic []biosConfigurationResetterProvider) (metadata Metadata, err error) {
metadata = newMetadata()
Loop:
for _, elem := range generic {
if elem.BiosConfigurationResetter == nil {
continue
}
select {
case <-ctx.Done():
err = multierror.Append(err, ctx.Err())
break Loop
default:
metadata.ProvidersAttempted = append(metadata.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

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

return biosConfig, metadataLocal, multierror.Append(err, errors.New("failure to get bios configuration"))
return metadata, 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) {
Expand Down Expand Up @@ -71,3 +145,55 @@ func GetBiosConfigurationInterfaces(ctx context.Context, generic []interface{})

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) {
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
Loading

0 comments on commit a3d8e72

Please sign in to comment.