Skip to content

Commit e6ff36b

Browse files
committed
VendorConfigManager implementations for dell, supermicro and asrockrack
1 parent 5eb9915 commit e6ff36b

File tree

5 files changed

+410
-0
lines changed

5 files changed

+410
-0
lines changed

config/asrockrack.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package config
2+
3+
import (
4+
"encoding/xml"
5+
"strings"
6+
)
7+
8+
type asrockrackVendorConfig struct {
9+
ConfigFormat string
10+
ConfigData *asrockrackConfig
11+
}
12+
13+
type asrockrackConfig struct {
14+
BiosCfg *asrockrackBiosCfg `xml:"BiosCfg"`
15+
}
16+
17+
type asrockrackBiosCfg struct {
18+
XMLName xml.Name `xml:"BiosCfg"`
19+
Menus []*asrockrackBiosCfgMenu `xml:"Menu"`
20+
}
21+
22+
type asrockrackBiosCfgMenu struct {
23+
XMLName xml.Name `xml:"Menu"`
24+
Name string `xml:"name,attr"`
25+
Settings []*asrockrackBiosCfgSetting `xml:"Setting"`
26+
Menus []*asrockrackBiosCfgMenu `xml:"Menu"`
27+
}
28+
29+
type asrockrackBiosCfgSetting struct {
30+
XMLName xml.Name `xml:"Setting"`
31+
Name string `xml:"Name,attr"`
32+
Order string `xml:"order,attr"`
33+
SelectedOption string `xml:"selectedOption,attr"`
34+
Type string `xml:"type,attr"`
35+
}
36+
37+
func NewAsrockrackVendorConfigManager(configFormat string) (VendorConfigManager, error) {
38+
asrr := &asrockrackVendorConfig{}
39+
40+
switch strings.ToLower(configFormat) {
41+
case "json":
42+
asrr.ConfigFormat = strings.ToLower(configFormat)
43+
default:
44+
return nil, UnknownConfigFormatError(strings.ToLower(configFormat))
45+
}
46+
47+
asrr.ConfigData = &asrockrackConfig{
48+
BiosCfg: &asrockrackBiosCfg{},
49+
}
50+
51+
return asrr, nil
52+
}
53+
54+
// FindMenu locates an existing asrockrackBiosCfgMenu if one exists in the ConfigData, if not
55+
// it creates one and returns a pointer to that.
56+
func (cm *asrockrackVendorConfig) FindMenu(menuName string) (m *asrockrackBiosCfgMenu) {
57+
for _, m = range cm.ConfigData.BiosCfg.Menus {
58+
if m.Name == menuName {
59+
return
60+
}
61+
}
62+
63+
m.Name = menuName
64+
65+
cm.ConfigData.BiosCfg.Menus = append(cm.ConfigData.BiosCfg.Menus, m)
66+
67+
return
68+
}
69+
70+
// FindMenuSetting locates an existing asrockrackBiosCfgSetting if one exists in the
71+
// ConfigData, if not it creates one and returns a pointer to that.
72+
func (cm *asrockrackVendorConfig) FindMenuSetting(m *asrockrackBiosCfgMenu, name string) (s *asrockrackBiosCfgSetting) {
73+
for _, s = range m.Settings {
74+
if s.Name == name {
75+
return
76+
}
77+
}
78+
79+
s.Name = name
80+
81+
m.Settings = append(m.Settings, s)
82+
83+
return
84+
}
85+
86+
// 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..
87+
func (cm *asrockrackVendorConfig) Raw(name, value string, menuPath []string) {
88+
}
89+
90+
func (cm *asrockrackVendorConfig) Marshal() (string, error) {
91+
switch strings.ToLower(cm.ConfigFormat) {
92+
case "xml":
93+
x, err := xml.Marshal(cm.ConfigData)
94+
if err != nil {
95+
return "", err
96+
}
97+
98+
return string(x), nil
99+
default:
100+
return "", UnknownConfigFormatError(strings.ToLower(cm.ConfigFormat))
101+
}
102+
}
103+
104+
// Generic config options
105+
106+
func (cm *asrockrackVendorConfig) EnableTPM() {
107+
// Unimplemented
108+
}
109+
110+
func (cm *asrockrackVendorConfig) EnableSRIOV() {
111+
// Unimplemented
112+
}

config/dell.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package config
2+
3+
import (
4+
"encoding/json"
5+
"encoding/xml"
6+
"strings"
7+
)
8+
9+
type dellVendorConfig struct {
10+
ConfigFormat string
11+
ConfigData *dellConfig
12+
}
13+
14+
type dellConfig struct {
15+
SystemConfiguration *dellSystemConfiguration `xml:"SystemConfiguration" json:"SystemConfiguration"`
16+
}
17+
18+
type dellSystemConfiguration struct {
19+
XMLName xml.Name `xml:"SystemConfiguration"`
20+
Model string `xml:"Model,attr" json:"Model"`
21+
Comments []string `xml:"Comments>Comment,omitempty" json:"Comments,omitempty" `
22+
ServiceTag string `xml:"ServiceTag,attr" json:"ServiceTag"`
23+
TimeStamp string `xml:"TimeStamp,attr" json:"TimeStamp"`
24+
Components []*dellComponent `xml:"Component" json:"Components"`
25+
}
26+
27+
type dellComponent struct {
28+
XMLName xml.Name `xml:"Component"`
29+
FQDD string `xml:"FQDD,attr" json:"FQDD"`
30+
Attributes []*dellComponentAttribute `xml:"Attribute" json:"Attributes"`
31+
}
32+
33+
type dellComponentAttribute struct {
34+
XMLName xml.Name `xml:"Attribute"`
35+
Name string `xml:"Name,attr" json:"Name"`
36+
SetOnImport bool `json:"SetOnImport"`
37+
Comment string `json:"Comment"`
38+
Value string `xml:",chardata" json:"Value"`
39+
}
40+
41+
func NewDellVendorConfigManager(configFormat string) (VendorConfigManager, error) {
42+
dell := &dellVendorConfig{}
43+
44+
switch strings.ToLower(configFormat) {
45+
case "xml", "json":
46+
dell.ConfigFormat = strings.ToLower(configFormat)
47+
default:
48+
return nil, UnknownConfigFormatError(strings.ToLower(configFormat))
49+
}
50+
51+
dell.ConfigData = &dellConfig{
52+
SystemConfiguration: &dellSystemConfiguration{},
53+
}
54+
55+
return dell, nil
56+
}
57+
58+
// FindComponent locates an existing DellComponent if one exists in the ConfigData, if not
59+
// it creates one and returns a pointer to that.
60+
func (cm *dellVendorConfig) FindComponent(fqdd string) (c *dellComponent) {
61+
for _, c = range cm.ConfigData.SystemConfiguration.Components {
62+
if c.FQDD == fqdd {
63+
return
64+
}
65+
}
66+
67+
c.FQDD = fqdd
68+
69+
cm.ConfigData.SystemConfiguration.Components = append(cm.ConfigData.SystemConfiguration.Components, c)
70+
71+
return
72+
}
73+
74+
// FindComponentAttribute locates an existing DellComponentAttribute if one exists in the
75+
// ConfigData, if not it creates one and returns a pointer to that.
76+
func (cm *dellVendorConfig) FindComponentAttribute(c *dellComponent, name string) (a *dellComponentAttribute) {
77+
for _, a = range c.Attributes {
78+
if a.Name == name {
79+
return
80+
}
81+
}
82+
83+
a.Name = name
84+
85+
c.Attributes = append(c.Attributes, a)
86+
87+
return
88+
}
89+
90+
func (cm *dellVendorConfig) Raw(name, value string, menuPath []string) {
91+
c := cm.FindComponent(menuPath[0])
92+
attr := cm.FindComponentAttribute(c, name)
93+
attr.Value = value
94+
}
95+
96+
func (cm *dellVendorConfig) Marshal() (string, error) {
97+
switch strings.ToLower(cm.ConfigFormat) {
98+
case "xml":
99+
x, err := xml.Marshal(cm.ConfigData)
100+
if err != nil {
101+
return "", err
102+
}
103+
104+
return string(x), nil
105+
case "json":
106+
x, err := json.Marshal(cm.ConfigData)
107+
if err != nil {
108+
return "", err
109+
}
110+
111+
return string(x), nil
112+
default:
113+
return "", UnknownConfigFormatError(strings.ToLower(cm.ConfigFormat))
114+
}
115+
}
116+
117+
// Generic config options
118+
119+
func (cm *dellVendorConfig) EnableTPM() {
120+
cm.Raw("EnableTPM", "Enabled", []string{"BIOS.Setup.1-1"})
121+
}
122+
123+
func (cm *dellVendorConfig) EnableSRIOV() {
124+
// TODO(jwb) How do we want to handle enabling this for different NICs
125+
cm.Raw("VirtualizationMode", "SRIOV", []string{"NIC.Slot.3-1-1"})
126+
}

config/errors.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package config
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
)
7+
8+
var errUnknownConfigFormat = errors.New("unknown config format")
9+
var errUnknownVendor = errors.New("unknown/unsupported vendor")
10+
11+
func UnknownConfigFormatError(format string) error {
12+
return fmt.Errorf("unknown config format %w : %s", errUnknownConfigFormat, format)
13+
}
14+
15+
func UnknownVendorError(vendorName string) error {
16+
return fmt.Errorf("unknown/unsupported vendor %w : %s", errUnknownVendor, vendorName)
17+
}

config/interface.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package config
2+
3+
import (
4+
"strings"
5+
6+
"github.com/bmc-toolbox/common"
7+
)
8+
9+
type VendorConfigManager interface {
10+
EnableTPM()
11+
EnableSRIOV()
12+
13+
Raw(name, value string, menuPath []string)
14+
Marshal() (string, error)
15+
}
16+
17+
func NewVendorConfigManager(configFormat, vendorName string) (VendorConfigManager, error) {
18+
switch strings.ToLower(vendorName) {
19+
case common.VendorDell:
20+
return NewDellVendorConfigManager(configFormat)
21+
case common.VendorSupermicro:
22+
return NewSupermicroVendorConfigManager(configFormat)
23+
case common.VendorAsrockrack:
24+
return NewAsrockrackVendorConfigManager(configFormat)
25+
default:
26+
return nil, UnknownVendorError(strings.ToLower(vendorName))
27+
}
28+
}

0 commit comments

Comments
 (0)