@@ -31,9 +31,12 @@ import (
3131 "k8s.io/apimachinery/pkg/runtime/schema"
3232 "k8s.io/utils/ptr"
3333 ctrl "sigs.k8s.io/controller-runtime"
34+ "sigs.k8s.io/controller-runtime/pkg/builder"
3435 "sigs.k8s.io/controller-runtime/pkg/client"
3536 "sigs.k8s.io/controller-runtime/pkg/controller"
37+ "sigs.k8s.io/controller-runtime/pkg/event"
3638 "sigs.k8s.io/controller-runtime/pkg/handler"
39+ "sigs.k8s.io/controller-runtime/pkg/predicate"
3740
3841 infrav1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
3942 ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/v2/controlplane/eks/api/v1beta2"
@@ -64,6 +67,13 @@ type AWSMachineTemplateReconciler struct {
6467 WatchFilterValue string
6568}
6669
70+ var resourceCreatedPredicate = predicate.Funcs {
71+ CreateFunc : func (e event.CreateEvent ) bool { return true },
72+ UpdateFunc : func (e event.UpdateEvent ) bool { return false },
73+ DeleteFunc : func (e event.DeleteEvent ) bool { return false },
74+ GenericFunc : func (e event.GenericEvent ) bool { return true },
75+ }
76+
6777// SetupWithManager sets up the controller with the Manager.
6878func (r * AWSMachineTemplateReconciler ) SetupWithManager (ctx context.Context , mgr ctrl.Manager , options controller.Options ) error {
6979 log := logger .FromContext (ctx )
@@ -75,12 +85,23 @@ func (r *AWSMachineTemplateReconciler) SetupWithManager(ctx context.Context, mgr
7585 Watches (
7686 & clusterv1.MachineDeployment {},
7787 handler .EnqueueRequestsFromMapFunc (r .machineDeploymentToAWSMachineTemplate ),
88+ // Only emit events for creation to reconcile in case the MachineDeployment got created after the AWSMachineTemplate was reconciled.
89+ builder .WithPredicates (resourceCreatedPredicate ),
90+ ).
91+ Watches (
92+ & clusterv1.MachineSet {},
93+ handler .EnqueueRequestsFromMapFunc (r .machineSetToAWSMachineTemplate ),
94+ // Only emit events for creation to reconcile in case the MachineSet got created after the AWSMachineTemplate was reconciled.
95+ builder .WithPredicates (resourceCreatedPredicate ),
7896 )
7997
80- // Optionally watch KubeadmControlPlane if the CRD exists
98+ // Watch KubeadmControlPlane if they exist.
8199 if _ , err := mgr .GetRESTMapper ().RESTMapping (schema.GroupKind {Group : controlplanev1 .GroupVersion .Group , Kind : "KubeadmControlPlane" }, controlplanev1 .GroupVersion .Version ); err == nil {
82100 b = b .Watches (& controlplanev1.KubeadmControlPlane {},
83- handler .EnqueueRequestsFromMapFunc (r .kubeadmControlPlaneToAWSMachineTemplate ))
101+ handler .EnqueueRequestsFromMapFunc (r .kubeadmControlPlaneToAWSMachineTemplate ),
102+ // Only emit events for creation to reconcile in case the KubeadmControlPlane got created after the AWSMachineTemplate was reconciled.
103+ builder .WithPredicates (resourceCreatedPredicate ),
104+ )
84105 }
85106
86107 _ , err := b .Build (r )
@@ -95,7 +116,7 @@ func (r *AWSMachineTemplateReconciler) SetupWithManager(ctx context.Context, mgr
95116// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsmachinetemplates/status,verbs=get;update;patch
96117// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsclusters,verbs=get;list;watch
97118// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters,verbs=get;list;watch
98- // +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machinedeployments,verbs=get;list;watch
119+ // +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machinedeployments;machinesets ,verbs=get;list;watch
99120// +kubebuilder:rbac:groups="",resources=events,verbs=get;list;watch;create;update;patch
100121
101122// Reconcile populates capacity information for AWSMachineTemplate.
@@ -387,7 +408,22 @@ func (r *AWSMachineTemplateReconciler) getKubernetesVersion(ctx context.Context,
387408 return "" , errors .Wrap (err , "failed to get parent list options" )
388409 }
389410
390- // Try to find version from MachineDeployment first
411+ // Try to find version from MachineSet first
412+ machineSetList := & clusterv1.MachineSetList {}
413+ if err := r .List (ctx , machineSetList , listOpts ... ); err != nil {
414+ return "" , errors .Wrap (err , "failed to list MachineSets" )
415+ }
416+
417+ // Find MachineSets that reference this AWSMachineTemplate
418+ for _ , ms := range machineSetList .Items {
419+ if ms .Spec .Template .Spec .InfrastructureRef .Kind == awsMachineTemplateKind &&
420+ ms .Spec .Template .Spec .InfrastructureRef .Name == template .Name &&
421+ ms .Spec .Template .Spec .Version != "" {
422+ return ms .Spec .Template .Spec .Version , nil
423+ }
424+ }
425+
426+ // If not found, try MachineDeployment.
391427 machineDeploymentList := & clusterv1.MachineDeploymentList {}
392428 if err := r .List (ctx , machineDeploymentList , listOpts ... ); err != nil {
393429 return "" , errors .Wrap (err , "failed to list MachineDeployments" )
@@ -402,7 +438,7 @@ func (r *AWSMachineTemplateReconciler) getKubernetesVersion(ctx context.Context,
402438 }
403439 }
404440
405- // If not found in MachineDeployment , try KubeadmControlPlane
441+ // If not found, try KubeadmControlPlane
406442 kcpList := & controlplanev1.KubeadmControlPlaneList {}
407443 if err := r .List (ctx , kcpList , listOpts ... ); err != nil {
408444 return "" , errors .Wrap (err , "failed to list KubeadmControlPlanes" )
@@ -492,3 +528,28 @@ func (r *AWSMachineTemplateReconciler) machineDeploymentToAWSMachineTemplate(ctx
492528 },
493529 }
494530}
531+
532+ // machineSetToAWSMachineTemplate maps MachineSet to AWSMachineTemplate reconcile requests.
533+ // This enables the controller to reconcile AWSMachineTemplate when its owner MachineSet is created or updated,
534+ // ensuring that nodeInfo can be populated even if the cache hasn't synced yet.
535+ func (r * AWSMachineTemplateReconciler ) machineSetToAWSMachineTemplate (ctx context.Context , o client.Object ) []ctrl.Request {
536+ md , ok := o .(* clusterv1.MachineSet )
537+ if ! ok {
538+ return nil
539+ }
540+
541+ // Check if it references an AWSMachineTemplate
542+ if md .Spec .Template .Spec .InfrastructureRef .Kind != awsMachineTemplateKind {
543+ return nil
544+ }
545+
546+ // Return reconcile request for the referenced AWSMachineTemplate
547+ return []ctrl.Request {
548+ {
549+ NamespacedName : client.ObjectKey {
550+ Namespace : md .Namespace ,
551+ Name : md .Spec .Template .Spec .InfrastructureRef .Name ,
552+ },
553+ },
554+ }
555+ }
0 commit comments