func (c *Client) UpdateBIOSFirmware(ctx context.Context, fileReader io.Reader, fileSize int64) (err error) {
	return bmc.UpdateBIOSFirmwareFromInterfaces(ctx, fileReader, fileSize, c.Registry.GetDriverInterfaces())
}
UpdateBIOSFirmware pass through library function
package bmclib
import (
	"context"
	"io"
	"sync"
	"github.com/bmc-toolbox/bmclib/bmc"
	"github.com/bmc-toolbox/bmclib/providers/asrockrack"
	"github.com/bmc-toolbox/bmclib/providers/dell/idrac9"
	"github.com/bmc-toolbox/bmclib/providers/goipmi"
	"github.com/bmc-toolbox/bmclib/providers/ipmitool"
	"github.com/bmc-toolbox/bmclib/providers/redfish"
	"github.com/go-logr/logr"
	"github.com/jacobweinstock/registrar"
)
type Client struct {
	Auth     Auth
	Logger   logr.Logger
	Registry *registrar.Registry
	metadata *bmc.Metadata
	mdLock   *sync.Mutex
}
type Auth struct {
	Host string
	Port string
	User string
	Pass string
}
type Option func(*Client)
func WithLogger(logger logr.Logger) Option {
	return func(args *Client) { args.Logger = logger }
}
func WithRegistry(registry *registrar.Registry) Option {
	return func(args *Client) { args.Registry = registry }
}
func NewClient(host, port, user, pass string, opts ...Option) *Client {
	var defaultClient = &Client{
		Logger:   logr.Discard(),
		Registry: registrar.NewRegistry(),
	}
	for _, opt := range opts {
		opt(defaultClient)
	}
	defaultClient.Registry.Logger = defaultClient.Logger
	defaultClient.Auth.Host = host
	defaultClient.Auth.Port = port
	defaultClient.Auth.User = user
	defaultClient.Auth.Pass = pass
	if len(defaultClient.Registry.Drivers) == 0 {
		defaultClient.registerProviders()
	}
	defaultClient.mdLock = &sync.Mutex{}
	return defaultClient
}
func (c *Client) registerProviders() {
	driverIpmitool := &ipmitool.Conn{Host: c.Auth.Host, Port: c.Auth.Port, User: c.Auth.User, Pass: c.Auth.Pass, Log: c.Logger}
	c.Registry.Register(ipmitool.ProviderName, ipmitool.ProviderProtocol, ipmitool.Features, nil, driverIpmitool)
	driverAsrockrack, _ := asrockrack.New(c.Auth.Host, c.Auth.User, c.Auth.Pass, c.Logger)
	c.Registry.Register(asrockrack.ProviderName, asrockrack.ProviderProtocol, asrockrack.Features, nil, driverAsrockrack)
	driverGoIpmi := &goipmi.Conn{Host: c.Auth.Host, Port: c.Auth.Port, User: c.Auth.User, Pass: c.Auth.Pass, Log: c.Logger}
	c.Registry.Register(goipmi.ProviderName, goipmi.ProviderProtocol, goipmi.Features, nil, driverGoIpmi)
	driverGoFish := &redfish.Conn{Host: c.Auth.Host, Port: c.Auth.Port, User: c.Auth.User, Pass: c.Auth.Pass, Log: c.Logger}
	c.Registry.Register(redfish.ProviderName, redfish.ProviderProtocol, redfish.Features, nil, driverGoFish)
	driverIdrac9 := &idrac9.Conn{Host: c.Auth.Host, Port: c.Auth.Port, User: c.Auth.User, Pass: c.Auth.Pass, Log: c.Logger}
	c.Registry.Register(idrac9.ProviderName, idrac9.ProviderProtocol, idrac9.Features, nil, driverIdrac9)
}
func (c *Client) GetMetadata() bmc.Metadata {
	return *c.metadata
}
func (c *Client) setMetadata(metadata bmc.Metadata) {
	if c.mdLock != nil {
		c.mdLock.Lock()
		defer c.mdLock.Unlock()
	}
	c.metadata = &metadata
}
func (c *Client) Open(ctx context.Context) error {
	ifs, metadata, err := bmc.OpenConnectionFromInterfaces(ctx, c.Registry.GetDriverInterfaces())
	if err != nil {
		return err
	}
	var reg registrar.Drivers
	for _, elem := range c.Registry.Drivers {
		for _, em := range ifs {
			if em == elem.DriverInterface {
				elem.DriverInterface = em
				reg = append(reg, elem)
			}
		}
	}
	c.Registry.Drivers = reg
	c.setMetadata(metadata)
	return nil
}
func (c *Client) Close(ctx context.Context) (err error) {
	metadata, err := bmc.CloseConnectionFromInterfaces(ctx, c.Registry.GetDriverInterfaces())
	c.setMetadata(metadata)
	return err
}
func (c *Client) GetPowerState(ctx context.Context) (state string, err error) {
	state, metadata, err := bmc.GetPowerStateFromInterfaces(ctx, c.Registry.GetDriverInterfaces())
	c.setMetadata(metadata)
	return state, err
}
func (c *Client) SetPowerState(ctx context.Context, state string) (ok bool, err error) {
	ok, metadata, err := bmc.SetPowerStateFromInterfaces(ctx, state, c.Registry.GetDriverInterfaces())
	c.setMetadata(metadata)
	return ok, err
}
func (c *Client) CreateUser(ctx context.Context, user, pass, role string) (ok bool, err error) {
	ok, metadata, err := bmc.CreateUserFromInterfaces(ctx, user, pass, role, c.Registry.GetDriverInterfaces())
	c.setMetadata(metadata)
	return ok, err
}
func (c *Client) UpdateUser(ctx context.Context, user, pass, role string) (ok bool, err error) {
	ok, metadata, err := bmc.UpdateUserFromInterfaces(ctx, user, pass, role, c.Registry.GetDriverInterfaces())
	c.setMetadata(metadata)
	return ok, err
}
func (c *Client) DeleteUser(ctx context.Context, user string) (ok bool, err error) {
	ok, metadata, err := bmc.DeleteUserFromInterfaces(ctx, user, c.Registry.GetDriverInterfaces())
	c.setMetadata(metadata)
	return ok, err
}
func (c *Client) ReadUsers(ctx context.Context) (users []map[string]string, err error) {
	users, metadata, err := bmc.ReadUsersFromInterfaces(ctx, c.Registry.GetDriverInterfaces())
	c.setMetadata(metadata)
	return users, err
}
func (c *Client) SetBootDevice(ctx context.Context, bootDevice string, setPersistent, efiBoot bool) (ok bool, err error) {
	ok, metadata, err := bmc.SetBootDeviceFromInterfaces(ctx, bootDevice, setPersistent, efiBoot, c.Registry.GetDriverInterfaces())
	c.setMetadata(metadata)
	return ok, err
}
func (c *Client) ResetBMC(ctx context.Context, resetType string) (ok bool, err error) {
	ok, metadata, err := bmc.ResetBMCFromInterfaces(ctx, resetType, c.Registry.GetDriverInterfaces())
	c.setMetadata(metadata)
	return ok, err
}
func (c *Client) GetBMCVersion(ctx context.Context) (version string, err error) {
	return bmc.GetBMCVersionFromInterfaces(ctx, c.Registry.GetDriverInterfaces())
}
func (c *Client) UpdateBMCFirmware(ctx context.Context, fileReader io.Reader, fileSize int64) (err error) {
	return bmc.UpdateBMCFirmwareFromInterfaces(ctx, fileReader, fileSize, c.Registry.GetDriverInterfaces())
}
func (c *Client) GetBIOSVersion(ctx context.Context) (version string, err error) {
	return bmc.GetBIOSVersionFromInterfaces(ctx, c.Registry.GetDriverInterfaces())
}