Skip to content

Commit

Permalink
feat: application resource deletion protection (#630)
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
  • Loading branch information
alexmt authored Oct 23, 2024
1 parent 72bcdda commit 09e5225
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pkg/sync/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const (
AnnotationKeyHook = "argocd.argoproj.io/hook"
// AnnotationKeyHookDeletePolicy is the policy of deleting a hook
AnnotationKeyHookDeletePolicy = "argocd.argoproj.io/hook-delete-policy"
AnnotationDeletionApproved = "argocd.argoproj.io/deletion-approved"

// Sync option that disables dry run in resource is missing in the cluster
SyncOptionSkipDryRunOnMissingResource = "SkipDryRunOnMissingResource=true"
Expand All @@ -35,6 +36,10 @@ const (
SyncOptionDisableDeletion = "Delete=false"
// Sync option that sync only out of sync resources
SyncOptionApplyOutOfSyncOnly = "ApplyOutOfSyncOnly=true"
// Sync option that requires confirmation before deleting the resource
SyncOptionDeleteRequireConfirm = "Delete=confirm"
// Sync option that requires confirmation before deleting the resource
SyncOptionPruneRequireConfirm = "Prune=confirm"
)

type PermissionValidator func(un *unstructured.Unstructured, res *metav1.APIResource) error
Expand Down
26 changes: 26 additions & 0 deletions pkg/sync/sync_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ func WithPrune(prune bool) SyncOpt {
}
}

// WithPruneConfirmed specifies if prune is confirmed for resources that require confirmation
func WithPruneConfirmed(confirmed bool) SyncOpt {
return func(ctx *syncContext) {
ctx.pruneConfirmed = confirmed
}
}

// WithOperationSettings allows to set sync operation settings
func WithOperationSettings(dryRun bool, prune bool, force bool, skipHooks bool) SyncOpt {
return func(ctx *syncContext) {
Expand Down Expand Up @@ -339,6 +346,7 @@ type syncContext struct {
serverSideApplyManager string
pruneLast bool
prunePropagationPolicy *metav1.DeletionPropagation
pruneConfirmed bool

syncRes map[string]common.ResourceSyncResult
startedAt time.Time
Expand Down Expand Up @@ -1149,6 +1157,24 @@ func (sc *syncContext) runTasks(tasks syncTasks, dryRun bool) runState {
}
// prune first
{
if !sc.pruneConfirmed {
var resources []string
for _, task := range pruneTasks {
if resourceutil.HasAnnotationOption(task.liveObj, common.AnnotationSyncOptions, common.SyncOptionPruneRequireConfirm) {
resources = append(resources, fmt.Sprintf("%s/%s/%s", task.obj().GetAPIVersion(), task.obj().GetKind(), task.name()))
}
}
if len(resources) > 0 {
sc.log.WithValues("resources", resources).Info("Prune requires confirmation")
andMessage := ""
if len(resources) > 1 {
andMessage = fmt.Sprintf(" and %d more resources", len(resources)-1)
}
sc.message = fmt.Sprintf("Waiting for pruning confirmation of %s%s", resources[0], andMessage)
return pending
}
}

ss := newStateSync(state)
for _, task := range pruneTasks {
t := task
Expand Down

0 comments on commit 09e5225

Please sign in to comment.