@@ -54,6 +54,8 @@ import (
5454
5555 "github.com/prometheus/client_golang/prometheus"
5656 "github.com/prometheus/client_golang/prometheus/promauto"
57+
58+ "github.com/google/go-cmp/cmp"
5759)
5860
5961const maxRetries = 5
@@ -131,7 +133,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
131133 cache.Indexers {},
132134 )
133135
134- allCoreEventsController := newResourceController (kubeClient , eventHandler , allCoreEventsInformer , objName (api_v1.Event {}), V1 , kubewatchEventsMetrics )
136+ allCoreEventsController := newResourceController (kubeClient , eventHandler , allCoreEventsInformer , objName (api_v1.Event {}), V1 , kubewatchEventsMetrics , conf . IgnoredFields )
135137 stopAllCoreEventsCh := make (chan struct {})
136138 defer close (stopAllCoreEventsCh )
137139
@@ -155,7 +157,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
155157 cache.Indexers {},
156158 )
157159
158- allEventsController := newResourceController (kubeClient , eventHandler , allEventsInformer , objName (events_v1.Event {}), EVENTS_V1 , kubewatchEventsMetrics )
160+ allEventsController := newResourceController (kubeClient , eventHandler , allEventsInformer , objName (events_v1.Event {}), EVENTS_V1 , kubewatchEventsMetrics , conf . IgnoredFields )
159161 stopAllEventsCh := make (chan struct {})
160162 defer close (stopAllEventsCh )
161163
@@ -177,7 +179,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
177179 cache.Indexers {},
178180 )
179181
180- c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.Pod {}), V1 , kubewatchEventsMetrics )
182+ c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.Pod {}), V1 , kubewatchEventsMetrics , conf . IgnoredFields )
181183 stopCh := make (chan struct {})
182184 defer close (stopCh )
183185
@@ -199,7 +201,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
199201 cache.Indexers {},
200202 )
201203
202- c := newResourceController (kubeClient , eventHandler , informer , objName (autoscaling_v1.HorizontalPodAutoscaler {}), AUTOSCALING_V1 , kubewatchEventsMetrics )
204+ c := newResourceController (kubeClient , eventHandler , informer , objName (autoscaling_v1.HorizontalPodAutoscaler {}), AUTOSCALING_V1 , kubewatchEventsMetrics , conf . IgnoredFields )
203205 stopCh := make (chan struct {})
204206 defer close (stopCh )
205207
@@ -222,7 +224,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
222224 cache.Indexers {},
223225 )
224226
225- c := newResourceController (kubeClient , eventHandler , informer , objName (apps_v1.DaemonSet {}), APPS_V1 , kubewatchEventsMetrics )
227+ c := newResourceController (kubeClient , eventHandler , informer , objName (apps_v1.DaemonSet {}), APPS_V1 , kubewatchEventsMetrics , conf . IgnoredFields )
226228 stopCh := make (chan struct {})
227229 defer close (stopCh )
228230
@@ -244,7 +246,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
244246 cache.Indexers {},
245247 )
246248
247- c := newResourceController (kubeClient , eventHandler , informer , objName (apps_v1.StatefulSet {}), APPS_V1 , kubewatchEventsMetrics )
249+ c := newResourceController (kubeClient , eventHandler , informer , objName (apps_v1.StatefulSet {}), APPS_V1 , kubewatchEventsMetrics , conf . IgnoredFields )
248250 stopCh := make (chan struct {})
249251 defer close (stopCh )
250252
@@ -266,7 +268,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
266268 cache.Indexers {},
267269 )
268270
269- c := newResourceController (kubeClient , eventHandler , informer , objName (apps_v1.ReplicaSet {}), APPS_V1 , kubewatchEventsMetrics )
271+ c := newResourceController (kubeClient , eventHandler , informer , objName (apps_v1.ReplicaSet {}), APPS_V1 , kubewatchEventsMetrics , conf . IgnoredFields )
270272 stopCh := make (chan struct {})
271273 defer close (stopCh )
272274
@@ -288,7 +290,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
288290 cache.Indexers {},
289291 )
290292
291- c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.Service {}), V1 , kubewatchEventsMetrics )
293+ c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.Service {}), V1 , kubewatchEventsMetrics , conf . IgnoredFields )
292294 stopCh := make (chan struct {})
293295 defer close (stopCh )
294296
@@ -310,7 +312,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
310312 cache.Indexers {},
311313 )
312314
313- c := newResourceController (kubeClient , eventHandler , informer , objName (apps_v1.Deployment {}), APPS_V1 , kubewatchEventsMetrics )
315+ c := newResourceController (kubeClient , eventHandler , informer , objName (apps_v1.Deployment {}), APPS_V1 , kubewatchEventsMetrics , conf . IgnoredFields )
314316 stopCh := make (chan struct {})
315317 defer close (stopCh )
316318
@@ -332,7 +334,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
332334 cache.Indexers {},
333335 )
334336
335- c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.Namespace {}), V1 , kubewatchEventsMetrics )
337+ c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.Namespace {}), V1 , kubewatchEventsMetrics , conf . IgnoredFields )
336338 stopCh := make (chan struct {})
337339 defer close (stopCh )
338340
@@ -354,7 +356,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
354356 cache.Indexers {},
355357 )
356358
357- c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.ReplicationController {}), V1 , kubewatchEventsMetrics )
359+ c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.ReplicationController {}), V1 , kubewatchEventsMetrics , conf . IgnoredFields )
358360 stopCh := make (chan struct {})
359361 defer close (stopCh )
360362
@@ -376,7 +378,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
376378 cache.Indexers {},
377379 )
378380
379- c := newResourceController (kubeClient , eventHandler , informer , objName (batch_v1.Job {}), BATCH_V1 , kubewatchEventsMetrics )
381+ c := newResourceController (kubeClient , eventHandler , informer , objName (batch_v1.Job {}), BATCH_V1 , kubewatchEventsMetrics , conf . IgnoredFields )
380382 stopCh := make (chan struct {})
381383 defer close (stopCh )
382384
@@ -398,7 +400,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
398400 cache.Indexers {},
399401 )
400402
401- c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.Node {}), V1 , kubewatchEventsMetrics )
403+ c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.Node {}), V1 , kubewatchEventsMetrics , conf . IgnoredFields )
402404 stopCh := make (chan struct {})
403405 defer close (stopCh )
404406
@@ -420,7 +422,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
420422 cache.Indexers {},
421423 )
422424
423- c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.ServiceAccount {}), V1 , kubewatchEventsMetrics )
425+ c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.ServiceAccount {}), V1 , kubewatchEventsMetrics , conf . IgnoredFields )
424426 stopCh := make (chan struct {})
425427 defer close (stopCh )
426428
@@ -442,7 +444,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
442444 cache.Indexers {},
443445 )
444446
445- c := newResourceController (kubeClient , eventHandler , informer , objName (rbac_v1.ClusterRole {}), RBAC_V1 , kubewatchEventsMetrics )
447+ c := newResourceController (kubeClient , eventHandler , informer , objName (rbac_v1.ClusterRole {}), RBAC_V1 , kubewatchEventsMetrics , conf . IgnoredFields )
446448 stopCh := make (chan struct {})
447449 defer close (stopCh )
448450
@@ -464,7 +466,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
464466 cache.Indexers {},
465467 )
466468
467- c := newResourceController (kubeClient , eventHandler , informer , objName (rbac_v1.ClusterRoleBinding {}), RBAC_V1 , kubewatchEventsMetrics )
469+ c := newResourceController (kubeClient , eventHandler , informer , objName (rbac_v1.ClusterRoleBinding {}), RBAC_V1 , kubewatchEventsMetrics , conf . IgnoredFields )
468470 stopCh := make (chan struct {})
469471 defer close (stopCh )
470472
@@ -486,7 +488,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
486488 cache.Indexers {},
487489 )
488490
489- c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.PersistentVolume {}), V1 , kubewatchEventsMetrics )
491+ c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.PersistentVolume {}), V1 , kubewatchEventsMetrics , conf . IgnoredFields )
490492 stopCh := make (chan struct {})
491493 defer close (stopCh )
492494
@@ -508,7 +510,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
508510 cache.Indexers {},
509511 )
510512
511- c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.Secret {}), V1 , kubewatchEventsMetrics )
513+ c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.Secret {}), V1 , kubewatchEventsMetrics , conf . IgnoredFields )
512514 stopCh := make (chan struct {})
513515 defer close (stopCh )
514516
@@ -530,7 +532,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
530532 cache.Indexers {},
531533 )
532534
533- c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.ConfigMap {}), V1 , kubewatchEventsMetrics )
535+ c := newResourceController (kubeClient , eventHandler , informer , objName (api_v1.ConfigMap {}), V1 , kubewatchEventsMetrics , conf . IgnoredFields )
534536 stopCh := make (chan struct {})
535537 defer close (stopCh )
536538
@@ -552,7 +554,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
552554 cache.Indexers {},
553555 )
554556
555- c := newResourceController (kubeClient , eventHandler , informer , objName (networking_v1.Ingress {}), NETWORKING_V1 , kubewatchEventsMetrics )
557+ c := newResourceController (kubeClient , eventHandler , informer , objName (networking_v1.Ingress {}), NETWORKING_V1 , kubewatchEventsMetrics , conf . IgnoredFields )
556558 stopCh := make (chan struct {})
557559 defer close (stopCh )
558560
@@ -583,7 +585,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
583585 cache.Indexers {},
584586 )
585587
586- c := newResourceController (kubeClient , eventHandler , informer , crd .Resource , fmt .Sprintf ("%s/%s" , crd .Group , crd .Version ), kubewatchEventsMetrics )
588+ c := newResourceController (kubeClient , eventHandler , informer , crd .Resource , fmt .Sprintf ("%s/%s" , crd .Group , crd .Version ), kubewatchEventsMetrics , conf . IgnoredFields )
587589 stopCh := make (chan struct {})
588590 defer close (stopCh )
589591
@@ -596,7 +598,7 @@ func Start(conf *config.Config, eventHandler handlers.Handler) {
596598 <- sigterm
597599}
598600
599- func newResourceController (client kubernetes.Interface , eventHandler handlers.Handler , informer cache.SharedIndexInformer , resourceType string , apiVersion string , kubewatchEventsMetrics * prometheus.CounterVec ) * Controller {
601+ func newResourceController (client kubernetes.Interface , eventHandler handlers.Handler , informer cache.SharedIndexInformer , resourceType string , apiVersion string , kubewatchEventsMetrics * prometheus.CounterVec , ignoredFields map [ string ] interface {} ) * Controller {
600602 queue := workqueue .NewRateLimitingQueue (workqueue .DefaultControllerRateLimiter ())
601603 var newEvent Event
602604 var err error
@@ -634,6 +636,15 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha
634636 if ! ok {
635637 logrus .WithField ("pkg" , "kubewatch-" + resourceType ).Errorf ("cannot convert old to runtime.Object for update on %v" , old )
636638 }
639+ if len (ignoredFields ) > 0 {
640+ diff , errDiff := diffObjects (old , new , ignoredFields )
641+ if errDiff != nil {
642+ logrus .WithField ("pkg" , "kubewatch-" + resourceType ).Errorf ("cannot diff old & new objects %v and %v: %v" , old , new , errDiff )
643+ } else if len (diff ) == 0 {
644+ logrus .WithField ("pkg" , "kubewatch-" + resourceType ).Infof ("Ignoring update to %v: %s" , resourceType , newEvent .key )
645+ return
646+ }
647+ }
637648 logrus .WithField ("pkg" , "kubewatch-" + resourceType ).Infof ("Processing update to %v: %s" , resourceType , newEvent .key )
638649 if err == nil {
639650 queue .Add (newEvent )
@@ -670,6 +681,38 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha
670681 }
671682}
672683
684+ func diffObjects (old , new interface {}, ignoredFields map [string ]interface {}) (string , error ) {
685+ oldContent , err := runtime .DefaultUnstructuredConverter .ToUnstructured (old )
686+ if err != nil {
687+ return "" , err
688+ }
689+ newContent , err := runtime .DefaultUnstructuredConverter .ToUnstructured (new )
690+ if err != nil {
691+ return "" , err
692+ }
693+ recursiveDelete (oldContent , ignoredFields )
694+ recursiveDelete (newContent , ignoredFields )
695+ return cmp .Diff (oldContent , newContent ), nil
696+ }
697+
698+ // recursiveDelete recursively removes key from object
699+ // value of key should be either nil or nested map[string]interface{}
700+ // value of object to delete from should be nested map[string]interface{}
701+ func recursiveDelete (object map [string ]interface {}, key map [string ]interface {}) {
702+ for k , v := range key {
703+ if v == nil {
704+ delete (object , k )
705+ continue
706+ }
707+ if recursiveKey , ok := v .(map [string ]interface {}); ok {
708+ if recursiveObj , ok := object [k ].(map [string ]interface {}); ok {
709+ recursiveDelete (recursiveObj , recursiveKey )
710+ }
711+ }
712+ }
713+ return
714+ }
715+
673716// Run starts the kubewatch controller
674717func (c * Controller ) Run (stopCh <- chan struct {}) {
675718 defer utilruntime .HandleCrash ()
0 commit comments