Skip to content

Commit

Permalink
Add SetBiosConfiguration(ctx, biosConfig) as well as ResetBiosConfigu…
Browse files Browse the repository at this point in the history
…ration(ctx) to redfishwrapper, redfish, etc.
  • Loading branch information
splaspood committed Apr 9, 2024
1 parent 5b958a7 commit d871563
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 1 deletion.
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 @@ 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
Loop:
Expand Down Expand Up @@ -46,6 +64,62 @@ Loop:
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
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 @@ 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)
}
24 changes: 23 additions & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import (
"github.com/bmc-toolbox/common"
"github.com/go-logr/logr"
"github.com/jacobweinstock/registrar"
"go.opencensus.io/trace"

Check failure on line 30 in client.go

View workflow job for this annotation

GitHub Actions / test

no required module provides package go.opencensus.io/trace; to add it:

Check failure on line 30 in client.go

View workflow job for this annotation

GitHub Actions / test

no required module provides package go.opencensus.io/trace; to add it:
"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 @@ -556,6 +556,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
38 changes: 38 additions & 0 deletions internal/redfishwrapper/bios.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

bmclibErrs "github.com/bmc-toolbox/bmclib/v2/errors"
"github.com/stmcginnis/gofish/redfish"
)

func (c *Client) GetBiosConfiguration(ctx context.Context) (biosConfig map[string]string, err error) {
Expand Down Expand Up @@ -34,3 +35,40 @@ func (c *Client) GetBiosConfiguration(ctx context.Context) (biosConfig map[strin

return biosConfig, nil
}

func (c *Client) SetBiosConfiguration(ctx context.Context, biosConfig map[string]string) (err error) {
systems, err := c.Systems()
if err != nil {
return err
}

settingsAttributes := make(redfish.SettingsAttributes)

for attr, value := range biosConfig {
settingsAttributes[attr] = value
}

for _, sys := range systems {
if !c.compatibleOdataID(sys.ODataID, knownSystemsOdataIDs) {
continue
}

bios, err := sys.Bios()
if err != nil {
return err
}

err = bios.UpdateBiosAttributes(settingsAttributes)

if err != nil {
return err
}
}

return nil
}

func (c *Client) ResetBiosConfiguration(ctx context.Context) (err error) {
// TODO(jwb) do the reset :P
return nil
}
18 changes: 18 additions & 0 deletions providers/dell/idrac.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ var (
providers.FeatureFirmwareTaskStatus,
providers.FeatureInventoryRead,
providers.FeatureBmcReset,
providers.FeatureGetBiosConfiguration,
providers.FeatureSetBiosConfiguration,
providers.FeatureResetBiosConfiguration,
}

errManufacturerUnknown = errors.New("error identifying device manufacturer")
Expand Down Expand Up @@ -219,6 +222,21 @@ func (c *Conn) BmcReset(ctx context.Context, resetType string) (ok bool, err err
return c.redfishwrapper.BMCReset(ctx, resetType)
}

// GetBiosConfiguration returns the BIOS configuration settings via the BMC
func (c *Conn) GetBiosConfiguration(ctx context.Context) (biosConfig map[string]string, err error) {
return c.redfishwrapper.GetBiosConfiguration(ctx)
}

// SetBiosConfiguration sets the BIOS configuration settings via the BMC
func (c *Conn) SetBiosConfiguration(ctx context.Context, biosConfig map[string]string) (err error) {
return c.redfishwrapper.SetBiosConfiguration(ctx, biosConfig)
}

// ResetBiosConfiguration resets the BIOS configuration settings back to 'factory defaults' via the BMC
func (c *Conn) ResetBiosConfiguration(ctx context.Context) (err error) {
return c.redfishwrapper.ResetBiosConfiguration(ctx)
}

// SendNMI tells the BMC to issue an NMI to the device
func (c *Conn) SendNMI(ctx context.Context) error {
return c.redfishwrapper.SendNMI(ctx)
Expand Down
9 changes: 9 additions & 0 deletions providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,13 @@ const (

// FeatureDeactivateSOL means an implementation that can deactivate active SOL sessions
FeatureDeactivateSOL registrar.Feature = "deactivatesol"

// FeatureResetBiosConfiguration means an implementation that can reset bios configuration back to 'factory' defaults
FeatureResetBiosConfiguration registrar.Feature = "resetbiosconfig"

// FeatureSetBiosConfiguration means an implementation that can set bios configuration from an input k/v map
FeatureSetBiosConfiguration registrar.Feature = "setbiosconfig"

// FeatureGetBiosConfiguration means an implementation that can get bios configuration in a simple k/v map
FeatureGetBiosConfiguration registrar.Feature = "getbiosconfig"
)
5 changes: 5 additions & 0 deletions providers/redfish/redfish.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ func (c *Conn) GetBiosConfiguration(ctx context.Context) (biosConfig map[string]
return c.redfishwrapper.GetBiosConfiguration(ctx)
}

// SetBiosConfiguration set bios configuration
func (c *Conn) SetBiosConfiguration(ctx context.Context, biosConfig map[string]string) (err error) {
return c.redfishwrapper.SetBiosConfiguration(ctx, biosConfig)
}

// SendNMI tells the BMC to issue an NMI to the device
func (c *Conn) SendNMI(ctx context.Context) error {
return c.redfishwrapper.SendNMI(ctx)
Expand Down

0 comments on commit d871563

Please sign in to comment.