15
15
package principal
16
16
17
17
import (
18
+ "fmt"
19
+
18
20
"github.com/argoproj-labs/argocd-agent/internal/event"
19
21
"github.com/argoproj-labs/argocd-agent/internal/manager"
20
22
"github.com/argoproj-labs/argocd-agent/internal/manager/appproject"
@@ -25,6 +27,7 @@ import (
25
27
corev1 "k8s.io/api/core/v1"
26
28
"k8s.io/apimachinery/pkg/api/errors"
27
29
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30
+ k8stypes "k8s.io/apimachinery/pkg/types"
28
31
)
29
32
30
33
// newAppCallback is executed when a new application event was emitted from
@@ -70,6 +73,26 @@ func (s *Server) updateAppCallback(old *v1alpha1.Application, new *v1alpha1.Appl
70
73
"event" : "application_update" ,
71
74
"application_name" : old .Name ,
72
75
})
76
+
77
+ if isResourceFromAutonomousAgent (new ) {
78
+ // Remove finalizers from autonomous agent applications if it is being deleted
79
+ if new .DeletionTimestamp != nil && len (new .Finalizers ) > 0 {
80
+ updated , err := s .appManager .RemoveFinalizers (s .ctx , new )
81
+ if err != nil {
82
+ logCtx .WithError (err ).Error ("Failed to remove finalizers from autonomous application" )
83
+ } else {
84
+ logCtx .Debug ("Removed finalizers from autonomous application to allow deletion" )
85
+ new = updated
86
+ }
87
+ }
88
+
89
+ // Revert modifications on autonomous agent applications
90
+ if s .appManager .RevertAutonomousAppChanges (s .ctx , new ) {
91
+ logCtx .Trace ("Modifications to the application are reverted" )
92
+ return
93
+ }
94
+ }
95
+
73
96
if s .appManager .IsChangeIgnored (new .QualifiedName (), new .ResourceVersion ) {
74
97
logCtx .WithField ("resource_version" , new .ResourceVersion ).Debugf ("Resource version has already been seen" )
75
98
return
@@ -103,6 +126,14 @@ func (s *Server) deleteAppCallback(outbound *v1alpha1.Application) {
103
126
"application_name" : outbound .Name ,
104
127
})
105
128
129
+ // Revert user-initiated deletion on autonomous agent applications
130
+ if isResourceFromAutonomousAgent (outbound ) {
131
+ if s .revertUserInitiatedDeletion (outbound , logCtx ) {
132
+ logCtx .Trace ("Deleted application is recreated" )
133
+ return
134
+ }
135
+ }
136
+
106
137
s .resources .Remove (outbound .Namespace , resources .NewResourceKeyFromApp (outbound ))
107
138
108
139
if ! s .queues .HasQueuePair (outbound .Namespace ) {
@@ -586,3 +617,30 @@ func isResourceFromAutonomousAgent(resource metav1.Object) bool {
586
617
_ , ok := annotations [manager .SourceUIDAnnotation ]
587
618
return ok
588
619
}
620
+
621
+ func (s * Server ) revertUserInitiatedDeletion (outbound * v1alpha1.Application , logCtx * logrus.Entry ) bool {
622
+ appKey := fmt .Sprintf ("%s/%s" , outbound .Namespace , outbound .Name )
623
+
624
+ // Check if this deletion was expected (agent-initiated)
625
+ if s .isExpectedDeletion (appKey ) {
626
+ logCtx .Debugf ("Expected deletion from autonomous agent - allowing it to proceed" )
627
+ // This is a legitimate deletion from the agent, let it proceed normally
628
+ return false
629
+ }
630
+
631
+ logCtx .Warnf ("Unauthorized deletion detected for autonomous agent application - recreating" )
632
+ // This is an unauthorized deletion (user-initiated), recreate the app
633
+ app := outbound .DeepCopy ()
634
+ app .ResourceVersion = ""
635
+ app .DeletionTimestamp = nil
636
+ sourceUID := outbound .Annotations [manager .SourceUIDAnnotation ]
637
+ app .SetUID (k8stypes .UID (sourceUID ))
638
+ _ , err := s .appManager .Create (s .ctx , app )
639
+ if err != nil {
640
+ logCtx .WithError (err ).Error ("failed to recreate application after unauthorized deletion" )
641
+ } else {
642
+ logCtx .Infof ("Recreated application %s after unauthorized deletion" , outbound .Name )
643
+ }
644
+
645
+ return true
646
+ }
0 commit comments