Skip to content

Commit d4eda58

Browse files
authored
Merge pull request #317 from llxp/feature/fix-deleted-cluster-skipping-reconcile
🐛 fix skipping reconciliation, when a referenced cluster is already deleted
2 parents 56dca4e + 9fe1049 commit d4eda58

File tree

2 files changed

+49
-25
lines changed

2 files changed

+49
-25
lines changed

internal/controllers/ipaddressclaim_test.go

+38-23
Original file line numberDiff line numberDiff line change
@@ -1903,32 +1903,47 @@ var _ = Describe("IPAddressClaimReconciler", func() {
19031903
})
19041904

19051905
Context("When the cluster can not be retrieved", func() {
1906-
AfterEach(func() {
1907-
deleteClaim("test", namespace)
1908-
deleteNamespacedPool(poolName, namespace)
1906+
When("the claim is not fulfilled", func() {
1907+
AfterEach(func() {
1908+
deleteClaim("test", namespace)
1909+
deleteNamespacedPool(poolName, namespace)
1910+
})
1911+
It("does not allocate an address", func() {
1912+
claim := newClaim("test", namespace, "InClusterIPPool", poolName)
1913+
claim.Spec.ClusterName = clusterName
1914+
claim.Finalizers = []string{ipamutil.ReleaseAddressFinalizer}
1915+
Expect(k8sClient.Create(context.Background(), &claim)).To(Succeed())
1916+
Eventually(Get(&claim)).Should(Succeed())
1917+
1918+
addresses := ipamv1.IPAddressList{}
1919+
Consistently(ObjectList(&addresses, client.InNamespace(namespace))).
1920+
WithTimeout(5 * time.Second).WithPolling(100 * time.Millisecond).Should(
1921+
HaveField("Items", HaveLen(0)))
1922+
})
19091923
})
1910-
It("When the cluster cannot be retrieved", func() {
1911-
claim := ipamv1.IPAddressClaim{
1912-
ObjectMeta: metav1.ObjectMeta{
1913-
Name: "test",
1914-
Namespace: namespace,
1915-
},
1916-
Spec: ipamv1.IPAddressClaimSpec{
1917-
ClusterName: clusterName,
1918-
PoolRef: corev1.TypedLocalObjectReference{
1919-
APIGroup: ptr.To("ipam.cluster.x-k8s.io"),
1920-
Kind: "InClusterIPPool",
1921-
Name: poolName,
1924+
1925+
When("the claim was fulfilled and is deleted", func() {
1926+
It("releases the IP address", func() {
1927+
// does not need to be paused, as the cluster just exists to allow the claim to be fulfilled before deleting the cluster again
1928+
cluster := clusterv1.Cluster{
1929+
ObjectMeta: metav1.ObjectMeta{
1930+
Name: clusterName,
1931+
Namespace: namespace,
19221932
},
1923-
},
1924-
}
1925-
Expect(k8sClient.Create(context.Background(), &claim)).To(Succeed())
1926-
Eventually(Get(&claim)).Should(Succeed())
1933+
}
1934+
Expect(k8sClient.Create(context.Background(), &cluster)).To(Succeed())
1935+
Eventually(Get(&cluster)).Should(Succeed())
1936+
claim := newClaim("test", namespace, "InClusterIPPool", poolName)
1937+
claim.Spec.ClusterName = clusterName
1938+
claim.Finalizers = []string{ipamutil.ReleaseAddressFinalizer}
1939+
Expect(k8sClient.Create(context.Background(), &claim)).To(Succeed())
1940+
Eventually(Get(&claim)).Should(Succeed())
19271941

1928-
addresses := ipamv1.IPAddressList{}
1929-
Consistently(ObjectList(&addresses, client.InNamespace(namespace))).
1930-
WithTimeout(5 * time.Second).WithPolling(100 * time.Millisecond).Should(
1931-
HaveField("Items", HaveLen(0)))
1942+
deleteCluster(clusterName, namespace)
1943+
1944+
Expect(k8sClient.Delete(context.Background(), &claim)).To(Succeed())
1945+
Eventually(Get(&claim)).ShouldNot(Succeed())
1946+
})
19321947
})
19331948
})
19341949

pkg/ipamutil/reconciler.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,15 @@ func (r *ClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ct
140140
if err != nil {
141141
if apierrors.IsNotFound(err) {
142142
if !claim.ObjectMeta.DeletionTimestamp.IsZero() {
143-
return ctrl.Result{}, r.reconcileDelete(ctx, claim)
143+
patch := client.MergeFrom(claim.DeepCopy())
144+
if err := r.reconcileDelete(ctx, claim); err != nil {
145+
return ctrl.Result{}, fmt.Errorf("reconcile delete: %w", err)
146+
}
147+
// we'll need to explicitly patch the claim here since we haven't set up a patch helper yet.
148+
if err := r.Client.Patch(ctx, claim, patch); err != nil {
149+
return ctrl.Result{}, fmt.Errorf("patch after reconciling delete: %w", err)
150+
}
151+
return ctrl.Result{}, nil
144152
}
145153
log.Info("IPAddressClaim linked to a cluster that is not found, unable to determine cluster's paused state, skipping reconciliation")
146154
return ctrl.Result{}, nil
@@ -265,8 +273,9 @@ func (r *ClaimReconciler) reconcileDelete(ctx context.Context, claim *ipamv1.IPA
265273

266274
if address.Name != "" {
267275
var err error
276+
patch := client.MergeFrom(address.DeepCopy())
268277
if controllerutil.RemoveFinalizer(address, ProtectAddressFinalizer) {
269-
if err = r.Client.Update(ctx, address); err != nil && !apierrors.IsNotFound(err) {
278+
if err = r.Client.Patch(ctx, address, patch); err != nil && !apierrors.IsNotFound(err) {
270279
return errors.Wrap(err, "failed to remove address finalizer")
271280
}
272281
}

0 commit comments

Comments
 (0)