Skip to content

Commit

Permalink
migrate addons to controller-runtime
Browse files Browse the repository at this point in the history
This commit merges token exchange addon and maintenance addon into a
single operator and migrates it to controller-runtime. This operator is
now considered a single addon and is deployed as such.

Due to this change reconciles are now driven via events and watches as
opposed to the previous periodic resync approach. These events are handled
much more efficiently and will provide better resource utilization and
faster event handling.

Signed-off-by: Umanga Chapagain <chapagainumanga@gmail.com>
  • Loading branch information
umangachapagain committed Feb 22, 2024
1 parent 3675a7b commit 7ba19be
Show file tree
Hide file tree
Showing 47 changed files with 623 additions and 1,954 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,6 @@ type MirrorPeerReconciler struct {
SpokeClusterName string
}

const (
RookCSIEnableKey = "CSI_ENABLE_OMAP_GENERATOR"
RookConfigMapName = "rook-ceph-operator-config"
RBDProvisionerTemplate = "%s.rbd.csi.ceph.com"
RamenLabelTemplate = "ramendr.openshift.io/%s"
StorageIDKey = "storageid"
CephFSProvisionerTemplate = "%s.cephfs.csi.ceph.com"
SpokeMirrorPeerFinalizer = "spoke.multicluster.odf.openshift.io"
)

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
//
Expand Down
File renamed without changes.
77 changes: 77 additions & 0 deletions addons/blue_secret_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package addons

import (
"context"

ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/source"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog/v2"
)

// BlueSecretReconciler reconciles a MirrorPeer object
type BlueSecretReconciler struct {
Scheme *runtime.Scheme
HubClient client.Client
SpokeClient client.Client
SpokeClusterName string
}

// SetupWithManager sets up the controller with the Manager.
func (r *BlueSecretReconciler) SetupWithManager(mgr ctrl.Manager) error {
isBlueSecret := func(obj interface{}) bool {
return getBlueSecretFilterForRook(obj)
}

blueSecretPredicate := predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
return isBlueSecret(e.Object)
},
DeleteFunc: func(e event.DeleteEvent) bool {
return isBlueSecret(e.Object)
},
UpdateFunc: func(e event.UpdateEvent) bool {
return isBlueSecret(e.ObjectNew)
},
GenericFunc: func(_ event.GenericEvent) bool {
return false
},
}

return ctrl.NewControllerManagedBy(mgr).
Named("bluesecret_controller").
Watches(&source.Kind{Type: &corev1.Secret{}}, &handler.EnqueueRequestForObject{},
builder.WithPredicates(predicate.GenerationChangedPredicate{}, blueSecretPredicate)).
Complete(r)
}

func (r *BlueSecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var err error
var secret corev1.Secret

klog.Infof("Reconciling blue secret", "secret", req.NamespacedName.String())
err = r.SpokeClient.Get(ctx, req.NamespacedName, &secret)
if err != nil {
if errors.IsNotFound(err) {
klog.Infof("Could not find secret. Ignoring since it must have been deleted")
return ctrl.Result{}, nil
}
klog.Errorf("Failed to get secret.", err)
return ctrl.Result{}, err
}

err = r.syncBlueSecretForRook(ctx, secret)
if err != nil {
return ctrl.Result{}, err
}

return ctrl.Result{}, nil
}
1 change: 1 addition & 0 deletions addons/blue_secret_controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package addons
13 changes: 13 additions & 0 deletions addons/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package addons

const (
RBDProvisionerTemplate = "%s.rbd.csi.ceph.com"
MaintenanceModeFinalizer = "maintenance.multicluster.odf.openshift.io"
RBDMirrorDeploymentNamePrefix = "rook-ceph-rbd-mirror"
RookCSIEnableKey = "CSI_ENABLE_OMAP_GENERATOR"
RookConfigMapName = "rook-ceph-operator-config"
RamenLabelTemplate = "ramendr.openshift.io/%s"
StorageIDKey = "storageid"
CephFSProvisionerTemplate = "%s.cephfs.csi.ceph.com"
SpokeMirrorPeerFinalizer = "spoke.multicluster.odf.openshift.io"
)
87 changes: 87 additions & 0 deletions addons/green_secret_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package addons

import (
"context"
"fmt"

"github.com/red-hat-storage/odf-multicluster-orchestrator/controllers/utils"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog/v2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/source"
)

// GreenSecretReconciler reconciles a MirrorPeer object
type GreenSecretReconciler struct {
Scheme *runtime.Scheme
HubClient client.Client
SpokeClient client.Client
SpokeClusterName string
}

// SetupWithManager sets up the controller with the Manager.
func (r *GreenSecretReconciler) SetupWithManager(mgr ctrl.Manager) error {
isGreenSecret := func(obj interface{}) bool {
metaObj, has := obj.(metav1.Object)
if has {
return metaObj.GetLabels()[utils.SecretLabelTypeKey] == string(utils.DestinationLabel)
}
return false
}

greenSecretPredicate := predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
return isGreenSecret(e.Object)
},
DeleteFunc: func(e event.DeleteEvent) bool {
return isGreenSecret(e.Object)
},
UpdateFunc: func(e event.UpdateEvent) bool {
return isGreenSecret(e.ObjectNew)
},
GenericFunc: func(_ event.GenericEvent) bool {
return false
},
}

return ctrl.NewControllerManagedBy(mgr).
Named("greensecret_controller").
Watches(&source.Kind{Type: &corev1.Secret{}}, &handler.EnqueueRequestForObject{},
builder.WithPredicates(predicate.GenerationChangedPredicate{}, greenSecretPredicate)).
Complete(r)
}

func (r *GreenSecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var err error
var greenSecret corev1.Secret

klog.Infof("Reconciling green secret", "secret", req.NamespacedName.String())
err = r.HubClient.Get(ctx, req.NamespacedName, &greenSecret)
if err != nil {
if errors.IsNotFound(err) {
klog.Infof("Could not find secret. Ignoring since it must have been deleted")
return ctrl.Result{}, nil
}
klog.Errorf("Failed to get secret.", err)
return ctrl.Result{}, err
}

if err = validateGreenSecret(greenSecret); err != nil {
return ctrl.Result{}, fmt.Errorf("failed to validate secret %q", greenSecret.Name)
}

err = r.syncGreenSecretForRook(ctx, greenSecret)
if err != nil {
return ctrl.Result{}, err
}

return ctrl.Result{}, nil
}
1 change: 1 addition & 0 deletions addons/green_secret_controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package addons
75 changes: 0 additions & 75 deletions addons/maintainence-agent/maintainence_mode_agent.go

This file was deleted.

80 changes: 0 additions & 80 deletions addons/maintainence-agent/manager.go

This file was deleted.

Loading

0 comments on commit 7ba19be

Please sign in to comment.