diff --git a/changelogs/unreleased/7380-kaovilai b/changelogs/unreleased/7380-kaovilai new file mode 100644 index 0000000000..a95fa4db2d --- /dev/null +++ b/changelogs/unreleased/7380-kaovilai @@ -0,0 +1 @@ +BackupRepositories associated with a BSL are invalidated when BSL is (re-)created. \ No newline at end of file diff --git a/pkg/controller/backup_repository_controller.go b/pkg/controller/backup_repository_controller.go index 12d2930517..a82661c639 100644 --- a/pkg/controller/backup_repository_controller.go +++ b/pkg/controller/backup_repository_controller.go @@ -76,7 +76,11 @@ func (r *BackupRepoReconciler) SetupWithManager(mgr ctrl.Manager) error { For(&velerov1api.BackupRepository{}). Watches(s, nil). Watches(&source.Kind{Type: &velerov1api.BackupStorageLocation{}}, kube.EnqueueRequestsFromMapUpdateFunc(r.invalidateBackupReposForBSL), - builder.WithPredicates(kube.NewUpdateEventPredicate(r.needInvalidBackupRepo))). + builder.WithPredicates( + // When BSL updates, check if the backup repositories need to be invalidated + kube.NewUpdateEventPredicate(r.needInvalidBackupRepo), + // When BSL is created, invalidate any backup repositories that reference it + kube.NewCreateEventPredicate(func(client.Object) bool { return true }))). Complete(r) } @@ -90,13 +94,13 @@ func (r *BackupRepoReconciler) invalidateBackupReposForBSL(bslObj client.Object) }).AsSelector(), } if err := r.List(context.TODO(), list, options); err != nil { - r.logger.WithField("BSL", bsl.Name).WithError(err).Error("unable to list BackupRepositorys") + r.logger.WithField("BSL", bsl.Name).WithError(err).Error("unable to list BackupRepositories") return []reconcile.Request{} } for i := range list.Items { r.logger.WithField("BSL", bsl.Name).Infof("Invalidating Backup Repository %s", list.Items[i].Name) - if err := r.patchBackupRepository(context.Background(), &list.Items[i], repoNotReady("re-establish on BSL change")); err != nil { + if err := r.patchBackupRepository(context.Background(), &list.Items[i], repoNotReady("re-establish on BSL change or create")); err != nil { r.logger.WithField("BSL", bsl.Name).WithError(err).Errorf("fail to patch BackupRepository %s", list.Items[i].Name) } } @@ -104,6 +108,7 @@ func (r *BackupRepoReconciler) invalidateBackupReposForBSL(bslObj client.Object) return []reconcile.Request{} } +// needInvalidBackupRepo returns true if the BSL's storage type, bucket, prefix, CACert, or config has changed func (r *BackupRepoReconciler) needInvalidBackupRepo(oldObj client.Object, newObj client.Object) bool { oldBSL := oldObj.(*velerov1api.BackupStorageLocation) newBSL := newObj.(*velerov1api.BackupStorageLocation) diff --git a/pkg/util/kube/event_handler.go b/pkg/util/kube/event_handler.go index 471a41c81e..e07d173449 100644 --- a/pkg/util/kube/event_handler.go +++ b/pkg/util/kube/event_handler.go @@ -26,10 +26,8 @@ import ( type MapUpdateFunc func(client.Object) []reconcile.Request -// EnqueueRequestsFromMapUpdateFunc is for the same purpose with EnqueueRequestsFromMapFunc. -// Merely, it is more friendly to updating the mapped objects in the MapUpdateFunc, because -// on Update event, MapUpdateFunc is called for only once with the new object, so if MapUpdateFunc -// does some update to the mapped objects, the update is done for once +// EnqueueRequestsFromMapUpdateFunc has the same purpose with handler.EnqueueRequestsFromMapFunc. +// MapUpdateFunc is simpler on Update event because mapAndEnqueue is called once with the new object. EnqueueRequestsFromMapFunc is called twice with the old and new object. func EnqueueRequestsFromMapUpdateFunc(fn MapUpdateFunc) handler.EventHandler { return &enqueueRequestsFromMapFunc{ toRequests: fn,