@@ -26,6 +26,7 @@ import (
26
26
"k8s.io/klog/v2"
27
27
"k8s.io/utils/ptr"
28
28
29
+ "sigs.k8s.io/controller-runtime/pkg/config"
29
30
"sigs.k8s.io/controller-runtime/pkg/controller/priorityqueue"
30
31
"sigs.k8s.io/controller-runtime/pkg/internal/controller"
31
32
"sigs.k8s.io/controller-runtime/pkg/manager"
@@ -80,13 +81,53 @@ type TypedOptions[request comparable] struct {
80
81
// Only use a custom NewQueue if you know what you are doing.
81
82
NewQueue func (controllerName string , rateLimiter workqueue.TypedRateLimiter [request ]) workqueue.TypedRateLimitingInterface [request ]
82
83
84
+ // Logger will be used to build a default LogConstructor if unset.
85
+ Logger logr.Logger
86
+
83
87
// LogConstructor is used to construct a logger used for this controller and passed
84
88
// to each reconciliation via the context field.
85
89
LogConstructor func (request * request ) logr.Logger
90
+
91
+ // UsePriorityQueue configures the controllers queue to use the controller-runtime provided
92
+ // priority queue.
93
+ //
94
+ // Note: This flag is disabled by default until a future version. It's currently in beta.
95
+ UsePriorityQueue * bool
96
+ }
97
+
98
+ // DefaultFromConfig defaults the config from a config.Controller
99
+ func (options * TypedOptions [request ]) DefaultFromConfig (config config.Controller ) {
100
+ if options .Logger .GetSink () == nil {
101
+ options .Logger = config .Logger
102
+ }
103
+
104
+ if options .SkipNameValidation == nil {
105
+ options .SkipNameValidation = config .SkipNameValidation
106
+ }
107
+
108
+ if options .MaxConcurrentReconciles <= 0 && config .MaxConcurrentReconciles > 0 {
109
+ options .MaxConcurrentReconciles = config .MaxConcurrentReconciles
110
+ }
111
+
112
+ if options .CacheSyncTimeout == 0 && config .CacheSyncTimeout > 0 {
113
+ options .CacheSyncTimeout = config .CacheSyncTimeout
114
+ }
115
+
116
+ if options .UsePriorityQueue == nil {
117
+ options .UsePriorityQueue = config .UsePriorityQueue
118
+ }
119
+
120
+ if options .RecoverPanic == nil {
121
+ options .RecoverPanic = config .RecoverPanic
122
+ }
123
+
124
+ if options .NeedLeaderElection == nil {
125
+ options .NeedLeaderElection = config .NeedLeaderElection
126
+ }
86
127
}
87
128
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.
129
+ // Controller implements an API. A Controller manages a work queue fed reconcile.Requests
130
+ // from source.Sources. Work is performed through the reconcile.Reconciler for each enqueued item.
90
131
// Work typically is reads and writes Kubernetes objects to make the system state match the state specified
91
132
// in the object Spec.
92
133
type Controller = TypedController [reconcile.Request ]
@@ -119,7 +160,8 @@ func New(name string, mgr manager.Manager, options Options) (Controller, error)
119
160
//
120
161
// The name must be unique as it is used to identify the controller in metrics and logs.
121
162
func NewTyped [request comparable ](name string , mgr manager.Manager , options TypedOptions [request ]) (TypedController [request ], error ) {
122
- c , err := NewTypedUnmanaged (name , mgr , options )
163
+ options .DefaultFromConfig (mgr .GetControllerOptions ())
164
+ c , err := NewTypedUnmanaged (name , options )
123
165
if err != nil {
124
166
return nil , err
125
167
}
@@ -132,14 +174,14 @@ func NewTyped[request comparable](name string, mgr manager.Manager, options Type
132
174
// caller is responsible for starting the returned controller.
133
175
//
134
176
// 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 )
177
+ func NewUnmanaged (name string , options Options ) (Controller , error ) {
178
+ return NewTypedUnmanaged (name , options )
137
179
}
138
180
139
181
// NewTypedUnmanaged returns a new typed controller without adding it to the manager.
140
182
//
141
183
// 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 ) {
184
+ func NewTypedUnmanaged [request comparable ](name string , options TypedOptions [request ]) (TypedController [request ], error ) {
143
185
if options .Reconciler == nil {
144
186
return nil , fmt .Errorf ("must specify Reconciler" )
145
187
}
@@ -148,18 +190,14 @@ func NewTypedUnmanaged[request comparable](name string, mgr manager.Manager, opt
148
190
return nil , fmt .Errorf ("must specify Name for Controller" )
149
191
}
150
192
151
- if options .SkipNameValidation == nil {
152
- options .SkipNameValidation = mgr .GetControllerOptions ().SkipNameValidation
153
- }
154
-
155
193
if options .SkipNameValidation == nil || ! * options .SkipNameValidation {
156
194
if err := checkName (name ); err != nil {
157
195
return nil , err
158
196
}
159
197
}
160
198
161
199
if options .LogConstructor == nil {
162
- log := mgr . GetLogger () .WithValues (
200
+ log := options . Logger .WithValues (
163
201
"controller" , name ,
164
202
)
165
203
options .LogConstructor = func (in * request ) logr.Logger {
@@ -175,23 +213,15 @@ func NewTypedUnmanaged[request comparable](name string, mgr manager.Manager, opt
175
213
}
176
214
177
215
if options .MaxConcurrentReconciles <= 0 {
178
- if mgr .GetControllerOptions ().MaxConcurrentReconciles > 0 {
179
- options .MaxConcurrentReconciles = mgr .GetControllerOptions ().MaxConcurrentReconciles
180
- } else {
181
- options .MaxConcurrentReconciles = 1
182
- }
216
+ options .MaxConcurrentReconciles = 1
183
217
}
184
218
185
219
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
- }
220
+ options .CacheSyncTimeout = 2 * time .Minute
191
221
}
192
222
193
223
if options .RateLimiter == nil {
194
- if ptr .Deref (mgr . GetControllerOptions () .UsePriorityQueue , false ) {
224
+ if ptr .Deref (options .UsePriorityQueue , false ) {
195
225
options .RateLimiter = workqueue .NewTypedItemExponentialFailureRateLimiter [request ](5 * time .Millisecond , 1000 * time .Second )
196
226
} else {
197
227
options .RateLimiter = workqueue .DefaultTypedControllerRateLimiter [request ]()
@@ -200,9 +230,9 @@ func NewTypedUnmanaged[request comparable](name string, mgr manager.Manager, opt
200
230
201
231
if options .NewQueue == nil {
202
232
options .NewQueue = func (controllerName string , rateLimiter workqueue.TypedRateLimiter [request ]) workqueue.TypedRateLimitingInterface [request ] {
203
- if ptr .Deref (mgr . GetControllerOptions () .UsePriorityQueue , false ) {
233
+ if ptr .Deref (options .UsePriorityQueue , false ) {
204
234
return priorityqueue .New (controllerName , func (o * priorityqueue.Opts [request ]) {
205
- o .Log = mgr . GetLogger () .WithValues ("controller" , controllerName )
235
+ o .Log = options . Logger .WithValues ("controller" , controllerName )
206
236
o .RateLimiter = rateLimiter
207
237
})
208
238
}
@@ -212,14 +242,6 @@ func NewTypedUnmanaged[request comparable](name string, mgr manager.Manager, opt
212
242
}
213
243
}
214
244
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
-
223
245
// Create controller with dependencies set
224
246
return & controller.Controller [request ]{
225
247
Do : options .Reconciler ,
0 commit comments