Skip to content

Commit ade711f

Browse files
authored
pkg/internal/predicate: refactor DependentPredicate (#3365)
1 parent feac19e commit ade711f

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

predicate/dependent.go

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+
}

0 commit comments

Comments
 (0)