@@ -191,14 +191,14 @@ func (r *MachineSyncReconciler) SetupWithManager(mgr ctrl.Manager) error {
191191
192192// Reconcile reconciles CAPI and MAPI machines for their respective namespaces.
193193//
194- //nolint:funlen
194+ //nolint:funlen,cyclop
195195func (r * MachineSyncReconciler ) Reconcile (ctx context.Context , req reconcile.Request ) (ctrl.Result , error ) {
196196 logger := logf .FromContext (ctx , "namespace" , req .Namespace , "name" , req .Name )
197197
198198 logger .V (1 ).Info ("Reconciling machine" )
199199 defer logger .V (1 ).Info ("Finished reconciling machine" )
200200
201- var mapiMachineNotFound , capiMachineNotFound bool
201+ var mapiMachineNotFound , capiMachineNotFound , capiInfraMachineExists bool
202202
203203 // Get the MAPI Machine.
204204 mapiMachine := & mapiv1beta1.Machine {}
@@ -254,12 +254,24 @@ func (r *MachineSyncReconciler) Reconcile(ctx context.Context, req reconcile.Req
254254 return ctrl.Result {}, nil
255255 }
256256
257+ // Check for existence of the Cluster API Infrastructure Machine or if it needs to get created from MAPI first.
258+ capiInfraMachineExists , err := r .doesCAPIInfraMachineExist (ctx , capiMachine , mapiMachine )
259+ if err != nil {
260+ return ctrl.Result {}, fmt .Errorf ("failed to check for existence of Cluster API infrastructure machine: %w" , err )
261+ }
262+
257263 authoritativeAPI := mapiMachine .Status .AuthoritativeAPI
258264
259265 switch {
260266 case authoritativeAPI == mapiv1beta1 .MachineAuthorityMachineAPI :
261267 return r .reconcileMAPIMachinetoCAPIMachine (ctx , mapiMachine , capiMachine )
262268 case authoritativeAPI == mapiv1beta1 .MachineAuthorityClusterAPI && ! capiMachineNotFound :
269+ // Create Cluster API Infrastructure Machine from MAPI if it doesn't exist
270+ // the CAPI machine is not marked for deletion and the MAPI machine was created before the Cluster API machine.
271+ if ! capiInfraMachineExists && capiMachine .DeletionTimestamp .IsZero () && ! mapiMachine .CreationTimestamp .After (capiMachine .CreationTimestamp .Time ) {
272+ return r .reconcileMAPIMachinetoCAPIMachine (ctx , mapiMachine , capiMachine )
273+ }
274+
263275 return r .reconcileCAPIMachinetoMAPIMachine (ctx , capiMachine , mapiMachine )
264276 case authoritativeAPI == mapiv1beta1 .MachineAuthorityClusterAPI && capiMachineNotFound :
265277 return r .reconcileMAPIMachinetoCAPIMachine (ctx , mapiMachine , capiMachine )
@@ -987,18 +999,14 @@ func (r *MachineSyncReconciler) fetchCAPIInfraResources(ctx context.Context, cap
987999 return nil , nil , nil
9881000 }
9891001
990- var infraCluster , infraMachine client.Object
1002+ var infraCluster client.Object
9911003
9921004 infraClusterKey := client.ObjectKey {
9931005 Namespace : capiMachine .Namespace ,
9941006 Name : capiMachine .Spec .ClusterName ,
9951007 }
9961008
9971009 infraMachineRef := capiMachine .Spec .InfrastructureRef
998- infraMachineKey := client.ObjectKey {
999- Namespace : infraMachineRef .Namespace ,
1000- Name : infraMachineRef .Name ,
1001- }
10021010
10031011 // Validate that required references are not empty to avoid nil pointer issues later.
10041012 // These are terminal configuration errors that require user intervention.
@@ -1012,7 +1020,7 @@ func (r *MachineSyncReconciler) fetchCAPIInfraResources(ctx context.Context, cap
10121020 capiMachine .Namespace , capiMachine .Name , errInvalidInfraMachineReference )
10131021 }
10141022
1015- infraMachine , infraCluster , err := controllers .InitInfraMachineAndInfraClusterFromProvider (r .Platform )
1023+ _ , infraCluster , err := controllers .InitInfraMachineAndInfraClusterFromProvider (r .Platform )
10161024 if err != nil {
10171025 return nil , nil , fmt .Errorf ("unable to devise Cluster API infra resources: %w" , err )
10181026 }
@@ -1021,13 +1029,50 @@ func (r *MachineSyncReconciler) fetchCAPIInfraResources(ctx context.Context, cap
10211029 return nil , nil , fmt .Errorf ("failed to get Cluster API infrastructure cluster: %w" , err )
10221030 }
10231031
1032+ infraMachine , err := r .fetchCAPIInfraMachine (ctx , infraMachineRef .Name , infraMachineRef .Namespace )
1033+ if err != nil {
1034+ return nil , nil , fmt .Errorf ("failed to fetch Cluster API infrastructure machine: %w" , err )
1035+ }
1036+
1037+ return infraCluster , infraMachine , nil
1038+ }
1039+
1040+ func (r * MachineSyncReconciler ) fetchCAPIInfraMachine (ctx context.Context , name , namespace string ) (client.Object , error ) {
1041+ infraMachine , _ , err := controllers .InitInfraMachineAndInfraClusterFromProvider (r .Platform )
1042+ if err != nil {
1043+ return nil , fmt .Errorf ("unable to devise Cluster API infra resources: %w" , err )
1044+ }
1045+
1046+ infraMachineKey := client.ObjectKey {
1047+ Namespace : namespace ,
1048+ Name : name ,
1049+ }
1050+
10241051 if err := r .Get (ctx , infraMachineKey , infraMachine ); err != nil && ! apierrors .IsNotFound (err ) {
1025- return nil , nil , fmt .Errorf ("failed to get Cluster API infrastructure machine : %w" , err )
1052+ return nil , fmt .Errorf ("failed to get: %w" , err )
10261053 } else if apierrors .IsNotFound (err ) {
10271054 infraMachine = nil
10281055 }
10291056
1030- return infraCluster , infraMachine , nil
1057+ return infraMachine , nil
1058+ }
1059+
1060+ // doesCAPIInfraMachineExist checks if the Cluster API Infrastructure Machine exists. It uses the infrastructureRef of the Cluster API Machine with fallback to the name of the MAPI Machine.
1061+ func (r * MachineSyncReconciler ) doesCAPIInfraMachineExist (ctx context.Context , capiMachine * clusterv1.Machine , mapiMachine * mapiv1beta1.Machine ) (bool , error ) {
1062+ namespace := r .CAPINamespace
1063+ name := mapiMachine .Name
1064+
1065+ if capiMachine != nil {
1066+ name = capiMachine .Spec .InfrastructureRef .Name
1067+ namespace = capiMachine .Spec .InfrastructureRef .Namespace
1068+ }
1069+
1070+ infraMachine , err := r .fetchCAPIInfraMachine (ctx , name , namespace )
1071+ if err != nil {
1072+ return false , fmt .Errorf ("checking existence: %w" , err )
1073+ }
1074+
1075+ return infraMachine != nil , nil
10311076}
10321077
10331078//nolint:funlen,gocognit,cyclop
0 commit comments