Skip to content

Commit 60f9eed

Browse files
committed
Add IfNotFound option to the ResourceReconciler
This can be optionally set and will be used if the resource doesn’t exist yet. When reconciliations are triggered from the outside the user can create the resource. This is useful if the ChildReconciler cannot be used, i.e. if there’s no explicit parent resource.
1 parent 21de323 commit 60f9eed

1 file changed

Lines changed: 22 additions & 5 deletions

File tree

reconcilers/resource.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ type ResourceReconciler[Type client.Object] struct {
126126
// +optional
127127
SkipResource func(ctx context.Context, resource Type) bool
128128

129+
// IfNotFound is called if the resource doesn't exist yet. Return nil if the reconcile should
130+
// be aborted.
131+
//
132+
// +optional
133+
IfNotFound func(ctx context.Context, req Request) Type
134+
129135
Config Config
130136

131137
lazyInit sync.Once
@@ -137,6 +143,12 @@ func (r *ResourceReconciler[T]) init() {
137143
var nilT T
138144
r.Type = newEmpty(nilT).(T)
139145
}
146+
if r.IfNotFound == nil {
147+
r.IfNotFound = func(ctx context.Context, req Request) T {
148+
var nilT T
149+
return nilT
150+
}
151+
}
140152
if r.Name == "" {
141153
r.Name = fmt.Sprintf("%sResourceReconciler", typeName(r.Type))
142154
}
@@ -315,13 +327,18 @@ func (r *ResourceReconciler[T]) reconcileOuter(ctx context.Context, req Request)
315327

316328
originalResource := r.Type.DeepCopyObject().(T)
317329

318-
if err := c.Get(ctx, req.NamespacedName, originalResource); err != nil {
319-
if apierrs.IsNotFound(err) {
320-
// we'll ignore not-found errors, since they can't be fixed by an immediate
321-
// requeue (we'll need to wait for a new notification), and we can get them
322-
// on deleted requests.
330+
err := c.Get(ctx, req.NamespacedName, originalResource)
331+
switch {
332+
case err == nil:
333+
// all good, continue
334+
case apierrs.IsNotFound(err):
335+
// we'll ignore not-found errors, since they can't be fixed by an immediate
336+
// requeue (we'll need to wait for a new notification), and we can get them
337+
// on deleted requests – except if `IfNotFound` returns a new resource
338+
if originalResource = r.IfNotFound(ctx, req); internal.IsNil(originalResource) {
323339
return Result{}, nil
324340
}
341+
default:
325342
if !errors.Is(err, ErrQuiet) {
326343
log.Error(err, "unable to fetch resource")
327344
}

0 commit comments

Comments
 (0)