55from .models import FileInvalidationRequests
66import base64
77from django .http import HttpResponse
8- from .tasks import process_invalidation
8+ from .utils import process_invalidation , get_cern_username
99from django .views .generic import TemplateView
1010from django .db .models import Count , CharField , Value , F , Case , When
1111from django .db .models .functions import StrIndex , Substr
1212import logging
1313import uuid
14- dids_limit = 1000
1514
1615class FileInvalidationRequestSerializer (serializers .Serializer ):
1716 reason = serializers .CharField (required = True ,help_text = "Enter the reason for the file invalidation request." )
@@ -81,40 +80,32 @@ def post(self, request, *args, **kwargs):
8180
8281 file_lines = file_lines .splitlines ()
8382 request_id = uuid .uuid4 ()
83+ logging .info ({k : v for k , v in request .META .items () if k .startswith ("HTTP_" ) or k == "REMOTE_USER" })
84+ user = get_cern_username (request )
8485
8586 cnt = 0
86- if len (file_lines )> dids_limit :
87- return Response ({"message" : f"Request aborted. The file exceeds DIDs limit ({ len (file_lines )} >{ dids_limit } )" }, status = status .HTTP_400_BAD_REQUEST )
8887
8988 raw_file_message = ""
9089 already_serviced_files = ""
9190 for fn in file_lines :
9291 fn = fn .strip ()
9392 fn = fn .replace ('cms:/store' ,'/store' )
9493 obj = FileInvalidationRequests .objects .filter (file_name = fn ).filter (dry_run = False ).first ()
95- if '/RAW/' in fn :
96- raw_file_message = raw_file_message + f'\n Request aborted for file { fn } . File contains RAW data.'
97- input_vals = {'request_id' :request_id ,'file_name' :fn ,'status' :'aborted' ,'mode' :mode ,'dry_run' :dry_run ,'reason' :reason ,'logs' :f'Request aborted for file { fn } . File contains RAW data.' }
98- file_record = FileInvalidationRequests .objects .create (** input_vals )
99- elif obj :
94+ if obj :
10095 already_serviced_files = already_serviced_files + f'\n Request was not created for file { fn } because it has already been submitted and it is currently in status: { obj .status } .'
10196 if obj .status == "in_progress" :
10297 already_serviced_files = already_serviced_files + ' Please wait 30min for the CronJob to update it on the database'
98+ elif obj .status == "waiting_approval" :
99+ already_serviced_files = already_serviced_files + ' Please ask DMOps to approve the invalidation.'
103100 else :
104- input_vals = {'request_id' :request_id ,'file_name' :fn ,'status' :'queued ' ,'mode' :mode ,'dry_run' :dry_run ,'reason' :reason ,'global_invalidate_last_replicas' :global_invalidate_last_replicas }
101+ input_vals = {'request_id' :request_id ,'file_name' :fn ,'status' :'waiting_approval ' ,'mode' :mode ,'dry_run' :dry_run ,'reason' :reason ,'global_invalidate_last_replicas' :global_invalidate_last_replicas , 'request_user' : user , 'rse' : rse }
105102 file_record = FileInvalidationRequests .objects .create (** input_vals )
106103 cnt += 1
107104
108- logging .info (f'{ cnt } of { len (file_lines )} files were created in the database with queued status.' )
105+ logging .info (f'{ cnt } of { len (file_lines )} files were created in the database with waiting_approval status.' )
109106
110- response_message = ""
111- if cnt > 0 :
112- logging .info (f'Processing request id { request_id } ...' )
113- response_message = process_invalidation (request_id , reason ,dry_run = dry_run ,mode = mode ,rse = rse ,to_process = 'queued' ,global_invalidate_last_replicas = global_invalidate_last_replicas )
114- else :
115- return Response ({"message" : f"None of the files could be invalidated. { raw_file_message } , { already_serviced_files } " }, status = status .HTTP_400_BAD_REQUEST )
116107
117- response_message = response_message + raw_file_message + already_serviced_files
108+ response_message = raw_file_message + already_serviced_files
118109
119110 return Response ({"message" : response_message ,
120111 "redirect_url" :f"https://file-invalidation.app.cern.ch/api/query/?request_id={ request_id } " ,
@@ -174,9 +165,43 @@ def get(self, request, *args, **kwargs):
174165 )
175166
176167
177- class HomePageView (TemplateView ):
178- template_name = 'core/home.html'
168+ class InvalidationApproval (APIView ):
169+
170+ def get (self , request , request_id ):
171+ files = FileInvalidationRequests .objects .filter (request_id = request_id )
172+
173+ return Response (
174+ [{"request_id" : f .request_id , "file_name" : f .file_name , "status" : f .status ,"mode" :f .mode ,"dry_run" :f .dry_run ,"reason" :f .reason ,"job_id" :f .job_id ,"logs" :f .logs ,"request_user" :f .request_user } for f in files ],
175+ status = status .HTTP_200_OK
176+ )
177+
178+
179+ def post (self , request , request_id ):
180+ files = FileInvalidationRequests .objects .filter (request_id = request_id )
181+
182+ if not files .exists ():
183+ return Response ({"message" :f"Files with request_id { request_id } not found" },
184+ status = status .HTTP_404_NOT_FOUND )
185+
186+ approval_user = get_cern_username (request )
187+ request_user = files .first ().request_user
179188
180- def get_context_data (self , ** kwargs ):
181- context = super ().get_context_data (** kwargs )
182- return context
189+ if approval_user == request_user :
190+ return Response ({"message" :f"Approval user cannot be the same as request user" },
191+ status = status .HTTP_403_FORBIDDEN )
192+
193+ updated = files .update (status = "approved" ,approval_user = approval_user )
194+ reason = updated .first ().reason
195+ dry_run = updated .first ().dry_run
196+ mode = updated .first ().mode
197+ rse = updated .first ().rse
198+ global_invalidate_last_replicas = updated .first ().global_invalidate_last_replicas
199+
200+ try :
201+ response_message = process_invalidation (request_id , reason , dry_run = dry_run , mode = mode , rse = rse ,to_process = "approved" ,global_invalidate_last_replicas = global_invalidate_last_replicas )
202+ return Response ({"message" : response_message ,
203+ "redirect_url" :f"https://file-invalidation.app.cern.ch/api/query/?request_id={ request_id } " ,
204+ "redirect_description" :"View request_id details" }, status = status .HTTP_201_CREATED )
205+
206+ except Exception as e :
207+ return Response ({"message" :f"None of the files could be invalidated - { str (e )} " })
0 commit comments