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 @@ 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
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 @@ 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"
"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) {
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
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