Skip to content

Commit cecc0f6

Browse files
update: increased edge-case handling
1 parent 1dfb4d4 commit cecc0f6

1 file changed

Lines changed: 78 additions & 86 deletions

File tree

app/api/tasks.py

Lines changed: 78 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from .utils.alerts import *
1919
from .utils.updater import update_flowrun
2020
from .utils.meter import meter_account
21+
from .utils.manager import record_task
2122
from .models import *
2223
from django.contrib.auth.models import User
2324
from 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()
269198
def 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)
704700
def 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---------------\nScan Complete\nStarting Test...\n---------------\n')
1351+
print('\n---------------\nStarting 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

Comments
 (0)