Skip to content

Commit 25ffade

Browse files
authored
Merge pull request #2199 from vincepri/manager-opts-refactor
⚠ Expose Manager.Cache/Client options, deprecate older opts
2 parents e2b265b + 0377e0f commit 25ffade

File tree

7 files changed

+140
-70
lines changed

7 files changed

+140
-70
lines changed

.golangci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ issues:
9292
text: Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked
9393
- linters:
9494
- staticcheck
95-
text: "SA1019: .* The component config package has been deprecated and will be removed in a future release."
95+
text: "SA1019: .*The component config package has been deprecated and will be removed in a future release."
9696
# With Go 1.16, the new embed directive can be used with an un-named import,
9797
# revive (previously, golint) only allows these to be imported in a main.go, which wouldn't work for us.
9898
# This directive allows the embed package to be imported with an underscore everywhere.

pkg/cache/cache.go

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import (
4141

4242
var (
4343
log = logf.RuntimeLog.WithName("object-cache")
44-
defaultResyncTime = 10 * time.Hour
44+
defaultSyncPeriod = 10 * time.Hour
4545
)
4646

4747
// Cache knows how to load Kubernetes objects, fetch informers to request
@@ -114,11 +114,32 @@ type Options struct {
114114
// Mapper is the RESTMapper to use for mapping GroupVersionKinds to Resources
115115
Mapper meta.RESTMapper
116116

117-
// ResyncEvery is the base frequency the informers are resynced.
118-
// Defaults to defaultResyncTime.
119-
// A 10 percent jitter will be added to the ResyncEvery period between informers
120-
// So that all informers will not send list requests simultaneously.
121-
ResyncEvery *time.Duration
117+
// SyncPeriod determines the minimum frequency at which watched resources are
118+
// reconciled. A lower period will correct entropy more quickly, but reduce
119+
// responsiveness to change if there are many watched resources. Change this
120+
// value only if you know what you are doing. Defaults to 10 hours if unset.
121+
// there will a 10 percent jitter between the SyncPeriod of all controllers
122+
// so that all controllers will not send list requests simultaneously.
123+
//
124+
// This applies to all controllers.
125+
//
126+
// A period sync happens for two reasons:
127+
// 1. To insure against a bug in the controller that causes an object to not
128+
// be requeued, when it otherwise should be requeued.
129+
// 2. To insure against an unknown bug in controller-runtime, or its dependencies,
130+
// that causes an object to not be requeued, when it otherwise should be
131+
// requeued, or to be removed from the queue, when it otherwise should not
132+
// be removed.
133+
//
134+
// If you want
135+
// 1. to insure against missed watch events, or
136+
// 2. to poll services that cannot be watched,
137+
// then we recommend that, instead of changing the default period, the
138+
// controller requeue, with a constant duration `t`, whenever the controller
139+
// is "done" with an object, and would otherwise not requeue it, i.e., we
140+
// recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`,
141+
// instead of `reconcile.Result{}`.
142+
SyncPeriod *time.Duration
122143

123144
// Namespaces restricts the cache's ListWatch to the desired namespaces
124145
// Default watches all namespaces
@@ -203,7 +224,7 @@ func New(config *rest.Config, opts Options) (Cache, error) {
203224
HTTPClient: opts.HTTPClient,
204225
Scheme: opts.Scheme,
205226
Mapper: opts.Mapper,
206-
ResyncPeriod: *opts.ResyncEvery,
227+
ResyncPeriod: *opts.SyncPeriod,
207228
Namespace: opts.Namespaces[0],
208229
ByGVK: byGVK,
209230
}),
@@ -243,7 +264,7 @@ func (options Options) inheritFrom(inherited Options) (*Options, error) {
243264
)
244265
combined.Scheme = combineScheme(inherited.Scheme, options.Scheme)
245266
combined.Mapper = selectMapper(inherited.Mapper, options.Mapper)
246-
combined.ResyncEvery = selectResync(inherited.ResyncEvery, options.ResyncEvery)
267+
combined.SyncPeriod = selectResync(inherited.SyncPeriod, options.SyncPeriod)
247268
combined.Namespaces = selectNamespaces(inherited.Namespaces, options.Namespaces)
248269
combined.DefaultLabelSelector = combineSelector(
249270
internal.Selector{Label: inherited.DefaultLabelSelector},
@@ -416,8 +437,8 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) {
416437
}
417438

418439
// Default the resync period to 10 hours if unset
419-
if opts.ResyncEvery == nil {
420-
opts.ResyncEvery = &defaultResyncTime
440+
if opts.SyncPeriod == nil {
441+
opts.SyncPeriod = &defaultSyncPeriod
421442
}
422443
return opts, nil
423444
}

pkg/cache/cache_unit_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,20 +92,20 @@ var _ = Describe("cache.inheritFrom", func() {
9292
})
9393
Context("Resync", func() {
9494
It("is nil when specified and inherited are unset", func() {
95-
Expect(checkError(specified.inheritFrom(inherited)).ResyncEvery).To(BeNil())
95+
Expect(checkError(specified.inheritFrom(inherited)).SyncPeriod).To(BeNil())
9696
})
9797
It("is unchanged when only specified is set", func() {
98-
specified.ResyncEvery = pointer.Duration(time.Second)
99-
Expect(checkError(specified.inheritFrom(inherited)).ResyncEvery).To(Equal(specified.ResyncEvery))
98+
specified.SyncPeriod = pointer.Duration(time.Second)
99+
Expect(checkError(specified.inheritFrom(inherited)).SyncPeriod).To(Equal(specified.SyncPeriod))
100100
})
101101
It("is inherited when only inherited is set", func() {
102-
inherited.ResyncEvery = pointer.Duration(time.Second)
103-
Expect(checkError(specified.inheritFrom(inherited)).ResyncEvery).To(Equal(inherited.ResyncEvery))
102+
inherited.SyncPeriod = pointer.Duration(time.Second)
103+
Expect(checkError(specified.inheritFrom(inherited)).SyncPeriod).To(Equal(inherited.SyncPeriod))
104104
})
105105
It("is unchanged when both inherited and specified are set", func() {
106-
specified.ResyncEvery = pointer.Duration(time.Second)
107-
inherited.ResyncEvery = pointer.Duration(time.Minute)
108-
Expect(checkError(specified.inheritFrom(inherited)).ResyncEvery).To(Equal(specified.ResyncEvery))
106+
specified.SyncPeriod = pointer.Duration(time.Second)
107+
inherited.SyncPeriod = pointer.Duration(time.Minute)
108+
Expect(checkError(specified.inheritFrom(inherited)).SyncPeriod).To(Equal(specified.SyncPeriod))
109109
})
110110
})
111111
Context("Namespace", func() {

pkg/cluster/cluster.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ type Options struct {
8383
Scheme *runtime.Scheme
8484

8585
// MapperProvider provides the rest mapper used to map go types to Kubernetes APIs
86-
//
87-
// Deprecated: Set Cache.Mapper and Client.Mapper directly instead.
8886
MapperProvider func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error)
8987

9088
// Logger is the logger that should be used by this Cluster.
@@ -210,8 +208,8 @@ func New(config *rest.Config, opts ...Option) (Cluster, error) {
210208
if cacheOpts.HTTPClient == nil {
211209
cacheOpts.HTTPClient = options.HTTPClient
212210
}
213-
if cacheOpts.ResyncEvery == nil {
214-
cacheOpts.ResyncEvery = options.SyncPeriod
211+
if cacheOpts.SyncPeriod == nil {
212+
cacheOpts.SyncPeriod = options.SyncPeriod
215213
}
216214
if len(cacheOpts.Namespaces) == 0 && options.Namespace != "" {
217215
cacheOpts.Namespaces = []string{options.Namespace}

pkg/manager/internal.go

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package manager
1818

1919
import (
2020
"context"
21-
"crypto/tls"
2221
"errors"
2322
"fmt"
2423
"net"
@@ -127,17 +126,6 @@ type controllerManager struct {
127126
// election was configured.
128127
elected chan struct{}
129128

130-
// port is the port that the webhook server serves at.
131-
port int
132-
// host is the hostname that the webhook server binds to.
133-
host string
134-
// CertDir is the directory that contains the server key and certificate.
135-
// if not set, webhook server would look up the server key and certificate in
136-
// {TempDir}/k8s-webhook-server/serving-certs
137-
certDir string
138-
// tlsOpts is used to allow configuring the TLS config used for the webhook server.
139-
tlsOpts []func(*tls.Config)
140-
141129
webhookServer *webhook.Server
142130
// webhookServerOnce will be called in GetWebhookServer() to optionally initialize
143131
// webhookServer if unset, and Add() it to controllerManager.
@@ -288,12 +276,7 @@ func (cm *controllerManager) GetAPIReader() client.Reader {
288276
func (cm *controllerManager) GetWebhookServer() *webhook.Server {
289277
cm.webhookServerOnce.Do(func() {
290278
if cm.webhookServer == nil {
291-
cm.webhookServer = &webhook.Server{
292-
Port: cm.port,
293-
Host: cm.host,
294-
CertDir: cm.certDir,
295-
TLSOpts: cm.tlsOpts,
296-
}
279+
panic("webhook should not be nil")
297280
}
298281
if err := cm.Add(cm.webhookServer); err != nil {
299282
panic(fmt.Sprintf("unable to add webhook server to the controller manager: %s", err))

pkg/manager/manager.go

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,45 @@ type Options struct {
100100
// Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources.
101101
// Defaults to the kubernetes/client-go scheme.Scheme, but it's almost always better
102102
// to pass your own scheme in. See the documentation in pkg/scheme for more information.
103+
//
104+
// If set, the Scheme will be used to create the default Client and Cache.
103105
Scheme *runtime.Scheme
104106

105-
// MapperProvider provides the rest mapper used to map go types to Kubernetes APIs
107+
// MapperProvider provides the rest mapper used to map go types to Kubernetes APIs.
108+
//
109+
// If set, the RESTMapper returned by this function is used to create the RESTMapper
110+
// used by the Client and Cache.
106111
MapperProvider func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error)
107112

113+
// Cache is the cache.Options that will be used to create the default Cache.
114+
// By default, the cache will watch and list requested objects in all namespaces.
115+
Cache cache.Options
116+
117+
// NewCache is the function that will create the cache to be used
118+
// by the manager. If not set this will use the default new cache function.
119+
//
120+
// When using a custom NewCache, the Cache options will be passed to the
121+
// NewCache function.
122+
//
123+
// NOTE: LOW LEVEL PRIMITIVE!
124+
// Only use a custom NewCache if you know what you are doing.
125+
NewCache cache.NewCacheFunc
126+
127+
// Client is the client.Options that will be used to create the default Client.
128+
// By default, the client will use the cache for reads and direct calls for writes.
129+
Client client.Options
130+
131+
// NewClient is the func that creates the client to be used by the manager.
132+
// If not set this will create a Client backed by a Cache for read operations
133+
// and a direct Client for write operations.
134+
//
135+
// When using a custom NewClient, the Client options will be passed to the
136+
// NewClient function.
137+
//
138+
// NOTE: LOW LEVEL PRIMITIVE!
139+
// Only use a custom NewClient if you know what you are doing.
140+
NewClient client.NewClientFunc
141+
108142
// SyncPeriod determines the minimum frequency at which watched resources are
109143
// reconciled. A lower period will correct entropy more quickly, but reduce
110144
// responsiveness to change if there are many watched resources. Change this
@@ -130,6 +164,8 @@ type Options struct {
130164
// is "done" with an object, and would otherwise not requeue it, i.e., we
131165
// recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`,
132166
// instead of `reconcile.Result{}`.
167+
//
168+
// Deprecated: Use Cache.SyncPeriod instead.
133169
SyncPeriod *time.Duration
134170

135171
// Logger is the logger that should be used by this manager.
@@ -215,6 +251,8 @@ type Options struct {
215251
// Note: If a namespace is specified, controllers can still Watch for a
216252
// cluster-scoped resource (e.g Node). For namespaced resources, the cache
217253
// will only hold objects from the desired namespace.
254+
//
255+
// Deprecated: Use Cache.Namespaces instead.
218256
Namespace string
219257

220258
// MetricsBindAddress is the TCP address that the controller should bind to
@@ -235,48 +273,49 @@ type Options struct {
235273

236274
// Port is the port that the webhook server serves at.
237275
// It is used to set webhook.Server.Port if WebhookServer is not set.
276+
//
277+
// Deprecated: Use WebhookServer.Port instead.
238278
Port int
239279
// Host is the hostname that the webhook server binds to.
240280
// It is used to set webhook.Server.Host if WebhookServer is not set.
281+
//
282+
// Deprecated: Use WebhookServer.Host instead.
241283
Host string
242284

243285
// CertDir is the directory that contains the server key and certificate.
244286
// If not set, webhook server would look up the server key and certificate in
245287
// {TempDir}/k8s-webhook-server/serving-certs. The server key and certificate
246288
// must be named tls.key and tls.crt, respectively.
247289
// It is used to set webhook.Server.CertDir if WebhookServer is not set.
290+
//
291+
// Deprecated: Use WebhookServer.CertDir instead.
248292
CertDir string
249293

250294
// TLSOpts is used to allow configuring the TLS config used for the webhook server.
295+
//
296+
// Deprecated: Use WebhookServer.TLSConfig instead.
251297
TLSOpts []func(*tls.Config)
252298

253299
// WebhookServer is an externally configured webhook.Server. By default,
254300
// a Manager will create a default server using Port, Host, and CertDir;
255301
// if this is set, the Manager will use this server instead.
256302
WebhookServer *webhook.Server
257303

258-
// Functions to allow for a user to customize values that will be injected.
259-
260-
// NewCache is the function that will create the cache to be used
261-
// by the manager. If not set this will use the default new cache function.
262-
NewCache cache.NewCacheFunc
263-
264-
// NewClient is the func that creates the client to be used by the manager.
265-
// If not set this will create a Client backed by a Cache for read operations
266-
// and a direct Client for write operations.
267-
NewClient client.NewClientFunc
268-
269304
// BaseContext is the function that provides Context values to Runnables
270305
// managed by the Manager. If a BaseContext function isn't provided, Runnables
271306
// will receive a new Background Context instead.
272307
BaseContext BaseContextFunc
273308

274309
// ClientDisableCacheFor tells the client that, if any cache is used, to bypass it
275310
// for the given objects.
311+
//
312+
// Deprecated: Use Client.Cache.DisableCacheFor instead.
276313
ClientDisableCacheFor []client.Object
277314

278315
// DryRunClient specifies whether the client should be configured to enforce
279316
// dryRun mode.
317+
//
318+
// Deprecated: Use Client.DryRun instead.
280319
DryRunClient bool
281320

282321
// EventBroadcaster records Events emitted by the manager and sends them to the Kubernetes API
@@ -348,12 +387,14 @@ func New(config *rest.Config, options Options) (Manager, error) {
348387

349388
cluster, err := cluster.New(config, func(clusterOptions *cluster.Options) {
350389
clusterOptions.Scheme = options.Scheme
351-
clusterOptions.MapperProvider = options.MapperProvider //nolint:staticcheck
390+
clusterOptions.MapperProvider = options.MapperProvider
352391
clusterOptions.Logger = options.Logger
353392
clusterOptions.SyncPeriod = options.SyncPeriod
354-
clusterOptions.Namespace = options.Namespace //nolint:staticcheck
355393
clusterOptions.NewCache = options.NewCache
356394
clusterOptions.NewClient = options.NewClient
395+
clusterOptions.Cache = options.Cache
396+
clusterOptions.Client = options.Client
397+
clusterOptions.Namespace = options.Namespace //nolint:staticcheck
357398
clusterOptions.ClientDisableCacheFor = options.ClientDisableCacheFor //nolint:staticcheck
358399
clusterOptions.DryRunClient = options.DryRunClient //nolint:staticcheck
359400
clusterOptions.EventBroadcaster = options.EventBroadcaster //nolint:staticcheck
@@ -432,10 +473,6 @@ func New(config *rest.Config, options Options) (Manager, error) {
432473
controllerConfig: options.Controller,
433474
logger: options.Logger,
434475
elected: make(chan struct{}),
435-
port: options.Port,
436-
host: options.Host,
437-
certDir: options.CertDir,
438-
tlsOpts: options.TLSOpts,
439476
webhookServer: options.WebhookServer,
440477
leaderElectionID: options.LeaderElectionID,
441478
leaseDuration: *options.LeaseDuration,
@@ -496,14 +533,19 @@ func (o Options) AndFrom(loader config.ControllerManagerConfiguration) (Options,
496533
if o.Port == 0 && newObj.Webhook.Port != nil {
497534
o.Port = *newObj.Webhook.Port
498535
}
499-
500536
if o.Host == "" && newObj.Webhook.Host != "" {
501537
o.Host = newObj.Webhook.Host
502538
}
503-
504539
if o.CertDir == "" && newObj.Webhook.CertDir != "" {
505540
o.CertDir = newObj.Webhook.CertDir
506541
}
542+
if o.WebhookServer == nil {
543+
o.WebhookServer = &webhook.Server{
544+
Port: o.Port,
545+
Host: o.Host,
546+
CertDir: o.CertDir,
547+
}
548+
}
507549

508550
if newObj.Controller != nil {
509551
if o.Controller.CacheSyncTimeout == 0 && newObj.Controller.CacheSyncTimeout != nil {
@@ -657,5 +699,14 @@ func setOptionsDefaults(options Options) Options {
657699
options.BaseContext = defaultBaseContext
658700
}
659701

702+
if options.WebhookServer == nil {
703+
options.WebhookServer = &webhook.Server{
704+
Host: options.Host,
705+
Port: options.Port,
706+
CertDir: options.CertDir,
707+
TLSOpts: options.TLSOpts,
708+
}
709+
}
710+
660711
return options
661712
}

0 commit comments

Comments
 (0)