Skip to content

Commit 70ca1e5

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. Signed-off-by: Daniel Lohse <info@asapdesign.de>
1 parent f20e3e5 commit 70ca1e5

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
@@ -131,6 +131,12 @@ type ResourceReconciler[Type client.Object] struct {
131131
// +optional
132132
SkipResource func(ctx context.Context, resource Type) bool
133133

134+
// IfNotFound is called if the resource doesn't exist yet. Return nil if the reconcile should
135+
// be aborted.
136+
//
137+
// +optional
138+
IfNotFound func(ctx context.Context, req Request) Type
139+
134140
Config Config
135141

136142
lazyInit sync.Once
@@ -142,6 +148,12 @@ func (r *ResourceReconciler[T]) init() {
142148
var nilT T
143149
r.Type = newEmpty(nilT).(T)
144150
}
151+
if r.IfNotFound == nil {
152+
r.IfNotFound = func(ctx context.Context, req Request) T {
153+
var nilT T
154+
return nilT
155+
}
156+
}
145157
if r.Name == "" {
146158
r.Name = fmt.Sprintf("%sResourceReconciler", typeName(r.Type))
147159
}
@@ -320,13 +332,18 @@ func (r *ResourceReconciler[T]) reconcileOuter(ctx context.Context, req Request)
320332

321333
originalResource := r.Type.DeepCopyObject().(T)
322334

323-
if err := c.Get(ctx, req.NamespacedName, originalResource); err != nil {
324-
if apierrs.IsNotFound(err) {
325-
// we'll ignore not-found errors, since they can't be fixed by an immediate
326-
// requeue (we'll need to wait for a new notification), and we can get them
327-
// on deleted requests.
335+
err := c.Get(ctx, req.NamespacedName, originalResource)
336+
switch {
337+
case err == nil:
338+
// all good, continue
339+
case apierrs.IsNotFound(err):
340+
// we'll ignore not-found errors, since they can't be fixed by an immediate
341+
// requeue (we'll need to wait for a new notification), and we can get them
342+
// on deleted requests – except if `IfNotFound` returns a new resource
343+
if originalResource = r.IfNotFound(ctx, req); internal.IsNil(originalResource) {
328344
return Result{}, nil
329345
}
346+
default:
330347
if !errors.Is(err, ErrQuiet) {
331348
log.Error(err, "unable to fetch resource")
332349
}

0 commit comments

Comments
 (0)