-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Supermicro DumpService object (#376)
This adds a DumpService OEM object for Supermicro systems. Signed-off-by: Sean McGinnis <[email protected]>
- Loading branch information
1 parent
4c227db
commit aa597ec
Showing
4 changed files
with
232 additions
and
4 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,123 @@ | ||
// | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
// | ||
|
||
package smc | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
|
||
"github.com/stmcginnis/gofish/common" | ||
) | ||
|
||
// Dump represents a dump from the DumpService. | ||
// NOTE: This is another one where the jsonschema reported by SMC appears to be | ||
// wildly inaccurate. Use with caution. | ||
type Dump struct { | ||
common.Entity | ||
|
||
AttestationFile []string | ||
} | ||
|
||
// GetDump will get a Dump instance from the service. | ||
func GetDump(c common.Client, uri string) (*Dump, error) { | ||
return common.GetObject[Dump](c, uri) | ||
} | ||
|
||
// ListReferencedDumps gets the collection of Dumps from | ||
// a provided reference. | ||
func ListReferencedDumps(c common.Client, uri string) ([]*Dump, error) { | ||
return common.GetCollectionObjects[Dump](c, uri) | ||
} | ||
|
||
// DumpService is the dump service instance associated with the system. | ||
type DumpService struct { | ||
common.Entity | ||
|
||
// Link to a DumpCollection. | ||
dumps string | ||
|
||
createDumpTarget string | ||
deleteAllTarget string | ||
collectTarget string | ||
} | ||
|
||
// UnmarshalJSON unmarshals an DumpService object from the raw JSON. | ||
func (ds *DumpService) UnmarshalJSON(b []byte) error { | ||
type temp DumpService | ||
var t struct { | ||
temp | ||
Dumps common.Link | ||
Actions struct { | ||
CreateDump common.ActionTarget `json:"#SmcDumpService.CreateDump"` | ||
DeleteAll common.ActionTarget `json:"#SmcDumpService.DeleteAll"` | ||
Collect common.ActionTarget `json:"#OemDumpService.Collect"` | ||
} | ||
} | ||
|
||
err := json.Unmarshal(b, &t) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
*ds = DumpService(t.temp) | ||
|
||
ds.dumps = t.Dumps.String() | ||
|
||
ds.createDumpTarget = t.Actions.CreateDump.Target | ||
ds.deleteAllTarget = t.Actions.DeleteAll.Target | ||
ds.collectTarget = t.Actions.Collect.Target | ||
|
||
return nil | ||
} | ||
|
||
// GetDefaultDumpService will get the default DumpService instance from the service. | ||
func GetDefaultDumpService(c common.Client) (*DumpService, error) { | ||
return common.GetObject[DumpService](c, "/redfish/v1/Oem/Supermicro/DumpService/") | ||
} | ||
|
||
// GetDumpService will get a DumpService instance from the service. | ||
func GetDumpService(c common.Client, uri string) (*DumpService, error) { | ||
return common.GetObject[DumpService](c, uri) | ||
} | ||
|
||
// CreateDump creates a new dump. Allowable dumpType is usually only | ||
// "Host Dump". | ||
func (ds *DumpService) CreateDump(dumpType string) error { | ||
if ds.createDumpTarget == "" { | ||
return errors.New("create dump is not supported by this system") | ||
} | ||
|
||
return ds.Post(ds.createDumpTarget, map[string]any{ | ||
"DumpType": dumpType, | ||
}) | ||
} | ||
|
||
// DeleteAll deletes all dumps. | ||
func (ds *DumpService) DeleteAll() error { | ||
if ds.deleteAllTarget == "" { | ||
return errors.New("delete all is not supported by this system") | ||
} | ||
|
||
return ds.Post(ds.deleteAllTarget, nil) | ||
} | ||
|
||
// Collect collects a dump. | ||
// dumptType is usually only "HGXLogDump". | ||
// actionType is usually one of "Create", "Delete", "Download", or "Query". | ||
func (ds *DumpService) Collect(dumpType, actionType string) error { | ||
if ds.collectTarget == "" { | ||
return errors.New("collect is not supported by this system") | ||
} | ||
|
||
return ds.Post(ds.collectTarget, map[string]any{ | ||
"DumpType": dumpType, | ||
"ActionType": actionType, | ||
}) | ||
} | ||
|
||
// Dumps will get the Dumps from the service. | ||
func (ds *DumpService) Dumps() ([]*Dump, error) { | ||
return ListReferencedDumps(ds.GetClient(), ds.dumps) | ||
} |
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,105 @@ | ||
// | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
// | ||
|
||
package smc | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
) | ||
|
||
var dumpServiceBody = `{ | ||
"@odata.type": "#DumpService.v1_0_2.DumpService", | ||
"@odata.id": "/redfish/v1/Oem/Supermicro/DumpService", | ||
"Id": "DumpService", | ||
"Name": "Dump Service", | ||
"Description": "Dump Service", | ||
"Dumps": { | ||
"@odata.id": "/redfish/v1/Oem/Supermicro/DumpService/Dumps" | ||
}, | ||
"Actions": { | ||
"Oem": {}, | ||
"#SmcDumpService.CreateDump": { | ||
"target": "/redfish/v1/Oem/Supermicro/DumpService/Actions/SmcDumpService.CreateDump", | ||
"@Redfish.ActionInfo": "/redfish/v1/Oem/Supermicro/DumpService/CreateDumpActionInfo" | ||
}, | ||
"#SmcDumpService.DeleteAll": { | ||
"target": "/redfish/v1/Oem/Supermicro/DumpService/Actions/SmcDumpService.DeleteAll" | ||
}, | ||
"#OemDumpService.Collect": { | ||
"target": "/redfish/v1/Oem/Supermicro/DumpService/Actions/OemDumpService.Collect", | ||
"@Redfish.ActionInfo": "/redfish/v1/Oem/Supermicro/DumpService/CollectActionInfo" | ||
} | ||
}, | ||
"@odata.etag": "\"697e2b05b6d5d49940bc0fd68803608b\"" | ||
}` | ||
|
||
var dumpBody = `{ | ||
"@odata.type": "#Dump.v1_1_0.Dump", | ||
"@odata.id": "/redfish/v1/Oem/Supermicro/DumpService/Dumps/AttestationDump", | ||
"Id": "AttestationDump", | ||
"Name": "AttestationDump", | ||
"Description": "Supermicro Attestation Dump Service", | ||
"AttestationFile": [ | ||
"attd_BS=OM243S046922_2024-09-18T18:10:52-07:00.bin", | ||
"attd_BS=OM243S046922_MB_2024-05-23T13:54:08+08:00.bin" | ||
], | ||
"Actions": { | ||
"Oem": {}, | ||
"#SmcAttestationDump.Generate": { | ||
"target": "/redfish/v1/Oem/Supermicro/DumpService/Dumps/AttestationDump/Actions/SmcAttestationDump.Generate" | ||
}, | ||
"#SmcAttestationDump.Download": { | ||
"target": "/redfish/v1/Oem/Supermicro/DumpService/Dumps/AttestationDump/Actions/SmcAttestationDump.Download" | ||
}, | ||
"#SmcAttestationDump.Delete": { | ||
"target": "/redfish/v1/Oem/Supermicro/DumpService/Dumps/AttestationDump/Actions/SmcAttestationDump.Delete" | ||
} | ||
}, | ||
"@odata.etag": "\"0e25db1a4c2d3d4a28cda306e1b29abe\"" | ||
}` | ||
|
||
// TestSmcDumpService tests the parsing of the DumpService oem field | ||
func TestSmcDumpService(t *testing.T) { | ||
ds := &DumpService{} | ||
if err := json.Unmarshal([]byte(dumpServiceBody), ds); err != nil { | ||
t.Fatalf("error decoding json: %v", err) | ||
} | ||
|
||
if ds.ID != "DumpService" { | ||
t.Errorf("unexpected ID: %s", ds.ID) | ||
} | ||
|
||
if ds.collectTarget != "/redfish/v1/Oem/Supermicro/DumpService/Actions/OemDumpService.Collect" { | ||
t.Errorf("unexpected install target: %s", ds.collectTarget) | ||
} | ||
|
||
if ds.createDumpTarget != "/redfish/v1/Oem/Supermicro/DumpService/Actions/SmcDumpService.CreateDump" { | ||
t.Errorf("unexpected ssl cert link: %s", ds.createDumpTarget) | ||
} | ||
|
||
if ds.deleteAllTarget != "/redfish/v1/Oem/Supermicro/DumpService/Actions/SmcDumpService.DeleteAll" { | ||
t.Errorf("unexpected ipmi config link: %s", ds.deleteAllTarget) | ||
} | ||
|
||
if ds.dumps != "/redfish/v1/Oem/Supermicro/DumpService/Dumps" { | ||
t.Errorf("unexpected dumps link: %s", ds.dumps) | ||
} | ||
} | ||
|
||
// TestSmcDump tests the parsing of the Dumpobject. | ||
func TestSmcDump(t *testing.T) { | ||
ds := &Dump{} | ||
if err := json.Unmarshal([]byte(dumpBody), ds); err != nil { | ||
t.Fatalf("error decoding json: %v", err) | ||
} | ||
|
||
if ds.ID != "AttestationDump" { | ||
t.Errorf("unexpected ID: %s", ds.ID) | ||
} | ||
|
||
if len(ds.AttestationFile) != 2 { | ||
t.Errorf("unexpected number of attestation files: %d", len(ds.AttestationFile)) | ||
} | ||
} |
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
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