Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,12 @@ resources:
kind: BIOSSettings
path: github.com/ironcore-dev/metal-operator/api/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
domain: ironcore.dev
group: metal
kind: BIOSVersion
path: github.com/ironcore-dev/metal-operator/api/v1alpha1
version: v1alpha1
version: "3"
119 changes: 119 additions & 0 deletions api/v1alpha1/biosversion_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-FileCopyrightText: 2025 SAP SE or an SAP affiliate company and IronCore contributors
// SPDX-License-Identifier: Apache-2.0

package v1alpha1

import (
"github.com/stmcginnis/gofish/common"
"github.com/stmcginnis/gofish/redfish"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type BIOSVersionState string

const (
// BIOSVersionStatePending specifies that the bios upgrade maintenance is waiting
BIOSVersionStatePending BIOSVersionState = "Pending"
// BIOSVersionStateInProgress specifies that upgrading bios is in progress.
BIOSVersionStateInProgress BIOSVersionState = "Processing"
// BIOSVersionStateCompleted specifies that the bios upgrade maintenance has been completed.
BIOSVersionStateCompleted BIOSVersionState = "Completed"
// BIOSVersionStateFailed specifies that the bios upgrade maintenance has failed.
BIOSVersionStateFailed BIOSVersionState = "Failed"
)

type BIOSUpdateType string

const (
// BIOSVersionStatePending specifies that the bios upgrade maintenance is waiting
ForceUpdateBIOS BIOSUpdateType = "ForceUpdate"
NormalUpdateBIOS BIOSUpdateType = "NormalUpdate"
)

// BIOSVersionSpec defines the desired state of BIOSVersion.
type BIOSVersionSpec struct {
// Version contains BIOS version to upgrade to
// +required
Version string `json:"version"`
// An indication of whether the server's upgrade service should bypass vendor update policies
UpdateType BIOSUpdateType `json:"updateType,omitempty"`
// details regarding the image to use to upgrade to given BIOS version
Image ImageSpec `json:"image,omitempty"`

// ServerRef is a reference to a specific server to apply bios upgrade on.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="serverRef is immutable"
ServerRef *corev1.LocalObjectReference `json:"serverRef,omitempty"`

// ServerMaintenancePolicy is maintenance policy to be enforced on the server.
ServerMaintenancePolicy ServerMaintenancePolicy `json:"serverMaintenancePolicy,omitempty"`

// ServerMaintenanceRef is a reference to a ServerMaintenance object that that Controller has requested for the referred server.
ServerMaintenanceRef *corev1.ObjectReference `json:"serverMaintenanceRef,omitempty"`
}

type ImageSpec struct {
// ImageSecretRef is a reference to the Kubernetes Secret (of type SecretTypeBasicAuth) object that contains the credentials
// to access the ImageURI. This secret includes sensitive information such as usernames and passwords.
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"`
// The network protocol that the server's update service uses to retrieve 'ImageURI'
TransferProtocol string `json:"transferProtocol,omitempty"`
// The URI of the software image to update/install."
// +required
URI string `json:"URI,omitempty"`
}

// BIOSVersionStatus defines the observed state of BIOSVersion.
type BIOSVersionStatus struct {
// State represents the current state of the bios configuration task.
State BIOSVersionState `json:"state,omitempty"`

// UpgradeTask contains the state of the Upgrade Task created by the BMC
UpgradeTask *TaskStatus `json:"upgradeTask,omitempty"`
// Conditions represents the latest available observations of the Bios version upgrade state.
// +patchStrategy=merge
// +patchMergeKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
}

type TaskStatus struct {
TaskURI string `json:"taskURI,omitempty"`
State redfish.TaskState `json:"taskState,omitempty"`
Status common.Health `json:"taskStatus,omitempty"`
PercentComplete int `json:"percentageComplete,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster
// +kubebuilder:printcolumn:name="BIOSVersion",type=string,JSONPath=`.spec.version`
// +kubebuilder:printcolumn:name="ForceUpdate",type=string,JSONPath=`.spec.updateType`
// +kubebuilder:printcolumn:name="State",type=string,JSONPath=`.status.state`
// +kubebuilder:printcolumn:name="TaskState",type=string,JSONPath=`.status.upgradeTask.taskState`
// +kubebuilder:printcolumn:name="TaskStatus",type=string,JSONPath=`.status.upgradeTask.taskStatus`
// +kubebuilder:printcolumn:name="TaskProgress",type=integer,JSONPath=`.status.upgradeTask.percentageComplete`
// +kubebuilder:printcolumn:name="ServerRef",type=string,JSONPath=`.spec.serverRef.name`
// +kubebuilder:printcolumn:name="ServerMaintenanceRef",type=string,JSONPath=`.spec.serverMaintenanceRef.name`

// BIOSVersion is the Schema for the biosversions API.
type BIOSVersion struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec BIOSVersionSpec `json:"spec,omitempty"`
Status BIOSVersionStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// BIOSVersionList contains a list of BIOSVersion.
type BIOSVersionList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []BIOSVersion `json:"items"`
}

func init() {
SchemeBuilder.Register(&BIOSVersion{}, &BIOSVersionList{})
}
147 changes: 147 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

58 changes: 58 additions & 0 deletions bmc/bmc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@ package bmc

import (
"context"
"fmt"
"net/http"

"github.com/stmcginnis/gofish"
"github.com/stmcginnis/gofish/common"
"github.com/stmcginnis/gofish/redfish"
"k8s.io/apimachinery/pkg/api/resource"

"github.com/ironcore-dev/metal-operator/bmc/oem"
)

type Manufacturer string

const (
DellServers Manufacturer = "Dell Inc."
LenovoServers Manufacturer = "Lenovo"
HPEServers Manufacturer = "HPE"
)

// BMC defines an interface for interacting with a Baseboard Management Controller.
Expand Down Expand Up @@ -56,6 +69,18 @@ type BMC interface {

GetStorages(ctx context.Context, systemUUID string) ([]Storage, error)

UpgradeBiosVersion(
ctx context.Context,
manufacturer string,
parameters *redfish.SimpleUpdateParameters,
) (string, bool, error)

GetBiosUpgradeTask(
ctx context.Context,
manufacturer string,
taskURI string,
) (*redfish.Task, error)

WaitForServerPowerState(ctx context.Context, systemUUID string, powerState redfish.PowerState) error
}

Expand Down Expand Up @@ -233,3 +258,36 @@ type Manager struct {
State string
MACAddress string
}

type OEMInterface interface {
GetUpdateRequestBody(
parameters *redfish.SimpleUpdateParameters,
) *oem.SimpleUpdateRequestBody
GetUpdateTaskMonitorURI(
response *http.Response,
) (string, error)
GetTaskMonitorDetails(
ctx context.Context,
taskMonitorResponse *http.Response,
) (*redfish.Task, error)
}

func NewOEM(manufacturer string, service *gofish.Service) (OEMInterface, error) {
var oemintf OEMInterface
switch manufacturer {
case string(DellServers):
return &oem.Dell{
Service: service,
}, nil
case string(HPEServers):
return &oem.HPE{
Service: service,
}, nil
case string(LenovoServers):
return &oem.Lenovo{
Service: service,
}, nil
default:
return oemintf, fmt.Errorf("unsupported manufacturer: %v", manufacturer)
}
}
Loading
Loading