1818from .utils .alerts import *
1919from .utils .updater import update_flowrun
2020from .utils .meter import meter_account
21+ from .utils .manager import record_task
2122from .models import *
2223from django .contrib .auth .models import User
2324from django .utils import timezone
@@ -193,85 +194,15 @@ def update_schedule(task_id: str=None) -> None:
193194
194195
195196
196- def record_task (
197- resource_type : str = None ,
198- resource_id : str = None ,
199- task_id : str = None ,
200- task_method : str = None ,
201- ** kwargs ,
202- ) -> bool :
203-
204- """
205- Records task information in the `resource.system`
206- attribute.
207-
208- Expects: {
209- 'resource_type' : str (scan, test, caserun)
210- 'resource_id' : str
211- 'task_id' : str
212- 'task_method' : str
213- 'kwargs' : dict
214- }
215-
216- Returns: max_attempts_reached <bool>
217- """
218-
219- # set default
220- max_atttempts_reached = False
221-
222- # get resource
223- if resource_type == 'scan' :
224- resource = Scan .objects .get (id = resource_id )
225- if resource_type == 'test' :
226- resource = Test .objects .get (id = resource_id )
227- if resource_type == 'caserun' :
228- resource = CaseRun .objects .get (id = resource_id )
229-
230- # get current resoruce.system.tasks data
231- tasks = resource .system .get ('tasks' , [])
232-
233- # get component based on task_name
234- component = task_method .replace ('run_' , '' ).replace ('_bg' , '' ).replace ('_and_logs' , '' )
235-
236- # check if task exists
237- i = 0
238- exists = False
239- for task in tasks :
240- if task ['component' ] == component :
241- # update existing task
242- tasks [i ]['task_id' ] = str (task_id )
243- tasks [i ]['attempts' ] += 1
244- max_atttempts_reached = True if (tasks [i ]['attempts' ] > settings .MAX_ATTEMPTS ) else False
245- exists = True
246- i += 1
247-
248- # append new task data
249- if not exists :
250- tasks .append ({
251- 'attempts' : int (1 ),
252- 'task_id' : str (task_id ),
253- 'task_method' : str (task_method ),
254- 'component' : str (component ),
255- 'kwargs' : kwargs .get ('kwargs' ),
256- })
257-
258- # update resource with new system data
259- resource .system ['tasks' ] = tasks
260- resource .save ()
261-
262- # return
263- return max_atttempts_reached
264-
265-
266-
267-
268197@shared_task ()
269198def redeliver_failed_tasks () -> None :
270199 """
271200 Check each un-completed resource (Scans & Tests)
272201 for any celery tasks which are no longer executing &
273202 associated resource.component is null. Once found,
274- re-run those specific tasks with saved kwargs.
203+ re-run those specific tasks with saved kwargs. If
204+ resource appears complete but is not marked as such,
205+ update `.time_completed` with `datetime.now()`
275206
276207 Expects: None
277208
@@ -302,6 +233,12 @@ def redeliver_failed_tasks() -> None:
302233 continue
303234
304235 # check each task in system['tasks']
236+ task_count = 0
237+ test_id = None
238+ alert_id = None
239+ flowrun_id = None
240+ node_index = None
241+ components = []
305242 for task in scan .system .get ('tasks' , []):
306243
307244 # get scan.{component} data
@@ -314,6 +251,15 @@ def redeliver_failed_tasks() -> None:
314251 if task ['component' ] == 'html' :
315252 component = scan .html
316253
254+ # record components
255+ components .append (task ['component' ])
256+
257+ # try to get args
258+ test_id = task ['kwargs' ].get ('test_id' )
259+ alert_id = task ['kwargs' ].get ('alert_id' )
260+ flowrun_id = task ['kwargs' ].get ('flowrun_id' )
261+ node_index = task ['kwargs' ].get ('node_index' )
262+
317263 # re-run task if not in executing_tasks &
318264 # scan.{component} is None
319265 if task ['task_id' ] not in executing_tasks and component is None :
@@ -322,24 +268,74 @@ def redeliver_failed_tasks() -> None:
322268 if task ['attempts' ] < settings .MAX_ATTEMPTS :
323269 print (f're-running -> { task ["task_method" ]} .delay(**{ task ["kwargs" ]} )' )
324270 eval (f'{ task ["task_method" ]} .delay(**{ task ["kwargs" ]} )' )
271+ task_count += 1
272+
273+ # try to get test_id
274+ if not test_id and Test .objects .filter (post_scan = scan , time_completed = None ).exists ():
275+ test_id = Test .objects .filter (post_scan = scan , time_completed = None )[0 ].id
276+
277+ # check for requested, and not recorded, components:
278+ for comp in scan .type :
279+ if comp not in components and comp != 'logs' :
280+ # building args
281+ task = f"run_{ comp .replace ('html' , 'html_and_logs' )} _bg"
282+ kwargs = {
283+ "scan_id" : str (scan .id ),
284+ "test_id" : str (test_id ),
285+ "alert_id" : alert_id ,
286+ "flowrun_id" : flowrun_id ,
287+ "node_index" : node_index
288+ }
289+ # run task
290+ print (f'running -> { task } .delay(**{ kwargs } )' )
291+ eval (f'{ task } .delay(**{ kwargs } )' )
292+ task_count += 1
293+
294+ # mark scan complete if no tasks were re-run
295+ if task_count == 0 and len (scan .system .get ('tasks' , [])) > 0 :
296+ print (f'marking scan as complete' )
297+ scan .time_completed = datetime .now ()
298+ scan .save ()
299+
300+ # execute `run_test()` if test_id present
301+ if test_id :
302+ print (f'executing run_test() from `post_scan` in `retry_tasks`' )
303+ run_test .delay (
304+ test_id = str (test_id ),
305+ alert_id = alert_id ,
306+ flowrun_id = flowrun_id ,
307+ node_index = node_index
308+ )
325309
326- # iterate through each test and re-run if failed
310+ # iterate through each test and re-run if failed
327311 for test in tests :
328312
329313 # check for localization
330314 if settings .LOCATION != 'us' :
331315 continue
332316
333317 # check each task in system['tasks']
318+ task_count = 0
334319 for task in test .system .get ('tasks' , []):
335320
336321 # re-run task if not in executing_tasks
337322 if task ['task_id' ] not in executing_tasks :
323+
324+ # check for post_scan completion
325+ if not test .post_scan .time_completed :
326+ print ('post_scan not complete skipping test re-run...' )
327+ continue
338328
339329 # check for max attempts
340330 if task ['attempts' ] < settings .MAX_ATTEMPTS :
341331 print (f're-running -> { task ["task_method" ]} .delay(**{ task ["kwargs" ]} )' )
342332 eval (f'{ task ["task_method" ]} .delay(**{ task ["kwargs" ]} )' )
333+ task_count += 1
334+
335+ # mark test complete if no tasks were re-run
336+ if task_count == 0 and len (test .system .get ('tasks' , [])) > 0 :
337+ test .time_completed = datetime .now ()
338+ test .save ()
343339
344340 return None
345341
@@ -703,12 +699,11 @@ def update_scan_score(self, scan_id: str) -> None:
703699@shared_task (bind = True , base = BaseTaskWithRetry )
704700def scan_page_bg (
705701 self ,
706- scan_id : str = None ,
707- test_id : str = None ,
708- alert_id : str = None ,
709- configs : dict = settings .CONFIGS ,
710- flowrun_id : str = None ,
711- node_index : str = None ,
702+ scan_id : str = None ,
703+ test_id : str = None ,
704+ alert_id : str = None ,
705+ flowrun_id : str = None ,
706+ node_index : str = None ,
712707 ) -> None :
713708 """
714709 Runs all the requested `Scan` components
@@ -763,7 +758,7 @@ def scan_page_bg(
763758 node_index = node_index ,
764759 )
765760
766- logger .info ('created new Scan of Page ' )
761+ logger .info ('started scan component tasks ' )
767762 return None
768763
769764
@@ -952,7 +947,6 @@ def create_scan_bg(self, *args, **kwargs) -> None:
952947 scan_page_bg .delay (
953948 scan_id = str (scan .id ),
954949 alert_id = alert_id ,
955- configs = configs ,
956950 flowrun_id = flowrun_id ,
957951 node_index = node_index
958952 )
@@ -1354,7 +1348,7 @@ def run_test(
13541348 })
13551349
13561350 # execute test
1357- print ('\n ---------------\n Scan Complete \ n Starting Test...\n ---------------\n ' )
1351+ print ('\n ---------------\n Starting Test...\n ---------------\n ' )
13581352 test = T (test = test ).run_test ()
13591353
13601354 # update FlowRun if passed
@@ -1462,8 +1456,7 @@ def create_test(
14621456 configs = configs ,
14631457 )
14641458 scan_page_bg .delay (
1465- scan_id = new_scan .id ,
1466- configs = configs ,
1459+ scan_id = new_scan .id ,
14671460 )
14681461
14691462 # update flowrun
@@ -1531,7 +1524,6 @@ def create_test(
15311524 scan_id = post_scan .id ,
15321525 test_id = created_test .id ,
15331526 alert_id = alert_id ,
1534- configs = configs ,
15351527 flowrun_id = flowrun_id ,
15361528 node_index = node_index
15371529 )
0 commit comments