Skip to content

Commit

Permalink
Add Supermicro OEM Manager object (#369)
Browse files Browse the repository at this point in the history
Signed-off-by: Sean McGinnis <[email protected]>
  • Loading branch information
stmcginnis authored Oct 15, 2024
1 parent 4b8c27e commit ca10211
Show file tree
Hide file tree
Showing 3 changed files with 249 additions and 4 deletions.
115 changes: 115 additions & 0 deletions oem/smc/manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//
// SPDX-License-Identifier: BSD-3-Clause
//

package smc

import (
"encoding/json"
"errors"

"github.com/stmcginnis/gofish/common"
"github.com/stmcginnis/gofish/redfish"
)

type ManagerConfigResetOption string

const (
PreserveUserManagerConfigResetOption ManagerConfigResetOption = "PreserveUser"
ClearConfigManagerConfigResetOption ManagerConfigResetOption = "ClearConfig"
ResetToAdminManagerConfigResetOption ManagerConfigResetOption = "ResetToADMIN"
)

// Manager is a Supermicro OEM instance of a Manager.
type Manager struct {
redfish.Manager

radius string
mouseMode string
ntp string
ipAccessControl string
smcRAKP string
syslog string
sysLockdown string
memoryPFA string
memoryHealthComp string
snooping string
fanMode string
iKVM string
kcsInterface string
lldp string
licenseManager string

managerConfigResetTarget string
}

// FromManager converts a standard Manager object to the OEM implementation.
func FromManager(manager *redfish.Manager) (*Manager, error) {
m := Manager{
Manager: *manager,
}

var t struct {
Oem struct {
Supermicro struct {
RADIUS common.Link `json:"RADIUS"`
MouseMode common.Link `json:"MouseMode"`
NTP common.Link `json:"NTP"`
IPAccessControl common.Link `json:"IPAccessControl"`
SMCRAKP common.Link `json:"SMCRAKP"`
Syslog common.Link `json:"Syslog"`
SysLockdown common.Link `json:"SysLockdown"`
MemoryPFA common.Link `json:"MemoryPFA"`
MemoryHealthComp common.Link `json:"MemoryHealthComp"`
Snooping common.Link `json:"Snooping"`
FanMode common.Link `json:"FanMode"`
IKVM common.Link `json:"IKVM"`
KCSInterface common.Link `json:"KCSInterface"`
LLDP common.Link `json:"LLDP"`
LicenseManager common.Link `json:"LicenseManager"`
} `json:"Supermicro"`
} `json:"Oem"`
Actions struct {
Oem struct {
ManagerConfigReset common.ActionTarget `json:"#SmcManagerConfig.Reset"`
} `json:"Oem"`
} `json:"Actions"`
}

err := json.Unmarshal(manager.RawData, &t)
if err != nil {
return nil, err
}

m.radius = t.Oem.Supermicro.RADIUS.String()
m.mouseMode = t.Oem.Supermicro.MouseMode.String()
m.ntp = t.Oem.Supermicro.NTP.String()
m.ipAccessControl = t.Oem.Supermicro.IPAccessControl.String()
m.smcRAKP = t.Oem.Supermicro.SMCRAKP.String()
m.syslog = t.Oem.Supermicro.Syslog.String()
m.sysLockdown = t.Oem.Supermicro.SysLockdown.String()
m.memoryPFA = t.Oem.Supermicro.MemoryPFA.String()
m.memoryHealthComp = t.Oem.Supermicro.MemoryHealthComp.String()
m.snooping = t.Oem.Supermicro.Snooping.String()
m.fanMode = t.Oem.Supermicro.FanMode.String()
m.iKVM = t.Oem.Supermicro.IKVM.String()
m.kcsInterface = t.Oem.Supermicro.KCSInterface.String()
m.lldp = t.Oem.Supermicro.LLDP.String()
m.licenseManager = t.Oem.Supermicro.LicenseManager.String()

m.managerConfigResetTarget = t.Actions.Oem.ManagerConfigReset.Target

m.SetClient(manager.GetClient())
return &m, nil
}

// TODO: Add linked objects

// ManagerConfigReset resets the BMC to factory defaults.
func (m *Manager) ManagerConfigReset(option ManagerConfigResetOption) error {
if m.managerConfigResetTarget == "" {
return errors.New("manager config reset not supported by this system")
}

return m.Post(m.managerConfigResetTarget, map[string]interface{}{"Option": option})
}
130 changes: 130 additions & 0 deletions oem/smc/manager_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
//
// SPDX-License-Identifier: BSD-3-Clause
//

package smc

import (
"encoding/json"
"strings"
"testing"

"github.com/stmcginnis/gofish/redfish"
)

var managerBody = `{
"@odata.type": "#Manager.v1_11_0.Manager",
"@odata.id": "/redfish/v1/Managers/1",
"Id": "1",
"Name": "Manager",
"Description": "BMC",
"ManagerType": "BMC",
"UUID": "00000000-0000-0000-0000-7CC25586E000",
"Model": "ASPEED",
"FirmwareVersion": "01.01.06",
"DateTime": "2024-10-15T21:35:01Z",
"DateTimeLocalOffset": "+00:00",
"Actions": {
"Oem": {
"#SmcManagerConfig.Reset": {
"target": "/redfish/v1/Managers/1/Actions/Oem/SmcManagerConfig.Reset",
"@Redfish.ActionInfo": "/redfish/v1/Managers/1/Oem/Supermicro/ResetActionInfo"
}
},
"#Manager.ResetToDefaults": {
"target": "/redfish/v1/Managers/1/Actions/Manager.ResetToDefaults",
"@Redfish.ActionInfo": "/redfish/v1/Managers/1/ResetToDefaultsActionInfo"
},
"#Manager.Reset": {
"target": "/redfish/v1/Managers/1/Actions/Manager.Reset",
"[email protected]": [
"GracefulRestart"
]
}
},
"Oem": {
"Supermicro": {
"@odata.type": "#SmcManagerExtensions.v1_0_0.Manager",
"RADIUS": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/RADIUS"
},
"MouseMode": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/MouseMode"
},
"NTP": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/NTP"
},
"IPAccessControl": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/IPAccessControl"
},
"SMCRAKP": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/SMCRAKP"
},
"Syslog": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/Syslog"
},
"SysLockdown": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/SysLockdown"
},
"MemoryPFA": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/MemoryPFA"
},
"MemoryHealthComp": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/MemoryHealthComp"
},
"Snooping": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/Snooping"
},
"FanMode": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/FanMode"
},
"IKVM": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/IKVM"
},
"KCSInterface": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/KCSInterface"
},
"LLDP": {
"@odata.id": "/redfish/v1/Managers/1/Oem/Supermicro/LLDP"
},
"LicenseManager": {
"@odata.id": "/redfish/v1/Managers/1/LicenseManager"
}
}
},
"@odata.etag": "\"70889f859f8f0399a6f71ffb167c1dc1\""
}`

// TestManager tests the parsing of Manager objects.
func TestManager(t *testing.T) {
var m redfish.Manager
err := json.NewDecoder(strings.NewReader(managerBody)).Decode(&m)
if err != nil {
t.Errorf("Error decoding JSON: %s", err)
}

result, err := FromManager(&m)
if err != nil {
t.Errorf("Error converting Redfish Manager to SMC Manager: %s", err)
}

if result.ID != "1" {
t.Errorf("Received invalid ID: %s", result.ID)
}

if result.Name != "Manager" {
t.Errorf("Received invalid name: %s", result.Name)
}

if result.radius != "/redfish/v1/Managers/1/Oem/Supermicro/RADIUS" {
t.Errorf("Invalid RADIUS link: %s", result.radius)
}

if result.mouseMode != "/redfish/v1/Managers/1/Oem/Supermicro/MouseMode" {
t.Errorf("Invalid MouseMode link: %s", result.mouseMode)
}

if result.managerConfigResetTarget != "/redfish/v1/Managers/1/Actions/Oem/SmcManagerConfig.Reset" {
t.Errorf("Invalid ManagerConfigResetTarget link: %s", result.managerConfigResetTarget)
}
}
8 changes: 4 additions & 4 deletions redfish/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,8 @@ type Manager struct {
// SupportedResetTypes, if provided, is the reset types this system supports.
SupportedResetTypes []ResetType
resetToDefaultsTarget string
// rawData holds the original serialized JSON so we can compare updates.
rawData []byte
// RawData holds the original serialized JSON so we can compare updates.
RawData []byte
}

// UnmarshalJSON unmarshals a Manager object from the raw JSON.
Expand Down Expand Up @@ -485,7 +485,7 @@ func (manager *Manager) UnmarshalJSON(b []byte) error {
manager.actionInfo = t.Actions.Reset.ActionInfo

// This is a read/write object, so we need to save the raw object data for later
manager.rawData = b
manager.RawData = b

return nil
}
Expand All @@ -495,7 +495,7 @@ func (manager *Manager) Update() error {
// Get a representation of the object's original state so we can find what
// to update.
original := new(Manager)
err := original.UnmarshalJSON(manager.rawData)
err := original.UnmarshalJSON(manager.RawData)
if err != nil {
return err
}
Expand Down

0 comments on commit ca10211

Please sign in to comment.