From 86a1feb2c1542dd98efe639d16a024b8b8f307ce Mon Sep 17 00:00:00 2001 From: Mohamed-Amine Bouqsimi Date: Wed, 18 Jan 2023 11:27:12 +0000 Subject: [PATCH] operator: Add watch on the Alertmanager in OCP's user-workload-monitoring namespace (#8038) --- operator/CHANGELOG.md | 1 + .../controllers/loki/lokistack_controller.go | 44 ++++++++++++++++++- .../loki/lokistack_controller_test.go | 16 +++++-- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/operator/CHANGELOG.md b/operator/CHANGELOG.md index b75b8ae62f..b32c6972de 100644 --- a/operator/CHANGELOG.md +++ b/operator/CHANGELOG.md @@ -1,5 +1,6 @@ ## Main +- [8038](https://github.com/grafana/loki/pull/8038) **aminesnow**: Add watch on the Alertmanager in OCP's user-workload-monitoring namespace - [8173](https://github.com/grafana/loki/pull/8173) **periklis**: Remove custom webhook cert mounts for OLM-based deployment (OpenShift) - [8001](https://github.com/grafana/loki/pull/8001) **aminesnow**: Add API validation to Alertmanager header auth config - [8087](https://github.com/grafana/loki/pull/8087) **xperimental**: Fix status not updating when state of pods changes diff --git a/operator/controllers/loki/lokistack_controller.go b/operator/controllers/loki/lokistack_controller.go index c9dd7b5834..b6776842bb 100644 --- a/operator/controllers/loki/lokistack_controller.go +++ b/operator/controllers/loki/lokistack_controller.go @@ -9,6 +9,7 @@ import ( "github.com/grafana/loki/operator/controllers/loki/internal/management/state" "github.com/grafana/loki/operator/internal/external/k8s" "github.com/grafana/loki/operator/internal/handlers" + "github.com/grafana/loki/operator/internal/manifests/openshift" "github.com/grafana/loki/operator/internal/status" openshiftconfigv1 "github.com/openshift/api/config/v1" routev1 "github.com/openshift/api/route/v1" @@ -92,6 +93,15 @@ var ( return false }, }) + createUpdateOrDeletePred = builder.WithPredicates(predicate.Funcs{ + UpdateFunc: func(e event.UpdateEvent) bool { + return (e.ObjectOld.GetGeneration() != e.ObjectNew.GetGeneration()) || + cmp.Diff(e.ObjectOld.GetAnnotations(), e.ObjectNew.GetAnnotations()) != "" + }, + CreateFunc: func(e event.CreateEvent) bool { return true }, + DeleteFunc: func(e event.DeleteEvent) bool { return true }, + GenericFunc: func(e event.GenericEvent) bool { return false }, + }) ) // LokiStackReconciler reconciles a LokiStack object @@ -194,7 +204,8 @@ func (r *LokiStackReconciler) buildController(bld k8s.Builder) error { Owns(&rbacv1.ClusterRole{}, updateOrDeleteOnlyPred). Owns(&rbacv1.ClusterRoleBinding{}, updateOrDeleteOnlyPred). Owns(&rbacv1.Role{}, updateOrDeleteOnlyPred). - Owns(&rbacv1.RoleBinding{}, updateOrDeleteOnlyPred) + Owns(&rbacv1.RoleBinding{}, updateOrDeleteOnlyPred). + Watches(&source.Kind{Type: &corev1.Service{}}, r.enqueueForUserWorkloadAMService(), createUpdateOrDeletePred) if r.FeatureGates.LokiStackAlerts { bld = bld.Owns(&monitoringv1.PrometheusRule{}, updateOrDeleteOnlyPred) @@ -253,3 +264,34 @@ func statusDifferent(e event.UpdateEvent) bool { return false } } + +func (r *LokiStackReconciler) enqueueForUserWorkloadAMService() handler.EventHandler { + ctx := context.TODO() + return handler.EnqueueRequestsFromMapFunc(func(obj client.Object) []reconcile.Request { + lokiStacks := &lokiv1.LokiStackList{} + if err := r.Client.List(ctx, lokiStacks); err != nil { + r.Log.Error(err, "Error getting LokiStack resources in event handler") + return nil + } + var requests []reconcile.Request + + if obj.GetName() == openshift.MonitoringSVCOperated && obj.GetNamespace() == openshift.MonitoringUserwWrkloadNS { + + for _, stack := range lokiStacks.Items { + if stack.Spec.Tenants != nil && (stack.Spec.Tenants.Mode == lokiv1.OpenshiftLogging || + stack.Spec.Tenants.Mode == lokiv1.OpenshiftNetwork) { + requests = append(requests, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: stack.Namespace, + Name: stack.Name, + }, + }) + } + } + + r.Log.Info("Enqueued requests for all LokiStacks because of UserWorkload Alertmanager Service resource change", "count", len(requests), "kind", obj.GetObjectKind()) + } + + return requests + }) +} diff --git a/operator/controllers/loki/lokistack_controller_test.go b/operator/controllers/loki/lokistack_controller_test.go index 1bd497c24d..dccba39be4 100644 --- a/operator/controllers/loki/lokistack_controller_test.go +++ b/operator/controllers/loki/lokistack_controller_test.go @@ -57,6 +57,7 @@ func TestLokiStackController_RegistersCustomResourceForCreateOrUpdate(t *testing b.ForReturns(b) b.OwnsReturns(b) + b.WatchesReturns(b) err := c.buildController(b) require.NoError(t, err) @@ -202,8 +203,8 @@ func TestLokiStackController_RegisterWatchedResources(t *testing.T) { table := []test{ { src: &source.Kind{Type: &openshiftconfigv1.APIServer{}}, - index: 0, - watchesCallsCount: 1, + index: 1, + watchesCallsCount: 2, featureGates: configv1.FeatureGates{ OpenShift: configv1.OpenShiftFeatureGates{ ClusterTLSPolicy: true, @@ -213,8 +214,8 @@ func TestLokiStackController_RegisterWatchedResources(t *testing.T) { }, { src: &source.Kind{Type: &openshiftconfigv1.Proxy{}}, - index: 0, - watchesCallsCount: 1, + index: 1, + watchesCallsCount: 2, featureGates: configv1.FeatureGates{ OpenShift: configv1.OpenShiftFeatureGates{ ClusterProxy: true, @@ -222,6 +223,13 @@ func TestLokiStackController_RegisterWatchedResources(t *testing.T) { }, pred: updateOrDeleteOnlyPred, }, + { + src: &source.Kind{Type: &corev1.Service{}}, + index: 0, + watchesCallsCount: 1, + featureGates: configv1.FeatureGates{}, + pred: createUpdateOrDeletePred, + }, } for _, tst := range table { b := &k8sfakes.FakeBuilder{}