Skip to content

Commit 58a7df0

Browse files
authored
Merge pull request #8667 from Jont828/machinepool-bootstrap-rollout
🐛 Update MachinePool bootstrap dataSecretName when bootstrap config changes
2 parents 1f69d07 + 1e4d365 commit 58a7df0

File tree

2 files changed

+82
-38
lines changed

2 files changed

+82
-38
lines changed

exp/internal/controllers/machinepool_controller_phases.go

+37-33
Original file line numberDiff line numberDiff line change
@@ -197,48 +197,52 @@ func (r *MachinePoolReconciler) reconcileBootstrap(ctx context.Context, cluster
197197
return ctrl.Result{}, nil
198198
}
199199
bootstrapConfig = bootstrapReconcileResult.Result
200-
}
201200

202-
// If the bootstrap data secret is populated, set ready and return.
203-
if m.Spec.Template.Spec.Bootstrap.DataSecretName != nil {
204-
m.Status.BootstrapReady = true
205-
conditions.MarkTrue(m, clusterv1.BootstrapReadyCondition)
206-
return ctrl.Result{}, nil
207-
}
201+
// If the bootstrap config is being deleted, return early.
202+
if !bootstrapConfig.GetDeletionTimestamp().IsZero() {
203+
return ctrl.Result{}, nil
204+
}
208205

209-
// If the bootstrap config is being deleted, return early.
210-
if !bootstrapConfig.GetDeletionTimestamp().IsZero() {
211-
return ctrl.Result{}, nil
212-
}
206+
// Determine if the bootstrap provider is ready.
207+
ready, err := external.IsReady(bootstrapConfig)
208+
if err != nil {
209+
return ctrl.Result{}, err
210+
}
213211

214-
// Determine if the bootstrap provider is ready.
215-
ready, err := external.IsReady(bootstrapConfig)
216-
if err != nil {
217-
return ctrl.Result{}, err
218-
}
212+
// Report a summary of current status of the bootstrap object defined for this machine pool.
213+
conditions.SetMirror(m, clusterv1.BootstrapReadyCondition,
214+
conditions.UnstructuredGetter(bootstrapConfig),
215+
conditions.WithFallbackValue(ready, clusterv1.WaitingForDataSecretFallbackReason, clusterv1.ConditionSeverityInfo, ""),
216+
)
219217

220-
// Report a summary of current status of the bootstrap object defined for this machine pool.
221-
conditions.SetMirror(m, clusterv1.BootstrapReadyCondition,
222-
conditions.UnstructuredGetter(bootstrapConfig),
223-
conditions.WithFallbackValue(ready, clusterv1.WaitingForDataSecretFallbackReason, clusterv1.ConditionSeverityInfo, ""),
224-
)
218+
if !ready {
219+
log.V(2).Info("Bootstrap provider is not ready, requeuing")
220+
m.Status.BootstrapReady = ready
221+
return ctrl.Result{RequeueAfter: externalReadyWait}, nil
222+
}
225223

226-
if !ready {
227-
log.V(2).Info("Bootstrap provider is not ready, requeuing")
228-
return ctrl.Result{RequeueAfter: externalReadyWait}, nil
224+
// Get and set the name of the secret containing the bootstrap data.
225+
secretName, _, err := unstructured.NestedString(bootstrapConfig.Object, "status", "dataSecretName")
226+
if err != nil {
227+
return ctrl.Result{}, errors.Wrapf(err, "failed to retrieve dataSecretName from bootstrap provider for MachinePool %q in namespace %q", m.Name, m.Namespace)
228+
} else if secretName == "" {
229+
return ctrl.Result{}, errors.Errorf("retrieved empty dataSecretName from bootstrap provider for MachinePool %q in namespace %q", m.Name, m.Namespace)
230+
}
231+
232+
m.Spec.Template.Spec.Bootstrap.DataSecretName = pointer.String(secretName)
233+
m.Status.BootstrapReady = true
234+
return ctrl.Result{}, nil
229235
}
230236

231-
// Get and set the name of the secret containing the bootstrap data.
232-
secretName, _, err := unstructured.NestedString(bootstrapConfig.Object, "status", "dataSecretName")
233-
if err != nil {
234-
return ctrl.Result{}, errors.Wrapf(err, "failed to retrieve dataSecretName from bootstrap provider for MachinePool %q in namespace %q", m.Name, m.Namespace)
235-
} else if secretName == "" {
236-
return ctrl.Result{}, errors.Errorf("retrieved empty dataSecretName from bootstrap provider for MachinePool %q in namespace %q", m.Name, m.Namespace)
237+
// If dataSecretName is set without a ConfigRef, this means the user brought their own bootstrap data.
238+
if m.Spec.Template.Spec.Bootstrap.DataSecretName != nil {
239+
m.Status.BootstrapReady = true
240+
conditions.MarkTrue(m, clusterv1.BootstrapReadyCondition)
241+
return ctrl.Result{}, nil
237242
}
238243

239-
m.Spec.Template.Spec.Bootstrap.DataSecretName = pointer.String(secretName)
240-
m.Status.BootstrapReady = true
241-
return ctrl.Result{}, nil
244+
// This should never happen because the MachinePool webhook would not allow neither ConfigRef nor DataSecretName to be set.
245+
return ctrl.Result{}, errors.Errorf("neither .spec.bootstrap.configRef nor .spec.bootstrap.dataSecretName are set for MachinePool %q in namespace %q", m.Name, m.Namespace)
242246
}
243247

244248
// reconcileInfrastructure reconciles the Spec.InfrastructureRef object on a MachinePool.

exp/internal/controllers/machinepool_controller_phases_test.go

+45-5
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) {
606606
expectError: true,
607607
},
608608
{
609-
name: "existing machinepool, bootstrap data should not change",
609+
name: "existing machinepool with config ref, update data secret name",
610610
bootstrapConfig: map[string]interface{}{
611611
"kind": builder.TestBootstrapConfigKind,
612612
"apiVersion": builder.BootstrapGroupVersion.String(),
@@ -644,13 +644,52 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) {
644644
},
645645
},
646646
expectError: false,
647+
expected: func(g *WithT, m *expv1.MachinePool) {
648+
g.Expect(m.Status.BootstrapReady).To(BeTrue())
649+
g.Expect(*m.Spec.Template.Spec.Bootstrap.DataSecretName).To(Equal("secret-data"))
650+
},
651+
},
652+
{
653+
name: "existing machinepool without config ref, do not update data secret name",
654+
bootstrapConfig: map[string]interface{}{
655+
"kind": builder.TestBootstrapConfigKind,
656+
"apiVersion": builder.BootstrapGroupVersion.String(),
657+
"metadata": map[string]interface{}{
658+
"name": "bootstrap-config1",
659+
"namespace": metav1.NamespaceDefault,
660+
},
661+
"spec": map[string]interface{}{},
662+
"status": map[string]interface{}{
663+
"ready": true,
664+
"dataSecretName": "secret-data",
665+
},
666+
},
667+
machinepool: &expv1.MachinePool{
668+
ObjectMeta: metav1.ObjectMeta{
669+
Name: "bootstrap-test-existing",
670+
Namespace: metav1.NamespaceDefault,
671+
},
672+
Spec: expv1.MachinePoolSpec{
673+
Template: clusterv1.MachineTemplateSpec{
674+
Spec: clusterv1.MachineSpec{
675+
Bootstrap: clusterv1.Bootstrap{
676+
DataSecretName: pointer.String("data"),
677+
},
678+
},
679+
},
680+
},
681+
Status: expv1.MachinePoolStatus{
682+
BootstrapReady: true,
683+
},
684+
},
685+
expectError: false,
647686
expected: func(g *WithT, m *expv1.MachinePool) {
648687
g.Expect(m.Status.BootstrapReady).To(BeTrue())
649688
g.Expect(*m.Spec.Template.Spec.Bootstrap.DataSecretName).To(Equal("data"))
650689
},
651690
},
652691
{
653-
name: "existing machinepool, bootstrap provider is to not ready",
692+
name: "existing machinepool, bootstrap provider is not ready",
654693
bootstrapConfig: map[string]interface{}{
655694
"kind": builder.TestBootstrapConfigKind,
656695
"apiVersion": builder.BootstrapGroupVersion.String(),
@@ -684,12 +723,13 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) {
684723
},
685724
},
686725
Status: expv1.MachinePoolStatus{
687-
BootstrapReady: true,
726+
BootstrapReady: false,
688727
},
689728
},
690-
expectError: false,
729+
expectError: false,
730+
expectResult: ctrl.Result{RequeueAfter: externalReadyWait},
691731
expected: func(g *WithT, m *expv1.MachinePool) {
692-
g.Expect(m.Status.BootstrapReady).To(BeTrue())
732+
g.Expect(m.Status.BootstrapReady).To(BeFalse())
693733
},
694734
},
695735
}

0 commit comments

Comments
 (0)