@@ -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,23 @@ func (r *MachineSyncReconciler) Reconcile(ctx context.Context, req reconcile.Req
254254 return ctrl.Result {}, nil
255255 }
256256
257+ // Check for existense 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 and the MAPI machine was created before the Cluster API machine.
270+ if ! capiInfraMachineExists && (mapiMachine .CreationTimestamp .Equal (& capiMachine .CreationTimestamp ) || mapiMachine .CreationTimestamp .Before (& capiMachine .CreationTimestamp )) {
271+ return r .reconcileMAPIMachinetoCAPIMachine (ctx , mapiMachine , capiMachine )
272+ }
273+
263274 return r .reconcileCAPIMachinetoMAPIMachine (ctx , capiMachine , mapiMachine )
264275 case authoritativeAPI == mapiv1beta1 .MachineAuthorityClusterAPI && capiMachineNotFound :
265276 return r .reconcileMAPIMachinetoCAPIMachine (ctx , mapiMachine , capiMachine )
@@ -987,18 +998,14 @@ func (r *MachineSyncReconciler) fetchCAPIInfraResources(ctx context.Context, cap
987998 return nil , nil , nil
988999 }
9891000
990- var infraCluster , infraMachine client.Object
1001+ var infraCluster client.Object
9911002
9921003 infraClusterKey := client.ObjectKey {
9931004 Namespace : capiMachine .Namespace ,
9941005 Name : capiMachine .Spec .ClusterName ,
9951006 }
9961007
9971008 infraMachineRef := capiMachine .Spec .InfrastructureRef
998- infraMachineKey := client.ObjectKey {
999- Namespace : infraMachineRef .Namespace ,
1000- Name : infraMachineRef .Name ,
1001- }
10021009
10031010 // Validate that required references are not empty to avoid nil pointer issues later.
10041011 // These are terminal configuration errors that require user intervention.
@@ -1012,7 +1019,7 @@ func (r *MachineSyncReconciler) fetchCAPIInfraResources(ctx context.Context, cap
10121019 capiMachine .Namespace , capiMachine .Name , errInvalidInfraMachineReference )
10131020 }
10141021
1015- infraMachine , infraCluster , err := controllers .InitInfraMachineAndInfraClusterFromProvider (r .Platform )
1022+ _ , infraCluster , err := controllers .InitInfraMachineAndInfraClusterFromProvider (r .Platform )
10161023 if err != nil {
10171024 return nil , nil , fmt .Errorf ("unable to devise Cluster API infra resources: %w" , err )
10181025 }
@@ -1021,13 +1028,50 @@ func (r *MachineSyncReconciler) fetchCAPIInfraResources(ctx context.Context, cap
10211028 return nil , nil , fmt .Errorf ("failed to get Cluster API infrastructure cluster: %w" , err )
10221029 }
10231030
1031+ infraMachine , err := r .fetchCAPIInfraMachine (ctx , infraMachineRef .Name , infraMachineRef .Namespace )
1032+ if err != nil {
1033+ return nil , nil , fmt .Errorf ("failed to fetch Cluster API infrastructure machine: %w" , err )
1034+ }
1035+
1036+ return infraCluster , infraMachine , nil
1037+ }
1038+
1039+ func (r * MachineSyncReconciler ) fetchCAPIInfraMachine (ctx context.Context , name , namespace string ) (client.Object , error ) {
1040+ infraMachine , _ , err := controllers .InitInfraMachineAndInfraClusterFromProvider (r .Platform )
1041+ if err != nil {
1042+ return nil , fmt .Errorf ("unable to devise Cluster API infra resources: %w" , err )
1043+ }
1044+
1045+ infraMachineKey := client.ObjectKey {
1046+ Namespace : namespace ,
1047+ Name : name ,
1048+ }
1049+
10241050 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 )
1051+ return nil , fmt .Errorf ("failed to get: %w" , err )
10261052 } else if apierrors .IsNotFound (err ) {
10271053 infraMachine = nil
10281054 }
10291055
1030- return infraCluster , infraMachine , nil
1056+ return infraMachine , nil
1057+ }
1058+
1059+ // 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.
1060+ func (r * MachineSyncReconciler ) doesCAPIInfraMachineExist (ctx context.Context , capiMachine * clusterv1.Machine , mapiMachine * mapiv1beta1.Machine ) (bool , error ) {
1061+ namespace := r .CAPINamespace
1062+ name := mapiMachine .Name
1063+
1064+ if capiMachine != nil {
1065+ name = capiMachine .Spec .InfrastructureRef .Name
1066+ namespace = capiMachine .Spec .InfrastructureRef .Namespace
1067+ }
1068+
1069+ infraMachine , err := r .fetchCAPIInfraMachine (ctx , name , namespace )
1070+ if err != nil {
1071+ return false , fmt .Errorf ("checking existence: %w" , err )
1072+ }
1073+
1074+ return infraMachine != nil , nil
10311075}
10321076
10331077//nolint:funlen,gocognit,cyclop
0 commit comments