Skip to content

Commit 5eaf9e3

Browse files
authored
Merge pull request #7623 from killianmuldoon/fix/ownerref-bug
🐛 Fix bug in kubeadmconfig adoption
2 parents e3de174 + 794f6c1 commit 5eaf9e3

File tree

2 files changed

+107
-5
lines changed

2 files changed

+107
-5
lines changed

bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ func (r *KubeadmConfigReconciler) storeBootstrapData(ctx context.Context, scope
10261026
return nil
10271027
}
10281028

1029-
// Ensure the bootstrap secret has the configOwner as a controller OwnerReference.
1029+
// Ensure the bootstrap secret has the KubeadmConfig as a controller OwnerReference.
10301030
func (r *KubeadmConfigReconciler) ensureBootstrapSecretOwnersRef(ctx context.Context, scope *Scope) error {
10311031
secret := &corev1.Secret{}
10321032
err := r.Client.Get(ctx, client.ObjectKey{Namespace: scope.Config.Namespace, Name: scope.Config.Name}, secret)
@@ -1041,11 +1041,14 @@ func (r *KubeadmConfigReconciler) ensureBootstrapSecretOwnersRef(ctx context.Con
10411041
if err != nil {
10421042
return errors.Wrapf(err, "failed to add KubeadmConfig %s as ownerReference to bootstrap Secret %s", scope.ConfigOwner.GetName(), secret.GetName())
10431043
}
1044+
if c := metav1.GetControllerOf(secret); c != nil && c.Kind != "KubeadmConfig" {
1045+
secret.OwnerReferences = util.RemoveOwnerRef(secret.OwnerReferences, *c)
1046+
}
10441047
secret.OwnerReferences = util.EnsureOwnerRef(secret.OwnerReferences, metav1.OwnerReference{
1045-
APIVersion: scope.ConfigOwner.GetAPIVersion(),
1046-
Kind: scope.ConfigOwner.GetKind(),
1047-
UID: scope.ConfigOwner.GetUID(),
1048-
Name: scope.ConfigOwner.GetName(),
1048+
APIVersion: bootstrapv1.GroupVersion.String(),
1049+
Kind: "KubeadmConfig",
1050+
UID: scope.Config.UID,
1051+
Name: scope.Config.Name,
10491052
Controller: pointer.Bool(true),
10501053
})
10511054
err = patchHelper.Patch(ctx, secret)

bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller_test.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,105 @@ func TestKubeadmConfigReconciler_Reconcile_ReturnEarlyIfKubeadmConfigIsReady(t *
117117
g.Expect(result.RequeueAfter).To(Equal(time.Duration(0)))
118118
}
119119

120+
// Reconcile returns early if the kubeadm config is ready because it should never re-generate bootstrap data.
121+
func TestKubeadmConfigReconciler_TestSecretOwnerReferenceReconciliation(t *testing.T) {
122+
g := NewWithT(t)
123+
124+
clusterName := "my-cluster"
125+
cluster := builder.Cluster(metav1.NamespaceDefault, clusterName).Build()
126+
machine := builder.Machine(metav1.NamespaceDefault, "machine").
127+
WithVersion("v1.19.1").
128+
WithClusterName(clusterName).
129+
WithBootstrapTemplate(bootstrapbuilder.KubeadmConfig(metav1.NamespaceDefault, "cfg").Unstructured()).
130+
Build()
131+
machine.Spec.Bootstrap.DataSecretName = pointer.String("something")
132+
133+
config := newKubeadmConfig(metav1.NamespaceDefault, "cfg")
134+
config.SetOwnerReferences(util.EnsureOwnerRef(config.GetOwnerReferences(), metav1.OwnerReference{
135+
APIVersion: machine.APIVersion,
136+
Kind: machine.Kind,
137+
Name: machine.Name,
138+
UID: machine.UID,
139+
}))
140+
secret := &corev1.Secret{
141+
ObjectMeta: metav1.ObjectMeta{
142+
Name: config.Name,
143+
Namespace: config.Namespace,
144+
},
145+
Type: corev1.SecretTypeBootstrapToken,
146+
}
147+
config.Status.Ready = true
148+
149+
objects := []client.Object{
150+
config,
151+
machine,
152+
secret,
153+
cluster,
154+
}
155+
myclient := fake.NewClientBuilder().WithObjects(objects...).Build()
156+
157+
k := &KubeadmConfigReconciler{
158+
Client: myclient,
159+
}
160+
161+
request := ctrl.Request{
162+
NamespacedName: client.ObjectKey{
163+
Namespace: metav1.NamespaceDefault,
164+
Name: "cfg",
165+
},
166+
}
167+
var err error
168+
key := client.ObjectKeyFromObject(config)
169+
actual := &corev1.Secret{}
170+
171+
t.Run("KubeadmConfig ownerReference is added on first reconcile", func(t *testing.T) {
172+
_, err = k.Reconcile(ctx, request)
173+
g.Expect(err).NotTo(HaveOccurred())
174+
175+
g.Expect(myclient.Get(ctx, key, actual)).To(Succeed())
176+
177+
controllerOwner := metav1.GetControllerOf(actual)
178+
g.Expect(controllerOwner).To(Not(BeNil()))
179+
g.Expect(controllerOwner.Kind).To(Equal(config.Kind))
180+
g.Expect(controllerOwner.Name).To(Equal(config.Name))
181+
})
182+
183+
t.Run("KubeadmConfig ownerReference re-reconciled without error", func(t *testing.T) {
184+
_, err = k.Reconcile(ctx, request)
185+
g.Expect(err).NotTo(HaveOccurred())
186+
187+
g.Expect(myclient.Get(ctx, key, actual)).To(Succeed())
188+
189+
controllerOwner := metav1.GetControllerOf(actual)
190+
g.Expect(controllerOwner).To(Not(BeNil()))
191+
g.Expect(controllerOwner.Kind).To(Equal(config.Kind))
192+
g.Expect(controllerOwner.Name).To(Equal(config.Name))
193+
})
194+
t.Run("non-KubeadmConfig controller OwnerReference is replaced", func(t *testing.T) {
195+
g.Expect(myclient.Get(ctx, key, actual)).To(Succeed())
196+
197+
actual.SetOwnerReferences([]metav1.OwnerReference{
198+
{
199+
APIVersion: machine.APIVersion,
200+
Kind: machine.Kind,
201+
Name: machine.Name,
202+
UID: machine.UID,
203+
Controller: pointer.Bool(true),
204+
}})
205+
g.Expect(myclient.Update(ctx, actual)).To(Succeed())
206+
207+
_, err = k.Reconcile(ctx, request)
208+
g.Expect(err).NotTo(HaveOccurred())
209+
210+
g.Expect(myclient.Get(ctx, key, actual)).To(Succeed())
211+
212+
controllerOwner := metav1.GetControllerOf(actual)
213+
g.Expect(controllerOwner).To(Not(BeNil()))
214+
g.Expect(controllerOwner.Kind).To(Equal(config.Kind))
215+
g.Expect(controllerOwner.Name).To(Equal(config.Name))
216+
})
217+
}
218+
120219
// Reconcile returns nil if the referenced Machine cannot be found.
121220
func TestKubeadmConfigReconciler_Reconcile_ReturnNilIfReferencedMachineIsNotFound(t *testing.T) {
122221
g := NewWithT(t)

0 commit comments

Comments
 (0)