@@ -26,6 +26,7 @@ import (
2626 "k8s.io/klog/v2"
2727 "k8s.io/utils/ptr"
2828
29+ "sigs.k8s.io/controller-runtime/pkg/config"
2930 "sigs.k8s.io/controller-runtime/pkg/controller/priorityqueue"
3031 "sigs.k8s.io/controller-runtime/pkg/internal/controller"
3132 "sigs.k8s.io/controller-runtime/pkg/manager"
@@ -80,13 +81,54 @@ type TypedOptions[request comparable] struct {
8081 // Only use a custom NewQueue if you know what you are doing.
8182 NewQueue func (controllerName string , rateLimiter workqueue.TypedRateLimiter [request ]) workqueue.TypedRateLimitingInterface [request ]
8283
84+ // Logger is the logger used for this controller, it will be used by the LogConstructor
85+ // to construt a log per request.
86+ Logger logr.Logger
87+
8388 // LogConstructor is used to construct a logger used for this controller and passed
8489 // to each reconciliation via the context field.
8590 LogConstructor func (request * request ) logr.Logger
91+
92+ // UsePriorityQueue configures the controllers queue to use the controller-runtime provided
93+ // priority queue.
94+ //
95+ // Note: This flag is disabled by default until a future version. It's currently in beta.
96+ UsePriorityQueue * bool
97+ }
98+
99+ // DefaultFromConfig defaults the config from a config.Controller
100+ func (options * TypedOptions [request ]) DefaultFromConfig (config config.Controller ) {
101+ if options .Logger .GetSink () == nil {
102+ options .Logger = config .Logger
103+ }
104+
105+ if options .SkipNameValidation == nil {
106+ options .SkipNameValidation = config .SkipNameValidation
107+ }
108+
109+ if options .MaxConcurrentReconciles <= 0 && config .MaxConcurrentReconciles > 0 {
110+ options .MaxConcurrentReconciles = config .MaxConcurrentReconciles
111+ }
112+
113+ if options .CacheSyncTimeout == 0 && config .CacheSyncTimeout > 0 {
114+ options .CacheSyncTimeout = config .CacheSyncTimeout
115+ }
116+
117+ if options .UsePriorityQueue == nil {
118+ options .UsePriorityQueue = config .UsePriorityQueue
119+ }
120+
121+ if options .RecoverPanic == nil {
122+ options .RecoverPanic = config .RecoverPanic
123+ }
124+
125+ if options .NeedLeaderElection == nil {
126+ options .NeedLeaderElection = config .NeedLeaderElection
127+ }
86128}
87129
88- // Controller implements a Kubernetes API. A Controller manages a work queue fed reconcile.Requests
89- // from source.Sources. Work is performed through the reconcile.Reconciler for each enqueued item.
130+ // Controller implements an API. A Controller manages a work queue fed reconcile.Requests
131+ // from source.Sources. Work is performed through the reconcile.Reconciler for each enqueued item.
90132// Work typically is reads and writes Kubernetes objects to make the system state match the state specified
91133// in the object Spec.
92134type Controller = TypedController [reconcile.Request ]
@@ -119,7 +161,8 @@ func New(name string, mgr manager.Manager, options Options) (Controller, error)
119161//
120162// The name must be unique as it is used to identify the controller in metrics and logs.
121163func NewTyped [request comparable ](name string , mgr manager.Manager , options TypedOptions [request ]) (TypedController [request ], error ) {
122- c , err := NewTypedUnmanaged (name , mgr , options )
164+ options .DefaultFromConfig (mgr .GetControllerOptions ())
165+ c , err := NewTypedUnmanaged (name , options )
123166 if err != nil {
124167 return nil , err
125168 }
@@ -132,14 +175,14 @@ func NewTyped[request comparable](name string, mgr manager.Manager, options Type
132175// caller is responsible for starting the returned controller.
133176//
134177// The name must be unique as it is used to identify the controller in metrics and logs.
135- func NewUnmanaged (name string , mgr manager. Manager , options Options ) (Controller , error ) {
136- return NewTypedUnmanaged (name , mgr , options )
178+ func NewUnmanaged (name string , options Options ) (Controller , error ) {
179+ return NewTypedUnmanaged (name , options )
137180}
138181
139182// NewTypedUnmanaged returns a new typed controller without adding it to the manager.
140183//
141184// The name must be unique as it is used to identify the controller in metrics and logs.
142- func NewTypedUnmanaged [request comparable ](name string , mgr manager. Manager , options TypedOptions [request ]) (TypedController [request ], error ) {
185+ func NewTypedUnmanaged [request comparable ](name string , options TypedOptions [request ]) (TypedController [request ], error ) {
143186 if options .Reconciler == nil {
144187 return nil , fmt .Errorf ("must specify Reconciler" )
145188 }
@@ -148,18 +191,14 @@ func NewTypedUnmanaged[request comparable](name string, mgr manager.Manager, opt
148191 return nil , fmt .Errorf ("must specify Name for Controller" )
149192 }
150193
151- if options .SkipNameValidation == nil {
152- options .SkipNameValidation = mgr .GetControllerOptions ().SkipNameValidation
153- }
154-
155194 if options .SkipNameValidation == nil || ! * options .SkipNameValidation {
156195 if err := checkName (name ); err != nil {
157196 return nil , err
158197 }
159198 }
160199
161200 if options .LogConstructor == nil {
162- log := mgr . GetLogger () .WithValues (
201+ log := options . Logger .WithValues (
163202 "controller" , name ,
164203 )
165204 options .LogConstructor = func (in * request ) logr.Logger {
@@ -175,23 +214,15 @@ func NewTypedUnmanaged[request comparable](name string, mgr manager.Manager, opt
175214 }
176215
177216 if options .MaxConcurrentReconciles <= 0 {
178- if mgr .GetControllerOptions ().MaxConcurrentReconciles > 0 {
179- options .MaxConcurrentReconciles = mgr .GetControllerOptions ().MaxConcurrentReconciles
180- } else {
181- options .MaxConcurrentReconciles = 1
182- }
217+ options .MaxConcurrentReconciles = 1
183218 }
184219
185220 if options .CacheSyncTimeout == 0 {
186- if mgr .GetControllerOptions ().CacheSyncTimeout != 0 {
187- options .CacheSyncTimeout = mgr .GetControllerOptions ().CacheSyncTimeout
188- } else {
189- options .CacheSyncTimeout = 2 * time .Minute
190- }
221+ options .CacheSyncTimeout = 2 * time .Minute
191222 }
192223
193224 if options .RateLimiter == nil {
194- if ptr .Deref (mgr . GetControllerOptions () .UsePriorityQueue , false ) {
225+ if ptr .Deref (options .UsePriorityQueue , false ) {
195226 options .RateLimiter = workqueue .NewTypedItemExponentialFailureRateLimiter [request ](5 * time .Millisecond , 1000 * time .Second )
196227 } else {
197228 options .RateLimiter = workqueue .DefaultTypedControllerRateLimiter [request ]()
@@ -200,9 +231,9 @@ func NewTypedUnmanaged[request comparable](name string, mgr manager.Manager, opt
200231
201232 if options .NewQueue == nil {
202233 options .NewQueue = func (controllerName string , rateLimiter workqueue.TypedRateLimiter [request ]) workqueue.TypedRateLimitingInterface [request ] {
203- if ptr .Deref (mgr . GetControllerOptions () .UsePriorityQueue , false ) {
234+ if ptr .Deref (options .UsePriorityQueue , false ) {
204235 return priorityqueue .New (controllerName , func (o * priorityqueue.Opts [request ]) {
205- o .Log = mgr . GetLogger () .WithValues ("controller" , controllerName )
236+ o .Log = options . Logger .WithValues ("controller" , controllerName )
206237 o .RateLimiter = rateLimiter
207238 })
208239 }
@@ -212,14 +243,6 @@ func NewTypedUnmanaged[request comparable](name string, mgr manager.Manager, opt
212243 }
213244 }
214245
215- if options .RecoverPanic == nil {
216- options .RecoverPanic = mgr .GetControllerOptions ().RecoverPanic
217- }
218-
219- if options .NeedLeaderElection == nil {
220- options .NeedLeaderElection = mgr .GetControllerOptions ().NeedLeaderElection
221- }
222-
223246 // Create controller with dependencies set
224247 return & controller.Controller [request ]{
225248 Do : options .Reconciler ,
0 commit comments