diff --git a/pkg/reconciler/reconciler.go b/pkg/reconciler/reconciler.go index 19f6deb..2b9e33c 100644 --- a/pkg/reconciler/reconciler.go +++ b/pkg/reconciler/reconciler.go @@ -42,6 +42,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/source" "github.com/joelanford/helm-operator/pkg/annotation" @@ -76,6 +77,7 @@ type Reconciler struct { chrt *chart.Chart overrideValues map[string]string skipDependentWatches bool + extraWatches []watchDescription maxConcurrentReconciles int reconcilePeriod time.Duration markFailedAfter time.Duration @@ -90,6 +92,12 @@ type Reconciler struct { uninstallAnnotations map[string]annotation.Uninstall } +type watchDescription struct { + src source.Source + predicates []predicate.Predicate + handler handler.EventHandler +} + // New creates a new Reconciler that reconciles custom resources that define a // Helm release. New takes variadic Option arguments that are used to configure // the Reconciler. @@ -463,6 +471,22 @@ func WithValueMapper(m values.Mapper) Option { } } +// WithExtraWatch is an Option that adds an extra event watch. +// Use this if you want your controller to respond to events other than coming from the primary custom resource, +// the helm release secret, or resources created by your helm chart. +// The meaning of the arguments is the same as for sigs.k8s.io/controller-runtime/pkg/controller.Controller Watch +// function. +func WithExtraWatch(src source.Source, handler handler.EventHandler, predicates ...predicate.Predicate) Option { + return func(r *Reconciler) error { + r.extraWatches = append(r.extraWatches, watchDescription{ + src: src, + predicates: predicates, + handler: handler, + }) + return nil + } +} + // Reconcile reconciles a CR that defines a Helm v3 release. // // - If a release does not exist for this CR, a new release is installed. @@ -953,6 +977,12 @@ func (r *Reconciler) setupWatches(mgr ctrl.Manager, c controller.Controller) err return err } + for _, w := range r.extraWatches { + if err := c.Watch(w.src, w.handler, w.predicates...); err != nil { + return err + } + } + if !r.skipDependentWatches { r.postHooks = append([]hook.PostHook{internalhook.NewDependentResourceWatcher(c, mgr.GetRESTMapper())}, r.postHooks...) }