diff --git a/internal/controllers/machine/machine_controller_phases.go b/internal/controllers/machine/machine_controller_phases.go index f7e1c8916194..daf4d72d9279 100644 --- a/internal/controllers/machine/machine_controller_phases.go +++ b/internal/controllers/machine/machine_controller_phases.go @@ -156,6 +156,20 @@ func (r *Reconciler) ensureExternalOwnershipAndWatch(ctx context.Context, cluste return obj, nil } +// checkMachineBootstrapReady checks if the bootstrap data for a Machine is +// available and marks it as ready if so. +func checkMachineBootstrapReady(m *clusterv1.Machine) bool { + if m.Spec.Bootstrap.DataSecretName != nil { + if m.Status.Initialization == nil { + m.Status.Initialization = &clusterv1.MachineInitializationStatus{} + } + m.Status.Initialization.BootstrapDataSecretCreated = true + v1beta1conditions.MarkTrue(m, clusterv1.BootstrapReadyV1Beta1Condition) + return true + } + return false +} + // reconcileBootstrap reconciles the BootstrapConfig of a Machine. func (r *Reconciler) reconcileBootstrap(ctx context.Context, s *scope) (ctrl.Result, error) { log := ctrl.LoggerFrom(ctx) @@ -164,6 +178,8 @@ func (r *Reconciler) reconcileBootstrap(ctx context.Context, s *scope) (ctrl.Res // If the Bootstrap ref is nil (and so the machine should use user generated data secret), return. if m.Spec.Bootstrap.ConfigRef == nil { + // If the bootstrap data is populated, set ready. + _ = checkMachineBootstrapReady(m) return ctrl.Result{}, nil } @@ -187,12 +203,7 @@ func (r *Reconciler) reconcileBootstrap(ctx context.Context, s *scope) (ctrl.Res s.bootstrapConfig = obj // If the bootstrap data is populated, set ready and return. - if m.Spec.Bootstrap.DataSecretName != nil { - if m.Status.Initialization == nil { - m.Status.Initialization = &clusterv1.MachineInitializationStatus{} - } - m.Status.Initialization.BootstrapDataSecretCreated = true - v1beta1conditions.MarkTrue(m, clusterv1.BootstrapReadyV1Beta1Condition) + if checkMachineBootstrapReady(m) { return ctrl.Result{}, nil } diff --git a/internal/controllers/machine/machine_controller_phases_test.go b/internal/controllers/machine/machine_controller_phases_test.go index e8c7f23ed330..be11e79808dd 100644 --- a/internal/controllers/machine/machine_controller_phases_test.go +++ b/internal/controllers/machine/machine_controller_phases_test.go @@ -112,6 +112,33 @@ func TestReconcileBootstrap(t *testing.T) { g.Expect(m.Status.Initialization != nil && m.Status.Initialization.BootstrapDataSecretCreated).To(BeFalse()) }, }, + { + name: "bootstrap data ready with no bootstrap config", + contract: "v1beta1", + machine: &clusterv1.Machine{ + ObjectMeta: metav1.ObjectMeta{ + Name: "bootstrap-test-external", + Namespace: metav1.NamespaceDefault, + }, + Spec: clusterv1.MachineSpec{ + Bootstrap: clusterv1.Bootstrap{ + DataSecretName: ptr.To("secret-data"), + }, + }, + Status: clusterv1.MachineStatus{ + Initialization: nil, + }, + }, + bootstrapConfig: nil, + bootstrapConfigGetError: errors.New("this should not happen"), + expectResult: ctrl.Result{}, + expectError: false, + expected: func(g *WithT, m *clusterv1.Machine) { + g.Expect(m.Status.Initialization != nil && m.Status.Initialization.BootstrapDataSecretCreated).To(BeTrue()) + g.Expect(m.Spec.Bootstrap.DataSecretName).NotTo(BeNil()) + g.Expect(*m.Spec.Bootstrap.DataSecretName).To(Equal("secret-data")) + }, + }, { name: "bootstrap config not ready, it should reconcile but no data should surface on the machine", contract: "v1beta1",