@@ -40,9 +40,13 @@ import (
4040 kuberecorder "k8s.io/client-go/tools/record"
4141 "k8s.io/client-go/tools/reference"
4242 ctrl "sigs.k8s.io/controller-runtime"
43+ "sigs.k8s.io/controller-runtime/pkg/builder"
4344 "sigs.k8s.io/controller-runtime/pkg/client"
4445 "sigs.k8s.io/controller-runtime/pkg/controller"
4546 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
47+ "sigs.k8s.io/controller-runtime/pkg/handler"
48+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
49+ "sigs.k8s.io/controller-runtime/pkg/source"
4650
4751 "github.com/fluxcd/pkg/runtime/events"
4852 "github.com/fluxcd/pkg/runtime/metrics"
@@ -208,10 +212,28 @@ func (r *HelmChartReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, opts
208212 r .indexHelmRepositoryByURL ); err != nil {
209213 return fmt .Errorf ("failed setting index fields: %w" , err )
210214 }
215+ if err := mgr .GetCache ().IndexField (context .TODO (), & sourcev1.HelmChart {}, sourcev1 .SourceIndexKey ,
216+ r .indexHelmChartBySource ); err != nil {
217+ return fmt .Errorf ("failed setting index fields: %w" , err )
218+ }
211219
212220 return ctrl .NewControllerManagedBy (mgr ).
213- For (& sourcev1.HelmChart {}).
214- WithEventFilter (predicates.ChangePredicate {}).
221+ For (& sourcev1.HelmChart {}, builder .WithPredicates (predicates.ChangePredicate {})).
222+ Watches (
223+ & source.Kind {Type : & sourcev1.HelmRepository {}},
224+ & handler.EnqueueRequestsFromMapFunc {ToRequests : handler .ToRequestsFunc (r .requestsForHelmRepositoryChange )},
225+ builder .WithPredicates (SourceRevisionChangePredicate {}),
226+ ).
227+ Watches (
228+ & source.Kind {Type : & sourcev1.GitRepository {}},
229+ & handler.EnqueueRequestsFromMapFunc {ToRequests : handler .ToRequestsFunc (r .requestsForGitRepositoryChange )},
230+ builder .WithPredicates (SourceRevisionChangePredicate {}),
231+ ).
232+ Watches (
233+ & source.Kind {Type : & sourcev1.Bucket {}},
234+ & handler.EnqueueRequestsFromMapFunc {ToRequests : handler .ToRequestsFunc (r .requestsForBucketChange )},
235+ builder .WithPredicates (SourceRevisionChangePredicate {}),
236+ ).
215237 WithOptions (controller.Options {MaxConcurrentReconciles : opts .MaxConcurrentReconciles }).
216238 Complete (r )
217239}
@@ -726,6 +748,14 @@ func (r *HelmChartReconciler) indexHelmRepositoryByURL(o runtime.Object) []strin
726748 return nil
727749}
728750
751+ func (r * HelmChartReconciler ) indexHelmChartBySource (o runtime.Object ) []string {
752+ hc , ok := o .(* sourcev1.HelmChart )
753+ if ! ok {
754+ panic (fmt .Sprintf ("Expected a HelmChart, got %T" , o ))
755+ }
756+ return []string {fmt .Sprintf ("%s/%s" , hc .Spec .SourceRef .Kind , hc .Spec .SourceRef .Name )}
757+ }
758+
729759func (r * HelmChartReconciler ) resolveDependencyRepository (ctx context.Context , dep * helmchart.Dependency , namespace string ) (* sourcev1.HelmRepository , error ) {
730760 url := helm .NormalizeChartRepositoryURL (dep .Repository )
731761 if url == "" {
@@ -766,3 +796,84 @@ func (r *HelmChartReconciler) getHelmRepositorySecret(ctx context.Context, repos
766796
767797 return nil , nil
768798}
799+
800+ func (r * HelmChartReconciler ) requestsForHelmRepositoryChange (obj handler.MapObject ) []reconcile.Request {
801+ repo , ok := obj .Object .(* sourcev1.HelmRepository )
802+ if ! ok {
803+ panic (fmt .Sprintf ("Expected a HelmRepository, got %T" , repo ))
804+ }
805+ // If we do not have an artifact, we have no requests to make
806+ if repo .GetArtifact () == nil {
807+ return nil
808+ }
809+
810+ ctx := context .Background ()
811+ var list sourcev1.HelmRepositoryList
812+ if err := r .List (ctx , & list , client.MatchingFields {
813+ sourcev1 .SourceIndexKey : fmt .Sprintf ("%s/%s" , repo .Kind , repo .Name ),
814+ }); err != nil {
815+ r .Log .Error (err , "failed to list HelmCharts for HelmRepository" )
816+ return nil
817+ }
818+
819+ var reqs []reconcile.Request
820+ for _ , i := range list .Items {
821+ req := reconcile.Request {NamespacedName : types.NamespacedName {Namespace : i .GetNamespace (), Name : i .GetName ()}}
822+ reqs = append (reqs , req )
823+ }
824+ return reqs
825+ }
826+
827+ func (r * HelmChartReconciler ) requestsForGitRepositoryChange (obj handler.MapObject ) []reconcile.Request {
828+ repo , ok := obj .Object .(* sourcev1.GitRepository )
829+ if ! ok {
830+ panic (fmt .Sprintf ("Expected a GitRepository, got %T" , repo ))
831+ }
832+ // If we do not have an artifact, we have no requests to make
833+ if repo .GetArtifact () == nil {
834+ return nil
835+ }
836+
837+ ctx := context .Background ()
838+ var list sourcev1.HelmChartList
839+ if err := r .List (ctx , & list , client.MatchingFields {
840+ sourcev1 .SourceIndexKey : fmt .Sprintf ("%s/%s" , repo .Kind , repo .Name ),
841+ }); err != nil {
842+ r .Log .Error (err , "failed to list HelmCharts for GitRepository" )
843+ return nil
844+ }
845+
846+ var reqs []reconcile.Request
847+ for _ , i := range list .Items {
848+ req := reconcile.Request {NamespacedName : types.NamespacedName {Namespace : i .GetNamespace (), Name : i .GetName ()}}
849+ reqs = append (reqs , req )
850+ }
851+ return reqs
852+ }
853+
854+ func (r * HelmChartReconciler ) requestsForBucketChange (obj handler.MapObject ) []reconcile.Request {
855+ bucket , ok := obj .Object .(* sourcev1.Bucket )
856+ if ! ok {
857+ panic (fmt .Sprintf ("Expected a Bucket, got %T" , bucket ))
858+ }
859+ // If we do not have an artifact, we have no requests to make
860+ if bucket .GetArtifact () == nil {
861+ return nil
862+ }
863+
864+ ctx := context .Background ()
865+ var list sourcev1.HelmChartList
866+ if err := r .List (ctx , & list , client.MatchingFields {
867+ sourcev1 .SourceIndexKey : fmt .Sprintf ("%s/%s" , bucket .Kind , bucket .Name ),
868+ }); err != nil {
869+ r .Log .Error (err , "failed to list HelmCharts for Bucket" )
870+ return nil
871+ }
872+
873+ var reqs []reconcile.Request
874+ for _ , i := range list .Items {
875+ req := reconcile.Request {NamespacedName : types.NamespacedName {Namespace : i .GetNamespace (), Name : i .GetName ()}}
876+ reqs = append (reqs , req )
877+ }
878+ return reqs
879+ }
0 commit comments