Skip to content

Commit

Permalink
Fix bug in kubeadmconfig adoption
Browse files Browse the repository at this point in the history
Signed-off-by: killianmuldoon <kmuldoon@vmware.com>
  • Loading branch information
killianmuldoon committed Nov 25, 2022
1 parent e3de174 commit 8f0f7d3
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1041,11 +1041,14 @@ func (r *KubeadmConfigReconciler) ensureBootstrapSecretOwnersRef(ctx context.Con
if err != nil {
return errors.Wrapf(err, "failed to add KubeadmConfig %s as ownerReference to bootstrap Secret %s", scope.ConfigOwner.GetName(), secret.GetName())
}
if c := metav1.GetControllerOf(secret); c != nil && c.Kind != "KubeadmConfig" {
secret.OwnerReferences = util.RemoveOwnerRef(secret.OwnerReferences, *c)
}
secret.OwnerReferences = util.EnsureOwnerRef(secret.OwnerReferences, metav1.OwnerReference{
APIVersion: scope.ConfigOwner.GetAPIVersion(),
Kind: scope.ConfigOwner.GetKind(),
UID: scope.ConfigOwner.GetUID(),
Name: scope.ConfigOwner.GetName(),
APIVersion: scope.Config.APIVersion,
Kind: scope.Config.Kind,
UID: scope.Config.UID,
Name: scope.Config.Name,
Controller: pointer.Bool(true),
})
err = patchHelper.Patch(ctx, secret)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,105 @@ func TestKubeadmConfigReconciler_Reconcile_ReturnEarlyIfKubeadmConfigIsReady(t *
g.Expect(result.RequeueAfter).To(Equal(time.Duration(0)))
}

// Reconcile returns early if the kubeadm config is ready because it should never re-generate bootstrap data.
func TestKubeadmConfigReconciler_TestSecretOwnerReferenceReconciliation(t *testing.T) {
g := NewWithT(t)

clusterName := "my-cluster"
cluster := builder.Cluster(metav1.NamespaceDefault, clusterName).Build()
machine := builder.Machine(metav1.NamespaceDefault, "machine").
WithVersion("v1.19.1").
WithClusterName(clusterName).
WithBootstrapTemplate(bootstrapbuilder.KubeadmConfig(metav1.NamespaceDefault, "cfg").Unstructured()).
Build()
machine.Spec.Bootstrap.DataSecretName = pointer.String("something")

config := newKubeadmConfig(metav1.NamespaceDefault, "cfg")
config.SetOwnerReferences(util.EnsureOwnerRef(config.GetOwnerReferences(), metav1.OwnerReference{
APIVersion: machine.APIVersion,
Kind: machine.Kind,
Name: machine.Name,
UID: machine.UID,
}))
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: config.Name,
Namespace: config.Namespace,
},
Type: corev1.SecretTypeBootstrapToken,
}
config.Status.Ready = true

objects := []client.Object{
config,
machine,
secret,
cluster,
}
myclient := fake.NewClientBuilder().WithObjects(objects...).Build()

k := &KubeadmConfigReconciler{
Client: myclient,
}

request := ctrl.Request{
NamespacedName: client.ObjectKey{
Namespace: metav1.NamespaceDefault,
Name: "cfg",
},
}
var err error
key := client.ObjectKeyFromObject(config)
actual := &corev1.Secret{}

t.Run("KubeadmConfig ownerReference is added on first reconcile", func(t *testing.T) {
_, err = k.Reconcile(ctx, request)
g.Expect(err).NotTo(HaveOccurred(), err)

g.Expect(myclient.Get(ctx, key, actual)).To(Succeed())

controllerOwner := metav1.GetControllerOf(actual)
g.Expect(controllerOwner).To(Not(BeNil()))
g.Expect(controllerOwner.Kind).To(Equal(config.Kind))
g.Expect(controllerOwner.Name).To(Equal(config.Name))
})

t.Run("KubeadmConfig ownerReference re-reconciled without error", func(t *testing.T) {
_, err = k.Reconcile(ctx, request)
g.Expect(err).NotTo(HaveOccurred(), err)

g.Expect(myclient.Get(ctx, key, actual)).To(Succeed())

controllerOwner := metav1.GetControllerOf(actual)
g.Expect(controllerOwner).To(Not(BeNil()))
g.Expect(controllerOwner.Kind).To(Equal(config.Kind))
g.Expect(controllerOwner.Name).To(Equal(config.Name))
})
t.Run("non-KubeadmConfig controller OwnerReference is replaced", func(t *testing.T) {
g.Expect(myclient.Get(ctx, key, actual)).To(Succeed())

actual.SetOwnerReferences([]metav1.OwnerReference{
{
APIVersion: machine.APIVersion,
Kind: machine.Kind,
Name: machine.Name,
UID: machine.UID,
Controller: pointer.Bool(true),
}})
g.Expect(myclient.Update(ctx, actual)).To(Succeed())

_, err = k.Reconcile(ctx, request)
g.Expect(err).NotTo(HaveOccurred(), err)

g.Expect(myclient.Get(ctx, key, actual)).To(Succeed())

controllerOwner := metav1.GetControllerOf(actual)
g.Expect(controllerOwner).To(Not(BeNil()))
g.Expect(controllerOwner.Kind).To(Equal(config.Kind))
g.Expect(controllerOwner.Name).To(Equal(config.Name))
})
}

// Reconcile returns nil if the referenced Machine cannot be found.
func TestKubeadmConfigReconciler_Reconcile_ReturnNilIfReferencedMachineIsNotFound(t *testing.T) {
g := NewWithT(t)
Expand Down

0 comments on commit 8f0f7d3

Please sign in to comment.