diff --git a/bmc/bmc.go b/bmc/bmc.go index e9592a9..fa6c8e5 100644 --- a/bmc/bmc.go +++ b/bmc/bmc.go @@ -17,7 +17,7 @@ type BMC interface { PowerOff(systemUUID string) error // Reset performs a reset on the system. - Reset() error + Reset(systemUUID string, resetType redfish.ResetType) error // SetPXEBootOnce sets the boot device for the next system boot. SetPXEBootOnce(systemUUID string) error diff --git a/bmc/redfish.go b/bmc/redfish.go index 2edf848..cf10dca 100644 --- a/bmc/redfish.go +++ b/bmc/redfish.go @@ -87,8 +87,14 @@ func (r *RedfishBMC) PowerOff(systemUUID string) error { } // Reset performs a reset on the system using Redfish. -func (r *RedfishBMC) Reset() error { - // Implementation details... +func (r *RedfishBMC) Reset(systemUUID string, resetType redfish.ResetType) error { + system, err := r.getSystemByUUID(systemUUID) + if err != nil { + return fmt.Errorf("failed to get systems: %w", err) + } + if err := system.Reset(resetType); err != nil { + return fmt.Errorf("failed to reset system: %w", err) + } return nil } diff --git a/internal/controller/server_controller.go b/internal/controller/server_controller.go index 2e1d870..22a7d9b 100644 --- a/internal/controller/server_controller.go +++ b/internal/controller/server_controller.go @@ -17,6 +17,7 @@ import ( metalv1alpha1 "github.com/ironcore-dev/metal-operator/api/v1alpha1" "github.com/ironcore-dev/metal-operator/internal/api/registry" "github.com/ironcore-dev/metal-operator/internal/ignition" + "github.com/stmcginnis/gofish/redfish" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" meta "k8s.io/apimachinery/pkg/api/meta" @@ -125,6 +126,10 @@ func (r *ServerReconciler) reconcile(ctx context.Context, log logr.Logger, serve return ctrl.Result{}, err } } + if modified, err := r.handleAnnotionOperations(ctx, log, server); err != nil || modified { + return ctrl.Result{}, err + } + log.V(1).Info("Handled annotation operations") if modified, err := clientutils.PatchEnsureFinalizer(ctx, r.Client, server, ServerFinalizer); err != nil || modified { return ctrl.Result{}, err @@ -812,6 +817,31 @@ func (r *ServerReconciler) applyBiosSettings(ctx context.Context, log logr.Logge return nil } +func (r *ServerReconciler) handleAnnotionOperations(ctx context.Context, log logr.Logger, server *metalv1alpha1.Server) (bool, error) { + annotations := server.GetAnnotations() + operation, ok := annotations[metalv1alpha1.OperationAnnotation] + if !ok { + return false, nil + } + bmcClient, err := GetBMCClientForServer(ctx, r.Client, server, r.Insecure) + if err != nil { + return false, fmt.Errorf("failed to create BMC client: %w", err) + } + defer bmcClient.Logout() + log.V(1).Info("Handling operation", "Operation", operation) + if err := bmcClient.Reset(server.Spec.UUID, redfish.ResetType(operation)); err != nil { + return false, fmt.Errorf("failed to reset server: %w", err) + } + log.V(1).Info("Operation completed", "Operation", operation) + serverBase := server.DeepCopy() + delete(annotations, metalv1alpha1.OperationAnnotation) + server.SetAnnotations(annotations) + if err := r.Patch(ctx, server, client.MergeFrom(serverBase)); err != nil { + return false, fmt.Errorf("failed to patch server annotations: %w", err) + } + return true, nil +} + // SetupWithManager sets up the controller with the Manager. func (r *ServerReconciler) SetupWithManager(mgr ctrl.Manager) error { // Create a channel to send periodic events