reduce code duplication

This commit is contained in:
Luca Burgazzoli 2024-05-18 09:06:38 +02:00
parent 53e52ba39a
commit a9fb58794a
No known key found for this signature in database
GPG Key ID: 238C46A40510C1A9
5 changed files with 118 additions and 100 deletions

View File

@ -20,6 +20,8 @@ import (
"context"
"fmt"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/openshift"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/helm"
@ -50,7 +52,7 @@ func NewReconciler(ctx context.Context, manager ctrlRt.Manager, o helm.Options)
rec := Reconciler{}
rec.l = ctrlRt.Log.WithName("dapr-controlplane-controller")
rec.Client = c
rec.client = c
rec.Scheme = manager.GetScheme()
rec.ClusterType = controller.ClusterTypeVanilla
rec.manager = manager
@ -94,8 +96,7 @@ func NewReconciler(ctx context.Context, manager ctrlRt.Manager, o helm.Options)
// +kubebuilder:rbac:groups=operator.dapr.io,resources=daprinstances/status,verbs=get
type Reconciler struct {
*client.Client
client *client.Client
Scheme *runtime.Scheme
ClusterType controller.ClusterType
actions []Action
@ -106,6 +107,10 @@ type Reconciler struct {
recorder record.EventRecorder
}
func (r *Reconciler) Client() *client.Client {
return r.client
}
func (r *Reconciler) init(ctx context.Context) error {
c := ctrlRt.NewControllerManagedBy(r.manager)
@ -115,7 +120,7 @@ func (r *Reconciler) init(ctx context.Context) error {
)))
for i := range r.actions {
b, err := r.actions[i].Configure(ctx, r.Client, c)
b, err := r.actions[i].Configure(ctx, r.Client(), c)
if err != nil {
//nolint:wrapcheck
return err
@ -124,7 +129,9 @@ func (r *Reconciler) init(ctx context.Context) error {
c = b
}
ct, err := c.Build(r)
objRec := reconcile.AsReconciler[*daprApi.DaprControlPlane](r.manager.GetClient(), r)
ct, err := c.Build(objRec)
if err != nil {
return fmt.Errorf("failure building the application controller for DaprControlPlane resource: %w", err)
}

View File

@ -23,6 +23,8 @@ import (
"os"
"sort"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/controller/reconciler"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/controller"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/conditions"
@ -32,34 +34,26 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
ctrlutil "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/log"
daprvApi "github.com/dapr-sandbox/dapr-kubernetes-operator/api/operator/v1alpha1"
daprApi "github.com/dapr-sandbox/dapr-kubernetes-operator/api/operator/v1alpha1"
)
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
func (r *Reconciler) Reconcile(ctx context.Context, res *daprApi.DaprControlPlane) (ctrl.Result, error) {
l := log.FromContext(ctx)
l.Info("Reconciling", "resource", req.NamespacedName.String())
rr := ReconciliationRequest{
Client: r.Client,
Client: r.Client(),
NamespacedName: types.NamespacedName{
Name: req.Name,
Namespace: req.Namespace,
Name: res.Name,
Namespace: res.Namespace,
},
ClusterType: r.ClusterType,
Reconciler: r,
Resource: &daprvApi.DaprControlPlane{},
Resource: res,
}
err := r.Get(ctx, req.NamespacedName, rr.Resource)
if err != nil {
if k8serrors.IsNotFound(err) {
// no CR found anymore, maybe deleted
return ctrl.Result{}, nil
}
}
l.Info("Reconciling", "resource", rr.NamespacedName.String())
// by default, the controller expect the DaprControlPlane resource to be created
// in the same namespace where it runs, if not fallback to the default namespace
@ -69,7 +63,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
ns = controller.NamespaceDefault
}
if req.Name != DaprControlPlaneResourceName || req.Namespace != ns {
if res.Name != DaprControlPlaneResourceName || res.Namespace != ns {
rr.Resource.Status.Phase = conditions.TypeError
meta.SetStatusCondition(&rr.Resource.Status.Conditions, metav1.Condition{
@ -82,7 +76,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
ns),
})
err = r.Status().Update(ctx, rr.Resource)
err := r.Client().Status().Update(ctx, rr.Resource)
if err != nil && k8serrors.IsConflict(err) {
l.Info(err.Error())
@ -92,42 +86,23 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
return ctrl.Result{}, fmt.Errorf("error updating DaprControlPlane resource: %w", err)
}
//nolint:nestif
//nolint:wrapcheck
if rr.Resource.ObjectMeta.DeletionTimestamp.IsZero() {
//
// Add finalizer
//
if ctrlutil.AddFinalizer(rr.Resource, DaprControlPlaneFinalizerName) {
if err := r.Update(ctx, rr.Resource); err != nil {
if k8serrors.IsConflict(err) {
return ctrl.Result{}, fmt.Errorf("conflict when adding finalizer to %s: %w", req.NamespacedName, err)
}
return ctrl.Result{}, fmt.Errorf("failure adding finalizer to %s: %w", req.NamespacedName, err)
}
err := reconciler.AddFinalizer(ctx, r.Client(), rr.Resource, DaprControlPlaneFinalizerName)
if err != nil {
return ctrl.Result{}, err
}
} else {
//
// Cleanup leftovers if needed
//
for i := len(r.actions) - 1; i >= 0; i-- {
if err := r.actions[i].Cleanup(ctx, &rr); err != nil {
//nolint:wrapcheck
return ctrl.Result{}, err
}
}
//
// Handle finalizer
//
if ctrlutil.RemoveFinalizer(rr.Resource, DaprControlPlaneFinalizerName) {
if err := r.Update(ctx, rr.Resource); err != nil {
if k8serrors.IsConflict(err) {
return ctrl.Result{}, fmt.Errorf("conflict when removing finalizer to %s: %w", req.NamespacedName, err)
}
return ctrl.Result{}, fmt.Errorf("failure removing finalizer from %s: %w", req.NamespacedName, err)
}
err := reconciler.RemoveFinalizer(ctx, r.Client(), rr.Resource, DaprControlPlaneFinalizerName)
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
@ -174,7 +149,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
// Update status
//
err = r.Status().Update(ctx, rr.Resource)
err := r.Client().Status().Update(ctx, rr.Resource)
if err != nil && k8serrors.IsConflict(err) {
l.Info(err.Error())
return ctrl.Result{Requeue: true}, nil

View File

@ -37,7 +37,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/predicate"
daprvApi "github.com/dapr-sandbox/dapr-kubernetes-operator/api/operator/v1alpha1"
daprApi "github.com/dapr-sandbox/dapr-kubernetes-operator/api/operator/v1alpha1"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/controller"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/controller/client"
"github.com/go-logr/logr"
@ -56,7 +56,7 @@ func NewReconciler(ctx context.Context, manager ctrlRt.Manager, o helm.Options)
rec := Reconciler{}
rec.l = ctrlRt.Log.WithName("dapr-instance-controller")
rec.Client = c
rec.client = c
rec.Scheme = manager.GetScheme()
rec.ClusterType = controller.ClusterTypeVanilla
rec.manager = manager
@ -126,8 +126,7 @@ func NewReconciler(ctx context.Context, manager ctrlRt.Manager, o helm.Options)
// +kubebuilder:rbac:groups=dapr.io,resources=subscriptions/finalizers,verbs=*
type Reconciler struct {
*client.Client
client *client.Client
Scheme *runtime.Scheme
ClusterType controller.ClusterType
actions []Action
@ -138,16 +137,20 @@ type Reconciler struct {
recorder record.EventRecorder
}
func (r *Reconciler) Client() *client.Client {
return r.client
}
func (r *Reconciler) init(ctx context.Context) error {
c := ctrlRt.NewControllerManagedBy(r.manager)
c = c.For(&daprvApi.DaprInstance{}, builder.WithPredicates(
c = c.For(&daprApi.DaprInstance{}, builder.WithPredicates(
predicate.Or(
predicate.GenerationChangedPredicate{},
)))
for i := range r.actions {
b, err := r.actions[i].Configure(ctx, r.Client, c)
b, err := r.actions[i].Configure(ctx, r.Client(), c)
if err != nil {
//nolint:wrapcheck
return err
@ -156,7 +159,9 @@ func (r *Reconciler) init(ctx context.Context) error {
c = b
}
ct, err := c.Build(r)
objRec := reconcile.AsReconciler[*daprApi.DaprInstance](r.manager.GetClient(), r)
ct, err := c.Build(objRec)
if err != nil {
return fmt.Errorf("failure building the application controller for DaprInstance resource: %w", err)
}

View File

@ -23,6 +23,8 @@ import (
"os"
"sort"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/controller/reconciler"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/controller"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/conditions"
@ -32,25 +34,23 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
ctrlutil "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/log"
daprvApi "github.com/dapr-sandbox/dapr-kubernetes-operator/api/operator/v1alpha1"
daprApi "github.com/dapr-sandbox/dapr-kubernetes-operator/api/operator/v1alpha1"
)
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
func (r *Reconciler) Reconcile(ctx context.Context, res *daprApi.DaprInstance) (ctrl.Result, error) {
l := log.FromContext(ctx)
l.Info("Reconciling", "resource", req.NamespacedName.String())
rr := ReconciliationRequest{
Client: r.Client,
Client: r.Client(),
NamespacedName: types.NamespacedName{
Name: req.Name,
Namespace: req.Namespace,
Name: res.Name,
Namespace: res.Namespace,
},
ClusterType: r.ClusterType,
Reconciler: r,
Resource: &daprvApi.DaprInstance{},
Resource: res,
Chart: r.c,
Overrides: map[string]interface{}{
"dapr_operator": map[string]interface{}{"runAsNonRoot": "true"},
@ -60,13 +60,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
},
}
err := r.Get(ctx, req.NamespacedName, rr.Resource)
if err != nil {
if k8serrors.IsNotFound(err) {
// no CR found anymore, maybe deleted
return ctrl.Result{}, nil
}
}
l.Info("Reconciling", "resource", rr.NamespacedName.String())
// by default, the controller expect the DaprInstance resource to be created
// in the same namespace where it runs, if not fallback to the default namespace
@ -76,7 +70,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
ns = controller.NamespaceDefault
}
if req.Name != DaprInstanceResourceName || req.Namespace != ns {
if res.Name != DaprInstanceResourceName || res.Namespace != ns {
rr.Resource.Status.Phase = conditions.TypeError
meta.SetStatusCondition(&rr.Resource.Status.Conditions, metav1.Condition{
@ -89,7 +83,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
ns),
})
err = r.Status().Update(ctx, rr.Resource)
err := r.Client().Status().Update(ctx, rr.Resource)
if err != nil && k8serrors.IsConflict(err) {
l.Info(err.Error())
@ -99,42 +93,23 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
return ctrl.Result{}, fmt.Errorf("error updating DaprInstance resource: %w", err)
}
//nolint:nestif
//nolint:wrapcheck
if rr.Resource.ObjectMeta.DeletionTimestamp.IsZero() {
//
// Add finalizer
//
if ctrlutil.AddFinalizer(rr.Resource, DaprInstanceFinalizerName) {
if err := r.Update(ctx, rr.Resource); err != nil {
if k8serrors.IsConflict(err) {
return ctrl.Result{}, fmt.Errorf("conflict when adding finalizer to %s: %w", req.NamespacedName, err)
}
return ctrl.Result{}, fmt.Errorf("failure adding finalizer to %s: %w", req.NamespacedName, err)
}
err := reconciler.AddFinalizer(ctx, r.Client(), rr.Resource, DaprInstanceFinalizerName)
if err != nil {
return ctrl.Result{}, err
}
} else {
//
// Cleanup leftovers if needed
//
for i := len(r.actions) - 1; i >= 0; i-- {
if err := r.actions[i].Cleanup(ctx, &rr); err != nil {
//nolint:wrapcheck
return ctrl.Result{}, err
}
}
//
// Handle finalizer
//
if ctrlutil.RemoveFinalizer(rr.Resource, DaprInstanceFinalizerName) {
if err := r.Update(ctx, rr.Resource); err != nil {
if k8serrors.IsConflict(err) {
return ctrl.Result{}, fmt.Errorf("conflict when removing finalizer to %s: %w", req.NamespacedName, err)
}
return ctrl.Result{}, fmt.Errorf("failure removing finalizer from %s: %w", req.NamespacedName, err)
}
err := reconciler.RemoveFinalizer(ctx, r.Client(), rr.Resource, DaprInstanceFinalizerName)
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
@ -181,7 +156,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
// Update status
//
err = r.Status().Update(ctx, rr.Resource)
err := r.Client().Status().Update(ctx, rr.Resource)
if err != nil && k8serrors.IsConflict(err) {
l.Info(err.Error())

View File

@ -0,0 +1,56 @@
package reconciler
import (
"context"
"fmt"
"github.com/dapr-sandbox/dapr-kubernetes-operator/pkg/controller/client"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/builder"
ctrlClient "sigs.k8s.io/controller-runtime/pkg/client"
ctrlutil "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)
type Reconciler interface {
Client() *client.Client
}
type Action[T any] interface {
Configure(ctx context.Context, c *client.Client, b *builder.Builder) (*builder.Builder, error)
Run(ctx context.Context, rc *T) error
Cleanup(ctx context.Context, rc *T) error
}
func AddFinalizer(ctx context.Context, client ctrlClient.Client, o ctrlClient.Object, name string) error {
if !ctrlutil.AddFinalizer(o, name) {
return nil
}
err := client.Update(ctx, o)
if k8serrors.IsConflict(err) {
return fmt.Errorf("conflict when adding finalizer to %s/%s: %w", o.GetNamespace(), o.GetName(), err)
}
if err != nil {
return fmt.Errorf("failure adding finalizer to %s/%s: %w", o.GetNamespace(), o.GetName(), err)
}
return nil
}
func RemoveFinalizer(ctx context.Context, client ctrlClient.Client, o ctrlClient.Object, name string) error {
if !ctrlutil.RemoveFinalizer(o, name) {
return nil
}
err := client.Update(ctx, o)
if k8serrors.IsConflict(err) {
return fmt.Errorf("conflict when removing finalizer to %s/%s: %w", o.GetNamespace(), o.GetName(), err)
}
if err != nil {
return fmt.Errorf("failure removing finalizer from %s/%s: %w", o.GetNamespace(), o.GetName(), err)
}
return nil
}