Skip to content

Commit

Permalink
Add BMC info to OOBs
Browse files Browse the repository at this point in the history
  • Loading branch information
Gchbg committed May 6, 2024
1 parent 6571fa7 commit 46b238e
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 25 deletions.
24 changes: 23 additions & 1 deletion internal/bmc/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"fmt"
"regexp"
"time"

"github.com/google/uuid"
)

func RegisterFake() {
Expand Down Expand Up @@ -81,7 +83,27 @@ func (b *FakeBMC) DeleteUsers(_ context.Context, _ *regexp.Regexp) error {
}

func (b *FakeBMC) ReadInfo(_ context.Context) (Info, error) {
return Info{}, nil
id, err := uuid.NewRandom()
if err != nil {
return Info{}, fmt.Errorf("cannot generate UUID: %w", err)
}

return Info{
Type: TypeMachine,
Manufacturer: "Fake",
SerialNumber: "0",
FirmwareVersion: "1",
Machines: []Machine{
{
UUID: id.String(),
Manufacturer: "Fake",
SKU: "Fake-0",
SerialNumber: "1",
Power: PowerOn,
LocatorLED: LEDOff,
},
},
}, nil
}

func (b *FakeBMC) SetLocatorLED(_ context.Context, state LED) (LED, error) {
Expand Down
29 changes: 15 additions & 14 deletions internal/bmc/ipmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"time"

"github.com/hashicorp/go-multierror"

"github.com/ironcore-dev/metal/internal/log"
)

Expand Down Expand Up @@ -68,20 +69,20 @@ type IPMIUser struct {

// TODO: ipmi ciphers, should this also be tested?

func outputmap(ml string, mi *map[string]string) {
for _, line := range strings.Split(ml, "\n") {
colon := strings.Index(line, ":")
if colon == -1 {
continue
}
k := strings.TrimSpace(line[:colon])
v := strings.TrimSpace(line[colon+1:])
if k == "" {
continue
}
(*mi)[k] = v
}
}
//func outputmap(ml string, mi *map[string]string) {
// for _, line := range strings.Split(ml, "\n") {
// colon := strings.Index(line, ":")
// if colon == -1 {
// continue
// }
// k := strings.TrimSpace(line[:colon])
// v := strings.TrimSpace(line[colon+1:])
// if k == "" {
// continue
// }
// (*mi)[k] = v
// }
//}

func outputmapspace(ml string, mi *map[string]string) {
for _, line := range strings.Split(ml, "\n") {
Expand Down
2 changes: 1 addition & 1 deletion internal/bmc/redfish.go
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ func (b *RedfishBMC) ReadInfo(ctx context.Context) (Info, error) {
machine.SerialNumber = system.SerialNumber
machine.UUID = strings.ToLower(system.UUID)
if machine.UUID == "" {
return Info{}, fmt.Errorf("System has no UUID")
return Info{}, fmt.Errorf("system has no UUID")
}
info.Machines = append(info.Machines, machine)
}
Expand Down
59 changes: 50 additions & 9 deletions internal/controller/oob_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ const (
OOBSecretSpecMACAddress = ".spec.MACAddress"
// OOBTemporaryNamespaceHack TODO: Remove temporary namespace hack.
OOBTemporaryNamespaceHack = "oob"

OOBErrorBadEndpoint = "BadEndpoint"
OOBErrorBadCredentials = "BadCredentials"
OOBErrorBadEndpoint = "BadEndpoint"
OOBErrorBadCredentials = "BadCredentials"
OOBErrorBadInfo = "BadInfo"
)

func NewOOBReconciler(systemNamespace, ipLabelSelector, macDB string, credsRenewalBeforeExpiry time.Duration, usernamePrefix, temporaryPasswordSecret string) (*OOBReconciler, error) {
Expand Down Expand Up @@ -131,6 +131,7 @@ type access struct {
}

type ctxkOOBHost struct{}
type ctxkBMC struct{}

func (r *OOBReconciler) PreStart(ctx context.Context) error {
return r.ensureTemporaryPassword(ctx)
Expand Down Expand Up @@ -291,6 +292,15 @@ func (r *OOBReconciler) reconcile(ctx context.Context, oob *metalv1alpha1.OOB) (
return ctrl.Result{}, err
}

ctx, advance, err = r.runPhase(ctx, oob, oobRecPhase{
name: "Info",
run: r.processInfo,
errType: OOBErrorBadInfo,
})
if !advance {
return ctrl.Result{}, err
}

ctx, advance, err = r.runPhase(ctx, oob, oobRecPhase{
name: "Ready",
run: r.processReady,
Expand Down Expand Up @@ -696,12 +706,14 @@ func (r *OOBReconciler) processCredentials(ctx context.Context, oob *metalv1alph
WithName(oob.Spec.Protocol.Name).
WithPort(oob.Spec.Protocol.Port)).
WithFlags(oob.Spec.Flags))
applyst, err := metalv1alpha1apply.ExtractOOBStatus(oob, OOBFieldManager)
if err != nil {
return ctx, nil, nil, fmt.Errorf("cannot extract OOB status: %w", err)
if a.Type != "" {
applyst, err := metalv1alpha1apply.ExtractOOBStatus(oob, OOBFieldManager)
if err != nil {
return ctx, nil, nil, fmt.Errorf("cannot extract OOB status: %w", err)
}
status = util.Ensure(applyst.Status).
WithType(metalv1alpha1.OOBType(a.Type))
}
status = util.Ensure(applyst.Status).
WithType(metalv1alpha1.OOBType(a.Type))
}

b, err := bmc.NewBMC(string(oob.Spec.Protocol.Name), oob.Spec.Flags, host, oob.Spec.Protocol.Port, creds, expiration)
Expand Down Expand Up @@ -825,7 +837,36 @@ func (r *OOBReconciler) processCredentials(ctx context.Context, oob *metalv1alph
}
}

return ctx, apply, nil, nil
return context.WithValue(ctx, ctxkBMC{}, b), apply, status, nil
}

func (r *OOBReconciler) processInfo(ctx context.Context, oob *metalv1alpha1.OOB) (context.Context, *metalv1alpha1apply.OOBApplyConfiguration, *metalv1alpha1apply.OOBStatusApplyConfiguration, error) {
b := ctx.Value(ctxkBMC{}).(bmc.BMC)

var status *metalv1alpha1apply.OOBStatusApplyConfiguration

log.Info(ctx, "Reading BMC info")
info, err := b.ReadInfo(ctx)
if err != nil {
return r.setError(ctx, oob, nil, status, OOBErrorBadInfo, fmt.Errorf("cannot read BMC info: %w", err))
}

if oob.Status.Manufacturer != info.Manufacturer ||
oob.Status.SerialNumber != info.SerialNumber ||
oob.Status.FirmwareVersion != info.FirmwareVersion {
log.Debug(ctx, "Setting manufacturer, serial number, and firmware version")
var applyst *metalv1alpha1apply.OOBApplyConfiguration
applyst, err = metalv1alpha1apply.ExtractOOBStatus(oob, OOBFieldManager)
if err != nil {
return ctx, nil, nil, fmt.Errorf("cannot extract OOB status: %w", err)
}
status = util.Ensure(applyst.Status).
WithManufacturer(info.Manufacturer).
WithSerialNumber(info.SerialNumber).
WithFirmwareVersion(info.FirmwareVersion)
}

return ctx, nil, status, nil
}

func (r *OOBReconciler) processReady(ctx context.Context, oob *metalv1alpha1.OOB) (context.Context, *metalv1alpha1apply.OOBApplyConfiguration, *metalv1alpha1apply.OOBStatusApplyConfiguration, error) {
Expand Down

0 comments on commit 46b238e

Please sign in to comment.