Skip to content

Commit

Permalink
Fix Storage linked collections
Browse files Browse the repository at this point in the history
A few more things that are actually single links to a collection, rather
than a collection of links.

Signed-off-by: Sean McGinnis <[email protected]>
  • Loading branch information
stmcginnis committed May 9, 2024
1 parent 145db18 commit 1b25a61
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 128 deletions.
149 changes: 23 additions & 126 deletions redfish/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ type Storage struct {
AutoVolumeCreate AutoVolumeCreate
// Connections shall contain a link to a resource collection of type ConnectionCollection. The members of this
// collection shall reference Connection resources subordinate to Fabric resources.
connections []string
connections string
// ConsistencyGroups shall contain a link to a resource collection of type ConsistencyGroupCollection. The property
// shall be used when groups of volumes are treated as a single resource by an application or set of applications.
consistencyGroups []string
consistencyGroups string
// Controllers shall contain a link to a resource collection of type StorageControllerCollection that contains the
// set of storage controllers allocated to this storage subsystem.
controllers []string
controllers string
// Description provides a description of this resource.
Description string
// Drives is a collection that indicates all the drives attached to the
Expand All @@ -117,10 +117,10 @@ type Storage struct {
EncryptionMode EncryptionMode
// EndpointGroups shall contain a link to a resource collection of type EndpointGroupCollection. This property
// shall be implemented when atomic control is needed to perform mapping, masking, and zoning operations.
endpointGroups []string
endpointGroups string
// FileSystems shall contain a link to a resource collection of type FileSystemCollection. This property shall be
// used when file systems are shared or exported by the storage subsystem.
fileSystems []string
fileSystems string
// HotspareActivationPolicy shall contain the policy under which all drives operating as hot spares in this storage
// domain will activate.
HotspareActivationPolicy HotspareActivationPolicy
Expand All @@ -147,7 +147,7 @@ type Storage struct {
// StoragePools shall contain a link to a resource collection of type StoragePoolCollection. This property shall be
// used when an abstraction of media, rather than references to individual media, are used as the storage data
// source.
storagePools []string
storagePools string
// Volumes is a collection that indicates all the volumes produced by the
// storage controllers that this resource represents.
volumes string
Expand Down Expand Up @@ -205,13 +205,13 @@ func (storage *Storage) UnmarshalJSON(b []byte) error {
var t struct {
temp
Links links
Connections common.Links
ConsistencyGroups common.Links
Controllers common.Links
Connections common.Link
ConsistencyGroups common.Link
Controllers common.Link
Drives common.Links
EndpointGroups common.Links
FileSystems common.Links
StoragePools common.Links
EndpointGroups common.Link
FileSystems common.Link
StoragePools common.Link
Volumes common.Link
Actions actions
}
Expand All @@ -224,13 +224,13 @@ func (storage *Storage) UnmarshalJSON(b []byte) error {
*storage = Storage(t.temp)

// Extract the links to other entities for later
storage.connections = t.Connections.ToStrings()
storage.consistencyGroups = t.ConsistencyGroups.ToStrings()
storage.controllers = t.Controllers.ToStrings()
storage.connections = t.Connections.String()
storage.consistencyGroups = t.ConsistencyGroups.String()
storage.controllers = t.Controllers.String()
storage.drives = t.Drives.ToStrings()
storage.endpointGroups = t.EndpointGroups.ToStrings()
storage.fileSystems = t.FileSystems.ToStrings()
storage.storagePools = t.StoragePools.ToStrings()
storage.endpointGroups = t.EndpointGroups.String()
storage.fileSystems = t.FileSystems.String()
storage.storagePools = t.StoragePools.String()
storage.volumes = t.Volumes.String()

storage.enclosures = t.Links.Enclosures.ToStrings()
Expand All @@ -254,66 +254,18 @@ func (storage *Storage) UnmarshalJSON(b []byte) error {

// Connection gets the connections that this storage subsystem contains.
func (storage *Storage) Connections() ([]*Connection, error) {
var result []*Connection

collectionError := common.NewCollectionError()
for _, uri := range storage.connections {
item, err := GetConnection(storage.GetClient(), uri)
if err != nil {
collectionError.Failures[uri] = err
} else {
result = append(result, item)
}
}

if collectionError.Empty() {
return result, nil
}

return result, collectionError
return ListReferencedConnections(storage.GetClient(), storage.connections)
}

// ConsistencyGroups gets groups of volumes that are treated as a single resource
// by an application or set of applications.
// func (storage *Storage) ConsistencyGroups() ([]*swordfish.ConsistencyGroup, error) {
// var result []*swordfish.ConsistencyGroup

// collectionError := common.NewCollectionError()
// for _, uri := range storage.consistencyGroups {
// item, err := swordfish.GetConsistencyGroup(storage.GetClient(), uri)
// if err != nil {
// collectionError.Failures[uri] = err
// } else {
// result = append(result, item)
// }
// }

// if collectionError.Empty() {
// return result, nil
// }

// return result, collectionError
// return swordfishListReferencedConsistencyGroups(storage.GetClient(), storage.consistencyGroups)
// }

// Controllers gets the set of storage controllers allocated to this storage subsystem.
func (storage *Storage) Controllers() ([]*StorageController, error) {
var result []*StorageController

collectionError := common.NewCollectionError()
for _, uri := range storage.controllers {
item, err := GetStorageController(storage.GetClient(), uri)
if err != nil {
collectionError.Failures[uri] = err
} else {
result = append(result, item)
}
}

if collectionError.Empty() {
return result, nil
}

return result, collectionError
return ListReferencedStorageControllers(storage.GetClient(), storage.controllers)
}

// Drives gets the drives attached to the storage controllers that this
Expand Down Expand Up @@ -341,67 +293,12 @@ func (storage *Storage) Drives() ([]*Drive, error) {
// EndpointGroups gets the set of endpoints that are used for a common purpose such as an ACL
// or logical identification, that belong to this storage subsystem.
func (storage *Storage) EndpointGroups() ([]*EndpointGroup, error) {
var result []*EndpointGroup

collectionError := common.NewCollectionError()
for _, uri := range storage.endpointGroups {
item, err := GetEndpointGroup(storage.GetClient(), uri)
if err != nil {
collectionError.Failures[uri] = err
} else {
result = append(result, item)
}
}

if collectionError.Empty() {
return result, nil
}

return result, collectionError
return ListReferencedEndpointGroups(storage.GetClient(), storage.endpointGroups)
}

// FileSystems gets the file systems that are allocated by this storage subsystem.
// func (storage *Storage) FileSystems() ([]*swordfish.FileSystem, error) {
// var result []*swordfish.FileSystem

// collectionError := common.NewCollectionError()
// for _, uri := range storage.fileSystems {
// item, err := swordfish.GetFileSystem(storage.GetClient(), uri)
// if err != nil {
// collectionError.Failures[uri] = err
// } else {
// result = append(result, item)
// }
// }

// if collectionError.Empty() {
// return result, nil
// }

// return result, collectionError
// }

// StoragePools gets the storage pools that are allocated by this storage subsystem.
// A storage pool is the set of storage capacity that can be used to produce volumes
// or other storage pools.
// func (storage *Storage) StoragePools() ([]*swordfish.StoragePool, error) {
// var result []*swordfish.StoragePool

// collectionError := common.NewCollectionError()
// for _, uri := range storage.storagePools {
// item, err := swordfish.GetStoragePool(storage.GetClient(), uri)
// if err != nil {
// collectionError.Failures[uri] = err
// } else {
// result = append(result, item)
// }
// }

// if collectionError.Empty() {
// return result, nil
// }

// return result, collectionError
// return swordfish.ListReferencedFileSystems(storage.GetClient(), storage.fileSystems)
// }

// Volumes gets the volumes associated with this storage subsystem.
Expand Down
154 changes: 154 additions & 0 deletions redfish/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,151 @@ var storageBody = `{
}
}`

var storageBodyDell = `{
"@odata.context": "/redfish/v1/$metadata#Storage.Storage",
"@odata.id": "/redfish/v1/Systems/System.Embedded.1/Storage/AHCI.Embedded.1-1",
"@odata.type": "#Storage.v1_15_0.Storage",
"Controllers": {
"@odata.id": "/redfish/v1/Systems/System.Embedded.1/Storage/AHCI.Embedded.1-1/Controllers"
},
"Description": "Embedded AHCI 1",
"Drives": [],
"[email protected]": 0,
"Id": "AHCI.Embedded.1-1",
"Identifiers": [
{
"DurableName": null,
"DurableNameFormat": null
}
],
"[email protected]": 1,
"Links": {
"Enclosures": [
{
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1"
}
],
"[email protected]": 1,
"Oem": {
"Dell": {
"@odata.type": "#DellOem.v1_3_0.DellOemLinks",
"CPUAffinity": [],
"[email protected]": 0
}
},
"SimpleStorage": {
"@odata.id": "/redfish/v1/Systems/System.Embedded.1/SimpleStorage/AHCI.Embedded.1-1"
}
},
"Name": "Sapphire Rapids SATA AHCI Controller",
"Oem": {
"Dell": {
"@odata.type": "#DellOem.v1_3_0.DellOemResources",
"DellController": {
"@odata.context": "/redfish/v1/$metadata#DellController.DellController",
"@odata.id": "/redfish/v1/Systems/System.Embedded.1/Storage/AHCI.Embedded.1-1/Oem/Dell/DellControllers/AHCI.Embedded.1-1",
"@odata.type": "#DellController.v1_4_1.DellController",
"AlarmState": "AlarmNotPresent",
"AutoConfigBehavior": "NotApplicable",
"BootVirtualDiskFQDD": null,
"CacheSizeInMB": 0,
"CachecadeCapability": "NotSupported",
"ConnectorCount": 0,
"ControllerFirmwareVersion": null,
"CurrentControllerMode": "NotSupported",
"Description": "An instance of DellController will have RAID Controller specific data.",
"Device": "0",
"DeviceCardDataBusWidth": "Unknown",
"DeviceCardSlotLength": "Unknown",
"DeviceCardSlotType": "Unknown",
"DriverVersion": null,
"EncryptionCapability": "None",
"EncryptionMode": "None",
"Id": "AHCI.Embedded.1-1",
"KeyID": null,
"LastSystemInventoryTime": "2024-04-10T22:38:06+00:00",
"LastUpdateTime": "2024-02-20T05:22:02+00:00",
"MaxAvailablePCILinkSpeed": null,
"MaxPossiblePCILinkSpeed": null,
"Name": "DellController",
"PCISlot": null,
"PatrolReadState": "Unknown",
"PersistentHotspare": "NotApplicable",
"RealtimeCapability": "Incapable",
"RollupStatus": "Unknown",
"SASAddress": "0",
"SecurityStatus": "EncryptionNotCapable",
"SharedSlotAssignmentAllowed": "NotApplicable",
"SlicedVDCapability": "NotSupported",
"SupportControllerBootMode": "NotSupported",
"SupportEnhancedAutoForeignImport": "NotSupported",
"SupportRAID10UnevenSpans": "NotSupported",
"SupportsLKMtoSEKMTransition": "No",
"T10PICapability": "NotSupported"
}
}
},
"Status": {
"Health": null,
"HealthRollup": null,
"State": "Enabled"
},
"StorageControllers": [
{
"@odata.id": "/redfish/v1/Systems/System.Embedded.1/Storage/AHCI.Embedded.1-1#/StorageControllers/0",
"Assembly": {
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Assembly"
},
"CacheSummary": {
"TotalCacheSizeMiB": 0
},
"ControllerRates": {
"ConsistencyCheckRatePercent": null,
"RebuildRatePercent": null
},
"FirmwareVersion": "",
"Identifiers": [
{
"DurableName": null,
"DurableNameFormat": null
}
],
"[email protected]": 1,
"Links": {
"PCIeFunctions": [
{
"@odata.id": "/redfish/v1/Chassis/System.Embedded.1/PCIeDevices/0-24/PCIeFunctions/0-24-0"
}
],
"[email protected]": 1
},
"Manufacturer": "DELL",
"MemberId": "0",
"Model": "Sapphire Rapids SATA AHCI Controller",
"Name": "Sapphire Rapids SATA AHCI Controller",
"SpeedGbps": null,
"Status": {
"Health": null,
"HealthRollup": null,
"State": "Enabled"
},
"SupportedControllerProtocols": [
"PCIe"
],
"[email protected]": 1,
"SupportedDeviceProtocols": [],
"[email protected]": 0,
"SupportedRAIDTypes": [],
"[email protected]": 0
}
],
"[email protected]": "Please migrate to use /redfish/v1/Systems/System.Embedded.1/Storage/AHCI.Embedded.1-1/Controllers",
"[email protected]": 1,
"Volumes": {
"@odata.id": "/redfish/v1/Systems/System.Embedded.1/Storage/AHCI.Embedded.1-1/Volumes"
}
}`

// TestStorage tests the parsing of Storage objects.
func TestStorage(t *testing.T) {
var result Storage
Expand Down Expand Up @@ -159,6 +304,15 @@ func TestStorage(t *testing.T) {
}
}

func TestStorageDell(t *testing.T) {
var result Storage
err := json.NewDecoder(strings.NewReader(storageBodyDell)).Decode(&result)

if err != nil {
t.Errorf("Error decoding JSON: %s", err)
}
}

// TestStorageControllerUpdate tests the Update call.
func TestStorageControllerUpdate(t *testing.T) {
var result Storage
Expand Down
4 changes: 2 additions & 2 deletions redfish/storagecontrollermetrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ func GetStorageControllerMetrics(c common.Client, uri string) (*StorageControlle
return &storagecontrollermetrics, nil
}

// ListReferencedStorageControllerMetricss gets the collection of StorageControllerMetrics from
// ListReferencedStorageControllerMetrics gets the collection of StorageControllerMetrics from
// a provided reference.
func ListReferencedStorageControllerMetricss(c common.Client, link string) ([]*StorageControllerMetrics, error) {
func ListReferencedStorageControllerMetrics(c common.Client, link string) ([]*StorageControllerMetrics, error) {
var result []*StorageControllerMetrics
if link == "" {
return result, nil
Expand Down

0 comments on commit 1b25a61

Please sign in to comment.