From 62ede83f610f01cb6eed1cc973b90c7c0f69ab8f Mon Sep 17 00:00:00 2001 From: tyichye19 <84450119+tyichye19@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:33:39 +0300 Subject: [PATCH] ODF-545 | Add event controller (#154) * add event controller and event permissions * change poolog event name and reason * add fencecompleted const --------- Signed-off-by: Tal Yichye --- ...ge-odf-operator.clusterserviceversion.yaml | 1 + config/rbac/role.yaml | 1 + controllers/event/event_controller.go | 108 ++++++++++++++++++ controllers/util/events.go | 7 +- main.go | 11 ++ 5 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 controllers/event/event_controller.go diff --git a/bundle/manifests/ibm-storage-odf-operator.clusterserviceversion.yaml b/bundle/manifests/ibm-storage-odf-operator.clusterserviceversion.yaml index c7cb7acc..06dc17c2 100644 --- a/bundle/manifests/ibm-storage-odf-operator.clusterserviceversion.yaml +++ b/bundle/manifests/ibm-storage-odf-operator.clusterserviceversion.yaml @@ -161,6 +161,7 @@ spec: - events verbs: - create + - delete - get - list - patch diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 8098aa58..b68a3dd4 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -105,6 +105,7 @@ rules: - events verbs: - create + - delete - get - list - patch diff --git a/controllers/event/event_controller.go b/controllers/event/event_controller.go new file mode 100644 index 00000000..acdb1381 --- /dev/null +++ b/controllers/event/event_controller.go @@ -0,0 +1,108 @@ +/** + * Copyright contributors to the ibm-storage-odf-operator project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package event + +import ( + "context" + "github.com/IBM/ibm-storage-odf-operator/controllers/util" + "github.com/go-logr/logr" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + 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/controller" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "strings" +) + +func reconcileEvent(obj runtime.Object) bool { + evt, ok := obj.(*corev1.Event) + if !ok { + return false + } + return strings.HasPrefix(evt.Name, util.PoolOGChangedReason) || + strings.HasPrefix(evt.Name, util.FenceCompletedReason) + +} + +var eventPredicate = predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + return reconcileEvent(e.Object) + }, + DeleteFunc: func(e event.DeleteEvent) bool { + return false + }, + UpdateFunc: func(e event.UpdateEvent) bool { + return false + }, + GenericFunc: func(e event.GenericEvent) bool { + return false + }, +} + +type EventWatcher struct { + Client client.Client + Scheme *runtime.Scheme + Log logr.Logger + Namespace string +} + +func (r *EventWatcher) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&corev1.Event{}, builder.WithPredicates(eventPredicate)). + WithOptions(controller.Options{MaxConcurrentReconciles: 1}). + Complete(r) +} + +//+kubebuilder:rbac:groups=core,resources=events,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch; + +// Reconcile Event +func (r *EventWatcher) Reconcile(_ context.Context, request reconcile.Request) (result reconcile.Result, err error) { + result = reconcile.Result{} + prevLogger := r.Log + + defer func() { + r.Log = prevLogger + if errors.IsConflict(err) { + r.Log.Info("requeue due to resource update conflicts") + result = reconcile.Result{Requeue: true} + err = nil + } + }() + + r.Log = r.Log.WithValues("Event", request.NamespacedName) + r.Log.Info("reconciling Event") + + evt := &corev1.Event{} + + if err = r.Client.Get(context.TODO(), request.NamespacedName, evt); err != nil { + if errors.IsNotFound(err) { + r.Log.Info("Event not found") + return result, nil + } + return result, err + } + + // TODO - Handle PoolOwnershipGroupChanged & FenceCompleted events + + return result, nil +} diff --git a/controllers/util/events.go b/controllers/util/events.go index 2f4b94b0..9c12136a 100644 --- a/controllers/util/events.go +++ b/controllers/util/events.go @@ -40,7 +40,8 @@ const ( FailedCreateStorageClassReason = "FailedCreateStorageClass" DeletedDuplicatedStorageClassReason = "DeletedDuplicatedStorageClass" FailedCreatePromRuleReason = "FailedCreatePromRule" - PoolOGChangeReason = "PoolOwnershipGroupChange" + PoolOGChangedReason = "PoolOwnershipGroupChanged" + FenceCompletedReason = "FenceCompleted" ) func InitK8sEvent(instance *odfv1alpha1.FlashSystemCluster, eventType, reason, message string) *corev1.Event { @@ -75,7 +76,7 @@ func InitK8sPoolOGChangeEvent(instance *odfv1alpha1.FlashSystemCluster, poolName selectLabels := GetLabels() return &corev1.Event{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%v_for_%v", PoolOGChangeReason, poolName), + Name: fmt.Sprintf("%v_for_%v", PoolOGChangedReason, poolName), Namespace: instance.Namespace, Labels: selectLabels, }, @@ -87,7 +88,7 @@ func InitK8sPoolOGChangeEvent(instance *odfv1alpha1.FlashSystemCluster, poolName ResourceVersion: instance.ResourceVersion, APIVersion: instance.APIVersion, }, - Reason: PoolOGChangeReason, + Reason: PoolOGChangedReason, Message: fmt.Sprintf("Pool %v changed ownership group to %v", poolName, ogName), FirstTimestamp: t, LastTimestamp: t, diff --git a/main.go b/main.go index 67a98ad9..69d1cc88 100644 --- a/main.go +++ b/main.go @@ -19,6 +19,7 @@ package main import ( "context" "flag" + "github.com/IBM/ibm-storage-odf-operator/controllers/event" "os" // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. @@ -148,6 +149,16 @@ func main() { os.Exit(1) } + if err = (&event.EventWatcher{ + Client: mgr.GetClient(), + Namespace: ns, + Log: ctrl.Log.WithName("controllers").WithName("EventWatcher"), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "EventWatcher") + os.Exit(1) + } + setupLog.Info("enable console") if err := mgr.Add(manager.RunnableFunc(func(context.Context) error { err = console.EnableIBMConsoleByDefault(mgr.GetClient())