def create_or_update_task(db_session, incident, task: dict, notify: bool = False, sync_external: bool = True): """Creates a new task in the database or updates an existing one.""" existing_task = task_service.get_by_resource_id( db_session=db_session, resource_id=task["resource_id"]) if existing_task: # we save the existing task status before we attempt to update the record existing_status = existing_task.status task = task_service.update( db_session=db_session, task=existing_task, task_in=TaskUpdate( **task, incident=incident, ), sync_external=sync_external, ) if notify: # determine if task was previously resolved if task.status == TaskStatus.resolved: if existing_status != TaskStatus.resolved: send_task_notification( incident, INCIDENT_TASK_RESOLVED_NOTIFICATION, task.creator, task.assignees, task.description, task.weblink, db_session, ) else: # we don't attempt to create new tasks if the incident is currently closed if incident.status == IncidentStatus.closed: return task = task_service.create( db_session=db_session, task_in=TaskCreate(**task, incident=incident), ) if notify: send_task_notification( incident, INCIDENT_TASK_NEW_NOTIFICATION, task.creator, task.assignees, task.description, task.weblink, db_session, ) db_session.commit()
def test_create( session, incident, incident_type, incident_priority, participant, individual_contact ): from dispatch.task.service import create from dispatch.task.models import TaskCreate incident.incident_type = incident_type incident.incident_priority = incident_priority participant.individual = individual_contact task_in = TaskCreate(incident=incident, owner=participant) task = create(db_session=session, task_in=task_in) assert task
def create_or_update_task(db_session, incident, task: dict, notify: bool = False): """Creates a new task in the database or updates an existing one.""" existing_task = task_service.get_by_resource_id( db_session=db_session, resource_id=task["resource_id"]) if existing_task: # save the status before we attempt to update the record existing_status = existing_task.status task = task_service.update(db_session=db_session, task=existing_task, task_in=TaskUpdate(**task)) if notify: # determine if task was previously resolved if task.status == TaskStatus.resolved.value: if existing_status != TaskStatus.resolved.value: send_task_notification( incident.conversation.channel_id, INCIDENT_TASK_RESOLVED_NOTIFICATION, task.assignees, task.description, task.weblink, db_session, ) else: task = task_service.create( db_session=db_session, incident=incident, task_in=TaskCreate(**task), ) if notify: send_task_notification( incident.conversation.channel_id, INCIDENT_TASK_NEW_NOTIFICATION, task.assignees, task.description, task.weblink, db_session, ) db_session.commit()
def create_or_update_task(db_session, incident, task: dict, notify: bool = False): """Creates a new task in the database or updates an existing one.""" incident_task = task_service.get_by_resource_id(db_session=db_session, resource_id=task["id"]) assignees = [] for a in task["assignees"]: assignees.append( db_session.merge( incident_add_or_reactivate_participant_flow( a, incident_id=incident.id, db_session=db_session))) description = task["description"][0] status = TaskStatus.open if not task["status"] else TaskStatus.resolved resource_id = task["id"] weblink = task["web_link"] # TODO we can build this out as our scraping gets more advanced tickets = [ ticket_service.get_or_create_by_weblink(db_session=db_session, weblink=t["web_link"]) for t in task["tickets"] ] if incident_task: # allways update tickets and assignees incident_task.assignees = assignees incident_task.tickets = tickets # only notify if it's newly resolved if status == TaskStatus.resolved: if incident_task.status != TaskStatus.resolved: incident_task.status = status if notify: send_task_notification( incident.conversation.channel_id, INCIDENT_TASK_RESOLVED_NOTIFICATION, assignees, description, weblink, ) else: # we add the task to the incident creator = db_session.merge( incident_add_or_reactivate_participant_flow( task["owner"], incident_id=incident.id, db_session=db_session)) task = task_service.create( db_session=db_session, creator=creator, assignees=assignees, description=description, status=status, tickets=tickets, resource_id=resource_id, resource_type=INCIDENT_RESOURCE_INCIDENT_TASK, weblink=weblink, ) incident.tasks.append(task) if notify: send_task_notification( incident.conversation.channel_id, INCIDENT_TASK_NEW_NOTIFICATION, assignees, description, weblink, ) db_session.commit()
def create_or_update_task(db_session, incident, task: dict, notify: bool = False): """Creates a new task in the database or updates an existing one.""" # TODO we should standarize this interface (kglisson) creator = task["owner"] assignees = ", ".join(task["assignees"]) description = task["description"][0] status = TaskStatus.open if not task["status"] else TaskStatus.resolved resource_id = task["id"] weblink = task["web_link"] incident_task = task_service.get_by_resource_id(db_session=db_session, resource_id=task["id"]) if incident_task: if status == TaskStatus.open: # we don't need to take any actions if the status of the task in the collaboration doc is open return else: if incident_task.status == TaskStatus.resolved: # we don't need to take any actions if the task has already been marked as resolved in the database return else: # we mark the task as resolved in the database incident_task.status = TaskStatus.resolved db_session.add(incident_task) db_session.commit() if notify: send_task_notification( incident.conversation.channel_id, INCIDENT_TASK_RESOLVED_NOTIFICATION, assignees, description, weblink, ) else: # we add the task to the incident task = task_service.create( db_session=db_session, creator=creator, assignees=assignees, description=description, status=status, resource_id=resource_id, resource_type=INCIDENT_RESOURCE_INCIDENT_TASK, weblink=weblink, ) incident.tasks.append(task) db_session.add(incident) db_session.commit() if notify: send_task_notification( incident.conversation.channel_id, INCIDENT_TASK_NEW_NOTIFICATION, assignees, description, weblink, )
def sync_tasks(db_session=None): """Syncs incident tasks.""" # we get all active and stable incidents active_incidents = incident_service.get_all_by_status( db_session=db_session, status=IncidentStatus.active) stable_incidents = incident_service.get_all_by_status( db_session=db_session, status=IncidentStatus.stable) incidents = active_incidents + stable_incidents # we create an instance of the drive task plugin drive_task_plugin = plugins.get(INCIDENT_PLUGIN_TASK_SLUG) for incident in incidents: for doc_type in [ INCIDENT_RESOURCE_INVESTIGATION_DOCUMENT, INCIDENT_RESOURCE_INCIDENT_REVIEW_DOCUMENT, ]: # we get the document object document = get_document(db_session=db_session, incident_id=incident.id, resource_type=doc_type) if not document: # the document may have not been created yet (e.g. incident review document) break # we get the list of tasks in the document tasks = drive_task_plugin.list(file_id=document.resource_id) for t in tasks: # we get the task information creator = t["task"]["owner"] assignees = ", ".join(t["task"]["assignees"]) description = t["task"]["description"][0] status = TaskStatus.open if not t["task"][ "status"] else TaskStatus.resolved resource_id = t["task"]["id"] weblink = t["task"]["web_link"] incident_task = task_service.get_by_resource_id( db_session=db_session, resource_id=t["task"]["id"]) if incident_task: if status == TaskStatus.open: # we don't need to take any actions if the status of the task in the collaboration doc is open break else: if incident_task.status == TaskStatus.resolved: # we don't need to take any actions if the task has already been marked as resolved in the database break else: # we mark the task as resolved in the database incident_task.status = TaskStatus.resolved db_session.add(incident_task) db_session.commit() # we send a notification to the incident conversation notification_text = "Incident Notification" notification_type = "incident-notification" convo_plugin = plugins.get( INCIDENT_PLUGIN_CONVERSATION_SLUG) convo_plugin.send( incident.conversation.channel_id, notification_text, INCIDENT_TASK_RESOLVED_NOTIFICATION, notification_type, task_assignees=assignees, task_description=description, task_weblink=weblink, ) else: # we add the task to the incident task = task_service.create( db_session=db_session, creator=creator, assignees=assignees, description=description, status=status, resource_id=resource_id, resource_type=INCIDENT_RESOURCE_INCIDENT_TASK, weblink=weblink, ) incident.tasks.append(task) db_session.add(incident) db_session.commit() # we send a notification to the incident conversation notification_text = "Incident Notification" notification_type = "incident-notification" convo_plugin = plugins.get( INCIDENT_PLUGIN_CONVERSATION_SLUG) convo_plugin.send( incident.conversation.channel_id, notification_text, INCIDENT_TASK_NEW_NOTIFICATION, notification_type, task_assignees=assignees, task_description=description, task_weblink=weblink, )