Skip to content

Commit 4987282

Browse files
authored
Merge pull request #338 from rikatz/check-cached-client-before-moving
🐛 Validate the cache contains the created address before moving on
2 parents 01f9a1e + 404c2e7 commit 4987282

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

pkg/ipamutil/reconciler.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ package ipamutil
33
import (
44
"context"
55
"fmt"
6+
"time"
67

78
"github.com/pkg/errors"
89
corev1 "k8s.io/api/core/v1"
910
apierrors "k8s.io/apimachinery/pkg/api/errors"
1011
"k8s.io/apimachinery/pkg/runtime"
1112
"k8s.io/apimachinery/pkg/types"
1213
kerrors "k8s.io/apimachinery/pkg/util/errors"
14+
"k8s.io/apimachinery/pkg/util/wait"
1315
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
1416
ipamv1 "sigs.k8s.io/cluster-api/exp/ipam/api/v1beta1"
1517
clusterutil "sigs.k8s.io/cluster-api/util"
@@ -245,6 +247,23 @@ func (r *ClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ct
245247
return unwrapResult(res), err
246248
}
247249

250+
// We need to ensure the address is properly watched by controller-runtime client (as it is cached) before moving
251+
// to the next reconciliation request.
252+
// This is required, otherwise if the next "EnsureAddress" is called too fast, or the controller-runtime cached client informer
253+
// is too slow, we may end up not seeing that the IP Address is being used and can provide duplicated IPs.
254+
err = wait.PollUntilContextTimeout(ctx, 5*time.Millisecond, 5*time.Second, true, func(ctx context.Context) (bool, error) {
255+
key := client.ObjectKeyFromObject(&address)
256+
if err := r.Client.Get(ctx, key, &ipamv1.IPAddress{}); err != nil {
257+
return false, client.IgnoreNotFound(err)
258+
}
259+
return true, nil
260+
})
261+
262+
if err != nil {
263+
log.Error(err, "failed waiting for IPAddress to be visible in the cache after create", "namespace", address.GetNamespace(), "name", address.GetName())
264+
return ctrl.Result{}, errors.Wrapf(err, "failed waiting for IPAddress %s/%s to be visible in the cache after create", address.GetNamespace(), address.GetName())
265+
}
266+
248267
log.Info(fmt.Sprintf("IPAddress %s/%s (%s) has been %s", address.Namespace, address.Name, address.Spec.Address, operationResult),
249268
"IPAddressClaim", fmt.Sprintf("%s/%s", claim.Namespace, claim.Name))
250269

0 commit comments

Comments
 (0)