update dependencies (#6267)

Signed-off-by: hongming <coder.scala@gmail.com>
This commit is contained in:
hongming
2024-11-06 10:27:06 +08:00
committed by GitHub
parent faf255a084
commit cfebd96a1f
4263 changed files with 341374 additions and 132036 deletions

View File

@@ -33,8 +33,12 @@ import (
var log = logf.RuntimeLog.WithName("source").WithName("EventHandler")
// NewEventHandler creates a new EventHandler.
func NewEventHandler(ctx context.Context, queue workqueue.RateLimitingInterface, handler handler.EventHandler, predicates []predicate.Predicate) *EventHandler {
return &EventHandler{
func NewEventHandler[object client.Object, request comparable](
ctx context.Context,
queue workqueue.TypedRateLimitingInterface[request],
handler handler.TypedEventHandler[object, request],
predicates []predicate.TypedPredicate[object]) *EventHandler[object, request] {
return &EventHandler[object, request]{
ctx: ctx,
handler: handler,
queue: queue,
@@ -43,19 +47,19 @@ func NewEventHandler(ctx context.Context, queue workqueue.RateLimitingInterface,
}
// EventHandler adapts a handler.EventHandler interface to a cache.ResourceEventHandler interface.
type EventHandler struct {
type EventHandler[object client.Object, request comparable] struct {
// ctx stores the context that created the event handler
// that is used to propagate cancellation signals to each handler function.
ctx context.Context
handler handler.EventHandler
queue workqueue.RateLimitingInterface
predicates []predicate.Predicate
handler handler.TypedEventHandler[object, request]
queue workqueue.TypedRateLimitingInterface[request]
predicates []predicate.TypedPredicate[object]
}
// HandlerFuncs converts EventHandler to a ResourceEventHandlerFuncs
// TODO: switch to ResourceEventHandlerDetailedFuncs with client-go 1.27
func (e *EventHandler) HandlerFuncs() cache.ResourceEventHandlerFuncs {
func (e *EventHandler[object, request]) HandlerFuncs() cache.ResourceEventHandlerFuncs {
return cache.ResourceEventHandlerFuncs{
AddFunc: e.OnAdd,
UpdateFunc: e.OnUpdate,
@@ -64,11 +68,11 @@ func (e *EventHandler) HandlerFuncs() cache.ResourceEventHandlerFuncs {
}
// OnAdd creates CreateEvent and calls Create on EventHandler.
func (e *EventHandler) OnAdd(obj interface{}) {
c := event.CreateEvent{}
func (e *EventHandler[object, request]) OnAdd(obj interface{}) {
c := event.TypedCreateEvent[object]{}
// Pull Object out of the object
if o, ok := obj.(client.Object); ok {
if o, ok := obj.(object); ok {
c.Object = o
} else {
log.Error(nil, "OnAdd missing Object",
@@ -89,10 +93,10 @@ func (e *EventHandler) OnAdd(obj interface{}) {
}
// OnUpdate creates UpdateEvent and calls Update on EventHandler.
func (e *EventHandler) OnUpdate(oldObj, newObj interface{}) {
u := event.UpdateEvent{}
func (e *EventHandler[object, request]) OnUpdate(oldObj, newObj interface{}) {
u := event.TypedUpdateEvent[object]{}
if o, ok := oldObj.(client.Object); ok {
if o, ok := oldObj.(object); ok {
u.ObjectOld = o
} else {
log.Error(nil, "OnUpdate missing ObjectOld",
@@ -101,7 +105,7 @@ func (e *EventHandler) OnUpdate(oldObj, newObj interface{}) {
}
// Pull Object out of the object
if o, ok := newObj.(client.Object); ok {
if o, ok := newObj.(object); ok {
u.ObjectNew = o
} else {
log.Error(nil, "OnUpdate missing ObjectNew",
@@ -122,8 +126,8 @@ func (e *EventHandler) OnUpdate(oldObj, newObj interface{}) {
}
// OnDelete creates DeleteEvent and calls Delete on EventHandler.
func (e *EventHandler) OnDelete(obj interface{}) {
d := event.DeleteEvent{}
func (e *EventHandler[object, request]) OnDelete(obj interface{}) {
d := event.TypedDeleteEvent[object]{}
// Deal with tombstone events by pulling the object out. Tombstone events wrap the object in a
// DeleteFinalStateUnknown struct, so the object needs to be pulled out.
@@ -149,7 +153,7 @@ func (e *EventHandler) OnDelete(obj interface{}) {
}
// Pull Object out of the object
if o, ok := obj.(client.Object); ok {
if o, ok := obj.(object); ok {
d.Object = o
} else {
log.Error(nil, "OnDelete missing Object",

View File

@@ -4,12 +4,14 @@ import (
"context"
"errors"
"fmt"
"reflect"
"time"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/util/workqueue"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/handler"
@@ -17,34 +19,40 @@ import (
)
// Kind is used to provide a source of events originating inside the cluster from Watches (e.g. Pod Create).
type Kind struct {
type Kind[object client.Object, request comparable] struct {
// Type is the type of object to watch. e.g. &v1.Pod{}
Type client.Object
Type object
// Cache used to watch APIs
Cache cache.Cache
// started may contain an error if one was encountered during startup. If its closed and does not
Handler handler.TypedEventHandler[object, request]
Predicates []predicate.TypedPredicate[object]
// startedErr may contain an error if one was encountered during startup. If its closed and does not
// contain an error, startup and syncing finished.
started chan error
startedErr chan error
startCancel func()
}
// Start is internal and should be called only by the Controller to register an EventHandler with the Informer
// to enqueue reconcile.Requests.
func (ks *Kind) Start(ctx context.Context, handler handler.EventHandler, queue workqueue.RateLimitingInterface,
prct ...predicate.Predicate) error {
if ks.Type == nil {
func (ks *Kind[object, request]) Start(ctx context.Context, queue workqueue.TypedRateLimitingInterface[request]) error {
if isNil(ks.Type) {
return fmt.Errorf("must create Kind with a non-nil object")
}
if ks.Cache == nil {
if isNil(ks.Cache) {
return fmt.Errorf("must create Kind with a non-nil cache")
}
if isNil(ks.Handler) {
return errors.New("must create Kind with non-nil handler")
}
// cache.GetInformer will block until its context is cancelled if the cache was already started and it can not
// sync that informer (most commonly due to RBAC issues).
ctx, ks.startCancel = context.WithCancel(ctx)
ks.started = make(chan error)
ks.startedErr = make(chan error)
go func() {
var (
i cache.Informer
@@ -72,30 +80,30 @@ func (ks *Kind) Start(ctx context.Context, handler handler.EventHandler, queue w
return true, nil
}); err != nil {
if lastErr != nil {
ks.started <- fmt.Errorf("failed to get informer from cache: %w", lastErr)
ks.startedErr <- fmt.Errorf("failed to get informer from cache: %w", lastErr)
return
}
ks.started <- err
ks.startedErr <- err
return
}
_, err := i.AddEventHandler(NewEventHandler(ctx, queue, handler, prct).HandlerFuncs())
_, err := i.AddEventHandler(NewEventHandler(ctx, queue, ks.Handler, ks.Predicates).HandlerFuncs())
if err != nil {
ks.started <- err
ks.startedErr <- err
return
}
if !ks.Cache.WaitForCacheSync(ctx) {
// Would be great to return something more informative here
ks.started <- errors.New("cache did not sync")
ks.startedErr <- errors.New("cache did not sync")
}
close(ks.started)
close(ks.startedErr)
}()
return nil
}
func (ks *Kind) String() string {
if ks.Type != nil {
func (ks *Kind[object, request]) String() string {
if !isNil(ks.Type) {
return fmt.Sprintf("kind source: %T", ks.Type)
}
return "kind source: unknown type"
@@ -103,9 +111,9 @@ func (ks *Kind) String() string {
// WaitForSync implements SyncingSource to allow controllers to wait with starting
// workers until the cache is synced.
func (ks *Kind) WaitForSync(ctx context.Context) error {
func (ks *Kind[object, request]) WaitForSync(ctx context.Context) error {
select {
case err := <-ks.started:
case err := <-ks.startedErr:
return err
case <-ctx.Done():
ks.startCancel()
@@ -115,3 +123,15 @@ func (ks *Kind) WaitForSync(ctx context.Context) error {
return fmt.Errorf("timed out waiting for cache to be synced for Kind %T", ks.Type)
}
}
func isNil(arg any) bool {
if v := reflect.ValueOf(arg); !v.IsValid() || ((v.Kind() == reflect.Ptr ||
v.Kind() == reflect.Interface ||
v.Kind() == reflect.Slice ||
v.Kind() == reflect.Map ||
v.Kind() == reflect.Chan ||
v.Kind() == reflect.Func) && v.IsNil()) {
return true
}
return false
}