@@ -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"
@@ -75,12 +78,23 @@ func (r *AWSMachineTemplateReconciler) SetupWithManager(ctx context.Context, mgr
7578 Watches (
7679 & clusterv1.MachineDeployment {},
7780 handler .EnqueueRequestsFromMapFunc (r .machineDeploymentToAWSMachineTemplate ),
81+ // Only emit events for creation to reconcile in case the MachineDeployment got created after the AWSMachineTemplate was reconciled.
82+ builder .WithPredicates (resourceCreatedPredicate ),
83+ ).
84+ Watches (
85+ & clusterv1.MachineSet {},
86+ handler .EnqueueRequestsFromMapFunc (r .machineSetToAWSMachineTemplate ),
87+ // Only emit events for creation to reconcile in case the MachineSet got created after the AWSMachineTemplate was reconciled.
88+ builder .WithPredicates (resourceCreatedPredicate ),
7889 )
7990
80- // Optionally watch KubeadmControlPlane if the CRD exists
91+ // Watch KubeadmControlPlane if they exist.
8192 if _ , err := mgr .GetRESTMapper ().RESTMapping (schema.GroupKind {Group : controlplanev1 .GroupVersion .Group , Kind : "KubeadmControlPlane" }, controlplanev1 .GroupVersion .Version ); err == nil {
8293 b = b .Watches (& controlplanev1.KubeadmControlPlane {},
83- handler .EnqueueRequestsFromMapFunc (r .kubeadmControlPlaneToAWSMachineTemplate ))
94+ handler .EnqueueRequestsFromMapFunc (r .kubeadmControlPlaneToAWSMachineTemplate ),
95+ // Only emit events for creation to reconcile in case the KubeadmControlPlane got created after the AWSMachineTemplate was reconciled.
96+ builder .WithPredicates (resourceCreatedPredicate ),
97+ )
8498 }
8599
86100 _ , err := b .Build (r )
@@ -95,7 +109,7 @@ func (r *AWSMachineTemplateReconciler) SetupWithManager(ctx context.Context, mgr
95109// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsmachinetemplates/status,verbs=get;update;patch
96110// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsclusters,verbs=get;list;watch
97111// +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
112+ // +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machinedeployments;machinesets ,verbs=get;list;watch
99113// +kubebuilder:rbac:groups="",resources=events,verbs=get;list;watch;create;update;patch
100114
101115// Reconcile populates capacity information for AWSMachineTemplate.
@@ -387,7 +401,22 @@ func (r *AWSMachineTemplateReconciler) getKubernetesVersion(ctx context.Context,
387401 return "" , errors .Wrap (err , "failed to get parent list options" )
388402 }
389403
390- // Try to find version from MachineDeployment first
404+ // Try to find version from MachineSet first
405+ machineSetList := & clusterv1.MachineSetList {}
406+ if err := r .List (ctx , machineSetList , listOpts ... ); err != nil {
407+ return "" , errors .Wrap (err , "failed to list MachineSets" )
408+ }
409+
410+ // Find MachineSets that reference this AWSMachineTemplate
411+ for _ , ms := range machineSetList .Items {
412+ if ms .Spec .Template .Spec .InfrastructureRef .Kind == awsMachineTemplateKind &&
413+ ms .Spec .Template .Spec .InfrastructureRef .Name == template .Name &&
414+ ms .Spec .Template .Spec .Version != "" {
415+ return ms .Spec .Template .Spec .Version , nil
416+ }
417+ }
418+
419+ // If not found, try MachineDeployment.
391420 machineDeploymentList := & clusterv1.MachineDeploymentList {}
392421 if err := r .List (ctx , machineDeploymentList , listOpts ... ); err != nil {
393422 return "" , errors .Wrap (err , "failed to list MachineDeployments" )
@@ -402,7 +431,7 @@ func (r *AWSMachineTemplateReconciler) getKubernetesVersion(ctx context.Context,
402431 }
403432 }
404433
405- // If not found in MachineDeployment , try KubeadmControlPlane
434+ // If not found, try KubeadmControlPlane
406435 kcpList := & controlplanev1.KubeadmControlPlaneList {}
407436 if err := r .List (ctx , kcpList , listOpts ... ); err != nil {
408437 return "" , errors .Wrap (err , "failed to list KubeadmControlPlanes" )
@@ -492,3 +521,35 @@ func (r *AWSMachineTemplateReconciler) machineDeploymentToAWSMachineTemplate(ctx
492521 },
493522 }
494523}
524+
525+ // machineSetToAWSMachineTemplate maps MachineSet to AWSMachineTemplate reconcile requests.
526+ // This enables the controller to reconcile AWSMachineTemplate when its owner MachineSet is created or updated,
527+ // ensuring that nodeInfo can be populated even if the cache hasn't synced yet.
528+ func (r * AWSMachineTemplateReconciler ) machineSetToAWSMachineTemplate (ctx context.Context , o client.Object ) []ctrl.Request {
529+ md , ok := o .(* clusterv1.MachineSet )
530+ if ! ok {
531+ return nil
532+ }
533+
534+ // Check if it references an AWSMachineTemplate
535+ if md .Spec .Template .Spec .InfrastructureRef .Kind != awsMachineTemplateKind {
536+ return nil
537+ }
538+
539+ // Return reconcile request for the referenced AWSMachineTemplate
540+ return []ctrl.Request {
541+ {
542+ NamespacedName : client.ObjectKey {
543+ Namespace : md .Namespace ,
544+ Name : md .Spec .Template .Spec .InfrastructureRef .Name ,
545+ },
546+ },
547+ }
548+ }
549+
550+ var resourceCreatedPredicate = predicate.Funcs {
551+ CreateFunc : func (e event.CreateEvent ) bool { return true },
552+ UpdateFunc : func (e event.UpdateEvent ) bool { return false },
553+ DeleteFunc : func (e event.DeleteEvent ) bool { return false },
554+ GenericFunc : func (e event.GenericEvent ) bool { return true },
555+ }
0 commit comments