From 17412d3faca795502acf89feba964f8f00360d65 Mon Sep 17 00:00:00 2001 From: Jim Fitzpatrick Date: Fri, 27 Sep 2024 12:16:36 +0100 Subject: [PATCH 1/3] ADD: Limitador sotw reconcile This sets up the subscription for events on kuadrant and limitador resources. The reconcile only is preformed if the limitador resource does not exist. Signed-off-by: Jim Fitzpatrick --- controllers/limitador_task.go | 111 ++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 controllers/limitador_task.go diff --git a/controllers/limitador_task.go b/controllers/limitador_task.go new file mode 100644 index 000000000..8684307bc --- /dev/null +++ b/controllers/limitador_task.go @@ -0,0 +1,111 @@ +package controllers + +import ( + "context" + "strings" + "sync" + + limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1" + "github.com/kuadrant/policy-machinery/controller" + "github.com/kuadrant/policy-machinery/machinery" + "github.com/samber/lo" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/dynamic" + "k8s.io/utils/ptr" + + "github.com/kuadrant/kuadrant-operator/api/v1beta1" + "github.com/kuadrant/kuadrant-operator/pkg/common" +) + +type LimitadorCrReconciler struct { + Client *dynamic.DynamicClient +} + +func NewLimitadorCrReconciler(client *dynamic.DynamicClient) *LimitadorCrReconciler { + return &LimitadorCrReconciler{Client: client} +} + +func (r *LimitadorCrReconciler) Subscription() *controller.Subscription { + return &controller.Subscription{ + ReconcileFunc: r.Reconcile, + Events: []controller.ResourceEventMatcher{ + {Kind: ptr.To(v1beta1.KuadrantGroupKind), EventType: ptr.To(controller.CreateEvent)}, + {Kind: ptr.To(v1beta1.LimitadorGroupKind), EventType: ptr.To(controller.DeleteEvent)}, + }, + } +} + +func (r *LimitadorCrReconciler) Reconcile(ctx context.Context, _ []controller.ResourceEvent, topology *machinery.Topology, _ error, _ *sync.Map) error { + logger := controller.LoggerFromContext(ctx).WithName("LimitadorResourceReconciler") + logger.Info("reconciling limtador resource", "status", "started") + defer logger.Info("reconciling limitador resource", "status", "completed") + + kobjs := lo.FilterMap(topology.Objects().Roots(), func(item machinery.Object, _ int) (*v1beta1.Kuadrant, bool) { + if item.GroupVersionKind().Kind == v1beta1.KuadrantGroupKind.Kind { + return item.(*v1beta1.Kuadrant), true + } + return nil, false + }) + + kobj, err := GetOldestKuadrant(kobjs) + if err != nil { + if strings.Contains(err.Error(), "empty list passed") { + logger.Info("kuadrant resource not found, ignoring", "status", "skipping") + return nil + } + logger.Error(err, "cannont find kuadrant resource", "status", "error") + return err + } + + aobjs := lo.FilterMap(topology.Objects().Objects().Items(), func(item machinery.Object, _ int) (machinery.Object, bool) { + if item.GroupVersionKind().Kind == v1beta1.LimitadorGroupKind.Kind { + return item, true + } + return nil, false + }) + + if len(aobjs) > 0 { + logger.Info("limitador resource already exists, no need to create", "status", "skipping") + return nil + } + + limitador := &limitadorv1alpha1.Limitador{ + TypeMeta: metav1.TypeMeta{ + Kind: "Limitador", + APIVersion: "limitador.kuadrant.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: common.LimitadorName, + Namespace: kobj.Namespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: kobj.GroupVersionKind().GroupVersion().String(), + Kind: kobj.GroupVersionKind().Kind, + Name: kobj.Name, + UID: kobj.UID, + BlockOwnerDeletion: ptr.To(true), + Controller: ptr.To(true), + }, + }, + }, + Spec: limitadorv1alpha1.LimitadorSpec{}, + } + + unstructuredLimitador, err := controller.Destruct(limitador) + if err != nil { + logger.Error(err, "failed to destruct limitador", "status", "error") + return err + } + logger.Info("creating limitador resource", "status", "processing") + _, err = r.Client.Resource(v1beta1.LimitadorsResource).Namespace(limitador.Namespace).Create(ctx, unstructuredLimitador, metav1.CreateOptions{}) + if err != nil { + if errors.IsAlreadyExists(err) { + logger.Info("already created limitador resource", "status", "acceptable") + } else { + logger.Error(err, "failed to create limitador resource", "status", "error") + return err + } + } + return nil +} From 366be339a68c83a3f72560db117d024150cf4690 Mon Sep 17 00:00:00 2001 From: Jim Fitzpatrick Date: Wed, 9 Oct 2024 17:00:07 +0100 Subject: [PATCH 2/3] REBASE: update to changes on main Signed-off-by: Jim Fitzpatrick --- controllers/limitador_reconciler.go | 95 +++++++++++++++++++++++- controllers/limitador_task.go | 111 ---------------------------- 2 files changed, 94 insertions(+), 112 deletions(-) delete mode 100644 controllers/limitador_task.go diff --git a/controllers/limitador_reconciler.go b/controllers/limitador_reconciler.go index db2bac902..3cc7cf3d7 100644 --- a/controllers/limitador_reconciler.go +++ b/controllers/limitador_reconciler.go @@ -1,8 +1,21 @@ package controllers import ( + "context" + "strings" + "sync" + + limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1" "github.com/kuadrant/policy-machinery/controller" + "github.com/kuadrant/policy-machinery/machinery" + "github.com/samber/lo" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/dynamic" + "k8s.io/utils/ptr" + + "github.com/kuadrant/kuadrant-operator/api/v1beta1" + "github.com/kuadrant/kuadrant-operator/pkg/common" ) type LimitadorReconciler struct { @@ -14,5 +27,85 @@ func NewLimitadorReconciler(client *dynamic.DynamicClient) *LimitadorReconciler } func (r *LimitadorReconciler) Subscription() *controller.Subscription { - return &controller.Subscription{} + return &controller.Subscription{ + ReconcileFunc: r.Reconcile, + Events: []controller.ResourceEventMatcher{ + {Kind: ptr.To(v1beta1.KuadrantGroupKind), EventType: ptr.To(controller.CreateEvent)}, + {Kind: ptr.To(v1beta1.LimitadorGroupKind), EventType: ptr.To(controller.DeleteEvent)}, + }, + } +} + +func (r *LimitadorReconciler) Reconcile(ctx context.Context, _ []controller.ResourceEvent, topology *machinery.Topology, _ error, _ *sync.Map) error { + logger := controller.LoggerFromContext(ctx).WithName("LimitadorResourceReconciler") + logger.Info("reconciling limtador resource", "status", "started") + defer logger.Info("reconciling limitador resource", "status", "completed") + + kobjs := lo.FilterMap(topology.Objects().Roots(), func(item machinery.Object, _ int) (*v1beta1.Kuadrant, bool) { + if item.GroupVersionKind().Kind == v1beta1.KuadrantGroupKind.Kind { + return item.(*v1beta1.Kuadrant), true + } + return nil, false + }) + + kobj, err := GetOldestKuadrant(kobjs) + if err != nil { + if strings.Contains(err.Error(), "empty list passed") { + logger.Info("kuadrant resource not found, ignoring", "status", "skipping") + return nil + } + logger.Error(err, "cannont find kuadrant resource", "status", "error") + return err + } + + aobjs := lo.FilterMap(topology.Objects().Objects().Items(), func(item machinery.Object, _ int) (machinery.Object, bool) { + if item.GroupVersionKind().Kind == v1beta1.LimitadorGroupKind.Kind { + return item, true + } + return nil, false + }) + + if len(aobjs) > 0 { + logger.Info("limitador resource already exists, no need to create", "status", "skipping") + return nil + } + + limitador := &limitadorv1alpha1.Limitador{ + TypeMeta: metav1.TypeMeta{ + Kind: "Limitador", + APIVersion: "limitador.kuadrant.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: common.LimitadorName, + Namespace: kobj.Namespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: kobj.GroupVersionKind().GroupVersion().String(), + Kind: kobj.GroupVersionKind().Kind, + Name: kobj.Name, + UID: kobj.UID, + BlockOwnerDeletion: ptr.To(true), + Controller: ptr.To(true), + }, + }, + }, + Spec: limitadorv1alpha1.LimitadorSpec{}, + } + + unstructuredLimitador, err := controller.Destruct(limitador) + if err != nil { + logger.Error(err, "failed to destruct limitador", "status", "error") + return err + } + logger.Info("creating limitador resource", "status", "processing") + _, err = r.Client.Resource(v1beta1.LimitadorsResource).Namespace(limitador.Namespace).Create(ctx, unstructuredLimitador, metav1.CreateOptions{}) + if err != nil { + if errors.IsAlreadyExists(err) { + logger.Info("already created limitador resource", "status", "acceptable") + } else { + logger.Error(err, "failed to create limitador resource", "status", "error") + return err + } + } + return nil } diff --git a/controllers/limitador_task.go b/controllers/limitador_task.go deleted file mode 100644 index 8684307bc..000000000 --- a/controllers/limitador_task.go +++ /dev/null @@ -1,111 +0,0 @@ -package controllers - -import ( - "context" - "strings" - "sync" - - limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1" - "github.com/kuadrant/policy-machinery/controller" - "github.com/kuadrant/policy-machinery/machinery" - "github.com/samber/lo" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/dynamic" - "k8s.io/utils/ptr" - - "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" -) - -type LimitadorCrReconciler struct { - Client *dynamic.DynamicClient -} - -func NewLimitadorCrReconciler(client *dynamic.DynamicClient) *LimitadorCrReconciler { - return &LimitadorCrReconciler{Client: client} -} - -func (r *LimitadorCrReconciler) Subscription() *controller.Subscription { - return &controller.Subscription{ - ReconcileFunc: r.Reconcile, - Events: []controller.ResourceEventMatcher{ - {Kind: ptr.To(v1beta1.KuadrantGroupKind), EventType: ptr.To(controller.CreateEvent)}, - {Kind: ptr.To(v1beta1.LimitadorGroupKind), EventType: ptr.To(controller.DeleteEvent)}, - }, - } -} - -func (r *LimitadorCrReconciler) Reconcile(ctx context.Context, _ []controller.ResourceEvent, topology *machinery.Topology, _ error, _ *sync.Map) error { - logger := controller.LoggerFromContext(ctx).WithName("LimitadorResourceReconciler") - logger.Info("reconciling limtador resource", "status", "started") - defer logger.Info("reconciling limitador resource", "status", "completed") - - kobjs := lo.FilterMap(topology.Objects().Roots(), func(item machinery.Object, _ int) (*v1beta1.Kuadrant, bool) { - if item.GroupVersionKind().Kind == v1beta1.KuadrantGroupKind.Kind { - return item.(*v1beta1.Kuadrant), true - } - return nil, false - }) - - kobj, err := GetOldestKuadrant(kobjs) - if err != nil { - if strings.Contains(err.Error(), "empty list passed") { - logger.Info("kuadrant resource not found, ignoring", "status", "skipping") - return nil - } - logger.Error(err, "cannont find kuadrant resource", "status", "error") - return err - } - - aobjs := lo.FilterMap(topology.Objects().Objects().Items(), func(item machinery.Object, _ int) (machinery.Object, bool) { - if item.GroupVersionKind().Kind == v1beta1.LimitadorGroupKind.Kind { - return item, true - } - return nil, false - }) - - if len(aobjs) > 0 { - logger.Info("limitador resource already exists, no need to create", "status", "skipping") - return nil - } - - limitador := &limitadorv1alpha1.Limitador{ - TypeMeta: metav1.TypeMeta{ - Kind: "Limitador", - APIVersion: "limitador.kuadrant.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: common.LimitadorName, - Namespace: kobj.Namespace, - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: kobj.GroupVersionKind().GroupVersion().String(), - Kind: kobj.GroupVersionKind().Kind, - Name: kobj.Name, - UID: kobj.UID, - BlockOwnerDeletion: ptr.To(true), - Controller: ptr.To(true), - }, - }, - }, - Spec: limitadorv1alpha1.LimitadorSpec{}, - } - - unstructuredLimitador, err := controller.Destruct(limitador) - if err != nil { - logger.Error(err, "failed to destruct limitador", "status", "error") - return err - } - logger.Info("creating limitador resource", "status", "processing") - _, err = r.Client.Resource(v1beta1.LimitadorsResource).Namespace(limitador.Namespace).Create(ctx, unstructuredLimitador, metav1.CreateOptions{}) - if err != nil { - if errors.IsAlreadyExists(err) { - logger.Info("already created limitador resource", "status", "acceptable") - } else { - logger.Error(err, "failed to create limitador resource", "status", "error") - return err - } - } - return nil -} From 4be705270b1b30dd3c8079efa3f6fed2ca3d33f1 Mon Sep 17 00:00:00 2001 From: Jim Fitzpatrick Date: Fri, 11 Oct 2024 12:42:45 +0100 Subject: [PATCH 3/3] nit: rename Signed-off-by: Jim Fitzpatrick --- controllers/limitador_reconciler.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controllers/limitador_reconciler.go b/controllers/limitador_reconciler.go index 3cc7cf3d7..c27c5dd88 100644 --- a/controllers/limitador_reconciler.go +++ b/controllers/limitador_reconciler.go @@ -58,14 +58,14 @@ func (r *LimitadorReconciler) Reconcile(ctx context.Context, _ []controller.Reso return err } - aobjs := lo.FilterMap(topology.Objects().Objects().Items(), func(item machinery.Object, _ int) (machinery.Object, bool) { + lobjs := lo.FilterMap(topology.Objects().Objects().Items(), func(item machinery.Object, _ int) (machinery.Object, bool) { if item.GroupVersionKind().Kind == v1beta1.LimitadorGroupKind.Kind { return item, true } return nil, false }) - if len(aobjs) > 0 { + if len(lobjs) > 0 { logger.Info("limitador resource already exists, no need to create", "status", "skipping") return nil }