Skip to content

Commit 3c00240

Browse files
authored
pkg/internal/predicate: refactor DependentPredicate (#3365)
1 parent 82106e8 commit 3c00240

File tree

4 files changed

+112
-102
lines changed

4 files changed

+112
-102
lines changed

pkg/ansible/proxy/proxy.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ import (
2929
"sync"
3030
"time"
3131

32-
"github.com/operator-framework/operator-sdk/pkg/ansible/proxy/controllermap"
33-
"github.com/operator-framework/operator-sdk/pkg/ansible/proxy/kubeconfig"
34-
k8sRequest "github.com/operator-framework/operator-sdk/pkg/ansible/proxy/requestfactory"
35-
osdkHandler "github.com/operator-framework/operator-sdk/pkg/handler"
36-
"github.com/operator-framework/operator-sdk/pkg/internal/predicates"
3732
"k8s.io/apimachinery/pkg/api/meta"
3833
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3934
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -43,6 +38,12 @@ import (
4338
"sigs.k8s.io/controller-runtime/pkg/cache"
4439
"sigs.k8s.io/controller-runtime/pkg/handler"
4540
"sigs.k8s.io/controller-runtime/pkg/source"
41+
42+
"github.com/operator-framework/operator-sdk/pkg/ansible/proxy/controllermap"
43+
"github.com/operator-framework/operator-sdk/pkg/ansible/proxy/kubeconfig"
44+
k8sRequest "github.com/operator-framework/operator-sdk/pkg/ansible/proxy/requestfactory"
45+
osdkHandler "github.com/operator-framework/operator-sdk/pkg/handler"
46+
"github.com/operator-framework/operator-sdk/pkg/internal/predicate"
4647
)
4748

4849
// This is the default timeout to wait for the cache to respond
@@ -226,9 +227,6 @@ func addWatchToController(owner kubeconfig.NamespacedOwnerReference, cMap *contr
226227
u := &unstructured.Unstructured{}
227228
u.SetGroupVersionKind(ownerMapping.GroupVersionKind)
228229

229-
// Adding dependentPredicate for avoiding reconciles when dependent objects are not changed by user
230-
dependentPredicate := predicates.DependentPredicateFuncs()
231-
232230
// Add a watch to controller
233231
if contents.WatchDependentResources && !contents.Blacklist[resource.GroupVersionKind()] {
234232
// Store watch in map
@@ -245,7 +243,7 @@ func addWatchToController(owner kubeconfig.NamespacedOwnerReference, cMap *contr
245243
log.Info("Watching child resource", "kind", resource.GroupVersionKind(),
246244
"enqueue_kind", u.GroupVersionKind())
247245
err := contents.Controller.Watch(&source.Kind{Type: resource},
248-
&handler.EnqueueRequestForOwner{OwnerType: u}, dependentPredicate)
246+
&handler.EnqueueRequestForOwner{OwnerType: u}, predicate.DependentPredicate{})
249247
// Store watch in map
250248
if err != nil {
251249
log.Error(err, "Failed to watch child resource",
@@ -263,7 +261,7 @@ func addWatchToController(owner kubeconfig.NamespacedOwnerReference, cMap *contr
263261
log.Info("Watching child resource", "kind", resource.GroupVersionKind(),
264262
"enqueue_annotation_type", typeString)
265263
err = contents.Controller.Watch(&source.Kind{Type: resource},
266-
&osdkHandler.EnqueueRequestForAnnotation{Type: typeString}, dependentPredicate)
264+
&osdkHandler.EnqueueRequestForAnnotation{Type: typeString}, predicate.DependentPredicate{})
267265
if err != nil {
268266
log.Error(err, "Failed to watch child resource",
269267
"kind", resource.GroupVersionKind(), "enqueue_kind", u.GroupVersionKind())

pkg/helm/controller/controller.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import (
3434

3535
"github.com/operator-framework/operator-sdk/pkg/handler"
3636
"github.com/operator-framework/operator-sdk/pkg/helm/release"
37-
"github.com/operator-framework/operator-sdk/pkg/internal/predicates"
37+
"github.com/operator-framework/operator-sdk/pkg/internal/predicate"
3838
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
3939
)
4040

@@ -98,9 +98,6 @@ func watchDependentResources(mgr manager.Manager, r *HelmOperatorReconciler, c c
9898
owner := &unstructured.Unstructured{}
9999
owner.SetGroupVersionKind(r.GVK)
100100

101-
// using predefined functions for filtering events
102-
dependentPredicate := predicates.DependentPredicateFuncs()
103-
104101
var m sync.RWMutex
105102
watches := map[schema.GroupVersionKind]struct{}{}
106103
releaseHook := func(release *rpb.Release) error {
@@ -130,13 +127,13 @@ func watchDependentResources(mgr manager.Manager, r *HelmOperatorReconciler, c c
130127

131128
if useOwnerRef { // Setup watch using owner references.
132129
err = c.Watch(&source.Kind{Type: &u}, &crthandler.EnqueueRequestForOwner{OwnerType: owner},
133-
dependentPredicate)
130+
predicate.DependentPredicate{})
134131
if err != nil {
135132
return err
136133
}
137134
} else { // Setup watch using annotations.
138135
err = c.Watch(&source.Kind{Type: &u}, &handler.EnqueueRequestForAnnotation{Type: gvk.GroupKind().String()},
139-
dependentPredicate)
136+
predicate.DependentPredicate{})
140137
if err != nil {
141138
return err
142139
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2019 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package predicate
16+
17+
import (
18+
"reflect"
19+
20+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
21+
"sigs.k8s.io/controller-runtime/pkg/event"
22+
logf "sigs.k8s.io/controller-runtime/pkg/log"
23+
"sigs.k8s.io/controller-runtime/pkg/predicate"
24+
)
25+
26+
var log = logf.Log.WithName("predicate")
27+
28+
var _ predicate.Predicate = DependentPredicate{}
29+
30+
// DependentPredicate is a predicate that filters events for resources
31+
// created as dependents of a primary resource. It follows the following
32+
// rules:
33+
//
34+
// - Create events are ignored because it is assumed that the controller
35+
// reconciling the parent is the client creating the dependent
36+
// resources.
37+
// - Update events that change only the dependent resource status are
38+
// ignored because it is not typical for the controller of a primary
39+
// resource to write to the status of one its dependent resources.
40+
// - Deletion events are always handled because a controller will
41+
// typically want to recreate deleted dependent resources if the
42+
// primary resource is not deleted.
43+
// - Generic events are ignored.
44+
//
45+
// DependentPredicate is most often used in conjunction with
46+
// controller-runtime's handler.EnqueueRequestForOwner
47+
type DependentPredicate struct {
48+
predicate.Funcs
49+
}
50+
51+
// Create filters out all events. It assumes that the controller
52+
// reconciling the parent is the only client creating the dependent
53+
// resources.
54+
func (DependentPredicate) Create(e event.CreateEvent) bool {
55+
o := e.Object.(*unstructured.Unstructured)
56+
log.V(1).Info("Skipping reconciliation for dependent resource creation",
57+
"name", o.GetName(), "namespace", o.GetNamespace(), "apiVersion",
58+
o.GroupVersionKind().GroupVersion(), "kind", o.GroupVersionKind().Kind)
59+
return false
60+
}
61+
62+
// Delete passes all events through. This allows the controller to
63+
// recreate deleted dependent resources if the primary resource is
64+
// not deleted.
65+
func (DependentPredicate) Delete(e event.DeleteEvent) bool {
66+
o := e.Object.(*unstructured.Unstructured)
67+
log.V(1).Info("Reconciling due to dependent resource deletion",
68+
"name", o.GetName(), "namespace", o.GetNamespace(), "apiVersion",
69+
o.GroupVersionKind().GroupVersion(), "kind", o.GroupVersionKind().Kind)
70+
return true
71+
}
72+
73+
// Generic filters out all events.
74+
func (DependentPredicate) Generic(e event.GenericEvent) bool {
75+
o := e.Object.(*unstructured.Unstructured)
76+
log.V(1).Info("Skipping reconcile due to generic event", "name", o.GetName(),
77+
"namespace", o.GetNamespace(), "apiVersion", o.GroupVersionKind().GroupVersion(),
78+
"kind", o.GroupVersionKind().Kind)
79+
return false
80+
}
81+
82+
// Update filters out events that change only the dependent resource
83+
// status. It is not typical for the controller of a primary
84+
// resource to write to the status of one its dependent resources.
85+
func (DependentPredicate) Update(e event.UpdateEvent) bool {
86+
old := e.ObjectOld.(*unstructured.Unstructured).DeepCopy()
87+
new := e.ObjectNew.(*unstructured.Unstructured).DeepCopy()
88+
89+
delete(old.Object, "status")
90+
delete(new.Object, "status")
91+
old.SetResourceVersion("")
92+
new.SetResourceVersion("")
93+
94+
if reflect.DeepEqual(old.Object, new.Object) {
95+
return false
96+
}
97+
log.V(1).Info("Reconciling due to dependent resource update",
98+
"name", new.GetName(), "namespace", new.GetNamespace(), "apiVersion",
99+
new.GroupVersionKind().GroupVersion(), "kind", new.GroupVersionKind().Kind)
100+
return true
101+
}

pkg/internal/predicates/predicates.go

Lines changed: 0 additions & 86 deletions
This file was deleted.

0 commit comments

Comments
 (0)