@@ -18,9 +18,7 @@ package controllers
18
18
19
19
import (
20
20
"context"
21
- "encoding/base64"
22
21
"fmt"
23
- "sort"
24
22
"time"
25
23
26
24
"github.com/pkg/errors"
@@ -51,10 +49,8 @@ import (
51
49
"sigs.k8s.io/cluster-api/util/predicates"
52
50
)
53
51
54
- var (
55
- // ErrSecretTypeNotSupported signals that a Secret is not supported.
56
- ErrSecretTypeNotSupported = errors .New ("unsupported secret type" )
57
- )
52
+ // ErrSecretTypeNotSupported signals that a Secret is not supported.
53
+ var ErrSecretTypeNotSupported = errors .New ("unsupported secret type" )
58
54
59
55
// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;patch
60
56
// +kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;patch
@@ -82,21 +78,20 @@ func (r *ClusterResourceSetReconciler) SetupWithManager(ctx context.Context, mgr
82
78
handler .EnqueueRequestsFromMapFunc (r .resourceToClusterResourceSet ),
83
79
builder .OnlyMetadata ,
84
80
builder .WithPredicates (
85
- resourcepredicates .ResourceCreate (ctrl .LoggerFrom (ctx )),
81
+ resourcepredicates .ResourceCreateOrUpdate (ctrl .LoggerFrom (ctx )),
86
82
),
87
83
).
88
84
Watches (
89
85
& source.Kind {Type : & corev1.Secret {}},
90
86
handler .EnqueueRequestsFromMapFunc (r .resourceToClusterResourceSet ),
91
87
builder .OnlyMetadata ,
92
88
builder .WithPredicates (
93
- resourcepredicates .ResourceCreate (ctrl .LoggerFrom (ctx )),
89
+ resourcepredicates .ResourceCreateOrUpdate (ctrl .LoggerFrom (ctx )),
94
90
),
95
91
).
96
92
WithOptions (options ).
97
93
WithEventFilter (predicates .ResourceNotPausedAndHasFilterLabel (ctrl .LoggerFrom (ctx ), r .WatchFilterValue )).
98
94
Complete (r )
99
-
100
95
if err != nil {
101
96
return errors .Wrap (err , "failed setting up with a controller manager" )
102
97
}
@@ -241,6 +236,8 @@ func (r *ClusterResourceSetReconciler) getClustersByClusterResourceSetSelector(c
241
236
// cluster's ClusterResourceSetBinding.
242
237
// In ApplyOnce strategy, resources are applied only once to a particular cluster. ClusterResourceSetBinding is used to check if a resource is applied before.
243
238
// It applies resources best effort and continue on scenarios like: unsupported resource types, failure during creation, missing resources.
239
+ // In Reconcile strategy, resources are re-applied to a particular cluster when their definition changes. The hash in ClusterResourceSetBinding is used to check
240
+ // if a resource has changed or not.
244
241
// TODO: If a resource already exists in the cluster but not applied by ClusterResourceSet, the resource will be updated ?
245
242
func (r * ClusterResourceSetReconciler ) ApplyClusterResourceSet (ctx context.Context , cluster * clusterv1.Cluster , clusterResourceSet * addonsv1.ClusterResourceSet ) error {
246
243
log := ctrl .LoggerFrom (ctx , "Cluster" , klog .KObj (cluster ))
@@ -301,8 +298,20 @@ func (r *ClusterResourceSetReconciler) ApplyClusterResourceSet(ctx context.Conte
301
298
errList = append (errList , err )
302
299
}
303
300
304
- // If resource is already applied successfully and clusterResourceSet mode is "ApplyOnce", continue. (No need to check hash changes here)
305
- if resourceSetBinding .IsApplied (resource ) {
301
+ resourceScope , err := reconcileScopeForResource (clusterResourceSet , resource , resourceSetBinding , unstructuredObj )
302
+ if err != nil {
303
+ resourceSetBinding .SetBinding (addonsv1.ResourceBinding {
304
+ ResourceRef : resource ,
305
+ Hash : "" ,
306
+ Applied : false ,
307
+ LastAppliedTime : & metav1.Time {Time : time .Now ().UTC ()},
308
+ })
309
+
310
+ errList = append (errList , err )
311
+ continue
312
+ }
313
+
314
+ if ! resourceScope .needsApply () {
306
315
continue
307
316
}
308
317
@@ -314,54 +323,20 @@ func (r *ClusterResourceSetReconciler) ApplyClusterResourceSet(ctx context.Conte
314
323
Applied : false ,
315
324
LastAppliedTime : & metav1.Time {Time : time .Now ().UTC ()},
316
325
})
317
- // Since maps are not ordered, we need to order them to get the same hash at each reconcile.
318
- keys := make ([]string , 0 )
319
- data , ok := unstructuredObj .UnstructuredContent ()["data" ]
320
- if ! ok {
321
- errList = append (errList , errors .New ("failed to get data field from the resource" ))
322
- continue
323
- }
324
-
325
- unstructuredData := data .(map [string ]interface {})
326
- for key := range unstructuredData {
327
- keys = append (keys , key )
328
- }
329
- sort .Strings (keys )
330
-
331
- dataList := make ([][]byte , 0 )
332
- for _ , key := range keys {
333
- val , ok , err := unstructured .NestedString (unstructuredData , key )
334
- if ! ok || err != nil {
335
- errList = append (errList , errors .New ("failed to get value field from the resource" ))
336
- continue
337
- }
338
-
339
- byteArr := []byte (val )
340
- // If the resource is a Secret, data needs to be decoded.
341
- if unstructuredObj .GetKind () == string (addonsv1 .SecretClusterResourceSetResourceKind ) {
342
- byteArr , _ = base64 .StdEncoding .DecodeString (val )
343
- }
344
-
345
- dataList = append (dataList , byteArr )
346
- }
347
326
348
327
// Apply all values in the key-value pair of the resource to the cluster.
349
328
// As there can be multiple key-value pairs in a resource, each value may have multiple objects in it.
350
329
isSuccessful := true
351
- for i := range dataList {
352
- data := dataList [i ]
353
-
354
- if err := apply (ctx , remoteClient , data ); err != nil {
355
- isSuccessful = false
356
- log .Error (err , "failed to apply ClusterResourceSet resource" , "Resource kind" , resource .Kind , "Resource name" , resource .Name )
357
- conditions .MarkFalse (clusterResourceSet , addonsv1 .ResourcesAppliedCondition , addonsv1 .ApplyFailedReason , clusterv1 .ConditionSeverityWarning , err .Error ())
358
- errList = append (errList , err )
359
- }
330
+ if err := resourceScope .apply (ctx , remoteClient ); err != nil {
331
+ isSuccessful = false
332
+ log .Error (err , "failed to apply ClusterResourceSet resource" , "Resource kind" , resource .Kind , "Resource name" , resource .Name )
333
+ conditions .MarkFalse (clusterResourceSet , addonsv1 .ResourcesAppliedCondition , addonsv1 .ApplyFailedReason , clusterv1 .ConditionSeverityWarning , err .Error ())
334
+ errList = append (errList , err )
360
335
}
361
336
362
337
resourceSetBinding .SetBinding (addonsv1.ResourceBinding {
363
338
ResourceRef : resource ,
364
- Hash : computeHash ( dataList ),
339
+ Hash : resourceScope . hash ( ),
365
340
Applied : isSuccessful ,
366
341
LastAppliedTime : & metav1.Time {Time : time .Now ().UTC ()},
367
342
})
0 commit comments