From 64957797391927baac5ce87574728bed75dcabb9 Mon Sep 17 00:00:00 2001 From: "James W. Brinkerhoff" Date: Tue, 20 Feb 2024 08:16:38 -0500 Subject: [PATCH] Add SetBiosConfigurationInterfaces alongside GetBiosConfigurationInterfaces --- bmc/bios.go | 63 +++++++++++++++++++++++++++++++++ client.go | 11 ++++++ internal/redfishwrapper/bios.go | 6 ++-- providers/dell/idrac.go | 2 ++ providers/redfish/redfish.go | 7 ++++ 5 files changed, 86 insertions(+), 3 deletions(-) diff --git a/bmc/bios.go b/bmc/bios.go index e1230fcaa..4041f7419 100644 --- a/bmc/bios.go +++ b/bmc/bios.go @@ -13,11 +13,20 @@ type BiosConfigurationGetter interface { GetBiosConfiguration(ctx context.Context) (biosConfig map[string]string, err error) } +type BiosConfigurationSetter interface { + SetBiosConfiguration(ctx context.Context, biosConfig map[string]string) (err error) +} + type biosConfigurationGetterProvider struct { name string BiosConfigurationGetter } +type biosConfigurationSetterProvider struct { + name string + BiosConfigurationSetter +} + func biosConfiguration(ctx context.Context, generic []biosConfigurationGetterProvider) (biosConfig map[string]string, metadata Metadata, err error) { var metadataLocal Metadata Loop: @@ -46,6 +55,34 @@ Loop: return biosConfig, metadataLocal, multierror.Append(err, errors.New("failure to get bios configuration")) } +func setBiosConfiguration(ctx context.Context, generic []biosConfigurationSetterProvider, toSet 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, toSet) + 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 GetBiosConfigurationInterfaces(ctx context.Context, generic []interface{}) (biosConfig map[string]string, metadata Metadata, err error) { implementations := make([]biosConfigurationGetterProvider, 0) for _, elem := range generic { @@ -71,3 +108,29 @@ func GetBiosConfigurationInterfaces(ctx context.Context, generic []interface{}) return biosConfiguration(ctx, implementations) } + +func SetBiosConfigurationInterfaces(ctx context.Context, generic []interface{}, toSet 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 BiosConfigurationGetter implementations found"), + ), + ) + } + + return setBiosConfiguration(ctx, implementations, toSet) +} diff --git a/client.go b/client.go index f93d76027..f5d9857ae 100644 --- a/client.go +++ b/client.go @@ -556,6 +556,17 @@ 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 +} + // 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") diff --git a/internal/redfishwrapper/bios.go b/internal/redfishwrapper/bios.go index 6c9398d59..b30b6d6e0 100644 --- a/internal/redfishwrapper/bios.go +++ b/internal/redfishwrapper/bios.go @@ -36,8 +36,8 @@ func (c *Client) GetBiosConfiguration(ctx context.Context) (biosConfig map[strin return biosConfig, nil } -func (c *Conn) SetBiosConfiguration(ctx context.Context, toSet map[string]string) (err error) { - systems, err := c.redfishwrapper.Systems() +func (c *Client) SetBiosConfiguration(ctx context.Context, toSet map[string]string) (err error) { + systems, err := c.Systems() if err != nil { return err } @@ -49,7 +49,7 @@ func (c *Conn) SetBiosConfiguration(ctx context.Context, toSet map[string]string } for _, sys := range systems { - if !compatibleOdataID(sys.ODataID, systemsOdataIDs) { + if !c.compatibleOdataID(sys.ODataID, knownSystemsOdataIDs) { continue } diff --git a/providers/dell/idrac.go b/providers/dell/idrac.go index e4b2aa463..1b1053a49 100644 --- a/providers/dell/idrac.go +++ b/providers/dell/idrac.go @@ -43,6 +43,8 @@ var ( providers.FeatureFirmwareTaskStatus, providers.FeatureInventoryRead, providers.FeatureBmcReset, + providers.FeatureBiosConfigurationGetting, + providers.FeatureBiosConfigurationSetting, } errManufacturerUnknown = errors.New("error identifying device manufacturer") diff --git a/providers/redfish/redfish.go b/providers/redfish/redfish.go index 1dae9e804..11839310b 100644 --- a/providers/redfish/redfish.go +++ b/providers/redfish/redfish.go @@ -36,6 +36,8 @@ var ( providers.FeatureInventoryRead, providers.FeatureBmcReset, providers.FeatureClearSystemEventLog, + providers.FeatureBiosConfigurationGetting, + providers.FeatureBiosConfigurationSetting, } ) @@ -217,3 +219,8 @@ func (c *Conn) Inventory(ctx context.Context) (device *common.Device, err error) func (c *Conn) GetBiosConfiguration(ctx context.Context) (biosConfig map[string]string, err error) { return c.redfishwrapper.GetBiosConfiguration(ctx) } + +// SetBiosConfiguration changes existing bios configuration +func (c *Conn) SetBiosConfiguration(ctx context.Context, biosConfig map[string]string) (err error) { + return c.redfishwrapper.SetBiosConfiguration(ctx, biosConfig) +}