@@ -21,17 +21,24 @@ import (
21
21
"fmt"
22
22
23
23
"github.com/fluxcd/pkg/runtime/conditions"
24
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25
+ "k8s.io/apimachinery/pkg/types"
24
26
ctrl "sigs.k8s.io/controller-runtime"
25
27
"sigs.k8s.io/controller-runtime/pkg/client"
26
28
"sigs.k8s.io/controller-runtime/pkg/handler"
27
29
"sigs.k8s.io/controller-runtime/pkg/reconcile"
28
30
31
+ "github.com/fluxcd/pkg/apis/meta"
29
32
"github.com/fluxcd/pkg/runtime/dependency"
30
33
sourcev1 "github.com/fluxcd/source-controller/api/v1"
31
34
32
35
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
33
36
)
34
37
38
+ const (
39
+ dependsOnIndexKey string = ".metadata.dependsOn"
40
+ )
41
+
35
42
func (r * KustomizationReconciler ) requestsForRevisionChangeOf (indexKey string ) handler.MapFunc {
36
43
return func (ctx context.Context , obj client.Object ) []reconcile.Request {
37
44
log := ctrl .LoggerFrom (ctx )
@@ -78,6 +85,53 @@ func (r *KustomizationReconciler) requestsForRevisionChangeOf(indexKey string) h
78
85
}
79
86
}
80
87
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
+
81
135
func (r * KustomizationReconciler ) indexBy (kind string ) func (o client.Object ) []string {
82
136
return func (o client.Object ) []string {
83
137
k , ok := o .(* kustomizev1.Kustomization )
@@ -96,3 +150,21 @@ func (r *KustomizationReconciler) indexBy(kind string) func(o client.Object) []s
96
150
return nil
97
151
}
98
152
}
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