5454 apiGVStr = executionv1 .GroupVersion .String ()
5555)
5656
57+ // Finalizer to delete related files in s3 when the scan gets deleted
58+ // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#finalizers
59+ var s3StorageFinalizer = "storage.s3.experimental.securecodebox.io"
60+
5761// +kubebuilder:rbac:groups=execution.experimental.securecodebox.io,resources=scans,verbs=get;list;watch;create;update;patch;delete
5862// +kubebuilder:rbac:groups=execution.experimental.securecodebox.io,resources=scans/status,verbs=get;update;patch
5963// +kubebuilder:rbac:groups=execution.experimental.securecodebox.io,resources=scantypes,verbs=get;list;watch
@@ -90,6 +94,14 @@ func (r *ScanReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
9094
9195 log .V (5 ).Info ("Scan Found" , "Type" , scan .Spec .ScanType , "State" , state )
9296
97+ // Handle Finalizer if the scan is getting deleted
98+ if ! scan .ObjectMeta .DeletionTimestamp .IsZero () {
99+ if err := r .handleFinalizer (& scan ); err != nil {
100+ r .Log .Error (err , "Failed to run Scan Finalizer" )
101+ return ctrl.Result {}, err
102+ }
103+ }
104+
93105 var err error
94106 switch state {
95107 case "Init" :
@@ -154,6 +166,45 @@ func (r *ScanReconciler) checkIfJobIsCompleted(name, namespace string) (jobCompl
154166 return unknown , nil
155167}
156168
169+ // Helper functions to check and remove string from a slice of strings.
170+ func containsString (slice []string , s string ) bool {
171+ for _ , item := range slice {
172+ if item == s {
173+ return true
174+ }
175+ }
176+ return false
177+ }
178+
179+ func removeString (slice []string , s string ) (result []string ) {
180+ for _ , item := range slice {
181+ if item == s {
182+ continue
183+ }
184+ result = append (result , item )
185+ }
186+ return
187+ }
188+
189+ func (r * ScanReconciler ) handleFinalizer (scan * executionv1.Scan ) error {
190+ if containsString (scan .ObjectMeta .Finalizers , s3StorageFinalizer ) {
191+ bucketName := os .Getenv ("S3_BUCKET" )
192+ r .Log .V (0 ).Info ("Deleting External Files from FileStorage" , "ScanUID" , scan .UID )
193+ if err := r .MinioClient .RemoveObject (bucketName , fmt .Sprintf ("scan-%s/%s" , scan .UID , scan .Status .RawResultFile )); err != nil {
194+ return err
195+ }
196+ if err := r .MinioClient .RemoveObject (bucketName , fmt .Sprintf ("scan-%s/findings.json" , scan .UID )); err != nil {
197+ return err
198+ }
199+
200+ scan .ObjectMeta .Finalizers = removeString (scan .ObjectMeta .Finalizers , s3StorageFinalizer )
201+ if err := r .Update (context .Background (), scan ); err != nil {
202+ return err
203+ }
204+ }
205+ return nil
206+ }
207+
157208func (r * ScanReconciler ) startScan (scan * executionv1.Scan ) error {
158209 ctx := context .Background ()
159210 namespacedName := fmt .Sprintf ("%s/%s" , scan .Namespace , scan .Name )
@@ -168,6 +219,14 @@ func (r *ScanReconciler) startScan(scan *executionv1.Scan) error {
168219 return nil
169220 }
170221
222+ // Add s3 storage finalizer to scan
223+ if ! containsString (scan .ObjectMeta .Finalizers , s3StorageFinalizer ) {
224+ scan .ObjectMeta .Finalizers = append (scan .ObjectMeta .Finalizers , s3StorageFinalizer )
225+ if err := r .Update (context .Background (), scan ); err != nil {
226+ return err
227+ }
228+ }
229+
171230 // get the ScanType for the scan
172231 var scanType executionv1.ScanType
173232 if err := r .Get (ctx , types.NamespacedName {Name : scan .Spec .ScanType , Namespace : scan .Namespace }, & scanType ); err != nil {
0 commit comments