@@ -21,17 +21,24 @@ import (
2121 "fmt"
2222
2323 "github.com/fluxcd/pkg/runtime/conditions"
24+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+ "k8s.io/apimachinery/pkg/types"
2426 ctrl "sigs.k8s.io/controller-runtime"
2527 "sigs.k8s.io/controller-runtime/pkg/client"
2628 "sigs.k8s.io/controller-runtime/pkg/handler"
2729 "sigs.k8s.io/controller-runtime/pkg/reconcile"
2830
31+ "github.com/fluxcd/pkg/apis/meta"
2932 "github.com/fluxcd/pkg/runtime/dependency"
3033 sourcev1 "github.com/fluxcd/source-controller/api/v1"
3134
3235 kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
3336)
3437
38+ const (
39+ dependsOnIndexKey string = ".metadata.dependsOn"
40+ )
41+
3542func (r * KustomizationReconciler ) requestsForRevisionChangeOf (indexKey string ) handler.MapFunc {
3643 return func (ctx context.Context , obj client.Object ) []reconcile.Request {
3744 log := ctrl .LoggerFrom (ctx )
@@ -78,6 +85,53 @@ func (r *KustomizationReconciler) requestsForRevisionChangeOf(indexKey string) h
7885 }
7986}
8087
88+ func isNotReadyForDependency (k * kustomizev1.Kustomization ) bool {
89+ c := conditions .Get (k , meta .ReadyCondition )
90+ if c == nil {
91+ return false
92+ }
93+ return c .Status == metav1 .ConditionFalse && c .Reason == meta .DependencyNotReadyReason
94+ }
95+
96+ func (r * KustomizationReconciler ) requestsForDependents (ctx context.Context , obj client.Object ) []reconcile.Request {
97+ log := ctrl .LoggerFrom (ctx )
98+
99+ var list kustomizev1.KustomizationList
100+ if err := r .List (ctx , & list , client.MatchingFields {
101+ dependsOnIndexKey : client .ObjectKeyFromObject (obj ).String (),
102+ }); err != nil {
103+ log .Error (err , "failed to list objects for dependency change" )
104+ return nil
105+ }
106+ var dd []dependency.Dependent
107+ for _ , d := range list .Items {
108+ if isNotReadyForDependency (& d ) {
109+ dd = append (dd , & d )
110+ }
111+ }
112+ sorted , err := dependency .Sort (dd )
113+ if err != nil {
114+ log .Error (err , "failed to sort dependents for dependency change" )
115+ return nil
116+ }
117+ reqs := make ([]reconcile.Request , 0 , len (sorted ))
118+ debugLog := log .V (1 ).WithValues ("dependency" , map [string ]string {
119+ "name" : obj .GetName (),
120+ "namespace" : obj .GetNamespace (),
121+ })
122+ for _ , d := range sorted {
123+ debugLog .Info ("requesting reconciliation of dependent" , "dependent" , map [string ]string {
124+ "name" : d .Name ,
125+ "namespace" : d .Namespace ,
126+ })
127+ reqs = append (reqs , reconcile.Request {NamespacedName : types.NamespacedName {
128+ Name : d .Name ,
129+ Namespace : d .Namespace ,
130+ }})
131+ }
132+ return reqs
133+ }
134+
81135func (r * KustomizationReconciler ) indexBy (kind string ) func (o client.Object ) []string {
82136 return func (o client.Object ) []string {
83137 k , ok := o .(* kustomizev1.Kustomization )
@@ -96,3 +150,21 @@ func (r *KustomizationReconciler) indexBy(kind string) func(o client.Object) []s
96150 return nil
97151 }
98152}
153+
154+ func (r * KustomizationReconciler ) indexDependsOn (o client.Object ) []string {
155+ k , ok := o .(* kustomizev1.Kustomization )
156+ if ! ok {
157+ panic (fmt .Sprintf ("Expected a Kustomization, got %T" , o ))
158+ }
159+
160+ deps := make ([]string , len (k .Spec .DependsOn ))
161+ for i , dep := range k .Spec .DependsOn {
162+ namespace := k .GetNamespace ()
163+ if dep .Namespace != "" {
164+ namespace = dep .Namespace
165+ }
166+ deps [i ] = fmt .Sprintf ("%s/%s" , namespace , dep .Name )
167+ }
168+
169+ return deps
170+ }
0 commit comments