@@ -19,19 +19,17 @@ package controllers
1919import (
2020 "context"
2121 "fmt"
22- "reflect"
2322 "time"
2423
2524 "github.com/pkg/errors"
2625 corev1 "k8s.io/api/core/v1"
2726 apierrors "k8s.io/apimachinery/pkg/api/errors"
28- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2927 "k8s.io/apimachinery/pkg/runtime"
30- "k8s.io/apimachinery/pkg/runtime/schema"
3128 kerrors "k8s.io/apimachinery/pkg/util/errors"
3229 "k8s.io/client-go/tools/record"
30+ "k8s.io/utils/ptr"
3331 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
34- kubeadmv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1 "
32+ "sigs.k8s.io/cluster-api/controllers/external "
3533 expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
3634 "sigs.k8s.io/cluster-api/util"
3735 "sigs.k8s.io/cluster-api/util/annotations"
@@ -41,7 +39,6 @@ import (
4139 "sigs.k8s.io/controller-runtime/pkg/client"
4240 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
4341 "sigs.k8s.io/controller-runtime/pkg/handler"
44- "sigs.k8s.io/controller-runtime/pkg/predicate"
4542 "sigs.k8s.io/controller-runtime/pkg/reconcile"
4643
4744 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
6360 Timeouts reconciler.Timeouts
6461 WatchFilterValue string
6562 createAzureMachinePoolService azureMachinePoolServiceCreator
66- BootstrapConfigGVK schema. GroupVersionKind
63+ externalTracker external. ObjectTracker
6764 CredentialCache azure.CredentialCache
6865 }
6966
@@ -77,21 +74,13 @@ type (
7774type azureMachinePoolServiceCreator func (machinePoolScope * scope.MachinePoolScope ) (* azureMachinePoolService , error )
7875
7976// NewAzureMachinePoolReconciler returns a new AzureMachinePoolReconciler instance.
80- func NewAzureMachinePoolReconciler (client client.Client , recorder record.EventRecorder , timeouts reconciler.Timeouts , watchFilterValue , bootstrapConfigGVK string , credCache azure.CredentialCache ) * AzureMachinePoolReconciler {
81- gvk := schema .FromAPIVersionAndKind (kubeadmv1 .GroupVersion .String (), reflect .TypeOf ((* kubeadmv1 .KubeadmConfig )(nil )).Elem ().Name ())
82- userGVK , _ := schema .ParseKindArg (bootstrapConfigGVK )
83-
84- if userGVK != nil {
85- gvk = * userGVK
86- }
87-
77+ func NewAzureMachinePoolReconciler (client client.Client , recorder record.EventRecorder , timeouts reconciler.Timeouts , watchFilterValue string , credCache azure.CredentialCache ) * AzureMachinePoolReconciler {
8878 ampr := & AzureMachinePoolReconciler {
89- Client : client ,
90- Recorder : recorder ,
91- Timeouts : timeouts ,
92- WatchFilterValue : watchFilterValue ,
93- BootstrapConfigGVK : gvk ,
94- CredentialCache : credCache ,
79+ Client : client ,
80+ Recorder : recorder ,
81+ Timeouts : timeouts ,
82+ WatchFilterValue : watchFilterValue ,
83+ CredentialCache : credCache ,
9584 }
9685
9786 ampr .createAzureMachinePoolService = newAzureMachinePoolService
@@ -127,9 +116,7 @@ func (ampr *AzureMachinePoolReconciler) SetupWithManager(ctx context.Context, mg
127116 return errors .Wrap (err , "failed to create mapper for Cluster to AzureMachines" )
128117 }
129118
130- config := & metav1.PartialObjectMetadata {}
131- config .SetGroupVersionKind (ampr .BootstrapConfigGVK )
132- return ctrl .NewControllerManagedBy (mgr ).
119+ controller , err := ctrl .NewControllerManagedBy (mgr ).
133120 WithOptions (options .Options ).
134121 For (& infrav1exp.AzureMachinePool {}).
135122 WithEventFilter (predicates .ResourceHasFilterLabel (mgr .GetScheme (), log , ampr .WatchFilterValue )).
@@ -148,12 +135,6 @@ func (ampr *AzureMachinePoolReconciler) SetupWithManager(ctx context.Context, mg
148135 & infrav1.AzureManagedControlPlane {},
149136 handler .EnqueueRequestsFromMapFunc (azureManagedControlPlaneMapper ),
150137 ).
151- // watch for changes in KubeadmConfig (or any BootstrapConfig) to sync bootstrap token
152- Watches (
153- config ,
154- handler .EnqueueRequestsFromMapFunc (BootstrapConfigToInfrastructureMapFunc (ctx , ampr .Client , log )),
155- builder .WithPredicates (predicate.ResourceVersionChangedPredicate {}),
156- ).
157138 Watches (
158139 & infrav1exp.AzureMachinePoolMachine {},
159140 handler .EnqueueRequestsFromMapFunc (AzureMachinePoolMachineMapper (mgr .GetScheme (), log )),
@@ -170,13 +151,25 @@ func (ampr *AzureMachinePoolReconciler) SetupWithManager(ctx context.Context, mg
170151 infracontroller .ClusterPauseChangeAndInfrastructureReady (mgr .GetScheme (), log ),
171152 predicates .ResourceHasFilterLabel (mgr .GetScheme (), log , ampr .WatchFilterValue ),
172153 ),
173- ).
174- Complete (r )
154+ ).Build (r )
155+ if err != nil {
156+ return fmt .Errorf ("creating new controller manager: %w" , err )
157+ }
158+
159+ predicateLog := ptr .To (ctrl .LoggerFrom (ctx ).WithValues ("controller" , "azuremachinepool" ))
160+ ampr .externalTracker = external.ObjectTracker {
161+ Controller : controller ,
162+ Cache : mgr .GetCache (),
163+ Scheme : mgr .GetScheme (),
164+ PredicateLogger : predicateLog ,
165+ }
166+
167+ return nil
175168}
176169
177170// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=azuremachinepools,verbs=get;list;watch;create;update;patch;delete
178171// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=azuremachinepools/status,verbs=get;update;patch
179- // +kubebuilder:rbac:groups=bootstrap.cluster.x-k8s.io,resources=kubeadmconfigs;kubeadmconfigs/status ,verbs=get;list;watch
172+ // +kubebuilder:rbac:groups=bootstrap.cluster.x-k8s.io,resources=* ,verbs=get;list;watch
180173// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=azuremachinepoolmachines,verbs=get;list;watch;create;update;patch;delete
181174// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=azuremachinepoolmachines/status,verbs=get
182175// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machinepools;machinepools/status,verbs=get;list;watch;update;patch
@@ -295,6 +288,27 @@ func (ampr *AzureMachinePoolReconciler) reconcileNormal(ctx context.Context, mac
295288 return reconcile.Result {}, nil
296289 }
297290
291+ // Add a Watch to the referenced Bootstrap Config
292+ if machinePoolScope .MachinePool .Spec .Template .Spec .Bootstrap .ConfigRef != nil {
293+ ref := machinePoolScope .MachinePool .Spec .Template .Spec .Bootstrap .ConfigRef
294+ obj , err := external .Get (ctx , ampr .Client , ref )
295+ if err != nil {
296+ if apierrors .IsNotFound (errors .Cause (err )) {
297+ return reconcile.Result {}, errors .Wrapf (err , "could not find %v %q for MachinePool %q in namespace %q, requeuing while searching for bootstrap ConfigRef" ,
298+ ref .GroupVersionKind (), ref .Name , machinePoolScope .MachinePool .Name , ref .Namespace )
299+ }
300+ return reconcile.Result {}, err
301+ }
302+
303+ // Ensure we add a watch to the external object, if there isn't one already.
304+ if err := ampr .externalTracker .Watch (log , obj ,
305+ handler .EnqueueRequestsFromMapFunc (BootstrapConfigToInfrastructureMapFunc (ampr .Client , * ampr .externalTracker .PredicateLogger )),
306+ predicates .ResourceIsChanged (ampr .Client .Scheme (), * ampr .externalTracker .PredicateLogger )); err != nil {
307+ return reconcile.Result {}, errors .Wrapf (err , "could not add a watcher to the object %v %q for MachinePool %q in namespace %q, requeuing" ,
308+ ref .GroupVersionKind (), ref .Name , machinePoolScope .MachinePool .Name , ref .Namespace )
309+ }
310+ }
311+
298312 // Make sure bootstrap data is available and populated.
299313 if machinePoolScope .MachinePool .Spec .Template .Spec .Bootstrap .DataSecretName == nil {
300314 log .Info ("Bootstrap data secret reference is not yet available" )
0 commit comments