def format_task_detail(self, task, show_files=False): """Formats a single task in detail. Args: task (dict): The task to format data for show_files (bool): Whether we want to print out log file paths Returns: list: Formatted task data """ report = [] saved_paths = task.get('saved_paths') or [] status = task.get('status') or 'No task status' report.append(fmt.heading2(task.get('name'))) line = '{0:s} {1:s}'.format(fmt.bold('Status:'), status) report.append(fmt.bullet(line)) report.append(fmt.bullet('Task Id: {0:s}'.format(task.get('id')))) report.append( fmt.bullet('Executed on worker {0:s}'.format( task.get('worker_name')))) if task.get('report_data'): report.append('') report.append(fmt.heading3('Task Reported Data')) report.extend(task.get('report_data').splitlines()) if show_files: report.append('') report.append(fmt.heading3('Saved Task Files:')) for path in saved_paths: report.append(fmt.bullet(fmt.code(path))) report.append('') return report
def testFormatting(self): """Test text formatting.""" self.assertEqual('**testing**', fmt.bold(self.test_string)) self.assertEqual('# testing', fmt.heading1(self.test_string)) self.assertEqual('## testing', fmt.heading2(self.test_string)) self.assertEqual('### testing', fmt.heading3(self.test_string)) self.assertEqual('#### testing', fmt.heading4(self.test_string)) self.assertEqual('##### testing', fmt.heading5(self.test_string)) self.assertEqual('* testing', fmt.bullet(self.test_string)) self.assertEqual(' * testing', fmt.bullet(self.test_string, level=3)) self.assertEqual('`testing`', fmt.code(self.test_string))
def format_request_status( self, instance, project, region, days=0, all_fields=False): """Formats the recent history for Turbinia Requests. Args: instance (string): The Turbinia instance name (by default the same as the INSTANCE_ID in the config). project (string): The name of the project. region (string): The name of the zone to execute in. days (int): The number of days we want history for. all_fields (bool): Include all fields for the Request, which includes, saved file paths. Returns: String of Request status """ # Set number of days to retrieve data num_days = 7 if days != 0: num_days = days task_results = self.get_task_data(instance, project, region, days=num_days) if not task_results: return '' # Sort task_results by last updated timestamp. task_results = sorted( task_results, key=itemgetter('last_update'), reverse=True) # Create dictionary of request_id: {saved_paths, last_update, requester, # task_id} request_dict = {} for result in task_results: request_id = result.get('request_id') saved_paths = result.get('saved_paths') if request_id not in request_dict: saved_paths = set(saved_paths) if saved_paths else set() request_dict[request_id] = {} request_dict[request_id]['saved_paths'] = saved_paths request_dict[request_id]['last_update'] = result.get('last_update') request_dict[request_id]['requester'] = result.get('requester') request_dict[request_id]['task_id'] = set([result.get('id')]) else: if saved_paths: request_dict[request_id]['saved_paths'].update(saved_paths) request_dict[request_id]['task_id'].update([result.get('id')]) # Generate report header report = [] report.append( fmt.heading1( 'Turbinia report for Requests made within {0:d} days'.format( num_days))) report.append( fmt.bullet( '{0:d} requests were made within this timeframe.'.format( len(request_dict.keys())))) # Print report data for Requests for request_id, values in request_dict.items(): report.append('') report.append(fmt.heading2('Request ID: {0:s}'.format(request_id))) report.append( fmt.bullet( 'Last Update: {0:s}'.format( values['last_update'].strftime(DATETIME_FORMAT)))) report.append(fmt.bullet('Requester: {0:s}'.format(values['requester']))) report.append( fmt.bullet('Task Count: {0:d}'.format(len(values['task_id'])))) if all_fields: report.append(fmt.bullet('Associated Evidence:')) # Append all saved paths in request for path in sorted(values['saved_paths']): report.append(fmt.bullet(fmt.code(path), level=2)) report.append('') return '\n'.join(report)
def format_worker_status( self, instance, project, region, days=0, all_fields=False): """Formats the recent history for Turbinia Workers. Args: instance (string): The Turbinia instance name (by default the same as the INSTANCE_ID in the config). project (string): The name of the project. region (string): The name of the zone to execute in. days (int): The number of days we want history for. all_fields (bool): Include historical Task information for the worker. Returns: String of Request status """ # Set number of days to retrieve data num_days = 7 if days != 0: num_days = days task_results = self.get_task_data(instance, project, region, days=num_days) if not task_results: return '' # Sort task_results by last updated timestamp. task_results = sorted( task_results, key=itemgetter('last_update'), reverse=True) # Create dictionary of worker_node: {{task_id, task_update, # task_name, task_status}} workers_dict = {} scheduled_counter = 0 for result in task_results: worker_node = result.get('worker_name') status = result.get('status') status = status if status else 'No task status' if worker_node and worker_node not in workers_dict: workers_dict[worker_node] = [] if worker_node: task_dict = {} task_dict['task_id'] = result.get('id') task_dict['last_update'] = result.get('last_update') task_dict['task_name'] = result.get('name') task_dict['status'] = status # Check status for anything that is running. if 'running' in status: run_time = (datetime.now() - result.get('last_update')).total_seconds() run_time = timedelta(seconds=run_time) task_dict['run_time'] = run_time else: run_time = result.get('run_time') task_dict['run_time'] = run_time if run_time else 'No run time.' workers_dict[worker_node].append(task_dict) else: # Track scheduled/unassigned Tasks for reporting. scheduled_counter += 1 # Generate report header report = [] report.append( fmt.heading1( 'Turbinia report for Worker activity within {0:d} days'.format( num_days))) report.append( fmt.bullet('{0:d} Worker(s) found.'.format(len(workers_dict.keys())))) report.append( fmt.bullet( '{0:d} Task(s) unassigned or scheduled and pending Worker assignment.' .format(scheduled_counter))) for worker_node, tasks in workers_dict.items(): report.append('') report.append(fmt.heading2('Worker Node: {0:s}'.format(worker_node))) # Append the statuses chronologically run_status, queued_status, other_status = [], [], [] for task in tasks: if 'running' in task['status']: run_status.extend(self.format_worker_task(task)) elif 'queued' in task['status']: queued_status.extend(self.format_worker_task(task)) else: other_status.extend(self.format_worker_task(task)) # Add each of the status lists back to report list not_found = [fmt.bullet('No Tasks found.')] report.append(fmt.heading3('Running Tasks')) report.extend(run_status if run_status else not_found) report.append('') report.append(fmt.heading3('Queued Tasks')) report.extend(queued_status if queued_status else not_found) # Add Historical Tasks if all_fields: report.append('') report.append(fmt.heading3('Finished Tasks')) report.extend(other_status if other_status else not_found) return '\n'.join(report)