2 Copyright 2018 The Kubernetes Authors.
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
22 "k8s.io/apimachinery/pkg/api/meta"
23 "k8s.io/apimachinery/pkg/runtime"
24 "k8s.io/client-go/tools/cache"
25 "k8s.io/client-go/util/workqueue"
26 "sigs.k8s.io/controller-runtime/pkg/event"
27 "sigs.k8s.io/controller-runtime/pkg/handler"
28 logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31 "sigs.k8s.io/controller-runtime/pkg/predicate"
34 var log = logf.KBLog.WithName("source").WithName("EventHandler")
36 var _ cache.ResourceEventHandler = EventHandler{}
38 // EventHandler adapts a eventhandler.EventHandler interface to a cache.ResourceEventHandler interface
39 type EventHandler struct {
40 EventHandler handler.EventHandler
41 Queue workqueue.RateLimitingInterface
42 Predicates []predicate.Predicate
45 // OnAdd creates and CreateEvent and calls Create on EventHandler
46 func (e EventHandler) OnAdd(obj interface{}) {
47 c := event.CreateEvent{}
49 // Pull metav1.Object out of the object
50 if o, err := meta.Accessor(obj); err == nil {
53 log.Error(err, "OnAdd missing Meta",
54 "object", obj, "type", fmt.Sprintf("%T", obj))
58 // Pull the runtime.Object out of the object
59 if o, ok := obj.(runtime.Object); ok {
62 log.Error(nil, "OnAdd missing runtime.Object",
63 "object", obj, "type", fmt.Sprintf("%T", obj))
67 for _, p := range e.Predicates {
73 // Invoke create handler
74 e.EventHandler.Create(c, e.Queue)
77 // OnUpdate creates and UpdateEvent and calls Update on EventHandler
78 func (e EventHandler) OnUpdate(oldObj, newObj interface{}) {
79 u := event.UpdateEvent{}
81 // Pull metav1.Object out of the object
82 if o, err := meta.Accessor(oldObj); err == nil {
85 log.Error(err, "OnUpdate missing MetaOld",
86 "object", oldObj, "type", fmt.Sprintf("%T", oldObj))
90 // Pull the runtime.Object out of the object
91 if o, ok := oldObj.(runtime.Object); ok {
94 log.Error(nil, "OnUpdate missing ObjectOld",
95 "object", oldObj, "type", fmt.Sprintf("%T", oldObj))
99 // Pull metav1.Object out of the object
100 if o, err := meta.Accessor(newObj); err == nil {
103 log.Error(err, "OnUpdate missing MetaNew",
104 "object", newObj, "type", fmt.Sprintf("%T", newObj))
108 // Pull the runtime.Object out of the object
109 if o, ok := newObj.(runtime.Object); ok {
112 log.Error(nil, "OnUpdate missing ObjectNew",
113 "object", oldObj, "type", fmt.Sprintf("%T", oldObj))
117 for _, p := range e.Predicates {
123 // Invoke update handler
124 e.EventHandler.Update(u, e.Queue)
127 // OnDelete creates and DeleteEvent and calls Delete on EventHandler
128 func (e EventHandler) OnDelete(obj interface{}) {
129 d := event.DeleteEvent{}
131 // Deal with tombstone events by pulling the object out. Tombstone events wrap the object in a
132 // DeleteFinalStateUnknown struct, so the object needs to be pulled out.
133 // Copied from sample-controller
134 // This should never happen if we aren't missing events, which we have concluded that we are not
135 // and made decisions off of this belief. Maybe this shouldn't be here?
137 if _, ok = obj.(metav1.Object); !ok {
138 // If the object doesn't have Metadata, assume it is a tombstone object of type DeletedFinalStateUnknown
139 tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
141 log.Error(nil, "Error decoding objects. Expected cache.DeletedFinalStateUnknown",
142 "type", fmt.Sprintf("%T", obj),
147 // Set obj to the tombstone obj
151 // Pull metav1.Object out of the object
152 if o, err := meta.Accessor(obj); err == nil {
155 log.Error(err, "OnDelete missing Meta",
156 "object", obj, "type", fmt.Sprintf("%T", obj))
160 // Pull the runtime.Object out of the object
161 if o, ok := obj.(runtime.Object); ok {
164 log.Error(nil, "OnDelete missing runtime.Object",
165 "object", obj, "type", fmt.Sprintf("%T", obj))
169 for _, p := range e.Predicates {
175 // Invoke delete handler
176 e.EventHandler.Delete(d, e.Queue)