Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BaseboardManagement controller to readonly #10

Merged
merged 2 commits into from
Jun 6, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
41 changes: 0 additions & 41 deletions api/v1alpha1/baseboardmanagement_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,11 @@ const (
ConditionFalse ConditionStatus = "False"
)

// PausedAnnotation is an annotation that can be applied to BaseboardManagement
// object to prevent a controller from processing a resource.
const PausedAnnotation = "bmc.tinkerbell.org/paused"

// BaseboardManagementSpec defines the desired state of BaseboardManagement
type BaseboardManagementSpec struct {

// Connection represents the BaseboardManagement connectivity information.
Connection Connection `json:"connection"`

// Power is the desired power state of the BaseboardManagement.
// +kubebuilder:validation:Enum=on;off
Power PowerState `json:"power"`
}

type Connection struct {
Expand Down Expand Up @@ -157,39 +149,6 @@ func WithBaseboardManagementConditionMessage(m string) BaseboardManagementSetCon
}
}

// PauseReconcile adds the pausedAnnotation to the BaseboardManagement object.
func (bm *BaseboardManagement) PauseReconcile() {
if bm.Annotations == nil {
bm.initAnnotations()
}
bm.Annotations[PausedAnnotation] = "true"
}

// ClearPauseAnnotation deletes the pausedAnnotation from the BaseboardManagement object.
func (bm *BaseboardManagement) ClearPauseAnnotation() {
if bm.Annotations != nil {
delete(bm.Annotations, PausedAnnotation)
}
}

// IsReconcilePaused checks if the pausedAnnotation is present on the BaseboardManagement object.
func (bm *BaseboardManagement) IsReconcilePaused() bool {
if bm.Annotations == nil {
return false
}

if s, ok := bm.Annotations[PausedAnnotation]; ok {
return s == "true"
}

return false
}

// initAnnotations initalizes the BaseboardManagement metadata annotations.
func (bm *BaseboardManagement) initAnnotations() {
bm.Annotations = map[string]string{}
}

// BaseboardManagementRef defines the reference information to a BaseboardManagement resource.
type BaseboardManagementRef struct {
// Name is unique within a namespace to reference a BaseboardManagement resource.
Expand Down
7 changes: 0 additions & 7 deletions config/crd/bases/bmc.tinkerbell.org_baseboardmanagements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,8 @@ spec:
- insecureTLS
- port
type: object
power:
description: Power is the desired power state of the BaseboardManagement.
enum:
- "on"
- "off"
type: string
required:
- connection
- power
type: object
status:
description: BaseboardManagementStatus defines the observed state of BaseboardManagement
Expand Down
25 changes: 2 additions & 23 deletions controllers/baseboardmanagement_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ type baseboardManagementFieldReconciler func(context.Context, *bmcv1alpha1.Baseb

// Reconcile ensures the state of a BaseboardManagement.
// Gets the BaseboardManagement object and uses the SecretReference to initialize a BMC Client.
// Ensures the BMC power is set to the desired state.
// Updates the status and conditions accordingly.
// Updates the Power status and conditions accordingly.
func (r *BaseboardManagementReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
logger := r.logger.WithValues("BaseboardManagement", req.NamespacedName)
logger.Info("Reconciling BaseboardManagement")
Expand All @@ -103,12 +102,6 @@ func (r *BaseboardManagementReconciler) Reconcile(ctx context.Context, req ctrl.
return ctrl.Result{}, err
}

// If BaseboardManagement is paused, noop.
if baseboardManagement.IsReconcilePaused() {
logger.Info("BaseboardManagement reconciliation is paused")
return ctrl.Result{}, nil
}

// Deletion is a noop.
if !baseboardManagement.DeletionTimestamp.IsZero() {
return ctrl.Result{}, nil
Expand Down Expand Up @@ -182,22 +175,8 @@ func (r *BaseboardManagementReconciler) reconcilePower(ctx context.Context, bm *
return fmt.Errorf("failed to get power state: %v", err)
}

// If BaseboardManagement has desired power state then return
if bm.Spec.Power == bmcv1alpha1.PowerState(strings.ToLower(powerStatus)) {
// Update status to represent current power state
bm.Status.Power = bm.Spec.Power
return nil
}

// Setting baseboard management to desired power state
_, err = bmcClient.SetPowerState(ctx, string(bm.Spec.Power))
if err != nil {
r.recorder.Eventf(bm, corev1.EventTypeWarning, EventSetPowerStateFailed, "failed to set power state: %v", err)
return fmt.Errorf("failed to set power state: %v", err)
}

// Update status to represent current power state
bm.Status.Power = bm.Spec.Power
bm.Status.Power = bmcv1alpha1.PowerState(strings.ToLower(powerStatus))

return nil
}
Expand Down
49 changes: 3 additions & 46 deletions controllers/baseboardmanagement_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,7 @@ import (
"github.com/tinkerbell/rufio/controllers/mocks"
)

func TestReconcileSetPowerSuccess(t *testing.T) {
g := gomega.NewWithT(t)

ctx := context.Background()
ctrl := gomock.NewController(t)
mockBMCClient := mocks.NewMockBMCClient(ctrl)

bm := getBaseboardManagement()
authSecret := getSecret()

objs := []runtime.Object{bm, authSecret}
scheme := runtime.NewScheme()
_ = bmcv1alpha1.AddToScheme(scheme)
_ = corev1.AddToScheme(scheme)

clientBuilder := fake.NewClientBuilder()
client := clientBuilder.WithScheme(scheme).WithRuntimeObjects(objs...).Build()
fakeRecorder := record.NewFakeRecorder(2)

mockBMCClient.EXPECT().GetPowerState(ctx).Return(string(bmcv1alpha1.Off), nil)
mockBMCClient.EXPECT().SetPowerState(ctx, string(bmcv1alpha1.On)).Return(true, nil)
mockBMCClient.EXPECT().Close(ctx).Return(nil)

reconciler := controllers.NewBaseboardManagementReconciler(
client,
fakeRecorder,
newMockBMCClientFactoryFunc(mockBMCClient),
testr.New(t),
)

req := reconcile.Request{
NamespacedName: types.NamespacedName{
Namespace: "test-namespace",
Name: "test-bm",
},
}

_, err := reconciler.Reconcile(ctx, req)
g.Expect(err).ToNot(gomega.HaveOccurred())
}

func TestReconcileDesiredPowerStateSuccess(t *testing.T) {
func TestReconcileGetPowerStateSuccess(t *testing.T) {
g := gomega.NewWithT(t)

ctx := context.Background()
Expand Down Expand Up @@ -207,7 +166,7 @@ func TestReconcileConnectionError(t *testing.T) {
g.Expect(err).To(gomega.HaveOccurred())
}

func TestReconcileSetPowerError(t *testing.T) {
func TestReconcileGetPowerStateError(t *testing.T) {
g := gomega.NewWithT(t)

ctx := context.Background()
Expand All @@ -226,8 +185,7 @@ func TestReconcileSetPowerError(t *testing.T) {
client := clientBuilder.WithScheme(scheme).WithRuntimeObjects(objs...).Build()
fakeRecorder := record.NewFakeRecorder(2)

mockBMCClient.EXPECT().GetPowerState(ctx).Return(string(bmcv1alpha1.Off), nil)
mockBMCClient.EXPECT().SetPowerState(ctx, string(bmcv1alpha1.On)).Return(false, errors.New("this is not allowed"))
mockBMCClient.EXPECT().GetPowerState(ctx).Return(string(bmcv1alpha1.Off), errors.New("this is not allowed"))
mockBMCClient.EXPECT().Close(ctx).Return(nil)

reconciler := controllers.NewBaseboardManagementReconciler(
Expand Down Expand Up @@ -279,7 +237,6 @@ func getBaseboardManagement() *bmcv1alpha1.BaseboardManagement {
},
InsecureTLS: false,
},
Power: bmcv1alpha1.On,
},
}
}
Expand Down