Skip to content

Commit

Permalink
Add drives and volumes to server.status.storages (#163)
Browse files Browse the repository at this point in the history
* adds drives and volumes to Status.Storages

* adds mediaType instead of rotational for drives

* renames internal var

* fixes typo
  • Loading branch information
stefanhipfel authored Nov 5, 2024
1 parent 86abc01 commit 2026e3d
Show file tree
Hide file tree
Showing 8 changed files with 430 additions and 64 deletions.
36 changes: 31 additions & 5 deletions api/v1alpha1/server_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,15 @@ type NetworkInterface struct {
MACAddress string `json:"macAddress"`
}

// Storage defines the details of one storage device
type Storage struct {
// StorageDrive defines the details of one storage drive
type StorageDrive struct {
// Name is the name of the storage interface.
Name string `json:"name,omitempty"`
// Rotational specifies whether the storage device is rotational.
Rotational bool `json:"rotational,omitempty"`
// MediaType specifies the media type of the storage device.
MediaType string `json:"mediaType,omitempty"`
// Type specifies the type of the storage device.
Type string `json:"type,omitempty"`
// SizeBytes specifies the size of the storage device in bytes.
// Capacity specifies the size of the storage device in bytes.
Capacity *resource.Quantity `json:"capacity,omitempty"`
// Vendor specifies the vendor of the storage device.
Vendor string `json:"vendor,omitempty"`
Expand All @@ -228,6 +228,32 @@ type Storage struct {
State StorageState `json:"state,omitempty"`
}

// StorageVolume defines the details of one storage volume
type StorageVolume struct {
// Name is the name of the storage interface.
Name string `json:"name,omitempty"`
// Capacity specifies the size of the storage device in bytes.
Capacity *resource.Quantity `json:"capacity,omitempty"`
// Status specifies the status of the volume.
State StorageState `json:"state,omitempty"`
// RAIDType specifies the RAID type of the associated Volume.
RAIDType string `json:"raidType,omitempty"`
// VolumeUsage specifies the volume usage type for the Volume.
VolumeUsage string `json:"volumeUsage,omitempty"`
}

// Storage defines the details of one storage device
type Storage struct {
// Name is the name of the storage interface.
Name string `json:"name,omitempty"`
// State specifies the state of the storage device.
State StorageState `json:"state,omitempty"`
// Volumes is a collection of volumes associated with this storage.
Volumes []StorageVolume `json:"volumes,omitempty"`
// Drives is a collection of drives associated with this storage.
Drives []StorageDrive `json:"drives,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:scope=Cluster
Expand Down
55 changes: 52 additions & 3 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 36 additions & 5 deletions bmc/bmc.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ type BMC interface {
GetStorages(systemUUID string) ([]Storage, error)
}

type Entity struct {
// ID uniquely identifies the resource.
ID string `json:"Id"`
// Name is the name of the resource or array element.
Name string `json:"name"`
}

type Bios struct {
Version string
Attributes map[string]string
Expand Down Expand Up @@ -107,11 +114,24 @@ type Server struct {
SerialNumber string
}

type Storage struct {
// Name is the name of the storage interface.
Name string `json:"name,omitempty"`
// Rotational specifies whether the storage device is rotational.
Rotational bool `json:"rotational,omitempty"`
// Volume represents a storage volume.
type Volume struct {
Entity
// CapacityBytes specifies the capacity of the volume in bytes.
SizeBytes int64 `json:"sizeBytes,omitempty"`
// Status specifies the status of the volume.
State common.State `json:"state,omitempty"`
// RAIDType specifies the RAID type of the associated Volume.
RAIDType redfish.RAIDType `json:"raidType,omitempty"`
// VolumeUsage specifies the volume usage type for the Volume.
VolumeUsage string `json:"volumeUsage,omitempty"`
}

// Drive represents a storage drive.
type Drive struct {
Entity
// MediaType specifies the media type of the storage device.
MediaType string `json:"mediaType,omitempty"`
// Type specifies the type of the storage device.
Type redfish.FormFactor `json:"type,omitempty"`
// SizeBytes specifies the size of the storage device in bytes.
Expand All @@ -124,6 +144,17 @@ type Storage struct {
State common.State `json:"state,omitempty"`
}

// Storage represents a storage resource.
type Storage struct {
Entity
// State specifies the state of the storage.
State common.State `json:"state,omitempty"`
// Drives is a collection of drives associated with this storage.
Drives []Drive `json:"drives,omitempty"`
// Volumes is a collection of volumes associated with this storage.
Volumes []Volume `json:"volumes,omitempty"`
}

// PowerState is the power state of the system.
type PowerState string

Expand Down
44 changes: 34 additions & 10 deletions bmc/redfish.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,21 +353,39 @@ func (r *RedfishBMC) GetStorages(systemUUID string) ([]Storage, error) {
}
result := make([]Storage, 0, len(systemStorage))
for _, s := range systemStorage {
storage := Storage{
Entity: Entity{ID: s.ID, Name: s.Name},
}
volumes, err := s.Volumes()
if err != nil {
return nil, err
}
storage.Volumes = make([]Volume, 0, len(volumes))
for _, v := range volumes {
storage.Volumes = append(storage.Volumes, Volume{
Entity: Entity{ID: v.ID, Name: v.Name},
SizeBytes: int64(v.CapacityBytes),
RAIDType: v.RAIDType,
State: v.Status.State,
})
}
drives, err := s.Drives()
if err != nil {
return nil, err
}
storage.Drives = make([]Drive, 0, len(drives))
for _, d := range drives {
result = append(result, Storage{
Name: d.Name,
Rotational: d.RotationSpeedRPM != 0,
Type: d.DriveFormFactor,
SizeBytes: d.CapacityBytes,
Vendor: d.Manufacturer,
Model: d.Model,
State: d.Status.State,
storage.Drives = append(storage.Drives, Drive{
Entity: Entity{ID: d.ID, Name: d.Name},
MediaType: string(d.MediaType),
Type: d.DriveFormFactor,
SizeBytes: d.CapacityBytes,
Vendor: d.Manufacturer,
Model: d.Model,
State: d.Status.State,
})
}
result = append(result, storage)
}
if len(result) == 0 {
// if no storage is found, fall back to simpleStorage (outdated storage API)
Expand All @@ -377,15 +395,21 @@ func (r *RedfishBMC) GetStorages(systemUUID string) ([]Storage, error) {
return nil, err
}
for _, s := range simpleStorages {
storage := Storage{
Entity: Entity{ID: s.ID, Name: s.Name},
}

storage.Drives = make([]Drive, 0, len(s.Devices))
for _, d := range s.Devices {
result = append(result, Storage{
Name: d.Name,
storage.Drives = append(storage.Drives, Drive{
Entity: Entity{Name: d.Name},
SizeBytes: d.CapacityBytes,
Vendor: d.Manufacturer,
Model: d.Model,
State: d.Status.State,
})
}
result = append(result, storage)
}
return result, nil
}
Expand Down
91 changes: 70 additions & 21 deletions config/crd/bases/metal.ironcore.dev_servers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -405,33 +405,82 @@ spec:
items:
description: Storage defines the details of one storage device
properties:
capacity:
anyOf:
- type: integer
- type: string
description: SizeBytes specifies the size of the storage device
in bytes.
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
model:
description: Model specifies the model of the storage device.
type: string
drives:
description: Drives is a collection of drives associated with
this storage.
items:
description: StorageDrive defines the details of one storage
drive
properties:
capacity:
anyOf:
- type: integer
- type: string
description: Capacity specifies the size of the storage
device in bytes.
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
mediaType:
description: MediaType specifies the media type of the
storage device.
type: string
model:
description: Model specifies the model of the storage
device.
type: string
name:
description: Name is the name of the storage interface.
type: string
state:
description: State specifies the state of the storage
device.
type: string
type:
description: Type specifies the type of the storage device.
type: string
vendor:
description: Vendor specifies the vendor of the storage
device.
type: string
type: object
type: array
name:
description: Name is the name of the storage interface.
type: string
rotational:
description: Rotational specifies whether the storage device
is rotational.
type: boolean
state:
description: State specifies the state of the storage device.
type: string
type:
description: Type specifies the type of the storage device.
type: string
vendor:
description: Vendor specifies the vendor of the storage device.
type: string
volumes:
description: Volumes is a collection of volumes associated with
this storage.
items:
description: StorageVolume defines the details of one storage
volume
properties:
capacity:
anyOf:
- type: integer
- type: string
description: Capacity specifies the size of the storage
device in bytes.
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
name:
description: Name is the name of the storage interface.
type: string
raidType:
description: RAIDType specifies the RAID type of the associated
Volume.
type: string
state:
description: Status specifies the status of the volume.
type: string
volumeUsage:
description: VolumeUsage specifies the volume usage type
for the Volume.
type: string
type: object
type: array
type: object
type: array
type: object
Expand Down
Loading

0 comments on commit 2026e3d

Please sign in to comment.