diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 4083c3fd12505..8f5e970d7e071 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -18,6 +18,7 @@ import ( "github.com/argoproj/gitops-engine/pkg/diff" "github.com/argoproj/gitops-engine/pkg/health" synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" + resourceutil "github.com/argoproj/gitops-engine/pkg/sync/resource" "github.com/argoproj/gitops-engine/pkg/utils/kube" jsonpatch "github.com/evanphx/json-patch" log "github.com/sirupsen/logrus" @@ -941,7 +942,7 @@ func (ctrl *ApplicationController) removeProjectFinalizer(proj *appv1.AppProject // shouldBeDeleted returns whether a given resource obj should be deleted on cascade delete of application app func (ctrl *ApplicationController) shouldBeDeleted(app *appv1.Application, obj *unstructured.Unstructured) bool { - return !kube.IsCRD(obj) && !isSelfReferencedApp(app, kube.GetObjectRef(obj)) + return !kube.IsCRD(obj) && !isSelfReferencedApp(app, kube.GetObjectRef(obj)) && !resourceutil.HasAnnotationOption(obj, synccommon.AnnotationSyncOptions, synccommon.SyncOptionDisableDeletion) } func (ctrl *ApplicationController) getPermittedAppLiveObjects(app *appv1.Application, proj *appv1.AppProject, projectClusters func(project string) ([]*appv1.Cluster, error)) (map[kube.ResourceKey]*unstructured.Unstructured, error) { diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 44e32e54ea945..3aec11bbc48b7 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -1401,3 +1401,20 @@ func Test_canProcessApp(t *testing.T) { assert.False(t, canProcess) }) } + +func Test_syncDeleteOption(t *testing.T) { + app := newFakeApp() + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + cm := newFakeCM() + t.Run("without delete option object is deleted", func(t *testing.T) { + cmObj := kube.MustToUnstructured(&cm) + delete := ctrl.shouldBeDeleted(app, cmObj) + assert.True(t, delete) + }) + t.Run("with delete set to false object is retained", func(t *testing.T) { + cmObj := kube.MustToUnstructured(&cm) + cmObj.SetAnnotations(map[string]string{"argocd.argoproj.io/sync-options": "Delete=false"}) + delete := ctrl.shouldBeDeleted(app, cmObj) + assert.False(t, delete) + }) +} diff --git a/docs/user-guide/sync-options.md b/docs/user-guide/sync-options.md index 098291e80d28b..688e1800bf406 100644 --- a/docs/user-guide/sync-options.md +++ b/docs/user-guide/sync-options.md @@ -58,6 +58,18 @@ metadata: The dry run will still be executed if the CRD is already present in the cluster. +## No Resource Deletion + +For certain resources you might want to retain them even after your application is deleted, for eg. Persistent Volume Claims. +In such situations you can stop those resources from being cleaned up during app deletion by using the following annotation: + + +```yaml +metadata: + annotations: + argocd.argoproj.io/sync-options: Delete=false +``` + ## Selective Sync Currently when syncing using auto sync Argo CD applies every object in the application. diff --git a/go.mod b/go.mod index 3d55effb8350a..17f84d6a3ec7e 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.0 github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d github.com/alicebob/miniredis/v2 v2.23.1 - github.com/argoproj/gitops-engine v0.7.1-0.20221208230615-917f5a0f16d5 + github.com/argoproj/gitops-engine v0.7.1-0.20230214165351-ed70eac8b7bd github.com/argoproj/notifications-engine v0.3.1-0.20221203221941-490d98afd1d6 github.com/argoproj/pkg v0.13.7-0.20221221191914-44694015343d github.com/aws/aws-sdk-go v1.44.164 diff --git a/go.sum b/go.sum index 47f93ada43d24..f6f0e9bb25030 100644 --- a/go.sum +++ b/go.sum @@ -147,8 +147,8 @@ github.com/antonmedv/expr v1.9.0/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmH github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= -github.com/argoproj/gitops-engine v0.7.1-0.20221208230615-917f5a0f16d5 h1:iRpHi7X3q9G55KTaMjxKicgNnS2blFHaEfOOgsmP8lE= -github.com/argoproj/gitops-engine v0.7.1-0.20221208230615-917f5a0f16d5/go.mod h1:WpA/B7tgwfz+sdNE3LqrTrb7ArEY1FOPI2pAGI0hfPc= +github.com/argoproj/gitops-engine v0.7.1-0.20230214165351-ed70eac8b7bd h1:4Y76oXOZ2b7px7ppRSNpdxFPhUEw5e3BYEWpxn8pO2I= +github.com/argoproj/gitops-engine v0.7.1-0.20230214165351-ed70eac8b7bd/go.mod h1:WpA/B7tgwfz+sdNE3LqrTrb7ArEY1FOPI2pAGI0hfPc= github.com/argoproj/notifications-engine v0.3.1-0.20221203221941-490d98afd1d6 h1:b92Xft7MQv/SP56FW08zt5CMTE1rySH8UPDKOAgSzOM= github.com/argoproj/notifications-engine v0.3.1-0.20221203221941-490d98afd1d6/go.mod h1:pgPU59KCsBOMhyw9amRWPoSuBmUWvx3Xsc5r0mUriLg= github.com/argoproj/pkg v0.13.7-0.20221221191914-44694015343d h1:7fXEKF3OQ9i1PrgieA6FLrXOL3UAKyiotomn0RHevds=