Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove associated Velero Backups after BSL removal #162

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions docs/design/non_admin_backupstoragelocation.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@ flowchart TD

%% Delete Flow
OPERATION -->|**Delete**| SET_PHASE_DELETING[Set Phase: Deleting]
SET_PHASE_DELETING --> CHECK_SECRET_EXISTS{Check if Secret Exists}
SET_PHASE_DELETING --> CHECK_SECRET_EXISTS{Check if Secret for the NaBSL Exists}
CHECK_SECRET_EXISTS -->|Yes| DELETE_SECRET[Delete Secret in OADP Namespace]
CHECK_SECRET_EXISTS -->|No| CHECK_BSL_EXISTS{Check if Velero BSL Exists}
CHECK_SECRET_EXISTS -->|No| CHECK_BSL_EXISTS{Check if Velero BSL for the NaBSL Exists}

DELETE_SECRET --> CHECK_BSL_EXISTS
CHECK_BSL_EXISTS -->|Yes| DELETE_BSL[Delete Velero BSL Resource in OADP Namespace]
CHECK_BSL_EXISTS -->|No| REMOVE_FINALIZER[Remove Finalizer from NaBSL Resource]
CHECK_BSL_EXISTS -->|No| CHECK_BACKUPS_EXISTS{Check if Velero Backups for the NaBSL Exists}

DELETE_BSL --> REMOVE_FINALIZER
DELETE_BSL --> CHECK_BACKUPS_EXISTS
CHECK_BACKUPS_EXISTS -->|Yes| DELETE_BACKUPS[Delete Velero Backups in OADP Namespace]
CHECK_BACKUPS_EXISTS -->|No| REMOVE_FINALIZER[Remove Finalizer from NaBSL Resource]

DELETE_BACKUPS --> REMOVE_FINALIZER

%% Endpoints
INVALID_CONFIG --> END[End Reconciliation]
Expand All @@ -61,6 +65,8 @@ flowchart TD
DELETE_SECRET
CHECK_BSL_EXISTS
DELETE_BSL
CHECK_BACKUPS_EXISTS
DELETE_BACKUPS
REMOVE_FINALIZER
end

Expand All @@ -72,8 +78,8 @@ flowchart TD

%% Apply styles
class START,END endpoint
class OPERATION,VALIDATE_CONFIG,CHECK_SECRET_EXISTS,CHECK_BSL_EXISTS decision
class GENERATE_UUID,CREATE_OR_UPDATE_SECRET,CREATE_OR_UPDATE_BSL,DELETE_SECRET,DELETE_BSL,REMOVE_FINALIZER process
class OPERATION,VALIDATE_CONFIG,CHECK_SECRET_EXISTS,CHECK_BSL_EXISTS,CHECK_BACKUPS_EXISTS decision
class GENERATE_UUID,CREATE_OR_UPDATE_SECRET,CREATE_OR_UPDATE_BSL,DELETE_SECRET,DELETE_BSL,DELETE_BACKUPS,REMOVE_FINALIZER process
class INVALID_CONFIG,UPDATE_STATUS,VALID_CONFIG,SET_PHASE_DELETING,SET_PHASE_NEW,SET_PHASE_CREATED phase
```

Expand Down Expand Up @@ -118,4 +124,5 @@ flowchart TD
1. User deletes the Non-Admin BSL resource.
2. Controller deletes the Secret from the OADP namespace based on the Non-Admin BSL UUID.
3. Controller deletes the Velero BSL resource from the OADP namespace based on the Non-Admin BSL UUID.
4. Controller removes the finalizer from the Non-Admin BSL resource.
4. Controller deletes the Velero Backups for the NaBSL from the OADP namespace based on the Non-Admin BSL UUID.
5. Controller removes the finalizer from the Non-Admin BSL resource.
3 changes: 3 additions & 0 deletions internal/common/constant/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ const NamespaceString = "Namespace"
// NameString defines a constant for the Name string
const NameString = "name"

// BackupString defines a constant for the Backup string
const BackupString = "backup"

// CurrentPhaseString defines a constant for the Current Phase string
const CurrentPhaseString = "currentPhase"

Expand Down
13 changes: 7 additions & 6 deletions internal/controller/nonadminbackup_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,11 @@ func (r *NonAdminBackupReconciler) createVeleroBackupAndSyncWithNonAdminBackup(c
}
}

veleroBackupLabels := function.GetNonAdminLabels()
// Add NonAdminBackup's veleroBackupNACUUID as the label to the VeleroBackup object
// We don't add this as an argument of GetNonAdminLabels(), because there may be
// situations where NAC object do not require NabOriginUUIDLabel
veleroBackupLabels[constant.NabOriginNACUUIDLabel] = veleroBackupNACUUID
// Included Namespaces are set by the controller and can not be overridden by the user
// nor admin user
backupSpec.IncludedNamespaces = []string{nab.Namespace}
Expand All @@ -639,23 +644,19 @@ func (r *NonAdminBackupReconciler) createVeleroBackupAndSyncWithNonAdminBackup(c
}

backupSpec.StorageLocation = nonAdminBsl.Status.VeleroBackupStorageLocation.Name
veleroBackupLabels[constant.NabslOriginNACUUIDLabel] = nonAdminBsl.Status.VeleroBackupStorageLocation.NACUUID
}

veleroBackup := velerov1.Backup{
ObjectMeta: metav1.ObjectMeta{
Name: veleroBackupNACUUID,
Namespace: r.OADPNamespace,
Labels: function.GetNonAdminLabels(),
Labels: veleroBackupLabels,
Annotations: function.GetNonAdminBackupAnnotations(nab.ObjectMeta),
},
Spec: *backupSpec,
}

// Add NonAdminBackup's veleroBackupNACUUID as the label to the VeleroBackup object
// We don't add this as an argument of GetNonAdminLabels(), because there may be
// situations where NAC object do not require NabOriginUUIDLabel
veleroBackup.Labels[constant.NabOriginNACUUIDLabel] = veleroBackupNACUUID

err = r.Create(ctx, &veleroBackup)

if err != nil {
Expand Down
36 changes: 36 additions & 0 deletions internal/controller/nonadminbackupstoragelocation_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func (r *NonAdminBackupStorageLocationReconciler) Reconcile(ctx context.Context,
r.initNaBSLDelete,
r.deleteVeleroBSLSecret,
r.deleteVeleroBSL,
r.deleteVeleroBackups,
r.removeNaBSLFinalizerUponVeleroBSLDeletion,
}
default:
Expand Down Expand Up @@ -163,6 +164,41 @@ func (r *NonAdminBackupStorageLocationReconciler) initNaBSLDelete(ctx context.Co
return false, nil
}

// deleteVeleroBackups deletes all Velero backups associated with the NonAdminBackupStorageLocation object
// this must happen after the VeleroBackupStorageLocation object is deleted
func (r *NonAdminBackupStorageLocationReconciler) deleteVeleroBackups(ctx context.Context, logger logr.Logger, nabsl *nacv1alpha1.NonAdminBackupStorageLocation) (bool, error) {
veleroBackupList := &velerov1.BackupList{}

if err := function.ListObjectsByLabel(ctx, r.Client, r.OADPNamespace, constant.NabslOriginNACUUIDLabel, nabsl.Status.VeleroBackupStorageLocation.NACUUID, veleroBackupList); err != nil {
return false, err
}

if len(veleroBackupList.Items) == 0 {
logger.V(1).Info("No Velero backups found for NonAdminBackupStorageLocation")
return false, nil
}

// Errors should not block next Backup deletion
// NAC Garbage Collection will remove the orphaned Backups
for _, veleroBackup := range veleroBackupList.Items {
logger.V(1).Info("Deleting Velero backup", constant.BackupString, veleroBackup.Name)
if controllerutil.ContainsFinalizer(&veleroBackup, constant.NabslFinalizerName) {
controllerutil.RemoveFinalizer(&veleroBackup, constant.NabslFinalizerName)
if err := r.Update(ctx, &veleroBackup); err != nil {
logger.Error(err, "Failed to remove finalizer from Velero backup", constant.BackupString, veleroBackup.Name)
}
}
// K8s API does not return 409 error on delete request, so we don't need to fetch
// the latest version of the VeleroBackup object after removing the finalizer
if err := r.Delete(ctx, &veleroBackup); err != nil {
logger.Error(err, "Failed to delete Velero backup", constant.BackupString, veleroBackup.Name)
}
}

logger.V(1).Info("Velero backups for NonAdminBackupStorageLocation deleted")
return false, nil
}

// deleteVeleroBSLSecret deletes the Secret associated with the VeleroBackupStorageLocation object that was created by the controller
func (r *NonAdminBackupStorageLocationReconciler) deleteVeleroBSLSecret(ctx context.Context, logger logr.Logger, nabsl *nacv1alpha1.NonAdminBackupStorageLocation) (bool, error) {
veleroObjectsNACUUID := nabsl.Status.VeleroBackupStorageLocation.NACUUID
Expand Down