-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from bmc-toolbox/hw-config-0
VendorConfigManager implementations for dell, supermicro and asrockrack
- Loading branch information
Showing
5 changed files
with
428 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package config | ||
|
||
import ( | ||
"encoding/xml" | ||
"strings" | ||
) | ||
|
||
type asrockrackVendorConfig struct { | ||
ConfigFormat string | ||
ConfigData *asrockrackConfig | ||
} | ||
|
||
type asrockrackConfig struct { | ||
BiosCfg *asrockrackBiosCfg `xml:"BiosCfg"` | ||
} | ||
|
||
type asrockrackBiosCfg struct { | ||
XMLName xml.Name `xml:"BiosCfg"` | ||
Menus []*asrockrackBiosCfgMenu `xml:"Menu"` | ||
} | ||
|
||
type asrockrackBiosCfgMenu struct { | ||
XMLName xml.Name `xml:"Menu"` | ||
Name string `xml:"name,attr"` | ||
Settings []*asrockrackBiosCfgSetting `xml:"Setting"` | ||
Menus []*asrockrackBiosCfgMenu `xml:"Menu"` | ||
} | ||
|
||
type asrockrackBiosCfgSetting struct { | ||
XMLName xml.Name `xml:"Setting"` | ||
Name string `xml:"Name,attr"` | ||
Order string `xml:"order,attr"` | ||
SelectedOption string `xml:"selectedOption,attr"` | ||
Type string `xml:"type,attr"` | ||
} | ||
|
||
func NewAsrockrackVendorConfigManager(configFormat string, vendorOptions map[string]string) (VendorConfigManager, error) { | ||
asrr := &asrockrackVendorConfig{} | ||
|
||
switch strings.ToLower(configFormat) { | ||
case "json": | ||
asrr.ConfigFormat = strings.ToLower(configFormat) | ||
default: | ||
return nil, UnknownConfigFormatError(strings.ToLower(configFormat)) | ||
} | ||
|
||
asrr.ConfigData = &asrockrackConfig{ | ||
BiosCfg: &asrockrackBiosCfg{}, | ||
} | ||
|
||
return asrr, nil | ||
} | ||
|
||
// FindMenu locates an existing asrockrackBiosCfgMenu if one exists in the ConfigData, if not | ||
// it creates one and returns a pointer to that. | ||
func (cm *asrockrackVendorConfig) FindMenu(menuName string) (m *asrockrackBiosCfgMenu) { | ||
if cm.ConfigData.BiosCfg.Menus == nil { | ||
return | ||
} | ||
|
||
for _, m = range cm.ConfigData.BiosCfg.Menus { | ||
if m.Name == menuName { | ||
return | ||
} | ||
} | ||
|
||
m.Name = menuName | ||
|
||
cm.ConfigData.BiosCfg.Menus = append(cm.ConfigData.BiosCfg.Menus, m) | ||
|
||
return | ||
} | ||
|
||
// FindMenuSetting locates an existing asrockrackBiosCfgSetting if one exists in the | ||
// ConfigData, if not it creates one and returns a pointer to that. | ||
func (cm *asrockrackVendorConfig) FindMenuSetting(m *asrockrackBiosCfgMenu, name string) (s *asrockrackBiosCfgSetting) { | ||
for _, s = range m.Settings { | ||
if s.Name == name { | ||
return | ||
} | ||
} | ||
|
||
s.Name = name | ||
|
||
m.Settings = append(m.Settings, s) | ||
|
||
return | ||
} | ||
|
||
// TODO(jwb) How do we handle the random nature of sub menus here.. we could make the user pass the explicit pointer to a menu struct, or.. | ||
func (cm *asrockrackVendorConfig) Raw(name, value string, menuPath []string) { | ||
} | ||
|
||
func (cm *asrockrackVendorConfig) Marshal() (string, error) { | ||
switch strings.ToLower(cm.ConfigFormat) { | ||
case "xml": | ||
x, err := xml.Marshal(cm.ConfigData) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return string(x), nil | ||
default: | ||
return "", UnknownConfigFormatError(strings.ToLower(cm.ConfigFormat)) | ||
} | ||
} | ||
|
||
// Generic config options | ||
|
||
func (cm *asrockrackVendorConfig) EnableTPM() { | ||
// Unimplemented | ||
} | ||
|
||
func (cm *asrockrackVendorConfig) EnableSRIOV() { | ||
// Unimplemented | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
package config | ||
|
||
import ( | ||
"encoding/json" | ||
"encoding/xml" | ||
"strings" | ||
) | ||
|
||
type dellVendorConfig struct { | ||
ConfigFormat string | ||
ConfigData *dellConfig | ||
} | ||
|
||
type dellConfig struct { | ||
SystemConfiguration *dellSystemConfiguration `xml:"SystemConfiguration" json:"SystemConfiguration"` | ||
} | ||
|
||
type dellSystemConfiguration struct { | ||
XMLName xml.Name `xml:"SystemConfiguration"` | ||
Model string `xml:"Model,attr" json:"Model"` | ||
Comments []string `xml:"Comments>Comment,omitempty" json:"Comments,omitempty"` | ||
ServiceTag string `xml:"ServiceTag,attr" json:"ServiceTag"` | ||
TimeStamp string `xml:"TimeStamp,attr" json:"TimeStamp"` | ||
Components []*dellComponent `xml:"Component" json:"Components"` | ||
} | ||
|
||
type dellComponent struct { | ||
XMLName xml.Name `xml:"Component"` | ||
FQDD string `xml:"FQDD,attr" json:"FQDD"` | ||
Attributes []*dellComponentAttribute `xml:"Attribute" json:"Attributes"` | ||
} | ||
|
||
type dellComponentAttribute struct { | ||
XMLName xml.Name `xml:"Attribute"` | ||
Name string `xml:"Name,attr" json:"Name"` | ||
SetOnImport bool `xml:"SetOnImport,omitempty" json:"SetOnImport,omitempty"` | ||
Comment string `xml:"Comment,omitempty" json:"Comment,omitempty"` | ||
Value string `xml:",chardata" json:"Value"` | ||
} | ||
|
||
func NewDellVendorConfigManager(configFormat string, vendorOptions map[string]string) (VendorConfigManager, error) { | ||
dell := &dellVendorConfig{} | ||
|
||
switch strings.ToLower(configFormat) { | ||
case "xml", "json": | ||
dell.ConfigFormat = strings.ToLower(configFormat) | ||
default: | ||
return nil, UnknownConfigFormatError(strings.ToLower(configFormat)) | ||
} | ||
|
||
dell.ConfigData = &dellConfig{ | ||
SystemConfiguration: &dellSystemConfiguration{}, | ||
} | ||
|
||
dell.setSystemConfiguration(vendorOptions["model"], vendorOptions["servicetag"]) | ||
|
||
return dell, nil | ||
} | ||
|
||
func (cm *dellVendorConfig) setSystemConfiguration(model, servicetag string) { | ||
cm.ConfigData.SystemConfiguration.Model = model | ||
cm.ConfigData.SystemConfiguration.ServiceTag = servicetag | ||
// TODO(jwb) Make this 'now' | ||
cm.ConfigData.SystemConfiguration.TimeStamp = "Tue Nov 2 21:19:16 2021" | ||
} | ||
|
||
// FindComponent locates an existing DellComponent if one exists in the ConfigData, if not | ||
// it creates one and returns a pointer to that. | ||
func (cm *dellVendorConfig) FindComponent(fqdd string) (c *dellComponent) { | ||
for _, c = range cm.ConfigData.SystemConfiguration.Components { | ||
if c.FQDD == fqdd { | ||
return | ||
} | ||
} | ||
|
||
c = &dellComponent{ | ||
XMLName: xml.Name{}, | ||
FQDD: fqdd, | ||
Attributes: []*dellComponentAttribute{}, | ||
} | ||
|
||
cm.ConfigData.SystemConfiguration.Components = append(cm.ConfigData.SystemConfiguration.Components, c) | ||
|
||
return | ||
} | ||
|
||
// FindComponentAttribute locates an existing DellComponentAttribute if one exists in the | ||
// ConfigData, if not it creates one and returns a pointer to that. | ||
func (cm *dellVendorConfig) FindComponentAttribute(c *dellComponent, name string) (a *dellComponentAttribute) { | ||
for _, a = range c.Attributes { | ||
if a.Name == name { | ||
return | ||
} | ||
} | ||
|
||
a = &dellComponentAttribute{ | ||
Name: name, | ||
} | ||
|
||
c.Attributes = append(c.Attributes, a) | ||
|
||
return | ||
} | ||
|
||
func (cm *dellVendorConfig) Raw(name, value string, menuPath []string) { | ||
c := cm.FindComponent(menuPath[0]) | ||
attr := cm.FindComponentAttribute(c, name) | ||
attr.Value = value | ||
} | ||
|
||
func (cm *dellVendorConfig) Marshal() (string, error) { | ||
switch strings.ToLower(cm.ConfigFormat) { | ||
case "xml": | ||
x, err := xml.Marshal(cm.ConfigData.SystemConfiguration) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return string(x), nil | ||
case "json": | ||
x, err := json.Marshal(cm.ConfigData.SystemConfiguration) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return string(x), nil | ||
default: | ||
return "", UnknownConfigFormatError(strings.ToLower(cm.ConfigFormat)) | ||
} | ||
} | ||
|
||
// Generic config options | ||
|
||
func (cm *dellVendorConfig) EnableTPM() { | ||
cm.Raw("EnableTPM", "Enabled", []string{"BIOS.Setup.1-1"}) | ||
} | ||
|
||
func (cm *dellVendorConfig) EnableSRIOV() { | ||
// TODO(jwb) How do we want to handle enabling this for different NICs | ||
cm.Raw("VirtualizationMode", "SRIOV", []string{"NIC.Slot.3-1-1"}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package config | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
) | ||
|
||
var errUnknownConfigFormat = errors.New("unknown config format") | ||
var errUnknownVendor = errors.New("unknown/unsupported vendor") | ||
|
||
func UnknownConfigFormatError(format string) error { | ||
return fmt.Errorf("unknown config format %w : %s", errUnknownConfigFormat, format) | ||
} | ||
|
||
func UnknownVendorError(vendorName string) error { | ||
return fmt.Errorf("unknown/unsupported vendor %w : %s", errUnknownVendor, vendorName) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package config | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/bmc-toolbox/common" | ||
) | ||
|
||
type VendorConfigManager interface { | ||
EnableTPM() | ||
EnableSRIOV() | ||
|
||
Raw(name, value string, menuPath []string) | ||
Marshal() (string, error) | ||
} | ||
|
||
func NewVendorConfigManager(configFormat, vendorName string, vendorOptions map[string]string) (VendorConfigManager, error) { | ||
switch strings.ToLower(vendorName) { | ||
case common.VendorDell: | ||
return NewDellVendorConfigManager(configFormat, vendorOptions) | ||
case common.VendorSupermicro: | ||
return NewSupermicroVendorConfigManager(configFormat, vendorOptions) | ||
case common.VendorAsrockrack: | ||
return NewAsrockrackVendorConfigManager(configFormat, vendorOptions) | ||
default: | ||
return nil, UnknownVendorError(strings.ToLower(vendorName)) | ||
} | ||
} |
Oops, something went wrong.