diff --git a/pkg/controller/certificatesigningrequests/controller.go b/pkg/controller/certificatesigningrequests/controller.go index d8f44f62f..ea9c6bc87 100644 --- a/pkg/controller/certificatesigningrequests/controller.go +++ b/pkg/controller/certificatesigningrequests/controller.go @@ -23,7 +23,6 @@ import ( "github.com/go-logr/logr" certificatesv1 "k8s.io/api/certificates/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime/schema" authzclient "k8s.io/client-go/kubernetes/typed/authorization/v1" certificatesclient "k8s.io/client-go/kubernetes/typed/certificates/v1" certificateslisters "k8s.io/client-go/listers/certificates/v1" @@ -50,6 +49,13 @@ type Signer interface { // context. type SignerConstructor func(*controllerpkg.Context) Signer +// RegisterExtraInformerFn is a function used by CertificateSigningRequest +// controller implementations to add custom workqueue functions based on +// informers not covered in the main shared controller implementation. +// The returned set of InformerSyncs will be waited on when the controller +// starts. +type RegisterExtraInformerFn func(*controllerpkg.Context, logr.Logger, workqueue.RateLimitingInterface) ([]cache.InformerSynced, error) + // Controller is a base Kubernetes CertificateSigningRequest controller. It is // responsible for orchestrating and performing shared operations that all // CertificateSigningRequest controllers do, before passing the @@ -81,9 +87,9 @@ type Controller struct { // the signer kind to react to when a certificate signing request is synced signerType string - // extraInformerResources are the set of resources which should cause - // reconciles if owned by a CertifcateRequest. - extraInformerResources []schema.GroupVersionResource + //registerExtraInformers is a list of functions that + //CertificateSigningRequest controllers can use to register custom informers. + registerExtraInformers []RegisterExtraInformerFn // used for testing clock clock.Clock @@ -91,20 +97,19 @@ type Controller struct { // New will construct a new certificatesigningrequest controller using the // given Signer implementation. -// Note: the extraInformers passed here will be 'waited' for when starting to -// ensure their corresponding listers have synced. -// An event handler will then be set on these informers that automatically -// resyncs CertificateSigningRequest resources that 'own' the objects in the -// informer. -// It's the callers responsibility to ensure the Run function on the informer -// is called in order to start the reflector. This is handled automatically -// when the informer factory's Start method is called, if the given informer -// was obtained using a SharedInformerFactory. -func New(signerType string, signerConstructor SignerConstructor, extraInformerResources ...schema.GroupVersionResource) *Controller { +// Note: the registerExtraInfromers passed here will be 'waited' for when +// starting to ensure their corresponding listers have synced. +// The caller is responsible for ensuring the informer work functions are setup +// correctly on any informer. +// It's also the callers responsibility to ensure the Run function on the +// informer is called in order to start the reflector. This is handled +// automatically when the informer factory's Start method is called, if the +// given informer was obtained using a SharedInformerFactory. +func New(signerType string, signerConstructor SignerConstructor, registerExtraInformers ...RegisterExtraInformerFn) *Controller { return &Controller{ signerType: signerType, signerConstructor: signerConstructor, - extraInformerResources: extraInformerResources, + registerExtraInformers: registerExtraInformers, } } @@ -125,27 +130,21 @@ func (c *Controller) Register(ctx *controllerpkg.Context) (workqueue.RateLimitin // obtain references to all the informers used by this controller csrInformer := ctx.KubeSharedInformerFactory.Certificates().V1().CertificateSigningRequests() - // build a list of InformerSynced functions that will be returned by the Register method. - // the controller will only begin processing items once all of these informers have synced. + // build a list of InformerSynced functions that will be returned by the + // Register method. The controller will only begin processing items once all + // of these informers have synced. + mustSync := []cache.InformerSynced{ csrInformer.Informer().HasSynced, issuerInformer.Informer().HasSynced, } - // Ensure we also catch all extra informers for this - // CertificateSigningRequest controller instance. - var extraInformers []cache.SharedIndexInformer - for _, i := range c.extraInformerResources { - // TODO (joshvanl): currently we only have an extra informer for - // cert-manager Orders. If extended to other informer factory sets, add a - // switch statement here for the group so that the correct shared informer - // can be selected. - extraInformer, err := ctx.SharedInformerFactory.ForResource(i) + for _, reg := range c.registerExtraInformers { + ms, err := reg(ctx, c.log, c.queue) if err != nil { - return nil, nil, fmt.Errorf("failed to get extra informer for %v: %w", i, err) + return nil, nil, fmt.Errorf("failed to register extra informer: %w", err) } - extraInformers = append(extraInformers, extraInformer.Informer()) - mustSync = append(mustSync, extraInformer.Informer().HasSynced) + mustSync = append(mustSync, ms...) } // if scoped to a single namespace @@ -165,17 +164,6 @@ func (c *Controller) Register(ctx *controllerpkg.Context) (workqueue.RateLimitin csrInformer.Informer().AddEventHandler(&controllerpkg.QueuingEventHandler{Queue: c.queue}) issuerInformer.Informer().AddEventHandler(&controllerpkg.BlockingEventHandler{WorkFunc: c.handleGenericIssuer}) - // Ensure we catch extra informers that are owned by certificate signing requests - for _, i := range extraInformers { - i.AddEventHandler(&controllerpkg.BlockingEventHandler{ - WorkFunc: controllerpkg.HandleOwnedResourceNamespacedFunc(c.log, c.queue, - schema.GroupVersionKind{Version: "v1", Group: "certificates.k8s.io", Kind: "CertificateSigningRequest"}, - func(_, name string) (interface{}, error) { - return c.csrLister.Get(name) - }), - }) - } - // create an issuer helper for reading generic issuers c.helper = issuer.NewHelper(issuerInformer.Lister(), clusterIssuerInformer.Lister())